Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.23-rc4 226 lines 5.1 kB view raw
1/* 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6#include <stdlib.h> 7#include <stdio.h> 8#include <unistd.h> 9#include <string.h> 10#include <errno.h> 11#include <termios.h> 12#include "chan_user.h" 13#include "os.h" 14#include "init.h" 15#include "user.h" 16#include "xterm.h" 17#include "kern_constants.h" 18 19struct xterm_chan { 20 int pid; 21 int helper_pid; 22 char *title; 23 int device; 24 int raw; 25 struct termios tt; 26}; 27 28static void *xterm_init(char *str, int device, const struct chan_opts *opts) 29{ 30 struct xterm_chan *data; 31 32 data = malloc(sizeof(*data)); 33 if (data == NULL) 34 return NULL; 35 *data = ((struct xterm_chan) { .pid = -1, 36 .helper_pid = -1, 37 .device = device, 38 .title = opts->xterm_title, 39 .raw = opts->raw } ); 40 return data; 41} 42 43/* Only changed by xterm_setup, which is a setup */ 44static char *terminal_emulator = "xterm"; 45static char *title_switch = "-T"; 46static char *exec_switch = "-e"; 47 48static int __init xterm_setup(char *line, int *add) 49{ 50 *add = 0; 51 terminal_emulator = line; 52 53 line = strchr(line, ','); 54 if (line == NULL) 55 return 0; 56 57 *line++ = '\0'; 58 if (*line) 59 title_switch = line; 60 61 line = strchr(line, ','); 62 if (line == NULL) 63 return 0; 64 65 *line++ = '\0'; 66 if (*line) 67 exec_switch = line; 68 69 return 0; 70} 71 72__uml_setup("xterm=", xterm_setup, 73"xterm=<terminal emulator>,<title switch>,<exec switch>\n" 74" Specifies an alternate terminal emulator to use for the debugger,\n" 75" consoles, and serial lines when they are attached to the xterm channel.\n" 76" The values are the terminal emulator binary, the switch it uses to set\n" 77" its title, and the switch it uses to execute a subprocess,\n" 78" respectively. The title switch must have the form '<switch> title',\n" 79" not '<switch>=title'. Similarly, the exec switch must have the form\n" 80" '<switch> command arg1 arg2 ...'.\n" 81" The default values are 'xterm=xterm,-T,-e'. Values for gnome-terminal\n" 82" are 'xterm=gnome-terminal,-t,-x'.\n\n" 83); 84 85static int xterm_open(int input, int output, int primary, void *d, 86 char **dev_out) 87{ 88 struct xterm_chan *data = d; 89 int pid, fd, new, err; 90 char title[256], file[] = "/tmp/xterm-pipeXXXXXX"; 91 char *argv[] = { terminal_emulator, title_switch, title, exec_switch, 92 "/usr/lib/uml/port-helper", "-uml-socket", 93 file, NULL }; 94 95 if (access(argv[4], X_OK) < 0) 96 argv[4] = "port-helper"; 97 98 /* Check that DISPLAY is set, this doesn't guarantee the xterm 99 * will work but w/o it we can be pretty sure it won't. */ 100 if (getenv("DISPLAY") == NULL) { 101 printk(UM_KERN_ERR "xterm_open: $DISPLAY not set.\n"); 102 return -ENODEV; 103 } 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 */ 111 fd = mkstemp(file); 112 if (fd < 0) { 113 err = -errno; 114 printk(UM_KERN_ERR "xterm_open : mkstemp failed, errno = %d\n", 115 errno); 116 return err; 117 } 118 119 if (unlink(file)) { 120 err = -errno; 121 printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n", 122 errno); 123 return err; 124 } 125 close(fd); 126 127 fd = os_create_unix_socket(file, sizeof(file), 1); 128 if (fd < 0) { 129 printk(UM_KERN_ERR "xterm_open : create_unix_socket failed, " 130 "errno = %d\n", -fd); 131 return fd; 132 } 133 134 sprintf(title, data->title, data->device); 135 pid = run_helper(NULL, NULL, argv); 136 if (pid < 0) { 137 err = pid; 138 printk(UM_KERN_ERR "xterm_open : run_helper failed, " 139 "errno = %d\n", -err); 140 goto out_close1; 141 } 142 143 err = os_set_fd_block(fd, 0); 144 if (err < 0) { 145 printk(UM_KERN_ERR "xterm_open : failed to set descriptor " 146 "non-blocking, err = %d\n", -err); 147 goto out_kill; 148 } 149 150 new = xterm_fd(fd, &data->helper_pid); 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; 156 } 157 158 err = os_set_fd_block(new, 0); 159 if (err) { 160 printk(UM_KERN_ERR "xterm_open : failed to set xterm " 161 "descriptor non-blocking, err = %d\n", -err); 162 goto out_close2; 163 } 164 165 CATCH_EINTR(err = tcgetattr(new, &data->tt)); 166 if (err) { 167 new = err; 168 goto out_close2; 169 } 170 171 if (data->raw) { 172 err = raw(new); 173 if (err) { 174 new = err; 175 goto out_close2; 176 } 177 } 178 179 unlink(file); 180 data->pid = pid; 181 *dev_out = NULL; 182 183 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; 193} 194 195static void xterm_close(int fd, void *d) 196{ 197 struct xterm_chan *data = d; 198 199 if (data->pid != -1) 200 os_kill_process(data->pid, 1); 201 data->pid = -1; 202 203 if (data->helper_pid != -1) 204 os_kill_process(data->helper_pid, 0); 205 data->helper_pid = -1; 206 207 os_close_file(fd); 208} 209 210static void xterm_free(void *d) 211{ 212 free(d); 213} 214 215const struct chan_ops xterm_ops = { 216 .type = "xterm", 217 .init = xterm_init, 218 .open = xterm_open, 219 .close = xterm_close, 220 .read = generic_read, 221 .write = generic_write, 222 .console_write = generic_console_write, 223 .window_size = generic_window_size, 224 .free = xterm_free, 225 .winch = 1, 226};