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.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 00e9388e947a..0ecac563c7b3 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -43,13 +43,13 @@ struct pollfds {
43/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread 43/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread
44 * synchronizes with it. 44 * synchronizes with it.
45 */ 45 */
46struct pollfds current_poll = { 46static struct pollfds current_poll = {
47 .poll = NULL, 47 .poll = NULL,
48 .size = 0, 48 .size = 0,
49 .used = 0 49 .used = 0
50}; 50};
51 51
52struct pollfds next_poll = { 52static struct pollfds next_poll = {
53 .poll = NULL, 53 .poll = NULL,
54 .size = 0, 54 .size = 0,
55 .used = 0 55 .used = 0
@@ -156,7 +156,7 @@ static void update_thread(void)
156 set_signals(flags); 156 set_signals(flags);
157} 157}
158 158
159int add_sigio_fd(int fd, int read) 159static int add_sigio_fd(int fd, int read)
160{ 160{
161 int err = 0, i, n, events; 161 int err = 0, i, n, events;
162 162
@@ -191,6 +191,13 @@ int ignore_sigio_fd(int fd)
191 struct pollfd *p; 191 struct pollfd *p;
192 int err = 0, i, n = 0; 192 int err = 0, i, n = 0;
193 193
194 /* This is called from exitcalls elsewhere in UML - if
195 * sigio_cleanup has already run, then update_thread will hang
196 * or fail because the thread is no longer running.
197 */
198 if(write_sigio_pid == -1)
199 return -EIO;
200
194 sigio_lock(); 201 sigio_lock();
195 for(i = 0; i < current_poll.used; i++){ 202 for(i = 0; i < current_poll.used; i++){
196 if(current_poll.poll[i].fd == fd) break; 203 if(current_poll.poll[i].fd == fd) break;
@@ -215,7 +222,7 @@ int ignore_sigio_fd(int fd)
215 update_thread(); 222 update_thread();
216 out: 223 out:
217 sigio_unlock(); 224 sigio_unlock();
218 return(err); 225 return err;
219} 226}
220 227
221static struct pollfd *setup_initial_poll(int fd) 228static struct pollfd *setup_initial_poll(int fd)
@@ -233,7 +240,7 @@ static struct pollfd *setup_initial_poll(int fd)
233 return p; 240 return p;
234} 241}
235 242
236void write_sigio_workaround(void) 243static void write_sigio_workaround(void)
237{ 244{
238 unsigned long stack; 245 unsigned long stack;
239 struct pollfd *p; 246 struct pollfd *p;
@@ -314,10 +321,24 @@ out_close1:
314 close(l_write_sigio_fds[1]); 321 close(l_write_sigio_fds[1]);
315} 322}
316 323
317void sigio_cleanup(void) 324void maybe_sigio_broken(int fd, int read)
325{
326 if(!isatty(fd))
327 return;
328
329 if((read || pty_output_sigio) && (!read || pty_close_sigio))
330 return;
331
332 write_sigio_workaround();
333 add_sigio_fd(fd, read);
334}
335
336static void sigio_cleanup(void)
318{ 337{
319 if(write_sigio_pid != -1){ 338 if(write_sigio_pid != -1){
320 os_kill_process(write_sigio_pid, 1); 339 os_kill_process(write_sigio_pid, 1);
321 write_sigio_pid = -1; 340 write_sigio_pid = -1;
322 } 341 }
323} 342}
343
344__uml_exitcall(sigio_cleanup);