* 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:
parent
280fdd0b67
commit
1204c515fe
|
@ -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>
|
||||
|
||||
* dcrt0.cc (getstack): New function.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,23 +1426,35 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
|
|||
}
|
||||
|
||||
if (res == SOCKET_ERROR)
|
||||
{
|
||||
set_winsock_errno ();
|
||||
}
|
||||
else
|
||||
res = ret;
|
||||
}
|
||||
|
||||
if (res == SOCKET_ERROR)
|
||||
{
|
||||
/* 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 (res == SOCKET_ERROR && get_errno () == ESHUTDOWN
|
||||
&& get_socket_type () == SOCK_STREAM)
|
||||
if (get_errno () == ESHUTDOWN && get_socket_type () == SOCK_STREAM)
|
||||
{
|
||||
set_errno (EPIPE);
|
||||
if (! (flags & MSG_NOSIGNAL))
|
||||
raise (SIGPIPE);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
@ -37,6 +37,54 @@ struct linger {
|
|||
};
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ details. */
|
|||
#include "shared_info.h"
|
||||
#include "registry.h"
|
||||
#include "cygtls.h"
|
||||
#include "ntdll.h"
|
||||
#include <assert.h>
|
||||
|
||||
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);
|
||||
}
|
||||
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 */
|
||||
{
|
||||
str2uni_cat (upath, "\\??\\");
|
||||
str2uni_cat (upath, path + 4);
|
||||
}
|
||||
/* 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
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
set_errno (ENOMEM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Convert an arbitrary path SRC to a pure Win32 path, suitable for
|
||||
|
|
|
@ -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 (__them);
|
||||
CloseHandle (__gotit);
|
||||
}
|
||||
|
||||
#define PIPEBUFSIZE (4096 * sizeof (DWORD))
|
||||
|
@ -663,18 +631,36 @@ _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)
|
||||
{
|
||||
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;
|
||||
else
|
||||
low_priority_sleep (0);
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
isalive = false;
|
||||
break;
|
||||
default:
|
||||
debug_printf ("WFMO failed with %E");
|
||||
myself->hello_pid = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -687,7 +673,7 @@ _pinfo::commune_send (DWORD code, ...)
|
|||
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.
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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,6 +599,58 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
|||
CloseHandle (hp);
|
||||
goto out;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue