* sigproc.h (wait_for_sigthread): Eliminate parameter.

* sigproc.cc (wait_for_sigthread): Ditto.  Don't synchronize with wait_sig
after receiving an event that it is ready to go.
(init_sig_pipe): New function.
(wait_sig): Call init_sig_pipe to create pipes for communicating signals to
this process.  Don't send sigCONT signal when initializing.
* fork.cc (frok::child): Accommodate wait_for_sigpipe parameter change.
* fhandler.h (fhandler_*::write): Make ssize_t/__stdcall.
(fhandler_*::write_overlapped): Ditto.
(fhandler_*::raw_write): Ditto.
(fhandler_*::readv): Ditto.
(fhandler_*::writev): Ditto.
(fhandler_*::raw_read): Make __stdcall.
* fhandler: Accommodate changes to read/write functions throughout.
* fhandler_clipboard.cc: Ditto.
* fhandler_console.cc: Ditto.
* fhandler_dsp.cc: Ditto.
* fhandler_fifo.cc: Ditto.
* fhandler_mailslot.cc: Ditto.
* fhandler_mem.cc: Ditto.
* fhandler_mem.cc: Ditto.
* fhandler_random.cc: Ditto.
* fhandler_tape.cc: Ditto.
* fhandler_tty.cc: Ditto.
* fhandler_virtual.cc: Ditto.
* fhandler_windows.cc: Ditto.
* fhandler_zero.cc: Ditto.
* syscalls.cc (readv): Use ssize_t as temp variable.
* fhandler.cc (fhandler_base::read): Coerce returned len to signed or it will
never be treated as < 0.
(fhandler_base::wait_overlapped): Minimize calls to GetLastError.  Remove
duplicate debugging test.  Fix error return.
* fhandler.h (fhandler_fifo::fifo_name): Declare new function.
(fhandler_fifo::close): Ditto.
(fhandler_fifo::dup): Ditto.
(fhandler_fifo::close_on_exec): Ditto.
* fhandler.cc (fhandler_fifo::fifo_name): Define new function.
(FIFO_BUF_SIZE): New define.
(cnp): Ditto.
(fhandler_fifo::open): Rework.  Use cnp to open named pipe.  Always open write
side as a client.  Open dummy client when writing and can't connect.
(wait): Rework.  Implement fifo_wait_for_next_client.  Handle signals during
connect better.  Add new fifo_wait_for_server code which polls
(sigh) waiting for server.
(fhandler_fifo::raw_read): Handle transition states when one client closes and
another is available.
(fhandler_fifo::close): Define.
(fhandler_fifo::dup): Ditto.
(fhandler_fifo::close_on_exec): Ditto.
This commit is contained in:
Christopher Faylor 2009-07-24 20:54:33 +00:00
parent a58ebe50c2
commit 43c23d4b82
21 changed files with 341 additions and 143 deletions

View File

@ -1,3 +1,61 @@
2009-07-24 Christopher Faylor <me+cygwin@cgf.cx>
* sigproc.h (wait_for_sigthread): Eliminate parameter.
* sigproc.cc (wait_for_sigthread): Ditto. Don't synchronize with
wait_sig after receiving an event that it is ready to go.
(init_sig_pipe): New function.
(wait_sig): Call init_sig_pipe to create pipes for communicating
signals to this process. Don't send sigCONT signal when initializing.
* fork.cc (frok::child): Accommodate wait_for_sigpipe parameter change.
2009-07-24 Christopher Faylor <me+cygwin@cgf.cx>
* fhandler.h (fhandler_*::write): Make ssize_t/__stdcall.
(fhandler_*::write_overlapped): Ditto.
(fhandler_*::raw_write): Ditto.
(fhandler_*::readv): Ditto.
(fhandler_*::writev): Ditto.
(fhandler_*::raw_read): Make __stdcall.
* fhandler: Accommodate changes to read/write functions throughout.
* fhandler_clipboard.cc: Ditto.
* fhandler_console.cc: Ditto.
* fhandler_dsp.cc: Ditto.
* fhandler_fifo.cc: Ditto.
* fhandler_mailslot.cc: Ditto.
* fhandler_mem.cc: Ditto.
* fhandler_mem.cc: Ditto.
* fhandler_random.cc: Ditto.
* fhandler_tape.cc: Ditto.
* fhandler_tty.cc: Ditto.
* fhandler_virtual.cc: Ditto.
* fhandler_windows.cc: Ditto.
* fhandler_zero.cc: Ditto.
* syscalls.cc (readv): Use ssize_t as temp variable.
* fhandler.cc (fhandler_base::read): Coerce returned len to signed or
it will never be treated as < 0.
(fhandler_base::wait_overlapped): Minimize calls to GetLastError.
Remove duplicate debugging test. Fix error return.
* fhandler.h (fhandler_fifo::fifo_name): Declare new function.
(fhandler_fifo::close): Ditto.
(fhandler_fifo::dup): Ditto.
(fhandler_fifo::close_on_exec): Ditto.
* fhandler.cc (fhandler_fifo::fifo_name): Define new function.
(FIFO_BUF_SIZE): New define.
(cnp): Ditto.
(fhandler_fifo::open): Rework. Use cnp to open named pipe. Always
open write side as a client. Open dummy client when writing and can't
connect.
(wait): Rework. Implement fifo_wait_for_next_client. Handle signals
during connect better. Add new fifo_wait_for_server code which polls
(sigh) waiting for server.
(fhandler_fifo::raw_read): Handle transition states when one client
closes and another is available.
(fhandler_fifo::close): Define.
(fhandler_fifo::dup): Ditto.
(fhandler_fifo::close_on_exec): Ditto.
2009-07-24 Corinna Vinschen <corinna@vinschen.de> 2009-07-24 Corinna Vinschen <corinna@vinschen.de>
* syscalls.cc (internal_setlocale): Fix typo in GBK codepage. * syscalls.cc (internal_setlocale): Fix typo in GBK codepage.

