diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index b22c3e40c..438de2dde 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,51 @@ +2010-01-14 Corinna Vinschen + + * cygwin.din (dup3): Export. + (pipe2): Export. + * dtable.cc (dtable::dup_worker): Take additional flags parameter. + Handle O_CLOEXEC flag. + (dtable::dup3): Rename from dup2. Take additional flags parameter. + Check for valid flags. Drop check for newfd == oldfd. + * dtable.h (dtable::dup_worker): Add flags parameter. + (dtable::dup3): Rename from dup2. + * fcntl.cc (fcntl64): Add F_DUPFD_CLOEXEC case. + * fhandler.h (fhandler_mailslot::get_object_attr): Add flags parameter. + * fhandler.cc (fhandler_base::open): Use security attribute with + inheritance according to setting of O_CLOEXEC flag. + * fhandler_console.cc (fhandler_console::open): Ditto. + * fhandler_fifo.cc (sec_user_cloexec): New inline function to + create security attribute with inheritance according to setting of + O_CLOEXEC flag. + (fhandler_fifo::open): Call sec_user_cloexec to fetch security + attribute. + (fhandler_fifo::wait): Ditto. + * fhandler_mem.cc (fhandler_dev_mem::open): Ditto. + * fhandler_mailslot.cc (fhandler_mailslot::get_object_attr): Take + additional flags parameter. Use security attribute with inheritance + according to setting of O_CLOEXEC flag. + (fhandler_mailslot::open): Call get_object_attr with flags parameter. + * fhandler_registry.cc (fhandler_registry::open): Call set_close_on_exec + on real handles to accommodate O_CLOEXEC flag. + * fhandler_tty.cc (fhandler_tty_slave::open): Ditto. + * fhandler_tape.cc: Create mutex with inheritance according to setting + of O_CLOEXEC flag. + * pipe.cc: Replace usage of O_NOINHERIT with O_CLOEXEC. + (fhandler_pipe::init): Simplify setting close_on_exec flag. + (fhandler_pipe::open): Remove setting close_on_exec flag. + (fhandler_pipe::create): Use security attribute with inheritance + according to setting of O_CLOEXEC flag. + (pipe2): New exported function. + * posix_ipc.cc: Throughout, open backing files with O_CLOEXEC + flag to follow POSIX semantics. + * security.h (sec_none_cloexec): New define. + * syscalls.cc (dup): Add missing extern "C" qualifier. Accommodate + renaming of dtable::dup2 to dtable::dup3. + (dup2): Ditto. Check newfd == oldfd here. + (dup3): New function. Check newfd == oldfd here. + (open): Set close_on_exec flag according to O_CLOEXEC flag before + calling fhandler->open. + * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. + 2010-01-13 Corinna Vinschen * include/fcntl.h (O_TTY_INIT): Define as 0. diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 74c487946..ec485236c 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -297,6 +297,7 @@ dup SIGFE _dup = dup SIGFE dup2 SIGFE _dup2 = dup2 SIGFE +dup3 SIGFE eaccess = euidaccess SIGFE ecvt SIGFE _ecvt = ecvt SIGFE @@ -1071,6 +1072,7 @@ perror SIGFE _perror = perror SIGFE pipe SIGFE _pipe SIGFE +pipe2 SIGFE poll SIGFE _poll = poll SIGFE popen SIGFE diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index ec5d3e386..f0738adc2 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -559,7 +559,7 @@ build_fh_pc (path_conv& pc, bool set_name) } fhandler_base * -dtable::dup_worker (fhandler_base *oldfh) +dtable::dup_worker (fhandler_base *oldfh, int flags) { /* Don't call set_name in build_fh_pc. It will be called in fhandler_base::operator= below. Calling it twice will result @@ -579,7 +579,11 @@ dtable::dup_worker (fhandler_base *oldfh) } else { - newfh->close_on_exec (false); + /* The O_CLOEXEC flag enforces close-on-exec behaviour. */ + if (flags & O_CLOEXEC) + newfh->set_close_on_exec (true); + else + newfh->close_on_exec (false); debug_printf ("duped '%s' old %p, new %p", oldfh->get_name (), oldfh->get_io_handle (), newfh->get_io_handle ()); } } @@ -587,13 +591,13 @@ dtable::dup_worker (fhandler_base *oldfh) } int -dtable::dup2 (int oldfd, int newfd) +dtable::dup3 (int oldfd, int newfd, int flags) { int res = -1; fhandler_base *newfh = NULL; // = NULL to avoid an incorrect warning MALLOC_CHECK; - debug_printf ("dup2 (%d, %d)", oldfd, newfd); + debug_printf ("dup3 (%d, %d, %p)", oldfd, newfd, flags); lock (); if (not_open (oldfd)) @@ -602,21 +606,20 @@ dtable::dup2 (int oldfd, int newfd) set_errno (EBADF); goto done; } - if (newfd < 0) { syscall_printf ("new fd out of bounds: %d", newfd); set_errno (EBADF); goto done; } - - if (newfd == oldfd) + if ((flags & ~O_CLOEXEC) != 0) { - res = newfd; - goto done; + syscall_printf ("invalid flags value %x", flags); + set_errno (EINVAL); + return -1; } - if ((newfh = dup_worker (fds[oldfd])) == NULL) + if ((newfh = dup_worker (fds[oldfd], flags)) == NULL) { res = -1; goto done; @@ -644,7 +647,7 @@ dtable::dup2 (int oldfd, int newfd) done: MALLOC_CHECK; unlock (); - syscall_printf ("%d = dup2 (%d, %d)", res, oldfd, newfd); + syscall_printf ("%d = dup3 (%d, %d, %p)", res, oldfd, newfd, flags); return res; } diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h index 1eedd7695..e3aa2625b 100644 --- a/winsup/cygwin/dtable.h +++ b/winsup/cygwin/dtable.h @@ -51,7 +51,7 @@ public: int vfork_child_dup (); void vfork_parent_restore (); void vfork_child_fixup (); - fhandler_base *dup_worker (fhandler_base *oldfh); + fhandler_base *dup_worker (fhandler_base *oldfh, int flags); int extend (int howmuch); void fixup_after_fork (HANDLE); inline int not_open (int fd) @@ -65,7 +65,7 @@ public: int find_unused_handle () { return find_unused_handle (first_fd_for_open);} void release (int fd); void init_std_file_from_handle (int fd, HANDLE handle); - int dup2 (int oldfd, int newfd); + int dup3 (int oldfd, int newfd, int flags); void fixup_after_exec (); inline fhandler_base *&operator [](int fd) const { return fds[fd]; } bool select_read (int fd, select_stuff *); diff --git a/winsup/cygwin/fcntl.cc b/winsup/cygwin/fcntl.cc index 78ce36569..de13f10bf 100644 --- a/winsup/cygwin/fcntl.cc +++ b/winsup/cygwin/fcntl.cc @@ -1,7 +1,7 @@ /* fcntl.cc: fcntl syscall Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2008, - 2009 Red Hat, Inc. + 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -41,8 +41,10 @@ fcntl64 (int fd, int cmd, ...) switch (cmd) { case F_DUPFD: + case F_DUPFD_CLOEXEC: if ((int) arg >= 0 && (int) arg < OPEN_MAX_MAX) - res = dup2 (fd, cygheap_fdnew (((int) arg) - 1)); + res = dup3 (fd, cygheap_fdnew (((int) arg) - 1), + cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0); else { set_errno (EINVAL); diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 57fcb8610..26a3ad8ee 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1,7 +1,7 @@ /* fhandler.cc. See console.cc for fhandler_console functions. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009 Red Hat, Inc. + 2005, 2006, 2007, 2008, 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -469,7 +469,7 @@ fhandler_base::open (int flags, mode_t mode) syscall_printf ("(%S, %p)", pc.get_nt_native_path (), flags); - pc.get_object_attr (attr, sec_none); + pc.get_object_attr (attr, *sec_none_cloexec (flags)); switch (query_open ()) { diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 60fe5fbf4..11162cbf1 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -399,7 +399,7 @@ class fhandler_base class fhandler_mailslot : public fhandler_base { - POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &, PUNICODE_STRING); + POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &, PUNICODE_STRING, int); public: fhandler_mailslot (); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 6cfbcf638..7a11fd22f 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -1,7 +1,7 @@ /* fhandler_console.cc Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2008, 2009 Red Hat, Inc. + 2006, 2008, 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -705,7 +705,7 @@ fhandler_console::open (int flags, mode_t) /* Open the input handle as handle_ */ h = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, &sec_none, + FILE_SHARE_READ | FILE_SHARE_WRITE, sec_none_cloexec (flags), OPEN_EXISTING, 0, 0); if (h == INVALID_HANDLE_VALUE) @@ -717,7 +717,7 @@ fhandler_console::open (int flags, mode_t) uninterruptible_io (true); // Handled explicitly in read code h = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, &sec_none, + FILE_SHARE_READ | FILE_SHARE_WRITE, sec_none_cloexec (flags), OPEN_EXISTING, 0, 0); if (h == INVALID_HANDLE_VALUE) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 81519ff72..d24c73143 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -1,6 +1,6 @@ /* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes. - Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Red Hat, Inc. + Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -70,6 +70,11 @@ fhandler_fifo::fifo_name (char *buf) PIPE_UNLIMITED_INSTANCES, (s), (s), \ NMPWAIT_WAIT_FOREVER, sa_buf) +inline PSECURITY_ATTRIBUTES +sec_user_cloexec (bool cloexec, PSECURITY_ATTRIBUTES sa, PSID sid) +{ + return cloexec ? sec_user_nih (sa, sid) : sec_user (sa, sid); +} int fhandler_fifo::open (int flags, mode_t) @@ -94,7 +99,8 @@ fhandler_fifo::open (int flags, mode_t) { char char_sa_buf[1024]; LPSECURITY_ATTRIBUTES sa_buf = - sec_user ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid()); + sec_user_cloexec (flags & O_CLOEXEC, (PSECURITY_ATTRIBUTES) char_sa_buf, + cygheap->user.sid()); bool do_seterrno = true; HANDLE h; @@ -205,7 +211,9 @@ fhandler_fifo::wait (bool iswrite) fifo_name (npname); char char_sa_buf[1024]; LPSECURITY_ATTRIBUTES sa_buf; - sa_buf = sec_user ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid()); + sa_buf = sec_user_cloexec (close_on_exec (), + (PSECURITY_ATTRIBUTES) char_sa_buf, + cygheap->user.sid()); while (1) { if (WaitNamedPipe (npname, 10)) diff --git a/winsup/cygwin/fhandler_mailslot.cc b/winsup/cygwin/fhandler_mailslot.cc index a59a3dcf9..691c6043b 100644 --- a/winsup/cygwin/fhandler_mailslot.cc +++ b/winsup/cygwin/fhandler_mailslot.cc @@ -1,7 +1,6 @@ /* fhandler_mailslot.cc. See fhandler.h for a description of the fhandler classes. - Copyright 2005, 2007, 2008, 2009 - Red Hat, Inc. + Copyright 2005, 2007, 2008, 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -47,12 +46,15 @@ fhandler_mailslot::fstat (struct __stat64 *buf) POBJECT_ATTRIBUTES fhandler_mailslot::get_object_attr (OBJECT_ATTRIBUTES &attr, - PUNICODE_STRING path) + PUNICODE_STRING path, + int flags) { RtlCopyUnicodeString (path, pc.get_nt_native_path ()); RtlAppendUnicodeStringToString (path, &installation_key); - InitializeObjectAttributes (&attr, path, OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + InitializeObjectAttributes (&attr, path, + OBJ_CASE_INSENSITIVE + | (flags & O_CLOEXEC ? 0 : OBJ_INHERIT), NULL, NULL); return &attr; } @@ -76,7 +78,7 @@ fhandler_mailslot::open (int flags, mode_t mode) case O_RDONLY: /* Server */ timeout.QuadPart = (flags & O_NONBLOCK) ? 0LL : 0x8000000000000000LL; status = NtCreateMailslotFile (&x, GENERIC_READ | SYNCHRONIZE, - get_object_attr (attr, &path), + get_object_attr (attr, &path, flags), &io, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0, &timeout); if (!NT_SUCCESS (status)) @@ -97,7 +99,7 @@ fhandler_mailslot::open (int flags, mode_t mode) break; } status = NtOpenFile (&x, GENERIC_READ | SYNCHRONIZE, - get_object_attr (attr, &path), &io, + get_object_attr (attr, &path, flags), &io, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT); #endif @@ -122,7 +124,7 @@ fhandler_mailslot::open (int flags, mode_t mode) break; } status = NtOpenFile (&x, GENERIC_WRITE | SYNCHRONIZE, - get_object_attr (attr, &path), &io, + get_object_attr (attr, &path, flags), &io, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS (status)) diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc index 7bd809472..b172cc576 100644 --- a/winsup/cygwin/fhandler_mem.cc +++ b/winsup/cygwin/fhandler_mem.cc @@ -1,7 +1,7 @@ /* fhandler_mem.cc. See fhandler.h for a description of the fhandler classes. - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 - Red Hat, Inc. + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, + 2010 Red Hat, Inc. This file is part of Cygwin. @@ -79,7 +79,8 @@ fhandler_dev_mem::open (int flags, mode_t) OBJECT_ATTRIBUTES attr; InitializeObjectAttributes (&attr, &ro_u_pmem, - OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + OBJ_CASE_INSENSITIVE + | (flags & O_CLOEXEC ? 0 : OBJ_INHERIT), NULL, NULL); ACCESS_MASK section_access; diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index e8f4e685f..9f8e9af97 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -1,6 +1,7 @@ /* fhandler_registry.cc: fhandler for /proc/registry virtual filesystem - Copyright 2002, 2003, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Red Hat, Inc. + Copyright 2002, 2003, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010 Red Hat, Inc. This file is part of Cygwin. @@ -771,6 +772,7 @@ fhandler_registry::open (int flags, mode_t mode) flags |= O_DIROPEN; set_io_handle (handle); + set_close_on_exec (!!(flags & O_CLOEXEC)); value_name = cwcsdup (dec_file); if (!(flags & O_DIROPEN) && !fill_filebuf ()) diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index 22869983e..ff7e84aab 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -2,7 +2,7 @@ classes. Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008 Red Hat, Inc. + 2008, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -1174,7 +1174,7 @@ fhandler_dev_tape::open (int flags, mode_t) set_errno (ENOENT); return 0; } - if (!(mt_mtx = CreateMutex (&sec_all, TRUE, NULL))) + if (!(mt_mtx = CreateMutex (&sec_all, !!(flags & O_CLOEXEC), NULL))) { __seterrno (); return 0; diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 36775401f..4e4dc5338 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -581,6 +581,7 @@ fhandler_tty_slave::open (int flags, mode_t) set_io_handle (from_master_local); set_output_handle (to_master_local); + set_close_on_exec (!!(flags & O_CLOEXEC)); set_open_status (); if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1 diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index ce8b45336..519c3a490 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -372,12 +372,13 @@ details. */ 216: CW_SET_EXTERNAL_TOKEN added. 217: CW_GET_INSTKEY added. 218: Export get_nprocs, get_nprocs_conf, get_phys_pages, get_avphys_pages. + 219: Export dup3, pipe2, O_CLOEXEC, F_DUPFD_CLOEXEC. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 218 +#define CYGWIN_VERSION_API_MINOR 219 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 39b93ccd8..2d351fd68 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -1,7 +1,7 @@ /* pipe.cc: pipe for Cygwin. Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009 Hat, Inc. + 2008, 2009, 2010 Hat, Inc. This file is part of Cygwin. @@ -53,8 +53,7 @@ fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode) bool opened_properly = a & FILE_CREATE_PIPE_INSTANCE; a &= ~FILE_CREATE_PIPE_INSTANCE; fhandler_base::init (f, a, mode); - if (mode & O_NOINHERIT) - close_on_exec (true); + close_on_exec (mode & O_CLOEXEC); setup_overlapped (opened_properly); return 1; } @@ -116,7 +115,7 @@ fhandler_pipe::open (int flags, mode_t mode) set_errno (EACCES); goto out; } - inh = !(flags & O_NOINHERIT); + inh = !(flags & O_CLOEXEC); if (!DuplicateHandle (proc, pipe_hdl, GetCurrentProcess (), &nio_hdl, 0, inh, DUPLICATE_SAME_ACCESS)) { @@ -124,8 +123,6 @@ fhandler_pipe::open (int flags, mode_t mode) goto out; } init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY); - if (flags & O_NOINHERIT) - close_on_exec (true); uninterruptible_io (fh->uninterruptible_io ()); cfree (fh); CloseHandle (proc); @@ -312,7 +309,7 @@ int fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode) { HANDLE r, w; - SECURITY_ATTRIBUTES *sa = (mode & O_NOINHERIT) ? &sec_none_nih : &sec_none; + SECURITY_ATTRIBUTES *sa = sec_none_cloexec (mode); int res; int ret = create_selectable (sa, r, w, psize); @@ -409,3 +406,9 @@ _pipe (int filedes[2], unsigned int psize, int mode) return res; } + +extern "C" int +pipe2 (int filedes[2], int mode) +{ + return _pipe (filedes, DEFAULT_PIPEBUFSIZE, mode); +} diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc index 07881be05..3b0ae7802 100644 --- a/winsup/cygwin/posix_ipc.cc +++ b/winsup/cygwin/posix_ipc.cc @@ -1,6 +1,6 @@ /* posix_ipc.cc: POSIX IPC API for Cygwin. - Copyright 2007, 2008, 2009 Red Hat, Inc. + Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -248,7 +248,7 @@ shm_open (const char *name, int oflag, mode_t mode) return -1; } - return open (shmname, oflag, mode & 0777); + return open (shmname, oflag | O_CLOEXEC, mode & 0777); } extern "C" int @@ -351,7 +351,7 @@ again: va_end (ap); /* Open and specify O_EXCL and user-execute */ - fd = open (mqname, oflag | O_EXCL | O_RDWR, mode | S_IXUSR); + fd = open (mqname, oflag | O_EXCL | O_RDWR | O_CLOEXEC, mode | S_IXUSR); if (fd < 0) { if (errno == EEXIST && (oflag & O_EXCL) == 0) @@ -435,7 +435,7 @@ again: exists: /* Open the file then memory map */ - if ((fd = open (mqname, O_RDWR)) < 0) + if ((fd = open (mqname, O_RDWR | O_CLOEXEC)) < 0) { if (errno == ENOENT && (oflag & O_CREAT)) goto again; @@ -944,7 +944,7 @@ again: va_end (ap); /* Open and specify O_EXCL and user-execute */ - fd = open (semname, oflag | O_EXCL | O_RDWR, mode | S_IXUSR); + fd = open (semname, oflag | O_EXCL | O_RDWR | O_CLOEXEC, mode | S_IXUSR); if (fd < 0) { if (errno == EEXIST && (oflag & O_EXCL) == 0) @@ -974,7 +974,7 @@ again: exists: /* Open the file and fetch the semaphore name. */ - if ((fd = open (semname, O_RDWR)) < 0) + if ((fd = open (semname, O_RDWR | O_CLOEXEC)) < 0) { if (errno == ENOENT && (oflag & O_CREAT)) goto again; diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 4de76aa99..f9538c129 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -437,6 +437,8 @@ extern SECURITY_ATTRIBUTES *__stdcall __sec_user (PVOID sa_buf, PSID sid1, PSID extern PSECURITY_DESCRIPTOR _everyone_sd (void *buf, ACCESS_MASK access); #define everyone_sd(access) (_everyone_sd (alloca (SD_MIN_SIZE), (access))) +#define sec_none_cloexec(f) (((f) & O_CLOEXEC ? &sec_none_nih : &sec_none)) + extern bool sec_acl (PACL acl, bool original, bool admins, PSID sid1 = NO_SID, PSID sid2 = NO_SID, DWORD access2 = 0); @@ -460,4 +462,5 @@ sec_user (SECURITY_ATTRIBUTES *sa_buf, PSID sid1, PSID sid2 = NULL, { return __sec_user (sa_buf, sid1, sid2, access2, TRUE); } + #endif /*_SECURITY_H*/ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index ec589712a..bd3308a42 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -116,13 +116,13 @@ close_all_files (bool norelease) cygheap->fdtab.unlock (); } -int +extern "C" int dup (int fd) { - return cygheap->fdtab.dup2 (fd, cygheap_fdnew ()); + return cygheap->fdtab.dup3 (fd, cygheap_fdnew (), 0); } -int +extern "C" int dup2 (int oldfd, int newfd) { if (newfd >= OPEN_MAX_MAX) @@ -131,7 +131,39 @@ dup2 (int oldfd, int newfd) set_errno (EBADF); return -1; } - return cygheap->fdtab.dup2 (oldfd, newfd); + if (newfd == oldfd) + { + cygheap_fdget cfd (oldfd); + if (cfd < 0) + { + syscall_printf ("-1 = dup2 (%d, %d) (oldfd not open)", oldfd, newfd); + return -1; + } + syscall_printf ("%d = dup2 (%d, %d) (newfd==oldfd)", oldfd, oldfd, newfd); + return oldfd; + } + return cygheap->fdtab.dup3 (oldfd, newfd, 0); +} + +extern "C" int +dup3 (int oldfd, int newfd, int flags) +{ + if (newfd >= OPEN_MAX_MAX) + { + syscall_printf ("-1 = dup3 (%d, %d, %p) (%d too large)", + oldfd, newfd, flags, newfd); + set_errno (EBADF); + return -1; + } + if (newfd == oldfd) + { + cygheap_fdget cfd (oldfd, false, false); + set_errno (cfd < 0 ? EBADF : EINVAL); + syscall_printf ("-1 = dup3 (%d, %d, %p) (newfd==oldfd)", + oldfd, newfd, flags); + return -1; + } + return cygheap->fdtab.dup3 (oldfd, newfd, flags); } static char desktop_ini[] = @@ -1037,16 +1069,20 @@ open (const char *unix_path, int flags, ...) delete fh; res = -1; } - else if (!fh->open (flags, (mode & 07777) & ~cygheap->umask)) - { - delete fh; - res = -1; - } else { - cygheap->fdtab[fd] = fh; - if ((res = fd) <= 2) - set_std_handle (res); + fh->close_on_exec (flags & O_CLOEXEC); + if (!fh->open (flags, (mode & 07777) & ~cygheap->umask)) + { + delete fh; + res = -1; + } + else + { + cygheap->fdtab[fd] = fh; + if ((res = fd) <= 2) + set_std_handle (res); + } } } }