environmental variables

C

Casanova

Hello!!

how can i get all the details of the environmental variables. If i use
getenv, i will have to specify the name of the variable. for intsance i
will have to give getenv("PATH")

How can i get the information of all the variables, with the variable
names and its values

Pls Help

Casanova
 
S

Satya Das

/*
This program should print all the environment variables.
*/
#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )
{
for( int i = 0; envp != NULL; ++i )
{
printf("%s\n", envp);
}

return 0;
}
 
J

Joona I Palaste

Satya Das said:
/*
This program should print all the environment variables.
*/

Only on some implementations.
#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )

This form of main() is non-standard and causes undefined behaviour.
It might work for some implementations but is not guaranteed to work
on any.
{
for( int i = 0; envp != NULL; ++i )
{
printf("%s\n", envp);
}
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Joona said:
Satya Das said:
/*
This program should print all the environment variables.
*/


Only on some implementations.

#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )


This form of main() is non-standard and causes undefined behaviour.

Hmm, the C99 standard says in 5.1.2.2.1 Program startup, that main() is
defined
a) "... with no parameters"
b) "... or with two parameters"
c) "..., or in some other implementation-defined manner".

That's not undefined and should not cause nasal daemons or anything
else, should it? ;-)

Bjørn
[snip]
 
J

Jens.Toerring

Only on some implementations.
#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )
This form of main() is non-standard and causes undefined behaviour.
It might work for some implementations but is not guaranteed to work
on any.

Just taking a closer look I found in the standard (C89):

In a hosted environment, the main function receives a third
argument, char *envp[], that points to a null-terminated array of
pointers to char, each of which points to a string that provides
information about the environment for this execution of the process

but which seems to contradict what's written further up about the
arguments of main() for a hosted environment:

The function called at program startup is named main. The
implementation declares no prototype for this function. It can be
defined with no parameters:

int main(void) { /*...*/ }

or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):

int main(int argc, char *argv[]) { /*...*/ }

Can someone shed some light on this? Is that why in C99 the extra
clause "or in some other implementation-defined manner" got added
(but they kept the requirement for the third, *envp argument, not
declaring that as also "implementation-defined")? Or does main()
receive a third argument but you're not allowed to put it into its
definition (but which would seem to be silly)?

Regards, Jens
 
E

Eric Sosman

Only on some implementations.
#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )
This form of main() is non-standard and causes undefined behaviour.
It might work for some implementations but is not guaranteed to work
on any.

Just taking a closer look I found in the standard (C89):

In a hosted environment, the main function receives a third
argument, char *envp[], that points to a null-terminated array of
pointers to char, each of which points to a string that provides
information about the environment for this execution of the process
[...]

The quoted text is from an appendix titled "Common
extensions." The paragraph immediately before the quote
begins

The following extensions are widely used in many
systems, but are not portable to all implementations.

Other nearby paragraphs mention such things as dollar
signs in identifiers, modifiable string literals, casting
data pointers to function pointers, the `asm' keyword, and
so on. Like the `envp' argument, all are non-Standard.
 
L

Lawrence Kirby

And it is mostly deprecated even on those now. For reference the POSIX way
is to use an extern char **environ variable.
#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )
This form of main() is non-standard and causes undefined behaviour.
It might work for some implementations but is not guaranteed to work
on any.

Just taking a closer look I found in the standard (C89):

In a hosted environment, the main function receives a third
argument, char *envp[], that points to a null-terminated array of
pointers to char, each of which points to a string that provides
information about the environment for this execution of the process

I believe you found this in an non-normative annex under a section called
"Common Extensions". I.e. this text is NOT part of the standard definition
of the C language.
but which seems to contradict what's written further up about the
arguments of main() for a hosted environment:

The function called at program startup is named main. The
implementation declares no prototype for this function. It can be
defined with no parameters:

int main(void) { /*...*/ }

or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):

int main(int argc, char *argv[]) { /*...*/ }

Can someone shed some light on this? Is that why in C99 the extra
clause "or in some other implementation-defined manner" got added
(but they kept the requirement for the third, *envp argument, not
declaring that as also "implementation-defined")? Or does main()
receive a third argument but you're not allowed to put it into its
definition (but which would seem to be silly)?

