- djm@cvs.openbsd.org 2006/04/16 00:52:55
[atomicio.c atomicio.h] introduce atomiciov() function that wraps readv/writev to retry interrupted transfers like atomicio() does for read/write; feedback deraadt@ dtucker@ stevesk@ ok deraadt@
This commit is contained in:
parent
499a0d5ada
commit
6aa139c41f
|
@ -26,6 +26,11 @@
|
|||
channels code can use to propsectivly check whether an incremental
|
||||
allocation will succeed. bz #1131, debugged with the assistance of
|
||||
cove AT wildpackets.com; ok dtucker@ deraadt@
|
||||
- djm@cvs.openbsd.org 2006/04/16 00:52:55
|
||||
[atomicio.c atomicio.h]
|
||||
introduce atomiciov() function that wraps readv/writev to retry
|
||||
interrupted transfers like atomicio() does for read/write;
|
||||
feedback deraadt@ dtucker@ stevesk@ ok deraadt@
|
||||
|
||||
20060421
|
||||
- (djm) [Makefile.in configure.ac session.c sshpty.c]
|
||||
|
@ -4537,4 +4542,4 @@
|
|||
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
|
||||
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
|
||||
|
||||
$Id: ChangeLog,v 1.4307 2006/04/23 02:06:03 djm Exp $
|
||||
$Id: ChangeLog,v 1.4308 2006/04/23 02:06:20 djm Exp $
|
||||
|
|
55
atomicio.c
55
atomicio.c
|
@ -1,5 +1,6 @@
|
|||
/* $OpenBSD: atomicio.c,v 1.17 2006/04/01 05:51:34 djm Exp $ */
|
||||
/* $OpenBSD: atomicio.c,v 1.18 2006/04/16 00:52:55 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* All rights reserved.
|
||||
|
@ -59,3 +60,55 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
|||
}
|
||||
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 > iov[0].iov_len || (rem > 0 && iovcnt <= 0)) {
|
||||
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;
|
||||
}
|
||||
|
|
18
atomicio.h
18
atomicio.h
|
@ -1,6 +1,7 @@
|
|||
/* $OpenBSD: atomicio.h,v 1.7 2006/03/25 22:22:42 djm Exp $ */
|
||||
/* $OpenBSD: atomicio.h,v 1.8 2006/04/16 00:52:55 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -25,9 +26,24 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _ATOMICIO_H
|
||||
#define _ATOMICIO_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
/*
|
||||
* Ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
|
||||
#define vwrite (ssize_t (*)(int, void *, size_t))write
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t atomiciov(ssize_t (*)(int, const struct iovec *, int),
|
||||
int, const struct iovec *, int);
|
||||
|
||||
#endif /* _ATOMICIO_H */
|
||||
|
|
Loading…
Reference in New Issue