1 /* Test opening a directory stream from a file descriptor. 2 Copyright (C) 2009-2021 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16 17 /* Written by Eric Blake <ebb9@byu.net>, 2009. */ 18 19 #include <config.h> 20 21 #include <dirent.h> 22 23 #include "signature.h" 24 SIGNATURE_CHECK (fdopendir, DIR *, (int)); 25 26 #include <errno.h> 27 #include <fcntl.h> 28 #include <unistd.h> 29 30 #include "macros.h" 31 32 int 33 main (_GL_UNUSED int argc, char *argv[]) /* */ 34 { 35 DIR *d; 36 int fd; 37 38 /* A non-directory cannot be turned into a directory stream. */ 39 fd = open ("test-fdopendir.tmp", O_RDONLY | O_CREAT, 0600); 40 ASSERT (0 <= fd); 41 errno = 0; 42 ASSERT (fdopendir (fd) == NULL); 43 ASSERT (errno == ENOTDIR); 44 ASSERT (close (fd) == 0); 45 ASSERT (unlink ("test-fdopendir.tmp") == 0); 46 47 /* A bad fd cannot be turned into a stream. */ 48 { 49 errno = 0; 50 ASSERT (fdopendir (-1) == NULL); 51 ASSERT (errno == EBADF); 52 } 53 { 54 close (99); 55 errno = 0; 56 ASSERT (fdopendir (99) == NULL); 57 ASSERT (errno == EBADF); 58 } 59 60 /* This should work. */ 61 fd = open (".", O_RDONLY); 62 ASSERT (0 <= fd); 63 d = fdopendir (fd); 64 ASSERT (d); 65 /* fdopendir should not close fd. */ 66 ASSERT (dup2 (fd, fd) == fd); 67 68 /* Don't test dirfd here. dirfd (d) must return fd on current POSIX 69 platforms, but on pre-2008 platforms or on non-POSIX platforms 70 dirfd (fd) might return some other descriptor, or -1, and gnulib 71 does not work around this porting problem. */ 72 73 ASSERT (closedir (d) == 0); 74 /* Now we can guarantee that fd must be closed. */ 75 errno = 0; 76 ASSERT (dup2 (fd, fd) == -1); 77 ASSERT (errno == EBADF); 78 79 return 0; 80 }