[pserverd patch: 8 Jan 1999 update: Andy Piper's web page is now at http://www.xemacs.freeserve.co.uk/. According to http://www.parallax.co.uk/~andyp/, this patch also applies against CVS 1.9.28. Some of the issues, if this is to be merged into the main CVS: * Basic concept seems sound. I guess it might be worth taking a glance at Apache or whatever, to see whether there is anything different we should be doing with respect to running as a daemon. * Details (setsid is not on all systems, for example. Indentation, for another. I haven't examined the code in great detail). * Needs documentation (http://www.parallax.co.uk/~andyp/ has most of the raw information, but it would want to be in NEWS/cvs.texinfo format. Would be nice to figure out what the deal is with text mounts once and for all, though). * I don't know whether this really has much to do with merging this in, but it might be worthwhile to let cygwin evolve a little bit more. For example, if I understood http://www.parallax.co.uk/~andyp/ correctly, one should build this with cygwin version b19 but with b19.1 libraries. Note that the patch might also be useful even on platforms other than Windows. Andy Piper writes: BTW as an aside I have found the pserverd patch really useful for running in a debugger in client/server mode since if you start it with -t it runs everything in the foreground whilst listening on the correct socket. -kingdon, Jun 1998] Date: Mon, 26 Jan 1998 17:35:39 +0000 To: info-cvs@prep.ai.mit.edu From: Andy Piper Subject: cvs-1.9.22 for cygwin available I have updated my web page (http://www.parallax.co.uk/~andyp) with a prebuilt 1.9.22 version of cvs for cygwin under NT. This implements full pserver operation (server and client) under NT. The patches I applied are on my web page and given below. Apart from my pserverd stuff the required extra patches are now very minimal. andy *** options.h.in.orig Thu Jan 15 08:48:30 1998 --- options.h.in Thu Jan 15 08:50:16 1998 *************** *** 187,195 **** --- 187,198 ---- * start again. You may override the default hi/low watermarks here * too. */ + + #ifndef __CYGWIN32__ #define SERVER_FLOWCONTROL #define SERVER_HI_WATER (2 * 1024 * 1024) #define SERVER_LO_WATER (1 * 1024 * 1024) + #endif /* End of CVS configuration section */ *** server.c.orig Thu Jan 15 08:48:30 1998 --- server.c Thu Jan 15 08:48:44 1998 *************** *** 4430,4435 **** --- 4430,4436 ---- initgroups (pw->pw_name, pw->pw_gid); #endif /* HAVE_INITGROUPS */ + #ifndef __CYGWIN32__ #ifdef SETXID_SUPPORT /* honor the setgid bit iff set*/ if (getgid() != getegid()) *************** *** 4447,4452 **** --- 4448,4454 ---- /* We don't want our umask to change file modes. The modes should be set by the modes used in the repository, and by the umask of the client. */ + #endif umask (0); #if HAVE_PUTENV *** main.c.org Sat Dec 27 22:43:45 1997 --- main.c Thu Jan 15 08:48:29 1998 *************** *** 20,25 **** --- 20,30 ---- extern int gethostname (); #endif + #if defined(AUTH_SERVER_SUPPORT) && defined(SERVER_SUPPORT) + #include + #include + #endif + char *program_name; char *program_path; char *command_name; *************** *** 103,108 **** --- 108,114 ---- { "logout", NULL, NULL, logout }, #ifdef SERVER_SUPPORT { "pserver", NULL, NULL, server }, /* placeholder */ + { "pserverd", NULL, NULL, server }, /* placeholder */ #endif #endif /* AUTH_CLIENT_SUPPORT */ { "rdiff", "patch", "pa", patch }, *************** *** 362,367 **** --- 368,388 ---- #endif /* !DONT_USE_SIGNALS */ } + #if defined(AUTH_SERVER_SUPPORT) && defined(SERVER_SUPPORT) + void reap_child(signo) + int signo; + { + int status; + pid_t pid; + /* wait for our process to die and munge return status */ + #ifdef HAVE_WAIT3 + pid = wait3(&status, WNOHANG, (struct rusage *)0); + #else + pid = wait (&status); + #endif + } + #endif + int main (argc, argv) int argc; *************** *** 377,383 **** int free_CVSroot = 0; int free_Editor = 0; int free_Tmpdir = 0; ! int help = 0; /* Has the user asked for help? This lets us support the `cvs -H cmd' convention to give help for cmd. */ --- 398,417 ---- int free_CVSroot = 0; int free_Editor = 0; int free_Tmpdir = 0; ! #if defined(AUTH_SERVER_SUPPORT) && defined(SERVER_SUPPORT) ! int servsock, childsock; ! struct sockaddr_in server; ! int on = 1; ! #ifdef POSIX_SIGNALS ! struct sigaction act; ! #else ! #ifdef BSD_SIGNALS ! struct sigvec vec; ! #else ! RETSIGTYPE (*istat) (); ! #endif ! #endif ! #endif int help = 0; /* Has the user asked for help? This lets us support the `cvs -H cmd' convention to give help for cmd. */ *************** *** 684,689 **** --- 718,836 ---- /* Pretend we were invoked as a plain server. */ command_name = "server"; + } + + if (strcmp (command_name, "pserverd") == 0) + { + /* pserver daemon mode */ + /* first fork and exit so that the child takes control */ + if (!trace && fork()) + { + exit(0); + } + /* become a daemon */ + if (!trace && setsid() < 0) + { + error(1, errno, "pserverd: setsid failed"); + } + + /* create a socket to listen on */ + if ((servsock = socket(AF_INET, SOCK_STREAM, 0)) <0) + { + error(1, errno, "pserverd: socket() failed"); + } + setsockopt(servsock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, + sizeof(on)); + + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = htons(CVS_AUTH_PORT); + + if (bind(servsock, (struct sockaddr *)&server, sizeof(server)) < 0) + { + shutdown(servsock, 2); + close(servsock); + error(1, errno, "pserverd: bind failed"); + } + + if (listen(servsock, 5) < 0) + { + error(1, errno, "pserverd: listen failed"); + } + + for (;;) { + if ((childsock = + accept(servsock, (struct sockaddr *)0, (int*)0))<0) + if (errno==EINTR) + { + continue; + } + else + { + error(1, errno, "pserverd: accept() failed"); + } + + if (trace || !fork()) + { /* child */ + close(servsock); + if (dup2(childsock,STDIN_FILENO)<0) + { + error(1, errno, "pserverd: dup2(stdin) failed"); + } + if ( close(childsock)<0 ) + { + error(1, errno, "pserverd: close(childsock) failed"); + } + if (dup2(STDIN_FILENO,STDOUT_FILENO)<0) + { + error(1, errno, "pserverd: dup2(stdout) failed"); + } + if (dup2(STDIN_FILENO,STDERR_FILENO)<0) + { + error(1, errno, "pserverd: dup2(stderr) failed"); + } + #ifdef POSIX_SIGNALS + act.sa_handler = SIG_DFL; + (void) sigemptyset (&act.sa_mask); + act.sa_flags = 0; + (void) sigaction (SIGCHLD, &act, (struct sigaction*)0); + #else + #ifdef BSD_SIGNALS + memset ((char *) &vec, 0, sizeof (vec)); + vec.sv_handler = SIG_DFL; + (void) sigvec (SIGCHLD, &vec, (struct sigvec*)0); + #else + istat = signal (SIGCHLD, SIG_DFL); + #endif + #endif + break; + } + else + { + if (!trace) + { + #ifdef POSIX_SIGNALS + act.sa_handler = reap_child; + (void) sigemptyset (&act.sa_mask); + act.sa_flags = 0; + (void) sigaction (SIGCHLD, &act, (struct sigaction*)0); + #else + #ifdef BSD_SIGNALS + memset ((char *) &vec, 0, sizeof (vec)); + vec.sv_handler = reap_child; + (void) sigvec (SIGCHLD, &vec, (struct sigvec*)0); + #else + istat = signal (SIGCHLD, reap_child); + #endif + #endif + } + close(childsock); + } + } + + pserver_authenticate_connection (); + /* Pretend we were invoked as a plain server. */ + command_name = "server"; } #endif /* (AUTH_SERVER_SUPPORT || HAVE_GSSAPI) && SERVER_SUPPORT */ ___ ____ Dr Andy Piper / _ \___ ________ _/ / Solutions_ (require 'disclaimer) / ___/ _ `/ __/ _ `/ / / _ `/\ \ / andyp@parallax.co.uk /_/ \_,_/_/ \_,_/_/_/\_,_//_\_\ boot /vmemacs