From bef217b241ec50d6aed87dbb3604acd1bdb74121 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 24 Nov 2015 22:04:36 +0000 Subject: Switch a fprintf to a fatal, and wrap some long lines. --- client.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'client.c') diff --git a/client.c b/client.c index 53a98a30..fcb704fb 100644 --- a/client.c +++ b/client.c @@ -303,11 +303,8 @@ client_main(struct event_base *base, int argc, char **argv, int flags) event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST, client_stdin_callback, NULL); if (client_flags & CLIENT_CONTROLCONTROL) { - if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) { - fprintf(stderr, "tcgetattr failed: %s\n", - strerror(errno)); - return (1); - } + if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) + fatal("tcgetattr failed"); cfmakeraw(&tio); tio.c_iflag = ICRNL|IXANY; tio.c_oflag = OPOST|ONLCR; @@ -389,7 +386,8 @@ client_send_identify(const char *ttynam, const char *cwd) s = ""; proc_send(client_peer, MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1); - proc_send(client_peer, MSG_IDENTIFY_TTYNAME, -1, ttynam, strlen(ttynam) + 1); + proc_send(client_peer, MSG_IDENTIFY_TTYNAME, -1, ttynam, + strlen(ttynam) + 1); proc_send(client_peer, MSG_IDENTIFY_CWD, -1, cwd, strlen(cwd) + 1); if ((fd = dup(STDIN_FILENO)) == -1) @@ -401,8 +399,9 @@ client_send_identify(const char *ttynam, const char *cwd) for (ss = environ; *ss != NULL; ss++) { sslen = strlen(*ss) + 1; - if (sslen <= MAX_IMSGSIZE - IMSG_HEADER_SIZE) - proc_send(client_peer, MSG_IDENTIFY_ENVIRON, -1, *ss, sslen); + if (sslen > MAX_IMSGSIZE - IMSG_HEADER_SIZE) + continue; + proc_send(client_peer, MSG_IDENTIFY_ENVIRON, -1, *ss, sslen); } proc_send(client_peer, MSG_IDENTIFY_DONE, -1, NULL, 0); -- cgit v1.2.3 From c913fb99b6f0f7d08b77d8d021df7d7fa27f82d0 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 24 Nov 2015 22:27:22 +0000 Subject: Tidy the code that works out the socket path, and just use the full path in the global socket_path rather than copying it. --- client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'client.c') diff --git a/client.c b/client.c index fcb704fb..595aff9b 100644 --- a/client.c +++ b/client.c @@ -55,7 +55,7 @@ int client_attached; __dead void client_exec(const char *); int client_get_lock(char *); -int client_connect(struct event_base *, char *, int); +int client_connect(struct event_base *, const char *, int); void client_send_identify(const char *, const char *); void client_stdin_callback(int, short, void *); void client_write(int, const char *, size_t); @@ -96,7 +96,7 @@ client_get_lock(char *lockfile) /* Connect client to server. */ int -client_connect(struct event_base *base, char *path, int start_server) +client_connect(struct event_base *base, const char *path, int start_server) { struct sockaddr_un sa; size_t size; -- cgit v1.2.3 From 73e30cbda8ade3a1c7ba3b771a911545826f76b7 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 24 Nov 2015 22:45:44 +0000 Subject: Actually show something (even if it not that helpful) if the server fails to start (for example if it can't create the socket), rather than hanging or showing nothing. --- client.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'client.c') diff --git a/client.c b/client.c index 595aff9b..5fdfd029 100644 --- a/client.c +++ b/client.c @@ -76,8 +76,12 @@ client_get_lock(char *lockfile) { int lockfd; - if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) - fatal("open failed"); + if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) { + lockfd = open("/dev/null", O_WRONLY); + if (lockfd == -1) + fatal("open failed"); + return (lockfd); + } log_debug("lock file is %s", lockfile); if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) { @@ -114,10 +118,10 @@ client_connect(struct event_base *base, const char *path, int start_server) retry: if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - fatal("socket failed"); + return (-1); log_debug("trying connect"); - if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) { + if (connect(fd, (struct sockaddr *)&sa, sizeof sa) == -1) { log_debug("connect failed: %s", strerror(errno)); if (errno != ECONNREFUSED && errno != ENOENT) goto failed; @@ -255,6 +259,9 @@ client_main(struct event_base *base, int argc, char **argv, int flags) cmd_list_free(cmdlist); } + /* Create client process structure (starts logging). */ + client_proc = proc_start("client", base, 0, client_signal); + /* Initialize the client socket and start the server. */ fd = client_connect(base, socket_path, cmdflags & CMD_STARTSERVER); if (fd == -1) { @@ -267,9 +274,6 @@ client_main(struct event_base *base, int argc, char **argv, int flags) } return (1); } - - /* Build process state. */ - client_proc = proc_start("client", base, 0, client_signal); client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL); /* Save these before pledge(). */ @@ -365,7 +369,8 @@ client_main(struct event_base *base, int argc, char **argv, int flags) printf("%%exit\n"); printf("\033\\"); tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio); - } + } else + fprintf(stderr, "%s\n", client_exit_message()); setblocking(STDIN_FILENO, 1); return (client_exitval); } @@ -517,7 +522,11 @@ client_dispatch(struct imsg *imsg, __unused void *arg) if (imsg == NULL) { client_exitreason = CLIENT_EXIT_LOST_SERVER; client_exitval = 1; - } else if (client_attached) + proc_exit(client_proc); + return; + } + + if (client_attached) client_dispatch_attached(imsg); else client_dispatch_wait(imsg); -- cgit v1.2.3 From dca93c56e05ce631dd2f80da759f40c4d4b20ab5 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 24 Nov 2015 23:01:51 +0000 Subject: Do lock failures slightly better, return a special value so we don't unlink the wrong thing. --- client.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'client.c') diff --git a/client.c b/client.c index 5fdfd029..8144dd1c 100644 --- a/client.c +++ b/client.c @@ -67,22 +67,20 @@ const char *client_exit_message(void); /* * Get server create lock. If already held then server start is happening in - * another client, so block until the lock is released and return -1 to - * retry. Ignore other errors - just continue and start the server without the - * lock. + * another client, so block until the lock is released and return -2 to + * retry. Return -1 on failure to continue and start the server anyway. */ int client_get_lock(char *lockfile) { int lockfd; + log_debug("lock file is %s", lockfile); + if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) { - lockfd = open("/dev/null", O_WRONLY); - if (lockfd == -1) - fatal("open failed"); - return (lockfd); + log_debug("open failed: %s", strerror(errno)); + return (-1); } - log_debug("lock file is %s", lockfile); if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) { log_debug("flock failed: %s", strerror(errno)); @@ -91,7 +89,7 @@ client_get_lock(char *lockfile) while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR) /* nothing */; close(lockfd); - return (-1); + return (-2); } log_debug("flock succeeded"); @@ -131,12 +129,16 @@ retry: if (!locked) { xasprintf(&lockfile, "%s.lock", path); - if ((lockfd = client_get_lock(lockfile)) == -1) { - log_debug("didn't get lock"); + if ((lockfd = client_get_lock(lockfile)) < 0) { + log_debug("didn't get lock (%d)", lockfd); + free(lockfile); - goto retry; + lockfile = NULL; + + if (lockfd == -2) + goto retry; } - log_debug("got lock"); + log_debug("got lock (%d)", lockfd); /* * Always retry at least once, even if we got the lock, @@ -148,7 +150,7 @@ retry: goto retry; } - if (unlink(path) != 0 && errno != ENOENT) { + if (lockfd >= 0 && unlink(path) != 0 && errno != ENOENT) { free(lockfile); close(lockfd); return (-1); @@ -156,7 +158,7 @@ retry: fd = server_start(base, lockfd, lockfile); } - if (locked) { + if (locked && lockfd >= 0) { free(lockfile); close(lockfd); } -- cgit v1.2.3 From 3ff46b2e43d48376f74c0fd74b5616925d4063f0 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 24 Nov 2015 23:22:51 +0000 Subject: Shell command from -c doesn't have to be global, pass it as an argument. --- client.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'client.c') diff --git a/client.c b/client.c index 8144dd1c..5987efa5 100644 --- a/client.c +++ b/client.c @@ -53,7 +53,7 @@ enum msgtype client_exittype; const char *client_exitsession; int client_attached; -__dead void client_exec(const char *); +__dead void client_exec(const char *,const char *); int client_get_lock(char *); int client_connect(struct event_base *, const char *, int); void client_send_identify(const char *, const char *); @@ -62,7 +62,7 @@ void client_write(int, const char *, size_t); void client_signal(int); void client_dispatch(struct imsg *, void *); void client_dispatch_attached(struct imsg *); -void client_dispatch_wait(struct imsg *); +void client_dispatch_wait(struct imsg *, const char *); const char *client_exit_message(void); /* @@ -213,7 +213,8 @@ client_exit_message(void) /* Client main loop. */ int -client_main(struct event_base *base, int argc, char **argv, int flags) +client_main(struct event_base *base, int argc, char **argv, int flags, + const char *shellcmd) { struct cmd *cmd; struct cmd_list *cmdlist; @@ -234,7 +235,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags) /* Set up the initial command. */ cmdflags = 0; - if (shell_cmd != NULL) { + if (shellcmd != NULL) { msg = MSG_SHELL; cmdflags = CMD_STARTSERVER; } else if (argc == 0) { @@ -276,7 +277,8 @@ client_main(struct event_base *base, int argc, char **argv, int flags) } return (1); } - client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL); + client_peer = proc_add_peer(client_proc, fd, client_dispatch, + (void *)shellcmd); /* Save these before pledge(). */ if ((cwd = getcwd(path, sizeof path)) == NULL) { @@ -450,12 +452,12 @@ client_write(int fd, const char *data, size_t size) /* Run command in shell; used for -c. */ __dead void -client_exec(const char *shell) +client_exec(const char *shell, const char *shellcmd) { const char *name, *ptr; char *argv0; - log_debug("shell %s, command %s", shell, shell_cmd); + log_debug("shell %s, command %s", shell, shellcmd); ptr = strrchr(shell, '/'); if (ptr != NULL && *(ptr + 1) != '\0') @@ -473,7 +475,7 @@ client_exec(const char *shell) setblocking(STDERR_FILENO, 1); closefrom(STDERR_FILENO + 1); - execl(shell, argv0, "-c", shell_cmd, (char *) NULL); + execl(shell, argv0, "-c", shellcmd, (char *) NULL); fatal("execl failed"); } @@ -519,7 +521,7 @@ client_signal(int sig) /* Callback for client read events. */ void -client_dispatch(struct imsg *imsg, __unused void *arg) +client_dispatch(struct imsg *imsg, void *arg) { if (imsg == NULL) { client_exitreason = CLIENT_EXIT_LOST_SERVER; @@ -531,12 +533,12 @@ client_dispatch(struct imsg *imsg, __unused void *arg) if (client_attached) client_dispatch_attached(imsg); else - client_dispatch_wait(imsg); + client_dispatch_wait(imsg, arg); } /* Dispatch imsgs when in wait state (before MSG_READY). */ void -client_dispatch_wait(struct imsg *imsg) +client_dispatch_wait(struct imsg *imsg, const char *shellcmd) { char *data; ssize_t datalen; @@ -616,7 +618,7 @@ client_dispatch_wait(struct imsg *imsg) fatalx("bad MSG_SHELL string"); clear_signals(0); - client_exec(data); + client_exec(data, shellcmd); /* NOTREACHED */ case MSG_DETACH: case MSG_DETACHKILL: -- cgit v1.2.3 From ac8678aefe157d7e40c5bcedd12333eaedf0df92 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 25 Nov 2015 07:58:55 +0000 Subject: Don't print error if none to print. --- client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client.c') diff --git a/client.c b/client.c index 5987efa5..516ed3bf 100644 --- a/client.c +++ b/client.c @@ -373,7 +373,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags, printf("%%exit\n"); printf("\033\\"); tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio); - } else + } else if (client_exitreason != CLIENT_EXIT_NONE) fprintf(stderr, "%s\n", client_exit_message()); setblocking(STDIN_FILENO, 1); return (client_exitval); -- cgit v1.2.3