emacsclient.c 55.2 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* Client process that communicates with GNU Emacs acting as server.
2

Paul Eggert's avatar
Paul Eggert committed
3
Copyright (C) 1986-1987, 1994, 1999-2020 Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
4 5 6

This file is part of GNU Emacs.

7
GNU Emacs is free software: you can redistribute it and/or modify
Richard M. Stallman's avatar
Richard M. Stallman committed
8
it under the terms of the GNU General Public License as published by
9 10
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
Richard M. Stallman's avatar
Richard M. Stallman committed
11 12 13 14 15 16 17

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
18
along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
Richard M. Stallman's avatar
Richard M. Stallman committed
19 20


Pavel Janík's avatar
Pavel Janík committed
21
#include <config.h>
22

23 24
#ifdef WINDOWSNT

25
/* ms-w32.h defines these, which disables sockets altogether!  */
26 27 28
# undef _WINSOCKAPI_
# undef _WINSOCK_H

29
# include <malloc.h>
Juanma Barranquero's avatar
Juanma Barranquero committed
30
# include <windows.h>
31
# include <commctrl.h>
Dan Nicolaescu's avatar
Dan Nicolaescu committed
32 33
# include <io.h>
# include <winsock2.h>
34

35 36
# define HSOCKET SOCKET
# define CLOSE_SOCKET closesocket
37
# define INITIALIZE() initialize_sockets ()
38

39
char *w32_getenv (const char *);
40
# define egetenv(VAR) w32_getenv (VAR)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
41

42 43
# undef signal

44 45
#else /* !WINDOWSNT */

46
# ifdef HAVE_NTGUI
47 48
#  include <windows.h>
# endif
49

50
# include "syswait.h"
51

Dan Nicolaescu's avatar
Dan Nicolaescu committed
52
# include <arpa/inet.h>
53
# include <fcntl.h>
54 55 56
# include <netinet/in.h>
# include <sys/socket.h>
# include <sys/un.h>
Dan Nicolaescu's avatar
Dan Nicolaescu committed
57

58 59
# define SOCKETS_IN_FILE_SYSTEM

60
# define INVALID_SOCKET (-1)
61 62 63
# define HSOCKET int
# define CLOSE_SOCKET close
# define INITIALIZE()
64

65
# define egetenv(VAR) getenv (VAR)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
66

67
#endif /* !WINDOWSNT */
68

69
#include <ctype.h>
70
#include <errno.h>
71
#include <getopt.h>
72
#include <inttypes.h>
Dan Nicolaescu's avatar
Dan Nicolaescu committed
73
#include <pwd.h>
74
#include <signal.h>
75
#include <stdarg.h>
76
#include <stddef.h>
Paul Eggert's avatar
Paul Eggert committed
77
#include <stdint.h>
78 79 80 81
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
82

83
#include <dosname.h>
84
#include <intprops.h>
85
#include <min-max.h>
Paul Eggert's avatar
Paul Eggert committed
86
#include <pathmax.h>
87 88
#include <unlocked-io.h>

89 90 91 92 93
/* Work around GCC bug 88251.  */
#if GNUC_PREREQ (7, 0, 0)
# pragma GCC diagnostic ignored "-Wformat-truncation=2"
#endif

94

95
/* Name used to invoke this program.  */
96
static char const *progname;
97

98
/* The first argument to main.  */
99
static int main_argc;
100

101
/* The second argument to main.  */
102
static char *const *main_argv;
Karoly Lorentey's avatar
Karoly Lorentey committed
103

104
/* True means don't wait for a response from Emacs.  --no-wait.  */
105
static bool nowait;
106

107
/* True means don't print messages for successful operations.  --quiet.  */
108
static bool quiet;
109

110
/* True means don't print values returned from emacs. --suppress-output.  */
111
static bool suppress_output;
112

113
/* True means args are expressions to be evaluated.  --eval.  */
114
static bool eval;
Stefan Monnier's avatar
Stefan Monnier committed
115

116 117
/* True means open a new frame.  --create-frame etc.  */
static bool create_frame;
118

Stefan Monnier's avatar
Stefan Monnier committed
119
/* The display on which Emacs should work.  --display.  */
120
static char const *display;
Stefan Monnier's avatar
Stefan Monnier committed
121

