aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/sigio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/sigio.c')
-rw-r--r--arch/um/os-Linux/sigio.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index abf47a7c4abd..eb8f2e4be192 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 2 * Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -15,6 +15,7 @@
15#include "kern_util.h" 15#include "kern_util.h"
16#include "init.h" 16#include "init.h"
17#include "os.h" 17#include "os.h"
18#include "process.h"
18#include "sigio.h" 19#include "sigio.h"
19#include "um_malloc.h" 20#include "um_malloc.h"
20#include "user.h" 21#include "user.h"
@@ -109,7 +110,7 @@ static int need_poll(struct pollfds *polls, int n)
109 if (n <= polls->size) 110 if (n <= polls->size)
110 return 0; 111 return 0;
111 112
112 new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); 113 new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
113 if (new == NULL) { 114 if (new == NULL) {
114 printk(UM_KERN_ERR "need_poll : failed to allocate new " 115 printk(UM_KERN_ERR "need_poll : failed to allocate new "
115 "pollfds\n"); 116 "pollfds\n");
@@ -243,7 +244,7 @@ static struct pollfd *setup_initial_poll(int fd)
243{ 244{
244 struct pollfd *p; 245 struct pollfd *p;
245 246
246 p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); 247 p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
247 if (p == NULL) { 248 if (p == NULL) {
248 printk(UM_KERN_ERR "setup_initial_poll : failed to allocate " 249 printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
249 "poll\n"); 250 "poll\n");
@@ -338,20 +339,10 @@ out_close1:
338 close(l_write_sigio_fds[1]); 339 close(l_write_sigio_fds[1]);
339} 340}
340 341
341/* Changed during early boot */ 342void sigio_broken(int fd, int read)
342static int pty_output_sigio = 0;
343static int pty_close_sigio = 0;
344
345void maybe_sigio_broken(int fd, int read)
346{ 343{
347 int err; 344 int err;
348 345
349 if (!isatty(fd))
350 return;
351
352 if ((read || pty_output_sigio) && (!read || pty_close_sigio))
353 return;
354
355 write_sigio_workaround(); 346 write_sigio_workaround();
356 347
357 sigio_lock(); 348 sigio_lock();
@@ -370,6 +361,21 @@ out:
370 sigio_unlock(); 361 sigio_unlock();
371} 362}
372 363
364/* Changed during early boot */
365static int pty_output_sigio;
366static int pty_close_sigio;
367
368void maybe_sigio_broken(int fd, int read)
369{
370 if (!isatty(fd))
371 return;
372
373 if ((read || pty_output_sigio) && (!read || pty_close_sigio))
374 return;
375
376 sigio_broken(fd, read);
377}
378
373static void sigio_cleanup(void) 379static void sigio_cleanup(void)
374{ 380{
375 if (write_sigio_pid == -1) 381 if (write_sigio_pid == -1)
@@ -383,7 +389,7 @@ static void sigio_cleanup(void)
383__uml_exitcall(sigio_cleanup); 389__uml_exitcall(sigio_cleanup);
384 390
385/* Used as a flag during SIGIO testing early in boot */ 391/* Used as a flag during SIGIO testing early in boot */
386static volatile int got_sigio = 0; 392static int got_sigio;
387 393
388static void __init handler(int sig) 394static void __init handler(int sig)
389{ 395{
@@ -498,7 +504,8 @@ static void tty_output(int master, int slave)
498 if (errno != EAGAIN) 504 if (errno != EAGAIN)
499 printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n", 505 printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n",
500 errno); 506 errno);
501 while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) 507 while (((n = read(slave, buf, sizeof(buf))) > 0) &&
508 !({ barrier(); got_sigio; }))
502 ; 509 ;
503 510
504 if (got_sigio) { 511 if (got_sigio) {