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:
authorCorinna Vinschen <corinna@vinschen.de>2011-05-06 14:56:37 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-05-06 14:56:37 +0400
commita4e5706eb2e207ee891bc1dec7488ac6d3a14d48 (patch)
tree334b8f95cf17a34b1182e41961fe38b847acecb3 /winsup/cygwin/syscalls.cc
parent92ddb74290655b6f9394801dac4242c93e03f9ed (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.cc154
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. */