122
/* The alternate display we should try if Emacs does not support display.  */
123
static char const *alt_display;
124

125
/* The parent window ID, if we are opening a frame via XEmbed.  */
126
static char *parent_id;
127

128
/* True means open a new Emacs frame on the current terminal.  */
129
static bool tty;
130

Stefan Monnier's avatar
Stefan Monnier committed
131 132
/* If non-NULL, the name of an editor to fallback to if the server
   is not running.  --alternate-editor.   */
133
static char *alternate_editor;
Stefan Monnier's avatar
Stefan Monnier committed
134

135
#ifdef SOCKETS_IN_FILE_SYSTEM
Richard M. Stallman's avatar
Richard M. Stallman committed
136
/* If non-NULL, the filename of the UNIX socket.  */
137
static char const *socket_name;
138
#endif
139

140
/* If non-NULL, the filename of the authentication file.  */
141
static char const *server_file;
142

143
/* If non-NULL, the tramp prefix emacs must use to find the files.  */
144
static char const *tramp_prefix;
145

146
/* If nonzero, PID of the Emacs server process.  */
147
static pid_t emacs_pid;
148

149
/* If non-NULL, a string that should form a frame parameter alist to
150
   be used for the new frame.  */
151
static char const *frame_parameters;
152

153
static _Noreturn void print_help_and_exit (void);
154

155
/* Long command-line options.  */
156

157
static struct option const longopts[] =
158
{
159
  { "no-wait",	no_argument,	   NULL, 'n' },
160
  { "quiet",	no_argument,	   NULL, 'q' },
161
  { "suppress-output", no_argument, NULL, 'u' },
Stefan Monnier's avatar
Stefan Monnier committed
162
  { "eval",	no_argument,	   NULL, 'e' },
163 164
  { "help",	no_argument,	   NULL, 'H' },
  { "version",	no_argument,	   NULL, 'V' },
165
  { "tty",	no_argument,       NULL, 't' },
166
  { "nw",	no_argument,       NULL, 't' },
167
  { "create-frame", no_argument,   NULL, 'c' },
168
  { "alternate-editor", required_argument, NULL, 'a' },
169
  { "frame-parameters", required_argument, NULL, 'F' },
170
#ifdef SOCKETS_IN_FILE_SYSTEM
171
  { "socket-name",	required_argument, NULL, 's' },
172
#endif
173
  { "server-file",	required_argument, NULL, 'f' },
Stefan Monnier's avatar
Stefan Monnier committed
174
  { "display",	required_argument, NULL, 'd' },
175
  { "parent-id", required_argument, NULL, 'p' },
176
  { "tramp",	required_argument, NULL, 'T' },
Stefan Monnier's avatar
Stefan Monnier committed
177
  { 0, 0, 0, 0 }
178 179
};

180 181 182 183
/* Short options, in the same order as the corresponding long options.
   There is no '-p' short option.  */
static char const shortopts[] =
  "nqueHVtca:F:"
184
#ifdef SOCKETS_IN_FILE_SYSTEM
185 186 187 188
  "s:"
#endif
  "f:d:T:";

189 190 191

/* Like malloc but get fatal error if memory is exhausted.  */

192
static void * ATTRIBUTE_MALLOC
193
xmalloc (size_t size)
194
{
195
  void *result = malloc (size);
196 197 198 199 200 201 202 203
  if (result == NULL)
    {
      perror ("malloc");
      exit (EXIT_FAILURE);
    }
  return result;
}

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
/* Like realloc but get fatal error if memory is exhausted.  */

static void *
xrealloc (void *ptr, size_t size)
{
  void *result = realloc (ptr, size);
  if (result == NULL)
    {
      perror ("realloc");
      exit (EXIT_FAILURE);
    }
  return result;
}

/* Like strdup but get a fatal error if memory is exhausted. */

220
static char * ATTRIBUTE_MALLOC
221 222 223 224 225 226 227 228 229 230 231
xstrdup (const char *s)
{
  char *result = strdup (s);
  if (result == NULL)
    {
      perror ("strdup");
      exit (EXIT_FAILURE);
    }
  return result;
}

