Update of /cvsroot/tmux/tmux
In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv15654

Modified Files:
        client.c server.c tmux.c tmux.h 
Log Message:
Sync OpenBSD patchset 777:

Merge the before and after attach client code into one in client.c
(instead of two in tmux.c and client.c).


Index: client.c
===================================================================
RCS file: /cvsroot/tmux/tmux/client.c,v
retrieving revision 1.98
retrieving revision 1.99
diff -u -d -r1.98 -r1.99
--- client.c    24 Oct 2010 00:45:57 -0000      1.98
+++ client.c    24 Oct 2010 01:31:08 -0000      1.99
@@ -28,7 +28,6 @@
 #include <pwd.h>
 #include <stdlib.h>
 #include <string.h>
-#include <syslog.h>
 #include <unistd.h>
 
 #include "tmux.h"
@@ -37,81 +36,171 @@
 struct event   client_event;
 const char     *client_exitmsg;
 int            client_exitval;
+int            client_attached;
 
+int            client_connect(char *, int);
 void           client_send_identify(int);
 void           client_send_environ(void);
 void           client_write_server(enum msgtype, void *, size_t);
 void           client_update_event(void);
 void           client_signal(int, short, void *);
 void           client_callback(int, short, void *);
-int            client_dispatch(void);
+int            client_dispatch_attached(void);
+int            client_dispatch_wait(void *);
 
-struct imsgbuf *
-client_init(char *path, int cmdflags, int flags)
+/* Connect client to server. */
+int
+client_connect(char *path, int start_server)
 {
        struct sockaddr_un      sa;
        size_t                  size;
        int                     fd, mode;
-#ifdef HAVE_SETPROCTITLE
-       char                    rpathbuf[MAXPATHLEN];
-#endif
-
-#ifdef HAVE_SETPROCTITLE
-       if (realpath(path, rpathbuf) == NULL)
-               strlcpy(rpathbuf, path, sizeof rpathbuf);
-       setproctitle("client (%s)", rpathbuf);
-#endif
 
        memset(&sa, 0, sizeof sa);
        sa.sun_family = AF_UNIX;
        size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
        if (size >= sizeof sa.sun_path) {
                errno = ENAMETOOLONG;
-               goto not_found;
+               return (-1);
        }
 
        if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
                fatal("socket failed");
 
        if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
-               if (!(cmdflags & CMD_STARTSERVER))
-                       goto not_found;
+               if (!start_server)
+                       goto failed;
                switch (errno) {
                case ECONNREFUSED:
                        if (unlink(path) != 0)
-                               goto not_found;
+                               goto failed;
                        /* FALLTHROUGH */
                case ENOENT:
-                       if ((fd = server_start(path)) == -1)
-                               goto start_failed;
-                       goto server_started;
+                       if ((fd = server_start()) == -1)
+                               goto failed;
+                       break;
+               default:
+                       goto failed;
                }
-               goto not_found;
        }
 
-server_started:
        if ((mode = fcntl(fd, F_GETFL)) == -1)
                fatal("fcntl failed");
        if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
                fatal("fcntl failed");
