* 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.
This commit is contained in:
Corinna Vinschen 2005-09-28 19:02:53 +00:00
parent 280fdd0b67
commit 1204c515fe
26 changed files with 500 additions and 172 deletions

View File

@ -1,3 +1,44 @@
2005-09-28 Corinna Vinschen <corinna@vinschen.de>
* 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 <cgf@timesys.com> 2005-09-28 Christopher Faylor <cgf@timesys.com>
* dcrt0.cc (getstack): New function. * dcrt0.cc (getstack): New function.

View File

@ -404,6 +404,9 @@ LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1) LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1) LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
LoadDLLfuncEx (RtlIsDosDeviceName_U, 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 (EnumProcessModules, 16, psapi, 1)
LoadDLLfuncEx (GetModuleFileNameExA, 16, psapi, 1) LoadDLLfuncEx (GetModuleFileNameExA, 16, psapi, 1)

View File

@ -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 * fhandler_base *
build_fh_name (const char *name, HANDLE h, unsigned opt, suffix_info *si) 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 = *oldfh;
newfh->set_io_handle (NULL); newfh->set_io_handle (NULL);
if (oldfh->dup (newfh)) if (oldfh->dup (newfh, hMainProc))
{ {
cfree (newfh); cfree (newfh);
debug_printf ("oldfh->dup failed"); debug_printf ("oldfh->dup failed");

View File

@ -555,12 +555,13 @@ fhandler_base::open (int flags, mode_t mode)
if (!wincap.is_winnt ()) if (!wincap.is_winnt ())
return fhandler_base::open_9x (flags, mode); return fhandler_base::open_9x (flags, mode);
WCHAR wpath[CYG_MAX_PATH + 10]; UNICODE_STRING upath;
UNICODE_STRING upath = {0, sizeof (wpath), wpath}; if (!pc.get_nt_native_path (upath))
pc.get_nt_native_path (upath); {
syscall_printf ("0 = fhandler_base::open (%s, %p)",
if (RtlIsDosDeviceName_U (upath.Buffer)) get_win32_name (), flags);
return fhandler_base::open_9x (flags, mode); return 0;
}
int res = 0; int res = 0;
HANDLE x; HANDLE x;
@ -576,7 +577,8 @@ fhandler_base::open (int flags, mode_t mode)
syscall_printf ("(%s, %p)", get_win32_name (), flags); 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); sa.lpSecurityDescriptor, NULL);
switch (query_open ()) switch (query_open ())
@ -681,6 +683,7 @@ done:
syscall_printf ("%d = fhandler_base::open (%s, %p)", res, get_win32_name (), syscall_printf ("%d = fhandler_base::open (%s, %p)", res, get_win32_name (),
flags); flags);
RtlFreeUnicodeString (&upath);
return res; return res;
} }
@ -1263,14 +1266,15 @@ fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
} }
int int
fhandler_base::dup (fhandler_base *child) fhandler_base::dup (fhandler_base *child, HANDLE from_proc)
{ {
debug_printf ("in fhandler_base dup"); debug_printf ("in fhandler_base dup");
HANDLE nh; HANDLE nh;
set_flags (child->get_flags ());
if (!nohandle ()) if (!nohandle ())
{ {
if (!DuplicateHandle (hMainProc, get_handle (), hMainProc, &nh, 0, TRUE, if (!DuplicateHandle (from_proc, get_handle (), hMainProc, &nh, 0, TRUE,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
debug_printf ("dup(%s) failed, handle %x, %E", debug_printf ("dup(%s) failed, handle %x, %E",
@ -1282,7 +1286,6 @@ fhandler_base::dup (fhandler_base *child)
VerifyHandle (nh); VerifyHandle (nh);
child->set_io_handle (nh); child->set_io_handle (nh);
} }
set_flags (child->get_flags ());
return 0; return 0;
} }

View File

@ -296,7 +296,7 @@ class fhandler_base
virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3))); virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
virtual _off64_t lseek (_off64_t offset, int whence); virtual _off64_t lseek (_off64_t offset, int whence);
virtual int lock (int, struct __flock64 *); 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, virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
int flags, _off64_t off); int flags, _off64_t off);
@ -466,7 +466,7 @@ class fhandler_socket: public fhandler_base
int shutdown (int how); int shutdown (int how);
int close (); int close ();
void hclose (HANDLE) {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); void set_close_on_exec (bool val);
virtual void fixup_before_fork_exec (DWORD); virtual void fixup_before_fork_exec (DWORD);
@ -513,7 +513,7 @@ public:
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int close (); int close ();
void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);} 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 *); int ioctl (unsigned int cmd, void *);
virtual void fixup_after_fork (HANDLE); virtual void fixup_after_fork (HANDLE);
void fixup_after_exec (); void fixup_after_exec ();
@ -543,7 +543,7 @@ public:
HANDLE& get_output_handle () { return output_handle; } HANDLE& get_output_handle () { return output_handle; }
void set_output_handle (HANDLE h) { output_handle = h; } void set_output_handle (HANDLE h) { output_handle = h; }
void set_use (); void set_use ();
int dup (fhandler_base *child); int dup (fhandler_base *child, HANDLE from_proc);
bool is_slow () {return 1;} bool is_slow () {return 1;}
void close_one_end (); 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 __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); 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 __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 fixup_after_fork (HANDLE parent);
virtual void set_close_on_exec (bool val); virtual void set_close_on_exec (bool val);
virtual int ioctl (unsigned int cmd, void *buf); virtual int ioctl (unsigned int cmd, void *buf);
@ -726,7 +726,7 @@ class fhandler_serial: public fhandler_base
int close (); int close ();
void init (HANDLE h, DWORD a, mode_t flags); void init (HANDLE h, DWORD a, mode_t flags);
void overlapped_setup (); void overlapped_setup ();
int dup (fhandler_base *child); int dup (fhandler_base *child, HANDLE from_proc);
void raw_read (void *ptr, size_t& ulen); void raw_read (void *ptr, size_t& ulen);
int raw_write (const void *ptr, size_t ulen); int raw_write (const void *ptr, size_t ulen);
int tcsendbreak (int); int tcsendbreak (int);
@ -909,7 +909,7 @@ class fhandler_console: public fhandler_termios
int tcgetattr (struct termios *t); int tcgetattr (struct termios *t);
/* Special dup as we must dup two handles */ /* 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 *); int ioctl (unsigned int cmd, void *);
void init (HANDLE, DWORD, mode_t); 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); DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
void __release_output_mutex (const char *fn, int ln); 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; } tty *get_ttyp () { return (tty *) tc; }
@ -980,7 +980,7 @@ class fhandler_tty_slave: public fhandler_tty_common
int tcflush (int); int tcflush (int);
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, HANDLE from_proc);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
select_record *select_read (select_record *s); 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))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
_off64_t lseek (_off64_t offset, int whence); _off64_t lseek (_off64_t offset, int whence);
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, HANDLE from_proc);
}; };
class fhandler_dev_mem: public fhandler_base 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))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
_off64_t lseek (_off64_t offset, int whence); _off64_t lseek (_off64_t offset, int whence);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); 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); 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); 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); _off64_t lseek (_off64_t offset, int whence);
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, HANDLE from_proc);
void fixup_after_exec (); void fixup_after_exec ();
}; };
@ -1162,7 +1162,7 @@ class fhandler_dev_dsp: public fhandler_base
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
_off64_t lseek (_off64_t, int); _off64_t lseek (_off64_t, int);
int close (); int close ();
int dup (fhandler_base *child); int dup (fhandler_base *child, HANDLE from_proc);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
void fixup_after_exec (); void fixup_after_exec ();
private: private:
@ -1192,7 +1192,7 @@ class fhandler_virtual : public fhandler_base
int write (const void *ptr, size_t len); int write (const void *ptr, size_t len);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
_off64_t lseek (_off64_t, int); _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 open (int flags, mode_t mode = 0);
int close (); int close ();
int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));

View File

@ -48,7 +48,7 @@ fhandler_dev_clipboard::fhandler_dev_clipboard ()
*/ */
int 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; fhandler_dev_clipboard *fhc = (fhandler_dev_clipboard *) child;

