summaryrefslogtreecommitdiff
path: root/usr.bin/cvs
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@cvs.openbsd.org>2007-09-17 10:07:22 +0000
committerTobias Stoeckmann <tobias@cvs.openbsd.org>2007-09-17 10:07:22 +0000
commitee89fbc00a9f91fdcac93f7160e2cc914f366667 (patch)
tree442f0130a0647a118f5c7eeb663782998fff3969 /usr.bin/cvs
parent891e3cba41e94abdf1f7f1f46df1b9a9c4e77f1c (diff)
Imported atomicio interface.
Requested by ray@, OK joris@
Diffstat (limited to 'usr.bin/cvs')
-rw-r--r--usr.bin/cvs/Makefile14
-rw-r--r--usr.bin/cvs/atomicio.c69
-rw-r--r--usr.bin/cvs/atomicio.h39
-rw-r--r--usr.bin/cvs/buf.c40
-rw-r--r--usr.bin/cvs/diff3.c8
-rw-r--r--usr.bin/cvs/file.c24
-rw-r--r--usr.bin/cvs/rcs.c7
-rw-r--r--usr.bin/cvs/remote.c33
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;
}