atomicio.c (181110) | atomicio.c (181111) |
---|---|
1/* $OpenBSD: atomicio.c,v 1.23 2006/08/03 03:34:41 deraadt Exp $ */ | 1/* $OpenBSD: atomicio.c,v 1.25 2007/06/25 12:02:27 dtucker Exp $ */ |
2/* 3 * Copyright (c) 2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. 5 * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 17 unchanged lines hidden (view full) --- 27 */ 28 29#include "includes.h" 30 31#include <sys/param.h> 32#include <sys/uio.h> 33 34#include <errno.h> | 2/* 3 * Copyright (c) 2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. 5 * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 17 unchanged lines hidden (view full) --- 27 */ 28 29#include "includes.h" 30 31#include <sys/param.h> 32#include <sys/uio.h> 33 34#include <errno.h> |
35#ifdef HAVE_POLL_H 36#include <poll.h> 37#else 38# ifdef HAVE_SYS_POLL_H 39# include <sys/poll.h> 40# endif 41#endif |
|
35#include <string.h> | 42#include <string.h> |
43#include <unistd.h> |
|
36 37#include "atomicio.h" 38 39/* 40 * ensure all of data on socket comes through. f==read || f==vwrite 41 */ 42size_t 43atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) 44{ 45 char *s = _s; 46 size_t pos = 0; 47 ssize_t res; | 44 45#include "atomicio.h" 46 47/* 48 * ensure all of data on socket comes through. f==read || f==vwrite 49 */ 50size_t 51atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) 52{ 53 char *s = _s; 54 size_t pos = 0; 55 ssize_t res; |
56 struct pollfd pfd; |
|
48 | 57 |
58 pfd.fd = fd; 59 pfd.events = f == read ? POLLIN : POLLOUT; |
|
49 while (n > pos) { 50 res = (f) (fd, s + pos, n - pos); 51 switch (res) { 52 case -1: | 60 while (n > pos) { 61 res = (f) (fd, s + pos, n - pos); 62 switch (res) { 63 case -1: |
53#ifdef EWOULDBLOCK 54 if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) 55#else 56 if (errno == EINTR || errno == EAGAIN) 57#endif | 64 if (errno == EINTR) |
58 continue; | 65 continue; |
66 if (errno == EAGAIN || errno == EWOULDBLOCK) { 67 (void)poll(&pfd, 1, -1); 68 continue; 69 } |
|
59 return 0; 60 case 0: 61 errno = EPIPE; 62 return pos; 63 default: 64 pos += (size_t)res; 65 } 66 } --- 5 unchanged lines hidden (view full) --- 72 */ 73size_t 74atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, 75 const struct iovec *_iov, int iovcnt) 76{ 77 size_t pos = 0, rem; 78 ssize_t res; 79 struct iovec iov_array[IOV_MAX], *iov = iov_array; | 70 return 0; 71 case 0: 72 errno = EPIPE; 73 return pos; 74 default: 75 pos += (size_t)res; 76 } 77 } --- 5 unchanged lines hidden (view full) --- 83 */ 84size_t 85atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, 86 const struct iovec *_iov, int iovcnt) 87{ 88 size_t pos = 0, rem; 89 ssize_t res; 90 struct iovec iov_array[IOV_MAX], *iov = iov_array; |
91 struct pollfd pfd; |
|
80 81 if (iovcnt > IOV_MAX) { 82 errno = EINVAL; 83 return 0; 84 } 85 /* Make a copy of the iov array because we may modify it below */ 86 memcpy(iov, _iov, iovcnt * sizeof(*_iov)); 87 | 92 93 if (iovcnt > IOV_MAX) { 94 errno = EINVAL; 95 return 0; 96 } 97 /* Make a copy of the iov array because we may modify it below */ 98 memcpy(iov, _iov, iovcnt * sizeof(*_iov)); 99 |
100#ifndef BROKEN_READV_COMPARISON 101 pfd.fd = fd; 102 pfd.events = f == readv ? POLLIN : POLLOUT; 103#endif |
|
88 for (; iovcnt > 0 && iov[0].iov_len > 0;) { 89 res = (f) (fd, iov, iovcnt); 90 switch (res) { 91 case -1: | 104 for (; iovcnt > 0 && iov[0].iov_len > 0;) { 105 res = (f) (fd, iov, iovcnt); 106 switch (res) { 107 case -1: |
92 if (errno == EINTR || errno == EAGAIN) | 108 if (errno == EINTR) |
93 continue; | 109 continue; |
110 if (errno == EAGAIN || errno == EWOULDBLOCK) { 111#ifndef BROKEN_READV_COMPARISON 112 (void)poll(&pfd, 1, -1); 113#endif 114 continue; 115 } |
|
94 return 0; 95 case 0: 96 errno = EPIPE; 97 return pos; 98 default: 99 rem = (size_t)res; 100 pos += rem; 101 /* skip completed iov entries */ --- 19 unchanged lines hidden --- | 116 return 0; 117 case 0: 118 errno = EPIPE; 119 return pos; 120 default: 121 rem = (size_t)res; 122 pos += rem; 123 /* skip completed iov entries */ --- 19 unchanged lines hidden --- |