+       return (fd);
+
+failed:
+       close(fd);
+       return (-1);
+}
+
+/* Client main loop. */
+int
+client_main(int argc, char **argv, int flags)
+{
+       struct cmd              *cmd;
+       struct cmd_list         *cmdlist;
+       struct msg_command_data  cmddata;
+       int                      cmdflags, fd;
+       enum msgtype             msg;
+       char                    *cause;
+
+       /* Set up the initial command. */
+       cmdflags = 0;
+       if (shell_cmd != NULL) {
+               msg = MSG_SHELL;
+               cmdflags = CMD_STARTSERVER;
+       } else if (argc == 0) {
+               msg = MSG_COMMAND;
+               cmdflags = CMD_STARTSERVER|CMD_SENDENVIRON|CMD_CANTNEST;
+       } else {
+               msg = MSG_COMMAND;
+
+               /*
+                * It sucks parsing the command string twice (in client and
+                * later in server) but it is necessary to get the start server
+                * flag.
+                */
+               if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
+                       log_warnx("%s", cause);
+                       return (1);
+               }
+               cmdflags &= ~CMD_STARTSERVER;
+               TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
+                       if (cmd->entry->flags & CMD_STARTSERVER)
+                               cmdflags |= CMD_STARTSERVER;
+                       if (cmd->entry->flags & CMD_SENDENVIRON)
+                               cmdflags |= CMD_SENDENVIRON;
+                       if (cmd->entry->flags & CMD_CANTNEST)
+                               cmdflags |= CMD_CANTNEST;
+               }
+               cmd_list_free(cmdlist);
+       }
+
+       /*
+        * Check if this could be a nested session, if the command can't nest:
+        * if the socket path matches $TMUX, this is probably the same server.
+        */
+       if (shell_cmd == NULL && environ_path != NULL &&
+           cmdflags & CMD_CANTNEST && strcmp(socket_path, environ_path) == 0) {
+               log_warnx("sessions should be nested with care. "
+                   "unset $TMUX to force.");
+               return (1);
+       }
+
+       /* Initialise the client socket and start the server. */
+       fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
+       if (fd == -1) {
+               log_warn("failed to connect to server");
+               return (1);
+       }
+
+       /* Set process title, log and signals now this is the client. */
+       setproctitle("client (%s)", socket_path);
+       logfile("client");
+
+       /* Create imsg. */
        imsg_init(&client_ibuf, fd);
-       event_set(&client_event, fd, EV_READ, client_callback, NULL);
+       event_set(&client_event, fd, EV_READ, client_callback, shell_cmd);
 
+       /* Establish signal handlers. */
+       set_signals(client_signal);
+
+       /* Send initial environment. */
        if (cmdflags & CMD_SENDENVIRON)
                client_send_environ();
        client_send_identify(flags);
 
-       return (&client_ibuf);
+       /* Send first command. */
+       if (msg == MSG_COMMAND) {
+               /* Fill in command line arguments. */
+               cmddata.pid = environ_pid;
+               cmddata.idx = environ_idx;
 
-start_failed:
-       log_warnx("server failed to start");
-       return (NULL);
+               /* Prepare command for server. */
+               cmddata.argc = argc;
+               if (cmd_pack_argv(
+                   argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
+                       log_warnx("command too long");
+                       return (1);
+               }
 
-not_found:
-       log_warn("server not found");
-       return (NULL);
+               client_write_server(msg, &cmddata, sizeof cmddata);
+       } else if (msg == MSG_SHELL)
+               client_write_server(msg, NULL, 0);
+
+       /* Set the event and dispatch. */
+       client_update_event();
+       event_dispatch();
+
+       /* Print the exit message, if any, and exit. */
+       if (client_attached && client_exitmsg != NULL && !login_shell)
+               printf("[%s]\n", client_exitmsg);
+       return (client_exitval);
 }
 
+/* Send identify message to server with the file descriptors. */
 void
 client_send_identify(int flags)
 {
@@ -136,13 +225,16 @@
 
        if ((fd = dup(STDOUT_FILENO)) == -1)
                fatal("dup failed");
-       imsg_compose(&client_ibuf, MSG_STDOUT, PROTOCOL_VERSION, -1, fd, NULL, 
0);
+       imsg_compose(&client_ibuf,
+           MSG_STDOUT, PROTOCOL_VERSION, -1, fd, NULL, 0);
 
        if ((fd = dup(STDERR_FILENO)) == -1)
                fatal("dup failed");
-       imsg_compose(&client_ibuf, MSG_STDERR, PROTOCOL_VERSION, -1, fd, NULL, 
0);
+       imsg_compose(&client_ibuf,
+           MSG_STDERR, PROTOCOL_VERSION, -1, fd, NULL, 0);
 }
 
