Mail Archives: cygwin/1997/11/03/06:39:21
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 <defunct> 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 <sys/socket.h>
+ #include <netinet/in.h>
+ #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".
- Raw text -