[BACK]Return to atomicio.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/atomicio.c between version 1.14 and 1.14.2.1

version 1.14, 2006/02/11 19:31:18 version 1.14.2.1, 2006/09/30 04:06:50
Line 1 
Line 1 
   /* $OpenBSD$ */
 /*  /*
    * Copyright (c) 2006 Damien Miller. All rights reserved.
  * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.   * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
  * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.   * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
  * All rights reserved.   * All rights reserved.
Line 24 
Line 26 
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */   */
   
 #include "includes.h"  #include <sys/param.h>
 RCSID("$OpenBSD$");  #include <sys/uio.h>
   
   #include <errno.h>
   #include <string.h>
   
 #include "atomicio.h"  #include "atomicio.h"
   
 /*  /*
  * ensure all of data on socket comes through. f==read || f==vwrite   * ensure all of data on socket comes through. f==read || f==vwrite
  */   */
 size_t  size_t
 atomicio(f, fd, _s, n)  atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
         ssize_t (*f) (int, void *, size_t);  
         int fd;  
         void *_s;  
         size_t n;  
 {  {
         char *s = _s;          char *s = _s;
         size_t pos = 0;          size_t pos = 0;
Line 58 
Line 59 
                 }                  }
         }          }
         return (pos);          return (pos);
   }
   
   /*
    * ensure all of data on socket comes through. f==readv || f==writev
    */
   size_t
   atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
       const struct iovec *_iov, int iovcnt)
   {
           size_t pos = 0, rem;
           ssize_t res;
           struct iovec iov_array[IOV_MAX], *iov = iov_array;
   
           if (iovcnt > IOV_MAX) {
                   errno = EINVAL;
                   return 0;
           }
           /* Make a copy of the iov array because we may modify it below */
           memcpy(iov, _iov, iovcnt * sizeof(*_iov));
   
           for (; iovcnt > 0 && iov[0].iov_len > 0;) {
                   res = (f) (fd, iov, iovcnt);
                   switch (res) {
                   case -1:
                           if (errno == EINTR || errno == EAGAIN)
                                   continue;
                           return 0;
                   case 0:
                           errno = EPIPE;
                           return pos;
                   default:
                           rem = (size_t)res;
                           pos += rem;
                           /* skip completed iov entries */
                           while (iovcnt > 0 && rem >= iov[0].iov_len) {
                                   rem -= iov[0].iov_len;
                                   iov++;
                                   iovcnt--;
                           }
                           /* This shouldn't happen... */
                           if (rem > 0 && (iovcnt <= 0 || rem > iov[0].iov_len)) {
                                   errno = EFAULT;
                                   return 0;
                           }
                           if (iovcnt == 0)
                                   break;
                           /* update pointer in partially complete iov */
                           iov[0].iov_base = ((char *)iov[0].iov_base) + rem;
                           iov[0].iov_len -= rem;
                   }
           }
           return pos;
 }  }

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.14.2.1