Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 143 lines (119 sloc) 3.719 kb
c2acb99b » orebokech
2011-11-01 Import upstream snapshot from SVN r2630
1 /* $Id: cmd-pipe-pane.c 2628 2011-10-31 13:55:43Z tcunha $ */
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
2
3 /*
4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/types.h>
dda8e8e5 » kfebert
2010-03-13 Imported Upstream version 1.2
20 #include <sys/socket.h>
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <string.h>
fb53a63d » kfebert
2010-07-23 Imported Upstream version 1.3
25 #include <time.h>
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
26 #include <unistd.h>
27
28 #include "tmux.h"
29
30 /*
31 * Open pipe to redirect pane output. If already open, close first.
32 */
33
34 int cmd_pipe_pane_exec(struct cmd *, struct cmd_ctx *);
35
dda8e8e5 » kfebert
2010-03-13 Imported Upstream version 1.2
36 void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
37
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
38 const struct cmd_entry cmd_pipe_pane_entry = {
39 "pipe-pane", "pipep",
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
40 "ot:", 0, 1,
c2acb99b » orebokech
2011-11-01 Import upstream snapshot from SVN r2630
41 "[-o] " CMD_TARGET_PANE_USAGE " [command]",
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
42 0,
43 NULL,
44 NULL,
45 cmd_pipe_pane_exec
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
46 };
47
48 int
49 cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
50 {
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
51 struct args *args = self->args;
fb53a63d » kfebert
2010-07-23 Imported Upstream version 1.3
52 struct client *c;
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
53 struct window_pane *wp;
fb53a63d » kfebert
2010-07-23 Imported Upstream version 1.3
54 char *command;
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
55 int old_fd, pipe_fd[2], null_fd;
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
56
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
57 if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
58 return (-1);
b0169484 » orebokech
2011-10-03 Import upstream snapshot from SVN r2608
59 c = cmd_find_client(ctx, NULL);
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
60
61 /* Destroy the old pipe. */
62 old_fd = wp->pipe_fd;
63 if (wp->pipe_fd != -1) {
dda8e8e5 » kfebert
2010-03-13 Imported Upstream version 1.2
64 bufferevent_free(wp->pipe_event);
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
65 close(wp->pipe_fd);
66 wp->pipe_fd = -1;
67 }
68
69 /* If no pipe command, that is enough. */
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
70 if (args->argc == 0 || *args->argv[0] == '\0')
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
71 return (0);
72
73 /*
74 * With -o, only open the new pipe if there was no previous one. This
75 * allows a pipe to be toggled with a single key, for example:
76 *
77 * bind ^p pipep -o 'cat >>~/output'
78 */
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
79 if (args_has(self->args, 'o') && old_fd != -1)
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
80 return (0);
81
82 /* Open the new pipe. */
dda8e8e5 » kfebert
2010-03-13 Imported Upstream version 1.2
83 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
84 ctx->error(ctx, "socketpair error: %s", strerror(errno));
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
85 return (-1);
86 }
87
88 /* Fork the child. */
89 switch (fork()) {
90 case -1:
91 ctx->error(ctx, "fork error: %s", strerror(errno));
dda8e8e5 » kfebert
2010-03-13 Imported Upstream version 1.2
92 return (-1);
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
93 case 0:
94 /* Child process. */
95 close(pipe_fd[0]);
77c63de6 » orebokech
2010-12-28 Import upstream version 1.4
96 clear_signals(1);
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
97
98 if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
99 _exit(1);
100 if (pipe_fd[1] != STDIN_FILENO)
101 close(pipe_fd[1]);
102
103 null_fd = open(_PATH_DEVNULL, O_WRONLY, 0);
104 if (dup2(null_fd, STDOUT_FILENO) == -1)
105 _exit(1);
106 if (dup2(null_fd, STDERR_FILENO) == -1)
107 _exit(1);
108 if (null_fd != STDOUT_FILENO && null_fd != STDERR_FILENO)
109 close(null_fd);
110
77c63de6 » orebokech
2010-12-28 Import upstream version 1.4
111 closefrom(STDERR_FILENO + 1);
112
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
113 command = status_replace(
114 c, NULL, NULL, NULL, args->argv[0], time(NULL), 0);
fb53a63d » kfebert
2010-07-23 Imported Upstream version 1.3
115 execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
116 _exit(1);
117 default:
118 /* Parent process. */
119 close(pipe_fd[1]);
120
121 wp->pipe_fd = pipe_fd[0];
dda8e8e5 » kfebert
2010-03-13 Imported Upstream version 1.2
122 wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
123
124 wp->pipe_event = bufferevent_new(wp->pipe_fd,
125 NULL, NULL, cmd_pipe_pane_error_callback, wp);
126 bufferevent_enable(wp->pipe_event, EV_WRITE);
127
7216c39c » kfebert
2011-07-09 Imported Upstream version 1.5
128 setblocking(wp->pipe_fd, 0);
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
129 return (0);
130 }
dda8e8e5 » kfebert
2010-03-13 Imported Upstream version 1.2
131 }
132
133 /* ARGSUSED */
134 void
135 cmd_pipe_pane_error_callback(
136 unused struct bufferevent *bufev, unused short what, void *data)
137 {
138 struct window_pane *wp = data;
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
139
dda8e8e5 » kfebert
2010-03-13 Imported Upstream version 1.2
140 bufferevent_free(wp->pipe_event);
141 close(wp->pipe_fd);
142 wp->pipe_fd = -1;
8fade26b » Karl Ferdinand Ebert
2009-11-22 Imported Upstream version 1.1
143 }
Something went wrong with that request. Please try again.