aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/xterm.c')
-rw-r--r--arch/um/drivers/xterm.c173
1 files changed, 88 insertions, 85 deletions
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index fe238e03a300..35912846ed21 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -1,22 +1,20 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h>
7#include <stdlib.h> 6#include <stdlib.h>
7#include <stdio.h>
8#include <unistd.h> 8#include <unistd.h>
9#include <string.h> 9#include <string.h>
10#include <errno.h> 10#include <errno.h>
11#include <termios.h> 11#include <termios.h>
12#include <signal.h>
13#include <sched.h>
14#include <sys/socket.h>
15#include "kern_util.h"
16#include "chan_user.h" 12#include "chan_user.h"
17#include "user.h"
18#include "os.h" 13#include "os.h"
14#include "init.h"
15#include "user.h"
19#include "xterm.h" 16#include "xterm.h"
17#include "kern_constants.h"
20 18
21struct xterm_chan { 19struct xterm_chan {
22 int pid; 20 int pid;
@@ -25,25 +23,21 @@ struct xterm_chan {
25 int device; 23 int device;
26 int raw; 24 int raw;
27 struct termios tt; 25 struct termios tt;
28 unsigned long stack;
29 int direct_rcv;
30}; 26};
31 27
32/* Not static because it's called directly by the tt mode gdb code */ 28static void *xterm_init(char *str, int device, const struct chan_opts *opts)
33void *xterm_init(char *str, int device, const struct chan_opts *opts)
34{ 29{
35 struct xterm_chan *data; 30 struct xterm_chan *data;
36 31
37 data = malloc(sizeof(*data)); 32 data = malloc(sizeof(*data));
38 if(data == NULL) return(NULL); 33 if (data == NULL)
39 *data = ((struct xterm_chan) { .pid = -1, 34 return NULL;
35 *data = ((struct xterm_chan) { .pid = -1,
40 .helper_pid = -1, 36 .helper_pid = -1,
41 .device = device, 37 .device = device,
42 .title = opts->xterm_title, 38 .title = opts->xterm_title,
43 .raw = opts->raw, 39 .raw = opts->raw } );
44 .stack = opts->tramp_stack, 40 return data;
45 .direct_rcv = !opts->in_kernel } );
46 return(data);
47} 41}
48 42
49/* Only changed by xterm_setup, which is a setup */ 43/* Only changed by xterm_setup, which is a setup */
@@ -57,16 +51,22 @@ static int __init xterm_setup(char *line, int *add)
57 terminal_emulator = line; 51 terminal_emulator = line;
58 52
59 line = strchr(line, ','); 53 line = strchr(line, ',');
60 if(line == NULL) return(0); 54 if (line == NULL)
55 return 0;
56
61 *line++ = '\0'; 57 *line++ = '\0';
62 if(*line) title_switch = line; 58 if (*line)
59 title_switch = line;
63 60
64 line = strchr(line, ','); 61 line = strchr(line, ',');
65 if(line == NULL) return(0); 62 if (line == NULL)
63 return 0;
64
66 *line++ = '\0'; 65 *line++ = '\0';
67 if(*line) exec_switch = line; 66 if (*line)
67 exec_switch = line;
68 68
69 return(0); 69 return 0;
70} 70}
71 71
72__uml_setup("xterm=", xterm_setup, 72__uml_setup("xterm=", xterm_setup,
@@ -82,114 +82,128 @@ __uml_setup("xterm=", xterm_setup,
82" are 'xterm=gnome-terminal,-t,-x'.\n\n" 82" are 'xterm=gnome-terminal,-t,-x'.\n\n"
83); 83);
84 84
85/* XXX This badly needs some cleaning up in the error paths 85static int xterm_open(int input, int output, int primary, void *d,
86 * Not static because it's called directly by the tt mode gdb code
87 */
88int xterm_open(int input, int output, int primary, void *d,
89 char **dev_out) 86 char **dev_out)
90{ 87{
91 struct xterm_chan *data = d; 88 struct xterm_chan *data = d;
92 unsigned long stack;
93 int pid, fd, new, err; 89 int pid, fd, new, err;
94 char title[256], file[] = "/tmp/xterm-pipeXXXXXX"; 90 char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
95 char *argv[] = { terminal_emulator, title_switch, title, exec_switch, 91 char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
96 "/usr/lib/uml/port-helper", "-uml-socket", 92 "/usr/lib/uml/port-helper", "-uml-socket",
97 file, NULL }; 93 file, NULL };
98 94
99 if(os_access(argv[4], OS_ACC_X_OK) < 0) 95 if (access(argv[4], X_OK) < 0)
100 argv[4] = "port-helper"; 96 argv[4] = "port-helper";
101 97
102 /* Check that DISPLAY is set, this doesn't guarantee the xterm 98 /* Check that DISPLAY is set, this doesn't guarantee the xterm
103 * will work but w/o it we can be pretty sure it won't. */ 99 * will work but w/o it we can be pretty sure it won't. */
104 if (!getenv("DISPLAY")) { 100 if (getenv("DISPLAY") == NULL) {
105 printk("xterm_open: $DISPLAY not set.\n"); 101 printk(UM_KERN_ERR "xterm_open: $DISPLAY not set.\n");
106 return -ENODEV; 102 return -ENODEV;
107 } 103 }
108 104
105 /*
106 * This business of getting a descriptor to a temp file,
107 * deleting the file and closing the descriptor is just to get
108 * a known-unused name for the Unix socket that we really
109 * want.
110 */
109 fd = mkstemp(file); 111 fd = mkstemp(file);
110 if(fd < 0){ 112 if (fd < 0) {
111 err = -errno; 113 err = -errno;
112 printk("xterm_open : mkstemp failed, errno = %d\n", errno); 114 printk(UM_KERN_ERR "xterm_open : mkstemp failed, errno = %d\n",
115 errno);
113 return err; 116 return err;
114 } 117 }
115 118
116 if(unlink(file)){ 119 if (unlink(file)) {
117 err = -errno; 120 err = -errno;
118 printk("xterm_open : unlink failed, errno = %d\n", errno); 121 printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n",
122 errno);
119 return err; 123 return err;
120 } 124 }
121 os_close_file(fd); 125 close(fd);
122 126
123 fd = os_create_unix_socket(file, sizeof(file), 1); 127 fd = os_create_unix_socket(file, sizeof(file), 1);
124 if(fd < 0){ 128 if (fd < 0) {
125 printk("xterm_open : create_unix_socket failed, errno = %d\n", 129 printk(UM_KERN_ERR "xterm_open : create_unix_socket failed, "
126 -fd); 130 "errno = %d\n", -fd);
127 return(fd); 131 return fd;
128 } 132 }
129 133
130 sprintf(title, data->title, data->device); 134 sprintf(title, data->title, data->device);
131 stack = data->stack; 135 pid = run_helper(NULL, NULL, argv, NULL);
132 pid = run_helper(NULL, NULL, argv, &stack); 136 if (pid < 0) {
133 if(pid < 0){ 137 err = pid;
134 printk("xterm_open : run_helper failed, errno = %d\n", -pid); 138 printk(UM_KERN_ERR "xterm_open : run_helper failed, "
135 return(pid); 139 "errno = %d\n", -err);
140 goto out_close1;
136 } 141 }
137 142
138 if (data->direct_rcv) { 143 err = os_set_fd_block(fd, 0);
139 new = os_rcv_fd(fd, &data->helper_pid); 144 if (err < 0) {
140 } else { 145 printk(UM_KERN_ERR "xterm_open : failed to set descriptor "
141 err = os_set_fd_block(fd, 0); 146 "non-blocking, err = %d\n", -err);
142 if(err < 0){ 147 goto out_kill;
143 printk("xterm_open : failed to set descriptor "
144 "non-blocking, err = %d\n", -err);
145 return(err);
146 }
147 new = xterm_fd(fd, &data->helper_pid);
148 } 148 }
149 if(new < 0){ 149
150 printk("xterm_open : os_rcv_fd failed, err = %d\n", -new); 150 new = xterm_fd(fd, &data->helper_pid);
151 goto out; 151 if (new < 0) {
152 err = new;
153 printk(UM_KERN_ERR "xterm_open : os_rcv_fd failed, err = %d\n",
154 -err);
155 goto out_kill;
152 } 156 }
153 157
154 err = os_set_fd_block(new, 0); 158 err = os_set_fd_block(new, 0);
155 if (err) { 159 if (err) {
156 printk("xterm_open : failed to set xterm descriptor " 160 printk(UM_KERN_ERR "xterm_open : failed to set xterm "
157 "non-blocking, err = %d\n", -err); 161 "descriptor non-blocking, err = %d\n", -err);
158 goto out; 162 goto out_close2;
159 } 163 }
160 164
161 CATCH_EINTR(err = tcgetattr(new, &data->tt)); 165 CATCH_EINTR(err = tcgetattr(new, &data->tt));
162 if(err){ 166 if (err) {
163 new = err; 167 new = err;
164 goto out; 168 goto out_close2;
165 } 169 }
166 170
167 if(data->raw){ 171 if (data->raw) {
168 err = raw(new); 172 err = raw(new);
169 if(err){ 173 if (err) {
170 new = err; 174 new = err;
171 goto out; 175 goto out_close2;
172 } 176 }
173 } 177 }
174 178
179 unlink(file);
175 data->pid = pid; 180 data->pid = pid;
176 *dev_out = NULL; 181 *dev_out = NULL;
177 out: 182
178 unlink(file); 183 return new;
179 return(new); 184
185 out_close2:
186 close(new);
187 out_kill:
188 os_kill_process(pid, 1);
189 out_close1:
190 close(fd);
191
192 return err;
180} 193}
181 194
182/* Not static because it's called directly by the tt mode gdb code */ 195static void xterm_close(int fd, void *d)
183void xterm_close(int fd, void *d)
184{ 196{
185 struct xterm_chan *data = d; 197 struct xterm_chan *data = d;
186 198
187 if(data->pid != -1) 199 if (data->pid != -1)
188 os_kill_process(data->pid, 1); 200 os_kill_process(data->pid, 1);
189 data->pid = -1; 201 data->pid = -1;
190 if(data->helper_pid != -1) 202
203 if (data->helper_pid != -1)
191 os_kill_process(data->helper_pid, 0); 204 os_kill_process(data->helper_pid, 0);
192 data->helper_pid = -1; 205 data->helper_pid = -1;
206
193 os_close_file(fd); 207 os_close_file(fd);
194} 208}
195 209
@@ -210,14 +224,3 @@ const struct chan_ops xterm_ops = {
210 .free = xterm_free, 224 .free = xterm_free,
211 .winch = 1, 225 .winch = 1,
212}; 226};
213
214/*
215 * Overrides for Emacs so that we follow Linus's tabbing style.
216 * Emacs will notice this stuff at the end of the file and automatically
217 * adjust the settings for this buffer only. This must remain at the end
218 * of the file.
219 * ---------------------------------------------------------------------------
220 * Local variables:
221 * c-file-style: "linux"
222 * End:
223 */