diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/file.c | 19 | ||||
-rw-r--r-- | arch/um/os-Linux/mem.c | 17 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 16 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 7 |
4 files changed, 45 insertions, 14 deletions
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 26e016489..2db18cbbb 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -264,6 +264,15 @@ int os_read_file(int fd, void *buf, int len) return n; } +int os_pread_file(int fd, void *buf, int len, unsigned long long offset) +{ + int n = pread(fd, buf, len, offset); + + if (n < 0) + return -errno; + return n; +} + int os_write_file(int fd, const void *buf, int len) { int n = write(fd, (void *) buf, len); @@ -282,6 +291,16 @@ int os_sync_file(int fd) return n; } +int os_pwrite_file(int fd, const void *buf, int len, unsigned long long offset) +{ + int n = pwrite(fd, (void *) buf, len, offset); + + if (n < 0) + return -errno; + return n; +} + + int os_file_size(const char *file, unsigned long long *size_out) { struct uml_stat buf; diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 897e9ad0c..8b1767668 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -106,6 +106,17 @@ static int __init make_tempfile(const char *template) } } +#ifdef O_TMPFILE + fd = open(tempdir, O_CLOEXEC | O_RDWR | O_EXCL | O_TMPFILE, 0700); + /* + * If the running system does not support O_TMPFILE flag then retry + * without it. + */ + if (fd != -1 || (errno != EINVAL && errno != EISDIR && + errno != EOPNOTSUPP)) + return fd; +#endif + tempname = malloc(strlen(tempdir) + strlen(template) + 1); if (tempname == NULL) return -1; @@ -142,12 +153,6 @@ static int __init create_tmp_file(unsigned long long len) if (fd < 0) exit(1); - err = fchmod(fd, 0777); - if (err < 0) { - perror("fchmod"); - exit(1); - } - /* * Seek to len - 1 because writing a character there will * increase the file size by one byte, to the desired length. diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index c211153ca..780166651 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -62,6 +62,7 @@ static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc) static int signals_enabled; static unsigned int signals_pending; +static unsigned int signals_active = 0; void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) { @@ -101,7 +102,12 @@ void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) block_signals(); + signals_active |= SIGALRM_MASK; + timer_real_alarm_handler(mc); + + signals_active &= ~SIGALRM_MASK; + set_signals(enabled); } @@ -286,8 +292,16 @@ void unblock_signals(void) if (save_pending & SIGIO_MASK) sig_handler_common(SIGIO, NULL, NULL); - if (save_pending & SIGALRM_MASK) + /* Do not reenter the handler */ + + if ((save_pending & SIGALRM_MASK) && (!(signals_active & SIGALRM_MASK))) timer_real_alarm_handler(NULL); + + /* Rerun the loop only if there is still pending SIGIO and not in TIMER handler */ + + if (!(signals_pending & SIGIO_MASK) && (signals_active & SIGALRM_MASK)) + return; + } } diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index b856c66eb..23025d645 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -172,13 +172,6 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, handle_syscall(regs); } -int get_syscall(struct uml_pt_regs *regs) -{ - UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp); - - return UPT_SYSCALL_NR(regs); -} - extern char __syscall_stub_start[]; static int userspace_tramp(void *stack) |