summaryrefslogtreecommitdiff
path: root/atomicio.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-09-24 22:15:11 +1000
committerDamien Miller <djm@mindrot.org>2010-09-24 22:15:11 +1000
commit65e42f87fe945a2bf30d7e02358554dbaefa8a4c (patch)
tree102c10a0b5328a40c79dca19d208f0ca0c1671b5 /atomicio.c
parent7fe2b1fec3b364faf952828f3875b8e7eed8feb4 (diff)
- djm@cvs.openbsd.org 2010/09/22 22:58:51
[atomicio.c atomicio.h misc.c misc.h scp.c sftp-client.c] [sftp-client.h sftp.1 sftp.c] add an option per-read/write callback to atomicio factor out bandwidth limiting code from scp(1) into a generic bandwidth limiter that can be attached using the atomicio callback mechanism add a bandwidth limit option to sftp(1) using the above "very nice" markus@
Diffstat (limited to 'atomicio.c')
-rw-r--r--atomicio.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/atomicio.c b/atomicio.c
index a6b2d127a..601b3c371 100644
--- a/atomicio.c
+++ b/atomicio.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: atomicio.c,v 1.25 2007/06/25 12:02:27 dtucker Exp $ */ 1/* $OpenBSD: atomicio.c,v 1.26 2010/09/22 22:58:51 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2006 Damien Miller. All rights reserved. 3 * Copyright (c) 2006 Damien Miller. All rights reserved.
4 * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. 4 * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
@@ -48,7 +48,8 @@
48 * ensure all of data on socket comes through. f==read || f==vwrite 48 * ensure all of data on socket comes through. f==read || f==vwrite
49 */ 49 */
50size_t 50size_t
51atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) 51atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
52 int (*cb)(void *, size_t), void *cb_arg)
52{ 53{
53 char *s = _s; 54 char *s = _s;
54 size_t pos = 0; 55 size_t pos = 0;
@@ -73,17 +74,28 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
73 return pos; 74 return pos;
74 default: 75 default:
75 pos += (size_t)res; 76 pos += (size_t)res;
77 if (cb != NULL && cb(cb_arg, (size_t)res) == -1) {
78 errno = EINTR;
79 return pos;
80 }
76 } 81 }
77 } 82 }
78 return (pos); 83 return pos;
84}
85
86size_t
87atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
88{
89 return atomicio6(f, fd, _s, n, NULL, NULL);
79} 90}
80 91
81/* 92/*
82 * ensure all of data on socket comes through. f==readv || f==writev 93 * ensure all of data on socket comes through. f==readv || f==writev
83 */ 94 */
84size_t 95size_t
85atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, 96atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
86 const struct iovec *_iov, int iovcnt) 97 const struct iovec *_iov, int iovcnt,
98 int (*cb)(void *, size_t), void *cb_arg)
87{ 99{
88 size_t pos = 0, rem; 100 size_t pos = 0, rem;
89 ssize_t res; 101 ssize_t res;
@@ -137,6 +149,17 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
137 iov[0].iov_base = ((char *)iov[0].iov_base) + rem; 149 iov[0].iov_base = ((char *)iov[0].iov_base) + rem;
138 iov[0].iov_len -= rem; 150 iov[0].iov_len -= rem;
139 } 151 }
152 if (cb != NULL && cb(cb_arg, (size_t)res) == -1) {
153 errno = EINTR;
154 return pos;
155 }
140 } 156 }
141 return pos; 157 return pos;
142} 158}
159
160size_t
161atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
162 const struct iovec *_iov, int iovcnt)
163{
164 return atomiciov6(f, fd, _iov, iovcnt, NULL, NULL);
165}