diff options
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r-- | contrib/cvs/src/rcscmds.c | 118 |
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 } |