Search code examples
cubuntustat

stat() not working properly?


What am I doing wrong here, or is there something wrong with Ubuntu 12.04 (latest patches)? Generally I am writing a piece of SUID code to do a bit of this, bit of that, and for security reasons I would like to make sure the file the program targets is a regular file, not something else, most notably symlink.

visti@honecker:~/Project/Images$ ls -al
total 3080
drwxrwxr-x 2 visti visti    4096 May 29 14:18 .
drwxrwxr-x 4 visti visti    4096 May 29 14:42 ..
lrwxrwxrwx 1 visti visti      10 May 29 14:18 foo -> image-ntfs
-rw-rw-r-- 1 visti visti 3145728 May 28 16:17 image-ntfs

I have here a directory with a regular file and a symlink to the file. In my opinion stat() should be able to distinguish between these two but it isn't:

main (int argc, char **argv) {
  int i;
  struct stat buf;
  if (argc < 2) 
    exit(1);
  for (i = 1; i < argc ; i++) {
    if (stat (argv[i], &buf) == -1) {
      perror("foo");
      exit(1);
    }
    printf ("%s,%d\n", argv[i], buf.st_mode & S_IFMT);
  }
}

And when I run the compiled program against the directory, this is what I get. Both of the files have only S_IFREG set. What am I doing wrong?

visti@honecker:~/Project/Images$ ../stat *
foo,32768
image-ntfs,32768

Solution

  • You may want to use lstat() instead of stat() if you want to do stat on symbolic link itself.

    man stat has

    lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to.