Annotation of 43BSDReno/contrib/emacs-18.55/etc/server.c, revision 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.