232
/* From sysdep.c */
233
#if !defined HAVE_GET_CURRENT_DIR_NAME || defined BROKEN_GET_CURRENT_DIR_NAME
234

235
char *get_current_dir_name (void);
236

237
/* Return the current working directory.  Returns NULL on errors.
238
   Any other returned value must be freed with free.  This is used
239
   only when get_current_dir_name is not defined on the system.  */
Paul Eggert's avatar
Paul Eggert committed
240
char *
241
get_current_dir_name (void)
242
{
Paul Eggert's avatar
Paul Eggert committed
243 244 245 246 247 248 249 250 251 252 253
  /* The maximum size of a directory name, including the terminating NUL.
     Leave room so that the caller can append a trailing slash.  */
  ptrdiff_t dirsize_max = min (PTRDIFF_MAX, SIZE_MAX) - 1;

  /* The maximum size of a buffer for a file name, including the
     terminating NUL.  This is bounded by PATH_MAX, if available.  */
  ptrdiff_t bufsize_max = dirsize_max;
#ifdef PATH_MAX
  bufsize_max = min (bufsize_max, PATH_MAX);
#endif

254 255
  char *buf;
  struct stat dotstat, pwdstat;
256
  size_t pwdlen;
257
  /* If PWD is accurate, use it instead of calling getcwd.  PWD is
258 259
     sometimes a nicer name, and using it may avoid a fatal error if a
     parent directory is searchable but not readable.  */
Paul Eggert's avatar
Paul Eggert committed
260 261
  char const *pwd = egetenv ("PWD");
  if (pwd
Paul Eggert's avatar
Paul Eggert committed
262 263
      && (pwdlen = strnlen (pwd, bufsize_max)) < bufsize_max
      && IS_DIRECTORY_SEP (pwd[pwdlen && IS_DEVICE_SEP (pwd[1]) ? 2 : 0])
264 265 266
      && stat (pwd, &pwdstat) == 0
      && stat (".", &dotstat) == 0
      && dotstat.st_ino == pwdstat.st_ino
Paul Eggert's avatar
Paul Eggert committed
267
      && dotstat.st_dev == pwdstat.st_dev)
268
    {
269
      buf = xmalloc (strlen (pwd) + 1);
270 271 272 273 274 275 276
      strcpy (buf, pwd);
    }
  else
    {
      size_t buf_size = 1024;
      for (;;)
        {
277 278 279 280
	  int tmp_errno;
	  buf = malloc (buf_size);
	  if (! buf)
	    break;
281 282
          if (getcwd (buf, buf_size) == buf)
            break;
283 284 285
	  tmp_errno = errno;
	  free (buf);
	  if (tmp_errno != ERANGE)
286 287 288 289 290
            {
              errno = tmp_errno;
              return NULL;
            }
          buf_size *= 2;
291 292 293 294 295
	  if (! buf_size)
	    {
	      errno = ENOMEM;
	      return NULL;
	    }
296 297 298 299 300 301
        }
    }
  return buf;
}
#endif

Juanma Barranquero's avatar
Juanma Barranquero committed
302
#ifdef WINDOWSNT
303

304
# define REG_ROOT "SOFTWARE\\GNU\\Emacs"
305

306 307
char *w32_get_resource (HKEY, const char *, LPDWORD);

308 309 310 311
/* Retrieve an environment variable from the Emacs subkeys of the registry.
   Return NULL if the variable was not found, or it was empty.
   This code is based on w32_get_resource (w32.c).  */
char *
312
w32_get_resource (HKEY predefined, const char *key, LPDWORD type)
313 314 315 316 317
{
  HKEY hrootkey = NULL;
  char *result = NULL;
  DWORD cbData;

318 319
  if (RegOpenKeyEx (predefined, REG_ROOT, 0, KEY_READ, &hrootkey)
      == ERROR_SUCCESS)
320
    {
321 322
      if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData)
	  == ERROR_SUCCESS)
323
	{
324
	  result = xmalloc (cbData);
325

326 327 328 329
	  if ((RegQueryValueEx (hrootkey, key, NULL, type, (LPBYTE) result,
				&cbData)
	       != ERROR_SUCCESS)
	      || *result == 0)
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
	    {
	      free (result);
	      result = NULL;
	    }
	}

      RegCloseKey (hrootkey);
    }

  return result;
}

