diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/drivers/chan_kern.c | 160 | ||||
-rw-r--r-- | arch/um/drivers/chan_user.c | 111 | ||||
-rw-r--r-- | arch/um/drivers/fd.c | 74 | ||||
-rw-r--r-- | arch/um/drivers/null.c | 28 | ||||
-rw-r--r-- | arch/um/drivers/port_kern.c | 82 | ||||
-rw-r--r-- | arch/um/drivers/port_user.c | 73 | ||||
-rw-r--r-- | arch/um/drivers/pty.c | 14 | ||||
-rw-r--r-- | arch/um/drivers/tty.c | 37 | ||||
-rw-r--r-- | arch/um/drivers/xterm.c | 16 |
9 files changed, 296 insertions, 299 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 9a6222f1a51b..c09dbdfa298a 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -1,28 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/stddef.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/list.h> | ||
9 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
10 | #include <linux/tty.h> | 7 | #include <linux/tty.h> |
11 | #include <linux/string.h> | ||
12 | #include <linux/tty_flip.h> | 8 | #include <linux/tty_flip.h> |
13 | #include <asm/irq.h> | ||
14 | #include "chan_kern.h" | 9 | #include "chan_kern.h" |
15 | #include "kern.h" | ||
16 | #include "irq_user.h" | ||
17 | #include "sigio.h" | ||
18 | #include "line.h" | ||
19 | #include "os.h" | 10 | #include "os.h" |
20 | 11 | ||
21 | #ifdef CONFIG_NOCONFIG_CHAN | 12 | #ifdef CONFIG_NOCONFIG_CHAN |
22 | static void *not_configged_init(char *str, int device, | 13 | static void *not_configged_init(char *str, int device, |
23 | const struct chan_opts *opts) | 14 | const struct chan_opts *opts) |
24 | { | 15 | { |
25 | printk("Using a channel type which is configured out of " | 16 | printk(KERN_ERR "Using a channel type which is configured out of " |
26 | "UML\n"); | 17 | "UML\n"); |
27 | return NULL; | 18 | return NULL; |
28 | } | 19 | } |
@@ -30,34 +21,34 @@ static void *not_configged_init(char *str, int device, | |||
30 | static int not_configged_open(int input, int output, int primary, void *data, | 21 | static int not_configged_open(int input, int output, int primary, void *data, |
31 | char **dev_out) | 22 | char **dev_out) |
32 | { | 23 | { |
33 | printk("Using a channel type which is configured out of " | 24 | printk(KERN_ERR "Using a channel type which is configured out of " |
34 | "UML\n"); | 25 | "UML\n"); |
35 | return -ENODEV; | 26 | return -ENODEV; |
36 | } | 27 | } |
37 | 28 | ||
38 | static void not_configged_close(int fd, void *data) | 29 | static void not_configged_close(int fd, void *data) |
39 | { | 30 | { |
40 | printk("Using a channel type which is configured out of " | 31 | printk(KERN_ERR "Using a channel type which is configured out of " |
41 | "UML\n"); | 32 | "UML\n"); |
42 | } | 33 | } |
43 | 34 | ||
44 | static int not_configged_read(int fd, char *c_out, void *data) | 35 | static int not_configged_read(int fd, char *c_out, void *data) |
45 | { | 36 | { |
46 | printk("Using a channel type which is configured out of " | 37 | printk(KERN_ERR "Using a channel type which is configured out of " |
47 | "UML\n"); | 38 | "UML\n"); |
48 | return -EIO; | 39 | return -EIO; |
49 | } | 40 | } |
50 | 41 | ||
51 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 42 | static int not_configged_write(int fd, const char *buf, int len, void *data) |
52 | { | 43 | { |
53 | printk("Using a channel type which is configured out of " | 44 | printk(KERN_ERR "Using a channel type which is configured out of " |
54 | "UML\n"); | 45 | "UML\n"); |
55 | return -EIO; | 46 | return -EIO; |
56 | } | 47 | } |
57 | 48 | ||
58 | static int not_configged_console_write(int fd, const char *buf, int len) | 49 | static int not_configged_console_write(int fd, const char *buf, int len) |
59 | { | 50 | { |
60 | printk("Using a channel type which is configured out of " | 51 | printk(KERN_ERR "Using a channel type which is configured out of " |
61 | "UML\n"); | 52 | "UML\n"); |
62 | return -EIO; | 53 | return -EIO; |
63 | } | 54 | } |
@@ -65,14 +56,14 @@ static int not_configged_console_write(int fd, const char *buf, int len) | |||
65 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 56 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, |
66 | unsigned short *cols) | 57 | unsigned short *cols) |
67 | { | 58 | { |
68 | printk("Using a channel type which is configured out of " | 59 | printk(KERN_ERR "Using a channel type which is configured out of " |
69 | "UML\n"); | 60 | "UML\n"); |
70 | return -ENODEV; | 61 | return -ENODEV; |
71 | } | 62 | } |
72 | 63 | ||
73 | static void not_configged_free(void *data) | 64 | static void not_configged_free(void *data) |
74 | { | 65 | { |
75 | printk("Using a channel type which is configured out of " | 66 | printk(KERN_ERR "Using a channel type which is configured out of " |
76 | "UML\n"); | 67 | "UML\n"); |
77 | } | 68 | } |
78 | 69 | ||
@@ -91,14 +82,15 @@ static const struct chan_ops not_configged_ops = { | |||
91 | 82 | ||
92 | static void tty_receive_char(struct tty_struct *tty, char ch) | 83 | static void tty_receive_char(struct tty_struct *tty, char ch) |
93 | { | 84 | { |
94 | if(tty == NULL) return; | 85 | if (tty == NULL) |
86 | return; | ||
95 | 87 | ||
96 | if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) { | 88 | if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) { |
97 | if(ch == STOP_CHAR(tty)){ | 89 | if (ch == STOP_CHAR(tty)) { |
98 | stop_tty(tty); | 90 | stop_tty(tty); |
99 | return; | 91 | return; |
100 | } | 92 | } |
101 | else if(ch == START_CHAR(tty)){ | 93 | else if (ch == START_CHAR(tty)) { |
102 | start_tty(tty); | 94 | start_tty(tty); |
103 | return; | 95 | return; |
104 | } | 96 | } |
@@ -111,14 +103,14 @@ static int open_one_chan(struct chan *chan) | |||
111 | { | 103 | { |
112 | int fd, err; | 104 | int fd, err; |
113 | 105 | ||
114 | if(chan->opened) | 106 | if (chan->opened) |
115 | return 0; | 107 | return 0; |
116 | 108 | ||
117 | if(chan->ops->open == NULL) | 109 | if (chan->ops->open == NULL) |
118 | fd = 0; | 110 | fd = 0; |
119 | else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary, | 111 | else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary, |
120 | chan->data, &chan->dev); | 112 | chan->data, &chan->dev); |
121 | if(fd < 0) | 113 | if (fd < 0) |
122 | return fd; | 114 | return fd; |
123 | 115 | ||
124 | err = os_set_fd_block(fd, 0); | 116 | err = os_set_fd_block(fd, 0); |
@@ -139,10 +131,10 @@ int open_chan(struct list_head *chans) | |||
139 | struct chan *chan; | 131 | struct chan *chan; |
140 | int ret, err = 0; | 132 | int ret, err = 0; |
141 | 133 | ||
142 | list_for_each(ele, chans){ | 134 | list_for_each(ele, chans) { |
143 | chan = list_entry(ele, struct chan, list); | 135 | chan = list_entry(ele, struct chan, list); |
144 | ret = open_one_chan(chan); | 136 | ret = open_one_chan(chan); |
145 | if(chan->primary) | 137 | if (chan->primary) |
146 | err = ret; | 138 | err = ret; |
147 | } | 139 | } |
148 | return err; | 140 | return err; |
@@ -153,9 +145,9 @@ void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) | |||
153 | struct list_head *ele; | 145 | struct list_head *ele; |
154 | struct chan *chan; | 146 | struct chan *chan; |
155 | 147 | ||
156 | list_for_each(ele, chans){ | 148 | list_for_each(ele, chans) { |
157 | chan = list_entry(ele, struct chan, list); | 149 | chan = list_entry(ele, struct chan, list); |
158 | if(chan->primary && chan->output && chan->ops->winch){ | 150 | if (chan->primary && chan->output && chan->ops->winch) { |
159 | register_winch(chan->fd, tty); | 151 | register_winch(chan->fd, tty); |
160 | return; | 152 | return; |
161 | } | 153 | } |
@@ -168,7 +160,7 @@ int enable_chan(struct line *line) | |||
168 | struct chan *chan; | 160 | struct chan *chan; |
169 | int err; | 161 | int err; |
170 | 162 | ||
171 | list_for_each(ele, &line->chan_list){ | 163 | list_for_each(ele, &line->chan_list) { |
172 | chan = list_entry(ele, struct chan, list); | 164 | chan = list_entry(ele, struct chan, list); |
173 | err = open_one_chan(chan); | 165 | err = open_one_chan(chan); |
174 | if (err) { | 166 | if (err) { |
@@ -178,7 +170,7 @@ int enable_chan(struct line *line) | |||
178 | continue; | 170 | continue; |
179 | } | 171 | } |
180 | 172 | ||
181 | if(chan->enabled) | 173 | if (chan->enabled) |
182 | continue; | 174 | continue; |
183 | err = line_setup_irq(chan->fd, chan->input, chan->output, line, | 175 | err = line_setup_irq(chan->fd, chan->input, chan->output, line, |
184 | chan); | 176 | chan); |
@@ -215,12 +207,12 @@ void free_irqs(void) | |||
215 | list_splice_init(&irqs_to_free, &list); | 207 | list_splice_init(&irqs_to_free, &list); |
216 | spin_unlock_irqrestore(&irqs_to_free_lock, flags); | 208 | spin_unlock_irqrestore(&irqs_to_free_lock, flags); |
217 | 209 | ||
218 | list_for_each(ele, &list){ | 210 | list_for_each(ele, &list) { |
219 | chan = list_entry(ele, struct chan, free_list); | 211 | chan = list_entry(ele, struct chan, free_list); |
220 | 212 | ||
221 | if(chan->input) | 213 | if (chan->input) |
222 | free_irq(chan->line->driver->read_irq, chan); | 214 | free_irq(chan->line->driver->read_irq, chan); |
223 | if(chan->output) | 215 | if (chan->output) |
224 | free_irq(chan->line->driver->write_irq, chan); | 216 | free_irq(chan->line->driver->write_irq, chan); |
225 | chan->enabled = 0; | 217 | chan->enabled = 0; |
226 | } | 218 | } |
@@ -230,22 +222,22 @@ static void close_one_chan(struct chan *chan, int delay_free_irq) | |||
230 | { | 222 | { |
231 | unsigned long flags; | 223 | unsigned long flags; |
232 | 224 | ||
233 | if(!chan->opened) | 225 | if (!chan->opened) |
234 | return; | 226 | return; |
235 | 227 | ||
236 | if(delay_free_irq){ | 228 | if (delay_free_irq) { |
237 | spin_lock_irqsave(&irqs_to_free_lock, flags); | 229 | spin_lock_irqsave(&irqs_to_free_lock, flags); |
238 | list_add(&chan->free_list, &irqs_to_free); | 230 | list_add(&chan->free_list, &irqs_to_free); |
239 | spin_unlock_irqrestore(&irqs_to_free_lock, flags); | 231 | spin_unlock_irqrestore(&irqs_to_free_lock, flags); |
240 | } | 232 | } |
241 | else { | 233 | else { |
242 | if(chan->input) | 234 | if (chan->input) |
243 | free_irq(chan->line->driver->read_irq, chan); | 235 | free_irq(chan->line->driver->read_irq, chan); |
244 | if(chan->output) | 236 | if (chan->output) |
245 | free_irq(chan->line->driver->write_irq, chan); | 237 | free_irq(chan->line->driver->write_irq, chan); |
246 | chan->enabled = 0; | 238 | chan->enabled = 0; |
247 | } | 239 | } |
248 | if(chan->ops->close != NULL) | 240 | if (chan->ops->close != NULL) |
249 | (*chan->ops->close)(chan->fd, chan->data); | 241 | (*chan->ops->close)(chan->fd, chan->data); |
250 | 242 | ||
251 | chan->opened = 0; | 243 | chan->opened = 0; |
@@ -274,7 +266,7 @@ void deactivate_chan(struct list_head *chans, int irq) | |||
274 | list_for_each(ele, chans) { | 266 | list_for_each(ele, chans) { |
275 | chan = list_entry(ele, struct chan, list); | 267 | chan = list_entry(ele, struct chan, list); |
276 | 268 | ||
277 | if(chan->enabled && chan->input) | 269 | if (chan->enabled && chan->input) |
278 | deactivate_fd(chan->fd, irq); | 270 | deactivate_fd(chan->fd, irq); |
279 | } | 271 | } |
280 | } | 272 | } |
@@ -287,7 +279,7 @@ void reactivate_chan(struct list_head *chans, int irq) | |||
287 | list_for_each(ele, chans) { | 279 | list_for_each(ele, chans) { |
288 | chan = list_entry(ele, struct chan, list); | 280 | chan = list_entry(ele, struct chan, list); |
289 | 281 | ||
290 | if(chan->enabled && chan->input) | 282 | if (chan->enabled && chan->input) |
291 | reactivate_fd(chan->fd, irq); | 283 | reactivate_fd(chan->fd, irq); |
292 | } | 284 | } |
293 | } | 285 | } |
@@ -303,6 +295,7 @@ int write_chan(struct list_head *chans, const char *buf, int len, | |||
303 | chan = list_entry(ele, struct chan, list); | 295 | chan = list_entry(ele, struct chan, list); |
304 | if (!chan->output || (chan->ops->write == NULL)) | 296 | if (!chan->output || (chan->ops->write == NULL)) |
305 | continue; | 297 | continue; |
298 | |||
306 | n = chan->ops->write(chan->fd, buf, len, chan->data); | 299 | n = chan->ops->write(chan->fd, buf, len, chan->data); |
307 | if (chan->primary) { | 300 | if (chan->primary) { |
308 | ret = n; | 301 | ret = n; |
@@ -319,12 +312,14 @@ int console_write_chan(struct list_head *chans, const char *buf, int len) | |||
319 | struct chan *chan; | 312 | struct chan *chan; |
320 | int n, ret = 0; | 313 | int n, ret = 0; |
321 | 314 | ||
322 | list_for_each(ele, chans){ | 315 | list_for_each(ele, chans) { |
323 | chan = list_entry(ele, struct chan, list); | 316 | chan = list_entry(ele, struct chan, list); |
324 | if(!chan->output || (chan->ops->console_write == NULL)) | 317 | if (!chan->output || (chan->ops->console_write == NULL)) |
325 | continue; | 318 | continue; |
319 | |||
326 | n = chan->ops->console_write(chan->fd, buf, len); | 320 | n = chan->ops->console_write(chan->fd, buf, len); |
327 | if(chan->primary) ret = n; | 321 | if (chan->primary) |
322 | ret = n; | ||
328 | } | 323 | } |
329 | return ret; | 324 | return ret; |
330 | } | 325 | } |
@@ -334,10 +329,11 @@ int console_open_chan(struct line *line, struct console *co) | |||
334 | int err; | 329 | int err; |
335 | 330 | ||
336 | err = open_chan(&line->chan_list); | 331 | err = open_chan(&line->chan_list); |
337 | if(err) | 332 | if (err) |
338 | return err; | 333 | return err; |
339 | 334 | ||
340 | printk("Console initialized on /dev/%s%d\n", co->name, co->index); | 335 | printk(KERN_INFO "Console initialized on /dev/%s%d\n", co->name, |
336 | co->index); | ||
341 | return 0; | 337 | return 0; |
342 | } | 338 | } |
343 | 339 | ||
@@ -347,10 +343,10 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out, | |||
347 | struct list_head *ele; | 343 | struct list_head *ele; |
348 | struct chan *chan; | 344 | struct chan *chan; |
349 | 345 | ||
350 | list_for_each(ele, chans){ | 346 | list_for_each(ele, chans) { |
351 | chan = list_entry(ele, struct chan, list); | 347 | chan = list_entry(ele, struct chan, list); |
352 | if(chan->primary){ | 348 | if (chan->primary) { |
353 | if(chan->ops->window_size == NULL) | 349 | if (chan->ops->window_size == NULL) |
354 | return 0; | 350 | return 0; |
355 | return chan->ops->window_size(chan->fd, chan->data, | 351 | return chan->ops->window_size(chan->fd, chan->data, |
356 | rows_out, cols_out); | 352 | rows_out, cols_out); |
@@ -365,10 +361,11 @@ static void free_one_chan(struct chan *chan, int delay_free_irq) | |||
365 | 361 | ||
366 | close_one_chan(chan, delay_free_irq); | 362 | close_one_chan(chan, delay_free_irq); |
367 | 363 | ||
368 | if(chan->ops->free != NULL) | 364 | if (chan->ops->free != NULL) |
369 | (*chan->ops->free)(chan->data); | 365 | (*chan->ops->free)(chan->data); |
370 | 366 | ||
371 | if(chan->primary && chan->output) ignore_sigio_fd(chan->fd); | 367 | if (chan->primary && chan->output) |
368 | ignore_sigio_fd(chan->fd); | ||
372 | kfree(chan); | 369 | kfree(chan); |
373 | } | 370 | } |
374 | 371 | ||
@@ -377,7 +374,7 @@ static void free_chan(struct list_head *chans, int delay_free_irq) | |||
377 | struct list_head *ele, *next; | 374 | struct list_head *ele, *next; |
378 | struct chan *chan; | 375 | struct chan *chan; |
379 | 376 | ||
380 | list_for_each_safe(ele, next, chans){ | 377 | list_for_each_safe(ele, next, chans) { |
381 | chan = list_entry(ele, struct chan, list); | 378 | chan = list_entry(ele, struct chan, list); |
382 | free_one_chan(chan, delay_free_irq); | 379 | free_one_chan(chan, delay_free_irq); |
383 | } | 380 | } |
@@ -388,14 +385,14 @@ static int one_chan_config_string(struct chan *chan, char *str, int size, | |||
388 | { | 385 | { |
389 | int n = 0; | 386 | int n = 0; |
390 | 387 | ||
391 | if(chan == NULL){ | 388 | if (chan == NULL) { |
392 | CONFIG_CHUNK(str, size, n, "none", 1); | 389 | CONFIG_CHUNK(str, size, n, "none", 1); |
393 | return n; | 390 | return n; |
394 | } | 391 | } |
395 | 392 | ||
396 | CONFIG_CHUNK(str, size, n, chan->ops->type, 0); | 393 | CONFIG_CHUNK(str, size, n, chan->ops->type, 0); |
397 | 394 | ||
398 | if(chan->dev == NULL){ | 395 | if (chan->dev == NULL) { |
399 | CONFIG_CHUNK(str, size, n, "", 1); | 396 | CONFIG_CHUNK(str, size, n, "", 1); |
400 | return n; | 397 | return n; |
401 | } | 398 | } |
@@ -415,7 +412,7 @@ static int chan_pair_config_string(struct chan *in, struct chan *out, | |||
415 | str += n; | 412 | str += n; |
416 | size -= n; | 413 | size -= n; |
417 | 414 | ||
418 | if(in == out){ | 415 | if (in == out) { |
419 | CONFIG_CHUNK(str, size, n, "", 1); | 416 | CONFIG_CHUNK(str, size, n, "", 1); |
420 | return n; | 417 | return n; |
421 | } | 418 | } |
@@ -435,13 +432,13 @@ int chan_config_string(struct list_head *chans, char *str, int size, | |||
435 | struct list_head *ele; | 432 | struct list_head *ele; |
436 | struct chan *chan, *in = NULL, *out = NULL; | 433 | struct chan *chan, *in = NULL, *out = NULL; |
437 | 434 | ||
438 | list_for_each(ele, chans){ | 435 | list_for_each(ele, chans) { |
439 | chan = list_entry(ele, struct chan, list); | 436 | chan = list_entry(ele, struct chan, list); |
440 | if(!chan->primary) | 437 | if (!chan->primary) |
441 | continue; | 438 | continue; |
442 | if(chan->input) | 439 | if (chan->input) |
443 | in = chan; | 440 | in = chan; |
444 | if(chan->output) | 441 | if (chan->output) |
445 | out = chan; | 442 | out = chan; |
446 | } | 443 | } |
447 | 444 | ||
@@ -500,27 +497,27 @@ static struct chan *parse_chan(struct line *line, char *str, int device, | |||
500 | 497 | ||
501 | ops = NULL; | 498 | ops = NULL; |
502 | data = NULL; | 499 | data = NULL; |
503 | for(i = 0; i < ARRAY_SIZE(chan_table); i++){ | 500 | for(i = 0; i < ARRAY_SIZE(chan_table); i++) { |
504 | entry = &chan_table[i]; | 501 | entry = &chan_table[i]; |
505 | if(!strncmp(str, entry->key, strlen(entry->key))){ | 502 | if (!strncmp(str, entry->key, strlen(entry->key))) { |
506 | ops = entry->ops; | 503 | ops = entry->ops; |
507 | str += strlen(entry->key); | 504 | str += strlen(entry->key); |
508 | break; | 505 | break; |
509 | } | 506 | } |
510 | } | 507 | } |
511 | if(ops == NULL){ | 508 | if (ops == NULL) { |
512 | *error_out = "No match for configured backends"; | 509 | *error_out = "No match for configured backends"; |
513 | return NULL; | 510 | return NULL; |
514 | } | 511 | } |
515 | 512 | ||
516 | data = (*ops->init)(str, device, opts); | 513 | data = (*ops->init)(str, device, opts); |
517 | if(data == NULL){ | 514 | if (data == NULL) { |
518 | *error_out = "Configuration failed"; | 515 | *error_out = "Configuration failed"; |
519 | return NULL; | 516 | return NULL; |
520 | } | 517 | } |
521 | 518 | ||
522 | chan = kmalloc(sizeof(*chan), GFP_ATOMIC); | 519 | chan = kmalloc(sizeof(*chan), GFP_ATOMIC); |
523 | if(chan == NULL){ | 520 | if (chan == NULL) { |
524 | *error_out = "Memory allocation failed"; | 521 | *error_out = "Memory allocation failed"; |
525 | return NULL; | 522 | return NULL; |
526 | } | 523 | } |
@@ -546,26 +543,26 @@ int parse_chan_pair(char *str, struct line *line, int device, | |||
546 | struct chan *new, *chan; | 543 | struct chan *new, *chan; |
547 | char *in, *out; | 544 | char *in, *out; |
548 | 545 | ||
549 | if(!list_empty(chans)){ | 546 | if (!list_empty(chans)) { |
550 | chan = list_entry(chans->next, struct chan, list); | 547 | chan = list_entry(chans->next, struct chan, list); |
551 | free_chan(chans, 0); | 548 | free_chan(chans, 0); |
552 | INIT_LIST_HEAD(chans); | 549 | INIT_LIST_HEAD(chans); |
553 | } | 550 | } |
554 | 551 | ||
555 | out = strchr(str, ','); | 552 | out = strchr(str, ','); |
556 | if(out != NULL){ | 553 | if (out != NULL) { |
557 | in = str; | 554 | in = str; |
558 | *out = '\0'; | 555 | *out = '\0'; |
559 | out++; | 556 | out++; |
560 | new = parse_chan(line, in, device, opts, error_out); | 557 | new = parse_chan(line, in, device, opts, error_out); |
561 | if(new == NULL) | 558 | if (new == NULL) |
562 | return -1; | 559 | return -1; |
563 | 560 | ||
564 | new->input = 1; | 561 | new->input = 1; |
565 | list_add(&new->list, chans); | 562 | list_add(&new->list, chans); |
566 | 563 | ||
567 | new = parse_chan(line, out, device, opts, error_out); | 564 | new = parse_chan(line, out, device, opts, error_out); |
568 | if(new == NULL) | 565 | if (new == NULL) |
569 | return -1; | 566 | return -1; |
570 | 567 | ||
571 | list_add(&new->list, chans); | 568 | list_add(&new->list, chans); |
@@ -573,7 +570,7 @@ int parse_chan_pair(char *str, struct line *line, int device, | |||
573 | } | 570 | } |
574 | else { | 571 | else { |
575 | new = parse_chan(line, str, device, opts, error_out); | 572 | new = parse_chan(line, str, device, opts, error_out); |
576 | if(new == NULL) | 573 | if (new == NULL) |
577 | return -1; | 574 | return -1; |
578 | 575 | ||
579 | list_add(&new->list, chans); | 576 | list_add(&new->list, chans); |
@@ -588,9 +585,9 @@ int chan_out_fd(struct list_head *chans) | |||
588 | struct list_head *ele; | 585 | struct list_head *ele; |
589 | struct chan *chan; | 586 | struct chan *chan; |
590 | 587 | ||
591 | list_for_each(ele, chans){ | 588 | list_for_each(ele, chans) { |
592 | chan = list_entry(ele, struct chan, list); | 589 | chan = list_entry(ele, struct chan, list); |
593 | if(chan->primary && chan->output) | 590 | if (chan->primary && chan->output) |
594 | return chan->fd; | 591 | return chan->fd; |
595 | } | 592 | } |
596 | return -1; | 593 | return -1; |
@@ -604,23 +601,25 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task, | |||
604 | int err; | 601 | int err; |
605 | char c; | 602 | char c; |
606 | 603 | ||
607 | list_for_each_safe(ele, next, chans){ | 604 | list_for_each_safe(ele, next, chans) { |
608 | chan = list_entry(ele, struct chan, list); | 605 | chan = list_entry(ele, struct chan, list); |
609 | if(!chan->input || (chan->ops->read == NULL)) continue; | 606 | if (!chan->input || (chan->ops->read == NULL)) |
607 | continue; | ||
610 | do { | 608 | do { |
611 | if (tty && !tty_buffer_request_room(tty, 1)) { | 609 | if (tty && !tty_buffer_request_room(tty, 1)) { |
612 | schedule_delayed_work(task, 1); | 610 | schedule_delayed_work(task, 1); |
613 | goto out; | 611 | goto out; |
614 | } | 612 | } |
615 | err = chan->ops->read(chan->fd, &c, chan->data); | 613 | err = chan->ops->read(chan->fd, &c, chan->data); |
616 | if(err > 0) | 614 | if (err > 0) |
617 | tty_receive_char(tty, c); | 615 | tty_receive_char(tty, c); |
618 | } while(err > 0); | 616 | } while (err > 0); |
619 | 617 | ||
620 | if(err == 0) reactivate_fd(chan->fd, irq); | 618 | if (err == 0) |
621 | if(err == -EIO){ | 619 | reactivate_fd(chan->fd, irq); |
622 | if(chan->primary){ | 620 | if (err == -EIO) { |
623 | if(tty != NULL) | 621 | if (chan->primary) { |
622 | if (tty != NULL) | ||
624 | tty_hangup(tty); | 623 | tty_hangup(tty); |
625 | close_chan(chans, 1); | 624 | close_chan(chans, 1); |
626 | return; | 625 | return; |
@@ -629,5 +628,6 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task, | |||
629 | } | 628 | } |
630 | } | 629 | } |
631 | out: | 630 | out: |
632 | if(tty) tty_flip_buffer_push(tty); | 631 | if (tty) |
632 | tty_flip_buffer_push(tty); | ||
633 | } | 633 | } |
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 40271afa3ee2..77557e233f58 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c | |||
@@ -1,25 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <unistd.h> | ||
7 | #include <stdlib.h> | 6 | #include <stdlib.h> |
7 | #include <unistd.h> | ||
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <termios.h> | ||
10 | #include <string.h> | ||
11 | #include <signal.h> | ||
12 | #include <sched.h> | 9 | #include <sched.h> |
13 | #include <sys/stat.h> | 10 | #include <signal.h> |
11 | #include <termios.h> | ||
14 | #include <sys/ioctl.h> | 12 | #include <sys/ioctl.h> |
15 | #include <sys/socket.h> | ||
16 | #include "kern_util.h" | ||
17 | #include "chan_user.h" | 13 | #include "chan_user.h" |
18 | #include "user.h" | ||
19 | #include "os.h" | 14 | #include "os.h" |
20 | #include "choose-mode.h" | ||
21 | #include "mode.h" | ||
22 | #include "um_malloc.h" | 15 | #include "um_malloc.h" |
16 | #include "user.h" | ||
23 | 17 | ||
24 | void generic_close(int fd, void *unused) | 18 | void generic_close(int fd, void *unused) |
25 | { | 19 | { |
@@ -53,7 +47,7 @@ int generic_window_size(int fd, void *unused, unsigned short *rows_out, | |||
53 | struct winsize size; | 47 | struct winsize size; |
54 | int ret; | 48 | int ret; |
55 | 49 | ||
56 | if(ioctl(fd, TIOCGWINSZ, &size) < 0) | 50 | if (ioctl(fd, TIOCGWINSZ, &size) < 0) |
57 | return -errno; | 51 | return -errno; |
58 | 52 | ||
59 | ret = ((*rows_out != size.ws_row) || (*cols_out != size.ws_col)); | 53 | ret = ((*rows_out != size.ws_row) || (*cols_out != size.ws_col)); |
@@ -74,7 +68,7 @@ int generic_console_write(int fd, const char *buf, int n) | |||
74 | struct termios save, new; | 68 | struct termios save, new; |
75 | int err; | 69 | int err; |
76 | 70 | ||
77 | if(isatty(fd)){ | 71 | if (isatty(fd)) { |
78 | CATCH_EINTR(err = tcgetattr(fd, &save)); | 72 | CATCH_EINTR(err = tcgetattr(fd, &save)); |
79 | if (err) | 73 | if (err) |
80 | goto error; | 74 | goto error; |
@@ -90,11 +84,11 @@ int generic_console_write(int fd, const char *buf, int n) | |||
90 | err = generic_write(fd, buf, n, NULL); | 84 | err = generic_write(fd, buf, n, NULL); |
91 | /* Restore raw mode, in any case; we *must* ignore any error apart | 85 | /* Restore raw mode, in any case; we *must* ignore any error apart |
92 | * EINTR, except for debug.*/ | 86 | * EINTR, except for debug.*/ |
93 | if(isatty(fd)) | 87 | if (isatty(fd)) |
94 | CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save)); | 88 | CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save)); |
95 | return(err); | 89 | return err; |
96 | error: | 90 | error: |
97 | return(-errno); | 91 | return -errno; |
98 | } | 92 | } |
99 | 93 | ||
100 | /* | 94 | /* |
@@ -137,56 +131,62 @@ static int winch_thread(void *arg) | |||
137 | pty_fd = data->pty_fd; | 131 | pty_fd = data->pty_fd; |
138 | pipe_fd = data->pipe_fd; | 132 | pipe_fd = data->pipe_fd; |
139 | count = os_write_file(pipe_fd, &c, sizeof(c)); | 133 | count = os_write_file(pipe_fd, &c, sizeof(c)); |
140 | if(count != sizeof(c)) | 134 | if (count != sizeof(c)) |
141 | printk("winch_thread : failed to write synchronization " | 135 | printk(UM_KERN_ERR "winch_thread : failed to write " |
142 | "byte, err = %d\n", -count); | 136 | "synchronization byte, err = %d\n", -count); |
143 | 137 | ||
144 | /* We are not using SIG_IGN on purpose, so don't fix it as I thought to | 138 | /* |
139 | * We are not using SIG_IGN on purpose, so don't fix it as I thought to | ||
145 | * do! If using SIG_IGN, the sigsuspend() call below would not stop on | 140 | * do! If using SIG_IGN, the sigsuspend() call below would not stop on |
146 | * SIGWINCH. */ | 141 | * SIGWINCH. |
142 | */ | ||
147 | 143 | ||
148 | signal(SIGWINCH, winch_handler); | 144 | signal(SIGWINCH, winch_handler); |
149 | sigfillset(&sigs); | 145 | sigfillset(&sigs); |
150 | /* Block all signals possible. */ | 146 | /* Block all signals possible. */ |
151 | if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){ | 147 | if (sigprocmask(SIG_SETMASK, &sigs, NULL) < 0) { |
152 | printk("winch_thread : sigprocmask failed, errno = %d\n", | 148 | printk(UM_KERN_ERR "winch_thread : sigprocmask failed, " |
153 | errno); | 149 | "errno = %d\n", errno); |
154 | exit(1); | 150 | exit(1); |
155 | } | 151 | } |
156 | /* In sigsuspend(), block anything else than SIGWINCH. */ | 152 | /* In sigsuspend(), block anything else than SIGWINCH. */ |
157 | sigdelset(&sigs, SIGWINCH); | 153 | sigdelset(&sigs, SIGWINCH); |
158 | 154 | ||
159 | if(setsid() < 0){ | 155 | if (setsid() < 0) { |
160 | printk("winch_thread : setsid failed, errno = %d\n", errno); | 156 | printk(UM_KERN_ERR "winch_thread : setsid failed, errno = %d\n", |
157 | errno); | ||
161 | exit(1); | 158 | exit(1); |
162 | } | 159 | } |
163 | 160 | ||
164 | err = os_new_tty_pgrp(pty_fd, os_getpid()); | 161 | err = os_new_tty_pgrp(pty_fd, os_getpid()); |
165 | if(err < 0){ | 162 | if (err < 0) { |
166 | printk("winch_thread : new_tty_pgrp failed on fd %d, " | 163 | printk(UM_KERN_ERR "winch_thread : new_tty_pgrp failed on " |
167 | "err = %d\n", pty_fd, -err); | 164 | "fd %d err = %d\n", pty_fd, -err); |
168 | exit(1); | 165 | exit(1); |
169 | } | 166 | } |
170 | 167 | ||
171 | /* These are synchronization calls between various UML threads on the | 168 | /* |
169 | * These are synchronization calls between various UML threads on the | ||
172 | * host - since they are not different kernel threads, we cannot use | 170 | * host - since they are not different kernel threads, we cannot use |
173 | * kernel semaphores. We don't use SysV semaphores because they are | 171 | * kernel semaphores. We don't use SysV semaphores because they are |
174 | * persistent. */ | 172 | * persistent. |
173 | */ | ||
175 | count = os_read_file(pipe_fd, &c, sizeof(c)); | 174 | count = os_read_file(pipe_fd, &c, sizeof(c)); |
176 | if(count != sizeof(c)) | 175 | if (count != sizeof(c)) |
177 | printk("winch_thread : failed to read synchronization byte, " | 176 | printk(UM_KERN_ERR "winch_thread : failed to read " |
178 | "err = %d\n", -count); | 177 | "synchronization byte, err = %d\n", -count); |
179 | 178 | ||
180 | while(1){ | 179 | while(1) { |
181 | /* This will be interrupted by SIGWINCH only, since | 180 | /* |
181 | * This will be interrupted by SIGWINCH only, since | ||
182 | * other signals are blocked. | 182 | * other signals are blocked. |
183 | */ | 183 | */ |
184 | sigsuspend(&sigs); | 184 | sigsuspend(&sigs); |
185 | 185 | ||
186 | count = os_write_file(pipe_fd, &c, sizeof(c)); | 186 | count = os_write_file(pipe_fd, &c, sizeof(c)); |
187 | if(count != sizeof(c)) | 187 | if (count != sizeof(c)) |
188 | printk("winch_thread : write failed, err = %d\n", | 188 | printk(UM_KERN_ERR "winch_thread : write failed, " |
189 | -count); | 189 | "err = %d\n", -count); |
190 | } | 190 | } |
191 | } | 191 | } |
192 | 192 | ||
@@ -198,36 +198,41 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out, | |||
198 | char c; | 198 | char c; |
199 | 199 | ||
200 | err = os_pipe(fds, 1, 1); | 200 | err = os_pipe(fds, 1, 1); |
201 | if(err < 0){ | 201 | if (err < 0) { |
202 | printk("winch_tramp : os_pipe failed, err = %d\n", -err); | 202 | printk(UM_KERN_ERR "winch_tramp : os_pipe failed, err = %d\n", |
203 | -err); | ||
203 | goto out; | 204 | goto out; |
204 | } | 205 | } |
205 | 206 | ||
206 | data = ((struct winch_data) { .pty_fd = fd, | 207 | data = ((struct winch_data) { .pty_fd = fd, |
207 | .pipe_fd = fds[1] } ); | 208 | .pipe_fd = fds[1] } ); |
208 | /* CLONE_FILES so this thread doesn't hold open files which are open | 209 | /* |
210 | * CLONE_FILES so this thread doesn't hold open files which are open | ||
209 | * now, but later closed in a different thread. This is a | 211 | * now, but later closed in a different thread. This is a |
210 | * problem with /dev/net/tun, which if held open by this | 212 | * problem with /dev/net/tun, which if held open by this |
211 | * thread, prevents the TUN/TAP device from being reused. | 213 | * thread, prevents the TUN/TAP device from being reused. |
212 | */ | 214 | */ |
213 | err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); | 215 | err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); |
214 | if(err < 0){ | 216 | if (err < 0) { |
215 | printk("fork of winch_thread failed - errno = %d\n", -err); | 217 | printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n", |
218 | -err); | ||
216 | goto out_close; | 219 | goto out_close; |
217 | } | 220 | } |
218 | 221 | ||
219 | *fd_out = fds[0]; | 222 | *fd_out = fds[0]; |
220 | n = os_read_file(fds[0], &c, sizeof(c)); | 223 | n = os_read_file(fds[0], &c, sizeof(c)); |
221 | if(n != sizeof(c)){ | 224 | if (n != sizeof(c)) { |
222 | printk("winch_tramp : failed to read synchronization byte\n"); | 225 | printk(UM_KERN_ERR "winch_tramp : failed to read " |
223 | printk("read failed, err = %d\n", -n); | 226 | "synchronization byte\n"); |
224 | printk("fd %d will not support SIGWINCH\n", fd); | 227 | printk(UM_KERN_ERR "read failed, err = %d\n", -n); |
225 | err = -EINVAL; | 228 | printk(UM_KERN_ERR "fd %d will not support SIGWINCH\n", fd); |
229 | err = -EINVAL; | ||
226 | goto out_close; | 230 | goto out_close; |
227 | } | 231 | } |
228 | 232 | ||
229 | if (os_set_fd_block(*fd_out, 0)) { | 233 | if (os_set_fd_block(*fd_out, 0)) { |
230 | printk("winch_tramp: failed to set thread_fd non-blocking.\n"); | 234 | printk(UM_KERN_ERR "winch_tramp: failed to set thread_fd " |
235 | "non-blocking.\n"); | ||
231 | goto out_close; | 236 | goto out_close; |
232 | } | 237 | } |
233 | 238 | ||
@@ -246,7 +251,7 @@ void register_winch(int fd, struct tty_struct *tty) | |||
246 | int pid, thread, count, thread_fd = -1; | 251 | int pid, thread, count, thread_fd = -1; |
247 | char c = 1; | 252 | char c = 1; |
248 | 253 | ||
249 | if(!isatty(fd)) | 254 | if (!isatty(fd)) |
250 | return; | 255 | return; |
251 | 256 | ||
252 | pid = tcgetpgrp(fd); | 257 | pid = tcgetpgrp(fd); |
@@ -259,8 +264,8 @@ void register_winch(int fd, struct tty_struct *tty) | |||
259 | register_winch_irq(thread_fd, fd, thread, tty, stack); | 264 | register_winch_irq(thread_fd, fd, thread, tty, stack); |
260 | 265 | ||
261 | count = os_write_file(thread_fd, &c, sizeof(c)); | 266 | count = os_write_file(thread_fd, &c, sizeof(c)); |
262 | if(count != sizeof(c)) | 267 | if (count != sizeof(c)) |
263 | printk("register_winch : failed to write " | 268 | printk(UM_KERN_ERR "register_winch : failed to write " |
264 | "synchronization byte, err = %d\n", -count); | 269 | "synchronization byte, err = %d\n", -count); |
265 | } | 270 | } |
266 | } | 271 | } |
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index 39c01ffd45c9..207b0444c9d9 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c | |||
@@ -1,17 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdio.h> | 6 | #include <stddef.h> |
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <unistd.h> | 8 | #include <stdio.h> |
9 | #include <termios.h> | ||
10 | #include <errno.h> | 9 | #include <errno.h> |
11 | #include "user.h" | 10 | #include <termios.h> |
11 | #include <unistd.h> | ||
12 | #include "chan_user.h" | 12 | #include "chan_user.h" |
13 | #include "os.h" | ||
14 | #include "um_malloc.h" | 13 | #include "um_malloc.h" |
14 | #include "user.h" | ||
15 | #include "os.h" | ||
16 | #include "kern_constants.h" | ||
15 | 17 | ||
16 | struct fd_chan { | 18 | struct fd_chan { |
17 | int fd; | 19 | int fd; |
@@ -26,22 +28,26 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts) | |||
26 | char *end; | 28 | char *end; |
27 | int n; | 29 | int n; |
28 | 30 | ||
29 | if(*str != ':'){ | 31 | if (*str != ':') { |
30 | printk("fd_init : channel type 'fd' must specify a file " | 32 | printk(UM_KERN_ERR "fd_init : channel type 'fd' must specify a " |
31 | "descriptor\n"); | 33 | "file descriptor\n"); |
32 | return(NULL); | 34 | return NULL; |
33 | } | 35 | } |
34 | str++; | 36 | str++; |
35 | n = strtoul(str, &end, 0); | 37 | n = strtoul(str, &end, 0); |
36 | if((*end != '\0') || (end == str)){ | 38 | if ((*end != '\0') || (end == str)) { |
37 | printk("fd_init : couldn't parse file descriptor '%s'\n", str); | 39 | printk(UM_KERN_ERR "fd_init : couldn't parse file descriptor " |
38 | return(NULL); | 40 | "'%s'\n", str); |
41 | return NULL; | ||
39 | } | 42 | } |
43 | |||
40 | data = kmalloc(sizeof(*data), UM_GFP_KERNEL); | 44 | data = kmalloc(sizeof(*data), UM_GFP_KERNEL); |
41 | if(data == NULL) return(NULL); | 45 | if(data == NULL) |
46 | return NULL; | ||
47 | |||
42 | *data = ((struct fd_chan) { .fd = n, | 48 | *data = ((struct fd_chan) { .fd = n, |
43 | .raw = opts->raw }); | 49 | .raw = opts->raw }); |
44 | return(data); | 50 | return data; |
45 | } | 51 | } |
46 | 52 | ||
47 | static int fd_open(int input, int output, int primary, void *d, char **dev_out) | 53 | static int fd_open(int input, int output, int primary, void *d, char **dev_out) |
@@ -49,18 +55,18 @@ static int fd_open(int input, int output, int primary, void *d, char **dev_out) | |||
49 | struct fd_chan *data = d; | 55 | struct fd_chan *data = d; |
50 | int err; | 56 | int err; |
51 | 57 | ||
52 | if(data->raw && isatty(data->fd)){ | 58 | if (data->raw && isatty(data->fd)) { |
53 | CATCH_EINTR(err = tcgetattr(data->fd, &data->tt)); | 59 | CATCH_EINTR(err = tcgetattr(data->fd, &data->tt)); |
54 | if(err) | 60 | if (err) |
55 | return(err); | 61 | return err; |
56 | 62 | ||
57 | err = raw(data->fd); | 63 | err = raw(data->fd); |
58 | if(err) | 64 | if (err) |
59 | return(err); | 65 | return err; |
60 | } | 66 | } |
61 | sprintf(data->str, "%d", data->fd); | 67 | sprintf(data->str, "%d", data->fd); |
62 | *dev_out = data->str; | 68 | *dev_out = data->str; |
63 | return(data->fd); | 69 | return data->fd; |
64 | } | 70 | } |
65 | 71 | ||
66 | static void fd_close(int fd, void *d) | 72 | static void fd_close(int fd, void *d) |
@@ -68,13 +74,14 @@ static void fd_close(int fd, void *d) | |||
68 | struct fd_chan *data = d; | 74 | struct fd_chan *data = d; |
69 | int err; | 75 | int err; |
70 | 76 | ||
71 | if(data->raw && isatty(fd)){ | 77 | if (!data->raw || !isatty(fd)) |
72 | CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt)); | 78 | return; |
73 | if(err) | 79 | |
74 | printk("Failed to restore terminal state - " | 80 | CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt)); |
75 | "errno = %d\n", -err); | 81 | if (err) |
76 | data->raw = 0; | 82 | printk(UM_KERN_ERR "Failed to restore terminal state - " |
77 | } | 83 | "errno = %d\n", -err); |
84 | data->raw = 0; | ||
78 | } | 85 | } |
79 | 86 | ||
80 | const struct chan_ops fd_ops = { | 87 | const struct chan_ops fd_ops = { |
@@ -89,14 +96,3 @@ const struct chan_ops fd_ops = { | |||
89 | .free = generic_free, | 96 | .free = generic_free, |
90 | .winch = 1, | 97 | .winch = 1, |
91 | }; | 98 | }; |
92 | |||
93 | /* | ||
94 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
95 | * Emacs will notice this stuff at the end of the file and automatically | ||
96 | * adjust the settings for this buffer only. This must remain at the end | ||
97 | * of the file. | ||
98 | * --------------------------------------------------------------------------- | ||
99 | * Local variables: | ||
100 | * c-file-style: "linux" | ||
101 | * End: | ||
102 | */ | ||
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c index 9016c68beee8..b808641ee679 100644 --- a/arch/um/drivers/null.c +++ b/arch/um/drivers/null.c | |||
@@ -1,31 +1,36 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdlib.h> | 6 | #include <stddef.h> |
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include "chan_user.h" | 8 | #include <fcntl.h> |
9 | #include "os.h" | 9 | #include "os.h" |
10 | #include "chan_user.h" | ||
10 | 11 | ||
11 | /* This address is used only as a unique identifer */ | 12 | /* This address is used only as a unique identifer */ |
12 | static int null_chan; | 13 | static int null_chan; |
13 | 14 | ||
14 | static void *null_init(char *str, int device, const struct chan_opts *opts) | 15 | static void *null_init(char *str, int device, const struct chan_opts *opts) |
15 | { | 16 | { |
16 | return(&null_chan); | 17 | return &null_chan; |
17 | } | 18 | } |
18 | 19 | ||
19 | static int null_open(int input, int output, int primary, void *d, | 20 | static int null_open(int input, int output, int primary, void *d, |
20 | char **dev_out) | 21 | char **dev_out) |
21 | { | 22 | { |
23 | int fd; | ||
24 | |||
22 | *dev_out = NULL; | 25 | *dev_out = NULL; |
23 | return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0)); | 26 | |
27 | fd = open(DEV_NULL, O_RDWR); | ||
28 | return (fd < 0) ? -errno : fd; | ||
24 | } | 29 | } |
25 | 30 | ||
26 | static int null_read(int fd, char *c_out, void *unused) | 31 | static int null_read(int fd, char *c_out, void *unused) |
27 | { | 32 | { |
28 | return(-ENODEV); | 33 | return -ENODEV; |
29 | } | 34 | } |
30 | 35 | ||
31 | static void null_free(void *data) | 36 | static void null_free(void *data) |
@@ -44,14 +49,3 @@ const struct chan_ops null_ops = { | |||
44 | .free = null_free, | 49 | .free = null_free, |
45 | .winch = 0, | 50 | .winch = 0, |
46 | }; | 51 | }; |
47 | |||
48 | /* | ||
49 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
50 | * Emacs will notice this stuff at the end of the file and automatically | ||
51 | * adjust the settings for this buffer only. This must remain at the end | ||
52 | * of the file. | ||
53 | * --------------------------------------------------------------------------- | ||
54 | * Local variables: | ||
55 | * c-file-style: "linux" | ||
56 | * End: | ||
57 | */ | ||
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index d8acf7470e70..330543b3129b 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c | |||
@@ -1,24 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/list.h" | 6 | #include "linux/completion.h" |
7 | #include "linux/sched.h" | ||
8 | #include "linux/slab.h" | ||
9 | #include "linux/interrupt.h" | 7 | #include "linux/interrupt.h" |
10 | #include "linux/spinlock.h" | 8 | #include "linux/list.h" |
11 | #include "linux/errno.h" | ||
12 | #include "asm/atomic.h" | 9 | #include "asm/atomic.h" |
13 | #include "asm/semaphore.h" | ||
14 | #include "asm/errno.h" | ||
15 | #include "kern_util.h" | ||
16 | #include "kern.h" | ||
17 | #include "irq_user.h" | ||
18 | #include "irq_kern.h" | ||
19 | #include "port.h" | ||
20 | #include "init.h" | 10 | #include "init.h" |
11 | #include "irq_kern.h" | ||
21 | #include "os.h" | 12 | #include "os.h" |
13 | #include "port.h" | ||
22 | 14 | ||
23 | struct port_list { | 15 | struct port_list { |
24 | struct list_head list; | 16 | struct list_head list; |
@@ -53,8 +45,8 @@ static irqreturn_t pipe_interrupt(int irq, void *data) | |||
53 | int fd; | 45 | int fd; |
54 | 46 | ||
55 | fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); | 47 | fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); |
56 | if(fd < 0){ | 48 | if (fd < 0) { |
57 | if(fd == -EAGAIN) | 49 | if (fd == -EAGAIN) |
58 | return IRQ_NONE; | 50 | return IRQ_NONE; |
59 | 51 | ||
60 | printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", | 52 | printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", |
@@ -81,18 +73,18 @@ static irqreturn_t pipe_interrupt(int irq, void *data) | |||
81 | static int port_accept(struct port_list *port) | 73 | static int port_accept(struct port_list *port) |
82 | { | 74 | { |
83 | struct connection *conn; | 75 | struct connection *conn; |
84 | int fd, socket[2], pid, ret = 0; | 76 | int fd, socket[2], pid; |
85 | 77 | ||
86 | fd = port_connection(port->fd, socket, &pid); | 78 | fd = port_connection(port->fd, socket, &pid); |
87 | if(fd < 0){ | 79 | if (fd < 0) { |
88 | if(fd != -EAGAIN) | 80 | if (fd != -EAGAIN) |
89 | printk(KERN_ERR "port_accept : port_connection " | 81 | printk(KERN_ERR "port_accept : port_connection " |
90 | "returned %d\n", -fd); | 82 | "returned %d\n", -fd); |
91 | goto out; | 83 | goto out; |
92 | } | 84 | } |
93 | 85 | ||
94 | conn = kmalloc(sizeof(*conn), GFP_ATOMIC); | 86 | conn = kmalloc(sizeof(*conn), GFP_ATOMIC); |
95 | if(conn == NULL){ | 87 | if (conn == NULL) { |
96 | printk(KERN_ERR "port_accept : failed to allocate " | 88 | printk(KERN_ERR "port_accept : failed to allocate " |
97 | "connection\n"); | 89 | "connection\n"); |
98 | goto out_close; | 90 | goto out_close; |
@@ -104,17 +96,17 @@ static int port_accept(struct port_list *port) | |||
104 | .telnetd_pid = pid, | 96 | .telnetd_pid = pid, |
105 | .port = port }); | 97 | .port = port }); |
106 | 98 | ||
107 | if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, | 99 | if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, |
108 | IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 100 | IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, |
109 | "telnetd", conn)){ | 101 | "telnetd", conn)) { |
110 | printk(KERN_ERR "port_accept : failed to get IRQ for " | 102 | printk(KERN_ERR "port_accept : failed to get IRQ for " |
111 | "telnetd\n"); | 103 | "telnetd\n"); |
112 | goto out_free; | 104 | goto out_free; |
113 | } | 105 | } |
114 | 106 | ||
115 | if(atomic_read(&port->wait_count) == 0){ | 107 | if (atomic_read(&port->wait_count) == 0) { |
116 | os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); | 108 | os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); |
117 | printk("No one waiting for port\n"); | 109 | printk(KERN_ERR "No one waiting for port\n"); |
118 | } | 110 | } |
119 | list_add(&conn->list, &port->pending); | 111 | list_add(&conn->list, &port->pending); |
120 | return 1; | 112 | return 1; |
@@ -123,28 +115,29 @@ static int port_accept(struct port_list *port) | |||
123 | kfree(conn); | 115 | kfree(conn); |
124 | out_close: | 116 | out_close: |
125 | os_close_file(fd); | 117 | os_close_file(fd); |
126 | if(pid != -1) | 118 | os_kill_process(pid, 1); |
127 | os_kill_process(pid, 1); | ||
128 | out: | 119 | out: |
129 | return ret; | 120 | return 0; |
130 | } | 121 | } |
131 | 122 | ||
132 | static DECLARE_MUTEX(ports_sem); | 123 | static DECLARE_MUTEX(ports_sem); |
133 | static LIST_HEAD(ports); | 124 | static LIST_HEAD(ports); |
134 | 125 | ||
135 | void port_work_proc(struct work_struct *unused) | 126 | static void port_work_proc(struct work_struct *unused) |
136 | { | 127 | { |
137 | struct port_list *port; | 128 | struct port_list *port; |
138 | struct list_head *ele; | 129 | struct list_head *ele; |
139 | unsigned long flags; | 130 | unsigned long flags; |
140 | 131 | ||
141 | local_irq_save(flags); | 132 | local_irq_save(flags); |
142 | list_for_each(ele, &ports){ | 133 | list_for_each(ele, &ports) { |
143 | port = list_entry(ele, struct port_list, list); | 134 | port = list_entry(ele, struct port_list, list); |
144 | if(!port->has_connection) | 135 | if (!port->has_connection) |
145 | continue; | 136 | continue; |
137 | |||
146 | reactivate_fd(port->fd, ACCEPT_IRQ); | 138 | reactivate_fd(port->fd, ACCEPT_IRQ); |
147 | while(port_accept(port)) ; | 139 | while (port_accept(port)) |
140 | ; | ||
148 | port->has_connection = 0; | 141 | port->has_connection = 0; |
149 | } | 142 | } |
150 | local_irq_restore(flags); | 143 | local_irq_restore(flags); |
@@ -169,25 +162,27 @@ void *port_data(int port_num) | |||
169 | int fd; | 162 | int fd; |
170 | 163 | ||
171 | down(&ports_sem); | 164 | down(&ports_sem); |
172 | list_for_each(ele, &ports){ | 165 | list_for_each(ele, &ports) { |
173 | port = list_entry(ele, struct port_list, list); | 166 | port = list_entry(ele, struct port_list, list); |
174 | if(port->port == port_num) goto found; | 167 | if (port->port == port_num) |
168 | goto found; | ||
175 | } | 169 | } |
176 | port = kmalloc(sizeof(struct port_list), GFP_KERNEL); | 170 | port = kmalloc(sizeof(struct port_list), GFP_KERNEL); |
177 | if(port == NULL){ | 171 | if (port == NULL) { |
178 | printk(KERN_ERR "Allocation of port list failed\n"); | 172 | printk(KERN_ERR "Allocation of port list failed\n"); |
179 | goto out; | 173 | goto out; |
180 | } | 174 | } |
181 | 175 | ||
182 | fd = port_listen_fd(port_num); | 176 | fd = port_listen_fd(port_num); |
183 | if(fd < 0){ | 177 | if (fd < 0) { |
184 | printk(KERN_ERR "binding to port %d failed, errno = %d\n", | 178 | printk(KERN_ERR "binding to port %d failed, errno = %d\n", |
185 | port_num, -fd); | 179 | port_num, -fd); |
186 | goto out_free; | 180 | goto out_free; |
187 | } | 181 | } |
188 | if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, | 182 | |
183 | if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, | ||
189 | IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 184 | IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, |
190 | "port", port)){ | 185 | "port", port)) { |
191 | printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); | 186 | printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); |
192 | goto out_close; | 187 | goto out_close; |
193 | } | 188 | } |
@@ -206,7 +201,7 @@ void *port_data(int port_num) | |||
206 | 201 | ||
207 | found: | 202 | found: |
208 | dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL); | 203 | dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL); |
209 | if(dev == NULL){ | 204 | if (dev == NULL) { |
210 | printk(KERN_ERR "Allocation of port device entry failed\n"); | 205 | printk(KERN_ERR "Allocation of port device entry failed\n"); |
211 | goto out; | 206 | goto out; |
212 | } | 207 | } |
@@ -233,9 +228,9 @@ int port_wait(void *data) | |||
233 | int fd; | 228 | int fd; |
234 | 229 | ||
235 | atomic_inc(&port->wait_count); | 230 | atomic_inc(&port->wait_count); |
236 | while(1){ | 231 | while (1) { |
237 | fd = -ERESTARTSYS; | 232 | fd = -ERESTARTSYS; |
238 | if(wait_for_completion_interruptible(&port->done)) | 233 | if (wait_for_completion_interruptible(&port->done)) |
239 | goto out; | 234 | goto out; |
240 | 235 | ||
241 | spin_lock(&port->lock); | 236 | spin_lock(&port->lock); |
@@ -258,7 +253,8 @@ int port_wait(void *data) | |||
258 | */ | 253 | */ |
259 | free_irq(TELNETD_IRQ, conn); | 254 | free_irq(TELNETD_IRQ, conn); |
260 | 255 | ||
261 | if(conn->fd >= 0) break; | 256 | if (conn->fd >= 0) |
257 | break; | ||
262 | os_close_file(conn->fd); | 258 | os_close_file(conn->fd); |
263 | kfree(conn); | 259 | kfree(conn); |
264 | } | 260 | } |
@@ -276,9 +272,9 @@ void port_remove_dev(void *d) | |||
276 | { | 272 | { |
277 | struct port_dev *dev = d; | 273 | struct port_dev *dev = d; |
278 | 274 | ||
279 | if(dev->helper_pid != -1) | 275 | if (dev->helper_pid != -1) |
280 | os_kill_process(dev->helper_pid, 0); | 276 | os_kill_process(dev->helper_pid, 0); |
281 | if(dev->telnetd_pid != -1) | 277 | if (dev->telnetd_pid != -1) |
282 | os_kill_process(dev->telnetd_pid, 1); | 278 | os_kill_process(dev->telnetd_pid, 1); |
283 | dev->helper_pid = -1; | 279 | dev->helper_pid = -1; |
284 | dev->telnetd_pid = -1; | 280 | dev->telnetd_pid = -1; |
@@ -297,7 +293,7 @@ static void free_port(void) | |||
297 | struct list_head *ele; | 293 | struct list_head *ele; |
298 | struct port_list *port; | 294 | struct port_list *port; |
299 | 295 | ||
300 | list_for_each(ele, &ports){ | 296 | list_for_each(ele, &ports) { |
301 | port = list_entry(ele, struct port_list, list); | 297 | port = list_entry(ele, struct port_list, list); |
302 | free_irq_by_fd(port->fd); | 298 | free_irq_by_fd(port->fd); |
303 | os_close_file(port->fd); | 299 | os_close_file(port->fd); |
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index c799b00012c7..addd75902656 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c | |||
@@ -1,24 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdio.h> | 6 | #include <stdio.h> |
7 | #include <stddef.h> | ||
8 | #include <stdlib.h> | 7 | #include <stdlib.h> |
9 | #include <string.h> | ||
10 | #include <errno.h> | 8 | #include <errno.h> |
11 | #include <unistd.h> | ||
12 | #include <termios.h> | 9 | #include <termios.h> |
13 | #include <sys/socket.h> | 10 | #include <unistd.h> |
14 | #include <sys/un.h> | ||
15 | #include <netinet/in.h> | 11 | #include <netinet/in.h> |
16 | #include "kern_util.h" | ||
17 | #include "user.h" | ||
18 | #include "chan_user.h" | 12 | #include "chan_user.h" |
19 | #include "port.h" | 13 | #include "kern_constants.h" |
20 | #include "os.h" | 14 | #include "os.h" |
15 | #include "port.h" | ||
21 | #include "um_malloc.h" | 16 | #include "um_malloc.h" |
17 | #include "user.h" | ||
22 | 18 | ||
23 | struct port_chan { | 19 | struct port_chan { |
24 | int raw; | 20 | int raw; |
@@ -34,24 +30,25 @@ static void *port_init(char *str, int device, const struct chan_opts *opts) | |||
34 | char *end; | 30 | char *end; |
35 | int port; | 31 | int port; |
36 | 32 | ||
37 | if(*str != ':'){ | 33 | if (*str != ':') { |
38 | printk("port_init : channel type 'port' must specify a " | 34 | printk(UM_KERN_ERR "port_init : channel type 'port' must " |
39 | "port number\n"); | 35 | "specify a port number\n"); |
40 | return NULL; | 36 | return NULL; |
41 | } | 37 | } |
42 | str++; | 38 | str++; |
43 | port = strtoul(str, &end, 0); | 39 | port = strtoul(str, &end, 0); |
44 | if((*end != '\0') || (end == str)){ | 40 | if ((*end != '\0') || (end == str)) { |
45 | printk("port_init : couldn't parse port '%s'\n", str); | 41 | printk(UM_KERN_ERR "port_init : couldn't parse port '%s'\n", |
42 | str); | ||
46 | return NULL; | 43 | return NULL; |
47 | } | 44 | } |
48 | 45 | ||
49 | kern_data = port_data(port); | 46 | kern_data = port_data(port); |
50 | if(kern_data == NULL) | 47 | if (kern_data == NULL) |
51 | return NULL; | 48 | return NULL; |
52 | 49 | ||
53 | data = kmalloc(sizeof(*data), UM_GFP_KERNEL); | 50 | data = kmalloc(sizeof(*data), UM_GFP_KERNEL); |
54 | if(data == NULL) | 51 | if (data == NULL) |
55 | goto err; | 52 | goto err; |
56 | 53 | ||
57 | *data = ((struct port_chan) { .raw = opts->raw, | 54 | *data = ((struct port_chan) { .raw = opts->raw, |
@@ -79,13 +76,13 @@ static int port_open(int input, int output, int primary, void *d, | |||
79 | int fd, err; | 76 | int fd, err; |
80 | 77 | ||
81 | fd = port_wait(data->kernel_data); | 78 | fd = port_wait(data->kernel_data); |
82 | if((fd >= 0) && data->raw){ | 79 | if ((fd >= 0) && data->raw) { |
83 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); | 80 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); |
84 | if(err) | 81 | if (err) |
85 | return err; | 82 | return err; |
86 | 83 | ||
87 | err = raw(fd); | 84 | err = raw(fd); |
88 | if(err) | 85 | if (err) |
89 | return err; | 86 | return err; |
90 | } | 87 | } |
91 | *dev_out = data->dev; | 88 | *dev_out = data->dev; |
@@ -119,11 +116,11 @@ int port_listen_fd(int port) | |||
119 | int fd, err, arg; | 116 | int fd, err, arg; |
120 | 117 | ||
121 | fd = socket(PF_INET, SOCK_STREAM, 0); | 118 | fd = socket(PF_INET, SOCK_STREAM, 0); |
122 | if(fd == -1) | 119 | if (fd == -1) |
123 | return -errno; | 120 | return -errno; |
124 | 121 | ||
125 | arg = 1; | 122 | arg = 1; |
126 | if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){ | 123 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0) { |
127 | err = -errno; | 124 | err = -errno; |
128 | goto out; | 125 | goto out; |
129 | } | 126 | } |
@@ -131,23 +128,23 @@ int port_listen_fd(int port) | |||
131 | addr.sin_family = AF_INET; | 128 | addr.sin_family = AF_INET; |
132 | addr.sin_port = htons(port); | 129 | addr.sin_port = htons(port); |
133 | addr.sin_addr.s_addr = htonl(INADDR_ANY); | 130 | addr.sin_addr.s_addr = htonl(INADDR_ANY); |
134 | if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){ | 131 | if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { |
135 | err = -errno; | 132 | err = -errno; |
136 | goto out; | 133 | goto out; |
137 | } | 134 | } |
138 | 135 | ||
139 | if(listen(fd, 1) < 0){ | 136 | if (listen(fd, 1) < 0) { |
140 | err = -errno; | 137 | err = -errno; |
141 | goto out; | 138 | goto out; |
142 | } | 139 | } |
143 | 140 | ||
144 | err = os_set_fd_block(fd, 0); | 141 | err = os_set_fd_block(fd, 0); |
145 | if(err < 0) | 142 | if (err < 0) |
146 | goto out; | 143 | goto out; |
147 | 144 | ||
148 | return fd; | 145 | return fd; |
149 | out: | 146 | out: |
150 | os_close_file(fd); | 147 | close(fd); |
151 | return err; | 148 | return err; |
152 | } | 149 | } |
153 | 150 | ||
@@ -163,10 +160,10 @@ void port_pre_exec(void *arg) | |||
163 | dup2(data->sock_fd, 0); | 160 | dup2(data->sock_fd, 0); |
164 | dup2(data->sock_fd, 1); | 161 | dup2(data->sock_fd, 1); |
165 | dup2(data->sock_fd, 2); | 162 | dup2(data->sock_fd, 2); |
166 | os_close_file(data->sock_fd); | 163 | close(data->sock_fd); |
167 | dup2(data->pipe_fd, 3); | 164 | dup2(data->pipe_fd, 3); |
168 | os_shutdown_socket(3, 1, 0); | 165 | shutdown(3, SHUT_RD); |
169 | os_close_file(data->pipe_fd); | 166 | close(data->pipe_fd); |
170 | } | 167 | } |
171 | 168 | ||
172 | int port_connection(int fd, int *socket, int *pid_out) | 169 | int port_connection(int fd, int *socket, int *pid_out) |
@@ -176,12 +173,12 @@ int port_connection(int fd, int *socket, int *pid_out) | |||
176 | "/usr/lib/uml/port-helper", NULL }; | 173 | "/usr/lib/uml/port-helper", NULL }; |
177 | struct port_pre_exec_data data; | 174 | struct port_pre_exec_data data; |
178 | 175 | ||
179 | new = os_accept_connection(fd); | 176 | new = accept(fd, NULL, 0); |
180 | if(new < 0) | 177 | if (new < 0) |
181 | return new; | 178 | return -errno; |
182 | 179 | ||
183 | err = os_pipe(socket, 0, 0); | 180 | err = os_pipe(socket, 0, 0); |
184 | if(err < 0) | 181 | if (err < 0) |
185 | goto out_close; | 182 | goto out_close; |
186 | 183 | ||
187 | data = ((struct port_pre_exec_data) | 184 | data = ((struct port_pre_exec_data) |
@@ -189,18 +186,18 @@ int port_connection(int fd, int *socket, int *pid_out) | |||
189 | .pipe_fd = socket[1] }); | 186 | .pipe_fd = socket[1] }); |
190 | 187 | ||
191 | err = run_helper(port_pre_exec, &data, argv); | 188 | err = run_helper(port_pre_exec, &data, argv); |
192 | if(err < 0) | 189 | if (err < 0) |
193 | goto out_shutdown; | 190 | goto out_shutdown; |
194 | 191 | ||
195 | *pid_out = err; | 192 | *pid_out = err; |
196 | return new; | 193 | return new; |
197 | 194 | ||
198 | out_shutdown: | 195 | out_shutdown: |
199 | os_shutdown_socket(socket[0], 1, 1); | 196 | shutdown(socket[0], SHUT_RDWR); |
200 | os_close_file(socket[0]); | 197 | close(socket[0]); |
201 | os_shutdown_socket(socket[1], 1, 1); | 198 | shutdown(socket[1], SHUT_RDWR); |
202 | os_close_file(socket[1]); | 199 | close(socket[1]); |
203 | out_close: | 200 | out_close: |
204 | os_close_file(new); | 201 | close(new); |
205 | return err; | 202 | return err; |
206 | } | 203 | } |
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index 1e3fd619a837..4123fe1fca98 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c | |||
@@ -56,11 +56,11 @@ static int pts_open(int input, int output, int primary, void *d, | |||
56 | if (data->raw) { | 56 | if (data->raw) { |
57 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); | 57 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); |
58 | if (err) | 58 | if (err) |
59 | return err; | 59 | goto out_close; |
60 | 60 | ||
61 | err = raw(fd); | 61 | err = raw(fd); |
62 | if (err) | 62 | if (err) |
63 | return err; | 63 | goto out_close; |
64 | } | 64 | } |
65 | 65 | ||
66 | dev = ptsname(fd); | 66 | dev = ptsname(fd); |
@@ -71,6 +71,10 @@ static int pts_open(int input, int output, int primary, void *d, | |||
71 | (*data->announce)(dev, data->dev); | 71 | (*data->announce)(dev, data->dev); |
72 | 72 | ||
73 | return fd; | 73 | return fd; |
74 | |||
75 | out_close: | ||
76 | close(fd); | ||
77 | return err; | ||
74 | } | 78 | } |
75 | 79 | ||
76 | static int getmaster(char *line) | 80 | static int getmaster(char *line) |
@@ -119,10 +123,12 @@ static int pty_open(int input, int output, int primary, void *d, | |||
119 | if (fd < 0) | 123 | if (fd < 0) |
120 | return fd; | 124 | return fd; |
121 | 125 | ||
122 | if(data->raw){ | 126 | if (data->raw) { |
123 | err = raw(fd); | 127 | err = raw(fd); |
124 | if (err) | 128 | if (err) { |
129 | close(fd); | ||
125 | return err; | 130 | return err; |
131 | } | ||
126 | } | 132 | } |
127 | 133 | ||
128 | if (data->announce) | 134 | if (data->announce) |
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index a9f87e19c5bf..c930fedc5172 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c | |||
@@ -1,16 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdio.h> | ||
7 | #include <termios.h> | ||
8 | #include <errno.h> | 6 | #include <errno.h> |
9 | #include <unistd.h> | 7 | #include <fcntl.h> |
8 | #include <termios.h> | ||
10 | #include "chan_user.h" | 9 | #include "chan_user.h" |
11 | #include "user.h" | 10 | #include "kern_constants.h" |
12 | #include "os.h" | 11 | #include "os.h" |
13 | #include "um_malloc.h" | 12 | #include "um_malloc.h" |
13 | #include "user.h" | ||
14 | 14 | ||
15 | struct tty_chan { | 15 | struct tty_chan { |
16 | char *dev; | 16 | char *dev; |
@@ -22,15 +22,15 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts) | |||
22 | { | 22 | { |
23 | struct tty_chan *data; | 23 | struct tty_chan *data; |
24 | 24 | ||
25 | if(*str != ':'){ | 25 | if (*str != ':') { |
26 | printk("tty_init : channel type 'tty' must specify " | 26 | printk(UM_KERN_ERR "tty_init : channel type 'tty' must specify " |
27 | "a device\n"); | 27 | "a device\n"); |
28 | return NULL; | 28 | return NULL; |
29 | } | 29 | } |
30 | str++; | 30 | str++; |
31 | 31 | ||
32 | data = kmalloc(sizeof(*data), UM_GFP_KERNEL); | 32 | data = kmalloc(sizeof(*data), UM_GFP_KERNEL); |
33 | if(data == NULL) | 33 | if (data == NULL) |
34 | return NULL; | 34 | return NULL; |
35 | *data = ((struct tty_chan) { .dev = str, | 35 | *data = ((struct tty_chan) { .dev = str, |
36 | .raw = opts->raw }); | 36 | .raw = opts->raw }); |
@@ -42,19 +42,26 @@ static int tty_open(int input, int output, int primary, void *d, | |||
42 | char **dev_out) | 42 | char **dev_out) |
43 | { | 43 | { |
44 | struct tty_chan *data = d; | 44 | struct tty_chan *data = d; |
45 | int fd, err; | 45 | int fd, err, mode = 0; |
46 | |||
47 | if (input && output) | ||
48 | mode = O_RDWR; | ||
49 | else if (input) | ||
50 | mode = O_RDONLY; | ||
51 | else if (output) | ||
52 | mode = O_WRONLY; | ||
46 | 53 | ||
47 | fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); | 54 | fd = open(data->dev, mode); |
48 | if(fd < 0) | 55 | if (fd < 0) |
49 | return fd; | 56 | return -errno; |
50 | 57 | ||
51 | if(data->raw){ | 58 | if (data->raw) { |
52 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); | 59 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); |
53 | if(err) | 60 | if (err) |
54 | return err; | 61 | return err; |
55 | 62 | ||
56 | err = raw(fd); | 63 | err = raw(fd); |
57 | if(err) | 64 | if (err) |
58 | return err; | 65 | return err; |
59 | } | 66 | } |
60 | 67 | ||
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index fd817e541543..87e18bf2c667 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c | |||
@@ -3,18 +3,19 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stddef.h> | ||
6 | #include <stdlib.h> | 7 | #include <stdlib.h> |
7 | #include <stdio.h> | 8 | #include <stdio.h> |
8 | #include <unistd.h> | 9 | #include <unistd.h> |
9 | #include <string.h> | ||
10 | #include <errno.h> | 10 | #include <errno.h> |
11 | #include <string.h> | ||
11 | #include <termios.h> | 12 | #include <termios.h> |
12 | #include "chan_user.h" | 13 | #include "chan_user.h" |
14 | #include "kern_constants.h" | ||
13 | #include "os.h" | 15 | #include "os.h" |
14 | #include "init.h" | 16 | #include "um_malloc.h" |
15 | #include "user.h" | 17 | #include "user.h" |
16 | #include "xterm.h" | 18 | #include "xterm.h" |
17 | #include "kern_constants.h" | ||
18 | 19 | ||
19 | struct xterm_chan { | 20 | struct xterm_chan { |
20 | int pid; | 21 | int pid; |
@@ -29,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts) | |||
29 | { | 30 | { |
30 | struct xterm_chan *data; | 31 | struct xterm_chan *data; |
31 | 32 | ||
32 | data = malloc(sizeof(*data)); | 33 | data = kmalloc(sizeof(*data), UM_GFP_KERNEL); |
33 | if (data == NULL) | 34 | if (data == NULL) |
34 | return NULL; | 35 | return NULL; |
35 | *data = ((struct xterm_chan) { .pid = -1, | 36 | *data = ((struct xterm_chan) { .pid = -1, |
@@ -207,11 +208,6 @@ static void xterm_close(int fd, void *d) | |||
207 | os_close_file(fd); | 208 | os_close_file(fd); |
208 | } | 209 | } |
209 | 210 | ||
210 | static void xterm_free(void *d) | ||
211 | { | ||
212 | free(d); | ||
213 | } | ||
214 | |||
215 | const struct chan_ops xterm_ops = { | 211 | const struct chan_ops xterm_ops = { |
216 | .type = "xterm", | 212 | .type = "xterm", |
217 | .init = xterm_init, | 213 | .init = xterm_init, |
@@ -221,6 +217,6 @@ const struct chan_ops xterm_ops = { | |||
221 | .write = generic_write, | 217 | .write = generic_write, |
222 | .console_write = generic_console_write, | 218 | .console_write = generic_console_write, |
223 | .window_size = generic_window_size, | 219 | .window_size = generic_window_size, |
224 | .free = xterm_free, | 220 | .free = generic_free, |
225 | .winch = 1, | 221 | .winch = 1, |
226 | }; | 222 | }; |