diff options
| author | Stefan Monnier | 2002-09-25 20:17:32 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-09-25 20:17:32 +0000 |
| commit | 038de5b8231ad6f98c8246f1cd7228786d0b702d (patch) | |
| tree | a0095900f2e8411c208320fc5c71e280bbc78a79 /lib-src | |
| parent | ca5004e7b41a870e8208a6054b9ce3c8d8dc84eb (diff) | |
| download | emacs-038de5b8231ad6f98c8246f1cd7228786d0b702d.tar.gz emacs-038de5b8231ad6f98c8246f1cd7228786d0b702d.zip | |
Remove emacsserver.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/emacsserver.c | 599 |
1 files changed, 0 insertions, 599 deletions
diff --git a/lib-src/emacsserver.c b/lib-src/emacsserver.c deleted file mode 100644 index 3d099098436..00000000000 --- a/lib-src/emacsserver.c +++ /dev/null | |||
| @@ -1,599 +0,0 @@ | |||
| 1 | /* Communication subprocess for GNU Emacs acting as server. | ||
| 2 | Copyright (C) 1986, 1987, 1992, 1994, 1999 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 19 | Boston, MA 02111-1307, USA. */ | ||
| 20 | |||
| 21 | |||
| 22 | /* The GNU Emacs edit server process is run as a subprocess of Emacs | ||
| 23 | under control of the file lisp/server.el. | ||
| 24 | This program accepts communication from client (program emacsclient.c) | ||
| 25 | and passes their commands (consisting of keyboard characters) | ||
| 26 | up to the Emacs which then executes them. */ | ||
| 27 | |||
| 28 | #define NO_SHORTNAMES | ||
| 29 | |||
| 30 | #ifdef HAVE_CONFIG_H | ||
| 31 | #include <config.h> | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #include <signal.h> | ||
| 35 | #undef signal | ||
| 36 | |||
| 37 | #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC) | ||
| 38 | #include <stdio.h> | ||
| 39 | |||
| 40 | int | ||
| 41 | main () | ||
| 42 | { | ||
| 43 | fprintf (stderr, "Sorry, the Emacs server is supported only on systems\n"); | ||
| 44 | fprintf (stderr, "with Berkeley sockets or System V IPC.\n"); | ||
| 45 | exit (1); | ||
| 46 | } | ||
| 47 | |||
| 48 | #else /* HAVE_SOCKETS or HAVE_SYSVIPC */ | ||
| 49 | |||
| 50 | void perror_1 (); | ||
| 51 | void fatal_error (); | ||
| 52 | |||
| 53 | #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM) | ||
| 54 | /* BSD code is very different from SYSV IPC code */ | ||
| 55 | |||
| 56 | #include <sys/types.h> | ||
| 57 | #include <sys/file.h> | ||
| 58 | #include <sys/socket.h> | ||
| 59 | #include <sys/un.h> | ||
| 60 | #include <stdio.h> | ||
| 61 | #include <errno.h> | ||
| 62 | #include <sys/stat.h> | ||
| 63 | |||
| 64 | #ifdef HAVE_UNISTD_H | ||
| 65 | #include <unistd.h> | ||
| 66 | #endif | ||
| 67 | |||
| 68 | #ifndef errno | ||
| 69 | extern int errno; | ||
| 70 | #endif | ||
| 71 | |||
| 72 | /* Copied from src/process.c */ | ||
| 73 | #ifdef FD_SET | ||
| 74 | /* We could get this from param.h, but better not to depend on finding that. | ||
| 75 | And better not to risk that it might define other symbols used in this | ||
| 76 | file. */ | ||
| 77 | #ifdef FD_SETSIZE | ||
| 78 | #define MAXDESC FD_SETSIZE | ||
| 79 | #else | ||
| 80 | #define MAXDESC 64 | ||
| 81 | #endif | ||
| 82 | #define SELECT_TYPE fd_set | ||
| 83 | #else /* no FD_SET */ | ||
| 84 | #define MAXDESC 32 | ||
| 85 | #define SELECT_TYPE int | ||
| 86 | |||
| 87 | /* Define the macros to access a single-int bitmap of descriptors. */ | ||
| 88 | #define FD_SET(n, p) (*(p) |= (1 << (n))) | ||
| 89 | #define FD_CLR(n, p) (*(p) &= ~(1 << (n))) | ||
| 90 | #define FD_ISSET(n, p) (*(p) & (1 << (n))) | ||
| 91 | #define FD_ZERO(p) (*(p) = 0) | ||
| 92 | #endif /* no FD_SET */ | ||
| 93 | |||
| 94 | /* This is the file name of the socket that we made. */ | ||
| 95 | |||
| 96 | char *socket_name; | ||
| 97 | |||
| 98 | /* Name of this program. */ | ||
| 99 | |||
| 100 | char *progname; | ||
| 101 | |||
| 102 | /* Handle fatal signals. */ | ||
| 103 | |||
| 104 | /* This is the handler. */ | ||
| 105 | |||
| 106 | SIGTYPE | ||
| 107 | delete_socket (sig) | ||
| 108 | int sig; | ||
| 109 | { | ||
| 110 | signal (sig, SIG_DFL); | ||
| 111 | unlink (socket_name); | ||
| 112 | kill (getpid (), sig); | ||
| 113 | } | ||
| 114 | |||
| 115 | /* Set up to handle all the signals. */ | ||
| 116 | |||
| 117 | void | ||
| 118 | handle_signals () | ||
| 119 | { | ||
| 120 | signal (SIGHUP, delete_socket); | ||
| 121 | signal (SIGINT, delete_socket); | ||
| 122 | signal (SIGQUIT, delete_socket); | ||
| 123 | signal (SIGILL, delete_socket); | ||
| 124 | signal (SIGTRAP, delete_socket); | ||
| 125 | #ifdef SIGABRT | ||
| 126 | signal (SIGABRT, delete_socket); | ||
| 127 | #endif | ||
| 128 | #ifdef SIGHWE | ||
| 129 | signal (SIGHWE, delete_socket); | ||
| 130 | #endif | ||
| 131 | #ifdef SIGPRE | ||
| 132 | signal (SIGPRE, delete_socket); | ||
| 133 | #endif | ||
| 134 | #ifdef SIGORE | ||
| 135 | signal (SIGORE, delete_socket); | ||
| 136 | #endif | ||
| 137 | #ifdef SIGUME | ||
| 138 | signal (SIGUME, delete_socket); | ||
| 139 | #endif | ||
| 140 | #ifdef SIGDLK | ||
| 141 | signal (SIGDLK, delete_socket); | ||
| 142 | #endif | ||
| 143 | #ifdef SIGCPULIM | ||
| 144 | signal (SIGCPULIM, delete_socket); | ||
| 145 | #endif | ||
| 146 | #ifdef SIGIOT | ||
| 147 | /* This is missing on some systems - OS/2, for example. */ | ||
| 148 | signal (SIGIOT, delete_socket); | ||
| 149 | #endif | ||
| 150 | #ifdef SIGEMT | ||
| 151 | signal (SIGEMT, delete_socket); | ||
| 152 | #endif | ||
| 153 | signal (SIGFPE, delete_socket); | ||
| 154 | #ifdef SIGBUS | ||
| 155 | signal (SIGBUS, delete_socket); | ||
| 156 | #endif | ||
| 157 | signal (SIGSEGV, delete_socket); | ||
| 158 | #ifdef SIGSYS | ||
| 159 | signal (SIGSYS, delete_socket); | ||
| 160 | #endif | ||
| 161 | signal (SIGTERM, delete_socket); | ||
| 162 | #ifdef SIGXCPU | ||
| 163 | signal (SIGXCPU, delete_socket); | ||
| 164 | #endif | ||
| 165 | #ifdef SIGXFSZ | ||
| 166 | signal (SIGXFSZ, delete_socket); | ||
| 167 | #endif /* SIGXFSZ */ | ||
| 168 | |||
| 169 | #ifdef AIX | ||
| 170 | /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ | ||
| 171 | signal (SIGXCPU, delete_socket); | ||
| 172 | #ifndef _I386 | ||
| 173 | signal (SIGIOINT, delete_socket); | ||
| 174 | #endif | ||
| 175 | signal (SIGGRANT, delete_socket); | ||
| 176 | signal (SIGRETRACT, delete_socket); | ||
| 177 | signal (SIGSOUND, delete_socket); | ||
| 178 | signal (SIGMSG, delete_socket); | ||
| 179 | #endif /* AIX */ | ||
| 180 | } | ||
| 181 | |||
| 182 | /* Print error message. `s1' is printf control string, `s2' is arg for it. */ | ||
| 183 | void | ||
| 184 | error (s1, s2) | ||
| 185 | char *s1, *s2; | ||
| 186 | { | ||
| 187 | fprintf (stderr, "%s: ", progname); | ||
| 188 | fprintf (stderr, s1, s2); | ||
| 189 | fprintf (stderr, "\n"); | ||
| 190 | } | ||
| 191 | |||
| 192 | /* Print error message and exit. */ | ||
| 193 | void | ||
| 194 | fatal (s1, s2) | ||
| 195 | char *s1, *s2; | ||
| 196 | { | ||
| 197 | error (s1, s2); | ||
| 198 | exit (1); | ||
| 199 | } | ||
| 200 | |||
| 201 | /* Like malloc but get fatal error if memory is exhausted. */ | ||
| 202 | |||
| 203 | long * | ||
| 204 | xmalloc (size) | ||
| 205 | unsigned int size; | ||
| 206 | { | ||
| 207 | long *result = (long *) malloc (size); | ||
| 208 | if (result == NULL) | ||
| 209 | fatal ("virtual memory exhausted", 0); | ||
| 210 | return result; | ||
| 211 | } | ||
| 212 | |||
| 213 | int | ||
| 214 | main (argc, argv) | ||
| 215 | int argc; | ||
| 216 | char **argv; | ||
| 217 | { | ||
| 218 | char *system_name; | ||
| 219 | int system_name_length; | ||
| 220 | int s, infd; | ||
| 221 | #ifdef SOCKLEN_TYPE | ||
| 222 | SOCKLEN_TYPE fromlen; | ||
| 223 | #else | ||
| 224 | size_t fromlen; | ||
| 225 | #endif | ||
| 226 | struct sockaddr_un server, fromunix; | ||
| 227 | #ifdef SERVER_HOME_DIR | ||
| 228 | char *homedir; | ||
| 229 | #endif | ||
| 230 | char *str, string[BUFSIZ], code[BUFSIZ]; | ||
| 231 | FILE *infile; | ||
| 232 | FILE **openfiles; | ||
| 233 | int openfiles_size; | ||
| 234 | struct stat statbuf; | ||
| 235 | |||
| 236 | #ifndef convex | ||
| 237 | char *getenv (); | ||
| 238 | #endif | ||
| 239 | |||
| 240 | progname = argv[0]; | ||
| 241 | |||
| 242 | openfiles_size = 20; | ||
| 243 | openfiles = (FILE **) malloc (openfiles_size * sizeof (FILE *)); | ||
| 244 | if (openfiles == 0) | ||
| 245 | abort (); | ||
| 246 | |||
| 247 | /* | ||
| 248 | * Open up an AF_UNIX socket in this person's home directory | ||
| 249 | */ | ||
| 250 | |||
| 251 | if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) | ||
| 252 | { | ||
| 253 | perror_1 ("socket"); | ||
| 254 | exit (1); | ||
| 255 | } | ||
| 256 | server.sun_family = AF_UNIX; | ||
| 257 | |||
| 258 | system_name_length = 32; | ||
| 259 | while (1) | ||
| 260 | { | ||
| 261 | system_name = (char *) xmalloc (system_name_length + 1); | ||
| 262 | |||
| 263 | /* system_name must be null-terminated string. */ | ||
| 264 | system_name[system_name_length] = '\0'; | ||
| 265 | |||
| 266 | if (gethostname (system_name, system_name_length) == 0) | ||
| 267 | break; | ||
| 268 | |||
| 269 | free (system_name); | ||
| 270 | system_name_length *= 2; | ||
| 271 | } | ||
| 272 | |||
| 273 | #ifndef SERVER_HOME_DIR | ||
| 274 | sprintf (server.sun_path, "/tmp/esrv%d-%s", (int) geteuid (), system_name); | ||
| 275 | |||
| 276 | if (unlink (server.sun_path) == -1 && errno != ENOENT) | ||
| 277 | { | ||
| 278 | perror_1 ("unlink"); | ||
| 279 | exit (1); | ||
| 280 | } | ||
| 281 | #else | ||
| 282 | if ((homedir = getenv ("HOME")) == NULL) | ||
| 283 | fatal_error ("No home directory\n"); | ||
| 284 | |||
| 285 | strcpy (server.sun_path, homedir); | ||
| 286 | strcat (server.sun_path, "/.emacs-server-"); | ||
| 287 | strcat (server.sun_path, system_name); | ||
| 288 | /* Delete anyone else's old server. */ | ||
| 289 | unlink (server.sun_path); | ||
| 290 | #endif | ||
| 291 | |||
| 292 | /* Save the socket name so we can delete it. */ | ||
| 293 | socket_name = (char *) xmalloc (strlen (server.sun_path) + 1); | ||
| 294 | strcpy (socket_name, server.sun_path); | ||
| 295 | |||
| 296 | handle_signals (); | ||
| 297 | |||
| 298 | if (bind (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2) < 0) | ||
| 299 | { | ||
| 300 | perror_1 ("bind"); | ||
| 301 | exit (1); | ||
| 302 | } | ||
| 303 | /* Only this user can send commands to this Emacs. */ | ||
| 304 | if (stat (server.sun_path, &statbuf) < 0) | ||
| 305 | { | ||
| 306 | perror_1 ("bind"); | ||
| 307 | exit (1); | ||
| 308 | } | ||
| 309 | |||
| 310 | chmod (server.sun_path, statbuf.st_mode & 0600); | ||
| 311 | /* | ||
| 312 | * Now, just wait for everything to come in.. | ||
| 313 | */ | ||
| 314 | if (listen (s, 5) < 0) | ||
| 315 | { | ||
| 316 | perror_1 ("listen"); | ||
| 317 | exit (1); | ||
| 318 | } | ||
| 319 | |||
| 320 | /* Disable sigpipes in case luser kills client... */ | ||
| 321 | signal (SIGPIPE, SIG_IGN); | ||
| 322 | for (;;) | ||
| 323 | { | ||
| 324 | SELECT_TYPE rmask; | ||
| 325 | FD_ZERO (&rmask); | ||
| 326 | FD_SET (0, &rmask); | ||
| 327 | FD_SET (s, &rmask); | ||
| 328 | if (select (s + 1, &rmask, 0, 0, 0) < 0) | ||
| 329 | perror_1 ("select"); | ||
| 330 | if (FD_ISSET (s, &rmask)) /* client sends list of filenames */ | ||
| 331 | { | ||
| 332 | fromlen = sizeof (fromunix); | ||
| 333 | fromunix.sun_family = AF_UNIX; | ||
| 334 | infd = accept (s, (struct sockaddr *) &fromunix, &fromlen); | ||
| 335 | if (infd < 0) | ||
| 336 | { | ||
| 337 | if (errno == EMFILE || errno == ENFILE) | ||
| 338 | fprintf (stderr, "Error: too many clients.\n"); | ||
| 339 | else | ||
| 340 | perror_1 ("accept"); | ||
| 341 | continue; | ||
| 342 | } | ||
| 343 | |||
| 344 | if (infd >= openfiles_size) | ||
| 345 | { | ||
| 346 | openfiles_size *= 2; | ||
| 347 | openfiles = (FILE **) realloc (openfiles, | ||
| 348 | openfiles_size * sizeof (FILE *)); | ||
| 349 | if (openfiles == 0) | ||
| 350 | abort (); | ||
| 351 | } | ||
| 352 | |||
| 353 | infile = fdopen (infd, "r+"); /* open stream */ | ||
| 354 | if (infile == NULL) | ||
| 355 | { | ||
| 356 | fprintf (stderr, "Error: too many clients.\n"); | ||
| 357 | write (infd, "Too many clients.\n", 18); | ||
| 358 | close (infd); /* Prevent descriptor leak.. */ | ||
| 359 | continue; | ||
| 360 | } | ||
| 361 | str = fgets (string, BUFSIZ, infile); | ||
| 362 | if (str == NULL) | ||
| 363 | { | ||
| 364 | perror_1 ("fgets"); | ||
| 365 | close (infd); /* Prevent descriptor leak.. */ | ||
| 366 | continue; | ||
| 367 | } | ||
| 368 | openfiles[infd] = infile; | ||
| 369 | printf ("Client: %d %s", infd, string); | ||
| 370 | /* If what we read did not end in a newline, | ||
| 371 | it means there is more. Keep reading from the socket | ||
| 372 | and outputting to Emacs, until we get the newline. */ | ||
| 373 | while (string[strlen (string) - 1] != '\n') | ||
| 374 | { | ||
| 375 | if (fgets (string, BUFSIZ, infile) == 0) | ||
| 376 | break; | ||
| 377 | printf ("%s", string); | ||
| 378 | } | ||
| 379 | fflush (stdout); | ||
| 380 | fflush (infile); | ||
| 381 | continue; | ||
| 382 | } | ||
| 383 | else if (FD_ISSET (0, &rmask)) /* emacs sends codeword, fd, and string message */ | ||
| 384 | { | ||
| 385 | /* Read command codeword and fd */ | ||
| 386 | clearerr (stdin); | ||
| 387 | scanf ("%s %d%*c", code, &infd); | ||
| 388 | if (ferror (stdin) || feof (stdin)) | ||
| 389 | fatal_error ("server: error reading from standard input\n"); | ||
| 390 | |||
| 391 | /* Transfer text from Emacs to the client, up to a newline. */ | ||
| 392 | infile = openfiles[infd]; | ||
| 393 | rewind (infile); | ||
| 394 | while (1) | ||
| 395 | { | ||
| 396 | if (fgets (string, BUFSIZ, stdin) == 0) | ||
| 397 | break; | ||
| 398 | fprintf (infile, "%s", string); | ||
| 399 | if (string[strlen (string) - 1] == '\n') | ||
| 400 | break; | ||
| 401 | } | ||
| 402 | fflush (infile); | ||
| 403 | |||
| 404 | /* If command is close, close connection to client. */ | ||
| 405 | if (strncmp (code, "Close:", 6) == 0) | ||
| 406 | if (infd > 2) | ||
| 407 | { | ||
| 408 | fclose (infile); | ||
| 409 | close (infd); | ||
| 410 | } | ||
| 411 | continue; | ||
| 412 | } | ||
| 413 | } | ||
| 414 | } | ||
| 415 | |||
| 416 | #else /* This is the SYSV IPC section */ | ||
| 417 | |||
| 418 | #include <sys/types.h> | ||
| 419 | #include <sys/ipc.h> | ||
| 420 | #include <sys/msg.h> | ||
| 421 | #include <setjmp.h> | ||
| 422 | #include <errno.h> | ||
| 423 | #include <sys/utsname.h> | ||
| 424 | |||
| 425 | struct utsname system_name; | ||
| 426 | |||
| 427 | #ifndef errno | ||
| 428 | extern int errno; | ||
| 429 | #endif | ||
| 430 | |||
| 431 | jmp_buf msgenv; | ||
| 432 | |||
| 433 | SIGTYPE | ||
| 434 | msgcatch () | ||
| 435 | { | ||
| 436 | longjmp (msgenv, 1); | ||
| 437 | } | ||
| 438 | |||
| 439 | |||
| 440 | /* "THIS has to be fixed. Remember, stderr may not exist...-rlk." | ||
| 441 | Incorrect. This program runs as an inferior of Emacs. | ||
| 442 | Its stderr always exists--rms. */ | ||
| 443 | #include <stdio.h> | ||
| 444 | |||
| 445 | int | ||
| 446 | main () | ||
| 447 | { | ||
| 448 | int s, infd, fromlen, ioproc; | ||
| 449 | key_t key; | ||
| 450 | struct msgbuf * msgp = | ||
| 451 | (struct msgbuf *) malloc (sizeof *msgp + BUFSIZ); | ||
| 452 | struct msqid_ds msg_st; | ||
| 453 | int p; | ||
| 454 | char *homedir, *getenv (); | ||
| 455 | char string[BUFSIZ]; | ||
| 456 | FILE *infile; | ||
| 457 | |||
| 458 | /* | ||
| 459 | * Create a message queue using ~/.emacs-server as the path for ftok | ||
| 460 | */ | ||
| 461 | if ((homedir = getenv ("HOME")) == NULL) | ||
| 462 | fatal_error ("No home directory\n"); | ||
| 463 | |||
| 464 | strcpy (string, homedir); | ||
| 465 | #ifndef HAVE_LONG_FILE_NAMES | ||
| 466 | /* If file names are short, we can't fit the host name. */ | ||
| 467 | strcat (string, "/.emacs-server"); | ||
| 468 | #else | ||
| 469 | strcat (string, "/.emacs-server-"); | ||
| 470 | uname (&system_name); | ||
| 471 | strcat (string, system_name.nodename); | ||
| 472 | #endif | ||
| 473 | creat (string, 0600); | ||
| 474 | key = ftok (string, 1); /* unlikely to be anyone else using it */ | ||
| 475 | s = msgget (key, 0600 | IPC_CREAT); | ||
| 476 | if (s == -1) | ||
| 477 | { | ||
| 478 | perror_1 ("msgget"); | ||
| 479 | exit (1); | ||
| 480 | } | ||
| 481 | |||
| 482 | /* Fork so we can close connection even if parent dies */ | ||
| 483 | p = fork (); | ||
| 484 | if (setjmp (msgenv)) | ||
| 485 | { | ||
| 486 | msgctl (s, IPC_RMID, 0); | ||
| 487 | if (p > 0) | ||
| 488 | kill (p, SIGKILL); | ||
| 489 | exit (0); | ||
| 490 | } | ||
| 491 | signal (SIGTERM, msgcatch); | ||
| 492 | signal (SIGINT, msgcatch); | ||
| 493 | signal (SIGHUP, msgcatch); | ||
| 494 | if (p > 0) | ||
| 495 | { | ||
| 496 | /* This is executed in the original process that did the fork above. */ | ||
| 497 | /* Get pid of Emacs itself. */ | ||
| 498 | p = getppid (); | ||
| 499 | setpgrp (); /* Gnu kills process group on exit */ | ||
| 500 | while (1) | ||
| 501 | { | ||
| 502 | /* Is Emacs still alive? */ | ||
| 503 | if (kill (p, 0) < 0) | ||
| 504 | { | ||
| 505 | msgctl (s, IPC_RMID, 0); | ||
| 506 | exit (0); | ||
| 507 | } | ||
| 508 | sleep (10); | ||
| 509 | } | ||
| 510 | } | ||
| 511 | |||
| 512 | /* This is executed in the child made by forking above. | ||
| 513 | Call it c1. Make another process, ioproc. */ | ||
| 514 | |||
| 515 | ioproc = fork (); | ||
| 516 | if (ioproc == 0) | ||
| 517 | { | ||
| 518 | /* In process ioproc, wait for text from Emacs, | ||
| 519 | and send it to the process c1. | ||
| 520 | This way, c1 only has to wait for one source of input. */ | ||
| 521 | while (fgets (msgp->mtext, BUFSIZ, stdin)) | ||
| 522 | { | ||
| 523 | msgp->mtype = 1; | ||
| 524 | msgsnd (s, msgp, strlen (msgp->mtext) + 1, 0); | ||
| 525 | } | ||
| 526 | exit (1); | ||
| 527 | } | ||
| 528 | |||
| 529 | /* In the process c1, | ||
| 530 | listen for messages from clients and pass them to Emacs. */ | ||
| 531 | while (1) | ||
| 532 | { | ||
| 533 | if ((fromlen = msgrcv (s, msgp, BUFSIZ - 1, 1, 0)) < 0) | ||
| 534 | { | ||
| 535 | #ifdef EINTR | ||
| 536 | if (errno == EINTR) | ||
| 537 | continue; | ||
| 538 | #endif | ||
| 539 | perror_1 ("msgrcv"); | ||
| 540 | exit (1); | ||
| 541 | } | ||
| 542 | else | ||
| 543 | { | ||
| 544 | msgctl (s, IPC_STAT, &msg_st); | ||
| 545 | |||
| 546 | /* Distinguish whether the message came from a client, or from | ||
| 547 | ioproc. */ | ||
| 548 | if (msg_st.msg_lspid == ioproc) | ||
| 549 | { | ||
| 550 | char code[BUFSIZ]; | ||
| 551 | int inproc; | ||
| 552 | |||
| 553 | /* Message from ioproc: tell a client we are done. */ | ||
| 554 | msgp->mtext[strlen (msgp->mtext)-1] = 0; | ||
| 555 | sscanf (msgp->mtext, "%s %d", code, &inproc); | ||
| 556 | msgp->mtype = inproc; | ||
| 557 | msgsnd (s, msgp, strlen (msgp->mtext) + 1, 0); | ||
| 558 | continue; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* This is a request from a client: copy to stdout | ||
| 562 | so that Emacs will get it. Include msg_lspid | ||
| 563 | so server.el can tell us where to send the reply. */ | ||
| 564 | strncpy (string, msgp->mtext, fromlen); | ||
| 565 | string[fromlen] = 0; /* make sure */ | ||
| 566 | /* Newline is part of string.. */ | ||
| 567 | printf ("Client: %d %s", msg_st.msg_lspid, string); | ||
| 568 | fflush (stdout); | ||
| 569 | } | ||
| 570 | } | ||
| 571 | } | ||
| 572 | |||
| 573 | #endif /* HAVE_SYSVIPC */ | ||
| 574 | |||
| 575 | |||
| 576 | /* This is like perror but puts `Error: ' at the beginning. */ | ||
| 577 | |||
| 578 | void | ||
| 579 | perror_1 (string) | ||
| 580 | char *string; | ||
| 581 | { | ||
| 582 | char *copy = (char *) malloc (strlen (string) + 8); | ||
| 583 | if (copy == 0) | ||
| 584 | fatal_error ("Virtual memory exhausted"); | ||
| 585 | |||
| 586 | strcpy (copy, "Error: "); | ||
| 587 | strcat (copy, string); | ||
| 588 | perror (copy); | ||
| 589 | } | ||
| 590 | |||
| 591 | void | ||
| 592 | fatal_error (string) | ||
| 593 | char *string; | ||
| 594 | { | ||
| 595 | fprintf (stderr, "%s", "Error: "); | ||
| 596 | fprintf (stderr, string); | ||
| 597 | exit (1); | ||
| 598 | } | ||
| 599 | #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */ | ||