diff --git a/src/estream.c b/src/estream.c --- a/src/estream.c +++ b/src/estream.c @@ -964,6 +964,9 @@ int fd; /* The file descriptor we are using for actual output. */ int no_close; /* If set we won't close the file descriptor. */ int nonblock; /* Non-blocking mode is enabled. */ +#ifdef HAVE_W32_SYSTEM + int no_syscall_clamp; /* Do not use the syscall clamp. */ +#endif } *estream_cookie_fd_t; @@ -971,7 +974,8 @@ * Create function for objects indentified by a libc file descriptor. */ static int -func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close) +func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close, + int no_syscall_clamp) { estream_cookie_fd_t fd_cookie; int err; @@ -991,6 +995,11 @@ fd_cookie->fd = fd; fd_cookie->no_close = no_close; fd_cookie->nonblock = !!(modeflags & O_NONBLOCK); +#ifdef HAVE_W32_SYSTEM + fd_cookie->no_syscall_clamp = no_syscall_clamp; +#else + (void)no_syscall_clamp; +#endif *cookie = fd_cookie; err = 0; } @@ -1021,12 +1030,18 @@ } else { +#ifdef HAVE_W32_SYSTEM + if (!file_cookie->no_syscall_clamp) +#endif _gpgrt_pre_syscall (); do { bytes_read = read (file_cookie->fd, buffer, size); } while (bytes_read == -1 && errno == EINTR); +#ifdef HAVE_W32_SYSTEM + if (!file_cookie->no_syscall_clamp) +#endif _gpgrt_post_syscall (); } @@ -1053,12 +1068,18 @@ } else if (buffer) { +#ifdef HAVE_W32_SYSTEM + if (!file_cookie->no_syscall_clamp) +#endif _gpgrt_pre_syscall (); do { bytes_written = write (file_cookie->fd, buffer, size); } while (bytes_written == -1 && errno == EINTR); +#ifdef HAVE_W32_SYSTEM + if (!file_cookie->no_syscall_clamp) +#endif _gpgrt_post_syscall (); } else @@ -1087,8 +1108,14 @@ } else { +#ifdef HAVE_W32_SYSTEM + if (!file_cookie->no_syscall_clamp) +#endif _gpgrt_pre_syscall (); offset_new = lseek (file_cookie->fd, *offset, whence); +#ifdef HAVE_W32_SYSTEM + if (!file_cookie->no_syscall_clamp) +#endif _gpgrt_post_syscall (); if (offset_new == -1) err = -1; @@ -2201,12 +2228,19 @@ stream_internal_new = NULL; #if HAVE_W32_SYSTEM - if ((xmode & X_POLLABLE) && kind != BACKEND_W32) - { - /* We require the W32 backend, because only that allows us to - * write directly using the native W32 API and to disable the - * system clamp. Note that func_w32_create has already been - * called with the flag to disable the system call clamp. */ + if ((xmode & X_POLLABLE) + && !(kind == BACKEND_W32 || kind == BACKEND_FD)) + { + /* + * W32 backend is supported, because it allows us to write + * directly using the native W32 API and to disable the system + * clamp. + * + * FD backend is also supported, disabling system clamp. + * + * Note that func_fd_create/func_w32_create has already been + * called with the flag to disable the system call clamp. + */ _set_errno (EINVAL); err = -1; goto out; @@ -3417,7 +3451,8 @@ goto out; } - err = func_fd_create (&cookie, filedes, modeflags, no_close); + err = func_fd_create (&cookie, filedes, modeflags, no_close, + !!(xmode & X_POLLABLE)); if (err) goto out; @@ -4759,7 +4794,7 @@ goto out; } - err = func_fd_create (&cookie, fd, modeflags, 0); + err = func_fd_create (&cookie, fd, modeflags, 0, 0); if (err) goto out;