/*
  getenv wrapper for Windows

345 346 347 348 349
  Value is allocated on the heap, and can be free'd.

  This is needed to duplicate Emacs's behavior, which is to look for
  environment variables in the registry if they don't appear in the
  environment.  */
350
char *
351
w32_getenv (const char *envvar)
352 353 354 355
{
  char *value;
  DWORD dwType;

356
  if ((value = getenv (envvar)))
357 358 359
    /* Found in the environment.  strdup it, because values returned
       by getenv cannot be free'd.  */
    return xstrdup (value);
360 361 362

  if (! (value = w32_get_resource (HKEY_CURRENT_USER, envvar, &dwType)) &&
      ! (value = w32_get_resource (HKEY_LOCAL_MACHINE, envvar, &dwType)))
363 364 365
    {
      /* "w32console" is what Emacs on Windows uses for tty-type under -nw.  */
      if (strcmp (envvar, "TERM") == 0)
366
	return xstrdup ("w32console");
367 368 369
      /* Found neither in the environment nor in the registry.  */
      return NULL;
    }
370 371 372 373 374 375 376 377 378

  if (dwType == REG_SZ)
    /* Registry; no need to expand.  */
    return value;

  if (dwType == REG_EXPAND_SZ)
    {
      DWORD size;

379
      if ((size = ExpandEnvironmentStrings (value, NULL, 0)))
380
	{
381
	  char *buffer = xmalloc (size);
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
	  if (ExpandEnvironmentStrings (value, buffer, size))
	    {
	      /* Found and expanded.  */
	      free (value);
	      return buffer;
	    }

	  /* Error expanding.  */
	  free (buffer);
	}
    }

  /* Not the right type, or not correctly expanded.  */
  free (value);
  return NULL;
}

399
int w32_window_app (void);
400

Juanma Barranquero's avatar
Juanma Barranquero committed
401
int
402
w32_window_app (void)
Juanma Barranquero's avatar
Juanma Barranquero committed
403 404 405 406 407
{
  static int window_app = -1;
  char szTitle[MAX_PATH];

  if (window_app < 0)
408 409 410 411 412
    {
      /* Checking for STDOUT does not work; it's a valid handle also in
         nonconsole apps.  Testing for the console title seems to work. */
      window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
      if (window_app)
413
        InitCommonControls ();
414
    }
Juanma Barranquero's avatar
Juanma Barranquero committed
415 416 417

  return window_app;
}
418

419
/* execvp wrapper for Windows.  Quotes arguments with embedded spaces.
420 421 422 423

  This is necessary due to the broken implementation of exec* routines in
  the Microsoft libraries: they concatenate the arguments together without
  quoting special characters, and pass the result to CreateProcess, with
424
  predictably bad results.  By contrast, POSIX execvp passes the arguments
425 426
  directly into the argv array of the child process.  */

427 428
int w32_execvp (const char *, char **);

429
int
430
w32_execvp (const char *path, char **argv)
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
{
  int i;

  /* Required to allow a .BAT script as alternate editor.  */
  argv[0] = (char *) alternate_editor;

  for (i = 0; argv[i]; i++)
    if (strchr (argv[i], ' '))
      {
	char *quoted = alloca (strlen (argv[i]) + 3);
	sprintf (quoted, "\"%s\"", argv[i]);
	argv[i] = quoted;
      }

  return execvp (path, argv);
}

448 449
# undef execvp
# define execvp w32_execvp
450

451
/* Emulation of ttyname for Windows.  */
452 453
const char *ttyname (int);
const char *
454 455 456 457 458
ttyname (int fd)
{
  return "CONOUT$";
}

459
#endif /* WINDOWSNT */
Juanma Barranquero's avatar
Juanma Barranquero committed
460

Juanma Barranquero's avatar
Juanma Barranquero committed
461 462
/* Display a normal or error message.
   On Windows, use a message box if compiled as a Windows app.  */
