X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=sympathy.git;a=blobdiff_plain;f=apps%2Fsympathy.c;h=23398535369ae2a45c89c41eb9c15fc0cac7e6e1;hp=b5bf326f1395e46d4e17502153690afa49a4393b;hb=0811309bdec5ebb179d6056005f94c585b8fc8fd;hpb=3e72a1f6fc28777c26e4fb109867bd2a3c7b89b0 diff --git a/apps/sympathy.c b/apps/sympathy.c index b5bf326..2339853 100644 --- a/apps/sympathy.c +++ b/apps/sympathy.c @@ -11,6 +11,9 @@ static char rcsid[] = /* * $Log$ + * Revision 1.24 2008/02/28 22:00:42 james + * *** empty log message *** + * * Revision 1.23 2008/02/28 16:57:51 james * *** empty log message *** * @@ -269,6 +272,9 @@ main (int argc, char *argv[]) extern int optind, opterr, optopt; CRT_Pos size = { VT102_COLS_80, VT102_ROWS_24 }; + int csnok_pipe[2] = { 0 }; + int csnok = 0; + int oflags[128]; char *oargs[128]; @@ -278,7 +284,7 @@ main (int argc, char *argv[]) Log *log = NULL; int history = 200; - + int pid; get_hostname (); @@ -386,43 +392,35 @@ main (int argc, char *argv[]) if (oflags['p'] && oflags['d']) fatal_moan ("-p incompatible with -d"); - /*implement server and client by opening the server socket to prevent */ - /*a race condition, and then forking and munging the cmd line options */ - /*in the parent and child so that the child is the server and the */ - /*parent becomes its client */ if (oflags['c'] && oflags['s'] && oflags['F']) fatal_moan ("-F is incompatible with -c -s"); - if (oflags['s'] && !oflags['k']) - { - char *path; - path = mome ("/.sympathy"); - mkdir (path, 0700); - free (path); - - oargs['k'] = mome ("/.sympathy/%s%d", hostname, getpid ()); - oflags['k']++; - } - - if (oflags['s']) - { - server_socket = socket_listen (oargs['k']); - if (!server_socket) - fatal_moan ("failed to create socket %s for listening", oargs['k']); - } + /*implement server and client: this process forks. The parent */ + /*becomes the client and the child forks again to become the */ + /*server. If there's no -k argument the client (parent) needs */ + /*to find out the pid of the server, we use a pipe */ if (oflags['s'] && oflags['c']) { - switch (fork ()) + if (!oflags['k']) + { + csnok++; + pipe (csnok_pipe); + } + + switch (pid = fork ()) { case 0: /*child becomes the server */ oflags['c'] = 0; oflags['H'] = 0; + + if (csnok) + close (csnok_pipe[0]); break; case -1: fatal_moan ("fork failed"); - default: + default: /*parent becomes client*/ oflags['s'] = 0; oflags['K'] = 0; oflags['d'] = 0; @@ -432,10 +430,26 @@ main (int argc, char *argv[]) oflags['L'] = 0; oflags['n'] = 0; oflags['w'] = 0; - if (server_socket) + + /*Collect the child*/ + waitpid (pid, NULL, 0); + + /*if there was no k argument we need to find the*/ + /*pid of the server process so that we can work out*/ + /*what the socket is called. The server tells us on*/ + /*a pipe*/ + + if (csnok) { - socket_free_parent (server_socket); - server_socket = NULL; + close (csnok_pipe[1]); + + if (read (csnok_pipe[0], &pid, sizeof (pid)) != sizeof (pid)) + fatal_moan ("Failed to receive pid of server process"); + + close (csnok_pipe[0]); + + oargs['k'] = mome ("/.sympathy/%s%d", hostname, pid); + oflags['k']++; } } } @@ -478,10 +492,41 @@ main (int argc, char *argv[]) if (oflags['s'] && !oflags['F']) { - daemon (1, 0); /*incase socket is relative path, unlink then will fail */ + /*nochdir incase socket is relative path, unlink then will fail */ + daemon (1, 0); + + /*Tell our parent's parent what our pid is */ + if (csnok) + { + pid = getpid (); + + write (csnok_pipe[1], &pid, sizeof (pid)); + close (csnok_pipe[1]); + } } + if (oflags['s'] ) + { + char *path; + path = mome ("/.sympathy"); + mkdir (path, 0700); + free (path); + + + if (!oflags['k']) { + pid = getpid (); + + oargs['k'] = mome ("/.sympathy/%s%d", hostname, pid); + oflags['k']++; + } + + server_socket = socket_listen (oargs['k']); + if (!server_socket) + fatal_moan ("failed to create socket %s for listening", oargs['k']); + + } + if (oflags['s'] || oflags['t']) {