Fix stat(2) related bugs introduced by changes made for Windows
authorTomohiro Kusumi <kusumi.tomohiro@gmail.com>
Wed, 27 Jul 2016 13:37:17 +0000 (22:37 +0900)
committerJens Axboe <axboe@fb.com>
Wed, 27 Jul 2016 14:29:45 +0000 (08:29 -0600)
commitd5b78f5a8fd73d21c1b84d71993c5690dbe098b5
tree30ee364cb86465970a713e03e0fedb28ceffa9c0
parent565e784df05c2529479eed8a38701a33b01894bd
Fix stat(2) related bugs introduced by changes made for Windows

Non-Windows could have regular files that start with "\\\\.\\",
so the conditionals added by ecc314ba and 3892182a in 2011-2012
introduced corner case bugs, though in reality I doubt anyone
would want to create such a file.

This commit brings back the original conditional that was there
before ecc314ba for non-Windows platforms. It also adds WIN32
guard for a change made by 3892182a.

--
 # uname
 Linux
 # cat ./test1.c
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 /* copied from fio/init.c */
 static int exists_and_not_file(const char *filename)
 {
  struct stat sb;
  if (lstat(filename, &sb) == -1)
  return 0;
  /* \\.\ is the device namespace in Windows, where every file
   * is a device node */
  if (S_ISREG(sb.st_mode) && strncmp(filename, "\\\\.\\", 4) != 0)
  return 0;
  return 1;
 }
 int main(int argc, char **argv) {
  printf("exists_and_not_file(\"%s\") = %d\n",
  argv[1], exists_and_not_file(argv[1]));
  return 0;
 }
 # gcc -Wall -g ./test1.c -o test1
 # ls /dev/sda
 /dev/sda
 # ./test1 /dev/sda
 exists_and_not_file("/dev/sda") = 1  /* the existing blkdev isn't a file */
 # touch xxxxx
 # ./test1 ./xxxxx
 exists_and_not_file("./xxxxx") = 0  /* the existing regfile is not not a file */
 # touch "\\\\.\\xxxxx"
 # ./test1 "\\\\.\\xxxxx"
 exists_and_not_file("\\.\xxxxx") = 1  /* XXX */
 # stat "\\\\.\\xxxxx" | head -2
   File: `\\\\.\\xxxxx'
   Size: 0               Blocks: 0          IO Block: 4096   regular empty file

Signed-off-by: Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
filesetup.c
init.c