diff options
author | Tobias Stoeckmann <tobias@cvs.openbsd.org> | 2007-09-17 10:07:22 +0000 |
---|---|---|
committer | Tobias Stoeckmann <tobias@cvs.openbsd.org> | 2007-09-17 10:07:22 +0000 |
commit | ee89fbc00a9f91fdcac93f7160e2cc914f366667 (patch) | |
tree | 442f0130a0647a118f5c7eeb663782998fff3969 /usr.bin/cvs | |
parent | 891e3cba41e94abdf1f7f1f46df1b9a9c4e77f1c (diff) |
Imported atomicio interface.
Requested by ray@, OK joris@
Diffstat (limited to 'usr.bin/cvs')
-rw-r--r-- | usr.bin/cvs/Makefile | 14 | ||||
-rw-r--r-- | usr.bin/cvs/atomicio.c | 69 | ||||
-rw-r--r-- | usr.bin/cvs/atomicio.h | 39 | ||||
-rw-r--r-- | usr.bin/cvs/buf.c | 40 | ||||
-rw-r--r-- | usr.bin/cvs/diff3.c | 8 | ||||
-rw-r--r-- | usr.bin/cvs/file.c | 24 | ||||
-rw-r--r-- | usr.bin/cvs/rcs.c | 7 | ||||
-rw-r--r-- | usr.bin/cvs/remote.c | 33 |
8 files changed, 159 insertions, 75 deletions
diff --git a/usr.bin/cvs/Makefile b/usr.bin/cvs/Makefile index 7603318376e..48c8989ac20 100644 --- a/usr.bin/cvs/Makefile +++ b/usr.bin/cvs/Makefile @@ -1,15 +1,15 @@ -# $OpenBSD: Makefile,v 1.40 2007/06/26 18:02:43 xsa Exp $ +# $OpenBSD: Makefile,v 1.41 2007/09/17 10:07:21 tobias Exp $ PROG= opencvs MAN= cvs.1 cvs.5 cvsintro.7 CPPFLAGS+=-I${.CURDIR} -SRCS= cvs.c add.c admin.c annotate.c commit.c config.c checkout.c client.c \ - buf.c cmd.c date.y diff.c diff3.c diff_internals.c edit.c entries.c \ - fatal.c file.c getlog.c history.c log.c logmsg.c import.c init.c \ - release.c remove.c repository.c rcs.c rcsnum.c remote.c root.c \ - server.c status.c tag.c worklist.c util.c update.c version.c \ - watch.c xmalloc.c +SRCS= cvs.c add.c admin.c annotate.c atomicio.c commit.c config.c \ + checkout.c client.c buf.c cmd.c date.y diff.c diff3.c \ + diff_internals.c edit.c entries.c fatal.c file.c getlog.c history.c \ + log.c logmsg.c import.c init.c release.c remove.c repository.c \ + rcs.c rcsnum.c remote.c root.c server.c status.c tag.c worklist.c \ + util.c update.c version.c watch.c xmalloc.c CFLAGS+=-Wall CFLAGS+=-Wstrict-prototypes -Wmissing-prototypes diff --git a/usr.bin/cvs/atomicio.c b/usr.bin/cvs/atomicio.c new file mode 100644 index 00000000000..d872cbf4711 --- /dev/null +++ b/usr.bin/cvs/atomicio.c @@ -0,0 +1,69 @@ +/* $OpenBSD: atomicio.c,v 1.1 2007/09/17 10:07:21 tobias 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. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> + +#include <errno.h> +#include <poll.h> +#include <unistd.h> + +#include "atomicio.h" + +/* + * ensure all of data on socket comes through. f==read || f==vwrite + */ +size_t +atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) +{ + char *s = _s; + size_t pos = 0; + ssize_t res; + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = f == read ? POLLIN : POLLOUT; + while (n > pos) { + res = (f) (fd, s + pos, n - pos); + switch (res) { + case -1: + if (errno == EINTR) + continue; + if (errno == EAGAIN) { + (void)poll(&pfd, 1, -1); + continue; + } + return 0; + case 0: + errno = EPIPE; + return pos; + default: + pos += (size_t)res; + } + } + return (pos); +} diff --git a/usr.bin/cvs/atomicio.h b/usr.bin/cvs/atomicio.h new file mode 100644 index 00000000000..e292c0b32c3 --- /dev/null +++ b/usr.bin/cvs/atomicio.h @@ -0,0 +1,39 @@ +/* $OpenBSD: atomicio.h,v 1.1 2007/09/17 10:07:21 tobias Exp $ */ + +/* + * Copyright (c) 2006 Damien Miller. All rights reserved. + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ATOMICIO_H +#define _ATOMICIO_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 + +#endif /* _ATOMICIO_H */ diff --git a/usr.bin/cvs/buf.c b/usr.bin/cvs/buf.c index 28134f5a1d2..35e21873c89 100644 --- a/usr.bin/cvs/buf.c +++ b/usr.bin/cvs/buf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buf.c,v 1.64 2007/08/29 21:15:06 joris Exp $ */ +/* $OpenBSD: buf.c,v 1.65 2007/09/17 10:07:21 tobias Exp $ */ /* * Copyright (c) 2003 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -31,6 +31,7 @@ #include <string.h> #include <unistd.h> +#include "atomicio.h" #include "cvs.h" #include "buf.h" @@ -93,9 +94,6 @@ cvs_buf_load(const char *path, u_int flags) BUF * cvs_buf_load_fd(int fd, u_int flags) { - ssize_t ret; - size_t len; - u_char *bp; struct stat st; BUF *buf; @@ -106,16 +104,9 @@ cvs_buf_load_fd(int fd, u_int flags) fatal("cvs_buf_load_fd: lseek: %s", strerror(errno)); buf = cvs_buf_alloc(st.st_size, flags); - for (bp = buf->cb_buf; ; bp += (size_t)ret) { - len = SIZE_LEFT(buf); - ret = read(fd, bp, len); - if (ret == -1) - fatal("cvs_buf_load_fd: read: %s", strerror(errno)); - else if (ret == 0) - break; - - buf->cb_len += (size_t)ret; - } + if (atomicio(read, fd, buf->cb_buf, buf->cb_size) != buf->cb_size) + fatal("cvs_buf_load_fd: read: %s", strerror(errno)); + buf->cb_len = buf->cb_size; return (buf); } @@ -275,25 +266,8 @@ cvs_buf_len(BUF *b) int cvs_buf_write_fd(BUF *b, int fd) { - u_char *bp; - size_t len; - ssize_t ret; - - len = b->cb_len; - bp = b->cb_buf; - - do { - ret = write(fd, bp, len); - if (ret == -1) { - if (errno == EINTR || errno == EAGAIN) - continue; - return (-1); - } - - len -= (size_t)ret; - bp += (size_t)ret; - } while (len > 0); - + if (atomicio(vwrite, fd, b->cb_buf, b->cb_len) != b->cb_len) + return (-1); return (0); } diff --git a/usr.bin/cvs/diff3.c b/usr.bin/cvs/diff3.c index 3f05e815907..9c811594429 100644 --- a/usr.bin/cvs/diff3.c +++ b/usr.bin/cvs/diff3.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff3.c,v 1.38 2007/09/10 14:29:53 tobias Exp $ */ +/* $OpenBSD: diff3.c,v 1.39 2007/09/17 10:07:21 tobias Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -72,7 +72,7 @@ static const char copyright[] = #ifndef lint static const char rcsid[] = - "$OpenBSD: diff3.c,v 1.38 2007/09/10 14:29:53 tobias Exp $"; + "$OpenBSD: diff3.c,v 1.39 2007/09/17 10:07:21 tobias Exp $"; #endif /* not lint */ #include <ctype.h> @@ -83,6 +83,7 @@ static const char rcsid[] = #include <string.h> #include <unistd.h> +#include "atomicio.h" #include "cvs.h" #include "diff.h" @@ -245,7 +246,8 @@ cvs_merge_file(struct cvs_file *cf, int verbose) if (lp->l_line == NULL) continue; - if (write(cf->fd, lp->l_line, lp->l_len) == -1) + if (atomicio(vwrite, cf->fd, lp->l_line, lp->l_len) != + lp->l_len) fatal("cvs_merge_file: %s", strerror(errno)); } diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c index 48e3c5f832c..57d88664fa7 100644 --- a/usr.bin/cvs/file.c +++ b/usr.bin/cvs/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.196 2007/09/09 20:24:06 tobias Exp $ */ +/* $OpenBSD: file.c,v 1.197 2007/09/17 10:07:21 tobias Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> @@ -36,6 +36,7 @@ #include <string.h> #include <unistd.h> +#include "atomicio.h" #include "cvs.h" #define CVS_IGN_STATIC 0x01 /* pattern is static, no need to glob */ @@ -935,9 +936,7 @@ cvs_file_copy(const char *from, const char *to) mtime = st.st_mtimespec.tv_sec; if (S_ISREG(st.st_mode)) { - size_t sz; - ssize_t nw; - char *p, *buf; + char *p; int saved_errno; if (st.st_size > (off_t)SIZE_MAX) { @@ -959,18 +958,11 @@ cvs_file_copy(const char *from, const char *to) madvise(p, st.st_size, MADV_SEQUENTIAL); - sz = st.st_size; - buf = p; - - while (sz > 0) { - if ((nw = write(dst, p, sz)) == -1) { - saved_errno = errno; - (void)unlink(to); - fatal("cvs_file_copy: `%s': %s", - from, strerror(saved_errno)); - } - buf += nw; - sz -= nw; + if (atomicio(vwrite, dst, p, st.st_size) != st.st_size) { + saved_errno = errno; + (void)unlink(to); + fatal("cvs_file_copy: `%s': %s", from, + strerror(saved_errno)); } (void)munmap(p, st.st_size); diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c index 0744daddcfc..d93ffbd8d98 100644 --- a/usr.bin/cvs/rcs.c +++ b/usr.bin/cvs/rcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.c,v 1.218 2007/09/13 13:10:57 tobias Exp $ */ +/* $OpenBSD: rcs.c,v 1.219 2007/09/17 10:07:21 tobias Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -34,6 +34,7 @@ #include <string.h> #include <unistd.h> +#include "atomicio.h" #include "cvs.h" #include "diff.h" #include "rcs.h" @@ -2914,11 +2915,11 @@ rcs_rev_write_fd(RCSFILE *rfp, RCSNUM *rev, int fd, int mode) if (cvs_server_active == 1 && (cvs_cmdop == CVS_OP_CHECKOUT || cvs_cmdop == CVS_OP_UPDATE) && print_stdout == 1) { - if (write(fd, "M ", 2) == -1) + if (atomicio(vwrite, fd, "M ", 2) != 2) fatal("rcs_rev_write_fd: %s", strerror(errno)); } - if (write(fd, lp->l_line, lp->l_len) == -1) + if (atomicio(vwrite, fd, lp->l_line, lp->l_len) != lp->l_len) fatal("rcs_rev_write_fd: %s", strerror(errno)); } diff --git a/usr.bin/cvs/remote.c b/usr.bin/cvs/remote.c index e90b62ab8d9..15534bc4ee7 100644 --- a/usr.bin/cvs/remote.c +++ b/usr.bin/cvs/remote.c @@ -1,4 +1,4 @@ -/* $OpenBSD: remote.c,v 1.16 2007/09/02 11:11:12 tobias Exp $ */ +/* $OpenBSD: remote.c,v 1.17 2007/09/17 10:07:21 tobias Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * @@ -23,6 +23,7 @@ #include <string.h> #include <unistd.h> +#include "atomicio.h" #include "cvs.h" #include "remote.h" @@ -56,6 +57,7 @@ void cvs_remote_output(const char *data) { FILE *out; + size_t len; char nl = '\n'; if (cvs_server_active) @@ -67,8 +69,10 @@ cvs_remote_output(const char *data) fputs("\n", out); if (cvs_server_active == 0 && cvs_client_inlog_fd != -1) { - (void)write(cvs_client_inlog_fd, data, strlen(data)); - (void)write(cvs_client_inlog_fd, &nl, 1); + len = strlen(data); + if (atomicio(vwrite, cvs_client_inlog_fd, data, len) != len || + atomicio(vwrite, cvs_client_inlog_fd, &nl, 1) != 1) + fatal("failed to write to log file"); } } @@ -108,8 +112,10 @@ cvs_remote_input(void) } if (cvs_server_active == 0 && cvs_client_outlog_fd != -1) { - (void)write(cvs_client_outlog_fd, data, strlen(data)); - (void)write(cvs_client_outlog_fd, &nl, 1); + len = strlen(data); + if (atomicio(vwrite, cvs_client_outlog_fd, data, len) != len || + atomicio(vwrite, cvs_client_outlog_fd, &nl, 1) != 1) + fatal("failed to write to log file"); } return (ldata); @@ -120,7 +126,7 @@ cvs_remote_receive_file(int fd, size_t len) { FILE *in; char data[MAXBSIZE]; - size_t nread, nwrite, nleft, toread; + size_t nread, nleft, toread; if (cvs_server_active) in = stdin; @@ -136,13 +142,13 @@ cvs_remote_receive_file(int fd, size_t len) if (nread == 0) fatal("error receiving file"); - nwrite = write(fd, data, nread); - if (nwrite != nread) + if (atomicio(vwrite, fd, data, nread) != nread) fatal("failed to write %zu bytes", nread); - if (cvs_server_active == 0 && - cvs_client_outlog_fd != -1) - (void)write(cvs_client_outlog_fd, data, nread); + if (cvs_server_active == 0 && cvs_client_outlog_fd != -1 && + atomicio(vwrite, cvs_client_outlog_fd, data, nread) + != nread) + fatal("failed to write to log file"); nleft -= nread; } @@ -184,8 +190,9 @@ cvs_remote_send_file(const char *path) if (rw != ret) fatal("failed to write %zu bytes", ret); - if (cvs_server_active == 0 && cvs_client_inlog_fd != -1) - (void)write(cvs_client_inlog_fd, data, ret); + if (cvs_server_active == 0 && cvs_client_inlog_fd != -1 && + atomicio(vwrite, cvs_client_inlog_fd, data, ret) != ret) + fatal("failed to write to log file"); total += ret; } |