There is NO three argument form of main() in standard C. It is simply
recognised in the standard document as a common extension. C99 allows
implementation-defined extensions. All this means is that if an
implementation supports any forms of main() other than the 2 above (and
those compatible with them) it must document them. There is no requirement
that a particular implementation supports specific other forms such as the
envp one, and code that uses them results in undefined behvaiour as far as
the standard is concerned.

Lawrence
 
J

Jens.Toerring

Eric Sosman said:
Just taking a closer look I found in the standard (C89):

In a hosted environment, the main function receives a third
argument, char *envp[], that points to a null-terminated array of
pointers to char, each of which points to a string that provides
information about the environment for this execution of the process
[...]
The quoted text is from an appendix titled "Common
extensions." The paragraph immediately before the quote
begins
The following extensions are widely used in many
systems, but are not portable to all implementations.

I see, thanks. Should have scrolled up instead of just down, not
really caring for anything that didn't contain the string "env"...

Regards, Jens
 
F

Flash Gordon

Joona said:
Satya Das said:
/*
This program should print all the environment variables.
*/


Only on some implementations.

#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )


This form of main() is non-standard and causes undefined behaviour.

Hmm, the C99 standard says in 5.1.2.2.1 Program startup, that main()
is defined
a) "... with no parameters"
b) "... or with two parameters"
c) "..., or in some other implementation-defined manner".

That's not undefined and should not cause nasal daemons or anything
else, should it? ;-)

Surely that means that if the implementation defines another prototype
it is implementation defined but if you do something neither explicitly
defined by the C standard nor the implementation then it is undefined
behaviour. So on a Posix system it may be defined (by the
implementation) but on Windows it might invoke undefined behaviour.
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Flash said:
Joona I Palaste wrote:

Satya Das <[email protected]> scribbled the following:


/*
This program should print all the environment variables.
*/


Only on some implementations.



#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )


This form of main() is non-standard and causes undefined behaviour.

Hmm, the C99 standard says in 5.1.2.2.1 Program startup, that main()
is defined
a) "... with no parameters"
b) "... or with two parameters"
c) "..., or in some other implementation-defined manner".

That's not undefined and should not cause nasal daemons or anything
else, should it? ;-)


Surely that means that if the implementation defines another prototype
it is implementation defined but if you do something neither explicitly
defined by the C standard nor the implementation then it is undefined
behaviour. So on a Posix system it may be defined (by the
implementation) but on Windows it might invoke undefined behaviour.

If a prototype for main() is neither according to the standard nor
supported by the implementation, I would expect a diagnostic message to
be printed instead of just silently allowing it and possibly invoke
undefined behaviour.

Now that I have tried it, I am not so sure anymore. gcc -std=c99 is
silent on the foo parameter unless -Wall is used, even if it reports
that main() doesn't return int. MSVC happily accepts the code, even when
/Za /W4 is used. :-|

Bjørn

$ cat m2.c
#include <stdio.h>

float main(int ac, char*av[], char**envp, char**foo)
{
while(*envp)
printf("%s\n", *envp++);

return 0;
}

boa@wintendo /tmp
$ gcc -std=c99 m2.c
m2.c: In function `main':
m2.c:4: warning: return type of `main' is not `int'

