Questions about getpwnam()

Ask a Question related to UNIX Programming, Design and Development.

  1. #1

    Default Questions about getpwnam()

    Hi,

    According to my Linux man page for the getpwnam() function, the function
    may return NULL if it failed to allocate a passwd structure. So far so
    good, but the man page says nothing about freeing the returned pointer.
    APUE, page 147, says that the "structure is usually a static variable
    within the function", which sounds reasonable to me, but why can the
    function then fail with ENOMEM? Does anyone know if the returned struct
    should be freed or not? Are there portability issues involved?

    The man page also lists one error code only, ENOMEM. What if the user
    doesn't exist in /etc/passwd? I'd expect getpwnam() to set errno to e.g.
    ENOENT. Any additional info about error codes out there? :-)

    Thanks in advance.

    --
    boa

    libclc home: [url]http://libclc.sourceforge.net[/url]

    Bjørn Augestad Guest

  2. Similar Questions and Discussions

    1. AMD-64 Questions
      Hi All: Newbie w/ some questions: PC: AMD-64 bit, full install working reasonably well (no attempts at multi-media yet): w/ Athlon AMD-64...
    2. Mac OS-10 & MX questions / Please Help!
      A couple of questions: 1. I am getting a Mac with OS10 running Director MX. If I create a projector, will it run on older OS systems? 2. Which...
    3. 2 questions
      For an example of how to use the SysCmd, open the Northwind sample database, and look in the Utility module. They have a wrapper function named...
    4. The questions.
      "Chris Thomas" <chrisvai777@hotmail.com> wrote in message news:9f682ea7.0307210257.5a2a89a1@posting.google.com... It depends on what drives you...
    5. 2 questions :) - portal questions
      Say the portal displays a relationship that uses the Box_ID field as the match field on both sides. In the child file (items in the box), add two...
  3. #2

    Default Re: Questions about getpwnam()

    On Sat, 12 Jul 2003 09:01:45 GMT, Bjørn Augestad
    <boa@metasystems.no.spam.to.me> wrote:
    > Hi,
    >
    > According to my Linux man page for the getpwnam() function, the function
    > may return NULL if it failed to allocate a passwd structure. So far so
    > good, but the man page says nothing about freeing the returned pointer.
    > APUE, page 147, says that the "structure is usually a static variable
    > within the function", which sounds reasonable to me, but why can the
    > function then fail with ENOMEM? Does anyone know if the returned struct
    > should be freed or not? Are there portability issues involved?
    >
    > The man page also lists one error code only, ENOMEM. What if the user
    > doesn't exist in /etc/passwd? I'd expect getpwnam() to set errno to e.g.
    > ENOENT. Any additional info about error codes out there? :-)
    >
    > Thanks in advance.
    >

    You absolutely must not free the returned pointer. There are very few
    standard functions and system calls for which this is done, and in those
    few cases it is always explicitly stated in the standard.

    Not finding an entry is not an error. In this case, NULL is returned, but
    errno is not changed. If NULL is returned and errno is changed, it is an
    error. You should set errno to zero before the call and then test it for
    non-zero if the function returns NULL.

    All of the above is from the Single UNIX Specification, version 3. it's
    entirely possible that the Linux implementation is non-standard, but I
    would go ahead and program according to the standard.

    (It's possible for a function that returns a pointer that's not to be
    freed, as is the case here, to still generate an ENOMEM error. Perhaps it
    is allocating an internal buffer, or perhaps it allocates the storage to be
    used for the returned pointer upon the first call.)

    --Marc
    Marc Rochkind Guest

  4. #3

    Default Re: Questions about getpwnam()

    On Sat, 12 Jul 2003 15:54:12 GMT, Bjørn Augestad
    <boa@metasystems.no.spam.to.me> wrote:


    [snip]
    >
    > That's what I do now, but IMHO the caller shouldn't be required to clear
    > errno prior to a function call to detect such a common situation, and not
    > finding an entry should set errno to ENOENT just like open() sets errno
    > if a file (entry) isn't found. Not that it matters much, the standard
    > won't change, will it? :-)
    >
    I couldn't agree more. But, the phrase "should not" makes little sense when
    one is considering any of the UNIX standards... the API at this point is
    such a terrible mess, especially when it comes to error handling, that, as
    you say, there's no possiblity of any improvement, especially when
    usability is an issue. The idea that the UNIX API was usable, present in
    early UNIX systems, was dropped in the mid-1970s when the semaphore API was
    introduced.

    --Marc


    Marc Rochkind Guest

  5. #4

    Default Re: Questions about getpwnam()

    On Sat, 12 Jul 2003 09:11:53 -0600, Marc Rochkind
    <rochkind@basepath.com> wrote:
    >On Sat, 12 Jul 2003 09:01:45 GMT, Bjørn Augestad
    ><boa@metasystems.no.spam.to.me> wrote:
    >
    >> Hi,
    >>
    >> According to my Linux man page for the getpwnam() function, the function
    >> may return NULL if it failed to allocate a passwd structure. So far so
    >> good, but the man page says nothing about freeing the returned pointer.
    >> APUE, page 147, says that the "structure is usually a static variable
    >> within the function", which sounds reasonable to me, but why can the
    >> function then fail with ENOMEM? Does anyone know if the returned struct
    >> should be freed or not? Are there portability issues involved?
    >>
    >> The man page also lists one error code only, ENOMEM. What if the user
    >> doesn't exist in /etc/passwd? I'd expect getpwnam() to set errno to e.g.
    >> ENOENT. Any additional info about error codes out there? :-)
    >>
    >> Thanks in advance.
    >>
    >
    >
    >You absolutely must not free the returned pointer. There are very few
    >standard functions and system calls for which this is done, and in those
    >few cases it is always explicitly stated in the standard.
    >
    >Not finding an entry is not an error. In this case, NULL is returned, but
    >errno is not changed. If NULL is returned and errno is changed, it is an
    >error. You should set errno to zero before the call and then test it for
    >non-zero if the function returns NULL.
    >
    >All of the above is from the Single UNIX Specification, version 3. it's
    >entirely possible that the Linux implementation is non-standard,
    Unfortunately linux is indeed non-standard here. As noted already, On
    Linux "not found" results in NULL returned + errno == ENOENT. Many
    other implementations simply return NULL, and leave errno unchanged
    (as described in SUSv3), so that the above technique is the right way
    to go. However, Linux isn't alone in non-standard behaviour here --
    last I looked, AIX 5.1 gave errno == ESRCH and Irix 6.5 gave errno ==
    ENOENT (just like Linux).
    > but I
    >would go ahead and program according to the standard.
    Probably not viable in the light of the above, and the widespread use
    of Linux as a platform.

    Cheers

    Michael
    Michael Kerrisk Guest

  6. #5

    Default Re: Questions about getpwnam()

    Michael Kerrisk <michael.kerrisk@freenet.de> wrote:
    > Probably not viable in the light of the above, and the widespread use
    > of Linux as a platform.
    I'd probably set errno = ENOENT before calling getpwnam, and then if it
    returns null, it's either set errno to something plausible or left it as
    ENOENT, which is fine. A bit bodgy, but it'll do.

    -- [mdw]
    Mark Wooding Guest

  7. #6

    Default Re: Questions about getpwnam()

    >>> Bj?rn Augestad wrote:

    BrA> According to my Linux man page for the getpwnam() function, the function
    BrA> may return NULL if it failed to allocate a passwd structure. So far so
    BrA> good, but the man page says nothing about freeing the returned pointer.
    BrA> APUE, page 147, says that the "structure is usually a static variable
    BrA> within the function", which sounds reasonable to me, but why can the
    BrA> function then fail with ENOMEM?

    Even if the `struct passwd' itself is static, it contains some data
    which can be arbitrary long (pw_gecos, pw_shell, pw_home). They can be
    allocated from heap. OTOH, if getpwnam() is made thread-safe, returning
    structure is allocated dynamically for each thread.

    BrA> Does anyone know if the returned struct
    BrA> should be freed or not?

    No. In no case caller can free it. If caller wants to keep data across
    calls to getpw*(), he has to make own copy of all included data.

    BrA> Are there portability issues involved?

    Yes. First is difference between 1) traditional Unix scheme with 7 fields
    in /etc/passwd, 2) BSD scheme with master.passwd, 3) some modern unixes
    scheme with passwd and shadow files, 4) other password hash masking and
    additional information schemes (e.g. AIX one); hence, `struct passwd' may
    contains additional fields (pw_change, pw_expire, pw_class in BSD) or
    nonsense fields (pw_passwd in (2) and (3), in Linux and Solaris always,
    in BSD unless caller is root). Second is reaction for errors; getpw*()
    are allowed not to set errno when no such entry is seen (this is discussed
    here already).

    BrA> The man page also lists one error code only, ENOMEM. What if the user
    BrA> doesn't exist in /etc/passwd? I'd expect getpwnam() to set errno to e.g.
    BrA> ENOENT. Any additional info about error codes out there? :-)

    Already discussed. But one should know that almost all systems has almost
    all manuals without complete list of errors. This is true not only for
    Unix world.


    -netch-
    Valentin Nechayev Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139