View File

@ -706,7 +706,7 @@ fhandler_console::close ()
*/ */
int int
fhandler_console::dup (fhandler_base *child) fhandler_console::dup (fhandler_base *child, HANDLE from_proc)
{ {
fhandler_console *fhc = (fhandler_console *) child; fhandler_console *fhc = (fhandler_console *) child;

View File

@ -1127,7 +1127,7 @@ fhandler_dev_dsp::close ()
} }
int int
fhandler_dev_dsp::dup (fhandler_base * child) fhandler_dev_dsp::dup (fhandler_base * child, HANDLE from_proc)
{ {
debug_printf (""); debug_printf ("");
child->archetype = archetype; child->archetype = archetype;

View File

@ -179,14 +179,14 @@ out:
} }
int 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) if (!res)
{ {
fhandler_fifo *ff = (fhandler_fifo *) child; fhandler_fifo *ff = (fhandler_fifo *) child;
if (get_output_handle () if (get_output_handle ()
&& !DuplicateHandle (hMainProc, get_output_handle (), hMainProc, && !DuplicateHandle (from_proc, get_output_handle (), hMainProc,
&ff->get_output_handle (), false, true, &ff->get_output_handle (), false, true,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {

View File

@ -408,9 +408,9 @@ fhandler_dev_mem::fstat (struct __stat64 *buf)
} }
int 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) if (! ret)
{ {

View File

@ -156,7 +156,7 @@ fhandler_dev_random::close ()
} }
int 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; fhandler_dev_random *fhr = (fhandler_dev_random *) child;
fhr->crypt_prov = (HCRYPTPROV)NULL; fhr->crypt_prov = (HCRYPTPROV)NULL;

View File

@ -321,9 +321,9 @@ fhandler_dev_raw::raw_write (const void *ptr, size_t len)
} }
int 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) if (! ret)
{ {
@ -345,8 +345,9 @@ fhandler_dev_raw::dup (fhandler_base *child)
} }
void void
fhandler_dev_raw::fixup_after_fork (HANDLE) fhandler_dev_raw::fixup_after_fork (HANDLE parent)
{ {
fhandler_base::fixup_after_fork (parent);
devbufstart = 0; devbufstart = 0;
devbufend = 0; devbufend = 0;
lastblk_to_read (false); lastblk_to_read (false);

View File

@ -1069,11 +1069,11 @@ fhandler_serial::fixup_after_exec ()
} }
int int
fhandler_serial::dup (fhandler_base *child) fhandler_serial::dup (fhandler_base *child, HANDLE from_proc)
{ {
fhandler_serial *fhc = (fhandler_serial *) child; fhandler_serial *fhc = (fhandler_serial *) child;
fhc->overlapped_setup (); fhc->overlapped_setup ();
fhc->vmin_ = vmin_; fhc->vmin_ = vmin_;
fhc->vtime_ = vtime_; fhc->vtime_ = vtime_;
return fhandler_base::dup (child); return fhandler_base::dup (child, from_proc);
} }

View File

@ -27,6 +27,7 @@
#include "perprocess.h" #include "perprocess.h"
#include "path.h" #include "path.h"
#include "fhandler.h" #include "fhandler.h"
#include "pinfo.h"
#include "dtable.h" #include "dtable.h"
#include "cygheap.h" #include "cygheap.h"
#include "sigproc.h" #include "sigproc.h"
@ -454,7 +455,7 @@ fhandler_socket::fixup_after_exec ()
} }
int int
fhandler_socket::dup (fhandler_base *child) fhandler_socket::dup (fhandler_base *child, HANDLE from_proc)
{ {
HANDLE nh; HANDLE nh;
@ -477,7 +478,7 @@ fhandler_socket::dup (fhandler_base *child)
} }
fhs->connect_state (connect_state ()); fhs->connect_state (connect_state ());
if (winsock2_active) if (winsock2_active && from_proc == hMainProc)
{ {
/* Since WSADuplicateSocket() fails on NT systems when the process /* Since WSADuplicateSocket() fails on NT systems when the process
is currently impersonating a non-privileged account, we revert 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 having winsock called from fhandler_base and it creates only
inheritable sockets which is wrong for winsock2. */ 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)) !winsock2_active, DUPLICATE_SAME_ACCESS))
{ {
system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ()); 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_namelen: 0,
msg_iov: (struct iovec *) iov, // const_cast msg_iov: (struct iovec *) iov, // const_cast
msg_iovlen: iovcnt, msg_iovlen: iovcnt,
msg_accrights: NULL, msg_control: NULL,
msg_accrightslen: 0 msg_controllen: 0,
msg_flags: 0
}; };
return recvmsg (&msg, 0, tot); 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 go ahead recv'ing the normal data blocks. Otherwise start
special handling for descriptor passing. */ special handling for descriptor passing. */
/*TODO*/ /*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; 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_namelen: 0,
msg_iov: (struct iovec *) iov, // const_cast msg_iov: (struct iovec *) iov, // const_cast
msg_iovlen: iovcnt, msg_iovlen: iovcnt,
msg_accrights: NULL, msg_control: NULL,
msg_accrightslen: 0 msg_controllen: 0,
msg_flags: 0
}; };
return sendmsg (&msg, 0, tot); return sendmsg (&msg, 0, tot);
@ -1263,13 +1269,64 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
int int
fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot) 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 the special handling for descriptor passing. Otherwise just
transmit an empty string to tell the receiver that no transmit an empty string to tell the receiver that no
descriptor passing is done. */ 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; 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) if (res == SOCKET_ERROR)
set_winsock_errno (); {
set_winsock_errno ();
}
else else
res = ret; res = ret;
} }
/* Special handling for EPIPE and SIGPIPE. if (res == SOCKET_ERROR)
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)
{ {
set_errno (EPIPE); /* If sendmsg fails, destroy all inflight descriptors. */
if (! (flags & MSG_NOSIGNAL)) if (descriptors_inflight && WSAGetLastError () != WSAEWOULDBLOCK)
raise (SIGPIPE); {
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; return res;

View File

@ -1442,11 +1442,11 @@ fhandler_dev_tape::fstat (struct __stat64 *buf)
} }
int int
fhandler_dev_tape::dup (fhandler_base *child) fhandler_dev_tape::dup (fhandler_base *child, HANDLE from_proc)
{ {
lock (-1); lock (-1);
fhandler_dev_tape *fh = (fhandler_dev_tape *) child; 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)) DUPLICATE_SAME_ACCESS))
{ {
debug_printf ("dup(%s) failed, mutex handle %x, %E", debug_printf ("dup(%s) failed, mutex handle %x, %E",
@ -1456,7 +1456,7 @@ fhandler_dev_tape::dup (fhandler_base *child)
} }
fh->mt_evt = NULL; fh->mt_evt = NULL;
if (mt_evt && 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)) DUPLICATE_SAME_ACCESS))
{ {
debug_printf ("dup(%s) failed, event handle %x, %E", debug_printf ("dup(%s) failed, event handle %x, %E",
@ -1464,7 +1464,7 @@ fhandler_dev_tape::dup (fhandler_base *child)
__seterrno (); __seterrno ();
return unlock (-1); return unlock (-1);
} }
return unlock (fhandler_dev_raw::dup (child)); return unlock (fhandler_dev_raw::dup (child, from_proc));
} }
void void

