/* Test opening a directory stream from a file descriptor. Copyright (C) 2009-2024 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Written by Eric Blake , 2009. */ #include #include #include "signature.h" SIGNATURE_CHECK (fdopendir, DIR *, (int)); #include #include #include #include "macros.h" int main () { DIR *d; int fd; /* A non-directory cannot be turned into a directory stream. */ fd = open ("test-fdopendir.tmp", O_RDONLY | O_CREAT, 0600); ASSERT (0 <= fd); errno = 0; ASSERT (fdopendir (fd) == NULL); ASSERT (errno == ENOTDIR); ASSERT (close (fd) == 0); ASSERT (unlink ("test-fdopendir.tmp") == 0); /* A bad fd cannot be turned into a stream. */ { errno = 0; ASSERT (fdopendir (-1) == NULL); ASSERT (errno == EBADF); } { close (99); errno = 0; ASSERT (fdopendir (99) == NULL); ASSERT (errno == EBADF); } #ifdef AT_FDCWD { errno = 0; ASSERT (fdopendir (AT_FDCWD) == NULL); ASSERT (errno == EBADF); } #endif /* This should work. */ fd = open (".", O_RDONLY); ASSERT (0 <= fd); d = fdopendir (fd); ASSERT (d); /* fdopendir should not close fd. */ ASSERT (dup2 (fd, fd) == fd); /* Don't test dirfd here. dirfd (d) must return fd on current POSIX platforms, but on pre-2008 platforms or on non-POSIX platforms dirfd (fd) might return some other descriptor, or -1, and gnulib does not work around this porting problem. */ ASSERT (closedir (d) == 0); /* Now we can guarantee that fd must be closed. */ errno = 0; ASSERT (dup2 (fd, fd) == -1); ASSERT (errno == EBADF); return test_exit_status; }