code review: read in ps(1) result

Discussion in 'C Programming' started by lovecreatesbea...@gmail.com, Jul 16, 2010.

  1. Guest

    /*thank you for your time*/

    /*read in ps(1) result*/

    #include <stdio.h>
    #include <errno.h>
    #include <sys/types.h>

    #define M 256
    #define N 32

    #define str(n) #n /*from pete's*/
    #define xstr(n) str(n)

    int main(void)
    {
    char uid[N + 1];
    pid_t pid;
    pid_t ppid;
    char stime[N + 1];
    char cmd[M + 1];
    char *ps = "ps -ef";
    FILE *fp;
    int errnum;
    int n;

    errno = 0;
    if (!(fp = popen(ps, "r"))){
    errnum = errno;
    fprintf(stderr, "%s\n", strerror(errnum));
    return 1;
    }
    errno = 0;
    while((n = fscanf(fp, "%"xstr(N)"s %d %d %*s "
    "%"xstr(N)"s %*s %*s %"xstr(M)"[^\n]",
    uid, &pid, &ppid, stime, cmd)) != EOF){
    if (n != 5){
    fscanf(fp, "%*[^\n]");
    continue;
    }
    fprintf(stdout, "%s, %d, %d, %s, %s\n",
    uid, (int)pid, (int)ppid, stime, cmd);
    errno = 0;
    }
    errnum = errno;
    if (errnum)
    fprintf(stderr, "%s\n", strerror(errnum));
    pclose(fp);
    return 0
    }
     
    , Jul 16, 2010
    #1
    1. Advertising

  2. ha scritto:

    > #include<stdio.h>
    > #include<errno.h>
    > #include<sys/types.h>
    > fprintf(stderr, "%s\n", strerror(errnum));


    you should #include <string.h>, this header
    contains the strerror's prototype

    > return 0


    and append a semicolon ";" to this line


    --
    Vincenzo Mercuri
     
    Vincenzo Mercuri, Jul 16, 2010
    #2
    1. Advertising

  3. Eric Sosman Guest

    On 7/16/2010 8:44 AM, wrote:
    > [...]
    > errno = 0;
    > [...]
    > errnum = errno;
    > if (errnum)
    > fprintf(stderr, "%s\n", strerror(errnum));


    No. Except as specifically documented (e.g., for strtod()),
    any library function can set `errno' to a non-zero value, even
    if no error occurs. Thus, finding `errno != 0' does not mean
    there has been an error. Also, only a few library functions are
    obliged to set `errno' when an error occurs -- for example, a
    failing fopen() is not required to set it -- so `errno == 0' does
    not imply the absence of errors. You have to detect success/failure
    by other means, and then (perhaps) consult `errno' for further
    information about a failure.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Jul 16, 2010
    #3
  4. Eric Sosman <> writes:
    > On 7/16/2010 8:44 AM, wrote:
    >> [...]
    >> errno = 0;
    >> [...]
    >> errnum = errno;
    >> if (errnum)
    >> fprintf(stderr, "%s\n", strerror(errnum));

    >
    > No. Except as specifically documented (e.g., for strtod()),
    > any library function can set `errno' to a non-zero value, even
    > if no error occurs. Thus, finding `errno != 0' does not mean
    > there has been an error. Also, only a few library functions are
    > obliged to set `errno' when an error occurs -- for example, a
    > failing fopen() is not required to set it -- so `errno == 0' does
    > not imply the absence of errors. You have to detect success/failure
    > by other means, and then (perhaps) consult `errno' for further
    > information about a failure.


    To expand on that a bit, some secondary standards may specify that
    certain standard C functions must set errno on failure. For example,
    POSIX requires fopen() to set errno to one of several values (none
    of which are defined by the C standard). And I don't know of any
    C implementations, POSIX or otherwise, in which fopen() *doesn't*
    set errno to some sensible value on failure (but my experience
    is sufficiently limited that I probably wouldn't know about them
    anyway).

    If you're only concerned with POSIX-compliant systems, you can assume
    that the value of errno is meaningful after a call to fopen() --
    but *only* if you set errno to 0 before the call *and* fopen()
    reported failure by returning a null pointer (otherwise errno
    could be set to some spurious value, either by previous code or by
    something called internally by fopen().

    For non-POSIX systems, you can *probably* assume that errno is
    meaningful under the above circumstances (and perror() and/or
    strerror() will give you a useful message), but that's not at all
    guaranteed by the C standard.

    Note that the only errno values specified by the C standard itself
    are 0, EDOM, EILSEQ, and ERANGE. Anything beyond that is left to
    secondary standards and to individual implementations.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jul 16, 2010
    #4
  5. Ben Pfaff Guest

    Keith Thompson <> writes:

    > To expand on that a bit, some secondary standards may specify that
    > certain standard C functions must set errno on failure. For example,
    > POSIX requires fopen() to set errno to one of several values (none
    > of which are defined by the C standard). And I don't know of any
    > C implementations, POSIX or otherwise, in which fopen() *doesn't*
    > set errno to some sensible value on failure (but my experience
    > is sufficiently limited that I probably wouldn't know about them
    > anyway).


    malloc() may be a better example. POSIX requires malloc() to set
    errno to ENOMEM on failure, if memory is not available. But a
    lot of non-POSIX implementations in fact do not do this (and
    ENOMEM is not defined by ISO C).
    --
    Ben Pfaff
    http://benpfaff.org
     
    Ben Pfaff, Jul 16, 2010
    #5
  6. Nobody Guest

    On Fri, 16 Jul 2010 12:30:03 -0700, Keith Thompson wrote:

    > Note that the only errno values specified by the C standard itself
    > are 0, EDOM, EILSEQ, and ERANGE. Anything beyond that is left to
    > secondary standards and to individual implementations.


    That should provide a clue as to which functions are required (by the C
    standard) to set errno under some circumstances (hint: not many of them).

    errno is basically a POSIX feature which managed to leak into the C
    standards. POSIX itself defines 81 possible non-zero values for errno,
    while Linux currently defines 129 (1 through 131, with 41 and 58 unused).

    http://www.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
     
    Nobody, Jul 16, 2010
    #6
  7. Guest

    Keith Thompson <> wrote:
    >
    > And I don't know of any
    > C implementations, POSIX or otherwise, in which fopen() *doesn't*
    > set errno to some sensible value on failure


    Traditional Unix implementations didn't explicitly set errno but most
    fopen() failures are caused by the failure of an underlying system call
    which does, so it works in most cases. But not all: there were some
    obscure failure modes that left errno set to a nonsensical value.
    --
    Larry Jones

    Any game without push-ups, hits, burns or noogies is a sissy game. -- Calvin
     
    , Jul 27, 2010
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. www
    Replies:
    51
    Views:
    1,485
  2. J.Ram
    Replies:
    7
    Views:
    654
  3. Pavel
    Replies:
    7
    Views:
    535
    Pavel
    Sep 19, 2010
  4. Lakshmi Sreekanth

    i = 10; result = ++i - --i; How result become ZERO

    Lakshmi Sreekanth, Sep 21, 2010, in forum: C Programming
    Replies:
    52
    Views:
    1,186
    Nick Keighley
    Sep 23, 2010
  5. Michael Tan
    Replies:
    32
    Views:
    991
    Ara.T.Howard
    Jul 21, 2005
Loading...

Share This Page