getenv returns same string as putenv?

Discussion in 'C Programming' started by Michael B Allen, Dec 11, 2006.

  1. Is the string returned by getenv guaranteed to be the same string supplied
    to putenv plus the offset of the variable name and equals sign?

    Because of API constraints I do not want to save a pointer to the string
    passed to putenv but I need to be able to free it later or I will have
    a memory leak.

    The following code demponstrates that with at least glibc the same string
    is in fact returned.

    unsigned char *s1, *s2;

    s2 = "SOMEVAR=whatever";
    s1 = malloc(strlen(s2) + 1);
    strcpy(s1, s2);

    if (putenv(s1) == -1) {
    PMNO(errno);
    return -1;
    }

    s2 = getenv("SOMEVAR");

    printf("s1=%p,s2 - 8=%p\n", s1, s2 - 8);

    free(s2 - 8);

    output: s1=0x9925828,s2 - 8=0x9925828

    Mike
     
    Michael B Allen, Dec 11, 2006
    #1
    1. Advertisements

  2. Michael B Allen

    Chris Dollin Guest

    There is no `putenv`, at least not in Standard C.

    (fx:eek:t)

    I see from `man putenv` on my Linux box that `putenv` is supposed there to
    conform to SVID 3, POSIX, 4.3BSD. So it looks like you will have to
    appeal to implementation-specific documentation or newsgroups.

    That same man page says

    int putenv(char *string);
    ....
    The string pointed to by string becomes part of the environment,
    so altering the string changes the environment.

    (fx:bot)

    Can you redesign to eliminate this use of `putenv` and eliminate the
    problem? That's what I'd [try to] do.
     
    Chris Dollin, Dec 11, 2006
    #2
    1. Advertisements

  3. Michael B Allen

    Eric Sosman Guest

    No, because there is no putenv() in the Standard C library.
    As far as C is concerned, the environment is read-only.
    ... and this may be one of the reasons the Standard doesn't
    define putenv(): deciding who manages the memory could turn out
    to be troublesome. Should putenv() copy the provided string,
    or should it require that the string continue to exist? If it
    copies, what should it do if unable to allocate memory to hold
    the string (in particular, can it free() a prior value and then
    fail to set the new one, or must it guarantee all-or-nothing)?

    Questions like this can, of course, be settled, even if by
    arbitrary choice. However, the Committee chose not to settle
    it, writing (in the Rationale)

    A corresponding putenv function was omitted from the
    Standard, since its utility outside a multi-process
    environment is questionable, and since its definition
    is properly the domain of an operating system standard.

    It's possible that this is face-saving language for "We couldn't
    find a way to reconcile the conflicting behaviors of different
    existing putenv() implementations, so we punted." But face-saving
    or face-value, that's the state of affairs: There's no putenv() in
    the C library, and systems that provide it as an extension have
    defined their extensions in somewhat different ways.
     
    Eric Sosman, Dec 11, 2006
    #3
  4. Michael B Allen

    Ben Pfaff Guest

    No: the implementation is allowed to reuse a static buffer on
    each call to getenv. (I am assuming that "putenv" is the "method
    for altering the environment list" that the Standard says is
    implementation-defined.)
     
    Ben Pfaff, Dec 11, 2006
    #4
  5. Yeah, on second thought, even if getenv was guaranteed to return what
    was supplied to putenv there would be no way to guarantee that putenv
    was not called by code outside of my scope and therefore freeing the
    result of getenv is inherently flawed.

    I'll have to wrap them and use a global to ensure it doesn't leak.

    Thanks,
    Mike
     
    Michael B Allen, Dec 11, 2006
    #5
  6. Michael B Allen

    Richard Bos Guest

    Possibly more like "We couldn't find a way to reconcile the conflicting
    behaviours of different OSes, so we were forced to punt".

    Richard
     
    Richard Bos, Dec 12, 2006
    #6
  7. Michael B Allen

    James Antill Guest

    Just use setenv() and free immediately, it has sane semantics.

    http://www.opengroup.org/onlinepubs/009695399/functions/setenv.html
     
    James Antill, Dec 12, 2006
    #7
  8. Michael B Allen

    CBFalconer Guest

    CBFalconer, Dec 12, 2006
    #8
  9. Michael B Allen

    Chris Dollin Guest

    There is no `setenv` in Standard C.
     
    Chris Dollin, Dec 13, 2006
    #9
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.