463
static void message (bool, const char *, ...) ATTRIBUTE_FORMAT_PRINTF (2, 3);
464
static void
465
message (bool is_error, const char *format, ...)
Juanma Barranquero's avatar
Juanma Barranquero committed
466 467 468
{
  va_list args;

469
  va_start (args, format);
Juanma Barranquero's avatar
Juanma Barranquero committed
470 471 472 473

#ifdef WINDOWSNT
  if (w32_window_app ())
    {
474 475 476 477
      char msg[2048];
      vsnprintf (msg, sizeof msg, format, args);
      msg[sizeof msg - 1] = '\0';

Juanma Barranquero's avatar
Juanma Barranquero committed
478 479 480 481 482 483 484
      if (is_error)
	MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
      else
	MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
    }
  else
#endif
485 486 487
    {
      FILE *f = is_error ? stderr : stdout;

488
      vfprintf (f, format, args);
489 490
      fflush (f);
    }
491 492

  va_end (args);
Juanma Barranquero's avatar
Juanma Barranquero committed
493 494
}

495
/* Decode the options from argv and argc.
496
   The global variable 'optind' will say how many arguments we used up.  */
497

498
static void
499
decode_options (int argc, char **argv)
500
{
501
  alternate_editor = egetenv ("ALTERNATE_EDITOR");
502
  tramp_prefix = egetenv ("EMACSCLIENT_TRAMP");
503

504
  while (true)
505
    {
506 507
      int opt = getopt_long_only (argc, argv, shortopts, longopts, NULL);
      if (opt < 0)
508 509 510 511 512 513 514 515
	break;

      switch (opt)
	{
	case 0:
	  /* If getopt returns 0, then it has already processed a
	     long-named option.  We should do nothing.  */
	  break;
516

517 518 519
	case 'a':
	  alternate_editor = optarg;
	  break;
520

521
#ifdef SOCKETS_IN_FILE_SYSTEM
522 523 524
	case 's':
	  socket_name = optarg;
	  break;
525
#endif
526

527 528 529
	case 'f':
	  server_file = optarg;
	  break;
530

531 532 533 534
	  /* We used to disallow this argument in w32, but it seems better
	     to allow it, for the occasional case where the user is
	     connecting with a w32 client to a server compiled with X11
	     support.  */
Stefan Monnier's avatar
Stefan Monnier committed
535 536 537 538
	case 'd':
	  display = optarg;
	  break;

539
	case 'n':
540
	  nowait = true;
541 542
	  break;

Stefan Monnier's avatar
Stefan Monnier committed
543
	case 'e':
544
	  eval = true;
Stefan Monnier's avatar
Stefan Monnier committed
545 546
	  break;

547
	case 'q':
548
	  quiet = true;
549 550
	  break;

551
	case 'u':
552
	  suppress_output = true;
553 554
	  break;

555
	case 'V':
556
	  message (false, "emacsclient %s\n", PACKAGE_VERSION);
557
	  exit (EXIT_SUCCESS);
558
	  break;
Richard M. Stallman's avatar
Richard M. Stallman committed
559

560
        case 't':
561 562
	  tty = true;
	  create_frame = true;
563 564
          break;

565
        case 'c':
566
	  create_frame = true;
567
          break;
568

569 570
	case 'p':
	  parent_id = optarg;
571
	  create_frame = true;
572 573
	  break;

574 575
	case 'H':
	  print_help_and_exit ();
576 577
	  break;

578 579 580 581
        case 'F':
          frame_parameters = optarg;
          break;

582 583 584 585
        case 'T':
          tramp_prefix = optarg;
          break;

586
	default:
587
	  message (true, "Try '%s --help' for more information\n", progname);
588
	  exit (EXIT_FAILURE);
589
	  break;
590 591
	}
    }
592

593 594
  /* If the -c option is used (without -t) and no --display argument
     is provided, try $DISPLAY.
595
     Without the -c option, we used to set 'display' to $DISPLAY by
596 597
     default, but this changed the default behavior and is sometimes
     inconvenient.  So we force users to use "--display $DISPLAY" if
598 599 600 601 602 603
     they want Emacs to connect to their current display.

     Some window systems have a notion of default display not
     reflected in the DISPLAY variable.  If the user didn't give us an
     explicit display, try this platform-specific after trying the
     display in DISPLAY (if any).  */
604
  if (create_frame && !tty && !display)
605
    {
606 607 608 609 610
      /* Set these here so we use a default_display only when the user
         didn't give us an explicit display.  */
#if defined (NS_IMPL_COCOA)
      alt_display = "ns";
#elif defined (HAVE_NTGUI)
611
      alt_display = "w32";
612
#endif
613 614 615 616 617 618 619 620

      display = egetenv ("DISPLAY");
    }

  if (!display)
    {
      display = alt_display;
      alt_display = NULL;
621
    }
622

623
  /* A null-string display is invalid.  */
624
  if (display && !display[0])
625 626
    display = NULL;

627
  /* If no display is available, new frames are tty frames.  */
628 629
  if (create_frame && !display)
    tty = true;
630

631
#ifdef WINDOWSNT
632 633 634
  /* Emacs on Windows does not support graphical and text terminal
     frames in the same instance.  So, treat the -t and -c options as
     equivalent, and open a new frame on the server's terminal.
635
     Ideally, we would set tty = true only if the server is running in a
636 637
     console, but alas we don't know that.  As a workaround, always
     ask for a tty frame, and let server.el figure it out.  */
638
  if (create_frame)
639 640
    {
      display = NULL;
641
      tty = true;
642
    }
643
#endif /* WINDOWSNT */
644 645
}

