1 /* $NetBSD: write_buf.c,v 1.1.1.1 2009/06/23 10:09:01 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* write_buf 3 6 /* SUMMARY 7 /* write buffer or bust 8 /* SYNOPSIS 9 /* #include <iostuff.h> 10 /* 11 /* ssize_t write_buf(fd, buf, len, timeout) 12 /* int fd; 13 /* const char *buf; 14 /* ssize_t len; 15 /* int timeout; 16 /* DESCRIPTION 17 /* write_buf() writes a buffer to the named stream in as many 18 /* fragments as needed, and returns the number of bytes written, 19 /* which is always the number requested or an error indication. 20 /* 21 /* Arguments: 22 /* .IP fd 23 /* File descriptor in the range 0..FD_SETSIZE. 24 /* .IP buf 25 /* Address of data to be written. 26 /* .IP len 27 /* Amount of data to be written. 28 /* .IP timeout 29 /* Bounds the time in seconds to wait until \fIfd\fD becomes writable. 30 /* A value <= 0 means do not wait; this is useful only when \fIfd\fR 31 /* uses blocking I/O. 32 /* DIAGNOSTICS 33 /* write_buf() returns -1 in case of trouble. The global \fIerrno\fR 34 /* variable reflects the nature of the problem. 35 /* LICENSE 36 /* .ad 37 /* .fi 38 /* The Secure Mailer license must be distributed with this software. 39 /* AUTHOR(S) 40 /* Wietse Venema 41 /* IBM T.J. Watson Research 42 /* P.O. Box 704 43 /* Yorktown Heights, NY 10598, USA 44 /*--*/ 45 46 /* System library. */ 47 48 #include <sys_defs.h> 49 #include <unistd.h> 50 #include <errno.h> 51 #include <time.h> 52 53 /* Utility library. */ 54 55 #include <msg.h> 56 #include <iostuff.h> 57 58 /* write_buf - write buffer or bust */ 59 60 ssize_t write_buf(int fd, const char *buf, ssize_t len, int timeout) 61 { 62 const char *start = buf; 63 ssize_t count; 64 time_t expire; 65 int time_left = timeout; 66 67 if (time_left > 0) 68 expire = time((time_t *) 0) + time_left; 69 70 while (len > 0) { 71 if (time_left > 0 && write_wait(fd, time_left) < 0) 72 return (-1); 73 if ((count = write(fd, buf, len)) < 0) { 74 if ((errno == EAGAIN && time_left > 0) || errno == EINTR) 75 /* void */ ; 76 else 77 return (-1); 78 } else { 79 buf += count; 80 len -= count; 81 } 82 if (len > 0 && time_left > 0) { 83 time_left = expire - time((time_t *) 0); 84 if (time_left <= 0) { 85 errno = ETIMEDOUT; 86 return (-1); 87 } 88 } 89 } 90 return (buf - start); 91 } 92