boa@wintendo /tmp
$ gcc -std=c99 -Wall m2.c
m2.c:4: warning: return type of `main' is not `int'
m2.c:4: warning: `main' takes only zero or two arguments

boa@wintendo /tmp
$
 
K

Keith Thompson

Casanova said:
how can i get all the details of the environmental variables. If i use
getenv, i will have to specify the name of the variable. for intsance i
will have to give getenv("PATH")

How can i get the information of all the variables, with the variable
names and its values

There is no portable way to do this in standard C.

Many implementations provide a way to do this. Consult the
documentation for your system (or, failing that, ask in an
implementation-specific newsgroup).

<OT>
Some systems may use
extern char **environ;
</OT>
 
M

Michael Wojcik

If a prototype for main() is neither according to the standard nor
supported by the implementation, I would expect a diagnostic message to
be printed instead of just silently allowing it and possibly invoke
undefined behaviour.

This is a dangerous expectation. The standard does not require a
diagnostic for this case. In fact, it doesn't require a diagnostic
for any specific case; what it requires is that, if a translation
unit has at least one constraint violation, the implementation must
emit at least one diagnostic (which might be "compilation finished",
say). But this isn't a constraint violation, so you don't even have
that guarantee.

The diagnostics provided by the implementation are purely a quality-
of-implementation issue, and many implementations are not of especially
high quality - including many of the most commonly used ones.

Moreover, there could be good reasons for an implementation to *not*
diagnose this. In particular, some implementations let you change the
parameters passed to main, and implement the parameterization of main
in a fashion sufficiently separate from the translator that the latter
does not know if you've changed it. (On some implementations, for
example, this would involve providing new "startup code".)

In short, it's better to know what the standard does and does not
require of an implementation, and what the implementation(s) you're
using documents as its implementation-defined behavior and extensions
to the language, than to hope that it will provide a diagnostic when
you violate the rules.

--
Michael Wojcik (e-mail address removed)

[After the lynching of George "Big Nose" Parrot, Dr. John] Osborne
had the skin tanned and made into a pair of shoes and a medical bag.
Osborne, who became governor, frequently wore the shoes.
-- _Lincoln [Nebraska] Journal Star_
 
K

Keith Thompson

This is a dangerous expectation. The standard does not require a
diagnostic for this case. In fact, it doesn't require a diagnostic
for any specific case; what it requires is that, if a translation
unit has at least one constraint violation, the implementation must
emit at least one diagnostic (which might be "compilation finished",
say). But this isn't a constraint violation, so you don't even have
that guarantee.

The diagnostics provided by the implementation are purely a quality-
of-implementation issue, and many implementations are not of especially
high quality - including many of the most commonly used ones.

(Irrelevant aside: the standard does require a specific diagnostic for
the "#error" directive.")

I don't think the situation is quite as dire as you imply. In my
experience, most implementations do make a good effort to produce
meaningful diagnostics for syntax errors and constraint violations,
including an attempt to indicate the line in the source file that
caused the problem. In the case of syntax errors, the parser is
likely to become confused about reporting any *further* errors (and a
misspelled typedef name is effectively a syntax error).

In the very worst case, a minimalist compiler could print a single
question mark as its only diagnostic, leaving the user to examine the
entire source file to figure out the problem. (For that matter, it
could print the question mark even if there is no error.) In the
worst realistic case, the first diagnostic emitted is likely to be
helpful in tracking down the problem; the usefulness of further
diagnostics depends on how badly the compiler was confused by the
first error.

But in the particular case of a non-standard declaration for main(),
you're right; the standard doesn't require a diagnostic, and many
implementations won't give you one.
 
K

Kenny McCormack

Satya Das said:
/*
This program should print all the environment variables.
*/

Only on some implementations.
#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )

This form of main() is non-standard and causes undefined behaviour.
It might work for some implementations but is not guaranteed to work
on any.

Bzzzzt. It is guaranteed to work on Unix (aka, POSIX).
This serves as a counterexample to the statement that there doesn't exist
a system under which it is guaranteed to work.
 
J

Joona I Palaste

Kenny McCormack said:
Satya Das said:
/*
This program should print all the environment variables.
*/

Only on some implementations.
#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )

This form of main() is non-standard and causes undefined behaviour.
It might work for some implementations but is not guaranteed to work
on any.
Bzzzzt. It is guaranteed to work on Unix (aka, POSIX).
This serves as a counterexample to the statement that there doesn't exist
a system under which it is guaranteed to work.

When I say "guaranteed" I mean "guaranteed by the C standard", keeping
with the topic of this group. Implementations may guarantee what they
want, as long as it doesn't conflict with the C standard, but that's off
topic here.
 
G

Greg Comeau

Satya Das said:
/*
This program should print all the environment variables.
*/

Only on some implementations.
#include <stdio.h>
int main( int argc, char *argv[], char *envp[] )

This form of main() is non-standard and causes undefined behaviour.
It might work for some implementations but is not guaranteed to work
on any.

Bzzzzt. It is guaranteed to work on Unix (aka, POSIX).
This serves as a counterexample to the statement that there doesn't exist
a system under which it is guaranteed to work.

What he was trying to say was that it was not guaranteed to work
under Standard C. Of course some thing else may guarantee it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top