summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-02-14 09:47:14 +0000
committerpeter <peter@FreeBSD.org>1998-02-14 09:47:14 +0000
commitd5c5dbdaffd5f02a852ff0d9ba304b27da72d452 (patch)
tree4550666d2440cec75ab018eb97075522fea27d33 /contrib/cvs/src
parenta0c428b21450c842d307a011a4d5b3bbd7661b86 (diff)
downloadFreeBSD-src-d5c5dbdaffd5f02a852ff0d9ba304b27da72d452.zip
FreeBSD-src-d5c5dbdaffd5f02a852ff0d9ba304b27da72d452.tar.gz
A hack to work around the sleep prior to calling the built-in diff. This
affects speed of doing 'cvs diff' (in all modes) and 'cvs update' over the network. 1: don't pause at all unless running in server protocol mode. 2: if running in server protocol mode, do a kludge that intercepts the stdout and stderr write functions and diverts them to cvs_output() and cvs_outerr(). Yes, this might be done with fwopen() etc, but that also requires copying "FILE" structs since you can't freopen stdout etc and specify functions at the same time. This HACK will go away once the cvs folks have done their changes to the library version of gnu diff to use the callbacks as mentioned in the comments.
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r--contrib/cvs/src/rcscmds.c118
1 files changed, 114 insertions, 4 deletions
diff --git a/contrib/cvs/src/rcscmds.c b/contrib/cvs/src/rcscmds.c
index f62b279..ea638b3 100644
--- a/contrib/cvs/src/rcscmds.c
+++ b/contrib/cvs/src/rcscmds.c
@@ -135,10 +135,29 @@ call_diff_add_arg (s)
/* diff_run is imported from libdiff.a. */
extern int diff_run PROTO ((int argc, char **argv, char *out));
+#if defined(__FreeBSD__) && defined(SERVER_SUPPORT)
+/* Some 4.4BSD Glue to hack stdout and stderr to call cvs_output */
+
+static
+int writehook(cookie, buf, len)
+ void *cookie; /* really [struct bufcookie *] */
+ const char *buf; /* characters to copy */
+ int len; /* length to copy */
+{
+ void (*fn)(const char *, size_t) =
+ (void (*)(const char *, size_t))cookie;
+
+ (*fn)(buf, len);
+
+ return 0;
+}
+#endif
+
static int
call_diff (out)
char *out;
{
+#if !defined(__FreeBSD__) || !defined(SERVER_SUPPORT)
/* Try to keep the out-of-order bugs at bay (protocol_pipe for cvs_output
with has "Index: foo" and such; stdout and/or stderr for diff's
output). I think the only reason that this used to not be such
@@ -148,13 +167,58 @@ call_diff (out)
The real fix, of course, will be to have the diff library do all
its output through callbacks (which CVS will supply as cvs_output
and cvs_outerr). */
- /* sleep (1); */
- usleep (10000);
+#if defined(SERVER_SUPPORT)
+ /* only do this on the server if it's in protocol mode */
+ if (error_use_protocol || server_active)
+ sleep (1);
+#endif
if (out == RUN_TTY)
return diff_run (call_diff_argc, call_diff_argv, NULL);
else
return diff_run (call_diff_argc, call_diff_argv, out);
+#else
+ /* avoid that sleep "by any means necessary".. */
+ void *save_out, *save_err;
+ void *cookie_out, *cookie_err;
+ int rv;
+
+ /* XXX: the cvs_out*() funcs call the buf routines which can call
+ cvs_outerr(), and also calls malloc which might printf something.
+ FreeBSD's malloc doesn't do this at the moment, so recursion should
+ be avoided. No guarantees for other BSD4.4-Lite* systems though. */
+ if (error_use_protocol || server_active) {
+ save_out = stdout->_write;
+ save_err = stderr->_write;
+ cookie_out = stdout->_cookie;
+ cookie_err = stderr->_cookie;
+
+ fflush(stdout);
+ fflush(stderr);
+
+ stdout->_write = writehook;
+ stderr->_write = writehook;
+ stdout->_cookie = cvs_output;
+ stderr->_cookie = cvs_outerr;
+ }
+
+ if (out == RUN_TTY)
+ rv = diff_run (call_diff_argc, call_diff_argv, NULL);
+ else
+ rv = diff_run (call_diff_argc, call_diff_argv, out);
+
+ if (error_use_protocol || server_active) {
+ fflush(stdout);
+ fflush(stderr);
+
+ stdout->_write = save_out;
+ stderr->_write = save_err;
+ stdout->_cookie = cookie_out;
+ stderr->_cookie = cookie_err;
+ }
+
+ return (rv);
+#endif
}
extern int diff3_run PROTO ((int argc, char **argv, char *out));
@@ -163,6 +227,7 @@ static int
call_diff3 (out)
char *out;
{
+#if !defined(__FreeBSD__) || !defined(SERVER_SUPPORT)
/* Try to keep the out-of-order bugs at bay (protocol_pipe for cvs_output
with has "Index: foo" and such; stdout and/or stderr for diff's
output). I think the only reason that this used to not be such
@@ -172,13 +237,58 @@ call_diff3 (out)
The real fix, of course, will be to have the diff library do all
its output through callbacks (which CVS will supply as cvs_output
and cvs_outerr). */
- /* sleep (1); */
- usleep (10000);
+#if defined(SERVER_SUPPORT)
+ /* only do this on the server if it's in protocol mode */
+ if (error_use_protocol || server_active)
+ sleep (1);
+#endif
if (out == RUN_TTY)
return diff3_run (call_diff_argc, call_diff_argv, NULL);
else
return diff3_run (call_diff_argc, call_diff_argv, out);
+#else
+ /* avoid that sleep "by any means necessary".. */
+ void *save_out, *save_err;
+ void *cookie_out, *cookie_err;
+ int rv;
+
+ /* XXX: the cvs_out*() funcs call the buf routines which can call
+ cvs_outerr(), and also calls malloc which might printf something.
+ FreeBSD's malloc doesn't do this at the moment, so recursion should
+ be avoided. No guarantees for other BSD4.4-Lite* systems though. */
+ if (error_use_protocol || server_active) {
+ save_out = stdout->_write;
+ save_err = stderr->_write;
+ cookie_out = stdout->_cookie;
+ cookie_err = stderr->_cookie;
+
+ fflush(stdout);
+ fflush(stderr);
+
+ stdout->_write = writehook;
+ stderr->_write = writehook;
+ stdout->_cookie = cvs_output;
+ stderr->_cookie = cvs_outerr;
+ }
+
+ if (out == RUN_TTY)
+ rv = diff3_run (call_diff_argc, call_diff_argv, NULL);
+ else
+ rv = diff3_run (call_diff_argc, call_diff_argv, out);
+
+ if (error_use_protocol || server_active) {
+ fflush(stdout);
+ fflush(stderr);
+
+ stdout->_write = save_out;
+ stderr->_write = save_err;
+ stdout->_cookie = cookie_out;
+ stderr->_cookie = cookie_err;
+ }
+
+ return (rv);
+#endif
}
OpenPOWER on IntegriCloud