diff options
Diffstat (limited to 'lib-src')
-rw-r--r-- | lib-src/b2m.pl | 2 | ||||
-rw-r--r-- | lib-src/emacsclient.c | 446 | ||||
-rwxr-xr-x | lib-src/rcs2log | 2 | ||||
-rwxr-xr-x | lib-src/vcdiff | 2 |
4 files changed, 374 insertions, 78 deletions
diff --git a/lib-src/b2m.pl b/lib-src/b2m.pl index 38eb96e076f..ce547e0dd81 100644 --- a/lib-src/b2m.pl +++ b/lib-src/b2m.pl @@ -30,7 +30,7 @@ use Mail::Address; use Date::Parse; my($whoami) = basename $0; -my($version) = '$Revision: 1.5 $'; +my($version) = '$Revision: 1.6 $'; my($usage) = "Usage: $whoami [--help] [--version] [--[no]full-headers] [Babyl-file] \tBy default, full headers are printed.\n"; diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index c8b2596198f..79642cbe47e 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -41,6 +41,10 @@ Boston, MA 02111-1307, USA. */ # include <pwd.h> #endif /* not VMS */ +#include <signal.h> +#include <errno.h> + + char *getenv (), *getwd (); char *getcwd (); @@ -54,15 +58,27 @@ char *getcwd (); /* Name used to invoke this program. */ char *progname; +/* The first argument to main. */ +int main_argc; + +/* The second argument to main. */ +char **main_argv; + /* Nonzero means don't wait for a response from Emacs. --no-wait. */ int nowait = 0; /* Nonzero means args are expressions to be evaluated. --eval. */ int eval = 0; +/* Nonzero means open a new graphical frame. */ +int window_system = 0; + /* The display on which Emacs should work. --display. */ char *display = NULL; +/* Nonzero means open a new Emacs frame on the current terminal. */ +int tty = 0; + /* If non-NULL, the name of an editor to fallback to if the server is not running. --alternate-editor. */ const char * alternate_editor = NULL; @@ -78,6 +94,8 @@ struct option longopts[] = { "eval", no_argument, NULL, 'e' }, { "help", no_argument, NULL, 'H' }, { "version", no_argument, NULL, 'V' }, + { "tty", no_argument, NULL, 't' }, + { "current-frame", no_argument, NULL, 'c' }, { "alternate-editor", required_argument, NULL, 'a' }, { "socket-name", required_argument, NULL, 's' }, { "display", required_argument, NULL, 'd' }, @@ -93,11 +111,19 @@ decode_options (argc, argv) char **argv; { alternate_editor = getenv ("ALTERNATE_EDITOR"); + display = getenv ("DISPLAY"); + if (display && strlen (display) == 0) + display = NULL; + + if (display) + window_system = 1; + else + tty = 1; while (1) { int opt = getopt_long (argc, argv, - "VHnea:s:d:", longopts, 0); + "VHnea:s:d:tc", longopts, 0); if (opt == EOF) break; @@ -134,6 +160,16 @@ decode_options (argc, argv) exit (0); break; + case 't': + tty = 1; + window_system = 0; + break; + + case 'c': + window_system = 0; + tty = 0; + break; + case 'H': print_help_and_exit (); break; @@ -144,6 +180,11 @@ decode_options (argc, argv) break; } } + + if (tty) { + nowait = 0; + display = 0; + } } void @@ -157,6 +198,8 @@ Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\ The following OPTIONS are accepted:\n\ -V, --version Just print a version info and return\n\ -H, --help Print this usage information message\n\ +-t, --tty Open a new Emacs frame on the current terminal\n\ +-c, --current-frame Do not create a new frame; use the current Emacs frame\n\ -n, --no-wait Don't wait for the server to return\n\ -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ -d, --display=DISPLAY Visit the file in the given display\n\ @@ -169,19 +212,21 @@ Report bugs to bug-gnu-emacs@gnu.org.\n", progname); exit (0); } -/* In NAME, insert a & before each &, each space, each newline, and +/* In STR, insert a & before each &, each space, each newline, and any initial -. Change spaces to underscores, too, so that the - return value never contains a space. */ + return value never contains a space. + + Does not change the string. Outputs the result to STREAM. */ void -quote_file_name (name, stream) - char *name; +quote_argument (str, stream) + char *str; FILE *stream; { - char *copy = (char *) malloc (strlen (name) * 2 + 1); + char *copy = (char *) malloc (strlen (str) * 2 + 1); char *p, *q; - p = name; + p = str; q = copy; while (*p) { @@ -199,7 +244,7 @@ quote_file_name (name, stream) } else { - if (*p == '&' || (*p == '-' && p == name)) + if (*p == '&' || (*p == '-' && p == str)) *q++ = '&'; *q++ = *p++; } @@ -211,6 +256,41 @@ quote_file_name (name, stream) free (copy); } + +/* The inverse of quote_argument. Removes quoting in string STR by + modifying the string in place. Returns STR. */ + +char * +unquote_argument (str) + char *str; +{ + char *p, *q; + + if (! str) + return str; + + p = str; + q = str; + while (*p) + { + if (*p == '&') + { + p++; + if (*p == '&') + *p = '&'; + else if (*p == '_') + *p = ' '; + else if (*p == 'n') + *p = '\n'; + else if (*p == '-') + *p = '-'; + } + *q++ = *p++; + } + *q = 0; + return str; +} + /* Like malloc but get fatal error if memory is exhausted. */ long * @@ -231,14 +311,12 @@ xmalloc (size) defined-- exit with an errorcode. */ void -fail (argc, argv) - int argc; - char **argv; +fail (void) { if (alternate_editor) { int i = optind - 1; - execvp (alternate_editor, argv + i); + execvp (alternate_editor, main_argv + i); return; } else @@ -247,6 +325,101 @@ fail (argc, argv) } } +/* The process id of Emacs. */ +int emacs_pid; + +/* File handles for communicating with Emacs. */ +FILE *out, *in; + +/* A signal handler that passes the signal to the Emacs process. + Useful for SIGWINCH. */ + +SIGTYPE +pass_signal_to_emacs (int signalnum) +{ + int old_errno = errno; + + if (emacs_pid) + kill (emacs_pid, signalnum); + + signal (signalnum, pass_signal_to_emacs); + errno = old_errno; +} + +/* Signal handler for SIGCONT; notify the Emacs process that it can + now resume our tty frame. */ + +SIGTYPE +handle_sigcont (int signalnum) +{ + int old_errno = errno; + + if (tcgetpgrp (1) == getpgrp ()) + { + /* We are in the foreground. */ + fprintf (out, "-resume \n"); + fflush (out); + fsync (fileno (out)); + } + else + { + /* We are in the background; cancel the continue. */ + kill (getpid (), SIGSTOP); + } + errno = old_errno; +} + +/* Signal handler for SIGTSTP; notify the Emacs process that we are + going to sleep. Normally the suspend is initiated by Emacs via + server-handle-suspend-tty, but if the server gets out of sync with + reality, we may get a SIGTSTP on C-z. Handling this signal and + notifying Emacs about it should get things under control again. */ + +SIGTYPE +handle_sigtstp (int signalnum) +{ + int old_errno = errno; + sigset_t set; + + if (out) + { + fprintf (out, "-suspend \n"); + fflush (out); + fsync (fileno (out)); + } + + /* Unblock this signal and call the default handler by temprarily + changing the handler and resignalling. */ + sigprocmask (SIG_BLOCK, NULL, &set); + sigdelset (&set, signalnum); + signal (signalnum, SIG_DFL); + kill (getpid (), signalnum); + sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */ + signal (signalnum, handle_sigtstp); + + errno = old_errno; +} + +/* Set up signal handlers before opening a frame on the current tty. */ + +void +init_signals (void) +{ + /* Set up signal handlers. */ + signal (SIGWINCH, pass_signal_to_emacs); + + /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of + deciding which terminal the signal came from. C-g is now a + normal input event on secondary terminals. */ +#if 0 + signal (SIGINT, pass_signal_to_emacs); + signal (SIGQUIT, pass_signal_to_emacs); +#endif + + signal (SIGCONT, handle_sigcont); + signal (SIGTSTP, handle_sigtstp); + signal (SIGTTOU, handle_sigtstp); +} #if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM) @@ -260,7 +433,7 @@ main (argc, argv) argv[0]); fprintf (stderr, "on systems with Berkeley sockets.\n"); - fail (argc, argv); + fail (); } #else /* HAVE_SOCKETS */ @@ -294,23 +467,41 @@ socket_status (socket_name) return 0; } +/* Returns 1 if PREFIX is a prefix of STRING. */ +static int +strprefix (char *prefix, char *string) +{ + int i; + if (! prefix) + return 1; + + if (!string) + return 0; + + for (i = 0; prefix[i]; i++) + if (!string[i] || string[i] != prefix[i]) + return 0; + return 1; +} + int main (argc, argv) int argc; char **argv; { int s, i, needlf = 0; - FILE *out, *in; struct sockaddr_un server; char *cwd, *str; char string[BUFSIZ]; + main_argc = argc; + main_argv = argv; progname = argv[0]; /* Process options. */ decode_options (argc, argv); - if ((argc - optind < 1) && !eval) + if ((argc - optind < 1) && !eval && !tty && !window_system) { fprintf (stderr, "%s: file name or argument required\n", progname); fprintf (stderr, "Try `%s --help' for more information\n", progname); @@ -325,7 +516,7 @@ main (argc, argv) { fprintf (stderr, "%s: ", argv[0]); perror ("socket"); - fail (argc, argv); + fail (); } server.sun_family = AF_UNIX; @@ -333,30 +524,31 @@ main (argc, argv) { int sock_status = 0; int default_sock = !socket_name; - int saved_errno; - char *server_name = "server"; - - if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\')) - { /* socket_name is a file name component. */ - server_name = socket_name; - socket_name = NULL; - default_sock = 1; /* Try both UIDs. */ - } + int saved_errno = 0; + + char *server_name = "server"; + + if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\')) + { /* socket_name is a file name component. */ + server_name = socket_name; + socket_name = NULL; + default_sock = 1; /* Try both UIDs. */ + } - if (default_sock) + if (default_sock) { - socket_name = alloca (100 + strlen (server_name)); - sprintf (socket_name, "/tmp/emacs%d/%s", - (int) geteuid (), server_name); + socket_name = alloca (100 + strlen (server_name)); + sprintf (socket_name, "/tmp/emacs%d/%s", + (int) geteuid (), server_name); } if (strlen (socket_name) < sizeof (server.sun_path)) strcpy (server.sun_path, socket_name); else { - fprintf (stderr, "%s: socket-name %s too long", - argv[0], socket_name); - exit (1); + fprintf (stderr, "%s: socket-name %s too long", + argv[0], socket_name); + fail (); } /* See if the socket exists, and if it's owned by us. */ @@ -395,7 +587,7 @@ main (argc, argv) } sock_status = socket_status (server.sun_path); - saved_errno = errno; + saved_errno = errno; } else errno = saved_errno; @@ -410,7 +602,7 @@ main (argc, argv) if (0 != geteuid ()) { fprintf (stderr, "%s: Invalid socket owner\n", argv[0]); - fail (argc, argv); + fail (); } break; @@ -418,13 +610,13 @@ main (argc, argv) /* `stat' failed */ if (saved_errno == ENOENT) fprintf (stderr, - "%s: can't find socket; have you started the server?\n\ + "%s: Can't find socket; have you started the server?\n\ To start the server in Emacs, type \"M-x server-start\".\n", argv[0]); else - fprintf (stderr, "%s: can't stat %s: %s\n", + fprintf (stderr, "%s: Can't stat %s: %s\n", argv[0], server.sun_path, strerror (saved_errno)); - fail (argc, argv); + fail (); break; } } @@ -434,7 +626,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", { fprintf (stderr, "%s: ", argv[0]); perror ("connect"); - fail (argc, argv); + fail (); } /* We use the stream OUT to send our command to the server. */ @@ -442,7 +634,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", { fprintf (stderr, "%s: ", argv[0]); perror ("fdopen"); - fail (argc, argv); + fail (); } /* We use the stream IN to read the response. @@ -454,7 +646,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", { fprintf (stderr, "%s: ", argv[0]); perror ("fdopen"); - fail (argc, argv); + fail (); } #ifdef HAVE_GETCWD @@ -472,83 +664,187 @@ To start the server in Emacs, type \"M-x server-start\".\n", #else fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno)); #endif - fail (argc, argv); + fail (); } + /* First of all, send our version number for verification. */ + fprintf (out, "-version %s ", VERSION); + if (nowait) fprintf (out, "-nowait "); - if (eval) - fprintf (out, "-eval "); - if (display) { fprintf (out, "-display "); - quote_file_name (display, out); + quote_argument (display, out); fprintf (out, " "); } + if (tty) + { + char *tty_name = ttyname (fileno (stdin)); + char *type = getenv ("TERM"); + + if (! tty_name) + { + fprintf (stderr, "%s: could not get terminal name\n", progname); + fail (); + } + + if (! type) + { + fprintf (stderr, "%s: please set the TERM variable to your terminal type\n", + progname); + fail (); + } + + if (! strcmp (type, "eterm")) + { + /* This causes nasty, MULTI_KBOARD-related input lockouts. */ + fprintf (stderr, "%s: opening a frame in an Emacs term buffer" + " is not supported\n", progname); + fail (); + } + + init_signals (); + + fprintf (out, "-tty "); + quote_argument (tty_name, out); + fprintf (out, " "); + quote_argument (type, out); + fprintf (out, " "); + } + + if (window_system) + fprintf (out, "-window-system "); + if ((argc - optind > 0)) { for (i = optind; i < argc; i++) { + int relative = 0; + if (eval) - ; /* Don't prepend any cwd or anything like that. */ - else if (*argv[i] == '+') - { + { + /* Don't prepend any cwd or anything like that. */ + fprintf (out, "-eval "); + quote_argument (argv[i], out); + fprintf (out, " "); + continue; + } + + if (*argv[i] == '+') + { char *p = argv[i] + 1; while (isdigit ((unsigned char) *p) || *p == ':') p++; - if (*p != 0) - { - quote_file_name (cwd, out); - fprintf (out, "/"); - } - } - else if (*argv[i] != '/') - { - quote_file_name (cwd, out); - fprintf (out, "/"); - } - - quote_file_name (argv[i], out); - fprintf (out, " "); - } + if (*p == 0) + { + fprintf (out, "-position "); + quote_argument (argv[i], out); + fprintf (out, " "); + continue; + } + else + relative = 1; + } + else if (*argv[i] != '/') + relative = 1; + + fprintf (out, "-file "); + if (relative) + { + quote_argument (cwd, out); + fprintf (out, "/"); + } + quote_argument (argv[i], out); + fprintf (out, " "); + } } else { - while ((str = fgets (string, BUFSIZ, stdin))) - { - quote_file_name (str, out); - } - fprintf (out, " "); + if (!tty && !window_system) + { + while ((str = fgets (string, BUFSIZ, stdin))) + { + if (eval) + fprintf (out, "-eval "); + else + fprintf (out, "-file "); + quote_argument (str, out); + } + fprintf (out, " "); + } } - + fprintf (out, "\n"); fflush (out); + fsync (fileno (out)); /* Maybe wait for an answer. */ if (nowait) - return 0; + { + return 0; + } - if (!eval) + if (!eval && !tty) { printf ("Waiting for Emacs..."); needlf = 2; } fflush (stdout); + fsync (1); /* Now, wait for an answer and print any messages. */ while ((str = fgets (string, BUFSIZ, in))) { - if (needlf == 2) - printf ("\n"); - printf ("%s", str); - needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; + char *p = str + strlen (str) - 1; + while (p > str && *p == '\n') + *p-- = 0; + + if (strprefix ("-good-version ", str)) + { + /* OK, we got the green light. */ + } + else if (strprefix ("-emacs-pid ", str)) + { + emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10); + } + else if (strprefix ("-print ", str)) + { + str = unquote_argument (str + strlen ("-print ")); + if (needlf) + printf ("\n"); + printf ("%s", str); + needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; + } + else if (strprefix ("-error ", str)) + { + str = unquote_argument (str + strlen ("-error ")); + if (needlf) + printf ("\n"); + printf ("*ERROR*: %s", str); + needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; + } + else if (strprefix ("-suspend ", str)) + { + if (needlf) + printf ("\n"); + needlf = 0; + kill (0, SIGSTOP); + } + else + { + if (needlf) + printf ("\n"); + printf ("*ERROR*: Unknown message: %s", str); + needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; + } } if (needlf) printf ("\n"); fflush (stdout); + fsync (1); return 0; } diff --git a/lib-src/rcs2log b/lib-src/rcs2log index b7466b6c134..658a30c789b 100755 --- a/lib-src/rcs2log +++ b/lib-src/rcs2log @@ -29,7 +29,7 @@ Options: Report bugs to <bug-gnu-emacs@gnu.org>.' -Id='$Id: rcs2log,v 1.52 2003/12/27 08:18:08 uid65632 Exp $' +Id='$Id: rcs2log,v 1.53 2004/02/15 07:41:58 uid65632 Exp $' # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003, # 2004 Free Software Foundation, Inc. diff --git a/lib-src/vcdiff b/lib-src/vcdiff index 32c4e5ba89e..9e52a7f4c30 100755 --- a/lib-src/vcdiff +++ b/lib-src/vcdiff @@ -23,7 +23,7 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # -# $Id: vcdiff,v 1.7 2001/02/20 12:36:28 gerd Exp $ +# $Id: vcdiff,v 1.8 2003/09/01 15:45:03 miles Exp $ # DIFF="diff" |