Mercurial > hg > octave-nkf > gnulib-hg
view tests/test-dup3.c @ 15752:b86e9061a6d0
New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
* lib/msvc-nothrow.h: New file.
* lib/msvc-nothrow.c: New file.
* m4/msvc-nothrow.m4: New file.
* modules/msvc-nothrow: New file.
* lib/dup2.c: Include msvc-nothrow.h.
(rpl_dup2): No need to protect _get_osfhandle call here.
* lib/accept4.c: Include msvc-nothrow.h.
* lib/error.c: Likewise.
* lib/fcntl.c: Likewise.
* lib/lseek.c: Likewise.
* lib/nonblocking.c: Likewise.
* lib/poll.c: Likewise.
* lib/read.c: Likewise.
* lib/select.c: Likewise.
* lib/sockets.h: Likewise.
* lib/sockets.c: Likewise.
* lib/stdio-read.c: Likewise.
* lib/stdio-write.c: Likewise.
* lib/write.c: Likewise.
* lib/w32sock.h: Likewise.
* lib/w32spawn.h: Likewise.
* lib/flock.c: Include msvc-nothrow.h instead of <io.h>.
* lib/fsync.c: Likewise.
* lib/isapipe.c: Likewise.
* modules/dup2 (Depends-on): Add msvc-nothrow.
* modules/accept4 (Depends-on): Likewise.
* modules/error (Depends-on): Likewise.
* modules/fcntl (Depends-on): Likewise.
* modules/lseek (Depends-on): Likewise.
* modules/nonblocking (Depends-on): Likewise.
* modules/poll (Depends-on): Likewise.
* modules/read (Depends-on): Likewise.
* modules/select (Depends-on): Likewise.
* modules/sockets (Depends-on): Likewise.
* modules/sigpipe (Depends-on): Likewise.
* modules/write (Depends-on): Likewise.
* modules/accept (Depends-on): Likewise.
* modules/bind (Depends-on): Likewise.
* modules/connect (Depends-on): Likewise.
* modules/gethostname (Depends-on): Likewise.
* modules/getpeername (Depends-on): Likewise.
* modules/getsockname (Depends-on): Likewise.
* modules/getsockopt (Depends-on): Likewise.
* modules/ioctl (Depends-on): Likewise.
* modules/listen (Depends-on): Likewise.
* modules/recv (Depends-on): Likewise.
* modules/recvfrom (Depends-on): Likewise.
* modules/send (Depends-on): Likewise.
* modules/sendto (Depends-on): Likewise.
* modules/setsockopt (Depends-on): Likewise.
* modules/shutdown (Depends-on): Likewise.
* modules/socket (Depends-on): Likewise.
* modules/execute (Depends-on): Likewise.
* modules/spawn-pipe (Depends-on): Likewise.
* modules/flock (Depends-on): Likewise.
* modules/fsync (Depends-on): Likewise.
* modules/isapipe (Depends-on): Likewise.
* tests/test-cloexec.c: Include msvc-nothrow.h.
* tests/test-dup-safer.c: Likewise.
* tests/test-dup2.c: Likewise.
* tests/test-dup3.c: Likewise.
* tests/test-fcntl.c: Likewise.
* tests/test-pipe.c: Likewise.
* tests/test-pipe2.c: Likewise.
* modules/cloexec-tests (Depends-on): Add msvc-nothrow.
* modules/unistd-safer-tests (Depends-on): Likewise.
* modules/dup2-tests (Depends-on): Likewise.
* modules/dup3-tests (Depends-on): Likewise.
* modules/fcntl-tests (Depends-on): Likewise.
* modules/pipe-posix-tests (Depends-on): Likewise.
* modules/pipe2-tests (Depends-on): Likewise.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Fri, 23 Sep 2011 21:38:44 +0200 |
parents | 97fc9a21a8fb |
children | 8250f2777afc |
line wrap: on
line source
/* Test duplicating file descriptors. Copyright (C) 2009-2011 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 <http://www.gnu.org/licenses/>. */ /* Written by Eric Blake <ebb9@byu.net>, 2009, and Bruno Haible <bruno@clisp.org>, 2009. */ #include <config.h> #include <unistd.h> #include "signature.h" SIGNATURE_CHECK (dup3, int, (int, int, int)); #include <errno.h> #include <fcntl.h> #include <stdbool.h> #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* Get declarations of the Win32 API functions. */ # define WIN32_LEAN_AND_MEAN # include <windows.h> /* Get _get_osfhandle. */ # include "msvc-nothrow.h" #endif #include "binary-io.h" #include "macros.h" /* Return true if FD is open. */ static bool is_open (int fd) { #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* On Win32, the initial state of unassigned standard file descriptors is that they are open but point to an INVALID_HANDLE_VALUE, and there is no fcntl. */ return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE; #else # ifndef F_GETFL # error Please port fcntl to your platform # endif return 0 <= fcntl (fd, F_GETFL); #endif } /* Return true if FD is not inherited to child processes. */ static bool is_cloexec (int fd) { #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ HANDLE h = (HANDLE) _get_osfhandle (fd); DWORD flags; ASSERT (GetHandleInformation (h, &flags)); return (flags & HANDLE_FLAG_INHERIT) == 0; #else int flags; ASSERT ((flags = fcntl (fd, F_GETFD)) >= 0); return (flags & FD_CLOEXEC) != 0; #endif } int main () { int use_cloexec; #if O_CLOEXEC for (use_cloexec = 0; use_cloexec <= 1; use_cloexec++) #else use_cloexec = 0; #endif { const char *file = "test-dup3.tmp"; int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600); int o_flags; char buffer[1]; o_flags = 0; #if O_CLOEXEC if (use_cloexec) o_flags |= O_CLOEXEC; #endif /* Assume std descriptors were provided by invoker. */ ASSERT (STDERR_FILENO < fd); ASSERT (is_open (fd)); /* Ignore any other fd's leaked into this process. */ close (fd + 1); close (fd + 2); ASSERT (!is_open (fd + 1)); ASSERT (!is_open (fd + 2)); /* Assigning to self is invalid. */ errno = 0; ASSERT (dup3 (fd, fd, o_flags) == -1); ASSERT (errno == EINVAL); ASSERT (is_open (fd)); /* If the source is not open, then the destination is unaffected. */ errno = 0; ASSERT (dup3 (fd + 1, fd + 2, o_flags) == -1); ASSERT (errno == EBADF); ASSERT (!is_open (fd + 2)); errno = 0; ASSERT (dup3 (fd + 1, fd, o_flags) == -1); ASSERT (errno == EBADF); ASSERT (is_open (fd)); /* The destination must be valid. */ errno = 0; ASSERT (dup3 (fd, -2, o_flags) == -1); ASSERT (errno == EBADF); errno = 0; ASSERT (dup3 (fd, 10000000, o_flags) == -1); ASSERT (errno == EBADF); /* Using dup3 can skip fds. */ ASSERT (dup3 (fd, fd + 2, o_flags) == fd + 2); ASSERT (is_open (fd)); ASSERT (!is_open (fd + 1)); ASSERT (is_open (fd + 2)); if (use_cloexec) ASSERT (is_cloexec (fd + 2)); else ASSERT (!is_cloexec (fd + 2)); /* Verify that dup3 closes the previous occupant of a fd. */ ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1); ASSERT (dup3 (fd + 1, fd, o_flags) == fd); ASSERT (close (fd + 1) == 0); ASSERT (write (fd, "1", 1) == 1); ASSERT (dup3 (fd + 2, fd, o_flags) == fd); ASSERT (lseek (fd, 0, SEEK_END) == 0); ASSERT (write (fd + 2, "2", 1) == 1); ASSERT (lseek (fd, 0, SEEK_SET) == 0); ASSERT (read (fd, buffer, 1) == 1); ASSERT (*buffer == '2'); /* Clean up. */ ASSERT (close (fd + 2) == 0); ASSERT (close (fd) == 0); ASSERT (unlink (file) == 0); } return 0; }