Annotation of 43BSDReno/contrib/emacs-18.55/etc/server.c, revision 1.1.1.1

1.1       root        1: /* Communication subprocess for GNU Emacs acting as server.
                      2:    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU Emacs.
                      5: 
                      6: GNU Emacs is distributed in the hope that it will be useful,
                      7: but without any warranty.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.
                     11: 
                     12: Everyone is granted permission to copy, modify and redistribute
                     13: GNU Emacs, but only under the conditions described in the
                     14: document "GNU Emacs copying permission notice".   An exact copy
                     15: of the document is supposed to have been given to you along with
                     16: GNU Emacs so that you can know how you may redistribute it all.
                     17: It should be in a file named COPYING.  Among other things, the
                     18: copyright notice and this notice must be preserved on all copies.  */
                     19: 
                     20: 
                     21: /* The GNU Emacs edit server process is run as a subprocess of Emacs
                     22:    under control of the file lisp/server.el.
                     23:    This program accepts communication from client (program emacsclient.c)
                     24:    and passes their commands (consisting of keyboard characters)
                     25:    up to the Emacs which then executes them.  */
                     26: 
                     27: #define NO_SHORTNAMES
                     28: #include "../src/config.h"
                     29: #undef read
                     30: #undef write
                     31: #undef open
                     32: #undef close
                     33: 
                     34: 
                     35: #if !defined(BSD) && !defined(HAVE_SYSVIPC)
                     36: #include <stdio.h>
                     37: 
                     38: main ()
                     39: {
                     40:   fprintf (stderr, "Sorry, the Emacs server is supported only on Berkeley Unix\n");
                     41:   fprintf (stderr, "or System V systems with IPC\n");
                     42:   exit (1);
                     43: }
                     44: 
                     45: #else /* BSD or HAVE_SYSVIPC */
                     46: 
                     47: #if defined (BSD) && ! defined (HAVE_SYSVIPC)
                     48: /* BSD code is very different from SYSV IPC code */
                     49: 
                     50: #include <sys/file.h>
                     51: #include <sys/types.h>
                     52: #include <sys/socket.h>
                     53: #include <sys/signal.h>
                     54: #include <sys/un.h>
                     55: #include <stdio.h>
                     56: #include <errno.h>
                     57: 
                     58: extern int errno;
                     59: 
                     60: main ()
                     61: {
                     62:   int s, infd, fromlen;
                     63:   struct sockaddr_un server, fromunix;
                     64:   char *homedir;
                     65:   char *str, string[BUFSIZ], code[BUFSIZ];
                     66:   FILE *infile;
                     67:   FILE **openfiles;
                     68:   int openfiles_size;
                     69: 
                     70:   char *getenv ();
                     71: 
                     72:   openfiles_size = 20;
                     73:   openfiles = (FILE **) malloc (openfiles_size * sizeof (FILE *));
                     74:   if (openfiles == 0)
                     75:     abort ();
                     76: 
                     77:   /* 
                     78:    * Open up an AF_UNIX socket in this person's home directory
                     79:    */
                     80: 
                     81:   if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
                     82:     {
                     83:       perror ("socket");
                     84:       exit (1);
                     85:     }
                     86:   server.sun_family = AF_UNIX;
                     87:   if ((homedir = getenv ("HOME")) == NULL)
                     88:     {
                     89:       fprintf (stderr,"No home directory\n");
                     90:       exit (1);
                     91:     }
                     92:   strcpy (server.sun_path, homedir);
                     93:   strcat (server.sun_path, "/.emacs_server");
                     94:   if (bind (s, &server, strlen (server.sun_path) + 2) < 0)
                     95:     {
                     96:       perror ("bind");
                     97:       exit (1);
                     98:     }
                     99:   /*
                    100:    * Now, just wait for everything to come in..
                    101:    */
                    102:   if (listen (s, 5) < 0)
                    103:     {
                    104:       perror ("listen");
                    105:       exit (1);
                    106:     }
                    107: 
                    108:   /* Disable sigpipes in case luser kills client... */
                    109:   signal (SIGPIPE, SIG_IGN);
                    110:   for (;;)
                    111:     {
                    112:       int rmask = (1 << s) + 1;
                    113:       if (select (s + 1, &rmask, 0, 0, 0) < 0)
                    114:        perror ("select");
                    115:       if (rmask & (1 << s))    /* client sends list of filenames */
                    116:        {
                    117:          fromlen = sizeof (fromunix);
                    118:          fromunix.sun_family = AF_UNIX;
                    119:          infd = accept (s, &fromunix, &fromlen); /* open socket fd */
                    120:          if (infd < 0)
                    121:            {
                    122:              if (errno == EMFILE || errno == ENFILE)
                    123:                printf ("Too many clients.\n");
                    124:              else
                    125:                perror ("accept");
                    126:              continue;
                    127:            }
                    128: 
                    129:          if (infd >= openfiles_size)
                    130:            {
                    131:              openfiles_size *= 2;
                    132:              openfiles = (FILE **) realloc (openfiles,
                    133:                                             openfiles_size * sizeof (FILE *));
                    134:              if (openfiles == 0)
                    135:                abort ();
                    136:            }
                    137: 
                    138:          infile = fdopen (infd, "r+"); /* open stream */
                    139:          if (infile == NULL)
                    140:            {
                    141:              printf ("Too many clients.\n");
                    142:              write (infd, "Too many clients.\n", 18);
                    143:              close (infd);             /* Prevent descriptor leak.. */
                    144:              continue;
                    145:            }
                    146:          str = fgets (string, BUFSIZ, infile);
                    147:          if (str == NULL)
                    148:            {
                    149:              perror ("fgets");
                    150:              close (infd);             /* Prevent descriptor leak.. */
                    151:              continue;
                    152:            }
                    153:          openfiles[infd] = infile;
                    154:          printf ("Client: %d %s", infd, string);
                    155:          /* If what we read did not end in a newline,
                    156:             it means there is more.  Keep reading from the socket
                    157:             and outputting to Emacs, until we get the newline.  */
                    158:          while (string[strlen (string) - 1] != '\n')
                    159:            {
                    160:              if (fgets (string, BUFSIZ, infile) == 0)
                    161:                break;
                    162:              printf ("%s", string);
                    163:            }
                    164:          fflush (stdout);
                    165:          fflush (infile);
                    166:          continue;
                    167:        }
                    168:       else if (rmask & 1) /* emacs sends codeword, fd, and string message */
                    169:        {
                    170:          /* Read command codeword and fd */
                    171:          scanf ("%s %d%*c", code, &infd);
                    172: 
                    173:          /* Transfer text from Emacs to the client, up to a newline.  */
                    174:          infile = openfiles[infd];
                    175:          while (1)
                    176:            {
                    177:              if (fgets (string, BUFSIZ, stdin) == 0)
                    178:                break;
                    179:              fprintf (infile, "%s", string);
                    180:              if (string[strlen (string) - 1] == '\n')
                    181:                break;
                    182:            }
                    183:          fflush (infile);
                    184: 
                    185:          /* If command is close, close connection to client.  */
                    186:          if (strncmp (code, "Close:", 6) == 0) 
                    187:            if (infd > 2) 
                    188:              {
                    189:                fclose (infile);
                    190:                close (infd);
                    191:              }
                    192:          continue;
                    193:        } 
                    194:     }
                    195: }
                    196: 
                    197: #else  /* This is the SYSV IPC section */
                    198: 
                    199: #include <sys/types.h>
                    200: #include <sys/signal.h>
                    201: #include <sys/ipc.h>
                    202: #include <sys/msg.h>
                    203: #include <setjmp.h>
                    204: 
                    205: jmp_buf msgenv;
                    206: 
                    207: msgcatch ()
                    208: {
                    209:   longjmp (msgenv, 1);
                    210: }
                    211: 
                    212: 
                    213: /* "THIS has to be fixed.  Remember, stderr may not exist...-rlk."
                    214:    Incorrect.  This program runs as an inferior of Emacs.
                    215:    Its stderr always exists--rms.  */
                    216: #include <stdio.h>
                    217: 
                    218: main ()
                    219: {
                    220:   int s, infd, fromlen;
                    221:   key_t key;
                    222:   struct msgbuf * msgp =
                    223:     (struct msgbuf *) malloc (sizeof *msgp + BUFSIZ);
                    224:   struct msqid_ds msg_st;
                    225:   int p;
                    226:   char *homedir, *getenv ();
                    227:   char string[BUFSIZ];
                    228:   FILE *infile;
                    229: 
                    230:   /*
                    231:    * Create a message queue using ~/.emacs_server as the path for ftok
                    232:    */
                    233:   if ((homedir = getenv ("HOME")) == NULL)
                    234:     {
                    235:       fprintf (stderr,"No home directory\n");
                    236:       exit (1);
                    237:     }
                    238:   strcpy (string, homedir);
                    239:   strcat (string, "/.emacs_server");
                    240:   creat (string, 0600);
                    241:   key = ftok (string, 1);      /* unlikely to be anyone else using it */
                    242:   s = msgget (key, 0600 | IPC_CREAT);
                    243:   if (s == -1)
                    244:     {
                    245:       perror ("msgget");
                    246:       exit (1);
                    247:     }
                    248: 
                    249:   /* Fork so we can close connection even if parent dies */
                    250:   p = fork ();
                    251:   if (setjmp (msgenv))
                    252:     {
                    253:       msgctl (s, IPC_RMID, 0);
                    254:       kill (p, SIGKILL);
                    255:       exit (0);
                    256:     }
                    257:   signal (SIGTERM, msgcatch);
                    258:   signal (SIGINT, msgcatch);
                    259:   /* If parent goes away, remove message box and exit */
                    260:   if (p == 0)
                    261:     {
                    262:       p = getppid ();
                    263:       setpgrp ();              /* Gnu kills process group on exit */
                    264:       while (1)
                    265:        {
                    266:          if (kill (p, 0) < 0)
                    267:            {
                    268:              msgctl (s, IPC_RMID, 0);
                    269:              exit (0);
                    270:            }
                    271:          sleep (10);
                    272:        }
                    273:     }
                    274: 
                    275:   while (1)
                    276:     {
                    277:       if ((fromlen = msgrcv (s, msgp, BUFSIZ - 1, 1, 0)) < 0)
                    278:         {
                    279:          perror ("msgrcv");
                    280:         }
                    281:       else
                    282:         {
                    283:          msgctl (s, IPC_STAT, &msg_st);
                    284:          strncpy (string, msgp->mtext, fromlen);
                    285:          string[fromlen] = 0;  /* make sure */
                    286:          /* Newline is part of string.. */
                    287:          printf ("Client: %d %s", s, string); 
                    288:          fflush (stdout);
                    289:          /* Now, wait for a wakeup */
                    290:          fgets (msgp->mtext, BUFSIZ, stdin);
                    291:          msgp->mtext[strlen (msgp->mtext)-1] = 0;
                    292:          /*      strcpy (msgp->mtext, "done");*/
                    293:          msgp->mtype = msg_st.msg_lspid;
                    294:          msgsnd (s, msgp, strlen (msgp->mtext)+1, 0);
                    295:        }
                    296:     }
                    297: }
                    298: 
                    299: #endif /* SYSV IPC */
                    300: 
                    301: #endif /* BSD && IPC */
                    302: 
                    303: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.