diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/file.c | 143 | ||||
-rw-r--r-- | arch/um/os-Linux/irq.c | 16 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 27 | ||||
-rw-r--r-- | arch/um/os-Linux/sigio.c | 33 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 23 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 18 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 23 | ||||
-rw-r--r-- | arch/um/os-Linux/uaccess.c | 3 |
8 files changed, 122 insertions, 164 deletions
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 0925133..189fa67 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -18,6 +18,7 @@ #include "os.h" #include "user.h" #include "kern_util.h" +#include "user_util.h" static void copy_stat(struct uml_stat *dst, struct stat64 *src) { @@ -42,16 +43,13 @@ int os_stat_fd(const int fd, struct uml_stat *ubuf) struct stat64 sbuf; int err; - do { - err = fstat64(fd, &sbuf); - } while((err < 0) && (errno == EINTR)) ; - + CATCH_EINTR(err = fstat64(fd, &sbuf)); if(err < 0) - return(-errno); + return -errno; if(ubuf != NULL) copy_stat(ubuf, &sbuf); - return(err); + return err; } int 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) } while((err < 0) && (errno == EINTR)) ; if(err < 0) - return(-errno); + return -errno; if(ubuf != NULL) copy_stat(ubuf, &sbuf); - return(err); + return err; } int os_access(const char* file, int mode) @@ -80,9 +78,9 @@ int os_access(const char* file, int mode) err = access(file, amode); if(err < 0) - return(-errno); + return -errno; - return(0); + return 0; } void os_print_error(int error, const char* str) @@ -99,9 +97,9 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg) err = ioctl(fd, cmd, arg); if(err < 0) - return(-errno); + return -errno; - return(err); + return err; } int os_window_size(int fd, int *rows, int *cols) @@ -109,12 +107,12 @@ int os_window_size(int fd, int *rows, int *cols) struct winsize size; if(ioctl(fd, TIOCGWINSZ, &size) < 0) - return(-errno); + return -errno; *rows = size.ws_row; *cols = size.ws_col; - return(0); + return 0; } int os_new_tty_pgrp(int fd, int pid) @@ -125,16 +123,16 @@ int os_new_tty_pgrp(int fd, int pid) if(tcsetpgrp(fd, pid) < 0) return -errno; - return(0); + return 0; } /* FIXME: ensure namebuf in os_get_if_name is big enough */ int os_get_ifname(int fd, char* namebuf) { if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) - return(-errno); + return -errno; - return(0); + return 0; } int os_set_slip(int fd) @@ -149,7 +147,7 @@ int os_set_slip(int fd) if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0) return -errno; - return(0); + return 0; } int os_set_owner(int fd, int pid) @@ -158,10 +156,10 @@ int os_set_owner(int fd, int pid) int save_errno = errno; if(fcntl(fd, F_GETOWN, 0) != pid) - return(-save_errno); + return -save_errno; } - return(0); + return 0; } /* 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) } while((err < 0) && (errno==EINTR)) ; if(err < 0) - return(-errno); + return -errno; - return(0); + return 0; } int os_file_type(char *file) @@ -204,15 +202,21 @@ int os_file_type(char *file) err = os_stat_file(file, &buf); if(err < 0) - return(err); + return err; - if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR); - else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK); - else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV); - else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV); - else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO); - else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK); - else return(OS_TYPE_FILE); + if(S_ISDIR(buf.ust_mode)) + return OS_TYPE_DIR; + else if(S_ISLNK(buf.ust_mode)) + return OS_TYPE_SYMLINK; + else if(S_ISCHR(buf.ust_mode)) + return OS_TYPE_CHARDEV; + else if(S_ISBLK(buf.ust_mode)) + return OS_TYPE_BLOCKDEV; + else if(S_ISFIFO(buf.ust_mode)) + return OS_TYPE_FIFO; + else if(S_ISSOCK(buf.ust_mode)) + return OS_TYPE_SOCK; + else return OS_TYPE_FILE; } int os_file_mode(char *file, struct openflags *mode_out) @@ -302,8 +306,8 @@ int os_seek_file(int fd, __u64 offset) actual = lseek64(fd, offset, SEEK_SET); if(actual != offset) - return(-errno); - return(0); + return -errno; + return 0; } static int fault_buffer(void *start, int len, @@ -314,13 +318,13 @@ static int fault_buffer(void *start, int len, for(i = 0; i < len; i += page){ if((*copy_proc)(start + i, &c, sizeof(c))) - return(-EFAULT); + return -EFAULT; } if((len % page) != 0){ if((*copy_proc)(start + len - 1, &c, sizeof(c))) - return(-EFAULT); + return -EFAULT; } - return(0); + return 0; } static int file_io(int fd, void *buf, int len, @@ -334,26 +338,26 @@ static int file_io(int fd, void *buf, int len, if((n < 0) && (errno == EFAULT)){ err = fault_buffer(buf, len, copy_user_proc); if(err) - return(err); + return err; n = (*io_proc)(fd, buf, len); } } while((n < 0) && (errno == EINTR)); if(n < 0) - return(-errno); - return(n); + return -errno; + return n; } int os_read_file(int fd, void *buf, int len) { - return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, - copy_from_user_proc)); + return file_io(fd, buf, len, (int (*)(int, void *, int)) read, + copy_from_user_proc); } int os_write_file(int fd, const void *buf, int len) { - return(file_io(fd, (void *) buf, len, - (int (*)(int, void *, int)) write, copy_to_user_proc)); + return file_io(fd, (void *) buf, len, + (int (*)(int, void *, int)) write, copy_to_user_proc); } int os_file_size(char *file, unsigned long long *size_out) @@ -398,11 +402,11 @@ int os_file_modtime(char *file, unsigned long *modtime) err = os_stat_file(file, &buf); if(err < 0){ printk("Couldn't stat \"%s\" : err = %d\n", file, -err); - return(err); + return err; } *modtime = buf.ust_mtime; - return(0); + return 0; } int 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) if(err < 0) goto error; - return(0); + return 0; error: printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); @@ -486,12 +490,12 @@ int os_set_fd_async(int fd, int owner) (fcntl(fd, F_SETOWN, owner) < 0)){ err = -errno; printk("os_set_fd_async : Failed to fcntl F_SETOWN " - "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, + "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, owner, errno); return err; } - return(0); + return 0; } int os_clear_fd_async(int fd) @@ -500,8 +504,8 @@ int os_clear_fd_async(int fd) flags &= ~(O_ASYNC | O_NONBLOCK); if(fcntl(fd, F_SETFL, flags) < 0) - return(-errno); - return(0); + return -errno; + return 0; } int os_set_fd_block(int fd, int blocking) @@ -516,7 +520,7 @@ int os_set_fd_block(int fd, int blocking) if(fcntl(fd, F_SETFL, flags) < 0) return -errno; - return(0); + return 0; } int os_accept_connection(int fd) @@ -524,9 +528,9 @@ int os_accept_connection(int fd) int new; new = accept(fd, NULL, 0); - if(new < 0) - return(-errno); - return(new); + if(new < 0) + return -errno; + return new; } #ifndef SHUT_RD @@ -550,12 +554,12 @@ int os_shutdown_socket(int fd, int r, int w) else if(w) what = SHUT_WR; else { printk("os_shutdown_socket : neither r or w was set\n"); - return(-EINVAL); + return -EINVAL; } err = shutdown(fd, what); if(err < 0) - return(-errno); - return(0); + return -errno; + return 0; } int os_rcv_fd(int fd, int *helper_pid_out) @@ -578,7 +582,7 @@ int os_rcv_fd(int fd, int *helper_pid_out) n = recvmsg(fd, &msg, 0); if(n < 0) - return(-errno); + return -errno; else if(n != sizeof(iov.iov_len)) *helper_pid_out = -1; @@ -586,16 +590,16 @@ int os_rcv_fd(int fd, int *helper_pid_out) cmsg = CMSG_FIRSTHDR(&msg); if(cmsg == NULL){ printk("rcv_fd didn't receive anything, error = %d\n", errno); - return(-1); + return -1; } - if((cmsg->cmsg_level != SOL_SOCKET) || + if((cmsg->cmsg_level != SOL_SOCKET) || (cmsg->cmsg_type != SCM_RIGHTS)){ printk("rcv_fd didn't receive a descriptor\n"); - return(-1); + return -1; } new = ((int *) CMSG_DATA(cmsg))[0]; - return(new); + return new; } int 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) if(err < 0) return -errno; - return(sock); + return sock; } void os_flush_stdout(void) @@ -654,16 +658,5 @@ int os_lock_file(int fd, int excl) printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); err = save; out: - return(err); + return err; } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index 3788d45..7555bf9 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) return n; } -int os_isatty(int fd) -{ - return isatty(fd); -} - int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) { if (pollfds_num == pollfds_size) { @@ -142,17 +137,14 @@ void os_set_ioignore(void) void init_irq_signals(int on_sigstack) { - __sighandler_t h; int flags; flags = on_sigstack ? SA_ONSTACK : 0; - if (timer_irq_inited) - h = (__sighandler_t)alarm_handler; - else - h = boot_timer_handler; - set_handler(SIGVTALRM, h, flags | SA_RESTART, - SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); + set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, + flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); + set_handler(SIGALRM, (__sighandler_t) alarm_handler, + flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); signal(SIGWINCH, SIG_IGN); diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 233be2f..b98d3ca 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)) if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); } -void init_new_thread_signals(int altstack) +void init_new_thread_signals(void) { - int flags = altstack ? SA_ONSTACK : 0; - - set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags, + set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); - set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, + set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); - set_handler(SIGFPE, (__sighandler_t) sig_handler, flags, + set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); - set_handler(SIGILL, (__sighandler_t) sig_handler, flags, + set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); - set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, + set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); set_handler(SIGUSR2, (__sighandler_t) sig_handler, - flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); + SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, + -1); signal(SIGHUP, SIG_IGN); - init_irq_signals(altstack); + init_irq_signals(1); } int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) { jmp_buf buf; - int n, enable; + int n; *jmp_ptr = &buf; - n = UML_SETJMP(&buf, enable); + n = UML_SETJMP(&buf); if(n != 0) - return(n); + return n; (*fn)(arg); - return(0); + return 0; } diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 00e9388..0ecac56 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -43,13 +43,13 @@ struct pollfds { /* Protected by sigio_lock(). Used by the sigio thread, but the UML thread * synchronizes with it. */ -struct pollfds current_poll = { +static struct pollfds current_poll = { .poll = NULL, .size = 0, .used = 0 }; -struct pollfds next_poll = { +static struct pollfds next_poll = { .poll = NULL, .size = 0, .used = 0 @@ -156,7 +156,7 @@ static void update_thread(void) set_signals(flags); } -int add_sigio_fd(int fd, int read) +static int add_sigio_fd(int fd, int read) { int err = 0, i, n, events; @@ -191,6 +191,13 @@ int ignore_sigio_fd(int fd) struct pollfd *p; int err = 0, i, n = 0; + /* This is called from exitcalls elsewhere in UML - if + * sigio_cleanup has already run, then update_thread will hang + * or fail because the thread is no longer running. + */ + if(write_sigio_pid == -1) + return -EIO; + sigio_lock(); for(i = 0; i < current_poll.used; i++){ if(current_poll.poll[i].fd == fd) break; @@ -215,7 +222,7 @@ int ignore_sigio_fd(int fd) update_thread(); out: sigio_unlock(); - return(err); + return err; } static struct pollfd *setup_initial_poll(int fd) @@ -233,7 +240,7 @@ static struct pollfd *setup_initial_poll(int fd) return p; } -void write_sigio_workaround(void) +static void write_sigio_workaround(void) { unsigned long stack; struct pollfd *p; @@ -314,10 +321,24 @@ out_close1: close(l_write_sigio_fds[1]); } -void sigio_cleanup(void) +void maybe_sigio_broken(int fd, int read) +{ + if(!isatty(fd)) + return; + + if((read || pty_output_sigio) && (!read || pty_close_sigio)) + return; + + write_sigio_workaround(); + add_sigio_fd(fd, read); +} + +static void sigio_cleanup(void) { if(write_sigio_pid != -1){ os_kill_process(write_sigio_pid, 1); write_sigio_pid = -1; } } + +__uml_exitcall(sigio_cleanup); diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index f11b312..60e4fae 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) set_signals(enabled); } -extern void do_boot_timer_handler(struct sigcontext * sc); - -void boot_timer_handler(ARCH_SIGHDLR_PARAM) -{ - struct sigcontext *sc; - int enabled; - - ARCH_GET_SIGCONTEXT(sc, sig); - - enabled = signals_enabled; - if(!enabled){ - if(sig == SIGVTALRM) - pending |= SIGVTALRM_MASK; - else pending |= SIGALRM_MASK; - return; - } - - block_signals(); - - do_boot_timer_handler(sc); - set_signals(enabled); -} - void set_sigstack(void *sig_stack, int size) { 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 bd89c6b..7baf90f 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) ptrace(PTRACE_TRACEME, 0, 0, 0); - init_new_thread_signals(1); + init_new_thread_signals(); enable_timer(); if(!proc_mm){ @@ -435,7 +435,6 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, { unsigned long flags; jmp_buf switch_buf, fork_buf; - int enable; *switch_buf_ptr = &switch_buf; *fork_buf_ptr = &fork_buf; @@ -450,7 +449,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, */ flags = get_signals(); block_signals(); - if(UML_SETJMP(&fork_buf, enable) == 0) + if(UML_SETJMP(&fork_buf) == 0) new_thread_proc(stack, handler); remove_sigstack(); @@ -467,21 +466,19 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, void thread_wait(void *sw, void *fb) { jmp_buf buf, **switch_buf = sw, *fork_buf; - int enable; *switch_buf = &buf; fork_buf = fb; - if(UML_SETJMP(&buf, enable) == 0) + if(UML_SETJMP(&buf) == 0) siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); } void switch_threads(void *me, void *next) { jmp_buf my_buf, **me_ptr = me, *next_buf = next; - int enable; *me_ptr = &my_buf; - if(UML_SETJMP(&my_buf, enable) == 0) + if(UML_SETJMP(&my_buf) == 0) UML_LONGJMP(next_buf, 1); } @@ -495,14 +492,14 @@ static jmp_buf *cb_back; int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) { jmp_buf **switch_buf = switch_buf_ptr; - int n, enable; + int n; set_handler(SIGWINCH, (__sighandler_t) sig_handler, SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, SIGVTALRM, -1); *fork_buf_ptr = &initial_jmpbuf; - n = UML_SETJMP(&initial_jmpbuf, enable); + n = UML_SETJMP(&initial_jmpbuf); switch(n){ case INIT_JMP_NEW_THREAD: 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) void initial_thread_cb_skas(void (*proc)(void *), void *arg) { jmp_buf here; - int enable; cb_proc = proc; cb_arg = arg; cb_back = &here; block_signals(); - if(UML_SETJMP(&here, enable) == 0) + if(UML_SETJMP(&here) == 0) UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); unblock_signals(); diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 280c4fb..4ae73c0 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -17,11 +17,6 @@ #include "kern_constants.h" #include "os.h" -/* XXX This really needs to be declared and initialized in a kernel file since - * it's in <linux/time.h> - */ -extern struct timespec wall_to_monotonic; - static void set_interval(int timer_type) { int usec = 1000000/hz(); @@ -71,6 +66,7 @@ void switch_timers(int to_real) errno); } +#ifdef UML_CONFIG_MODE_TT void uml_idle_timer(void) { if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) @@ -80,14 +76,7 @@ void uml_idle_timer(void) SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); set_interval(ITIMER_REAL); } - -void time_init(void) -{ - if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) - panic("Couldn't set SIGVTALRM handler"); - set_interval(ITIMER_VIRTUAL); - time_init_kern(); -} +#endif unsigned long long os_nsecs(void) { @@ -106,15 +95,7 @@ void idle_sleep(int secs) nanosleep(&ts, NULL); } -/* XXX This partly duplicates init_irq_signals */ - void user_time_init(void) { - set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, - SIGALRM, SIGUSR2, -1); - set_handler(SIGALRM, (__sighandler_t) alarm_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, - SIGVTALRM, SIGUSR2, -1); set_interval(ITIMER_VIRTUAL); } diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c index e523719..865f6a6 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, int n), int *faulted_out) { unsigned long *faddrp = (unsigned long *) fault_addr, ret; - int enable; jmp_buf jbuf; *fault_catcher = &jbuf; - if(UML_SETJMP(&jbuf, enable) == 0){ + if(UML_SETJMP(&jbuf) == 0){ (*op)(to, from, n); ret = 0; *faulted_out = 0; |