* 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.
This commit is contained in:
Corinna Vinschen 2010-01-14 18:46:02 +00:00
parent 491912bffe
commit e70fdfb99f
19 changed files with 175 additions and 63 deletions

View File

@ -1,3 +1,51 @@
2010-01-14 Corinna Vinschen <corinna@vinschen.de>
* 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 <corinna@vinschen.de> 2010-01-13 Corinna Vinschen <corinna@vinschen.de>
* include/fcntl.h (O_TTY_INIT): Define as 0. * include/fcntl.h (O_TTY_INIT): Define as 0.

View File

@ -297,6 +297,7 @@ dup SIGFE
_dup = dup SIGFE _dup = dup SIGFE
dup2 SIGFE dup2 SIGFE
_dup2 = dup2 SIGFE _dup2 = dup2 SIGFE
dup3 SIGFE
eaccess = euidaccess SIGFE eaccess = euidaccess SIGFE
ecvt SIGFE ecvt SIGFE
_ecvt = ecvt SIGFE _ecvt = ecvt SIGFE
@ -1071,6 +1072,7 @@ perror SIGFE
_perror = perror SIGFE _perror = perror SIGFE
pipe SIGFE pipe SIGFE
_pipe SIGFE _pipe SIGFE
pipe2 SIGFE
poll SIGFE poll SIGFE
_poll = poll SIGFE _poll = poll SIGFE
popen SIGFE popen SIGFE

View File

@ -559,7 +559,7 @@ build_fh_pc (path_conv& pc, bool set_name)
} }
fhandler_base * 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 /* Don't call set_name in build_fh_pc. It will be called in
fhandler_base::operator= below. Calling it twice will result fhandler_base::operator= below. Calling it twice will result
@ -579,7 +579,11 @@ dtable::dup_worker (fhandler_base *oldfh)
} }
else 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 ()); 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 int
dtable::dup2 (int oldfd, int newfd) dtable::dup3 (int oldfd, int newfd, int flags)
{ {
int res = -1; int res = -1;
fhandler_base *newfh = NULL; // = NULL to avoid an incorrect warning fhandler_base *newfh = NULL; // = NULL to avoid an incorrect warning
MALLOC_CHECK; MALLOC_CHECK;
debug_printf ("dup2 (%d, %d)", oldfd, newfd); debug_printf ("dup3 (%d, %d, %p)", oldfd, newfd, flags);
lock (); lock ();
if (not_open (oldfd)) if (not_open (oldfd))
@ -602,21 +606,20 @@ dtable::dup2 (int oldfd, int newfd)
set_errno (EBADF); set_errno (EBADF);
goto done; goto done;
} }
if (newfd < 0) if (newfd < 0)
{ {
syscall_printf ("new fd out of bounds: %d", newfd); syscall_printf ("new fd out of bounds: %d", newfd);
set_errno (EBADF); set_errno (EBADF);
goto done; goto done;
} }
if ((flags & ~O_CLOEXEC) != 0)
if (newfd == oldfd)
{ {
res = newfd; syscall_printf ("invalid flags value %x", flags);
goto done; set_errno (EINVAL);
return -1;
} }
if ((newfh = dup_worker (fds[oldfd])) == NULL) if ((newfh = dup_worker (fds[oldfd], flags)) == NULL)
{ {
res = -1; res = -1;
goto done; goto done;
@ -644,7 +647,7 @@ dtable::dup2 (int oldfd, int newfd)
done: done:
MALLOC_CHECK; MALLOC_CHECK;
unlock (); unlock ();
syscall_printf ("%d = dup2 (%d, %d)", res, oldfd, newfd); syscall_printf ("%d = dup3 (%d, %d, %p)", res, oldfd, newfd, flags);
return res; return res;
} }

View File

@ -51,7 +51,7 @@ public:
int vfork_child_dup (); int vfork_child_dup ();
void vfork_parent_restore (); void vfork_parent_restore ();
void vfork_child_fixup (); void vfork_child_fixup ();
fhandler_base *dup_worker (fhandler_base *oldfh); fhandler_base *dup_worker (fhandler_base *oldfh, int flags);
int extend (int howmuch); int extend (int howmuch);
void fixup_after_fork (HANDLE); void fixup_after_fork (HANDLE);
inline int not_open (int fd) inline int not_open (int fd)
@ -65,7 +65,7 @@ public:
int find_unused_handle () { return find_unused_handle (first_fd_for_open);} int find_unused_handle () { return find_unused_handle (first_fd_for_open);}
void release (int fd); void release (int fd);
void init_std_file_from_handle (int fd, HANDLE handle); 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 (); void fixup_after_exec ();
inline fhandler_base *&operator [](int fd) const { return fds[fd]; } inline fhandler_base *&operator [](int fd) const { return fds[fd]; }
bool select_read (int fd, select_stuff *); bool select_read (int fd, select_stuff *);

View File

@ -1,7 +1,7 @@
/* fcntl.cc: fcntl syscall /* fcntl.cc: fcntl syscall
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2008, 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. This file is part of Cygwin.
@ -41,8 +41,10 @@ fcntl64 (int fd, int cmd, ...)
switch (cmd) switch (cmd)
{ {
case F_DUPFD: case F_DUPFD:
case F_DUPFD_CLOEXEC:
if ((int) arg >= 0 && (int) arg < OPEN_MAX_MAX) 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 else
{ {
set_errno (EINVAL); set_errno (EINVAL);

View File

@ -1,7 +1,7 @@
/* fhandler.cc. See console.cc for fhandler_console functions. /* fhandler.cc. See console.cc for fhandler_console functions.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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. 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); 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 ()) switch (query_open ())
{ {

View File

@ -399,7 +399,7 @@ class fhandler_base
class fhandler_mailslot : public 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: public:
fhandler_mailslot (); fhandler_mailslot ();
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));

View File

@ -1,7 +1,7 @@
/* fhandler_console.cc /* fhandler_console.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 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. This file is part of Cygwin.
@ -705,7 +705,7 @@ fhandler_console::open (int flags, mode_t)
/* Open the input handle as handle_ */ /* Open the input handle as handle_ */
h = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE, 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); OPEN_EXISTING, 0, 0);
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE)
@ -717,7 +717,7 @@ fhandler_console::open (int flags, mode_t)
uninterruptible_io (true); // Handled explicitly in read code uninterruptible_io (true); // Handled explicitly in read code
h = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE, 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); OPEN_EXISTING, 0, 0);
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE)

