diff --git a/lib/std/io/os/fileinfo.c3 b/lib/std/io/os/fileinfo.c3 index ebddfb1e8..afde1aab9 100644 --- a/lib/std/io/os/fileinfo.c3 +++ b/lib/std/io/os/fileinfo.c3 @@ -95,7 +95,7 @@ fn bool native_is_file(String path) $case env::DARWIN: $case env::LINUX: Stat stat; - return @ok(native_stat(&stat, path)) && stat.st_mode & libc::S_IFREG; + return @ok(native_stat(&stat, path)) && libc_S_ISTYPE(stat.st_mode, libc::S_IFREG); $default: File! f = file::open(path, "r"); defer (void)f.close(); @@ -107,7 +107,7 @@ fn bool native_is_dir(String path) { $if env::DARWIN || env::LINUX: Stat stat; - return @ok(native_stat(&stat, path)) && stat.st_mode & libc::S_IFDIR; + return @ok(native_stat(&stat, path)) && libc_S_ISTYPE(stat.st_mode, libc::S_IFDIR); $else return native_file_or_dir_exists(path) && !native_is_file(path); $endif diff --git a/lib/std/libc/libc.c3 b/lib/std/libc/libc.c3 index bf7c65eba..7f9803394 100644 --- a/lib/std/libc/libc.c3 +++ b/lib/std/libc/libc.c3 @@ -360,6 +360,7 @@ const int EOF = -1; const int FOPEN_MAX = 20; const int FILENAME_MAX = 1024; +macro bool libc_S_ISTYPE(value, mask) @builtin => (value & S_IFMT) == mask; const S_IFMT = 0o170000; // type of file mask const S_IFIFO = 0o010000; // named pipe (fifo) const S_IFCHR = 0o020000; // character special diff --git a/test/unit/stdlib/io/fileinfo.c3 b/test/unit/stdlib/io/fileinfo.c3 new file mode 100644 index 000000000..b682f6ab6 --- /dev/null +++ b/test/unit/stdlib/io/fileinfo.c3 @@ -0,0 +1,16 @@ +module std::io::fileinfo @test; +import std::io::os; + +fn void test_native_is_file() @if(env::LINUX || env::DARWIN) +{ + assert(!os::native_is_file("/dev/loop0")); + assert(!os::native_is_file("/dev/null")); +} + +fn void test_native_is_dir() @if(env::LINUX || env::DARWIN) +{ + assert(os::native_is_dir("/")); + assert(!os::native_is_file("/")); + assert(!os::native_is_dir("/dev/loop0")); + assert(!os::native_is_dir("/dev/null")); +} \ No newline at end of file