646

647
static _Noreturn void
648
print_help_and_exit (void)
649
{
650 651 652 653
  /* Spaces and tabs are significant in this message; they're chosen so the
     message aligns properly both in a tty and in a Windows message box.
     Please try to preserve them; otherwise the output is very hard to read
     when using emacsclientw.  */
654
  message (false,
Paul Eggert's avatar
Paul Eggert committed
655
	   "Usage: %s [OPTIONS] FILE...\n%s%s%s", progname, "\
Stefan Monnier's avatar
Stefan Monnier committed
656 657
Tell the Emacs server to visit the specified files.\n\
Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
658
\n\
Stefan Monnier's avatar
Stefan Monnier committed
659
The following OPTIONS are accepted:\n\
660 661
-V, --version		Just print version info and return\n\
-H, --help    		Print this usage information message\n\
662
-nw, -t, --tty 		Open a new Emacs frame on the current terminal\n\
663
-c, --create-frame    	Create a new frame instead of trying to\n\
664
			use the current Emacs frame\n\
Paul Eggert's avatar
Paul Eggert committed
665
", "\
666
-F ALIST, --frame-parameters=ALIST\n\
667
			Set the parameters of a new frame\n\
668
-e, --eval    		Evaluate the FILE arguments as ELisp expressions\n\
669
-n, --no-wait		Don't wait for the server to return\n\
670
-q, --quiet		Don't display messages on success\n\
671
-u, --suppress-output   Don't display return values from the server\n\
672
-d DISPLAY, --display=DISPLAY\n\
673
			Visit the file in the given display\n\
Paul Eggert's avatar
Paul Eggert committed
674
", "\
675
--parent-id=ID          Open in parent window ID, via XEmbed\n"
676
#ifdef SOCKETS_IN_FILE_SYSTEM
677
"-s SOCKET, --socket-name=SOCKET\n\
678
			Set filename of the UNIX socket for communication\n"
679
#endif
680
"-f SERVER, --server-file=SERVER\n\
681
			Set filename of the TCP authentication file\n\
682
-a EDITOR, --alternate-editor=EDITOR\n\
683
			Editor to fallback to if the server is not running\n"
684 685
"			If EDITOR is the empty string, start Emacs in daemon\n\
			mode and try connecting again\n"
686 687 688
"-T PREFIX, --tramp=PREFIX\n\
                        PREFIX to prepend to filenames sent by emacsclient\n\
                        for locating files remotely via Tramp\n"
689
"\n\
Paul Eggert's avatar
Paul Eggert committed
690
Report bugs with M-x report-emacs-bug.\n");
691
  exit (EXIT_SUCCESS);
692
}
693

694
/* Try to run a different command, or --if no alternate editor is
695
   defined-- exit with an error code.
696 697
   Uses argv, but gets it from the global variable main_argv.  */

698
static _Noreturn void
699
fail (void)
700
{
701
  if (alternate_editor)
702
    {
703
      size_t extra_args_size = (main_argc - optind + 1) * sizeof (char *);
704
      size_t new_argv_size = extra_args_size;
705
      char **new_argv = xmalloc (new_argv_size);
706
      char *s = xstrdup (alternate_editor);
707
      ptrdiff_t toks = 0;
708 709 710 711 712 713

      /* Unpack alternate_editor's space-separated tokens into new_argv.  */
      for (char *tok = s; tok != NULL && *tok != '\0';)
        {
          /* Allocate new token.  */
          ++toks;
714 715
          new_argv = xrealloc (new_argv,
			       new_argv_size + toks * sizeof (char *));
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733

          /* Skip leading delimiters, and set separator, skipping any
             opening quote.  */
          size_t skip = strspn (tok, " \"");
          tok += skip;
          char sep = (skip > 0 && tok[-1] == '"') ? '"' : ' ';

          /* Record start of token.  */
          new_argv[toks - 1] = tok;

          /* Find end of token and overwrite it with NUL.  */
          tok = strchr (tok, sep);
          if (tok != NULL)
            *tok++ = '\0';
        }

      /* Append main_argv arguments to new_argv.  */
      memcpy (&new_argv[toks], main_argv + optind, extra_args_size);
734

735
      execvp (*new_argv, new_argv);
736
      message (true, "%s: error executing alternate editor \"%s\"\n",
737
	       progname, alternate_editor);
738
    }
739
  exit (EXIT_FAILURE);
740 741
}

742

743
#ifdef SOCKETS_IN_FILE_SYSTEM
744
static void act_on_signals (HSOCKET);
745
#else
746
static void act_on_signals (HSOCKET s) {}
747
static void init_signals (void) {}
748
#endif
749

750
enum { AUTH_KEY_LENGTH = 64 };
751

752
static void
753
sock_err_message (const char *function_name)
754
{
755
#ifdef WINDOWSNT
756 757 758 759 760 761 762
  /* On Windows, the socket library was historically separate from the
     standard C library, so errors are handled differently.  */

  if (w32_window_app () && alternate_editor)
    return;

  char *msg = NULL;
763 764 765 766 767 768

  FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
                 | FORMAT_MESSAGE_ALLOCATE_BUFFER
                 | FORMAT_MESSAGE_ARGUMENT_ARRAY,
                 NULL, WSAGetLastError (), 0, (LPTSTR)&msg, 0, NULL);

769
  message (true, "%s: %s: %s\n", progname, function_name, msg);
770 771

  LocalFree (msg);
772
#else
773
  message (true, "%s: %s: %s\n", progname, function_name, strerror (errno));
774
#endif
775 776 777
}


778 779
/* Send to S the data in *DATA when either
   - the data's last byte is '\n', or
780
   - the buffer is full (but this shouldn't happen)
781
   Otherwise, just accumulate the data.  */
782
static void
783
send_to_emacs (HSOCKET s, const char *data)
784
{
785 786 787 788 789 790 791 792
  enum { SEND_BUFFER_SIZE = 4096 };

  /* Buffer to accumulate data to send in TCP connections.  */
  static char send_buffer[SEND_BUFFER_SIZE + 1];

  /* Fill pointer for the send buffer.  */
  static int sblen;

Paul Eggert's avatar
Paul Eggert committed
793
  for (ptrdiff_t dlen = strlen (data); dlen != 0; )
794
    {
Paul Eggert's avatar
Paul Eggert committed
795
      int part = min (dlen, SEND_BUFFER_SIZE - sblen);
796 797 798
      memcpy (&send_buffer[sblen], data, part);
      data += part;
      sblen += part;
799 800

      if (sblen == SEND_BUFFER_SIZE
Paul Eggert's avatar
Paul Eggert committed
801
	  || (0 < sblen && send_buffer[sblen - 1] == '\n'))
802
	{
803 804
	  int sent;
	  while ((sent = send (s, send_buffer, sblen, 0)) < 0)
805
	    {
806 807 808 809 810 811 812 813 814 815
	      if (errno != EINTR)
		{
		  message (true, "%s: failed to send %d bytes to socket: %s\n",
			   progname, sblen, strerror (errno));
		  fail ();
		}
	      /* Act on signals not requiring communication to Emacs,
		 but defer action on the others to avoid confusing the
		 communication currently in progress.  */
	      act_on_signals (INVALID_SOCKET);
816
	    }
817
	  sblen -= sent;
818
	  memmove (send_buffer, &send_buffer[sent], sblen);
819
	}
820 821

      dlen -= part;
822 823 824 825
    }
}


