From: pat@rwing.UUCP (Pat Myrto)
Newsgroups: comp.lang.c
Subject: Re: Unix System calls
Date: 12 Dec 92 05:00:14 GMT
Organization: Totally Unorganized

In article <Dec.8.02.02.25.1992.429@clam.rutgers.edu> dalessan@clam.rutgers.edu (Gene) writes:
>
> [ ... synopsis, etc deleted ... ]
>
>I began writing a program to call stat inorder to get to a few
>values that I'm interested in comcerning different files. ie
>file serial number,last modify time,blocks allocated etc.
>Anyhow I wrote a little test prog to see how easy it would
>be(I figured very easy), but I seem to have hit a snag. Here's
>what I got:
>
>#include <stdio.h>
>#include <sys/types.h>
>#include <sys/stat.h>
>
>main (argc,argv)
>int argc;
>char *argv[];
>{
>struct stat *info; <--- only size of ptr var is allocated, not a structure.
>off_t   bytes;
>
>stat(argv[1],&info);
>}              \_____  uninitialized ptr var plus wrong indirection level...

The problem is you are using the pointer variable before its initialized
to a meaningful value AND you are passing the ADDRESS of the pointer variable to
stat(), so stat gets struct stat **info, pointing to unknown location.
You should remove the '*' from the declaration so a full stat structure
sized area is allocated, OR allocate the structure as another name, like
statb, and then set info to the address of stat struct statb (handy if
the same stat() call gets made with different stat structs, where the
program sets the pointer variable (struct stat *info) to a different
structure on each call.  This is useful for cases where one doesn't know
till runtime what particular stat structure is used in the call (such
as where several structs are passed, and then compared, etc).

Following are examples how I would call using both a pointer variable
and using the address-of operator ('&') in the stat() call.

Also, just to be complete, I will mention that one should test the return
value of the stat() syscall to be sure it succeeds, otherwise the data
is meaningless (if stat() returns zero it is a successful call).

============================ EXAMPLES ===============================
/* passing address of stat buffer directly */

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

main(argc, argv)
int argc;
char *argv[];
{
    struct stat info;     /* causes space for a stat STRUCT to be allocated */
                          /* instead of an unitialized pointer variable */
    off_t bytes;

    stat(argv[1], &info); /* pass stat the ADDRESS of the stat struct */
                          /* stat syscall fills it in */
    bytes = info.st_size; /* set bytes to the size returned */
                          /* note if one is not going to use it other ways */
                          /* one could simply access the element itself in */
                          /* following expression(s) instead of the variable */
    printf("Size is: %d\n", bytes);     /* or whatever */
    exit(0);              /* define exit value */
}

=================== OR, USING POINTER VARIABLE =========================
/* passing addr of statbuf via use of a pointer variable  and testing
 * whether stat() call succeeded or not.
 */

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

void die();                       /* something to do if stat() call fails */

main(argc, argv)
int argc;
char *argv[];
{
    struct stat statb;            /* allocate a stat structure */
    struct stat *info = &statb    /* inits ptr variable with addr of statb */

                                  /* example of testing success of stat() */
    if(stat(argv[1], info) != 0)  /* like above, but using pointer variable */
        die("stat failed!\n");    /* function to print msg and exit program */

    printf("Size is: %d\n", info->st_size);    /* or whatever */
    exit(0);                      /* define exit value */
}

void
die(s)
char *s;
{
    fprintf(stderr, "ERROR: %s", s);   /* complain */
    exit(1);                      /* non-zero value for problem exit */
}
============================== END OF EXAMPLES ========================

>Every time I try to print a value (info->st_ino) or something
>I get a segmentation fault(I really hate them). Info is a ptr
>to a stat structure into which infomation is placed concerning

Until it is initialized, it points to <undefined>.  See examples above...

>a file.  Any idea on how to assign desired fields to vars.
>This was a little test prog. It works as is, but when you try
>to access a field -- seg fault.

That is because the field you are trying to address is evaluated
as a location outside your allocated memory space (info being some
random value, which is regarded as a memory address).

Hope this helps, and isn't TOO verbose.... I got nailed on similar stuff
when I first tried some coding in C ...

-- 
pat@rwing.uucp                                  (Pat Myrto),  Seattle, WA
                      If all else fails, try:
         ...!uunet!{pilchuck, polari}!rwing!pat
WISDOM:    "Travelling unarmed is like boating without a life jacket" 
Newsgroups: comp.lang.c