View File

@ -209,7 +209,7 @@ fhandler_base::set_flags (int flags, int supplied_bin)
/* Cover function to ReadFile to achieve (as much as possible) Posix style /* Cover function to ReadFile to achieve (as much as possible) Posix style
semantics and use of errno. */ semantics and use of errno. */
void void __stdcall
fhandler_base::raw_read (void *ptr, size_t& ulen) fhandler_base::raw_read (void *ptr, size_t& ulen)
{ {
#define bytes_read ulen #define bytes_read ulen
@ -278,7 +278,7 @@ retry:
static LARGE_INTEGER off_current = { QuadPart:FILE_USE_FILE_POINTER_POSITION }; static LARGE_INTEGER off_current = { QuadPart:FILE_USE_FILE_POINTER_POSITION };
static LARGE_INTEGER off_append = { QuadPart:FILE_WRITE_TO_END_OF_FILE }; static LARGE_INTEGER off_append = { QuadPart:FILE_WRITE_TO_END_OF_FILE };
int ssize_t __stdcall
fhandler_base::raw_write (const void *ptr, size_t len) fhandler_base::raw_write (const void *ptr, size_t len)
{ {
NTSTATUS status; NTSTATUS status;
@ -649,7 +649,7 @@ done:
an \n. If last char is an \r, look ahead one more char, if \n then an \n. If last char is an \r, look ahead one more char, if \n then
modify \r, if not, remember char. modify \r, if not, remember char.
*/ */
void void __stdcall
fhandler_base::read (void *in_ptr, size_t& len) fhandler_base::read (void *in_ptr, size_t& len)
{ {
char *ptr = (char *) in_ptr; char *ptr = (char *) in_ptr;
@ -676,7 +676,7 @@ fhandler_base::read (void *in_ptr, size_t& len)
else else
len = copied_chars; len = copied_chars;
if (rbinary () || len <= 0) if (rbinary () || (ssize_t) len <= 0)
goto out; goto out;
/* Scan buffer and turn \r\n into \n */ /* Scan buffer and turn \r\n into \n */
@ -739,7 +739,7 @@ out:
debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text"); debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
} }
int ssize_t __stdcall
fhandler_base::write (const void *ptr, size_t len) fhandler_base::write (const void *ptr, size_t len)
{ {
int res; int res;
@ -834,7 +834,7 @@ fhandler_base::write (const void *ptr, size_t len)
return res; return res;
} }
ssize_t ssize_t __stdcall
fhandler_base::readv (const struct iovec *const iov, const int iovcnt, fhandler_base::readv (const struct iovec *const iov, const int iovcnt,
ssize_t tot) ssize_t tot)
{ {
@ -891,7 +891,7 @@ fhandler_base::readv (const struct iovec *const iov, const int iovcnt,
return len; return len;
} }
ssize_t ssize_t __stdcall
fhandler_base::writev (const struct iovec *const iov, const int iovcnt, fhandler_base::writev (const struct iovec *const iov, const int iovcnt,
ssize_t tot) ssize_t tot)
{ {
@ -1682,10 +1682,10 @@ fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes, DWORD le
int res = 0; int res = 0;
DWORD err; DWORD err = GetLastError ();
if (is_nonblocking ()) if (is_nonblocking ())
{ {
if (inres || GetLastError () == ERROR_IO_PENDING) if (inres || err == ERROR_IO_PENDING)
{ {
if (writing && !inres) if (writing && !inres)
*bytes = len; /* This really isn't true but it seems like *bytes = len; /* This really isn't true but it seems like
@ -1696,17 +1696,10 @@ fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes, DWORD le
res = 1; res = 1;
err = 0; err = 0;
} }
else
{
res = 0;
err = GetLastError ();
}
} }
else if (inres || ((err = GetLastError ()) == ERROR_IO_PENDING)) else if (inres || err == ERROR_IO_PENDING)
{ {
#ifdef DEBUGGING #ifdef DEBUGGING
if (!get_overlapped ())
system_printf ("get_overlapped is zero?");
if (!get_overlapped ()->hEvent) if (!get_overlapped ()->hEvent)
system_printf ("hEvent is zero?"); system_printf ("hEvent is zero?");
#endif #endif
@ -1749,7 +1742,7 @@ fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes, DWORD le
debug_printf ("err %u", err); debug_printf ("err %u", err);
__seterrno_from_win_error (err); __seterrno_from_win_error (err);
*bytes = (DWORD) -1; *bytes = (DWORD) -1;
res = -1; res = 0;
} }
else else
{ {
@ -1796,7 +1789,7 @@ fhandler_base::read_overlapped (void *ptr, size_t& len)
len = (size_t) nbytes; len = (size_t) nbytes;
} }
int __stdcall ssize_t __stdcall
fhandler_base::write_overlapped (const void *ptr, size_t len) fhandler_base::write_overlapped (const void *ptr, size_t len)
{ {
DWORD nbytes; DWORD nbytes;

View File

@ -310,10 +310,10 @@ class fhandler_base
virtual void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); virtual void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
virtual void __stdcall read_overlapped (void *ptr, size_t& len) __attribute__ ((regparm (3))); virtual void __stdcall read_overlapped (void *ptr, size_t& len) __attribute__ ((regparm (3)));
virtual bool __stdcall has_ongoing_io (bool) __attribute__ ((regparm (2))); virtual bool __stdcall has_ongoing_io (bool) __attribute__ ((regparm (2)));
virtual int write (const void *ptr, size_t len); virtual ssize_t __stdcall write (const void *ptr, size_t len);
virtual int __stdcall write_overlapped (const void *ptr, size_t len); virtual ssize_t __stdcall write_overlapped (const void *ptr, size_t len);
virtual ssize_t readv (const struct iovec *, int iovcnt, ssize_t tot = -1); virtual ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
virtual ssize_t writev (const struct iovec *, int iovcnt, ssize_t tot = -1); virtual ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
virtual ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3))); virtual ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
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);
@ -349,8 +349,8 @@ class fhandler_base
virtual class fhandler_console *is_console () { return 0; } virtual class fhandler_console *is_console () { return 0; }
virtual int is_windows () {return 0; } virtual int is_windows () {return 0; }
virtual void raw_read (void *ptr, size_t& ulen); virtual void __stdcall raw_read (void *ptr, size_t& ulen);
virtual int raw_write (const void *ptr, size_t ulen); virtual ssize_t __stdcall raw_write (const void *ptr, size_t ulen);
virtual OVERLAPPED *get_overlapped () {return NULL;} virtual OVERLAPPED *get_overlapped () {return NULL;}
virtual OVERLAPPED *get_overlapped_buffer () {return NULL;} virtual OVERLAPPED *get_overlapped_buffer () {return NULL;}
virtual void set_overlapped (OVERLAPPED *) {} virtual void set_overlapped (OVERLAPPED *) {}
@ -399,7 +399,7 @@ class fhandler_mailslot : public fhandler_base
fhandler_mailslot (); fhandler_mailslot ();
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); ssize_t __stdcall write (const void *ptr, size_t len);
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
select_record *select_read (select_stuff *); select_record *select_read (select_stuff *);
}; };
@ -499,13 +499,13 @@ class fhandler_socket: public fhandler_base
int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid); int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid);
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
ssize_t readv (const struct iovec *, int iovcnt, ssize_t tot = -1); ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
inline ssize_t recv_internal (struct _WSAMSG *wsamsg); inline ssize_t recv_internal (struct _WSAMSG *wsamsg);
ssize_t recvfrom (void *ptr, size_t len, int flags, ssize_t recvfrom (void *ptr, size_t len, int flags,
struct sockaddr *from, int *fromlen); struct sockaddr *from, int *fromlen);
ssize_t recvmsg (struct msghdr *msg, int flags); ssize_t recvmsg (struct msghdr *msg, int flags);
ssize_t writev (const struct iovec *, int iovcnt, ssize_t tot = -1); ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags); inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags);
ssize_t sendto (const void *ptr, size_t len, int flags, ssize_t sendto (const void *ptr, size_t len, int flags,
const struct sockaddr *to, int tolen); const struct sockaddr *to, int tolen);
@ -563,8 +563,8 @@ public:
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (select_stuff *); select_record *select_except (select_stuff *);
char *get_proc_fd_name (char *buf); char *get_proc_fd_name (char *buf);
void raw_read (void *ptr, size_t& len); void __stdcall raw_read (void *ptr, size_t& len);
int raw_write (const void *, size_t); ssize_t __stdcall raw_write (const void *, size_t);
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int dup (fhandler_base *child); int dup (fhandler_base *child);
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
@ -578,25 +578,34 @@ public:
friend class fhandler_fifo; friend class fhandler_fifo;
}; };
enum fifo_state
{
fifo_unknown,
fifo_wait_for_client,
fifo_wait_for_server,
fifo_ok
};
class fhandler_fifo: public fhandler_base class fhandler_fifo: public fhandler_base
{ {
enum fifo_state
{
fifo_unknown,
fifo_wait_for_client,
fifo_wait_for_server,
fifo_wait_for_next_client,
fifo_eof,
fifo_error,
fifo_eintr,
fifo_ok
};
fifo_state wait_state; fifo_state wait_state;
HANDLE dummy_client;
HANDLE open_nonserver (const char *, unsigned, LPSECURITY_ATTRIBUTES); HANDLE open_nonserver (const char *, unsigned, LPSECURITY_ATTRIBUTES);
OVERLAPPED io_status; OVERLAPPED io_status;
bool wait (bool) __attribute__ ((regparm (1))); bool wait (bool) __attribute__ ((regparm (1)));
char *fifo_name (char *) __attribute__ ((regparm (2)));
public: public:
fhandler_fifo (); fhandler_fifo ();
void raw_read (void *, size_t&); void __stdcall raw_read (void *, size_t&);
int raw_write (const void *, size_t); ssize_t __stdcall raw_write (const void *, size_t);
int open (int, mode_t); int open (int, mode_t);
int close ();
int dup (fhandler_base *child);
bool isfifo () { return true; } bool isfifo () { return true; }
void set_close_on_exec (bool val);
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2))); int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
OVERLAPPED *get_overlapped () {return &io_status;} OVERLAPPED *get_overlapped () {return &io_status;}
OVERLAPPED *get_overlapped_buffer () {return &io_status;} OVERLAPPED *get_overlapped_buffer () {return &io_status;}
@ -662,8 +671,8 @@ class fhandler_dev_floppy: public fhandler_dev_raw
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int dup (fhandler_base *child); int dup (fhandler_base *child);
void raw_read (void *ptr, size_t& ulen); void __stdcall raw_read (void *ptr, size_t& ulen);
int raw_write (const void *ptr, size_t ulen); ssize_t __stdcall raw_write (const void *ptr, size_t ulen);
_off64_t lseek (_off64_t offset, int whence); _off64_t lseek (_off64_t offset, int whence);
int ioctl (unsigned int cmd, void *buf); int ioctl (unsigned int cmd, void *buf);
}; };
@ -686,8 +695,8 @@ class fhandler_dev_tape: public fhandler_dev_raw
virtual int open (int flags, mode_t mode = 0); virtual int open (int flags, mode_t mode = 0);
virtual int close (); virtual int close ();
void raw_read (void *ptr, size_t& ulen); void __stdcall raw_read (void *ptr, size_t& ulen);
int raw_write (const void *ptr, size_t ulen); ssize_t __stdcall raw_write (const void *ptr, size_t ulen);
virtual _off64_t lseek (_off64_t offset, int whence); virtual _off64_t lseek (_off64_t offset, int whence);
@ -780,8 +789,8 @@ class fhandler_serial: public fhandler_base
int init (HANDLE h, DWORD a, mode_t flags); int init (HANDLE h, DWORD a, mode_t flags);
void overlapped_setup (); void overlapped_setup ();
int dup (fhandler_base *child); int dup (fhandler_base *child);
void raw_read (void *ptr, size_t& ulen); void __stdcall raw_read (void *ptr, size_t& ulen);
int raw_write (const void *ptr, size_t ulen); ssize_t __stdcall raw_write (const void *ptr, size_t ulen);
int tcsendbreak (int); int tcsendbreak (int);
int tcdrain (); int tcdrain ();
int tcflow (int); int tcflow (int);
@ -966,9 +975,9 @@ class fhandler_console: public fhandler_termios
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len);
void doecho (const void *str, DWORD len) { (void) write (str, len); }
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
ssize_t __stdcall write (const void *ptr, size_t len);
void doecho (const void *str, DWORD len) { (void) write (str, len); }
int close (); int close ();
int tcflush (int); int tcflush (int);
@ -1038,7 +1047,7 @@ class fhandler_tty_slave: public fhandler_tty_common
fhandler_tty_slave (); fhandler_tty_slave ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); ssize_t __stdcall 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)));
int init (HANDLE, DWORD, mode_t); int init (HANDLE, DWORD, mode_t);
@ -1071,7 +1080,7 @@ public:
void doecho (const void *str, DWORD len); void doecho (const void *str, DWORD len);
int accept_input (); int accept_input ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); ssize_t __stdcall 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)));
int close (); int close ();
@ -1118,7 +1127,7 @@ class fhandler_dev_zero: public fhandler_base
public: public:
fhandler_dev_zero (); fhandler_dev_zero ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); ssize_t __stdcall 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 offset, int whence); _off64_t lseek (_off64_t offset, int whence);
@ -1145,7 +1154,7 @@ class fhandler_dev_random: public fhandler_base
public: public:
fhandler_dev_random (); fhandler_dev_random ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); ssize_t __stdcall 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 offset, int whence); _off64_t lseek (_off64_t offset, int whence);
int close (); int close ();
@ -1163,7 +1172,7 @@ class fhandler_dev_mem: public fhandler_base
~fhandler_dev_mem (); ~fhandler_dev_mem ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t ulen); ssize_t __stdcall write (const void *ptr, size_t ulen);
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)));
@ -1186,7 +1195,7 @@ class fhandler_dev_clipboard: public fhandler_base
fhandler_dev_clipboard (); fhandler_dev_clipboard ();
int is_windows () { return 1; } int is_windows () { return 1; }
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); ssize_t __stdcall 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 offset, int whence); _off64_t lseek (_off64_t offset, int whence);
int close (); int close ();
@ -1204,7 +1213,7 @@ class fhandler_windows: public fhandler_base
fhandler_windows (); fhandler_windows ();
int is_windows () { return 1; } int is_windows () { return 1; }
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); ssize_t __stdcall 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)));
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
_off64_t lseek (_off64_t, int) { return 0; } _off64_t lseek (_off64_t, int) { return 0; }
@ -1235,7 +1244,7 @@ class fhandler_dev_dsp: public fhandler_base
fhandler_dev_dsp (); fhandler_dev_dsp ();
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int write (const void *ptr, size_t len); ssize_t __stdcall 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)));
int ioctl (unsigned int cmd, void *); int ioctl (unsigned int cmd, void *);
_off64_t lseek (_off64_t, int); _off64_t lseek (_off64_t, int);
@ -1266,7 +1275,7 @@ class fhandler_virtual : public fhandler_base
void seekdir (DIR *, _off64_t); void seekdir (DIR *, _off64_t);
void rewinddir (DIR *); void rewinddir (DIR *);
int closedir (DIR *); int closedir (DIR *);
int write (const void *ptr, size_t len); ssize_t __stdcall 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);

View File

@ -143,7 +143,7 @@ set_clipboard (const void *buf, size_t len)
} }
/* FIXME: arbitrary seeking is not handled */ /* FIXME: arbitrary seeking is not handled */
int ssize_t __stdcall
fhandler_dev_clipboard::write (const void *buf, size_t len) fhandler_dev_clipboard::write (const void *buf, size_t len)
{ {
if (!eof) if (!eof)

View File

@ -1639,7 +1639,7 @@ fhandler_console::write_normal (const unsigned char *src,
return found; return found;
} }
int ssize_t __stdcall
fhandler_console::write (const void *vsrc, size_t len) fhandler_console::write (const void *vsrc, size_t len)
{ {
/* Run and check for ansi sequences */ /* Run and check for ansi sequences */

View File

@ -997,7 +997,7 @@ fhandler_dev_dsp::open (int flags, mode_t mode)
#define IS_WRITE() ((get_flags() & O_ACCMODE) != O_RDONLY) #define IS_WRITE() ((get_flags() & O_ACCMODE) != O_RDONLY)
#define IS_READ() ((get_flags() & O_ACCMODE) != O_WRONLY) #define IS_READ() ((get_flags() & O_ACCMODE) != O_WRONLY)
int ssize_t __stdcall
fhandler_dev_dsp::write (const void *ptr, size_t len) fhandler_dev_dsp::write (const void *ptr, size_t len)
{ {
debug_printf ("ptr=%08x len=%d", ptr, len); debug_printf ("ptr=%08x len=%d", ptr, len);

View File

@ -21,7 +21,7 @@
#include "cygtls.h" #include "cygtls.h"
fhandler_fifo::fhandler_fifo (): fhandler_fifo::fhandler_fifo ():
wait_state (fifo_unknown) wait_state (fifo_unknown), dummy_client (NULL)
{ {
get_overlapped ()->hEvent = NULL; get_overlapped ()->hEvent = NULL;
need_fork_fixup (true); need_fork_fixup (true);
@ -54,80 +54,87 @@ fhandler_fifo::open_nonserver (const char *npname, unsigned low_flags,
} }
} }
char *
fhandler_fifo::fifo_name (char *buf)
{
/* Generate a semi-unique name to associate with this fifo. */
__small_sprintf (buf, "\\\\.\\pipe\\__cygfifo__%08x_%016X",
get_dev (), get_ino ());
return buf;
}
#define FIFO_PIPE_MODE (PIPE_TYPE_BYTE | PIPE_READMODE_BYTE) #define FIFO_PIPE_MODE (PIPE_TYPE_BYTE | PIPE_READMODE_BYTE)
#define FIFO_BUF_SIZE 4096
#define cnp(m, s) CreateNamedPipe(npname, (m), FIFO_PIPE_MODE, \
PIPE_UNLIMITED_INSTANCES, (s), (s), \
NMPWAIT_WAIT_FOREVER, sa_buf)
int int
fhandler_fifo::open (int flags, mode_t) fhandler_fifo::open (int flags, mode_t)
{ {
int res; int res = 1;
char npname[MAX_PATH]; char npname[MAX_PATH];
DWORD mode = 0;
/* Generate a semi-unique name to associate with this fifo. */
__small_sprintf (npname, "\\\\.\\pipe\\__cygfifo__%08x_%016X",
get_dev (), get_ino ());
fifo_name (npname);
unsigned low_flags = flags & O_ACCMODE; unsigned low_flags = flags & O_ACCMODE;
if (low_flags == O_RDONLY) DWORD mode = 0;
mode = PIPE_ACCESS_INBOUND; if (low_flags == O_WRONLY)
else if (low_flags == O_WRONLY)
mode = PIPE_ACCESS_OUTBOUND; mode = PIPE_ACCESS_OUTBOUND;
else if (low_flags == O_RDWR) else if (low_flags == O_RDONLY || low_flags == O_RDWR)
mode = PIPE_ACCESS_DUPLEX; mode = PIPE_ACCESS_DUPLEX;
else
if (!mode)
{ {
set_errno (EINVAL); set_errno (EINVAL);
res = 0; res = 0;
} }
else
if (res)
{ {
char char_sa_buf[1024]; char char_sa_buf[1024];
LPSECURITY_ATTRIBUTES sa_buf = LPSECURITY_ATTRIBUTES sa_buf =
sec_user ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid()); sec_user ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid());
mode |= FILE_FLAG_OVERLAPPED;
HANDLE h; HANDLE h;
DWORD err;
bool nonblocking_write = !!((flags & (O_WRONLY | O_NONBLOCK)) == (O_WRONLY | O_NONBLOCK)); bool nonblocking_write = !!((flags & (O_WRONLY | O_NONBLOCK)) == (O_WRONLY | O_NONBLOCK));
if (nonblocking_write) wait_state = fifo_unknown;
if (mode != PIPE_ACCESS_OUTBOUND)
{ {
h = INVALID_HANDLE_VALUE; h = cnp (mode | FILE_FLAG_OVERLAPPED, FIFO_BUF_SIZE);
err = ERROR_ACCESS_DENIED; wait_state = fifo_wait_for_client;
} }
else else
{ {
h = CreateNamedPipe(npname, mode, FIFO_PIPE_MODE, h = open_nonserver (npname, low_flags, sa_buf);
PIPE_UNLIMITED_INSTANCES, 0, 0, if (h != INVALID_HANDLE_VALUE)
NMPWAIT_WAIT_FOREVER, sa_buf); wait_state = fifo_ok;
err = GetLastError (); else if (nonblocking_write)
} set_errno (ENXIO);
if (h != INVALID_HANDLE_VALUE) else if ((h = cnp (PIPE_ACCESS_DUPLEX, 1)) != INVALID_HANDLE_VALUE)
wait_state = fifo_wait_for_client;
else
switch (err)
{ {
case ERROR_ACCESS_DENIED: if ((dummy_client = open_nonserver (npname, low_flags, sa_buf))
h = open_nonserver (npname, low_flags, sa_buf); != INVALID_HANDLE_VALUE)
if (h != INVALID_HANDLE_VALUE)
{ {
wait_state = fifo_wait_for_server; wait_state = fifo_wait_for_server;
break; ProtectHandle (dummy_client);
} }
if (nonblocking_write && GetLastError () == ERROR_FILE_NOT_FOUND) else
{ {
set_errno (ENXIO); DWORD saveerr = GetLastError ();
break; CloseHandle (h);
h = INVALID_HANDLE_VALUE;
SetLastError (saveerr);
} }
/* fall through intentionally */
default:
__seterrno ();
break;
} }
if (!h || h == INVALID_HANDLE_VALUE) }
res = 0; if (h == INVALID_HANDLE_VALUE)
{
__seterrno ();
res = 0;
}
else if (!setup_overlapped ()) else if (!setup_overlapped ())
{ {
CloseHandle (h);
__seterrno (); __seterrno ();
res = 0; res = 0;
} }
@ -146,35 +153,116 @@ fhandler_fifo::open (int flags, mode_t)
bool bool
fhandler_fifo::wait (bool iswrite) fhandler_fifo::wait (bool iswrite)
{ {
DWORD ninstances;
switch (wait_state) switch (wait_state)
{ {
case fifo_wait_for_next_client:
DisconnectNamedPipe (get_handle ());
if (!GetNamedPipeHandleState (get_handle (), NULL, &ninstances, NULL, NULL, NULL, 0))
{
__seterrno ();
wait_state = fifo_error;
return false;
}
if (ninstances <= 1)
{
wait_state = fifo_eof;
return false;
}
case fifo_wait_for_client: case fifo_wait_for_client:
{ {
bool res = ConnectNamedPipe (get_handle (), get_overlapped ());
DWORD dummy_bytes; DWORD dummy_bytes;
if (res || GetLastError () == ERROR_PIPE_CONNECTED) while (1)
return true; {
return wait_overlapped (res, iswrite, &dummy_bytes); int res = ConnectNamedPipe (get_handle (), get_overlapped ());
if (GetLastError () != ERROR_NO_DATA && GetLastError () != ERROR_PIPE_CONNECTED)
{
res = wait_overlapped (res, iswrite, &dummy_bytes);
if (!res)
{
if (get_errno () != EINTR)
wait_state = fifo_error;
else if (!_my_tls.call_signal_handler ())
wait_state = fifo_eintr;
else
continue;
return false;
}
}
wait_state = fifo_ok;
break;
}
} }
case fifo_unknown: break;
case fifo_wait_for_server: case fifo_wait_for_server:
/* CGF FIXME SOON: test if these really need to be handled. */ char npname[MAX_PATH];
fifo_name (npname);
char char_sa_buf[1024];
LPSECURITY_ATTRIBUTES sa_buf;
sa_buf = sec_user ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid());
while (1)
{
if (WaitNamedPipe (npname, 10))
/* connected, maybe */;
else if (GetLastError () != ERROR_SEM_TIMEOUT)
{
__seterrno ();
return false;
}
else if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
continue;
else if (_my_tls.call_signal_handler ())
continue;
else
{
set_errno (EINTR);
return false;
}
HANDLE h = open_nonserver (npname, get_flags () & O_ACCMODE, sa_buf);
if (h != INVALID_HANDLE_VALUE)
{
ForceCloseHandle (get_handle ());
ForceCloseHandle (dummy_client);
dummy_client = NULL;
wait_state = fifo_ok;
set_io_handle (h);
break;
}
if (GetLastError () == ERROR_PIPE_LISTENING)
continue;
else
{
__seterrno ();
return false;
}
}
default: default:
break; break;
} }
return true; return true;
} }
void void __stdcall
fhandler_fifo::raw_read (void *in_ptr, size_t& len) fhandler_fifo::raw_read (void *in_ptr, size_t& len)
{ {
if (!wait (false)) while (wait_state != fifo_eof && wait_state != fifo_error && wait_state != fifo_eintr)
len = 0; if (!wait (false))
else len = (wait_state == fifo_error || wait_state == fifo_eintr) ? (size_t) -1 : 0;
read_overlapped (in_ptr, len); else
{
size_t prev_len = len;
read_overlapped (in_ptr, len);
if (len)
break;
wait_state = fifo_wait_for_next_client;
len = prev_len;
}
if (wait_state == fifo_eintr)
wait_state = fifo_wait_for_client;
debug_printf ("returning %d, mode %d, %E\n", len, get_errno ());
} }
int ssize_t __stdcall
fhandler_fifo::raw_write (const void *ptr, size_t len) fhandler_fifo::raw_write (const void *ptr, size_t len)
{ {
return wait (true) ? write_overlapped (ptr, len) : -1; return wait (true) ? write_overlapped (ptr, len) : -1;
@ -187,3 +275,44 @@ fhandler_fifo::fstatvfs (struct statvfs *sfs)
fh.get_device () = FH_FS; fh.get_device () = FH_FS;
return fh.fstatvfs (sfs); return fh.fstatvfs (sfs);
} }
int
fhandler_fifo::close ()
{
wait_state = fifo_eof;
if (dummy_client)
{
ForceCloseHandle (dummy_client);
dummy_client = NULL;
}
return fhandler_base::close ();
}
int
fhandler_fifo::dup (fhandler_base *child)
{
int res = fhandler_base::dup (child);
fhandler_fifo *fifo_child = (fhandler_fifo *) child;
if (res == 0 && dummy_client)
{
bool dres = DuplicateHandle (hMainProc, dummy_client, hMainProc,
&fifo_child->dummy_client, 0,
TRUE, DUPLICATE_SAME_ACCESS);
if (!dres)
{
fifo_child->dummy_client = NULL;
child->close ();
__seterrno ();
res = -1;
}
}
return res;
}
void
fhandler_fifo::set_close_on_exec (bool val)
{
fhandler_base::set_close_on_exec (val);
if (dummy_client)
set_no_inheritance (dummy_client, val);
}

View File

@ -255,7 +255,7 @@ fhandler_dev_floppy::get_current_position ()
return off.QuadPart; return off.QuadPart;
} }
void void __stdcall
fhandler_dev_floppy::raw_read (void *ptr, size_t& ulen) fhandler_dev_floppy::raw_read (void *ptr, size_t& ulen)
{ {
DWORD bytes_read = 0; DWORD bytes_read = 0;
@ -387,7 +387,7 @@ err:
ulen = (size_t) -1; ulen = (size_t) -1;
} }
int int __stdcall
fhandler_dev_floppy::raw_write (const void *ptr, size_t len) fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
{ {
DWORD bytes_written = 0; DWORD bytes_written = 0;

View File

@ -124,7 +124,7 @@ fhandler_mailslot::open (int flags, mode_t mode)
return res; return res;
} }
int ssize_t __stdcall
fhandler_mailslot::write (const void *ptr, size_t len) fhandler_mailslot::write (const void *ptr, size_t len)
{ {
/* Check for 425/426 byte weirdness */ /* Check for 425/426 byte weirdness */

View File

@ -113,7 +113,7 @@ fhandler_dev_mem::open (int flags, mode_t)
return 1; return 1;
} }
int ssize_t __stdcall
fhandler_dev_mem::write (const void *ptr, size_t ulen) fhandler_dev_mem::write (const void *ptr, size_t ulen)
{ {
if (!ulen || pos >= mem_size) if (!ulen || pos >= mem_size)

View File

@ -68,7 +68,7 @@ fhandler_dev_random::pseudo_write (const void *ptr, size_t len)
return len; return len;
} }
int ssize_t __stdcall
fhandler_dev_random::write (const void *ptr, size_t len) fhandler_dev_random::write (const void *ptr, size_t len)
{ {
if (!len) if (!len)

View File

@ -37,7 +37,7 @@ fhandler_serial::overlapped_setup ()
overlapped_armed = 0; overlapped_armed = 0;
} }
void void __stdcall
fhandler_serial::raw_read (void *ptr, size_t& ulen) fhandler_serial::raw_read (void *ptr, size_t& ulen)
{ {
int tot; int tot;
@ -144,7 +144,7 @@ out:
/* Cover function to WriteFile to provide Posix interface and semantics /* Cover function to WriteFile to provide Posix interface and semantics
(as much as possible). */ (as much as possible). */
int ssize_t __stdcall
fhandler_serial::raw_write (const void *ptr, size_t len) fhandler_serial::raw_write (const void *ptr, size_t len)
{ {
DWORD bytes_written; DWORD bytes_written;

View File

@ -1232,7 +1232,7 @@ fhandler_dev_tape::close ()
return ret ? -1 : cret; return ret ? -1 : cret;
} }
void void __stdcall
fhandler_dev_tape::raw_read (void *ptr, size_t &ulen) fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
{ {
char *buf = (char *) ptr; char *buf = (char *) ptr;
@ -1333,7 +1333,7 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
unlock (); unlock ();
} }
int ssize_t __stdcall
fhandler_dev_tape::raw_write (const void *ptr, size_t len) fhandler_dev_tape::raw_write (const void *ptr, size_t len)
{ {
lock (-1); lock (-1);

View File

@ -671,7 +671,7 @@ fhandler_tty_slave::init (HANDLE, DWORD a, mode_t)
return open (flags); return open (flags);
} }
int ssize_t __stdcall
fhandler_tty_slave::write (const void *ptr, size_t len) fhandler_tty_slave::write (const void *ptr, size_t len)
{ {
DWORD n, towrite = len; DWORD n, towrite = len;
@ -1202,7 +1202,7 @@ fhandler_pty_master::close ()
return 0; return 0;
} }
int ssize_t __stdcall
fhandler_pty_master::write (const void *ptr, size_t len) fhandler_pty_master::write (const void *ptr, size_t len)
{ {
int i; int i;

View File

@ -180,7 +180,7 @@ fhandler_virtual::close ()
return 0; return 0;
} }
void void __stdcall
fhandler_virtual::read (void *ptr, size_t& len) fhandler_virtual::read (void *ptr, size_t& len)
{ {
if (len == 0) if (len == 0)
@ -205,7 +205,7 @@ fhandler_virtual::read (void *ptr, size_t& len)
position += len; position += len;
} }
int ssize_t __stdcall
fhandler_virtual::write (const void *ptr, size_t len) fhandler_virtual::write (const void *ptr, size_t len)
{ {
set_errno (EACCES); set_errno (EACCES);

View File

@ -60,7 +60,7 @@ fhandler_windows::open (int flags, mode_t)
return 1; return 1;
} }
int ssize_t __stdcall
fhandler_windows::write (const void *buf, size_t) fhandler_windows::write (const void *buf, size_t)
{ {
MSG *ptr = (MSG *) buf; MSG *ptr = (MSG *) buf;

View File

@ -30,7 +30,7 @@ fhandler_dev_zero::open (int flags, mode_t)
return 1; return 1;
} }
int ssize_t __stdcall
fhandler_dev_zero::write (const void *, size_t len) fhandler_dev_zero::write (const void *, size_t len)
{ {
if (get_device () == FH_FULL) if (get_device () == FH_FULL)

View File

@ -242,7 +242,7 @@ frok::child (volatile char * volatile here)
ld_preload (); ld_preload ();
fixup_hooks_after_fork (); fixup_hooks_after_fork ();
_my_tls.fixup_after_fork (); _my_tls.fixup_after_fork ();
wait_for_sigthread (true); wait_for_sigthread ();
cygwin_finished_initializing = true; cygwin_finished_initializing = true;
return 0; return 0;
} }

View File

@ -128,24 +128,16 @@ signal_fixup_after_exec ()
} }
void __stdcall void __stdcall
wait_for_sigthread (bool forked) wait_for_sigthread ()
{ {
char char_sa_buf[1024];
PSECURITY_ATTRIBUTES sa_buf = sec_user_nih ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid());
if (!CreatePipe (&my_readsig, &my_sendsig, sa_buf, 0))
api_fatal ("couldn't create signal pipe%s, %E", forked ? " for forked process" : "");
ProtectHandle (my_readsig);
myself->sendsig = my_sendsig;
myself->process_state |= PID_ACTIVE;
myself->process_state &= ~PID_INITIALIZING;
sigproc_printf ("wait_sig_inited %p", wait_sig_inited); sigproc_printf ("wait_sig_inited %p", wait_sig_inited);
HANDLE hsig_inited = wait_sig_inited; HANDLE hsig_inited = wait_sig_inited;
WaitForSingleObject (hsig_inited, INFINITE); WaitForSingleObject (hsig_inited, INFINITE);
wait_sig_inited = NULL; wait_sig_inited = NULL;
myself->sendsig = my_sendsig;
myself->process_state |= PID_ACTIVE;
myself->process_state &= ~PID_INITIALIZING;
ForceCloseHandle1 (hsig_inited, wait_sig_inited); ForceCloseHandle1 (hsig_inited, wait_sig_inited);
SetEvent (sigCONT);
sigproc_printf ("process/signal handling enabled, state %p", myself->process_state); sigproc_printf ("process/signal handling enabled, state %p", myself->process_state);
} }
@ -1152,11 +1144,28 @@ pending_signals::next ()
return res; return res;
} }
/* Called separately to allow stack space reutilization by wait_sig.
This function relies on the fact that it will be called after cygheap
has been set up. For the case of non-dynamic DLL initialization this
means that it relies on the implicit serialization guarantted by being
run as part of DLL_PROCESS_ATTACH. */
static void __attribute__ ((noinline))
init_sig_pipe()
{
char char_sa_buf[1024];
PSECURITY_ATTRIBUTES sa_buf = sec_user_nih ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid());
if (!CreatePipe (&my_readsig, &my_sendsig, sa_buf, 0))
api_fatal ("couldn't create signal pipe, %E");
ProtectHandle (my_readsig);
}
/* Process signals by waiting for signal data to arrive in a pipe. /* Process signals by waiting for signal data to arrive in a pipe.
Set a completion event if one was specified. */ Set a completion event if one was specified. */
static DWORD WINAPI static DWORD WINAPI
wait_sig (VOID *) wait_sig (VOID *)
{ {
init_sig_pipe ();
/* Initialization */ /* Initialization */
SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
@ -1169,7 +1178,7 @@ wait_sig (VOID *)
my_readsig, my_sendsig); my_readsig, my_sendsig);
sigpacket pack; sigpacket pack;
pack.si.si_signo = __SIGHOLD; pack.si.si_signo = 0;
for (;;) for (;;)
{ {
if (pack.si.si_signo == __SIGHOLD) if (pack.si.si_signo == __SIGHOLD)

View File

@ -81,7 +81,7 @@ bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3))); int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3)));
int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2))); int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
void __stdcall signal_fixup_after_exec (); void __stdcall signal_fixup_after_exec ();
void __stdcall wait_for_sigthread (bool = false); void __stdcall wait_for_sigthread ();
void __stdcall sigalloc (); void __stdcall sigalloc ();
void __stdcall create_signal_arrived (); void __stdcall create_signal_arrived ();

View File

@ -842,7 +842,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
extern int sigcatchers; extern int sigcatchers;
const int e = get_errno (); const int e = get_errno ();
int res = -1; ssize_t res = -1;
const ssize_t tot = check_iovec_for_read (iov, iovcnt); const ssize_t tot = check_iovec_for_read (iov, iovcnt);