views:

318

answers:

3

hi I'm trying to understand system calls: directories and files on unix, .. I found this website where they explain some calls with their own examples, but do not understand these code snippets ..

    void state (char *file) 
    {
    struct stat    buf;
    struct passwd *pw;
    struct group  *gr;
    int i;

    if (stat(file, &buf)==-1)
    {
    perror(file);
    exit(-1);
    }

    printf ("file: %s\n", archivo);
    printf ("\t resides in the device: %d, %d\n",(buf.st_dev & 0xFF00)>>8,            buf.st_dev   &   0x00FF);
    printf ("\t  i-node number: %d\n", buf.st_ino);
    printf ("\t type: ");
    switch (buf.st_mode & S_IFMT)
    {
    case S_IFREG: printf ("ordinario\n");     break;
    case S_IFDIR: printf ("directorio\n");    break;
    case S_IFCHR: printf ("tipo caracter\n"); break;
    case S_IFBLK: printf ("tipo bloque\n");   break;
    case S_IFIFO: printf ("FIFO\n");          break;
    }

  if (buf.st_mode & S_ISUID) printf ("\tSUID activo");
  if (buf.st_mode & S_ISGID) printf ("\tSGID activo");
  if (buf.st_mode & S_ISVTX) printf ("\tStiky bit activo\n");

  /* Permissions access */
  printf ("\tPermission: 0%o ",buf.st_mode & 0777);
  for (i=0; i<9; i++)
      if (buf.st_mode & (0400>>i)) printf ("%c", permisos[(8-i)%3]);
      else  printf ("-"); ....

I do not understand the comparison to find out which device file is missing .. someone could help me understand? specifically here ..

printf ("\tReside en el dispositivo: %d, %d\n", (buf.st_dev & 0xFF00)>>8,
buf.st_dev & 0x00FF);



/* Permissions */
  printf ("\tPermission: 0%o ",buf.st_mode & 0777);
  for (i=0; i<9; i++)
      if (buf.st_mode & (0400>>i)) printf ("%c", permisos[(8-i)%3]);
      else  printf ("-");

would welcome any help or explanation of the comparisons that are made on both sides PD: sorry for my english =P

link where it appears the entire code example 1 called estado.c

http://translate.googleusercontent.com/translate_c?hl=es&amp;ie=UTF-8&amp;sl=es&amp;tl=en&amp;u=http://malicia.super.unam.mx/wiki/index.php/Llamadas%5Fal%5FSistema%3A%5FDirectorios%5Fy%5FArchivos&amp;prev=%5Ft&amp;rurl=translate.google.co.ve&amp;twu=1&amp;usg=ALkJrhhwwFSx-UiPs4rtgSJADbrZy13v7A

+2  A: 

I'm assuming you mean this:

(buf.st_dev & 0xFF00)>>8

That isn't a comparison. >> is the right-shift operator. It shifts the first operand to the right by the number of bits specified by the second operand. This expression is zeroing all but the 9th through 16th bits of buf.st_dev (That's what & 0xFF00 does) and then shifting the resulting 8 bits down to the 1st through 8th least-significant bits. This will result in a number from 0 to 255.

Laurence Gonsalves
A: 

(buf.st_dev & 0xFF00)>>8, buf.st_dev & 0x00FF are not comparisons but arithmetic expressions:

& performs a bitwise binary AND of the operands:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

>> performs a bitwise shift

Using & is a common way to "mask" bits out of another value so they can be inspected in isolation. In the first expression, the eight bits in positions 8 through 15 are isolated and shifted to be in positions 0 through 7, so it's as though the second-to-least significant byte is displayed as a standalone byte.

The second expression doesn't do the shift because after masking it is already in the lowest bit position, and so makes sense directly.

wallyk
A: 

We are trying to access the stat struscture used for commands such as stat and lstat here:

struct stat {
     dev_t     st_dev;     /* ID of device containing file */
     ino_t     st_ino;     /* inode number */
     mode_t    st_mode;    /* protection */
     nlink_t   st_nlink;   /* number of hard links */
     uid_t     st_uid;     /* user ID of owner */
     gid_t     st_gid;     /* group ID of owner */
     dev_t     st_rdev;    /* device ID (if special file) */
     off_t     st_size;    /* total size, in bytes */
     blksize_t st_blksize; /* blocksize for file system I/O */
     blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
     time_t    st_atime;   /* time of last access */
     time_t    st_mtime;   /* time of last modification */
     time_t    st_ctime;   /* time of last status change */
 };

for the line:

buf.st_mode & (0400>>i)

I think they are trying to extract the permissions of the file which is bits 5-16 in the st_mode member of the above structure.

I think we can also extract the info using the macro S_IFMT:

file_type = statbuf.st_mode&S_IFMT;  // for bits 1-4
file_perm = statbuf.st_mode&~S_IFMT  // for bits 5-16

I think the developer is doin the samethin manually in your snippet and displaying rwx or a - , I suppse.

As for the st_dev part of the code:

I have never really tried to manipulate that member variable, so I cant really say wat the member does. The best way to find out is look at its definition in sys/types.h . As for the reason of the usage is same as what Laurence Gonsalves is trying to explain.

All I see from the man pages is the following line: "The st_ino and st_dev fields taken together uniquely identify the file within the system."

Hope this info helped u.

tomkaith13