emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r117857: src/w32.c (sys_write): Use SAFE_NALLOCA for


From: Eli Zaretskii
Subject: [Emacs-diffs] trunk r117857: src/w32.c (sys_write): Use SAFE_NALLOCA for the NL -> CRLF translation buffer.
Date: Wed, 10 Sep 2014 17:52:10 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 117857
revision-id: address@hidden
parent: address@hidden
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Wed 2014-09-10 20:51:53 +0300
message:
  src/w32.c (sys_write): Use SAFE_NALLOCA for the NL -> CRLF translation buffer.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/w32.c                      w32.c-20091113204419-o5vbwnq5f7feedwu-808
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2014-09-10 17:18:38 +0000
+++ b/src/ChangeLog     2014-09-10 17:51:53 +0000
@@ -1,3 +1,8 @@
+2014-09-10  Eli Zaretskii  <address@hidden>
+
+       * w32.c (sys_write): Use SAFE_NALLOCA for the NL -> CRLF
+       translation buffer.
+
 2014-09-10  Paul Eggert  <address@hidden>
 
        * xterm.c (handle_one_xevent): Add braces to pacify gcc -Wall.

=== modified file 'src/w32.c'
--- a/src/w32.c 2014-08-25 15:55:46 +0000
+++ b/src/w32.c 2014-09-10 17:51:53 +0000
@@ -8241,6 +8241,7 @@
 sys_write (int fd, const void * buffer, unsigned int count)
 {
   int nchars;
+  USE_SAFE_ALLOCA;
 
   if (fd < 0)
     {
@@ -8259,30 +8260,33 @@
       /* Perform text mode translation if required.  */
       if ((fd_info[fd].flags & FILE_BINARY) == 0)
        {
-         char * tmpbuf = alloca (count * 2);
-         unsigned char * src = (void *)buffer;
-         unsigned char * dst = tmpbuf;
+         char * tmpbuf;
+         const unsigned char * src = buffer;
+         unsigned char * dst;
          int nbytes = count;
 
+         SAFE_NALLOCA (tmpbuf, 2, count);
+         dst = tmpbuf;
+
          while (1)
            {
              unsigned char *next;
-             /* copy next line or remaining bytes */
+             /* Copy next line or remaining bytes.  */
              next = _memccpy (dst, src, '\n', nbytes);
              if (next)
                {
-                 /* copied one line ending with '\n' */
+                 /* Copied one line ending with '\n'.  */
                  int copied = next - dst;
                  nbytes -= copied;
                  src += copied;
-                 /* insert '\r' before '\n' */
+                 /* Insert '\r' before '\n'.  */
                  next[-1] = '\r';
                  next[0] = '\n';
                  dst = next + 1;
                  count++;
                }
              else
-               /* copied remaining partial line -> now finished */
+               /* Copied remaining partial line -> now finished.  */
                break;
            }
          buffer = tmpbuf;
@@ -8296,31 +8300,44 @@
       HANDLE wait_hnd[2] = { interrupt_handle, ovl->hEvent };
       DWORD active = 0;
 
+      /* This is async (a.k.a. "overlapped") I/O, so the return value
+        of FALSE from WriteFile means either an error or the output
+        will be completed asynchronously (ERROR_IO_PENDING).  */
       if (!WriteFile (hnd, buffer, count, (DWORD*) &nchars, ovl))
        {
          if (GetLastError () != ERROR_IO_PENDING)
            {
              errno = EIO;
-             return -1;
+             nchars = -1;
            }
-         if (detect_input_pending ())
-           active = MsgWaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE,
-                                               QS_ALLINPUT);
          else
-           active = WaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE);
-         if (active == WAIT_OBJECT_0)
-           { /* User pressed C-g, cancel write, then leave.  Don't bother
-                cleaning up as we may only get stuck in buggy drivers.  */
-             PurgeComm (hnd, PURGE_TXABORT | PURGE_TXCLEAR);
-             CancelIo (hnd);
-             errno = EIO;
-             return -1;
-           }
-         if (active == WAIT_OBJECT_0 + 1
-             && !GetOverlappedResult (hnd, ovl, (DWORD*) &nchars, TRUE))
            {
-             errno = EIO;
-             return -1;
+             /* Wait for the write to complete, and watch C-g while
+                at that.  */
+             if (detect_input_pending ())
+               active = MsgWaitForMultipleObjects (2, wait_hnd, FALSE,
+                                                   INFINITE, QS_ALLINPUT);
+             else
+               active = WaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE);
+             switch (active)
+               {
+               case WAIT_OBJECT_0:
+                 /* User pressed C-g, cancel write, then leave.
+                    Don't bother cleaning up as we may only get stuck
+                    in buggy drivers.  */
+                 PurgeComm (hnd, PURGE_TXABORT | PURGE_TXCLEAR);
+                 CancelIo (hnd);
+                 errno = EIO;  /* Why not EINTR? */
+                 nchars = -1;
+                 break;
+               case WAIT_OBJECT_0 + 1:
+                 if (!GetOverlappedResult (hnd, ovl, (DWORD*) &nchars, TRUE))
+                   {
+                     errno = EIO;
+                     nchars = -1;
+                   }
+                 break;
+               }
            }
        }
     }
@@ -8381,6 +8398,7 @@
        }
     }
 
+  SAFE_FREE ();
   return nchars;
 }
 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]