From: Tomohiro Kusumi Date: Wed, 27 Jul 2016 13:37:17 +0000 (+0900) Subject: Fix stat(2) related bugs introduced by changes made for Windows X-Git-Tag: fio-2.14~82 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=d5b78f5a8fd73d21c1b84d71993c5690dbe098b5 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 #include #include #include /* 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 Signed-off-by: Jens Axboe --- diff --git a/filesetup.c b/filesetup.c index d208a69e..a48faf58 100644 --- a/filesetup.c +++ b/filesetup.c @@ -1225,10 +1225,12 @@ static void get_file_type(struct fio_file *f) else f->filetype = FIO_TYPE_FILE; +#ifdef WIN32 /* \\.\ is the device namespace in Windows, where every file is * a block device */ if (strncmp(f->file_name, "\\\\.\\", 4) == 0) f->filetype = FIO_TYPE_BD; +#endif if (!stat(f->file_name, &sb)) { if (S_ISBLK(sb.st_mode)) diff --git a/init.c b/init.c index 47519bf0..82b21c78 100644 --- a/init.c +++ b/init.c @@ -911,10 +911,15 @@ static int exists_and_not_file(const char *filename) if (lstat(filename, &sb) == -1) return 0; +#ifndef WIN32 /* NOT Windows */ + if (S_ISREG(sb.st_mode)) + return 0; +#else /* \\.\ 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; +#endif return 1; }