+/* Forward entire environment to server. */
 void
 client_send_environ(void)
 {
@@ -156,12 +248,14 @@
        }
 }
 
+/* Write a message to the server without a file descriptor. */
 void
 client_write_server(enum msgtype type, void *buf, size_t len)
 {
        imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
 }
 
+/* Update client event based on whether it needs to read or read and write. */
 void
 client_update_event(void)
 {
@@ -171,91 +265,74 @@
        events = EV_READ;
        if (client_ibuf.w.queued > 0)
                events |= EV_WRITE;
-       event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
+       event_set(
+           &client_event, client_ibuf.fd, events, client_callback, shell_cmd);
        event_add(&client_event, NULL);
 }
 
-__dead void
-client_main(void)
-{
-       logfile("client");
-
-       /* Note: event_init() has already been called. */
-
-       /* Set up signals. */
-       set_signals(client_signal);
-
-       /*
-        * Send a resize message immediately in case the terminal size has
-        * changed between the identify message to the server and the MSG_READY
-        * telling us to move into the client code.
-        */
-        client_write_server(MSG_RESIZE, NULL, 0);
-
-       /*
-        * imsg_read in the first client poll loop (before the terminal has
-        * been initialised) may have read messages into the buffer after the
-        * MSG_READY switched to here. Process anything outstanding now to
-        * avoid hanging waiting for messages that have already arrived.
-        */
-       if (client_dispatch() != 0)
-               goto out;
-
-       /* Set the event and dispatch. */
-       client_update_event();
-       event_dispatch();
-
-out:
-       /* Print the exit message, if any, and exit. */
-       if (client_exitmsg != NULL && !login_shell)
-               printf("[%s]\n", client_exitmsg);
-       exit(client_exitval);
-}
-
+/* Callback to handle signals in the client. */
 /* ARGSUSED */
 void
 client_signal(int sig, unused short events, unused void *data)
 {
-       struct sigaction        sigact;
+       struct sigaction sigact;
+       int              status;
 
-       switch (sig) {
-       case SIGHUP:
-               client_exitmsg = "lost tty";
-               client_exitval = 1;
-               client_write_server(MSG_EXITING, NULL, 0);
-               break;
-       case SIGTERM:
-               client_exitmsg = "terminated";
-               client_exitval = 1;
-               client_write_server(MSG_EXITING, NULL, 0);
-               break;
-       case SIGWINCH:
-               client_write_server(MSG_RESIZE, NULL, 0);
-               break;
-       case SIGCONT:
-               memset(&sigact, 0, sizeof sigact);
-               sigemptyset(&sigact.sa_mask);
-               sigact.sa_flags = SA_RESTART;
-               sigact.sa_handler = SIG_IGN;
-               if (sigaction(SIGTSTP, &sigact, NULL) != 0)
-                       fatal("sigaction failed");
-               client_write_server(MSG_WAKEUP, NULL, 0);
-               break;
+       if (!client_attached) {
+               switch (sig) {
+               case SIGCHLD:
+                       waitpid(WAIT_ANY, &status, WNOHANG);
+                       break;
+               case SIGTERM:
+                       event_loopexit(NULL);
+                       break;
+               }
+       } else {
+               switch (sig) {
+               case SIGHUP:
+                       client_exitmsg = "lost tty";
+                       client_exitval = 1;
+                       client_write_server(MSG_EXITING, NULL, 0);
+                       break;
+               case SIGTERM:
+                       client_exitmsg = "terminated";
+                       client_exitval = 1;
+                       client_write_server(MSG_EXITING, NULL, 0);
+                       break;
+               case SIGWINCH:
+                       client_write_server(MSG_RESIZE, NULL, 0);
+                       break;
+               case SIGCONT:
+                       memset(&sigact, 0, sizeof sigact);
+                       sigemptyset(&sigact.sa_mask);
+                       sigact.sa_flags = SA_RESTART;
+                       sigact.sa_handler = SIG_IGN;
+                       if (sigaction(SIGTSTP, &sigact, NULL) != 0)
+                               fatal("sigaction failed");
+                       client_write_server(MSG_WAKEUP, NULL, 0);
+                       break;
+               }
        }
 
        client_update_event();
 }
 
+/* Callback for client imsg read events. */
 /* ARGSUSED */
 void
-client_callback(unused int fd, short events, unused void *data)
+client_callback(unused int fd, short events, void *data)
 {
        ssize_t n;
+       int     retval;
 
        if (events & EV_READ) {
                if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
                        goto lost_server;
-               if (client_dispatch() != 0) {
+               if (client_attached)
+                       retval = client_dispatch_attached();
+               else
+                       retval = client_dispatch_wait(data);
+               if (retval != 0) {
                        event_loopexit(NULL);
                        return;
                }
@@ -275,8 +352,76 @@
        event_loopexit(NULL);
 }
 
+/* Dispatch imsgs when in wait state (before MSG_READY). */
 int
-client_dispatch(void)
+client_dispatch_wait(void *data)
+{
+       struct imsg             imsg;
+       ssize_t                 n, datalen;
+       struct msg_shell_data   shelldata;
+       struct msg_exit_data    exitdata;
+       const char             *shellcmd = data;
+
+       if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
+               fatalx("imsg_read failed");
+
+       for (;;) {
+               if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
+                       fatalx("imsg_get failed");
+               if (n == 0)
+                       return (0);
+               datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+
+               switch (imsg.hdr.type) {
+               case MSG_EXIT:
+               case MSG_SHUTDOWN:
+                       if (datalen != sizeof exitdata) {
+                               if (datalen != 0)
+                                       fatalx("bad MSG_EXIT size");
+                       } else {
+                               memcpy(&exitdata, imsg.data, sizeof exitdata);
+                               client_exitval = exitdata.retcode;
+                       }
+                       imsg_free(&imsg);
+                       return (-1);
+               case MSG_READY:
+                       if (datalen != 0)
+                               fatalx("bad MSG_READY size");
+
+                       client_attached = 1;
+                       break;
+               case MSG_VERSION:
+                       if (datalen != 0)
+                               fatalx("bad MSG_VERSION size");
+
+                       log_warnx("protocol version mismatch (client %u, "
+                           "server %u)", PROTOCOL_VERSION, imsg.hdr.peerid);
+                       client_exitval = 1;
+
+                       imsg_free(&imsg);
+                       return (-1);
+               case MSG_SHELL:
+                       if (datalen != sizeof shelldata)
+                               fatalx("bad MSG_SHELL size");
+                       memcpy(&shelldata, imsg.data, sizeof shelldata);
+                       shelldata.shell[(sizeof shelldata.shell) - 1] = '\0';
+
+                       clear_signals(0);
+
+                       shell_exec(shelldata.shell, shellcmd);
+                       /* NOTREACHED */
+               default:
+                       fatalx("unexpected message");
+               }
+
+               imsg_free(&imsg);
+       }
+}
+
+/* Dispatch imsgs in attached state (after MSG_READY). */
+/* ARGSUSED */
+int
+client_dispatch_attached(void)
 {
        struct imsg             imsg;
        struct msg_lock_data    lockdata;

Index: server.c
===================================================================
RCS file: /cvsroot/tmux/tmux/server.c,v
retrieving revision 1.246
retrieving revision 1.247
diff -u -d -r1.246 -r1.247
--- server.c    24 Oct 2010 00:45:57 -0000      1.246
+++ server.c    24 Oct 2010 01:31:08 -0000      1.247
@@ -105,16 +105,13 @@
 
 /* Fork new server. */
 int
-server_start(char *path)
+server_start(void)
 {
        struct window_pane      *wp;
        int                      pair[2];
        char                    *cause;
        struct timeval           tv;
        u_int                    i;
-#ifdef HAVE_SETPROCTITLE
-       char                     rpathbuf[MAXPATHLEN];
-#endif
 
        /* The first client is special and gets a socketpair; create it. */
        if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
@@ -157,14 +154,8 @@
        utf8_build();
 
        start_time = time(NULL);
-       socket_path = path;
-
-#ifdef HAVE_SETPROCTITLE
-       if (realpath(socket_path, rpathbuf) == NULL)
-               strlcpy(rpathbuf, socket_path, sizeof rpathbuf);
        log_debug("socket path %s", socket_path);
-       setproctitle("server (%s)", rpathbuf);
-#endif
+       setproctitle("server (%s)", socket_path);
 
        server_fd = server_create_socket();
        server_client_create(pair[1]);

Index: tmux.c
===================================================================
RCS file: /cvsroot/tmux/tmux/tmux.c,v
retrieving revision 1.219
retrieving revision 1.220
diff -u -d -r1.219 -r1.220
--- tmux.c      24 Oct 2010 00:47:46 -0000      1.219
+++ tmux.c      24 Oct 2010 01:31:08 -0000      1.220
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.c,v 1.91 2010/10/16 08:42:35 nicm Exp $ */
+/* $Id$ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -18,16 +18,13 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/wait.h>
 
 #include <errno.h>
 #include <event.h>
 #include <fcntl.h>
 #include <pwd.h>
-#include <signal.h>
 #include <stdlib.h>
 #include <string.h>
-#include <syslog.h>
 #include <unistd.h>
 
 #include "tmux.h"
@@ -36,7 +33,6 @@
 extern char    *malloc_options;
 #endif
 
-char           *cfg_file;
 struct options  global_options;        /* server options */
 struct options  global_s_options;      /* session options */
 struct options  global_w_options;      /* window options */
@@ -44,28 +40,19 @@
 
 struct event_base *ev_base;
 
+char           *cfg_file;
+char           *shell_cmd;
 int             debug_level;
 time_t          start_time;
-char           *socket_path;
+char            socket_path[MAXPATHLEN];
 int             login_shell;
-
-struct env_data {
-       char    *path;
-       pid_t    pid;
-       u_int    idx;
-};
+char           *environ_path;
+pid_t           environ_pid;
+u_int           environ_idx;
 
 __dead void     usage(void);
-void            parse_env(struct env_data *);
-char           *makesockpath(const char *);
-__dead void     shell_exec(const char *, const char *);
-
-struct imsgbuf *main_ibuf;
-struct event    main_event;
-
-void            main_signal(int, short, unused void *);
-void            main_callback(int, short, void *);
-void            main_dispatch(const char *);
+void            parseenvironment(void);
+char           *makesocketpath(const char *);
 
 #ifndef HAVE_PROGNAME
 char      *__progname = (char *) "tmux";
@@ -139,14 +126,14 @@
 }
 
 void
-parse_env(struct env_data *data)
+parseenvironment(void)
 {
        char            *env, *path_pid, *pid_idx, buf[256];
        size_t           len;
        const char      *errstr;
        long long        ll;
 
-       data->pid = -1;
+       environ_pid = -1;
        if ((env = getenv("TMUX")) == NULL)
                return;
 
@@ -159,9 +146,9 @@
 
        /* path */
        len = path_pid - env;
-       data->path = xmalloc (len + 1);
-       memcpy(data->path, env, len);
-       data->path[len] = '\0';
+       environ_path = xmalloc(len + 1);
+       memcpy(environ_path, env, len);
+       environ_path[len] = '\0';
 
        /* pid */
        len = pid_idx - path_pid - 1;
@@ -173,17 +160,17 @@
        ll = strtonum(buf, 0, LONG_MAX, &errstr);
        if (errstr != NULL)
                return;
-       data->pid = ll;
+       environ_pid = ll;
 
        /* idx */
-       ll = strtonum(pid_idx+1, 0, UINT_MAX, &errstr);
+       ll = strtonum(pid_idx + 1, 0, UINT_MAX, &errstr);
        if (errstr != NULL)
                return;
-       data->idx = ll;
+       environ_idx = ll;
 }
 
 char *
-makesockpath(const char *label)
+makesocketpath(const char *label)
 {
        char            base[MAXPATHLEN], *path;
        struct stat     sb;
@@ -243,28 +230,18 @@
 int
 main(int argc, char **argv)
 {
-       struct cmd_list         *cmdlist;
-       struct cmd              *cmd;
-       enum msgtype             msg;
-       struct passwd           *pw;
-       struct options          *oo, *so, *wo;
-       struct keylist          *keylist;
-       struct env_data          envdata;
-       struct msg_command_data  cmddata;
-       char                    *s, *shellcmd, *path, *label, *home, *cause;
-       char                   **var;
-       void                    *buf;
-       size_t                   len;
-       int                      opt, flags, quiet = 0, cmdflags = 0;
-       short                    events;
+       struct passwd   *pw;
+       struct options  *oo, *so, *wo;
+       struct keylist  *keylist;
+       char            *s, *path, *label, *home, **var;
+       int              opt, flags, quiet = 0;
 
 #if defined(DEBUG) && defined(__OpenBSD__)
        malloc_options = (char *) "AFGJPX";
 #endif
 
        flags = 0;
-       shellcmd = label = path = NULL;
-       envdata.path = NULL;
+       label = path = NULL;
        login_shell = (**argv == '-');
        while ((opt = getopt(argc, argv, "28c:df:lL:qS:uUv")) != -1) {
                switch (opt) {
@@ -277,9 +254,9 @@
                        flags &= ~IDENTIFY_256COLOURS;
                        break;
                case 'c':
-                       if (shellcmd != NULL)
-                               xfree(shellcmd);
-                       shellcmd = xstrdup(optarg);
+                       if (shell_cmd != NULL)
+                               xfree(shell_cmd);
+                       shell_cmd = xstrdup(optarg);
                        break;
                case 'f':
                        if (cfg_file != NULL)
@@ -315,7 +292,7 @@
        argc -= optind;
        argv += optind;
 
-       if (shellcmd != NULL && argc != 0)
+       if (shell_cmd != NULL && argc != 0)
                usage();
 
        log_open_tty(debug_level);
@@ -451,6 +428,7 @@
                options_set_number(wo, "utf8", 0);
        }
 
+       /* Locate the configuration file. */
        if (cfg_file == NULL) {
                home = getenv("HOME");
                if (home == NULL || *home == '\0') {
@@ -466,21 +444,22 @@
        }
 
        /*
-        * Figure out the socket path. If specified on the command-line with
-        * -S or -L, use it, otherwise try $TMUX or assume -L default.
+        * Figure out the socket path. If specified on the command-line with -S
+        * or -L, use it, otherwise try $TMUX or assume -L default.
         */
-       parse_env(&envdata);
+       parseenvironment();
        if (path == NULL) {
-               /* No -L. Try $TMUX, or default. */
+               /* If no -L, use the environment. */
                if (label == NULL) {
-                       path = envdata.path;
-                       if (path == NULL)
+                       if (environ_path != NULL)
+                               path = xstrdup(environ_path);
+                       else
                                label = xstrdup("default");
                }
 
                /* -L or default set. */
                if (label != NULL) {
-                       if ((path = makesockpath(label)) == NULL) {
+                       if ((path = makesocketpath(label)) == NULL) {
                                log_warn("can't create socket");
                                exit(1);
                        }
@@ -488,66 +467,14 @@
        }
        if (label != NULL)
                xfree(label);
+       if (realpath(path, socket_path) == NULL)
+               strlcpy(socket_path, path, sizeof socket_path);
+       xfree(path);
 
-       if (shellcmd != NULL) {
-               msg = MSG_SHELL;
-               buf = NULL;
-               len = 0;
-       } else {
-               cmddata.pid = envdata.pid;
-               cmddata.idx = envdata.idx;
-
-               /* Prepare command for server. */
-               cmddata.argc = argc;
-               if (cmd_pack_argv(
-                   argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
-                       log_warnx("command too long");
-                       exit(1);
-               }
-
-               msg = MSG_COMMAND;
-               buf = &cmddata;
-               len = sizeof cmddata;
-       }
-
-       if (shellcmd != NULL)
-               cmdflags |= CMD_STARTSERVER;
-       else if (argc == 0)     /* new-session is the default */
-               cmdflags |= CMD_STARTSERVER|CMD_SENDENVIRON|CMD_CANTNEST;
-       else {
-               /*
-                * It sucks parsing the command string twice (in client and
-                * later in server) but it is necessary to get the start server
-                * flag.
-                */
-               if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
-                       log_warnx("%s", cause);
-                       exit(1);
-               }
-               cmdflags &= ~CMD_STARTSERVER;
-               TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
-                       if (cmd->entry->flags & CMD_STARTSERVER)
-                               cmdflags |= CMD_STARTSERVER;
-                       if (cmd->entry->flags & CMD_SENDENVIRON)
-                               cmdflags |= CMD_SENDENVIRON;
-                       if (cmd->entry->flags & CMD_CANTNEST)
-                               cmdflags |= CMD_CANTNEST;
-               }
-               cmd_list_free(cmdlist);
-       }
-
-       /*
-        * Check if this could be a nested session, if the command can't nest:
-        * if the socket path matches $TMUX, this is probably the same server.
-        */
-       if (shellcmd == NULL && envdata.path != NULL &&
-           cmdflags & CMD_CANTNEST &&
-           (path == envdata.path || strcmp(path, envdata.path) == 0)) {
-               log_warnx("sessions should be nested with care. "
-                   "unset $TMUX to force.");
-               exit(1);
-       }
+       /* Set process title. */
+       setproctitle("%s (%s)", __progname, socket_path);
 
+       /* Pass control to the client. */
 #ifdef HAVE_BROKEN_KQUEUE
        if (setenv("EVENT_NOKQUEUE", "1", 1) != 0)
                fatal("setenv failed");
@@ -563,120 +490,5 @@
 #ifdef HAVE_BROKEN_POLL
        unsetenv("EVENT_NOPOLL");
 #endif
-       set_signals(main_signal);
-
-       /* Initialise the client socket/start the server. */
-       if ((main_ibuf = client_init(path, cmdflags, flags)) == NULL)
-               exit(1);
-       xfree(path);
-
-       imsg_compose(main_ibuf, msg, PROTOCOL_VERSION, -1, -1, buf, len);
-
-       events = EV_READ;
-       if (main_ibuf->w.queued > 0)
-               events |= EV_WRITE;
-       event_set(&main_event, main_ibuf->fd, events, main_callback, shellcmd);
-       event_add(&main_event, NULL);
-
-       event_dispatch();
-
-       event_del(&main_event);
-
-       clear_signals(0);
-       client_main();  /* doesn't return */
-}
-
-/* ARGSUSED */
-void
-main_signal(int sig, unused short events, unused void *data)
-{
-       int     status;
-
-       switch (sig) {
-       case SIGTERM:
-               exit(1);
-       case SIGCHLD:
-               waitpid(WAIT_ANY, &status, WNOHANG);
-               break;
-       }
-}
-
-/* ARGSUSED */
-void
-main_callback(unused int fd, short events, void *data)
-{
-       char    *shellcmd = data;
-
-       if (events & EV_READ)
-               main_dispatch(shellcmd);
-
-       if (events & EV_WRITE) {
-               if (msgbuf_write(&main_ibuf->w) < 0)
-                       fatalx("msgbuf_write failed");
-       }
-
-       event_del(&main_event);
-       events = EV_READ;
-       if (main_ibuf->w.queued > 0)
-               events |= EV_WRITE;
-       event_set(&main_event, main_ibuf->fd, events, main_callback, shellcmd);
-       event_add(&main_event, NULL);
-}
-
-void
-main_dispatch(const char *shellcmd)
-{
-       struct imsg             imsg;
-       ssize_t                 n, datalen;
-       struct msg_shell_data   shelldata;
-       struct msg_exit_data    exitdata;
-
-       if ((n = imsg_read(main_ibuf)) == -1 || n == 0)
-               fatalx("imsg_read failed");
-
-       for (;;) {
-               if ((n = imsg_get(main_ibuf, &imsg)) == -1)
-                       fatalx("imsg_get failed");
-               if (n == 0)
-                       return;
-               datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
-
-               switch (imsg.hdr.type) {
-               case MSG_EXIT:
-               case MSG_SHUTDOWN:
-                       if (datalen != sizeof exitdata) {
-                               if (datalen != 0)
-                                       fatalx("bad MSG_EXIT size");
-                               exit(0);
-                       }
-                       memcpy(&exitdata, imsg.data, sizeof exitdata);
-                       exit(exitdata.retcode);
-               case MSG_READY:
-                       if (datalen != 0)
-                               fatalx("bad MSG_READY size");
-
-                       event_loopexit(NULL);   /* move to client_main() */
-                       break;
-               case MSG_VERSION:
-                       if (datalen != 0)
-                               fatalx("bad MSG_VERSION size");
-
-                       log_warnx("protocol version mismatch (client %u, "
-                           "server %u)", PROTOCOL_VERSION, imsg.hdr.peerid);
-                       exit(1);
-               case MSG_SHELL:
-                       if (datalen != sizeof shelldata)
-                               fatalx("bad MSG_SHELL size");
-                       memcpy(&shelldata, imsg.data, sizeof shelldata);
-                       shelldata.shell[(sizeof shelldata.shell) - 1] = '\0';
-
-                       clear_signals(0);
-
-                       shell_exec(shelldata.shell, shellcmd);
-               default:
-                       fatalx("unexpected message");
-               }
-
-               imsg_free(&imsg);
-       }
+       exit(client_main(argc, argv, flags));
 }

Index: tmux.h
===================================================================
RCS file: /cvsroot/tmux/tmux/tmux.h,v
retrieving revision 1.579
retrieving revision 1.580
diff -u -d -r1.579 -r1.580
--- tmux.h      9 Oct 2010 14:30:26 -0000       1.579
+++ tmux.h      24 Oct 2010 01:31:08 -0000      1.580
@@ -1289,15 +1289,19 @@
 extern struct environ global_environ;
 extern struct event_base *ev_base;
 extern char    *cfg_file;
+extern char    *shell_cmd;
 extern int      debug_level;
-extern int      be_quiet;
 extern time_t   start_time;
-extern char    *socket_path;
+extern char     socket_path[MAXPATHLEN];
 extern int      login_shell;
+extern char    *environ_path;
+extern pid_t    environ_pid;
+extern u_int    environ_idx;
 void            logfile(const char *);
 const char     *getshell(void);
 int             checkshell(const char *);
 int             areshell(const char *);
+__dead void     shell_exec(const char *, const char *);
 
 /* cfg.c */
 extern int       cfg_finished;
@@ -1596,8 +1600,7 @@
 size_t cmd_buffer_print(struct cmd *, char *, size_t);
 
 /* client.c */
-struct imsgbuf *client_init(char *, int, int);
-__dead void    client_main(void);
+int    client_main(int, char **, int);
 
 /* key-bindings.c */
 extern struct key_bindings key_bindings;
@@ -1620,7 +1623,7 @@
 /* server.c */
 extern struct clients clients;
 extern struct clients dead_clients;
-int     server_start(char *);
+int     server_start(void);
 void    server_update_socket(void);
 
 /* server-client.c */


------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in  U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store 
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to