aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-07-31 20:37:25 -0400
committerPaul Mackerras <paulus@samba.org>2006-07-31 20:37:25 -0400
commit57cad8084e0837e0f2c97da789ec9b3f36809be9 (patch)
treee9c790afb4286f78cb08d9664f58baa7e876fe55 /arch/um/os-Linux
parentcb18bd40030c879cd93fef02fd579f74dbab473d (diff)
parent49b1e3ea19b1c95c2f012b8331ffb3b169e4c042 (diff)
Merge branch 'merge'
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r--arch/um/os-Linux/file.c143
-rw-r--r--arch/um/os-Linux/irq.c16
-rw-r--r--arch/um/os-Linux/process.c27
-rw-r--r--arch/um/os-Linux/sigio.c33
-rw-r--r--arch/um/os-Linux/signal.c23
-rw-r--r--arch/um/os-Linux/skas/process.c18
-rw-r--r--arch/um/os-Linux/time.c23
-rw-r--r--arch/um/os-Linux/uaccess.c3
8 files changed, 122 insertions, 164 deletions
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 09251338d99e..189fa677085a 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -18,6 +18,7 @@
18#include "os.h" 18#include "os.h"
19#include "user.h" 19#include "user.h"
20#include "kern_util.h" 20#include "kern_util.h"
21#include "user_util.h"
21 22
22static void copy_stat(struct uml_stat *dst, struct stat64 *src) 23static void copy_stat(struct uml_stat *dst, struct stat64 *src)
23{ 24{
@@ -42,16 +43,13 @@ int os_stat_fd(const int fd, struct uml_stat *ubuf)
42 struct stat64 sbuf; 43 struct stat64 sbuf;
43 int err; 44 int err;
44 45
45 do { 46 CATCH_EINTR(err = fstat64(fd, &sbuf));
46 err = fstat64(fd, &sbuf);
47 } while((err < 0) && (errno == EINTR)) ;
48
49 if(err < 0) 47 if(err < 0)
50 return(-errno); 48 return -errno;
51 49
52 if(ubuf != NULL) 50 if(ubuf != NULL)
53 copy_stat(ubuf, &sbuf); 51 copy_stat(ubuf, &sbuf);
54 return(err); 52 return err;
55} 53}
56 54
57int os_stat_file(const char *file_name, struct uml_stat *ubuf) 55int os_stat_file(const char *file_name, struct uml_stat *ubuf)
@@ -64,11 +62,11 @@ int os_stat_file(const char *file_name, struct uml_stat *ubuf)
64 } while((err < 0) && (errno == EINTR)) ; 62 } while((err < 0) && (errno == EINTR)) ;
65 63
66 if(err < 0) 64 if(err < 0)
67 return(-errno); 65 return -errno;
68 66
69 if(ubuf != NULL) 67 if(ubuf != NULL)
70 copy_stat(ubuf, &sbuf); 68 copy_stat(ubuf, &sbuf);
71 return(err); 69 return err;
72} 70}
73 71
74int os_access(const char* file, int mode) 72int os_access(const char* file, int mode)
@@ -80,9 +78,9 @@ int os_access(const char* file, int mode)
80 78
81 err = access(file, amode); 79 err = access(file, amode);
82 if(err < 0) 80 if(err < 0)
83 return(-errno); 81 return -errno;
84 82
85 return(0); 83 return 0;
86} 84}
87 85
88void os_print_error(int error, const char* str) 86void os_print_error(int error, const char* str)
@@ -99,9 +97,9 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
99 97
100 err = ioctl(fd, cmd, arg); 98 err = ioctl(fd, cmd, arg);
101 if(err < 0) 99 if(err < 0)
102 return(-errno); 100 return -errno;
103 101
104 return(err); 102 return err;
105} 103}
106 104
107int os_window_size(int fd, int *rows, int *cols) 105int os_window_size(int fd, int *rows, int *cols)
@@ -109,12 +107,12 @@ int os_window_size(int fd, int *rows, int *cols)
109 struct winsize size; 107 struct winsize size;
110 108
111 if(ioctl(fd, TIOCGWINSZ, &size) < 0) 109 if(ioctl(fd, TIOCGWINSZ, &size) < 0)
112 return(-errno); 110 return -errno;
113 111
114 *rows = size.ws_row; 112 *rows = size.ws_row;
115 *cols = size.ws_col; 113 *cols = size.ws_col;
116 114
117 return(0); 115 return 0;
118} 116}
119 117
120int os_new_tty_pgrp(int fd, int pid) 118int os_new_tty_pgrp(int fd, int pid)
@@ -125,16 +123,16 @@ int os_new_tty_pgrp(int fd, int pid)
125 if(tcsetpgrp(fd, pid) < 0) 123 if(tcsetpgrp(fd, pid) < 0)
126 return -errno; 124 return -errno;
127 125
128 return(0); 126 return 0;
129} 127}
130 128
131/* FIXME: ensure namebuf in os_get_if_name is big enough */ 129/* FIXME: ensure namebuf in os_get_if_name is big enough */
132int os_get_ifname(int fd, char* namebuf) 130int os_get_ifname(int fd, char* namebuf)
133{ 131{
134 if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) 132 if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
135 return(-errno); 133 return -errno;
136 134
137 return(0); 135 return 0;
138} 136}
139 137
140int os_set_slip(int fd) 138int os_set_slip(int fd)
@@ -149,7 +147,7 @@ int os_set_slip(int fd)
149 if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0) 147 if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0)
150 return -errno; 148 return -errno;
151 149
152 return(0); 150 return 0;
153} 151}
154 152
155int os_set_owner(int fd, int pid) 153int os_set_owner(int fd, int pid)
@@ -158,10 +156,10 @@ int os_set_owner(int fd, int pid)
158 int save_errno = errno; 156 int save_errno = errno;
159 157
160 if(fcntl(fd, F_GETOWN, 0) != pid) 158 if(fcntl(fd, F_GETOWN, 0) != pid)
161 return(-save_errno); 159 return -save_errno;
162 } 160 }
163 161
164 return(0); 162 return 0;
165} 163}
166 164
167/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ 165/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */
@@ -192,9 +190,9 @@ int os_mode_fd(int fd, int mode)
192 } while((err < 0) && (errno==EINTR)) ; 190 } while((err < 0) && (errno==EINTR)) ;
193 191
194 if(err < 0) 192 if(err < 0)
195 return(-errno); 193 return -errno;
196 194
197 return(0); 195 return 0;
198} 196}
199 197
200int os_file_type(char *file) 198int os_file_type(char *file)
@@ -204,15 +202,21 @@ int os_file_type(char *file)
204 202
205 err = os_stat_file(file, &buf); 203 err = os_stat_file(file, &buf);
206 if(err < 0) 204 if(err < 0)
207 return(err); 205 return err;
208 206
209 if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR); 207 if(S_ISDIR(buf.ust_mode))
210 else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK); 208 return OS_TYPE_DIR;
211 else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV); 209 else if(S_ISLNK(buf.ust_mode))
212 else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV); 210 return OS_TYPE_SYMLINK;
213 else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO); 211 else if(S_ISCHR(buf.ust_mode))
214 else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK); 212 return OS_TYPE_CHARDEV;
215 else return(OS_TYPE_FILE); 213 else if(S_ISBLK(buf.ust_mode))
214 return OS_TYPE_BLOCKDEV;
215 else if(S_ISFIFO(buf.ust_mode))
216 return OS_TYPE_FIFO;
217 else if(S_ISSOCK(buf.ust_mode))
218 return OS_TYPE_SOCK;
219 else return OS_TYPE_FILE;
216} 220}
217 221
218int os_file_mode(char *file, struct openflags *mode_out) 222int os_file_mode(char *file, struct openflags *mode_out)
@@ -302,8 +306,8 @@ int os_seek_file(int fd, __u64 offset)
302 306
303 actual = lseek64(fd, offset, SEEK_SET); 307 actual = lseek64(fd, offset, SEEK_SET);
304 if(actual != offset) 308 if(actual != offset)
305 return(-errno); 309 return -errno;
306 return(0); 310 return 0;
307} 311}
308 312
309static int fault_buffer(void *start, int len, 313static int fault_buffer(void *start, int len,
@@ -314,13 +318,13 @@ static int fault_buffer(void *start, int len,
314 318
315 for(i = 0; i < len; i += page){ 319 for(i = 0; i < len; i += page){
316 if((*copy_proc)(start + i, &c, sizeof(c))) 320 if((*copy_proc)(start + i, &c, sizeof(c)))
317 return(-EFAULT); 321 return -EFAULT;
318 } 322 }
319 if((len % page) != 0){ 323 if((len % page) != 0){
320 if((*copy_proc)(start + len - 1, &c, sizeof(c))) 324 if((*copy_proc)(start + len - 1, &c, sizeof(c)))
321 return(-EFAULT); 325 return -EFAULT;
322 } 326 }
323 return(0); 327 return 0;
324} 328}
325 329
326static int file_io(int fd, void *buf, int len, 330static int file_io(int fd, void *buf, int len,
@@ -334,26 +338,26 @@ static int file_io(int fd, void *buf, int len,
334 if((n < 0) && (errno == EFAULT)){ 338 if((n < 0) && (errno == EFAULT)){
335 err = fault_buffer(buf, len, copy_user_proc); 339 err = fault_buffer(buf, len, copy_user_proc);
336 if(err) 340 if(err)
337 return(err); 341 return err;
338 n = (*io_proc)(fd, buf, len); 342 n = (*io_proc)(fd, buf, len);
339 } 343 }
340 } while((n < 0) && (errno == EINTR)); 344 } while((n < 0) && (errno == EINTR));
341 345
342 if(n < 0) 346 if(n < 0)
343 return(-errno); 347 return -errno;
344 return(n); 348 return n;
345} 349}
346 350
347int os_read_file(int fd, void *buf, int len) 351int os_read_file(int fd, void *buf, int len)
348{ 352{
349 return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, 353 return file_io(fd, buf, len, (int (*)(int, void *, int)) read,
350 copy_from_user_proc)); 354 copy_from_user_proc);
351} 355}
352 356
353int os_write_file(int fd, const void *buf, int len) 357int os_write_file(int fd, const void *buf, int len)
354{ 358{
355 return(file_io(fd, (void *) buf, len, 359 return file_io(fd, (void *) buf, len,
356 (int (*)(int, void *, int)) write, copy_to_user_proc)); 360 (int (*)(int, void *, int)) write, copy_to_user_proc);
357} 361}
358 362
359int os_file_size(char *file, unsigned long long *size_out) 363int os_file_size(char *file, unsigned long long *size_out)
@@ -398,11 +402,11 @@ int os_file_modtime(char *file, unsigned long *modtime)
398 err = os_stat_file(file, &buf); 402 err = os_stat_file(file, &buf);
399 if(err < 0){ 403 if(err < 0){
400 printk("Couldn't stat \"%s\" : err = %d\n", file, -err); 404 printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
401 return(err); 405 return err;
402 } 406 }
403 407
404 *modtime = buf.ust_mtime; 408 *modtime = buf.ust_mtime;
405 return(0); 409 return 0;
406} 410}
407 411
408int os_get_exec_close(int fd, int* close_on_exec) 412int os_get_exec_close(int fd, int* close_on_exec)
@@ -455,7 +459,7 @@ int os_pipe(int *fds, int stream, int close_on_exec)
455 if(err < 0) 459 if(err < 0)
456 goto error; 460 goto error;
457 461
458 return(0); 462 return 0;
459 463
460 error: 464 error:
461 printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); 465 printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
@@ -486,12 +490,12 @@ int os_set_fd_async(int fd, int owner)
486 (fcntl(fd, F_SETOWN, owner) < 0)){ 490 (fcntl(fd, F_SETOWN, owner) < 0)){
487 err = -errno; 491 err = -errno;
488 printk("os_set_fd_async : Failed to fcntl F_SETOWN " 492 printk("os_set_fd_async : Failed to fcntl F_SETOWN "
489 "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, 493 "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd,
490 owner, errno); 494 owner, errno);
491 return err; 495 return err;
492 } 496 }
493 497
494 return(0); 498 return 0;
495} 499}
496 500
497int os_clear_fd_async(int fd) 501int os_clear_fd_async(int fd)
@@ -500,8 +504,8 @@ int os_clear_fd_async(int fd)
500 504
501 flags &= ~(O_ASYNC | O_NONBLOCK); 505 flags &= ~(O_ASYNC | O_NONBLOCK);
502 if(fcntl(fd, F_SETFL, flags) < 0) 506 if(fcntl(fd, F_SETFL, flags) < 0)
503 return(-errno); 507 return -errno;
504 return(0); 508 return 0;
505} 509}
506 510
507int os_set_fd_block(int fd, int blocking) 511int os_set_fd_block(int fd, int blocking)
@@ -516,7 +520,7 @@ int os_set_fd_block(int fd, int blocking)
516 if(fcntl(fd, F_SETFL, flags) < 0) 520 if(fcntl(fd, F_SETFL, flags) < 0)
517 return -errno; 521 return -errno;
518 522
519 return(0); 523 return 0;
520} 524}
521 525
522int os_accept_connection(int fd) 526int os_accept_connection(int fd)
@@ -524,9 +528,9 @@ int os_accept_connection(int fd)
524 int new; 528 int new;
525 529
526 new = accept(fd, NULL, 0); 530 new = accept(fd, NULL, 0);
527 if(new < 0) 531 if(new < 0)
528 return(-errno); 532 return -errno;
529 return(new); 533 return new;
530} 534}
531 535
532#ifndef SHUT_RD 536#ifndef SHUT_RD
@@ -550,12 +554,12 @@ int os_shutdown_socket(int fd, int r, int w)
550 else if(w) what = SHUT_WR; 554 else if(w) what = SHUT_WR;
551 else { 555 else {
552 printk("os_shutdown_socket : neither r or w was set\n"); 556 printk("os_shutdown_socket : neither r or w was set\n");
553 return(-EINVAL); 557 return -EINVAL;
554 } 558 }
555 err = shutdown(fd, what); 559 err = shutdown(fd, what);
556 if(err < 0) 560 if(err < 0)
557 return(-errno); 561 return -errno;
558 return(0); 562 return 0;
559} 563}
560 564
561int os_rcv_fd(int fd, int *helper_pid_out) 565int os_rcv_fd(int fd, int *helper_pid_out)
@@ -578,7 +582,7 @@ int os_rcv_fd(int fd, int *helper_pid_out)
578 582
579 n = recvmsg(fd, &msg, 0); 583 n = recvmsg(fd, &msg, 0);
580 if(n < 0) 584 if(n < 0)
581 return(-errno); 585 return -errno;
582 586
583 else if(n != sizeof(iov.iov_len)) 587 else if(n != sizeof(iov.iov_len))
584 *helper_pid_out = -1; 588 *helper_pid_out = -1;
@@ -586,16 +590,16 @@ int os_rcv_fd(int fd, int *helper_pid_out)
586 cmsg = CMSG_FIRSTHDR(&msg); 590 cmsg = CMSG_FIRSTHDR(&msg);
587 if(cmsg == NULL){ 591 if(cmsg == NULL){
588 printk("rcv_fd didn't receive anything, error = %d\n", errno); 592 printk("rcv_fd didn't receive anything, error = %d\n", errno);
589 return(-1); 593 return -1;
590 } 594 }
591 if((cmsg->cmsg_level != SOL_SOCKET) || 595 if((cmsg->cmsg_level != SOL_SOCKET) ||
592 (cmsg->cmsg_type != SCM_RIGHTS)){ 596 (cmsg->cmsg_type != SCM_RIGHTS)){
593 printk("rcv_fd didn't receive a descriptor\n"); 597 printk("rcv_fd didn't receive a descriptor\n");
594 return(-1); 598 return -1;
595 } 599 }
596 600
597 new = ((int *) CMSG_DATA(cmsg))[0]; 601 new = ((int *) CMSG_DATA(cmsg))[0];
598 return(new); 602 return new;
599} 603}
600 604
601int os_create_unix_socket(char *file, int len, int close_on_exec) 605int os_create_unix_socket(char *file, int len, int close_on_exec)
@@ -623,7 +627,7 @@ int os_create_unix_socket(char *file, int len, int close_on_exec)
623 if(err < 0) 627 if(err < 0)
624 return -errno; 628 return -errno;
625 629
626 return(sock); 630 return sock;
627} 631}
628 632
629void os_flush_stdout(void) 633void os_flush_stdout(void)
@@ -654,16 +658,5 @@ int os_lock_file(int fd, int excl)
654 printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); 658 printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
655 err = save; 659 err = save;
656 out: 660 out:
657 return(err); 661 return err;
658} 662}
659
660/*
661 * Overrides for Emacs so that we follow Linus's tabbing style.
662 * Emacs will notice this stuff at the end of the file and automatically
663 * adjust the settings for this buffer only. This must remain at the end
664 * of the file.
665 * ---------------------------------------------------------------------------
666 * Local variables:
667 * c-file-style: "linux"
668 * End:
669 */
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index 3788d4568d33..7555bf9c33d9 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -52,11 +52,6 @@ int os_waiting_for_events(struct irq_fd *active_fds)
52 return n; 52 return n;
53} 53}
54 54
55int os_isatty(int fd)
56{
57 return isatty(fd);
58}
59
60int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) 55int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds)
61{ 56{
62 if (pollfds_num == pollfds_size) { 57 if (pollfds_num == pollfds_size) {
@@ -142,17 +137,14 @@ void os_set_ioignore(void)
142 137
143void init_irq_signals(int on_sigstack) 138void init_irq_signals(int on_sigstack)
144{ 139{
145 __sighandler_t h;
146 int flags; 140 int flags;
147 141
148 flags = on_sigstack ? SA_ONSTACK : 0; 142 flags = on_sigstack ? SA_ONSTACK : 0;
149 if (timer_irq_inited)
150 h = (__sighandler_t)alarm_handler;
151 else
152 h = boot_timer_handler;
153 143
154 set_handler(SIGVTALRM, h, flags | SA_RESTART, 144 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
155 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); 145 flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
146 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
147 flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
156 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, 148 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
157 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 149 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
158 signal(SIGWINCH, SIG_IGN); 150 signal(SIGWINCH, SIG_IGN);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 233be2f4f8cb..b98d3ca2cd1b 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -250,36 +250,35 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
250 if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); 250 if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
251} 251}
252 252
253void init_new_thread_signals(int altstack) 253void init_new_thread_signals(void)
254{ 254{
255 int flags = altstack ? SA_ONSTACK : 0; 255 set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK,
256
257 set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
258 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 256 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
259 set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, 257 set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK,
260 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 258 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
261 set_handler(SIGFPE, (__sighandler_t) sig_handler, flags, 259 set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK,
262 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 260 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
263 set_handler(SIGILL, (__sighandler_t) sig_handler, flags, 261 set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK,
264 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 262 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
265 set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 263 set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK,
266 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 264 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
267 set_handler(SIGUSR2, (__sighandler_t) sig_handler, 265 set_handler(SIGUSR2, (__sighandler_t) sig_handler,
268 flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 266 SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
267 -1);
269 signal(SIGHUP, SIG_IGN); 268 signal(SIGHUP, SIG_IGN);
270 269
271 init_irq_signals(altstack); 270 init_irq_signals(1);
272} 271}
273 272
274int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) 273int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
275{ 274{
276 jmp_buf buf; 275 jmp_buf buf;
277 int n, enable; 276 int n;
278 277
279 *jmp_ptr = &buf; 278 *jmp_ptr = &buf;
280 n = UML_SETJMP(&buf, enable); 279 n = UML_SETJMP(&buf);
281 if(n != 0) 280 if(n != 0)
282 return(n); 281 return n;
283 (*fn)(arg); 282 (*fn)(arg);
284 return(0); 283 return 0;
285} 284}
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);
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index f11b3124a0c8..60e4faedf254 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -106,29 +106,6 @@ void alarm_handler(ARCH_SIGHDLR_PARAM)
106 set_signals(enabled); 106 set_signals(enabled);
107} 107}
108 108
109extern void do_boot_timer_handler(struct sigcontext * sc);
110
111void boot_timer_handler(ARCH_SIGHDLR_PARAM)
112{
113 struct sigcontext *sc;
114 int enabled;
115
116 ARCH_GET_SIGCONTEXT(sc, sig);
117
118 enabled = signals_enabled;
119 if(!enabled){
120 if(sig == SIGVTALRM)
121 pending |= SIGVTALRM_MASK;
122 else pending |= SIGALRM_MASK;
123 return;
124 }
125
126 block_signals();
127
128 do_boot_timer_handler(sc);
129 set_signals(enabled);
130}
131
132void set_sigstack(void *sig_stack, int size) 109void set_sigstack(void *sig_stack, int size)
133{ 110{
134 stack_t stack = ((stack_t) { .ss_flags = 0, 111 stack_t stack = ((stack_t) { .ss_flags = 0,
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index bd89c6b99d5d..7baf90fda58b 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -159,7 +159,7 @@ static int userspace_tramp(void *stack)
159 159
160 ptrace(PTRACE_TRACEME, 0, 0, 0); 160 ptrace(PTRACE_TRACEME, 0, 0, 0);
161 161
162 init_new_thread_signals(1); 162 init_new_thread_signals();
163 enable_timer(); 163 enable_timer();
164 164
165 if(!proc_mm){ 165 if(!proc_mm){
@@ -435,7 +435,6 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
435{ 435{
436 unsigned long flags; 436 unsigned long flags;
437 jmp_buf switch_buf, fork_buf; 437 jmp_buf switch_buf, fork_buf;
438 int enable;
439 438
440 *switch_buf_ptr = &switch_buf; 439 *switch_buf_ptr = &switch_buf;
441 *fork_buf_ptr = &fork_buf; 440 *fork_buf_ptr = &fork_buf;
@@ -450,7 +449,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
450 */ 449 */
451 flags = get_signals(); 450 flags = get_signals();
452 block_signals(); 451 block_signals();
453 if(UML_SETJMP(&fork_buf, enable) == 0) 452 if(UML_SETJMP(&fork_buf) == 0)
454 new_thread_proc(stack, handler); 453 new_thread_proc(stack, handler);
455 454
456 remove_sigstack(); 455 remove_sigstack();
@@ -467,21 +466,19 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
467void thread_wait(void *sw, void *fb) 466void thread_wait(void *sw, void *fb)
468{ 467{
469 jmp_buf buf, **switch_buf = sw, *fork_buf; 468 jmp_buf buf, **switch_buf = sw, *fork_buf;
470 int enable;
471 469
472 *switch_buf = &buf; 470 *switch_buf = &buf;
473 fork_buf = fb; 471 fork_buf = fb;
474 if(UML_SETJMP(&buf, enable) == 0) 472 if(UML_SETJMP(&buf) == 0)
475 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); 473 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
476} 474}
477 475
478void switch_threads(void *me, void *next) 476void switch_threads(void *me, void *next)
479{ 477{
480 jmp_buf my_buf, **me_ptr = me, *next_buf = next; 478 jmp_buf my_buf, **me_ptr = me, *next_buf = next;
481 int enable;
482 479
483 *me_ptr = &my_buf; 480 *me_ptr = &my_buf;
484 if(UML_SETJMP(&my_buf, enable) == 0) 481 if(UML_SETJMP(&my_buf) == 0)
485 UML_LONGJMP(next_buf, 1); 482 UML_LONGJMP(next_buf, 1);
486} 483}
487 484
@@ -495,14 +492,14 @@ static jmp_buf *cb_back;
495int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) 492int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
496{ 493{
497 jmp_buf **switch_buf = switch_buf_ptr; 494 jmp_buf **switch_buf = switch_buf_ptr;
498 int n, enable; 495 int n;
499 496
500 set_handler(SIGWINCH, (__sighandler_t) sig_handler, 497 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
501 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, 498 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
502 SIGVTALRM, -1); 499 SIGVTALRM, -1);
503 500
504 *fork_buf_ptr = &initial_jmpbuf; 501 *fork_buf_ptr = &initial_jmpbuf;
505 n = UML_SETJMP(&initial_jmpbuf, enable); 502 n = UML_SETJMP(&initial_jmpbuf);
506 switch(n){ 503 switch(n){
507 case INIT_JMP_NEW_THREAD: 504 case INIT_JMP_NEW_THREAD:
508 new_thread_proc((void *) stack, new_thread_handler); 505 new_thread_proc((void *) stack, new_thread_handler);
@@ -529,14 +526,13 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
529void initial_thread_cb_skas(void (*proc)(void *), void *arg) 526void initial_thread_cb_skas(void (*proc)(void *), void *arg)
530{ 527{
531 jmp_buf here; 528 jmp_buf here;
532 int enable;
533 529
534 cb_proc = proc; 530 cb_proc = proc;
535 cb_arg = arg; 531 cb_arg = arg;
536 cb_back = &here; 532 cb_back = &here;
537 533
538 block_signals(); 534 block_signals();
539 if(UML_SETJMP(&here, enable) == 0) 535 if(UML_SETJMP(&here) == 0)
540 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); 536 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
541 unblock_signals(); 537 unblock_signals();
542 538
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 280c4fb9b585..4ae73c0e5485 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -17,11 +17,6 @@
17#include "kern_constants.h" 17#include "kern_constants.h"
18#include "os.h" 18#include "os.h"
19 19
20/* XXX This really needs to be declared and initialized in a kernel file since
21 * it's in <linux/time.h>
22 */
23extern struct timespec wall_to_monotonic;
24
25static void set_interval(int timer_type) 20static void set_interval(int timer_type)
26{ 21{
27 int usec = 1000000/hz(); 22 int usec = 1000000/hz();
@@ -71,6 +66,7 @@ void switch_timers(int to_real)
71 errno); 66 errno);
72} 67}
73 68
69#ifdef UML_CONFIG_MODE_TT
74void uml_idle_timer(void) 70void uml_idle_timer(void)
75{ 71{
76 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) 72 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
@@ -80,14 +76,7 @@ void uml_idle_timer(void)
80 SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); 76 SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
81 set_interval(ITIMER_REAL); 77 set_interval(ITIMER_REAL);
82} 78}
83 79#endif
84void time_init(void)
85{
86 if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
87 panic("Couldn't set SIGVTALRM handler");
88 set_interval(ITIMER_VIRTUAL);
89 time_init_kern();
90}
91 80
92unsigned long long os_nsecs(void) 81unsigned long long os_nsecs(void)
93{ 82{
@@ -106,15 +95,7 @@ void idle_sleep(int secs)
106 nanosleep(&ts, NULL); 95 nanosleep(&ts, NULL);
107} 96}
108 97
109/* XXX This partly duplicates init_irq_signals */
110
111void user_time_init(void) 98void user_time_init(void)
112{ 99{
113 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
114 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
115 SIGALRM, SIGUSR2, -1);
116 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
117 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
118 SIGVTALRM, SIGUSR2, -1);
119 set_interval(ITIMER_VIRTUAL); 100 set_interval(ITIMER_VIRTUAL);
120} 101}
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index e523719330b2..865f6a6a2590 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -14,11 +14,10 @@ unsigned long __do_user_copy(void *to, const void *from, int n,
14 int n), int *faulted_out) 14 int n), int *faulted_out)
15{ 15{
16 unsigned long *faddrp = (unsigned long *) fault_addr, ret; 16 unsigned long *faddrp = (unsigned long *) fault_addr, ret;
17 int enable;
18 17
19 jmp_buf jbuf; 18 jmp_buf jbuf;
20 *fault_catcher = &jbuf; 19 *fault_catcher = &jbuf;
21 if(UML_SETJMP(&jbuf, enable) == 0){ 20 if(UML_SETJMP(&jbuf) == 0){
22 (*op)(to, from, n); 21 (*op)(to, from, n);
23 ret = 0; 22 ret = 0;
24 *faulted_out = 0; 23 *faulted_out = 0;