From 1204c515fe00335920c5707cc136e9562fd7cf38 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 28 Sep 2005 19:02:53 +0000 Subject: * fhandler.h (class fhandler_dev_raw): Delete current_position and eof_detected status flag. Delete is_eom and is_eof methods. Move drive_size, bytes_per_sector, eom_detected status flag, as well as the methods read_file, write_file, raw_read and raw_write to ... (class fhandler_dev_floppy): ... here. Remove is_eom and is_eof methods. Add dup method. * fhandler_floppy.cc (IS_EOM): New macro. (fhandler_dev_floppy::is_eom): Remove. (fhandler_dev_floppy::is_eof): Remove. (fhandler_dev_floppy::fhandler_dev_floppy): Initialize status flags. (fhandler_dev_floppy::get_drive_info): Only call EX functions on systems supporting them and stop suffering strange delays. (fhandler_dev_floppy::read_file): Move here, drop setting current_position. (fhandler_dev_floppy::write_file): Move here, drop setting current_position. (fhandler_dev_floppy::open): Rearrange comment. (fhandler_dev_floppy::dup): New method. (fhandler_dev_floppy::get_current_position): New inline method. Use instead of former current_position were appropriate. (fhandler_dev_floppy::raw_read): Move here. Drop EOF handling. (fhandler_dev_floppy::raw_write): Move here. Drop EOF handling. (fhandler_dev_floppy::lseek): Remove useless conditions. Convert sector_aligned_offset to LARGE_INTEGER to improve SetFilePointer call. (fhandler_dev_floppy::ioctl): Move blocksize check in RDSETBLK case to here. * fhandler_raw.cc (fhandler_dev_raw::is_eom): Remove. (fhandler_dev_raw::is_eof): Remove. (fhandler_dev_raw::write_file): Remove. (fhandler_dev_raw::read_file): Remove. (fhandler_dev_raw::raw_read): Remove. (fhandler_dev_raw::raw_write): Remove. (fhandler_dev_raw::dup): Drop copying removed members. (fhandler_dev_raw::ioctl): Drop blocksize testing. * wincap.h: Implement has_disk_ex_ioctls throughout. * wincap.cc: Ditto. (wincap_vista): Preliminary wincaps for Windows Vista/Longhorn. (wincapc::init): Add Vista/Longhorn handling. --- winsup/cygwin/ChangeLog | 41 +++++++++ winsup/cygwin/autoload.cc | 3 + winsup/cygwin/dtable.cc | 4 +- winsup/cygwin/fhandler.cc | 23 ++--- winsup/cygwin/fhandler.h | 30 +++---- winsup/cygwin/fhandler_clipboard.cc | 2 +- winsup/cygwin/fhandler_console.cc | 2 +- winsup/cygwin/fhandler_dsp.cc | 2 +- winsup/cygwin/fhandler_fifo.cc | 6 +- winsup/cygwin/fhandler_mem.cc | 4 +- winsup/cygwin/fhandler_random.cc | 2 +- winsup/cygwin/fhandler_raw.cc | 7 +- winsup/cygwin/fhandler_serial.cc | 4 +- winsup/cygwin/fhandler_socket.cc | 113 ++++++++++++++++++----- winsup/cygwin/fhandler_tape.cc | 8 +- winsup/cygwin/fhandler_tty.cc | 25 +++--- winsup/cygwin/fhandler_virtual.cc | 4 +- winsup/cygwin/include/cygwin/socket.h | 55 +++++++++++- winsup/cygwin/include/cygwin/version.h | 8 ++ winsup/cygwin/ntdll.h | 4 + winsup/cygwin/path.cc | 35 ++++---- winsup/cygwin/pinfo.cc | 159 +++++++++++++++++++-------------- winsup/cygwin/pinfo.h | 8 ++ winsup/cygwin/pipe.cc | 12 +-- winsup/cygwin/sigproc.cc | 57 +++++++++++- winsup/cygwin/wincap.cc | 56 ++++++++++++ 26 files changed, 501 insertions(+), 173 deletions(-) (limited to 'winsup') diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 65d7a0fb9..8e742faa5 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,44 @@ +2005-09-28 Corinna Vinschen + + * fhandler.h (class fhandler_dev_raw): Delete current_position and + eof_detected status flag. Delete is_eom and is_eof methods. + Move drive_size, bytes_per_sector, eom_detected status flag, as well + as the methods read_file, write_file, raw_read and raw_write to ... + (class fhandler_dev_floppy): ... here. Remove is_eom and is_eof + methods. Add dup method. + * fhandler_floppy.cc (IS_EOM): New macro. + (fhandler_dev_floppy::is_eom): Remove. + (fhandler_dev_floppy::is_eof): Remove. + (fhandler_dev_floppy::fhandler_dev_floppy): Initialize status flags. + (fhandler_dev_floppy::get_drive_info): Only call EX functions on + systems supporting them and stop suffering strange delays. + (fhandler_dev_floppy::read_file): Move here, drop setting + current_position. + (fhandler_dev_floppy::write_file): Move here, drop setting + current_position. + (fhandler_dev_floppy::open): Rearrange comment. + (fhandler_dev_floppy::dup): New method. + (fhandler_dev_floppy::get_current_position): New inline method. Use + instead of former current_position were appropriate. + (fhandler_dev_floppy::raw_read): Move here. Drop EOF handling. + (fhandler_dev_floppy::raw_write): Move here. Drop EOF handling. + (fhandler_dev_floppy::lseek): Remove useless conditions. Convert + sector_aligned_offset to LARGE_INTEGER to improve SetFilePointer call. + (fhandler_dev_floppy::ioctl): Move blocksize check in RDSETBLK case + to here. + * fhandler_raw.cc (fhandler_dev_raw::is_eom): Remove. + (fhandler_dev_raw::is_eof): Remove. + (fhandler_dev_raw::write_file): Remove. + (fhandler_dev_raw::read_file): Remove. + (fhandler_dev_raw::raw_read): Remove. + (fhandler_dev_raw::raw_write): Remove. + (fhandler_dev_raw::dup): Drop copying removed members. + (fhandler_dev_raw::ioctl): Drop blocksize testing. + * wincap.h: Implement has_disk_ex_ioctls throughout. + * wincap.cc: Ditto. + (wincap_vista): Preliminary wincaps for Windows Vista/Longhorn. + (wincapc::init): Add Vista/Longhorn handling. + 2005-09-28 Christopher Faylor * dcrt0.cc (getstack): New function. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 5f0b5ddf3..dcfa98ed5 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -404,6 +404,9 @@ LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1) LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1) LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1) LoadDLLfuncEx (RtlIsDosDeviceName_U, 4, ntdll, 1) +LoadDLLfuncEx (RtlDosPathNameToNtPathName_U, 16, ntdll, 1) +LoadDLLfuncEx (RtlCreateUnicodeStringFromAsciiz, 8, ntdll, 1) +LoadDLLfuncEx (RtlFreeUnicodeString, 4, ntdll, 1) LoadDLLfuncEx (EnumProcessModules, 16, psapi, 1) LoadDLLfuncEx (GetModuleFileNameExA, 16, psapi, 1) diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 05d9037ab..4640444f5 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -334,7 +334,7 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle) } } -#define cnew(name) new ((void *) ccalloc (HEAP_FHANDLER, 1, sizeof (name))) name +#define cnew(name) new ((void *) ccalloc (HEAP_FHANDLER, 1, sizeof (fhandler_union))) name fhandler_base * build_fh_name (const char *name, HANDLE h, unsigned opt, suffix_info *si) { @@ -495,7 +495,7 @@ dtable::dup_worker (fhandler_base *oldfh) { *newfh = *oldfh; newfh->set_io_handle (NULL); - if (oldfh->dup (newfh)) + if (oldfh->dup (newfh, hMainProc)) { cfree (newfh); debug_printf ("oldfh->dup failed"); diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index a8a27862a..eae83e965 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -555,12 +555,13 @@ fhandler_base::open (int flags, mode_t mode) if (!wincap.is_winnt ()) return fhandler_base::open_9x (flags, mode); - WCHAR wpath[CYG_MAX_PATH + 10]; - UNICODE_STRING upath = {0, sizeof (wpath), wpath}; - pc.get_nt_native_path (upath); - - if (RtlIsDosDeviceName_U (upath.Buffer)) - return fhandler_base::open_9x (flags, mode); + UNICODE_STRING upath; + if (!pc.get_nt_native_path (upath)) + { + syscall_printf ("0 = fhandler_base::open (%s, %p)", + get_win32_name (), flags); + return 0; + } int res = 0; HANDLE x; @@ -576,7 +577,8 @@ fhandler_base::open (int flags, mode_t mode) syscall_printf ("(%s, %p)", get_win32_name (), flags); - InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + InitializeObjectAttributes (&attr, &upath, + OBJ_CASE_INSENSITIVE | OBJ_INHERIT, sa.lpSecurityDescriptor, NULL); switch (query_open ()) @@ -681,6 +683,7 @@ done: syscall_printf ("%d = fhandler_base::open (%s, %p)", res, get_win32_name (), flags); + RtlFreeUnicodeString (&upath); return res; } @@ -1263,14 +1266,15 @@ fhandler_base::init (HANDLE f, DWORD a, mode_t bin) } int -fhandler_base::dup (fhandler_base *child) +fhandler_base::dup (fhandler_base *child, HANDLE from_proc) { debug_printf ("in fhandler_base dup"); HANDLE nh; + set_flags (child->get_flags ()); if (!nohandle ()) { - if (!DuplicateHandle (hMainProc, get_handle (), hMainProc, &nh, 0, TRUE, + if (!DuplicateHandle (from_proc, get_handle (), hMainProc, &nh, 0, TRUE, DUPLICATE_SAME_ACCESS)) { debug_printf ("dup(%s) failed, handle %x, %E", @@ -1282,7 +1286,6 @@ fhandler_base::dup (fhandler_base *child) VerifyHandle (nh); child->set_io_handle (nh); } - set_flags (child->get_flags ()); return 0; } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index ac1e4e9a9..90c17317a 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -296,7 +296,7 @@ class fhandler_base virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3))); virtual _off64_t lseek (_off64_t offset, int whence); virtual int lock (int, struct __flock64 *); - virtual int dup (fhandler_base *child); + virtual int dup (fhandler_base *child, HANDLE from_proc); virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, _off64_t off); @@ -466,7 +466,7 @@ class fhandler_socket: public fhandler_base int shutdown (int how); int close (); void hclose (HANDLE) {close ();} - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); void set_close_on_exec (bool val); virtual void fixup_before_fork_exec (DWORD); @@ -513,7 +513,7 @@ public: int open (int flags, mode_t mode = 0); int close (); void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);} - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); int ioctl (unsigned int cmd, void *); virtual void fixup_after_fork (HANDLE); void fixup_after_exec (); @@ -543,7 +543,7 @@ public: HANDLE& get_output_handle () { return output_handle; } void set_output_handle (HANDLE h) { output_handle = h; } void set_use (); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); bool is_slow () {return 1;} void close_one_end (); }; @@ -593,7 +593,7 @@ class fhandler_dev_raw: public fhandler_base int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); int ioctl (unsigned int cmd, void *buf); @@ -645,7 +645,7 @@ class fhandler_dev_tape: public fhandler_dev_raw virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); - virtual int dup (fhandler_base *child); + virtual int dup (fhandler_base *child, HANDLE from_proc); virtual void fixup_after_fork (HANDLE parent); virtual void set_close_on_exec (bool val); virtual int ioctl (unsigned int cmd, void *buf); @@ -726,7 +726,7 @@ class fhandler_serial: public fhandler_base int close (); void init (HANDLE h, DWORD a, mode_t flags); void overlapped_setup (); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); void raw_read (void *ptr, size_t& ulen); int raw_write (const void *ptr, size_t ulen); int tcsendbreak (int); @@ -909,7 +909,7 @@ class fhandler_console: public fhandler_termios int tcgetattr (struct termios *t); /* Special dup as we must dup two handles */ - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); int ioctl (unsigned int cmd, void *); void init (HANDLE, DWORD, mode_t); @@ -950,7 +950,7 @@ class fhandler_tty_common: public fhandler_termios DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms); void __release_output_mutex (const char *fn, int ln); - virtual int dup (fhandler_base *child); + virtual int dup (fhandler_base *child, HANDLE from_proc); tty *get_ttyp () { return (tty *) tc; } @@ -980,7 +980,7 @@ class fhandler_tty_slave: public fhandler_tty_common int tcflush (int); int ioctl (unsigned int cmd, void *); int close (); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); void fixup_after_fork (HANDLE parent); select_record *select_read (select_record *s); @@ -1071,7 +1071,7 @@ class fhandler_dev_random: public fhandler_base void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); _off64_t lseek (_off64_t offset, int whence); int close (); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); }; class fhandler_dev_mem: public fhandler_base @@ -1089,7 +1089,7 @@ class fhandler_dev_mem: public fhandler_base void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); _off64_t lseek (_off64_t offset, int whence); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, _off64_t off); int munmap (HANDLE h, caddr_t addr, size_t len); @@ -1113,7 +1113,7 @@ class fhandler_dev_clipboard: public fhandler_base _off64_t lseek (_off64_t offset, int whence); int close (); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); void fixup_after_exec (); }; @@ -1162,7 +1162,7 @@ class fhandler_dev_dsp: public fhandler_base int ioctl (unsigned int cmd, void *); _off64_t lseek (_off64_t, int); int close (); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); void fixup_after_fork (HANDLE parent); void fixup_after_exec (); private: @@ -1192,7 +1192,7 @@ class fhandler_virtual : public fhandler_base int write (const void *ptr, size_t len); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); _off64_t lseek (_off64_t, int); - int dup (fhandler_base *child); + int dup (fhandler_base *child, HANDLE from_proc); int open (int flags, mode_t mode = 0); int close (); int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2))); diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index e5b6ebe5f..9a9b51436 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -48,7 +48,7 @@ fhandler_dev_clipboard::fhandler_dev_clipboard () */ int -fhandler_dev_clipboard::dup (fhandler_base * child) +fhandler_dev_clipboard::dup (fhandler_base * child, HANDLE from_proc) { fhandler_dev_clipboard *fhc = (fhandler_dev_clipboard *) child; diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index f1e180a95..558e793e7 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -706,7 +706,7 @@ fhandler_console::close () */ int -fhandler_console::dup (fhandler_base *child) +fhandler_console::dup (fhandler_base *child, HANDLE from_proc) { fhandler_console *fhc = (fhandler_console *) child; diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc index 3813eeef9..f1a7524dc 100644 --- a/winsup/cygwin/fhandler_dsp.cc +++ b/winsup/cygwin/fhandler_dsp.cc @@ -1127,7 +1127,7 @@ fhandler_dev_dsp::close () } int -fhandler_dev_dsp::dup (fhandler_base * child) +fhandler_dev_dsp::dup (fhandler_base * child, HANDLE from_proc) { debug_printf (""); child->archetype = archetype; diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 694a51819..03b4f892c 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -179,14 +179,14 @@ out: } int -fhandler_fifo::dup (fhandler_base *child) +fhandler_fifo::dup (fhandler_base *child, HANDLE from_proc) { - int res = fhandler_pipe::dup (child); + int res = fhandler_pipe::dup (child, from_proc); if (!res) { fhandler_fifo *ff = (fhandler_fifo *) child; if (get_output_handle () - && !DuplicateHandle (hMainProc, get_output_handle (), hMainProc, + && !DuplicateHandle (from_proc, get_output_handle (), hMainProc, &ff->get_output_handle (), false, true, DUPLICATE_SAME_ACCESS)) { diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc index 58d67858d..c54c07bdb 100644 --- a/winsup/cygwin/fhandler_mem.cc +++ b/winsup/cygwin/fhandler_mem.cc @@ -408,9 +408,9 @@ fhandler_dev_mem::fstat (struct __stat64 *buf) } int -fhandler_dev_mem::dup (fhandler_base *child) +fhandler_dev_mem::dup (fhandler_base *child, HANDLE from_proc) { - int ret = fhandler_base::dup (child); + int ret = fhandler_base::dup (child, from_proc); if (! ret) { diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc index eecbe65bf..13d8fdfaa 100644 --- a/winsup/cygwin/fhandler_random.cc +++ b/winsup/cygwin/fhandler_random.cc @@ -156,7 +156,7 @@ fhandler_dev_random::close () } int -fhandler_dev_random::dup (fhandler_base *child) +fhandler_dev_random::dup (fhandler_base *child, HANDLE from_proc) { fhandler_dev_random *fhr = (fhandler_dev_random *) child; fhr->crypt_prov = (HCRYPTPROV)NULL; diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index fe27bbd91..196ebb531 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -321,9 +321,9 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len) } int -fhandler_dev_raw::dup (fhandler_base *child) +fhandler_dev_raw::dup (fhandler_base *child, HANDLE from_proc) { - int ret = fhandler_base::dup (child); + int ret = fhandler_base::dup (child, from_proc); if (! ret) { @@ -345,8 +345,9 @@ fhandler_dev_raw::dup (fhandler_base *child) } void -fhandler_dev_raw::fixup_after_fork (HANDLE) +fhandler_dev_raw::fixup_after_fork (HANDLE parent) { + fhandler_base::fixup_after_fork (parent); devbufstart = 0; devbufend = 0; lastblk_to_read (false); diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc index 785c8b69a..099f8e965 100644 --- a/winsup/cygwin/fhandler_serial.cc +++ b/winsup/cygwin/fhandler_serial.cc @@ -1069,11 +1069,11 @@ fhandler_serial::fixup_after_exec () } int -fhandler_serial::dup (fhandler_base *child) +fhandler_serial::dup (fhandler_base *child, HANDLE from_proc) { fhandler_serial *fhc = (fhandler_serial *) child; fhc->overlapped_setup (); fhc->vmin_ = vmin_; fhc->vtime_ = vtime_; - return fhandler_base::dup (child); + return fhandler_base::dup (child, from_proc); } diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index b5e5248ec..563db5347 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -27,6 +27,7 @@ #include "perprocess.h" #include "path.h" #include "fhandler.h" +#include "pinfo.h" #include "dtable.h" #include "cygheap.h" #include "sigproc.h" @@ -454,7 +455,7 @@ fhandler_socket::fixup_after_exec () } int -fhandler_socket::dup (fhandler_base *child) +fhandler_socket::dup (fhandler_base *child, HANDLE from_proc) { HANDLE nh; @@ -477,7 +478,7 @@ fhandler_socket::dup (fhandler_base *child) } fhs->connect_state (connect_state ()); - if (winsock2_active) + if (winsock2_active && from_proc == hMainProc) { /* Since WSADuplicateSocket() fails on NT systems when the process is currently impersonating a non-privileged account, we revert @@ -506,7 +507,7 @@ fhandler_socket::dup (fhandler_base *child) having winsock called from fhandler_base and it creates only inheritable sockets which is wrong for winsock2. */ - if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0, + if (!DuplicateHandle (from_proc, get_io_handle (), hMainProc, &nh, 0, !winsock2_active, DUPLICATE_SAME_ACCESS)) { system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ()); @@ -992,8 +993,9 @@ fhandler_socket::readv (const struct iovec *const iov, const int iovcnt, msg_namelen: 0, msg_iov: (struct iovec *) iov, // const_cast msg_iovlen: iovcnt, - msg_accrights: NULL, - msg_accrightslen: 0 + msg_control: NULL, + msg_controllen: 0, + msg_flags: 0 }; return recvmsg (&msg, 0, tot); @@ -1064,7 +1066,10 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot) go ahead recv'ing the normal data blocks. Otherwise start special handling for descriptor passing. */ /*TODO*/ - msg->msg_accrightslen = 0; + if (CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR) + ((struct OLD_msghdr *) msg)->msg_accrightslen = 0; + else + msg->msg_controllen = 0; } struct iovec *const iov = msg->msg_iov; @@ -1186,8 +1191,9 @@ fhandler_socket::writev (const struct iovec *const iov, const int iovcnt, msg_namelen: 0, msg_iov: (struct iovec *) iov, // const_cast msg_iovlen: iovcnt, - msg_accrights: NULL, - msg_accrightslen: 0 + msg_control: NULL, + msg_controllen: 0, + msg_flags: 0 }; return sendmsg (&msg, 0, tot); @@ -1263,13 +1269,64 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags, int fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot) { - if (get_addr_family () == AF_LOCAL) + struct cmsghdr *cmsg; + bool descriptors_inflight = false; + + if (get_addr_family () == AF_LOCAL + && get_socket_type () == SOCK_STREAM + && msg->msg_controllen > 0) /* Works for ancient msghdr, too. */ { - /* For AF_LOCAL/AF_UNIX sockets, if descriptors are given, start + /* For AF_LOCAL/SOCK_STREAM sockets, if descriptors are given, start the special handling for descriptor passing. Otherwise just transmit an empty string to tell the receiver that no descriptor passing is done. */ - /*TODO*/ + + /* NOTE: SOCK_DGRAMs are usually allowed, but we can't support them + unless credential passing works for SOCK_DGRAM sockets as well. + OTOH, since DGRAMs can be easily discarded, they are not reliable + and seldomly used anyway. */ + + struct msghdr lmsg; + + union { + struct cmsghdr cm; + char control[CMSG_SPACE (sizeof (int))]; + } control_un; + if (CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR) + { + memcpy (&lmsg, msg, sizeof *msg); + lmsg.msg_control = (void *) control_un.control; + lmsg.msg_controllen = sizeof control_un.control; + lmsg.msg_flags = 0; + cmsg = CMSG_FIRSTHDR (&lmsg); + cmsg->cmsg_len = CMSG_LEN (sizeof (int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *((int *) CMSG_DATA (cmsg)) = + *(int *) ((OLD_msghdr *) msg)->msg_accrights; + msg = &lmsg; + } + + pinfo p (sec_peer_pid); + if (!p) + { + set_errno (ENOTCONN); + return SOCKET_ERROR; + } + for (cmsg = CMSG_FIRSTHDR (msg); cmsg; cmsg = CMSG_NXTHDR (msg, cmsg)) + { + if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) + { + set_errno (ENOTSUP); + return SOCKET_ERROR; + } + int *fds = (int *) CMSG_DATA (cmsg); + int cnt = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr))) + / sizeof (int); + if (!p->send_descriptors (cnt, fds)) + return SOCKET_ERROR; + descriptors_inflight = true; + } } struct iovec *const iov = msg->msg_iov; @@ -1369,22 +1426,34 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot) } if (res == SOCKET_ERROR) - set_winsock_errno (); + { + set_winsock_errno (); + } else res = ret; } - /* Special handling for EPIPE and SIGPIPE. - - EPIPE is generated if the local end has been shut down on a connection - oriented socket. In this case the process will also receive a SIGPIPE - unless MSG_NOSIGNAL is set. */ - if (res == SOCKET_ERROR && get_errno () == ESHUTDOWN - && get_socket_type () == SOCK_STREAM) + if (res == SOCKET_ERROR) { - set_errno (EPIPE); - if (! (flags & MSG_NOSIGNAL)) - raise (SIGPIPE); + /* If sendmsg fails, destroy all inflight descriptors. */ + if (descriptors_inflight && WSAGetLastError () != WSAEWOULDBLOCK) + { + pinfo p (sec_peer_pid); + if (p) + p->destroy_inflight_descriptors (); + } + + /* Special handling for EPIPE and SIGPIPE. + + EPIPE is generated if the local end has been shut down on a connection + oriented socket. In this case the process will also receive a SIGPIPE + unless MSG_NOSIGNAL is set. */ + if (get_errno () == ESHUTDOWN && get_socket_type () == SOCK_STREAM) + { + set_errno (EPIPE); + if (! (flags & MSG_NOSIGNAL)) + raise (SIGPIPE); + } } return res; diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index d3fd3eee2..a0ab47457 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -1442,11 +1442,11 @@ fhandler_dev_tape::fstat (struct __stat64 *buf) } int -fhandler_dev_tape::dup (fhandler_base *child) +fhandler_dev_tape::dup (fhandler_base *child, HANDLE from_proc) { lock (-1); fhandler_dev_tape *fh = (fhandler_dev_tape *) child; - if (!DuplicateHandle (hMainProc, mt_mtx, hMainProc, &fh->mt_mtx, 0, TRUE, + if (!DuplicateHandle (from_proc, mt_mtx, hMainProc, &fh->mt_mtx, 0, TRUE, DUPLICATE_SAME_ACCESS)) { debug_printf ("dup(%s) failed, mutex handle %x, %E", @@ -1456,7 +1456,7 @@ fhandler_dev_tape::dup (fhandler_base *child) } fh->mt_evt = NULL; if (mt_evt && - !DuplicateHandle (hMainProc, mt_evt, hMainProc, &fh->mt_evt, 0, TRUE, + !DuplicateHandle (from_proc, mt_evt, hMainProc, &fh->mt_evt, 0, TRUE, DUPLICATE_SAME_ACCESS)) { debug_printf ("dup(%s) failed, event handle %x, %E", @@ -1464,7 +1464,7 @@ fhandler_dev_tape::dup (fhandler_base *child) __seterrno (); return unlock (-1); } - return unlock (fhandler_dev_raw::dup (child)); + return unlock (fhandler_dev_raw::dup (child, from_proc)); } void diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 5016c5a4f..2c7f1e8cd 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -915,9 +915,12 @@ fhandler_tty_slave::read (void *ptr, size_t& len) } int -fhandler_tty_slave::dup (fhandler_base *child) +fhandler_tty_slave::dup (fhandler_base *child, HANDLE from_proc) { fhandler_tty_slave *arch = (fhandler_tty_slave *) archetype; + if (!arch) /* Might happen on descriptor passing */ + return !((fhandler_tty_slave *) child)->open (get_flags (), 0); + *(fhandler_tty_slave *) child = *arch; child->usecount = 0; arch->usecount++; @@ -928,7 +931,7 @@ fhandler_tty_slave::dup (fhandler_base *child) } int -fhandler_tty_common::dup (fhandler_base *child) +fhandler_tty_common::dup (fhandler_base *child, HANDLE from_proc) { fhandler_tty_slave *fts = (fhandler_tty_slave *) child; int errind; @@ -941,7 +944,7 @@ fhandler_tty_common::dup (fhandler_base *child) if (output_done_event == NULL) fts->output_done_event = NULL; - else if (!DuplicateHandle (hMainProc, output_done_event, hMainProc, + else if (!DuplicateHandle (from_proc, output_done_event, hMainProc, &fts->output_done_event, 0, 1, DUPLICATE_SAME_ACCESS)) { @@ -950,7 +953,7 @@ fhandler_tty_common::dup (fhandler_base *child) } if (ioctl_request_event == NULL) fts->ioctl_request_event = NULL; - else if (!DuplicateHandle (hMainProc, ioctl_request_event, hMainProc, + else if (!DuplicateHandle (from_proc, ioctl_request_event, hMainProc, &fts->ioctl_request_event, 0, 1, DUPLICATE_SAME_ACCESS)) { @@ -959,35 +962,35 @@ fhandler_tty_common::dup (fhandler_base *child) } if (ioctl_done_event == NULL) fts->ioctl_done_event = NULL; - else if (!DuplicateHandle (hMainProc, ioctl_done_event, hMainProc, + else if (!DuplicateHandle (from_proc, ioctl_done_event, hMainProc, &fts->ioctl_done_event, 0, 1, DUPLICATE_SAME_ACCESS)) { errind = 3; goto err; } - if (!DuplicateHandle (hMainProc, input_available_event, hMainProc, + if (!DuplicateHandle (from_proc, input_available_event, hMainProc, &fts->input_available_event, 0, 1, DUPLICATE_SAME_ACCESS)) { errind = 4; goto err; } - if (!DuplicateHandle (hMainProc, output_mutex, hMainProc, + if (!DuplicateHandle (from_proc, output_mutex, hMainProc, &fts->output_mutex, 0, 1, DUPLICATE_SAME_ACCESS)) { errind = 5; goto err; } - if (!DuplicateHandle (hMainProc, input_mutex, hMainProc, + if (!DuplicateHandle (from_proc, input_mutex, hMainProc, &fts->input_mutex, 0, 1, DUPLICATE_SAME_ACCESS)) { errind = 6; goto err; } - if (!DuplicateHandle (hMainProc, get_handle (), hMainProc, + if (!DuplicateHandle (from_proc, get_handle (), hMainProc, &nh, 0, 1, DUPLICATE_SAME_ACCESS)) { @@ -996,7 +999,7 @@ fhandler_tty_common::dup (fhandler_base *child) } fts->set_io_handle (nh); - if (!DuplicateHandle (hMainProc, get_output_handle (), hMainProc, + if (!DuplicateHandle (from_proc, get_output_handle (), hMainProc, &nh, 0, 1, DUPLICATE_SAME_ACCESS)) { @@ -1007,7 +1010,7 @@ fhandler_tty_common::dup (fhandler_base *child) if (inuse == NULL) fts->inuse = NULL; - else if (!DuplicateHandle (hMainProc, inuse, hMainProc, + else if (!DuplicateHandle (from_proc, inuse, hMainProc, &fts->inuse, 0, 1, DUPLICATE_SAME_ACCESS)) { diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index 414d5c83f..3ff1dfff6 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -146,9 +146,9 @@ fhandler_virtual::lseek (_off64_t offset, int whence) } int -fhandler_virtual::dup (fhandler_base * child) +fhandler_virtual::dup (fhandler_base * child, HANDLE from_proc) { - int ret = fhandler_base::dup (child); + int ret = fhandler_base::dup (child, from_proc); if (!ret) { diff --git a/winsup/cygwin/include/cygwin/socket.h b/winsup/cygwin/include/cygwin/socket.h index f6dc11353..d0344c085 100644 --- a/winsup/cygwin/include/cygwin/socket.h +++ b/winsup/cygwin/include/cygwin/socket.h @@ -1,6 +1,6 @@ /* cygwin/socket.h - Copyright 1999, 2000, 2001 Red Hat, Inc. + Copyright 1999, 2000, 2001, 2005 Red Hat, Inc. This file is part of Cygwin. @@ -32,11 +32,59 @@ struct ucred { }; struct linger { - unsigned short l_onoff; /* Linger active */ - unsigned short l_linger; /* How long to linger for */ + unsigned short l_onoff; /* Linger active */ + unsigned short l_linger; /* How long to linger for */ }; struct msghdr +{ + void * msg_name; /* Socket name */ + int msg_namelen; /* Length of name */ + struct iovec * msg_iov; /* Data blocks */ + int msg_iovlen; /* Number of blocks */ + void * msg_control; /* Ancillary data */ + size_t msg_controllen; /* Ancillary data length */ + int msg_flags; /* Received flags on recvmsg */ +}; + +struct cmsghdr +{ + size_t cmsg_len; /* Length of cmsghdr + data */ + int cmsg_level; /* Protocol */ + int cmsg_type; /* Protocol type */ +}; + +#define CMSG_ALIGN(len) \ + (((len) + sizeof (size_t) - 1) & ~(sizeof (size_t) - 1)) +#define CMSG_LEN(len) \ + (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) +#define CMSG_SPACE(len) \ + (CMSG_ALIGN (sizeof (struct cmsghdr)) + CMSG_ALIGN(len)) +#define CMSG_FIRSTHDR(mhdr) \ + ({ \ + struct msghdr *_m = (struct msghdr *) mhdr; \ + (_m)->msg_controllen >= sizeof (struct cmsghdr) \ + ? (struct cmsghdr *) (_m)->msg_control \ + : (struct cmsghdr *) NULL; \ + }) +#define CMSG_NXTHDR(mhdr,cmsg) \ + ({ \ + struct msghdr *_m = (struct msghdr *) mhdr; \ + struct cmsghdr *_c = (struct cmsghdr *) cmsg; \ + ((char *) _c + CMSG_SPACE (_c->cmsg_len) \ + > (char *) _m->msg_control + _m->msg_controllen) \ + ? (struct cmsghdr *) NULL \ + : (struct cmsghdr *) ((char *) _c + CMSG_ALIGN (_c->cmsg_len)); \ + }) +#define CMSG_DATA(cmsg) \ + ((unsigned char *) ((struct cmsghdr *)(cmsg) + 1)) + +/* "Socket"-level control message types: */ +#define SCM_RIGHTS 0x01 /* access rights (array of int) */ + +#ifdef __INSIDE_CYGWIN__ +/* Definition of struct msghdr up to release 1.5.18 */ +struct OLD_msghdr { void * msg_name; /* Socket name */ int msg_namelen; /* Length of name */ @@ -45,6 +93,7 @@ struct msghdr void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */ int msg_accrightslen; /* Length of rights list */ }; +#endif #ifndef socklen_t #define socklen_t int diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 7984df7f2..7111ef812 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -88,6 +88,10 @@ details. */ #define CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES \ (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) >= \ 79) + +#define CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR \ + (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \ + 132) /* We used to use the DLL major/minor to track non-backward-compatible interface changes to the API. Now we use an API major/minor number for this purpose. */ @@ -268,6 +272,10 @@ details. */ 138: Export readdir_r. */ + /* + 133: Start using POSIX definition of struct msghdr. + */ + /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index 5a43df538..f03bb2925 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -507,4 +507,8 @@ extern "C" VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR); ULONG NTAPI RtlNtStatusToDosError (NTSTATUS); ULONG WINAPI RtlIsDosDeviceName_U (PCWSTR); + ULONG WINAPI RtlDosPathNameToNtPathName_U (PCWSTR, PUNICODE_STRING, + PCWSTR *, PUNICODE_STRING); + ULONG WINAPI RtlCreateUnicodeStringFromAsciiz (PUNICODE_STRING, PCSTR); + ULONG WINAPI RtlFreeUnicodeString (PUNICODE_STRING); } diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 6b1e44cbd..cec315b74 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -75,6 +75,7 @@ details. */ #include "shared_info.h" #include "registry.h" #include "cygtls.h" +#include "ntdll.h" #include static int normalize_win32_path (const char *, char *, char *&); @@ -488,25 +489,29 @@ path_conv::set_normalized_path (const char *path_copy, bool strip_tail) PUNICODE_STRING path_conv::get_nt_native_path (UNICODE_STRING &upath) { - if (path[0] != '\\') /* X:\... or NUL, etc. */ + if (path[0] == '\\' && path[1] != '\\') { - str2uni_cat (upath, "\\??\\"); - str2uni_cat (upath, path); + /* This handles all paths already given in NT speak. On writing this + comment, these are the raw device paths. */ + if (RtlCreateUnicodeStringFromAsciiz (&upath, path)) + return &upath; } - else if (path[1] != '\\') /* \Device\... */ - str2uni_cat (upath, path); - else if (path[2] != '.' - || path[3] != '\\') /* \\server\share\... */ - { - str2uni_cat (upath, "\\??\\UNC\\"); - str2uni_cat (upath, path + 2); - } - else /* \\.\device */ + else { - str2uni_cat (upath, "\\??\\"); - str2uni_cat (upath, path + 4); + wchar_t wc_path[CYG_MAX_PATH]; + sys_mbstowcs (wc_path, path, CYG_MAX_PATH); + if (RtlDosPathNameToNtPathName_U (wc_path, &upath, NULL, NULL)) + { +#ifdef DEBUGGING + char nt_path[CYG_MAX_PATH + 7]; + sys_wcstombs (nt_path, upath.Buffer, CYG_MAX_PATH + 7); + debug_printf ("DOS: <%s> NT: <%s>", path, nt_path); +#endif + return &upath; + } } - return &upath; + set_errno (ENOMEM); + return NULL; } /* Convert an arbitrary path SRC to a pure Win32 path, suitable for diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 2dd727ba1..ec0e22bf8 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -385,39 +385,18 @@ _pinfo::commune_recv () char path[CYG_MAX_PATH]; DWORD nr; DWORD code; - HANDLE hp; - HANDLE __fromthem = NULL; - HANDLE __tothem = NULL; - hp = OpenProcess (PROCESS_DUP_HANDLE, false, dwProcessId); - if (!hp) - { - sigproc_printf ("couldn't open handle for pid %d(%u)", pid, dwProcessId); - hello_pid = -1; - return; - } - if (!DuplicateHandle (hp, fromthem, hMainProc, &__fromthem, 0, false, DUPLICATE_SAME_ACCESS)) - { - sigproc_printf ("couldn't duplicate fromthem, %E"); - CloseHandle (hp); - hello_pid = -1; - return; - } + /* Don't remove. It's necessary to copy to local variables for process + synchronization. */ + HANDLE __fromthem = this->__fromthem; + HANDLE __tothem = this->__tothem; + HANDLE __them = this->__them; + HANDLE __gotit = this->__gotit; - if (!DuplicateHandle (hp, tothem, hMainProc, &__tothem, 0, false, DUPLICATE_SAME_ACCESS)) - { - sigproc_printf ("couldn't duplicate tothem, %E"); - CloseHandle (__fromthem); - CloseHandle (hp); - hello_pid = -1; - return; - } - - hello_pid = 0; + SetEvent (__gotit); if (!ReadFile (__fromthem, &code, sizeof code, &nr, NULL) || nr != sizeof code) { - CloseHandle (hp); /* __seterrno ();*/ // this is run from the signal thread, so don't set errno goto out; } @@ -431,7 +410,6 @@ _pinfo::commune_recv () extern int __argc_safe; const char *argv[__argc_safe + 1]; - CloseHandle (hp); for (int i = 0; i < __argc_safe; i++) { if (IsBadStringPtr (__argv[i], INT32_MAX)) @@ -463,7 +441,6 @@ _pinfo::commune_recv () case PICOM_CWD: { CloseHandle (__fromthem); __fromthem = NULL; - CloseHandle (hp); unsigned int n = strlen (cygheap->cwd.get (path, 1, 1, CYG_MAX_PATH)) + 1; if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL)) @@ -475,7 +452,6 @@ _pinfo::commune_recv () case PICOM_ROOT: { CloseHandle (__fromthem); __fromthem = NULL; - CloseHandle (hp); unsigned int n; if (cygheap->root.exists ()) n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1; @@ -490,7 +466,6 @@ _pinfo::commune_recv () case PICOM_FDS: { CloseHandle (__fromthem); __fromthem = NULL; - CloseHandle (hp); unsigned int n = 0; int fd; cygheap_fdenum cfd; @@ -515,11 +490,9 @@ _pinfo::commune_recv () || nr != sizeof hdl) { sigproc_printf ("ReadFile hdl failed, %E"); - CloseHandle (hp); goto out; } CloseHandle (__fromthem); __fromthem = NULL; - CloseHandle (hp); unsigned int n = 0; cygheap_fdenum cfd; while (cfd.next () >= 0) @@ -543,11 +516,9 @@ _pinfo::commune_recv () || nr != sizeof fd) { sigproc_printf ("ReadFile fd failed, %E"); - CloseHandle (hp); goto out; } CloseHandle (__fromthem); __fromthem = NULL; - CloseHandle (hp); unsigned int n = 0; cygheap_fdget cfd (fd); if (cfd < 0) @@ -566,7 +537,6 @@ _pinfo::commune_recv () if (!ReadFile (__fromthem, &len, sizeof len, &nr, NULL) || nr != sizeof len) { - CloseHandle (hp); /* __seterrno ();*/ // this is run from the signal thread, so don't set errno goto out; } @@ -574,7 +544,6 @@ _pinfo::commune_recv () if (!ReadFile (__fromthem, path, len, &nr, NULL) || nr != len) { - CloseHandle (hp); /* __seterrno ();*/ // this is run from the signal thread, so don't set errno goto out; } @@ -588,7 +557,7 @@ _pinfo::commune_recv () it[0] = fh->get_handle (); it[1] = fh->get_output_handle (); for (int i = 0; i < 2; i++) - if (!DuplicateHandle (hMainProc, it[i], hp, &it[i], 0, false, + if (!DuplicateHandle (hMainProc, it[i], __them, &it[i], 0, false, DUPLICATE_SAME_ACCESS)) { it[0] = it[1] = NULL; /* FIXME: possibly left a handle open in child? */ @@ -598,7 +567,6 @@ _pinfo::commune_recv () fh->close_one_end (); /* FIXME: not quite right - need more handshaking */ } - CloseHandle (hp); if (!WriteFile (__tothem, it, sizeof (it), &nr, NULL)) { /*__seterrno ();*/ // this is run from the signal thread, so don't set errno @@ -611,10 +579,10 @@ _pinfo::commune_recv () } out: - if (__fromthem) - CloseHandle (__fromthem); - if (__tothem) - CloseHandle (__tothem); + CloseHandle (__fromthem); + CloseHandle (__tothem); + CloseHandle (__them); + CloseHandle (__gotit); } #define PIPEBUFSIZE (4096 * sizeof (DWORD)) @@ -663,31 +631,49 @@ _pinfo::commune_send (DWORD code, ...) if (sig_send (this, __SIGCOMMUNE)) goto err; - /* FIXME: Need something better than an busy loop here */ - bool isalive; - for (int i = 0; (isalive = alive ()) && (i < 10000); i++) - if (myself->hello_pid <= 0) - break; - else - low_priority_sleep (0); - - CloseHandle (tome); - tome = NULL; - CloseHandle (fromme); - fromme = NULL; - - if (!isalive) - { - set_errno (ESRCH); - goto err; - } + { + bool isalive = true; + HANDLE w4[2] = { myself->gotit, myself->them }; + /* FIXME: How long should we wait here? */ + switch (WaitForMultipleObjects (2, w4, false, INFINITE)) + { + case WAIT_OBJECT_0: + myself->hello_pid = 0; + break; + case WAIT_OBJECT_0 + 1: + isalive = false; + break; + default: + debug_printf ("WFMO failed with %E"); + myself->hello_pid = -1; + break; + } - if (myself->hello_pid < 0) - { - set_errno (ENOSYS); - goto err; - } + CloseHandle (tome); + tome = NULL; + CloseHandle (fromme); + fromme = NULL; + CloseHandle (myself->them); + myself->them = NULL; + CloseHandle (myself->gotit); + myself->gotit = NULL; + myself->__tothem = NULL; + myself->__fromthem = NULL; + myself->__them = NULL; + myself->__gotit = NULL; + + if (!isalive) + { + set_errno (ESRCH); + goto err; + } + if (myself->hello_pid < 0) + { + set_errno (ENOSYS); + goto err; + } + } size_t n; switch (code) { @@ -785,6 +771,7 @@ err: out: myself->hello_pid = 0; + tothem = fromthem = NULL; myself.unlock (); return res; } @@ -926,6 +913,44 @@ _pinfo::cmdline (size_t& n) return s; } +bool +_pinfo::send_descriptors (int cnt, int *fds) +{ + HANDLE target_proc; + HANDLE my_proc; + + /* First try to create a handle of this process into the space of the + target process which allows the target process to duplicate handles. + If this fails, the target process will try the same. */ + for (int i = 0; i < cnt; ++i) + { + cygheap_fdget cfd (fds[i]); + if (cfd < 0) + { + set_errno (ENOENT); + goto fault; + } + + } + return true; + +fault: + destroy_inflight_descriptors (); + return false; +} + +void +_pinfo::destroy_inflight_descriptors () +{ +} + +#if 0 +bool +_pinfo::recv_descriptors () +{ +} +#endif + /* This is the workhorse which waits for the write end of the pipe created during new process creation. If the pipe is closed or a zero is received on the pipe, it is assumed that the cygwin pid has exited. diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 564f6f798..b603f409f 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -91,6 +91,12 @@ public: pid_t hello_pid; HANDLE tothem; HANDLE fromthem; + HANDLE __tothem; + HANDLE __fromthem; + HANDLE them; + HANDLE __them; + HANDLE gotit; + HANDLE __gotit; inline void set_has_pgid_children () { @@ -119,6 +125,8 @@ public: char *root (size_t &); char *cwd (size_t &); char *cmdline (size_t &); + bool send_descriptors (int, int *); + void destroy_inflight_descriptors (); void set_ctty (class tty_min *, int, class fhandler_tty_slave *); bool dup_proc_pipe (HANDLE) __attribute__ ((regparm(2))); void sync_proc_pipe (); diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 3407f0945..eb6287008 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -60,7 +60,7 @@ fhandler_pipe::open (int flags, mode_t mode) set_errno (EACCES); return 0; } - if (!cfd->dup (this)) + if (!cfd->dup (this, hMainProc)) return 1; return 0; } @@ -246,7 +246,7 @@ debug_printf ("here"); } int -fhandler_pipe::dup (fhandler_base *child) +fhandler_pipe::dup (fhandler_base *child, HANDLE from_proc) { int res = -1; fhandler_pipe *ftp = (fhandler_pipe *) child; @@ -254,14 +254,14 @@ fhandler_pipe::dup (fhandler_base *child) if (get_handle ()) { - res = fhandler_base::dup (child); + res = fhandler_base::dup (child, from_proc); if (res) goto err; } if (guard == NULL) ftp->guard = NULL; - else if (!DuplicateHandle (hMainProc, guard, hMainProc, &ftp->guard, 0, 1, + else if (!DuplicateHandle (from_proc, guard, hMainProc, &ftp->guard, 0, 1, DUPLICATE_SAME_ACCESS)) { debug_printf ("couldn't duplicate guard %p, %E", guard); @@ -270,7 +270,7 @@ fhandler_pipe::dup (fhandler_base *child) if (writepipe_exists == NULL) ftp->writepipe_exists = NULL; - else if (!DuplicateHandle (hMainProc, writepipe_exists, hMainProc, + else if (!DuplicateHandle (from_proc, writepipe_exists, hMainProc, &ftp->writepipe_exists, 0, 1, DUPLICATE_SAME_ACCESS)) { @@ -280,7 +280,7 @@ fhandler_pipe::dup (fhandler_base *child) if (read_state == NULL) ftp->read_state = NULL; - else if (!DuplicateHandle (hMainProc, read_state, hMainProc, + else if (!DuplicateHandle (from_proc, read_state, hMainProc, &ftp->read_state, 0, 0, DUPLICATE_SAME_ACCESS)) { diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index e27fccdd9..bc21c33ec 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -582,7 +582,8 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) sigproc_printf ("sendsig handle never materialized"); goto out; } - HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, dwProcessId); + HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE | SYNCHRONIZE, + false, dwProcessId); if (!hp) { __seterrno (); @@ -598,7 +599,59 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) CloseHandle (hp); goto out; } - CloseHandle (hp); + if (si.si_signo == __SIGCOMMUNE) + { + if (!(myself->gotit = CreateEvent (&sec_none_nih, true, false, NULL))) + { + __seterrno (); + sigproc_printf ("CreateEvent failed, %E"); + CloseHandle (hp); + goto out; + } + if (!DuplicateHandle (hMainProc, myself->gotit, hp, + &myself->__gotit, false, 0, + DUPLICATE_SAME_ACCESS)) + { + __seterrno (); + sigproc_printf ("DuplicateHandle failed, %E"); + CloseHandle (myself->gotit); + CloseHandle (hp); + goto out; + } + if (!DuplicateHandle (hMainProc, myself->tothem, hp, + &myself->__tothem, false, 0, + DUPLICATE_SAME_ACCESS)) + { + __seterrno (); + sigproc_printf ("DuplicateHandle failed, %E"); + CloseHandle (myself->gotit); + CloseHandle (hp); + goto out; + } + if (!DuplicateHandle (hMainProc, myself->fromthem, hp, + &myself->__fromthem, false, 0, + DUPLICATE_SAME_ACCESS)) + { + __seterrno (); + sigproc_printf ("DuplicateHandle failed, %E"); + CloseHandle (myself->gotit); + CloseHandle (hp); + goto out; + } + if (!DuplicateHandle (hMainProc, hMainProc, hp, + &myself->__them, false, 0, + DUPLICATE_SAME_ACCESS)) + { + __seterrno (); + sigproc_printf ("DuplicateHandle failed, %E"); + CloseHandle (myself->gotit); + CloseHandle (hp); + goto out; + } + myself->them = hp; + } + else + CloseHandle (hp); VerifyHandle (sendsig); } diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index a062c2ac2..0a9eb35c2 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -623,6 +623,57 @@ static NO_COPY wincaps wincap_2003 = { has_null_console_handler_routine:true }; +static NO_COPY wincaps wincap_vista = { + lock_file_highword:UINT32_MAX, + chunksize:0, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + is_winnt:true, + is_server:false, + access_denied_on_delete:false, + has_delete_on_close:true, + has_page_guard:true, + has_security:true, + has_security_descriptor_control:true, + has_get_process_times:true, + has_lseek_bug:false, + has_lock_file_ex:true, + has_signal_object_and_wait:true, + has_eventlog:true, + has_ip_helper_lib:true, + has_set_handle_information:true, + has_set_handle_information_on_console_handles:true, + supports_smp:true, + map_view_of_file_ex_sucks:false, + altgr_is_ctrl_alt:true, + has_physical_mem_access:true, + has_working_copy_on_write:true, + share_mmaps_only_by_name:false, + virtual_protect_works_on_shared_pages:true, + has_hard_links:true, + can_open_directories:true, + has_move_file_ex:true, + has_negative_pids:false, + has_unreliable_pipes:false, + has_named_pipes:true, + has_try_enter_critical_section:true, + has_raw_devices:true, + has_valid_processorlevel:true, + has_64bit_file_access:true, + has_process_io_counters:true, + supports_reading_modem_output_lines:true, + needs_memory_protection:true, + pty_needs_alloc_console:true, + has_terminal_services:true, + has_switch_to_thread:true, + cant_debug_dll_entry:false, + has_ioctl_storage_get_media_types_ex:true, + start_proc_suspended:false, + has_extended_priority_class:true, + has_guid_volumes:true, + detect_win16_exe:false, + has_null_console_handler_routine:true +}; + wincapc wincap; void @@ -676,6 +727,11 @@ wincapc::init () caps = &wincap_2003; } break; + case 6: + os = "NT"; + has_osversioninfoex = true; + caps = &wincap_vista; + break; default: os = "??"; caps = &wincap_unknown; -- cgit v1.2.3