summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2015-10-18 15:26:14 +0200
committerWerner Koch <wk@gnupg.org>2015-10-18 15:26:24 +0200
commit75172adc3b103bd7ef75575a0c0c9c3b63fa4023 (patch)
treefc2ffd5ff0f4f7ff163e31d529fcc6619edfd14a
parentc09997bc50f3fffaf76d60d2e571b1d85536571e (diff)
downloadlibgpg-error-75172adc3b103bd7ef75575a0c0c9c3b63fa4023.tar.gz
estream: Avoid calling write(fd,NULL,n).
* src/estream.c (es_func_fd_write): Take care of a flush requests. (es_func_w32_write): Ditto. (es_func_fp_write): Ditto. -- The write handlers may be called with (BUFFER,SIZE) of (NULL,0) to propagate flush events to user supplied functions (es_fopencookie). However we need to take care to also do this with the internal handler. Might be a reason for system faults due to write or fwrite with a NULL buffer; on Linux this seems to be harmless. Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--doc/errorref.txt1
-rw-r--r--src/estream.c52
2 files changed, 33 insertions, 20 deletions
diff --git a/doc/errorref.txt b/doc/errorref.txt
index 268454f..563ce9b 100644
--- a/doc/errorref.txt
+++ b/doc/errorref.txt
@@ -670,6 +670,7 @@ GPG_ERR_COMPR_FAILED Compression or decompression failed
GPG_ERR_WOULD_WRAP A counter would wrap
NTBTLS: - Too many messages exchanged
+ Other: - A counter would wrap.
GPG_ERR_FATAL_ALERT Fatal alert message received
diff --git a/src/estream.c b/src/estream.c
index 21694a3..1c3e772 100644
--- a/src/estream.c
+++ b/src/estream.c
@@ -955,7 +955,7 @@ es_func_fd_write (void *cookie, const void *buffer, size_t size)
_gpgrt_yield ();
bytes_written = size; /* Yeah: Success writing to the bit bucket. */
}
- else
+ else if (buffer)
{
if (pre_syscall_func)
pre_syscall_func ();
@@ -967,6 +967,8 @@ es_func_fd_write (void *cookie, const void *buffer, size_t size)
if (post_syscall_func)
post_syscall_func ();
}
+ else
+ bytes_written = size; /* Note that for a flush SIZE should be 0. */
return bytes_written;
}
@@ -1171,7 +1173,7 @@ es_func_w32_write (void *cookie, const void *buffer, size_t size)
_gpgrt_yield ();
bytes_written = size; /* Yeah: Success writing to the bit bucket. */
}
- else
+ else if (buffer)
{
if (pre_syscall_func)
pre_syscall_func ();
@@ -1191,6 +1193,8 @@ es_func_w32_write (void *cookie, const void *buffer, size_t size)
if (post_syscall_func)
post_syscall_func ();
}
+ else
+ bytes_written = size; /* Note that for a flush SIZE should be 0. */
return bytes_written;
}
@@ -1369,32 +1373,39 @@ es_func_fp_write (void *cookie, const void *buffer, size_t size)
{
if (pre_syscall_func)
pre_syscall_func ();
-#ifdef HAVE_W32_SYSTEM
- /* Using an fwrite to stdout connected to the console fails with
- the error "Not enough space" for an fwrite size of >= 52KB
- (tested on Windows XP SP2). To solve this we always chunk
- the writes up into smaller blocks. */
- bytes_written = 0;
- while (bytes_written < size)
+ if (buffer)
{
- size_t cnt = size - bytes_written;
-
- if (cnt > 32*1024)
- cnt = 32*1024;
- if (fwrite ((const char*)buffer + bytes_written,
- cnt, 1, file_cookie->fp) != 1)
- break; /* Write error. */
- bytes_written += cnt;
- }
+#ifdef HAVE_W32_SYSTEM
+ /* Using an fwrite to stdout connected to the console fails
+ with the error "Not enough space" for an fwrite size of
+ >= 52KB (tested on Windows XP SP2). To solve this we
+ always chunk the writes up into smaller blocks. */
+ bytes_written = 0;
+ while (bytes_written < size)
+ {
+ size_t cnt = size - bytes_written;
+
+ if (cnt > 32*1024)
+ cnt = 32*1024;
+ if (fwrite ((const char*)buffer + bytes_written,
+ cnt, 1, file_cookie->fp) != 1)
+ break; /* Write error. */
+ bytes_written += cnt;
+ }
#else
- bytes_written = fwrite (buffer, 1, size, file_cookie->fp);
+ bytes_written = fwrite (buffer, 1, size, file_cookie->fp);
#endif
+ }
+ else /* Only flush requested. */
+ bytes_written = size;
+
fflush (file_cookie->fp);
if (post_syscall_func)
post_syscall_func ();
}
else
bytes_written = size; /* Successfully written to the bit bucket. */
+
if (bytes_written != size)
return -1;
return bytes_written;
@@ -2515,7 +2526,8 @@ es_writen (estream_t _GPGRT__RESTRICT stream,
static int
-es_peek (estream_t _GPGRT__RESTRICT stream, unsigned char **_GPGRT__RESTRICT data,
+es_peek (estream_t _GPGRT__RESTRICT stream,
+ unsigned char **_GPGRT__RESTRICT data,
size_t *_GPGRT__RESTRICT data_len)
{
int err;