Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2009-07-25 00:54:33 +0400
committerChristopher Faylor <me@cgf.cx>2009-07-25 00:54:33 +0400
commit43c23d4b822cc23f35c3668272526bebf3630454 (patch)
tree90bda14088be11218540c2b991cabb39f062a9ee
parenta58ebe50c216947d748e51c16d3fa93f9b98ed30 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog58
-rw-r--r--winsup/cygwin/fhandler.cc31
-rw-r--r--winsup/cygwin/fhandler.h83
-rw-r--r--winsup/cygwin/fhandler_clipboard.cc2
-rw-r--r--winsup/cygwin/fhandler_console.cc2
-rw-r--r--winsup/cygwin/fhandler_dsp.cc2
-rw-r--r--winsup/cygwin/fhandler_fifo.cc235
-rw-r--r--winsup/cygwin/fhandler_floppy.cc4
-rw-r--r--winsup/cygwin/fhandler_mailslot.cc2
-rw-r--r--winsup/cygwin/fhandler_mem.cc2
-rw-r--r--winsup/cygwin/fhandler_random.cc2
-rw-r--r--winsup/cygwin/fhandler_serial.cc4
-rw-r--r--winsup/cygwin/fhandler_tape.cc4
-rw-r--r--winsup/cygwin/fhandler_tty.cc4
-rw-r--r--winsup/cygwin/fhandler_virtual.cc4
-rw-r--r--winsup/cygwin/fhandler_windows.cc2
-rw-r--r--winsup/cygwin/fhandler_zero.cc2
-rw-r--r--winsup/cygwin/fork.cc2
-rw-r--r--winsup/cygwin/sigproc.cc35
-rw-r--r--winsup/cygwin/sigproc.h2
-rw-r--r--winsup/cygwin/syscalls.cc2
21 files changed, 341 insertions, 143 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 50b183dbe..49cc67e79 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>
* syscalls.cc (internal_setlocale): Fix typo in GBK codepage.
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 9ba286ec0..b8f624e2f 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -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
semantics and use of errno. */
-void
+void __stdcall
fhandler_base::raw_read (void *ptr, size_t& 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_append = { QuadPart:FILE_WRITE_TO_END_OF_FILE };
-int
+ssize_t __stdcall
fhandler_base::raw_write (const void *ptr, size_t len)
{
NTSTATUS status;
@@ -649,7 +649,7 @@ done:
an \n. If last char is an \r, look ahead one more char, if \n then
modify \r, if not, remember char.
*/
-void
+void __stdcall
fhandler_base::read (void *in_ptr, size_t& len)
{
char *ptr = (char *) in_ptr;
@@ -676,7 +676,7 @@ fhandler_base::read (void *in_ptr, size_t& len)
else
len = copied_chars;
- if (rbinary () || len <= 0)
+ if (rbinary () || (ssize_t) len <= 0)
goto out;
/* Scan buffer and turn \r\n into \n */
@@ -739,7 +739,7 @@ out:
debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
}
-int
+ssize_t __stdcall
fhandler_base::write (const void *ptr, size_t len)
{
int res;
@@ -834,7 +834,7 @@ fhandler_base::write (const void *ptr, size_t len)
return res;
}
-ssize_t
+ssize_t __stdcall
fhandler_base::readv (const struct iovec *const iov, const int iovcnt,
ssize_t tot)
{
@@ -891,7 +891,7 @@ fhandler_base::readv (const struct iovec *const iov, const int iovcnt,
return len;
}
-ssize_t
+ssize_t __stdcall
fhandler_base::writev (const struct iovec *const iov, const int iovcnt,
ssize_t tot)
{
@@ -1682,10 +1682,10 @@ fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes, DWORD le
int res = 0;
- DWORD err;
+ DWORD err = GetLastError ();
if (is_nonblocking ())
{
- if (inres || GetLastError () == ERROR_IO_PENDING)
+ if (inres || err == ERROR_IO_PENDING)
{
if (writing && !inres)
*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;
err = 0;
}
- else
- {
- res = 0;
- err = GetLastError ();
- }
}
- else if (inres || ((err = GetLastError ()) == ERROR_IO_PENDING))
+ else if (inres || err == ERROR_IO_PENDING)
{
#ifdef DEBUGGING
- if (!get_overlapped ())
- system_printf ("get_overlapped is zero?");
if (!get_overlapped ()->hEvent)
system_printf ("hEvent is zero?");
#endif
@@ -1749,7 +1742,7 @@ fhandler_base::wait_overlapped (bool inres, bool writing, DWORD *bytes, DWORD le
debug_printf ("err %u", err);
__seterrno_from_win_error (err);
*bytes = (DWORD) -1;
- res = -1;
+ res = 0;
}
else
{
@@ -1796,7 +1789,7 @@ fhandler_base::read_overlapped (void *ptr, size_t& len)
len = (size_t) nbytes;
}
-int __stdcall
+ssize_t __stdcall
fhandler_base::write_overlapped (const void *ptr, size_t len)
{
DWORD nbytes;
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 4995d15b2..382a592cb 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -310,10 +310,10 @@ class fhandler_base
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 bool __stdcall has_ongoing_io (bool) __attribute__ ((regparm (2)));
- virtual int write (const void *ptr, size_t len);
- virtual int __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 writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
+ virtual ssize_t __stdcall write (const void *ptr, size_t len);
+ virtual ssize_t __stdcall write_overlapped (const void *ptr, size_t len);
+ virtual ssize_t __stdcall readv (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 pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));
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 int is_windows () {return 0; }
- virtual void raw_read (void *ptr, size_t& ulen);
- virtual int raw_write (const void *ptr, size_t ulen);
+ virtual void __stdcall raw_read (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_buffer () {return NULL;}
virtual void set_overlapped (OVERLAPPED *) {}
@@ -399,7 +399,7 @@ class fhandler_mailslot : public fhandler_base
fhandler_mailslot ();
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
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 *);
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 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);
ssize_t recvfrom (void *ptr, size_t len, int flags,
struct sockaddr *from, int *fromlen);
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);
ssize_t sendto (const void *ptr, size_t len, int flags,
const struct sockaddr *to, int tolen);
@@ -563,8 +563,8 @@ public:
select_record *select_write (select_stuff *);
select_record *select_except (select_stuff *);
char *get_proc_fd_name (char *buf);
- void raw_read (void *ptr, size_t& len);
- int raw_write (const void *, size_t);
+ void __stdcall raw_read (void *ptr, size_t& len);
+ ssize_t __stdcall raw_write (const void *, size_t);
int open (int flags, mode_t mode = 0);
int dup (fhandler_base *child);
int ioctl (unsigned int cmd, void *);
@@ -578,25 +578,34 @@ public:
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
{
+ 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;
+ HANDLE dummy_client;
HANDLE open_nonserver (const char *, unsigned, LPSECURITY_ATTRIBUTES);
OVERLAPPED io_status;
bool wait (bool) __attribute__ ((regparm (1)));
+ char *fifo_name (char *) __attribute__ ((regparm (2)));
public:
fhandler_fifo ();
- void raw_read (void *, size_t&);
- int raw_write (const void *, size_t);
+ void __stdcall raw_read (void *, size_t&);
+ ssize_t __stdcall raw_write (const void *, size_t);
int open (int, mode_t);
+ int close ();
+ int dup (fhandler_base *child);
bool isfifo () { return true; }
+ void set_close_on_exec (bool val);
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
OVERLAPPED *get_overlapped () {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 dup (fhandler_base *child);
- void raw_read (void *ptr, size_t& ulen);
- int raw_write (const void *ptr, size_t ulen);
+ void __stdcall raw_read (void *ptr, size_t& ulen);
+ ssize_t __stdcall raw_write (const void *ptr, size_t ulen);
_off64_t lseek (_off64_t offset, int whence);
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 close ();
- void raw_read (void *ptr, size_t& ulen);
- int raw_write (const void *ptr, size_t ulen);
+ void __stdcall raw_read (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);
@@ -780,8 +789,8 @@ class fhandler_serial: public fhandler_base
int init (HANDLE h, DWORD a, mode_t flags);
void overlapped_setup ();
int dup (fhandler_base *child);
- void raw_read (void *ptr, size_t& ulen);
- int raw_write (const void *ptr, size_t ulen);
+ void __stdcall raw_read (void *ptr, size_t& ulen);
+ ssize_t __stdcall raw_write (const void *ptr, size_t ulen);
int tcsendbreak (int);
int tcdrain ();
int tcflow (int);
@@ -966,9 +975,9 @@ class fhandler_console: public fhandler_termios
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)));
+ ssize_t __stdcall write (const void *ptr, size_t len);
+ void doecho (const void *str, DWORD len) { (void) write (str, len); }
int close ();
int tcflush (int);
@@ -1038,7 +1047,7 @@ class fhandler_tty_slave: public fhandler_tty_common
fhandler_tty_slave ();
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)));
int init (HANDLE, DWORD, mode_t);
@@ -1071,7 +1080,7 @@ public:
void doecho (const void *str, DWORD len);
int accept_input ();
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)));
int close ();
@@ -1118,7 +1127,7 @@ class fhandler_dev_zero: public fhandler_base
public:
fhandler_dev_zero ();
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)));
_off64_t lseek (_off64_t offset, int whence);
@@ -1145,7 +1154,7 @@ class fhandler_dev_random: public fhandler_base
public:
fhandler_dev_random ();
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)));
_off64_t lseek (_off64_t offset, int whence);
int close ();
@@ -1163,7 +1172,7 @@ class fhandler_dev_mem: public fhandler_base
~fhandler_dev_mem ();
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)));
_off64_t lseek (_off64_t offset, int whence);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
@@ -1186,7 +1195,7 @@ class fhandler_dev_clipboard: public fhandler_base
fhandler_dev_clipboard ();
int is_windows () { return 1; }
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)));
_off64_t lseek (_off64_t offset, int whence);
int close ();
@@ -1204,7 +1213,7 @@ class fhandler_windows: public fhandler_base
fhandler_windows ();
int is_windows () { return 1; }
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)));
int ioctl (unsigned int cmd, void *);
_off64_t lseek (_off64_t, int) { return 0; }
@@ -1235,7 +1244,7 @@ class fhandler_dev_dsp: public fhandler_base
fhandler_dev_dsp ();
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)));
int ioctl (unsigned int cmd, void *);
_off64_t lseek (_off64_t, int);
@@ -1266,7 +1275,7 @@ class fhandler_virtual : public fhandler_base
void seekdir (DIR *, _off64_t);
void rewinddir (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)));
_off64_t lseek (_off64_t, int);
int dup (fhandler_base *child);
diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc
index 3750d16cd..c4f060578 100644
--- a/winsup/cygwin/fhandler_clipboard.cc
+++ b/winsup/cygwin/fhandler_clipboard.cc
@@ -143,7 +143,7 @@ set_clipboard (const void *buf, size_t len)
}
/* FIXME: arbitrary seeking is not handled */
-int
+ssize_t __stdcall
fhandler_dev_clipboard::write (const void *buf, size_t len)
{
if (!eof)
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 339b83cbf..5cc7e332f 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -1639,7 +1639,7 @@ fhandler_console::write_normal (const unsigned char *src,
return found;
}
-int
+ssize_t __stdcall
fhandler_console::write (const void *vsrc, size_t len)
{
/* Run and check for ansi sequences */
diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc
index 1927a9b28..9095ba517 100644
--- a/winsup/cygwin/fhandler_dsp.cc
+++ b/winsup/cygwin/fhandler_dsp.cc
@@ -997,7 +997,7 @@ fhandler_dev_dsp::open (int flags, mode_t mode)
#define IS_WRITE() ((get_flags() & O_ACCMODE) != O_RDONLY)
#define IS_READ() ((get_flags() & O_ACCMODE) != O_WRONLY)
-int
+ssize_t __stdcall
fhandler_dev_dsp::write (const void *ptr, size_t len)
{
debug_printf ("ptr=%08x len=%d", ptr, len);
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 517eceb31..d96616fc5 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -21,7 +21,7 @@
#include "cygtls.h"
fhandler_fifo::fhandler_fifo ():
- wait_state (fifo_unknown)
+ wait_state (fifo_unknown), dummy_client (NULL)
{
get_overlapped ()->hEvent = NULL;
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_BUF_SIZE 4096
+#define cnp(m, s) CreateNamedPipe(npname, (m), FIFO_PIPE_MODE, \
+ PIPE_UNLIMITED_INSTANCES, (s), (s), \
+ NMPWAIT_WAIT_FOREVER, sa_buf)
+
int
fhandler_fifo::open (int flags, mode_t)
{
- int res;
+ int res = 1;
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;
- if (low_flags == O_RDONLY)
- mode = PIPE_ACCESS_INBOUND;
- else if (low_flags == O_WRONLY)
+ DWORD mode = 0;
+ if (low_flags == O_WRONLY)
mode = PIPE_ACCESS_OUTBOUND;
- else if (low_flags == O_RDWR)
+ else if (low_flags == O_RDONLY || low_flags == O_RDWR)
mode = PIPE_ACCESS_DUPLEX;
-
- if (!mode)
+ else
{
set_errno (EINVAL);
res = 0;
}
- else
+
+ if (res)
{
char char_sa_buf[1024];
LPSECURITY_ATTRIBUTES sa_buf =
sec_user ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid());
- mode |= FILE_FLAG_OVERLAPPED;
HANDLE h;
- DWORD err;
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;
- err = ERROR_ACCESS_DENIED;
+ h = cnp (mode | FILE_FLAG_OVERLAPPED, FIFO_BUF_SIZE);
+ wait_state = fifo_wait_for_client;
}
else
{
- h = CreateNamedPipe(npname, mode, FIFO_PIPE_MODE,
- PIPE_UNLIMITED_INSTANCES, 0, 0,
- NMPWAIT_WAIT_FOREVER, sa_buf);
- err = GetLastError ();
- }
- if (h != INVALID_HANDLE_VALUE)
- wait_state = fifo_wait_for_client;
- else
- switch (err)
+ h = open_nonserver (npname, low_flags, sa_buf);
+ if (h != INVALID_HANDLE_VALUE)
+ wait_state = fifo_ok;
+ else if (nonblocking_write)
+ set_errno (ENXIO);
+ else if ((h = cnp (PIPE_ACCESS_DUPLEX, 1)) != INVALID_HANDLE_VALUE)
{
- case ERROR_ACCESS_DENIED:
- h = open_nonserver (npname, low_flags, sa_buf);
- if (h != INVALID_HANDLE_VALUE)
+ if ((dummy_client = open_nonserver (npname, low_flags, sa_buf))
+ != INVALID_HANDLE_VALUE)
{
wait_state = fifo_wait_for_server;
- break;
+ ProtectHandle (dummy_client);
}
- if (nonblocking_write && GetLastError () == ERROR_FILE_NOT_FOUND)
+ else
{
- set_errno (ENXIO);
- break;
+ DWORD saveerr = GetLastError ();
+ 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 ())
{
+ CloseHandle (h);
__seterrno ();
res = 0;
}
@@ -146,35 +153,116 @@ fhandler_fifo::open (int flags, mode_t)
bool
fhandler_fifo::wait (bool iswrite)
{
+ DWORD ninstances;
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:
{
- bool res = ConnectNamedPipe (get_handle (), get_overlapped ());
DWORD dummy_bytes;
- if (res || GetLastError () == ERROR_PIPE_CONNECTED)
- return true;
- return wait_overlapped (res, iswrite, &dummy_bytes);
+ while (1)
+ {
+ 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:
- /* 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:
break;
}
return true;
}
-void
+void __stdcall
fhandler_fifo::raw_read (void *in_ptr, size_t& len)
{
- if (!wait (false))
- len = 0;
- else
- read_overlapped (in_ptr, len);
+ while (wait_state != fifo_eof && wait_state != fifo_error && wait_state != fifo_eintr)
+ if (!wait (false))
+ len = (wait_state == fifo_error || wait_state == fifo_eintr) ? (size_t) -1 : 0;
+ 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)
{
return wait (true) ? write_overlapped (ptr, len) : -1;
@@ -187,3 +275,44 @@ fhandler_fifo::fstatvfs (struct statvfs *sfs)
fh.get_device () = FH_FS;
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);
+}
diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc
index 5a78a731a..0d906b186 100644
--- a/winsup/cygwin/fhandler_floppy.cc
+++ b/winsup/cygwin/fhandler_floppy.cc
@@ -255,7 +255,7 @@ fhandler_dev_floppy::get_current_position ()
return off.QuadPart;
}
-void
+void __stdcall
fhandler_dev_floppy::raw_read (void *ptr, size_t& ulen)
{
DWORD bytes_read = 0;
@@ -387,7 +387,7 @@ err:
ulen = (size_t) -1;
}
-int
+int __stdcall
fhandler_dev_floppy::raw_write (const void *ptr, size_t len)
{
DWORD bytes_written = 0;
diff --git a/winsup/cygwin/fhandler_mailslot.cc b/winsup/cygwin/fhandler_mailslot.cc
index dda4d3385..c0813df94 100644
--- a/winsup/cygwin/fhandler_mailslot.cc
+++ b/winsup/cygwin/fhandler_mailslot.cc
@@ -124,7 +124,7 @@ fhandler_mailslot::open (int flags, mode_t mode)
return res;
}
-int
+ssize_t __stdcall
fhandler_mailslot::write (const void *ptr, size_t len)
{
/* Check for 425/426 byte weirdness */
diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc
index 752c114ed..7bd809472 100644
--- a/winsup/cygwin/fhandler_mem.cc
+++ b/winsup/cygwin/fhandler_mem.cc
@@ -113,7 +113,7 @@ fhandler_dev_mem::open (int flags, mode_t)
return 1;
}
-int
+ssize_t __stdcall
fhandler_dev_mem::write (const void *ptr, size_t ulen)
{
if (!ulen || pos >= mem_size)
diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc
index 09d70c554..e5d8a4866 100644
--- a/winsup/cygwin/fhandler_random.cc
+++ b/winsup/cygwin/fhandler_random.cc
@@ -68,7 +68,7 @@ fhandler_dev_random::pseudo_write (const void *ptr, size_t len)
return len;
}
-int
+ssize_t __stdcall
fhandler_dev_random::write (const void *ptr, size_t len)
{
if (!len)
diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc
index 8a08beecc..a076dad1a 100644
--- a/winsup/cygwin/fhandler_serial.cc
+++ b/winsup/cygwin/fhandler_serial.cc
@@ -37,7 +37,7 @@ fhandler_serial::overlapped_setup ()
overlapped_armed = 0;
}
-void
+void __stdcall
fhandler_serial::raw_read (void *ptr, size_t& ulen)
{
int tot;
@@ -144,7 +144,7 @@ out:
/* Cover function to WriteFile to provide Posix interface and semantics
(as much as possible). */
-int
+ssize_t __stdcall
fhandler_serial::raw_write (const void *ptr, size_t len)
{
DWORD bytes_written;
diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc
index 57f918557..d90810f89 100644
--- a/winsup/cygwin/fhandler_tape.cc
+++ b/winsup/cygwin/fhandler_tape.cc
@@ -1232,7 +1232,7 @@ fhandler_dev_tape::close ()
return ret ? -1 : cret;
}
-void
+void __stdcall
fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
{
char *buf = (char *) ptr;
@@ -1333,7 +1333,7 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen)
unlock ();
}
-int
+ssize_t __stdcall
fhandler_dev_tape::raw_write (const void *ptr, size_t len)
{
lock (-1);
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index ae857e9ef..fbb766c3f 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -671,7 +671,7 @@ fhandler_tty_slave::init (HANDLE, DWORD a, mode_t)
return open (flags);
}
-int
+ssize_t __stdcall
fhandler_tty_slave::write (const void *ptr, size_t len)
{
DWORD n, towrite = len;
@@ -1202,7 +1202,7 @@ fhandler_pty_master::close ()
return 0;
}
-int
+ssize_t __stdcall
fhandler_pty_master::write (const void *ptr, size_t len)
{
int i;
diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc
index b11d596e0..c47d2ccdd 100644
--- a/winsup/cygwin/fhandler_virtual.cc
+++ b/winsup/cygwin/fhandler_virtual.cc
@@ -180,7 +180,7 @@ fhandler_virtual::close ()
return 0;
}
-void
+void __stdcall
fhandler_virtual::read (void *ptr, size_t& len)
{
if (len == 0)
@@ -205,7 +205,7 @@ fhandler_virtual::read (void *ptr, size_t& len)
position += len;
}
-int
+ssize_t __stdcall
fhandler_virtual::write (const void *ptr, size_t len)
{
set_errno (EACCES);
diff --git a/winsup/cygwin/fhandler_windows.cc b/winsup/cygwin/fhandler_windows.cc
index 09ce3a017..7475b89bb 100644
--- a/winsup/cygwin/fhandler_windows.cc
+++ b/winsup/cygwin/fhandler_windows.cc
@@ -60,7 +60,7 @@ fhandler_windows::open (int flags, mode_t)
return 1;
}
-int
+ssize_t __stdcall
fhandler_windows::write (const void *buf, size_t)
{
MSG *ptr = (MSG *) buf;
diff --git a/winsup/cygwin/fhandler_zero.cc b/winsup/cygwin/fhandler_zero.cc
index 41d1dcdca..a27c0f6ec 100644
--- a/winsup/cygwin/fhandler_zero.cc
+++ b/winsup/cygwin/fhandler_zero.cc
@@ -30,7 +30,7 @@ fhandler_dev_zero::open (int flags, mode_t)
return 1;
}
-int
+ssize_t __stdcall
fhandler_dev_zero::write (const void *, size_t len)
{
if (get_device () == FH_FULL)
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index cdaaca649..49ff2e1ab 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -242,7 +242,7 @@ frok::child (volatile char * volatile here)
ld_preload ();
fixup_hooks_after_fork ();
_my_tls.fixup_after_fork ();
- wait_for_sigthread (true);
+ wait_for_sigthread ();
cygwin_finished_initializing = true;
return 0;
}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 29bb00101..9c11ea022 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -128,24 +128,16 @@ signal_fixup_after_exec ()
}
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);
HANDLE hsig_inited = wait_sig_inited;
WaitForSingleObject (hsig_inited, INFINITE);
wait_sig_inited = NULL;
+ myself->sendsig = my_sendsig;
+ myself->process_state |= PID_ACTIVE;
+ myself->process_state &= ~PID_INITIALIZING;
ForceCloseHandle1 (hsig_inited, wait_sig_inited);
- SetEvent (sigCONT);
sigproc_printf ("process/signal handling enabled, state %p", myself->process_state);
}
@@ -1152,11 +1144,28 @@ pending_signals::next ()
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.
Set a completion event if one was specified. */
static DWORD WINAPI
wait_sig (VOID *)
{
+ init_sig_pipe ();
/* Initialization */
SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
@@ -1169,7 +1178,7 @@ wait_sig (VOID *)
my_readsig, my_sendsig);
sigpacket pack;
- pack.si.si_signo = __SIGHOLD;
+ pack.si.si_signo = 0;
for (;;)
{
if (pack.si.si_signo == __SIGHOLD)
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 5fef01d7a..7da1bc389 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -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 *, int) __attribute__ ((regparm (2)));
void __stdcall signal_fixup_after_exec ();
-void __stdcall wait_for_sigthread (bool = false);
+void __stdcall wait_for_sigthread ();
void __stdcall sigalloc ();
void __stdcall create_signal_arrived ();
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index eea65907b..fb17f1e2a 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -842,7 +842,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
extern int sigcatchers;
const int e = get_errno ();
- int res = -1;
+ ssize_t res = -1;
const ssize_t tot = check_iovec_for_read (iov, iovcnt);