View File

@ -915,9 +915,12 @@ fhandler_tty_slave::read (void *ptr, size_t& len)
} }
int 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; 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; *(fhandler_tty_slave *) child = *arch;
child->usecount = 0; child->usecount = 0;
arch->usecount++; arch->usecount++;
@ -928,7 +931,7 @@ fhandler_tty_slave::dup (fhandler_base *child)
} }
int 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; fhandler_tty_slave *fts = (fhandler_tty_slave *) child;
int errind; int errind;
@ -941,7 +944,7 @@ fhandler_tty_common::dup (fhandler_base *child)
if (output_done_event == NULL) if (output_done_event == NULL)
fts->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, &fts->output_done_event, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
@ -950,7 +953,7 @@ fhandler_tty_common::dup (fhandler_base *child)
} }
if (ioctl_request_event == NULL) if (ioctl_request_event == NULL)
fts->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, &fts->ioctl_request_event, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
@ -959,35 +962,35 @@ fhandler_tty_common::dup (fhandler_base *child)
} }
if (ioctl_done_event == NULL) if (ioctl_done_event == NULL)
fts->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, &fts->ioctl_done_event, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
errind = 3; errind = 3;
goto err; goto err;
} }
if (!DuplicateHandle (hMainProc, input_available_event, hMainProc, if (!DuplicateHandle (from_proc, input_available_event, hMainProc,
&fts->input_available_event, 0, 1, &fts->input_available_event, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
errind = 4; errind = 4;
goto err; goto err;
} }
if (!DuplicateHandle (hMainProc, output_mutex, hMainProc, if (!DuplicateHandle (from_proc, output_mutex, hMainProc,
&fts->output_mutex, 0, 1, &fts->output_mutex, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
errind = 5; errind = 5;
goto err; goto err;
} }
if (!DuplicateHandle (hMainProc, input_mutex, hMainProc, if (!DuplicateHandle (from_proc, input_mutex, hMainProc,
&fts->input_mutex, 0, 1, &fts->input_mutex, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
errind = 6; errind = 6;
goto err; goto err;
} }
if (!DuplicateHandle (hMainProc, get_handle (), hMainProc, if (!DuplicateHandle (from_proc, get_handle (), hMainProc,
&nh, 0, 1, &nh, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
@ -996,7 +999,7 @@ fhandler_tty_common::dup (fhandler_base *child)
} }
fts->set_io_handle (nh); fts->set_io_handle (nh);
if (!DuplicateHandle (hMainProc, get_output_handle (), hMainProc, if (!DuplicateHandle (from_proc, get_output_handle (), hMainProc,
&nh, 0, 1, &nh, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
@ -1007,7 +1010,7 @@ fhandler_tty_common::dup (fhandler_base *child)
if (inuse == NULL) if (inuse == NULL)
fts->inuse = NULL; fts->inuse = NULL;
else if (!DuplicateHandle (hMainProc, inuse, hMainProc, else if (!DuplicateHandle (from_proc, inuse, hMainProc,
&fts->inuse, 0, 1, &fts->inuse, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {

View File

@ -146,9 +146,9 @@ fhandler_virtual::lseek (_off64_t offset, int whence)
} }
int 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) if (!ret)
{ {

View File

@ -1,6 +1,6 @@
/* cygwin/socket.h /* cygwin/socket.h
Copyright 1999, 2000, 2001 Red Hat, Inc. Copyright 1999, 2000, 2001, 2005 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -32,11 +32,59 @@ struct ucred {
}; };
struct linger { struct linger {
unsigned short l_onoff; /* Linger active */ unsigned short l_onoff; /* Linger active */
unsigned short l_linger; /* How long to linger for */ unsigned short l_linger; /* How long to linger for */
}; };
struct msghdr 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 */ void * msg_name; /* Socket name */
int msg_namelen; /* Length of name */ int msg_namelen; /* Length of name */
@ -45,6 +93,7 @@ struct msghdr
void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */ void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */
int msg_accrightslen; /* Length of rights list */ int msg_accrightslen; /* Length of rights list */
}; };
#endif
#ifndef socklen_t #ifndef socklen_t
#define socklen_t int #define socklen_t int

View File

@ -88,6 +88,10 @@ details. */
#define CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES \ #define CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES \
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) >= \ (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) >= \
79) 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 /* We used to use the DLL major/minor to track
non-backward-compatible interface changes to the API. Now we non-backward-compatible interface changes to the API. Now we
use an API major/minor number for this purpose. */ use an API major/minor number for this purpose. */
@ -268,6 +272,10 @@ details. */
138: Export readdir_r. 138: Export readdir_r.
*/ */
/*
133: Start using POSIX definition of struct msghdr.
*/
/* 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

View File

@ -507,4 +507,8 @@ extern "C"
VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR); VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
ULONG NTAPI RtlNtStatusToDosError (NTSTATUS); ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
ULONG WINAPI RtlIsDosDeviceName_U (PCWSTR); 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);
} }

View File

@ -75,6 +75,7 @@ details. */
#include "shared_info.h" #include "shared_info.h"
#include "registry.h" #include "registry.h"
#include "cygtls.h" #include "cygtls.h"
#include "ntdll.h"
#include <assert.h> #include <assert.h>
static int normalize_win32_path (const char *, char *, char *&); 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 PUNICODE_STRING
path_conv::get_nt_native_path (UNICODE_STRING &upath) path_conv::get_nt_native_path (UNICODE_STRING &upath)
{ {
if (path[0] != '\\') /* X:\... or NUL, etc. */ if (path[0] == '\\' && path[1] != '\\')
{ {
str2uni_cat (upath, "\\??\\"); /* This handles all paths already given in NT speak. On writing this
str2uni_cat (upath, path); comment, these are the raw device paths. */
if (RtlCreateUnicodeStringFromAsciiz (&upath, path))
return &upath;
} }
else if (path[1] != '\\') /* \Device\... */ else
str2uni_cat (upath, path);
else if (path[2] != '.'
|| path[3] != '\\') /* \\server\share\... */
{ {
str2uni_cat (upath, "\\??\\UNC\\"); wchar_t wc_path[CYG_MAX_PATH];
str2uni_cat (upath, path + 2); 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;
}
} }
else /* \\.\device */ set_errno (ENOMEM);
{ return NULL;
str2uni_cat (upath, "\\??\\");
str2uni_cat (upath, path + 4);
}
return &upath;
} }
/* Convert an arbitrary path SRC to a pure Win32 path, suitable for /* Convert an arbitrary path SRC to a pure Win32 path, suitable for

View File

@ -385,39 +385,18 @@ _pinfo::commune_recv ()
char path[CYG_MAX_PATH]; char path[CYG_MAX_PATH];
DWORD nr; DWORD nr;
DWORD code; DWORD code;
HANDLE hp;
HANDLE __fromthem = NULL;
HANDLE __tothem = NULL;
hp = OpenProcess (PROCESS_DUP_HANDLE, false, dwProcessId); /* Don't remove. It's necessary to copy to local variables for process
if (!hp) synchronization. */
{ HANDLE __fromthem = this->__fromthem;
sigproc_printf ("couldn't open handle for pid %d(%u)", pid, dwProcessId); HANDLE __tothem = this->__tothem;
hello_pid = -1; HANDLE __them = this->__them;
return; HANDLE __gotit = this->__gotit;
}
if (!DuplicateHandle (hp, fromthem, hMainProc, &__fromthem, 0, false, DUPLICATE_SAME_ACCESS))
{
sigproc_printf ("couldn't duplicate fromthem, %E");
CloseHandle (hp);
hello_pid = -1;
return;
}
if (!DuplicateHandle (hp, tothem, hMainProc, &__tothem, 0, false, DUPLICATE_SAME_ACCESS)) SetEvent (__gotit);
{
sigproc_printf ("couldn't duplicate tothem, %E");
CloseHandle (__fromthem);
CloseHandle (hp);
hello_pid = -1;
return;
}
hello_pid = 0;
if (!ReadFile (__fromthem, &code, sizeof code, &nr, NULL) || nr != sizeof code) 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 /* __seterrno ();*/ // this is run from the signal thread, so don't set errno
goto out; goto out;
} }
@ -431,7 +410,6 @@ _pinfo::commune_recv ()
extern int __argc_safe; extern int __argc_safe;
const char *argv[__argc_safe + 1]; const char *argv[__argc_safe + 1];
CloseHandle (hp);
for (int i = 0; i < __argc_safe; i++) for (int i = 0; i < __argc_safe; i++)
{ {
if (IsBadStringPtr (__argv[i], INT32_MAX)) if (IsBadStringPtr (__argv[i], INT32_MAX))
@ -463,7 +441,6 @@ _pinfo::commune_recv ()
case PICOM_CWD: case PICOM_CWD:
{ {
CloseHandle (__fromthem); __fromthem = NULL; CloseHandle (__fromthem); __fromthem = NULL;
CloseHandle (hp);
unsigned int n = strlen (cygheap->cwd.get (path, 1, 1, unsigned int n = strlen (cygheap->cwd.get (path, 1, 1,
CYG_MAX_PATH)) + 1; CYG_MAX_PATH)) + 1;
if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL)) if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
@ -475,7 +452,6 @@ _pinfo::commune_recv ()
case PICOM_ROOT: case PICOM_ROOT:
{ {
CloseHandle (__fromthem); __fromthem = NULL; CloseHandle (__fromthem); __fromthem = NULL;
CloseHandle (hp);
unsigned int n; unsigned int n;
if (cygheap->root.exists ()) if (cygheap->root.exists ())
n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1; n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1;
@ -490,7 +466,6 @@ _pinfo::commune_recv ()
case PICOM_FDS: case PICOM_FDS:
{ {
CloseHandle (__fromthem); __fromthem = NULL; CloseHandle (__fromthem); __fromthem = NULL;
CloseHandle (hp);
unsigned int n = 0; unsigned int n = 0;
int fd; int fd;
cygheap_fdenum cfd; cygheap_fdenum cfd;
@ -515,11 +490,9 @@ _pinfo::commune_recv ()
|| nr != sizeof hdl) || nr != sizeof hdl)
{ {
sigproc_printf ("ReadFile hdl failed, %E"); sigproc_printf ("ReadFile hdl failed, %E");
CloseHandle (hp);
goto out; goto out;
} }
CloseHandle (__fromthem); __fromthem = NULL; CloseHandle (__fromthem); __fromthem = NULL;
CloseHandle (hp);
unsigned int n = 0; unsigned int n = 0;
cygheap_fdenum cfd; cygheap_fdenum cfd;
while (cfd.next () >= 0) while (cfd.next () >= 0)
@ -543,11 +516,9 @@ _pinfo::commune_recv ()
|| nr != sizeof fd) || nr != sizeof fd)
{ {
sigproc_printf ("ReadFile fd failed, %E"); sigproc_printf ("ReadFile fd failed, %E");
CloseHandle (hp);
goto out; goto out;
} }
CloseHandle (__fromthem); __fromthem = NULL; CloseHandle (__fromthem); __fromthem = NULL;
CloseHandle (hp);
unsigned int n = 0; unsigned int n = 0;
cygheap_fdget cfd (fd); cygheap_fdget cfd (fd);
if (cfd < 0) if (cfd < 0)
@ -566,7 +537,6 @@ _pinfo::commune_recv ()
if (!ReadFile (__fromthem, &len, sizeof len, &nr, NULL) if (!ReadFile (__fromthem, &len, sizeof len, &nr, NULL)
|| nr != sizeof len) || nr != sizeof len)
{ {
CloseHandle (hp);
/* __seterrno ();*/ // this is run from the signal thread, so don't set errno /* __seterrno ();*/ // this is run from the signal thread, so don't set errno
goto out; goto out;
} }
@ -574,7 +544,6 @@ _pinfo::commune_recv ()
if (!ReadFile (__fromthem, path, len, &nr, NULL) if (!ReadFile (__fromthem, path, len, &nr, NULL)
|| nr != len) || nr != len)
{ {
CloseHandle (hp);
/* __seterrno ();*/ // this is run from the signal thread, so don't set errno /* __seterrno ();*/ // this is run from the signal thread, so don't set errno
goto out; goto out;
} }
@ -588,7 +557,7 @@ _pinfo::commune_recv ()
it[0] = fh->get_handle (); it[0] = fh->get_handle ();
it[1] = fh->get_output_handle (); it[1] = fh->get_output_handle ();
for (int i = 0; i < 2; i++) 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)) DUPLICATE_SAME_ACCESS))
{ {
it[0] = it[1] = NULL; /* FIXME: possibly left a handle open in child? */ 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 */ fh->close_one_end (); /* FIXME: not quite right - need more handshaking */
} }
CloseHandle (hp);
if (!WriteFile (__tothem, it, sizeof (it), &nr, NULL)) if (!WriteFile (__tothem, it, sizeof (it), &nr, NULL))
{ {
/*__seterrno ();*/ // this is run from the signal thread, so don't set errno /*__seterrno ();*/ // this is run from the signal thread, so don't set errno
@ -611,10 +579,10 @@ _pinfo::commune_recv ()
} }
out: out:
if (__fromthem) CloseHandle (__fromthem);
CloseHandle (__fromthem); CloseHandle (__tothem);
if (__tothem) CloseHandle (__them);
CloseHandle (__tothem); CloseHandle (__gotit);
} }
#define PIPEBUFSIZE (4096 * sizeof (DWORD)) #define PIPEBUFSIZE (4096 * sizeof (DWORD))
@ -663,31 +631,49 @@ _pinfo::commune_send (DWORD code, ...)
if (sig_send (this, __SIGCOMMUNE)) if (sig_send (this, __SIGCOMMUNE))
goto err; goto err;
/* FIXME: Need something better than an busy loop here */ {
bool isalive; bool isalive = true;
for (int i = 0; (isalive = alive ()) && (i < 10000); i++) HANDLE w4[2] = { myself->gotit, myself->them };
if (myself->hello_pid <= 0) /* FIXME: How long should we wait here? */
break; switch (WaitForMultipleObjects (2, w4, false, INFINITE))
else {
low_priority_sleep (0); 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;
}
CloseHandle (tome); CloseHandle (tome);
tome = NULL; tome = NULL;
CloseHandle (fromme); CloseHandle (fromme);
fromme = NULL; 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) if (!isalive)
{ {
set_errno (ESRCH); set_errno (ESRCH);
goto err; goto err;
} }
if (myself->hello_pid < 0)
{
set_errno (ENOSYS);
goto err;
}
if (myself->hello_pid < 0)
{
set_errno (ENOSYS);
goto err;
}
}
size_t n; size_t n;
switch (code) switch (code)
{ {
@ -785,6 +771,7 @@ err:
out: out:
myself->hello_pid = 0; myself->hello_pid = 0;
tothem = fromthem = NULL;
myself.unlock (); myself.unlock ();
return res; return res;
} }
@ -926,6 +913,44 @@ _pinfo::cmdline (size_t& n)
return s; 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 /* 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 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. is received on the pipe, it is assumed that the cygwin pid has exited.

View File

@ -91,6 +91,12 @@ public:
pid_t hello_pid; pid_t hello_pid;
HANDLE tothem; HANDLE tothem;
HANDLE fromthem; HANDLE fromthem;
HANDLE __tothem;
HANDLE __fromthem;
HANDLE them;
HANDLE __them;
HANDLE gotit;
HANDLE __gotit;
inline void set_has_pgid_children () inline void set_has_pgid_children ()
{ {
@ -119,6 +125,8 @@ public:
char *root (size_t &); char *root (size_t &);
char *cwd (size_t &); char *cwd (size_t &);
char *cmdline (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 *); void set_ctty (class tty_min *, int, class fhandler_tty_slave *);
bool dup_proc_pipe (HANDLE) __attribute__ ((regparm(2))); bool dup_proc_pipe (HANDLE) __attribute__ ((regparm(2)));
void sync_proc_pipe (); void sync_proc_pipe ();

View File

@ -60,7 +60,7 @@ fhandler_pipe::open (int flags, mode_t mode)
set_errno (EACCES); set_errno (EACCES);
return 0; return 0;
} }
if (!cfd->dup (this)) if (!cfd->dup (this, hMainProc))
return 1; return 1;
return 0; return 0;
} }
@ -246,7 +246,7 @@ debug_printf ("here");
} }
int int
fhandler_pipe::dup (fhandler_base *child) fhandler_pipe::dup (fhandler_base *child, HANDLE from_proc)
{ {
int res = -1; int res = -1;
fhandler_pipe *ftp = (fhandler_pipe *) child; fhandler_pipe *ftp = (fhandler_pipe *) child;
@ -254,14 +254,14 @@ fhandler_pipe::dup (fhandler_base *child)
if (get_handle ()) if (get_handle ())
{ {
res = fhandler_base::dup (child); res = fhandler_base::dup (child, from_proc);
if (res) if (res)
goto err; goto err;
} }
if (guard == NULL) if (guard == NULL)
ftp->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)) DUPLICATE_SAME_ACCESS))
{ {
debug_printf ("couldn't duplicate guard %p, %E", guard); debug_printf ("couldn't duplicate guard %p, %E", guard);
@ -270,7 +270,7 @@ fhandler_pipe::dup (fhandler_base *child)
if (writepipe_exists == NULL) if (writepipe_exists == NULL)
ftp->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, &ftp->writepipe_exists, 0, 1,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {
@ -280,7 +280,7 @@ fhandler_pipe::dup (fhandler_base *child)
if (read_state == NULL) if (read_state == NULL)
ftp->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, &ftp->read_state, 0, 0,
DUPLICATE_SAME_ACCESS)) DUPLICATE_SAME_ACCESS))
{ {

View File

@ -582,7 +582,8 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
sigproc_printf ("sendsig handle never materialized"); sigproc_printf ("sendsig handle never materialized");
goto out; goto out;
} }
HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, dwProcessId); HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE | SYNCHRONIZE,
false, dwProcessId);
if (!hp) if (!hp)
{ {
__seterrno (); __seterrno ();
@ -598,7 +599,59 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
CloseHandle (hp); CloseHandle (hp);
goto out; 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); VerifyHandle (sendsig);
} }

View File

@ -623,6 +623,57 @@ static NO_COPY wincaps wincap_2003 = {
has_null_console_handler_routine:true 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; wincapc wincap;
void void
@ -676,6 +727,11 @@ wincapc::init ()
caps = &wincap_2003; caps = &wincap_2003;
} }
break; break;
case 6:
os = "NT";
has_osversioninfoex = true;
caps = &wincap_vista;
break;
default: default:
os = "??"; os = "??";
caps = &wincap_unknown; caps = &wincap_unknown;