aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/w32.c66
2 files changed, 47 insertions, 24 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 311e10765ec..0b3aa8e22ec 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
12014-09-10 Eli Zaretskii <eliz@gnu.org>
2
3 * w32.c (sys_write): Use SAFE_NALLOCA for the NL -> CRLF
4 translation buffer.
5
12014-09-10 Paul Eggert <eggert@cs.ucla.edu> 62014-09-10 Paul Eggert <eggert@cs.ucla.edu>
2 7
3 * xterm.c (handle_one_xevent): Add braces to pacify gcc -Wall. 8 * xterm.c (handle_one_xevent): Add braces to pacify gcc -Wall.
diff --git a/src/w32.c b/src/w32.c
index 25549d79d7f..cc0d0af3445 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -8241,6 +8241,7 @@ int
8241sys_write (int fd, const void * buffer, unsigned int count) 8241sys_write (int fd, const void * buffer, unsigned int count)
8242{ 8242{
8243 int nchars; 8243 int nchars;
8244 USE_SAFE_ALLOCA;
8244 8245
8245 if (fd < 0) 8246 if (fd < 0)
8246 { 8247 {
@@ -8259,30 +8260,33 @@ sys_write (int fd, const void * buffer, unsigned int count)
8259 /* Perform text mode translation if required. */ 8260 /* Perform text mode translation if required. */
8260 if ((fd_info[fd].flags & FILE_BINARY) == 0) 8261 if ((fd_info[fd].flags & FILE_BINARY) == 0)
8261 { 8262 {
8262 char * tmpbuf = alloca (count * 2); 8263 char * tmpbuf;
8263 unsigned char * src = (void *)buffer; 8264 const unsigned char * src = buffer;
8264 unsigned char * dst = tmpbuf; 8265 unsigned char * dst;
8265 int nbytes = count; 8266 int nbytes = count;
8266 8267
8268 SAFE_NALLOCA (tmpbuf, 2, count);
8269 dst = tmpbuf;
8270
8267 while (1) 8271 while (1)
8268 { 8272 {
8269 unsigned char *next; 8273 unsigned char *next;
8270 /* copy next line or remaining bytes */ 8274 /* Copy next line or remaining bytes. */
8271 next = _memccpy (dst, src, '\n', nbytes); 8275 next = _memccpy (dst, src, '\n', nbytes);
8272 if (next) 8276 if (next)
8273 { 8277 {
8274 /* copied one line ending with '\n' */ 8278 /* Copied one line ending with '\n'. */
8275 int copied = next - dst; 8279 int copied = next - dst;
8276 nbytes -= copied; 8280 nbytes -= copied;
8277 src += copied; 8281 src += copied;
8278 /* insert '\r' before '\n' */ 8282 /* Insert '\r' before '\n'. */
8279 next[-1] = '\r'; 8283 next[-1] = '\r';
8280 next[0] = '\n'; 8284 next[0] = '\n';
8281 dst = next + 1; 8285 dst = next + 1;
8282 count++; 8286 count++;
8283 } 8287 }
8284 else 8288 else
8285 /* copied remaining partial line -> now finished */ 8289 /* Copied remaining partial line -> now finished. */
8286 break; 8290 break;
8287 } 8291 }
8288 buffer = tmpbuf; 8292 buffer = tmpbuf;
@@ -8296,31 +8300,44 @@ sys_write (int fd, const void * buffer, unsigned int count)
8296 HANDLE wait_hnd[2] = { interrupt_handle, ovl->hEvent }; 8300 HANDLE wait_hnd[2] = { interrupt_handle, ovl->hEvent };
8297 DWORD active = 0; 8301 DWORD active = 0;
8298 8302
8303 /* This is async (a.k.a. "overlapped") I/O, so the return value
8304 of FALSE from WriteFile means either an error or the output
8305 will be completed asynchronously (ERROR_IO_PENDING). */
8299 if (!WriteFile (hnd, buffer, count, (DWORD*) &nchars, ovl)) 8306 if (!WriteFile (hnd, buffer, count, (DWORD*) &nchars, ovl))
8300 { 8307 {
8301 if (GetLastError () != ERROR_IO_PENDING) 8308 if (GetLastError () != ERROR_IO_PENDING)
8302 { 8309 {
8303 errno = EIO; 8310 errno = EIO;
8304 return -1; 8311 nchars = -1;
8305 } 8312 }
8306 if (detect_input_pending ())
8307 active = MsgWaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE,
8308 QS_ALLINPUT);
8309 else 8313 else
8310 active = WaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE);
8311 if (active == WAIT_OBJECT_0)
8312 { /* User pressed C-g, cancel write, then leave. Don't bother
8313 cleaning up as we may only get stuck in buggy drivers. */
8314 PurgeComm (hnd, PURGE_TXABORT | PURGE_TXCLEAR);
8315 CancelIo (hnd);
8316 errno = EIO;
8317 return -1;
8318 }
8319 if (active == WAIT_OBJECT_0 + 1
8320 && !GetOverlappedResult (hnd, ovl, (DWORD*) &nchars, TRUE))
8321 { 8314 {
8322 errno = EIO; 8315 /* Wait for the write to complete, and watch C-g while
8323 return -1; 8316 at that. */
8317 if (detect_input_pending ())
8318 active = MsgWaitForMultipleObjects (2, wait_hnd, FALSE,
8319 INFINITE, QS_ALLINPUT);
8320 else
8321 active = WaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE);
8322 switch (active)
8323 {
8324 case WAIT_OBJECT_0:
8325 /* User pressed C-g, cancel write, then leave.
8326 Don't bother cleaning up as we may only get stuck
8327 in buggy drivers. */
8328 PurgeComm (hnd, PURGE_TXABORT | PURGE_TXCLEAR);
8329 CancelIo (hnd);
8330 errno = EIO; /* Why not EINTR? */
8331 nchars = -1;
8332 break;
8333 case WAIT_OBJECT_0 + 1:
8334 if (!GetOverlappedResult (hnd, ovl, (DWORD*) &nchars, TRUE))
8335 {
8336 errno = EIO;
8337 nchars = -1;
8338 }
8339 break;
8340 }
8324 } 8341 }
8325 } 8342 }
8326 } 8343 }
@@ -8381,6 +8398,7 @@ sys_write (int fd, const void * buffer, unsigned int count)
8381 } 8398 }
8382 } 8399 }
8383 8400
8401 SAFE_FREE ();
8384 return nchars; 8402 return nchars;
8385} 8403}
8386 8404