826
/* In STR, insert a & before each &, each space, each newline, and
Richard M. Stallman's avatar
Richard M. Stallman committed
827
   any initial -.  Change spaces to underscores, too, so that the
828 829
   return value never contains a space.

Juanma Barranquero's avatar
Juanma Barranquero committed
830
   Does not change the string.  Outputs the result to S.  */
831
static void
832
quote_argument (HSOCKET s, const char *str)
833
{
834
  char *copy = xmalloc (strlen (str) * 2 + 1);
835 836 837 838
  char *q = copy;
  if (*str == '-')
    *q++ = '&', *q++ = *str++;
  for (; *str; str++)
839
    {
840 841 842 843 844 845 846 847
      char c = *str;
      if (c == ' ')
	*q++ = '&', c = '_';
      else if (c == '\n')
	*q++ = '&', c = 'n';
      else if (c == '&')
	*q++ = '&';
      *q++ = c;
848
    }
849
  *q = 0;
850

851
  send_to_emacs (s, copy);
852 853

  free (copy);
854
}
855

856

857 858
/* The inverse of quote_argument.  Remove quoting in string STR by
   modifying the addressed string in place.  Return STR.  */
859

860
static char *
861
unquote_argument (char *str)
862
{
863 864 865
  char const *p = str;
  char *q = str;
  char c;
866

867
  do
868
    {
869 870 871 872 873 874 875 876 877 878
      c = *p++;
      if (c == '&')
	{
	  c = *p++;
	  if (c == '_')
	    c = ' ';
	  else if (c == 'n')
	    c = '\n';
	}
      *q++ = c;
879
    }
880 881
  while (c);

882 883 884
  return str;
}

885

886
#ifdef WINDOWSNT
887
/* Wrapper to make WSACleanup a cdecl, as required by atexit.  */
888
void __cdecl close_winsock (void);
889 890
void __cdecl
close_winsock (void)
891 892 893
{
  WSACleanup ();
}
894

895
/* Initialize the WinSock2 library.  */
896
void initialize_sockets (void);
897
void
898
initialize_sockets (void)
899
{
900 901 902 903
  WSADATA wsaData;

  if (WSAStartup (MAKEWORD (2, 0), &wsaData))
    {
904
      message (true, "%s: error initializing WinSock2\n", progname);
905 906 907 908
      exit (EXIT_FAILURE);
    }

  atexit (close_winsock);
909
}
910
#endif /* WINDOWSNT */
911

912

913 914 915
/* If the home directory is HOME, and XDG_CONFIG_HOME's value is XDG,
   return the configuration file with basename CONFIG_FILE.  Fail if
   the configuration file could not be opened.  */
916 917

static FILE *
918
open_config (char const *home, char const *xdg, char const *config_file)
919
{
920 921 922 923 924 925 926
  ptrdiff_t xdgsubdirsize = xdg ? strlen (xdg) + sizeof "/emacs/server/" : 0;
  ptrdiff_t homesuffixsizemax = max (sizeof "/.config/emacs/server/",
				     sizeof "/.emacs.d/server/");
  ptrdiff_t homesubdirsizemax = home ? strlen (home) + homesuffixsizemax : 0;
  char *configname = xmalloc (max (xdgsubdirsize, homesubdirsizemax)
			      + strlen (config_file));
  FILE *config;
927 928

  if (home)
929
    {
930 931
      strcpy (stpcpy (stpcpy (configname, home), "/.emacs.d/server/"),
              config_file);
932 933 934 935 936
      config = fopen (configname, "rb");
    }
  else
    config = NULL;

937
  if (! config && (xdg || home))
938
    {
939 940 941 942
      strcpy ((xdg
               ? stpcpy (stpcpy (configname, xdg), "/emacs/server/")
               : stpcpy (stpcpy (configname, home), "/.config/emacs/server/")),
              config_file);
943 944 945
      config = fopen (configname, "rb");
    }