View File

@ -1,6 +1,6 @@
/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes. /* 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. This file is part of Cygwin.
@ -70,6 +70,11 @@ fhandler_fifo::fifo_name (char *buf)
PIPE_UNLIMITED_INSTANCES, (s), (s), \ PIPE_UNLIMITED_INSTANCES, (s), (s), \
NMPWAIT_WAIT_FOREVER, sa_buf) 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 int
fhandler_fifo::open (int flags, mode_t) fhandler_fifo::open (int flags, mode_t)
@ -94,7 +99,8 @@ fhandler_fifo::open (int flags, mode_t)
{ {
char char_sa_buf[1024]; char char_sa_buf[1024];
LPSECURITY_ATTRIBUTES sa_buf = 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; bool do_seterrno = true;
HANDLE h; HANDLE h;
@ -205,7 +211,9 @@ fhandler_fifo::wait (bool iswrite)
fifo_name (npname); fifo_name (npname);
char char_sa_buf[1024]; char char_sa_buf[1024];
LPSECURITY_ATTRIBUTES sa_buf; 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) while (1)
{ {
if (WaitNamedPipe (npname, 10)) if (WaitNamedPipe (npname, 10))

View File

@ -1,7 +1,6 @@
/* fhandler_mailslot.cc. See fhandler.h for a description of the fhandler classes. /* fhandler_mailslot.cc. See fhandler.h for a description of the fhandler classes.
Copyright 2005, 2007, 2008, 2009 Copyright 2005, 2007, 2008, 2009, 2010 Red Hat, Inc.
Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -47,12 +46,15 @@ fhandler_mailslot::fstat (struct __stat64 *buf)
POBJECT_ATTRIBUTES POBJECT_ATTRIBUTES
fhandler_mailslot::get_object_attr (OBJECT_ATTRIBUTES &attr, fhandler_mailslot::get_object_attr (OBJECT_ATTRIBUTES &attr,
PUNICODE_STRING path) PUNICODE_STRING path,
int flags)
{ {
RtlCopyUnicodeString (path, pc.get_nt_native_path ()); RtlCopyUnicodeString (path, pc.get_nt_native_path ());
RtlAppendUnicodeStringToString (path, &installation_key); 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); NULL, NULL);
return &attr; return &attr;
} }
@ -76,7 +78,7 @@ fhandler_mailslot::open (int flags, mode_t mode)
case O_RDONLY: /* Server */ case O_RDONLY: /* Server */
timeout.QuadPart = (flags & O_NONBLOCK) ? 0LL : 0x8000000000000000LL; timeout.QuadPart = (flags & O_NONBLOCK) ? 0LL : 0x8000000000000000LL;
status = NtCreateMailslotFile (&x, GENERIC_READ | SYNCHRONIZE, status = NtCreateMailslotFile (&x, GENERIC_READ | SYNCHRONIZE,
get_object_attr (attr, &path), get_object_attr (attr, &path, flags),
&io, FILE_SYNCHRONOUS_IO_NONALERT, &io, FILE_SYNCHRONOUS_IO_NONALERT,
0, 0, &timeout); 0, 0, &timeout);
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))
@ -97,7 +99,7 @@ fhandler_mailslot::open (int flags, mode_t mode)
break; break;
} }
status = NtOpenFile (&x, GENERIC_READ | SYNCHRONIZE, status = NtOpenFile (&x, GENERIC_READ | SYNCHRONIZE,
get_object_attr (attr, &path), &io, get_object_attr (attr, &path, flags), &io,
FILE_SHARE_VALID_FLAGS, FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT); FILE_SYNCHRONOUS_IO_NONALERT);
#endif #endif
@ -122,7 +124,7 @@ fhandler_mailslot::open (int flags, mode_t mode)
break; break;
} }
status = NtOpenFile (&x, GENERIC_WRITE | SYNCHRONIZE, status = NtOpenFile (&x, GENERIC_WRITE | SYNCHRONIZE,
get_object_attr (attr, &path), &io, get_object_attr (attr, &path, flags), &io,
FILE_SHARE_VALID_FLAGS, FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT); FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))

View File

@ -1,7 +1,7 @@
/* fhandler_mem.cc. See fhandler.h for a description of the fhandler classes. /* fhandler_mem.cc. See fhandler.h for a description of the fhandler classes.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009,
Red Hat, Inc. 2010 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -79,7 +79,8 @@ fhandler_dev_mem::open (int flags, mode_t)
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
InitializeObjectAttributes (&attr, &ro_u_pmem, InitializeObjectAttributes (&attr, &ro_u_pmem,
OBJ_CASE_INSENSITIVE | OBJ_INHERIT, OBJ_CASE_INSENSITIVE
| (flags & O_CLOEXEC ? 0 : OBJ_INHERIT),
NULL, NULL); NULL, NULL);
ACCESS_MASK section_access; ACCESS_MASK section_access;

View File

@ -1,6 +1,7 @@
/* fhandler_registry.cc: fhandler for /proc/registry virtual filesystem /* 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. This file is part of Cygwin.
@ -771,6 +772,7 @@ fhandler_registry::open (int flags, mode_t mode)
flags |= O_DIROPEN; flags |= O_DIROPEN;
set_io_handle (handle); set_io_handle (handle);
set_close_on_exec (!!(flags & O_CLOEXEC));
value_name = cwcsdup (dec_file); value_name = cwcsdup (dec_file);
if (!(flags & O_DIROPEN) && !fill_filebuf ()) if (!(flags & O_DIROPEN) && !fill_filebuf ())

View File

@ -2,7 +2,7 @@
classes. classes.
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 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. This file is part of Cygwin.
@ -1174,7 +1174,7 @@ fhandler_dev_tape::open (int flags, mode_t)
set_errno (ENOENT); set_errno (ENOENT);
return 0; return 0;
} }
if (!(mt_mtx = CreateMutex (&sec_all, TRUE, NULL))) if (!(mt_mtx = CreateMutex (&sec_all, !!(flags & O_CLOEXEC), NULL)))
{ {
__seterrno (); __seterrno ();
return 0; return 0;

View File

@ -581,6 +581,7 @@ fhandler_tty_slave::open (int flags, mode_t)
set_io_handle (from_master_local); set_io_handle (from_master_local);
set_output_handle (to_master_local); set_output_handle (to_master_local);
set_close_on_exec (!!(flags & O_CLOEXEC));
set_open_status (); set_open_status ();
if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1 if (cygheap->manage_console_count ("fhandler_tty_slave::open", 1) == 1

View File

@ -372,12 +372,13 @@ details. */
216: CW_SET_EXTERNAL_TOKEN added. 216: CW_SET_EXTERNAL_TOKEN added.
217: CW_GET_INSTKEY added. 217: CW_GET_INSTKEY added.
218: Export get_nprocs, get_nprocs_conf, get_phys_pages, get_avphys_pages. 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 */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #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 /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -1,7 +1,7 @@
/* pipe.cc: pipe for Cygwin. /* pipe.cc: pipe for Cygwin.
Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 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. 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; bool opened_properly = a & FILE_CREATE_PIPE_INSTANCE;
a &= ~FILE_CREATE_PIPE_INSTANCE; a &= ~FILE_CREATE_PIPE_INSTANCE;
fhandler_base::init (f, a, mode); fhandler_base::init (f, a, mode);
if (mode & O_NOINHERIT) close_on_exec (mode & O_CLOEXEC);
close_on_exec (true);
setup_overlapped (opened_properly); setup_overlapped (opened_properly);
return 1; return 1;
} }
@ -116,7 +115,7 @@ fhandler_pipe::open (int flags, mode_t mode)
set_errno (EACCES); set_errno (EACCES);
goto out; goto out;
} }
inh = !(flags & O_NOINHERIT); inh = !(flags & O_CLOEXEC);
if (!DuplicateHandle (proc, pipe_hdl, GetCurrentProcess (), &nio_hdl, if (!DuplicateHandle (proc, pipe_hdl, GetCurrentProcess (), &nio_hdl,
0, inh, DUPLICATE_SAME_ACCESS)) 0, inh, DUPLICATE_SAME_ACCESS))
{ {
@ -124,8 +123,6 @@ fhandler_pipe::open (int flags, mode_t mode)
goto out; goto out;
} }
init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY); init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY);
if (flags & O_NOINHERIT)
close_on_exec (true);
uninterruptible_io (fh->uninterruptible_io ()); uninterruptible_io (fh->uninterruptible_io ());
cfree (fh); cfree (fh);
CloseHandle (proc); CloseHandle (proc);
@ -312,7 +309,7 @@ int
fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode) fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode)
{ {
HANDLE r, w; HANDLE r, w;
SECURITY_ATTRIBUTES *sa = (mode & O_NOINHERIT) ? &sec_none_nih : &sec_none; SECURITY_ATTRIBUTES *sa = sec_none_cloexec (mode);
int res; int res;
int ret = create_selectable (sa, r, w, psize); int ret = create_selectable (sa, r, w, psize);
@ -409,3 +406,9 @@ _pipe (int filedes[2], unsigned int psize, int mode)
return res; return res;
} }
extern "C" int
pipe2 (int filedes[2], int mode)
{
return _pipe (filedes, DEFAULT_PIPEBUFSIZE, mode);
}

View File

@ -1,6 +1,6 @@
/* posix_ipc.cc: POSIX IPC API for Cygwin. /* 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. This file is part of Cygwin.
@ -248,7 +248,7 @@ shm_open (const char *name, int oflag, mode_t mode)
return -1; return -1;
} }
return open (shmname, oflag, mode & 0777); return open (shmname, oflag | O_CLOEXEC, mode & 0777);
} }
extern "C" int extern "C" int
@ -351,7 +351,7 @@ again:
va_end (ap); va_end (ap);
/* Open and specify O_EXCL and user-execute */ /* 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 (fd < 0)
{ {
if (errno == EEXIST && (oflag & O_EXCL) == 0) if (errno == EEXIST && (oflag & O_EXCL) == 0)
@ -435,7 +435,7 @@ again:
exists: exists:
/* Open the file then memory map */ /* 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)) if (errno == ENOENT && (oflag & O_CREAT))
goto again; goto again;
@ -944,7 +944,7 @@ again:
va_end (ap); va_end (ap);
/* Open and specify O_EXCL and user-execute */ /* 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 (fd < 0)
{ {
if (errno == EEXIST && (oflag & O_EXCL) == 0) if (errno == EEXIST && (oflag & O_EXCL) == 0)
@ -974,7 +974,7 @@ again:
exists: exists:
/* Open the file and fetch the semaphore name. */ /* 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)) if (errno == ENOENT && (oflag & O_CREAT))
goto again; goto again;

View File

@ -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); extern PSECURITY_DESCRIPTOR _everyone_sd (void *buf, ACCESS_MASK access);
#define everyone_sd(access) (_everyone_sd (alloca (SD_MIN_SIZE), (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, extern bool sec_acl (PACL acl, bool original, bool admins, PSID sid1 = NO_SID,
PSID sid2 = NO_SID, DWORD access2 = 0); 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); return __sec_user (sa_buf, sid1, sid2, access2, TRUE);
} }
#endif /*_SECURITY_H*/ #endif /*_SECURITY_H*/

View File

@ -116,13 +116,13 @@ close_all_files (bool norelease)
cygheap->fdtab.unlock (); cygheap->fdtab.unlock ();
} }
int extern "C" int
dup (int fd) 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) dup2 (int oldfd, int newfd)
{ {
if (newfd >= OPEN_MAX_MAX) if (newfd >= OPEN_MAX_MAX)
@ -131,7 +131,39 @@ dup2 (int oldfd, int newfd)
set_errno (EBADF); set_errno (EBADF);
return -1; 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[] = static char desktop_ini[] =
@ -1037,16 +1069,20 @@ open (const char *unix_path, int flags, ...)
delete fh; delete fh;
res = -1; res = -1;
} }
else if (!fh->open (flags, (mode & 07777) & ~cygheap->umask))
{
delete fh;
res = -1;
}
else else
{ {
cygheap->fdtab[fd] = fh; fh->close_on_exec (flags & O_CLOEXEC);
if ((res = fd) <= 2) if (!fh->open (flags, (mode & 07777) & ~cygheap->umask))
set_std_handle (res); {
delete fh;
res = -1;
}
else
{
cygheap->fdtab[fd] = fh;
if ((res = fd) <= 2)
set_std_handle (res);
}
} }
} }
} }