diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-05-06 14:56:37 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-05-06 14:56:37 +0400 |
commit | a4e5706eb2e207ee891bc1dec7488ac6d3a14d48 (patch) | |
tree | 334b8f95cf17a34b1182e41961fe38b847acecb3 /winsup/cygwin/syscalls.cc | |
parent | 92ddb74290655b6f9394801dac4242c93e03f9ed (diff) |
* fhandler.h (fhandler_socket::read): Declare.
(fhandler_socket::write): Declare.
* fhandler_procsys.cc (fhandler_procsys::read): Add FIXME comment.
(fhandler_procsys::write): Ditto.
* fhandler_socket.cc (fhandler_socket::read): New method.
(fhandler_socket::write): New method.
* syscalls.cc: Rearrange order of read/write functions.
(read): Call fhandler read method directly instead of just readv.
(readv): Remove EINTR loop. This is done in all affected fhandler's
now.
(write): Call fhandler write method directly instead of just writev.
Fix debug output.
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r-- | winsup/cygwin/syscalls.cc | 154 |
1 files changed, 100 insertions, 54 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index d122c8dc2..70eb8ea1f 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -898,36 +898,86 @@ getsid (pid_t pid) extern "C" ssize_t read (int fd, void *ptr, size_t len) { - const iovec iov = + pthread_testcancel (); + + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + + size_t res = (size_t) -1; + + cygheap_fdget cfd (fd); + if (cfd < 0) + goto done; + + if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY) { - iov_base: ptr, - iov_len: len - }; + set_errno (EBADF); + goto done; + } - return readv (fd, &iov, 1); + /* Could block, so let user know we at least got here. */ + extern int sigcatchers; + syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", + fd, ptr, len, cfd->is_nonblocking () ? "non" : "", + sigcatchers); + + cfd->read (ptr, res = len); + +done: + syscall_printf ("%d = read (%d, %p, %d), errno %d", res, fd, ptr, len, + get_errno ()); + MALLOC_CHECK; + return (ssize_t) res; } EXPORT_ALIAS (read, _read) extern "C" ssize_t -pread (int fd, void *ptr, size_t len, _off64_t off) +readv (int fd, const struct iovec *const iov, const int iovcnt) { pthread_testcancel (); - ssize_t res; + myfault efault; + if (efault.faulted (EFAULT)) + return -1; + + ssize_t res = -1; + const ssize_t tot = check_iovec_for_read (iov, iovcnt); + cygheap_fdget cfd (fd); if (cfd < 0) - res = -1; - else - res = cfd->pread (ptr, len, off); + goto done; - syscall_printf ("%d = pread (%d, %p, %d, %d), errno %d", - res, fd, ptr, len, off, get_errno ()); + if (tot <= 0) + { + res = tot; + goto done; + } + + if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY) + { + set_errno (EBADF); + goto done; + } + + /* Could block, so let user know we at least got here. */ + extern int sigcatchers; + syscall_printf ("readv (%d, %p, %d) %sblocking, sigcatchers %d", + fd, iov, iovcnt, cfd->is_nonblocking () ? "non" : "", + sigcatchers); + + res = cfd->readv (iov, iovcnt, tot); + +done: + syscall_printf ("%d = readv (%d, %p, %d), errno %d", res, fd, iov, iovcnt, + get_errno ()); + MALLOC_CHECK; return res; } extern "C" ssize_t -pwrite (int fd, void *ptr, size_t len, _off64_t off) +pread (int fd, void *ptr, size_t len, _off64_t off) { pthread_testcancel (); @@ -936,9 +986,9 @@ pwrite (int fd, void *ptr, size_t len, _off64_t off) if (cfd < 0) res = -1; else - res = cfd->pwrite (ptr, len, off); + res = cfd->pread (ptr, len, off); - syscall_printf ("%d = pwrite (%d, %p, %d, %d), errno %d", + syscall_printf ("%d = pread (%d, %p, %d, %d), errno %d", res, fd, ptr, len, off, get_errno ()); return res; } @@ -946,67 +996,46 @@ pwrite (int fd, void *ptr, size_t len, _off64_t off) extern "C" ssize_t write (int fd, const void *ptr, size_t len) { - const struct iovec iov = - { - iov_base: (void *) ptr, // const_cast - iov_len: len - }; - - return writev (fd, &iov, 1); -} - -EXPORT_ALIAS (write, _write) - -extern "C" ssize_t -readv (int fd, const struct iovec *const iov, const int iovcnt) -{ pthread_testcancel (); myfault efault; if (efault.faulted (EFAULT)) return -1; - ssize_t res = -1; - const int e = get_errno (); - const ssize_t tot = check_iovec_for_read (iov, iovcnt); + int res = -1; cygheap_fdget cfd (fd); if (cfd < 0) goto done; - if (tot <= 0) - { - res = tot; - goto done; - } - - if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY) + if ((cfd->get_flags () & O_ACCMODE) == O_RDONLY) { set_errno (EBADF); goto done; } /* Could block, so let user know we at least got here. */ - extern int sigcatchers; - syscall_printf ("readv (%d, %p, %d) %sblocking, sigcatchers %d", - fd, iov, iovcnt, cfd->is_nonblocking () ? "non" : "", - sigcatchers); + if (fd == 1 || fd == 2) + paranoid_printf ("write (%d, %p, %d)", fd, ptr, len); + else + syscall_printf ("write (%d, %p, %d)", fd, ptr, len); - while (1) - { - res = cfd->readv (iov, iovcnt, tot); - if (res >= 0 || get_errno () != EINTR || !_my_tls.call_signal_handler ()) - break; - set_errno (e); - } + res = cfd->write (ptr, len); done: - syscall_printf ("%d = readv (%d, %p, %d), errno %d", res, fd, iov, iovcnt, - get_errno ()); + if (fd == 1 || fd == 2) + paranoid_printf ("%d = write (%d, %p, %d), errno %d", + res, fd, ptr, len, get_errno ()); + else + syscall_printf ("%d = write (%d, %p, %d), errno %d", + res, fd, ptr, len, get_errno ()); + MALLOC_CHECK; return res; } +EXPORT_ALIAS (write, _write) + extern "C" ssize_t writev (const int fd, const struct iovec *const iov, const int iovcnt) { @@ -1045,16 +1074,33 @@ writev (const int fd, const struct iovec *const iov, const int iovcnt) done: if (fd == 1 || fd == 2) - paranoid_printf ("%d = write (%d, %p, %d), errno %d", + paranoid_printf ("%d = writev (%d, %p, %d), errno %d", res, fd, iov, iovcnt, get_errno ()); else - syscall_printf ("%d = write (%d, %p, %d), errno %d", + syscall_printf ("%d = writev (%d, %p, %d), errno %d", res, fd, iov, iovcnt, get_errno ()); MALLOC_CHECK; return res; } +extern "C" ssize_t +pwrite (int fd, void *ptr, size_t len, _off64_t off) +{ + pthread_testcancel (); + + ssize_t res; + cygheap_fdget cfd (fd); + if (cfd < 0) + res = -1; + else + res = cfd->pwrite (ptr, len, off); + + syscall_printf ("%d = pwrite (%d, %p, %d, %d), errno %d", + res, fd, ptr, len, off, get_errno ()); + return res; +} + /* _open */ /* newlib's fcntl.h defines _open as taking variable args so we must correspond. The third arg if it exists is: mode_t mode. */ |