From: andyp AT parallax DOT co DOT uk (Andy Piper) Subject: Comments on this socket code for cvs please? 3 Nov 1997 06:39:21 -0800 Message-ID: <3.0.1.32.19971103135605.00ac7100.cygnus.gnu-win32@mailhost> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" To: gnu-win32 AT cygnus DOT com Hi, I have generated the following patch for cvs which allows cvs to be started as a daemon listening on the cvs socket. However, the subprocess which is generated doesn't disappear when it exits (it goes to mode) and if I try fork() + execv() that doesn't work at all for some reason. If anyone who is more familiar with this sort of thing could comment I would be very grateful. andy *** main.c 1997/10/31 09:31:28 1.1 --- main.c 1997/10/31 12:11:14 *************** *** 20,25 **** --- 20,30 ---- extern int gethostname (); #endif + #ifdef SERVER_SUPPORT + #include + #include + #endif + char *program_name; char *program_path; char *command_name; *************** *** 107,112 **** --- 112,118 ---- { "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 }, *************** *** 380,386 **** 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. */ --- 386,397 ---- int free_CVSroot = 0; int free_Editor = 0; int free_Tmpdir = 0; ! #ifdef SERVER_SUPPORT ! int servsock, childsock; ! struct sockaddr_in server; ! int on = 1; ! char** saveargv=argv; ! #endif int help = 0; /* Has the user asked for help? This lets us support the `cvs -H cmd' convention to give help for cmd. */ *************** *** 682,687 **** --- 693,774 ---- /* 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 (;;) { + childsock = + accept(servsock, (struct sockaddr *)0, (int*)0); + + if (trace || !fork()) + { /* child */ + close(servsock); + if (dup2(childsock,STDIN_FILENO)<0 + || + close(childsock)<0 + || + dup2(STDIN_FILENO,STDOUT_FILENO)<0) + /* || */ + /* dup2(STDIN_FILENO,STDERR_FILENO)<0) */ + { + error(1, errno, "pserverd: dup2() failed"); + } + /* argv[0]="pserver"; */ + /* fprintf(stderr,"execing"); */ + /* fprintf(stderr,"%s %s %s %d\n", saveargv[0], saveargv[1], */ + /* saveargv[2], (int)saveargv[3]); */ + + /* if (execv(saveargv[0],++saveargv) <0) */ + /* { */ + /* error(1, errno, "pserverd: execv() failed"); */ + /* } */ + break; + } + else + { + close(childsock); + } + } + + pserver_authenticate_connection (); + /* Pretend we were invoked as a plain server. */ + command_name = "server"; } #endif /* AUTH_SERVER_SUPPORT && SERVER_SUPPORT */ ___ ____ Dr Andy Piper / _ \___ ________ _/ / Solutions_ (require 'disclaimer) / ___/ _ `/ __/ _ `/ / / _ `/\ \ / andyp AT parallax DOT co DOT uk /_/ \_,_/_/ \_,_/_/_/\_,_//_\_\ boot /vmemacs - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".