static ssize_t hostaudio_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct hostaudio_state *state = file->private_data; void *kbuf; int err; #ifdef DEBUG printk("hostaudio: write called, count = %d\n", count); #endif kbuf = kmalloc(count, GFP_KERNEL); if(kbuf == NULL) return(-ENOMEM); err = -EFAULT; if(copy_from_user(kbuf, buffer, count)) goto out; err = os_write_file(state->fd, kbuf, count); if(err < 0) goto out; *ppos += err; out: kfree(kbuf); return(err); }
void __init setup_physmem(unsigned long start, unsigned long reserve_end, unsigned long len, unsigned long long highmem) { unsigned long reserve = reserve_end - start; int pfn = PFN_UP(__pa(reserve_end)); int delta = (len - reserve) >> PAGE_SHIFT; int err, offset, bootmap_size; physmem_fd = create_mem_file(len + highmem); offset = uml_reserved - uml_physmem; err = os_map_memory((void *) uml_reserved, physmem_fd, offset, len - offset, 1, 1, 1); if (err < 0) { printf("setup_physmem - mapping %ld bytes of memory at 0x%p " "failed - errno = %d\n", len - offset, (void *) uml_reserved, err); exit(1); } /* * Special kludge - This page will be mapped in to userspace processes * from physmem_fd, so it needs to be written out there. */ os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); bootmap_size = init_bootmem(pfn, pfn + delta); free_bootmem(__pa(reserve_end) + bootmap_size, len - bootmap_size - reserve); }
static void tracer_winch_handler(int sig) { int n; char c = 1; n = os_write_file(tracer_winch[1], &c, sizeof(c)); if(n != sizeof(c)) printk("tracer_winch_handler - write failed, err = %d\n", -n); }
void switch_to_tt(void *prev, void *next) { struct task_struct *from, *to, *prev_sched; unsigned long flags; int err, vtalrm, alrm, prof, cpu; char c; from = prev; to = next; cpu = from->thread_info->cpu; if(cpu == 0) forward_interrupts(to->thread.mode.tt.extern_pid); #ifdef CONFIG_SMP forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid); #endif local_irq_save(flags); vtalrm = change_sig(SIGVTALRM, 0); alrm = change_sig(SIGALRM, 0); prof = change_sig(SIGPROF, 0); forward_pending_sigio(to->thread.mode.tt.extern_pid); c = 0; err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); /* If the process that we have just scheduled away from has exited, * then it needs to be killed here. The reason is that, even though * it will kill itself when it next runs, that may be too late. Its * stack will be freed, possibly before then, and if that happens, * we have a use-after-free situation. So, it gets killed here * in case it has not already killed itself. */ prev_sched = current->thread.prev_sched; if(prev_sched->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); change_sig(SIGVTALRM, vtalrm); change_sig(SIGALRM, alrm); change_sig(SIGPROF, prof); arch_switch(); flush_tlb_all(); local_irq_restore(flags); }
int net_write(int fd, void *buf, int len) { int n; n = os_write_file(fd, buf, len); if(n == -EAGAIN) return(0); else if(n == 0) return(-ENOTCONN); return(n); }
int net_write(int fd, void *buf, int len) { int n; n = os_write_file(fd, buf, len); if(n == -EAGAIN) return 0; else if(n == 0) return -ENOTCONN; return n; }
void smp_send_stop(void) { int i; printk(KERN_INFO "Stopping all CPUs..."); for (i = 0; i < num_online_cpus(); i++) { if (i == current_thread->cpu) continue; os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); } printk(KERN_CONT "done\n"); }
int ping_watchdog(int fd) { int n; char c = '\n'; n = os_write_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("ping_watchdog - write failed, err = %d\n", -n); if(n < 0) return n; return -EIO; } return 1; }
static int helper_child(void *arg) { struct helper_data *data = arg; char **argv = data->argv; int errval; if(helper_pause){ signal(SIGHUP, helper_hup); pause(); } if(data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); execvp(argv[0], argv); errval = errno; printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); os_write_file(data->fd, &errval, sizeof(errval)); os_kill_process(os_getpid(), 0); return(0); }
static void etap_change(int op, unsigned char *addr, unsigned char *netmask, int fd) { struct addr_change change; char *output; int n; change.what = op; memcpy(change.addr, addr, sizeof(change.addr)); memcpy(change.netmask, netmask, sizeof(change.netmask)); n = os_write_file(fd, &change, sizeof(change)); if(n != sizeof(change)) printk("etap_change - request failed, err = %d\n", -n); output = um_kmalloc(page_size()); if(output == NULL) printk("etap_change : Failed to allocate output buffer\n"); read_output(fd, output, page_size()); if(output != NULL){ printk("%s", output); kfree(output); } }
static int __init create_pid_file(void) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")]; int fd, n; if(umid_file_name("pid", file, sizeof(file))) return 0; fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 0644); if(fd < 0){ printf("Open of machine pid file \"%s\" failed: %s\n", file, strerror(-fd)); return 0; } sprintf(pid, "%d\n", os_getpid()); n = os_write_file(fd, pid, strlen(pid)); if(n != strlen(pid)) printf("Write of pid file failed - err = %d\n", -n); os_close_file(fd); return 0; }
static ssize_t hostaudio_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct hostaudio_state *state = file->private_data; void *kbuf; int err; #ifdef DEBUG printk(KERN_DEBUG "hostaudio: write called, count = %d\n", count); #endif kbuf = memdup_user(buffer, count); if (IS_ERR(kbuf)) return PTR_ERR(kbuf); err = os_write_file(state->fd, kbuf, count); if (err < 0) goto out; *ppos += err; out: kfree(kbuf); return err; }
void smp_send_reschedule(int cpu) { os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1); num_reschedules_sent++; }
static int connect_to_switch(struct daemon_data *pri) { struct sockaddr_un *ctl_addr = pri->ctl_addr; struct sockaddr_un *local_addr = pri->local_addr; struct sockaddr_un *sun; struct request_v3 req; int fd, n, err; pri->control = socket(AF_UNIX, SOCK_STREAM, 0); if(pri->control < 0){ printk("daemon_open : control socket failed, errno = %d\n", errno); return(-errno); } if(connect(pri->control, (struct sockaddr *) ctl_addr, sizeof(*ctl_addr)) < 0){ printk("daemon_open : control connect failed, errno = %d\n", errno); err = -errno; goto out; } fd = socket(AF_UNIX, SOCK_DGRAM, 0); if(fd < 0){ printk("daemon_open : data socket failed, errno = %d\n", errno); err = -errno; goto out; } if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){ printk("daemon_open : data bind failed, errno = %d\n", errno); err = -errno; goto out_close; } sun = um_kmalloc(sizeof(struct sockaddr_un)); if(sun == NULL){ printk("new_addr: allocation of sockaddr_un failed\n"); err = -ENOMEM; goto out_close; } req.magic = SWITCH_MAGIC; req.version = SWITCH_VERSION; req.type = REQ_NEW_CONTROL; req.sock = *local_addr; n = os_write_file(pri->control, &req, sizeof(req)); if(n != sizeof(req)){ printk("daemon_open : control setup request failed, err = %d\n", -n); err = -ENOTCONN; goto out_free; } n = os_read_file(pri->control, sun, sizeof(*sun)); if(n != sizeof(*sun)){ printk("daemon_open : read of data socket failed, err = %d\n", -n); err = -ENOTCONN; goto out_free; } pri->data_addr = sun; return(fd); out_free: kfree(sun); out_close: os_close_file(fd); out: os_close_file(pri->control); return(err); }
void switch_to_tt(void *prev, void *next) { struct task_struct *from, *to, *prev_sched; unsigned long flags; int err, vtalrm, alrm, prof, cpu; char c; from = prev; to = next; cpu = task_thread_info(from)->cpu; if(cpu == 0) forward_interrupts(to->thread.mode.tt.extern_pid); #ifdef CONFIG_SMP forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid); #endif local_irq_save(flags); vtalrm = change_sig(SIGVTALRM, 0); alrm = change_sig(SIGALRM, 0); prof = change_sig(SIGPROF, 0); forward_pending_sigio(to->thread.mode.tt.extern_pid); c = 0; /* Notice that here we "up" the semaphore on which "to" is waiting, and * below (the read) we wait on this semaphore (which is implemented by * switch_pipe) and go sleeping. Thus, after that, we have resumed in * "to", and can't use any more the value of "from" (which is outdated), * nor the value in "to" (since it was the task which stole us the CPU, * which we don't care about). */ err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); /* If the process that we have just scheduled away from has exited, * then it needs to be killed here. The reason is that, even though * it will kill itself when it next runs, that may be too late. Its * stack will be freed, possibly before then, and if that happens, * we have a use-after-free situation. So, it gets killed here * in case it has not already killed itself. */ prev_sched = current->thread.prev_sched; if(prev_sched->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); change_sig(SIGVTALRM, vtalrm); change_sig(SIGALRM, alrm); change_sig(SIGPROF, prof); arch_switch_to_tt(prev_sched, current); flush_tlb_all(); local_irq_restore(flags); }
int generic_write(int fd, const char *buf, int n, void *unused) { return os_write_file(fd, buf, n); }
void *switch_to_tt(void *prev, void *next, void *last) { struct task_struct *from, *to, *prev_sched; unsigned long flags; int err, vtalrm, alrm, prof, cpu; char c; /* jailing and SMP are incompatible, so this doesn't need to be * made per-cpu */ static int reading; from = prev; to = next; to->thread.prev_sched = from; cpu = from->thread_info->cpu; if(cpu == 0) forward_interrupts(to->thread.mode.tt.extern_pid); #ifdef CONFIG_SMP forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid); #endif local_irq_save(flags); vtalrm = change_sig(SIGVTALRM, 0); alrm = change_sig(SIGALRM, 0); prof = change_sig(SIGPROF, 0); forward_pending_sigio(to->thread.mode.tt.extern_pid); c = 0; set_current(to); reading = 0; err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); reading = 1; if((from->exit_state == EXIT_ZOMBIE) || (from->exit_state == EXIT_DEAD)) os_kill_process(os_getpid(), 0); err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); /* If the process that we have just scheduled away from has exited, * then it needs to be killed here. The reason is that, even though * it will kill itself when it next runs, that may be too late. Its * stack will be freed, possibly before then, and if that happens, * we have a use-after-free situation. So, it gets killed here * in case it has not already killed itself. */ prev_sched = current->thread.prev_sched; if((prev_sched->exit_state == EXIT_ZOMBIE) || (prev_sched->exit_state == EXIT_DEAD)) os_kill_ptraced_process(prev_sched->thread.mode.tt.extern_pid, 1); /* This works around a nasty race with 'jail'. If we are switching * between two threads of a threaded app and the incoming process * runs before the outgoing process reaches the read, and it makes * it all the way out to userspace, then it will have write-protected * the outgoing process stack. Then, when the outgoing process * returns from the write, it will segfault because it can no longer * write its own stack. So, in order to avoid that, the incoming * thread sits in a loop yielding until 'reading' is set. This * isn't entirely safe, since there may be a reschedule from a timer * happening between setting 'reading' and sleeping in read. But, * it should get a whole quantum in which to reach the read and sleep, * which should be enough. */ if(jail){ while(!reading) sched_yield(); } change_sig(SIGVTALRM, vtalrm); change_sig(SIGALRM, alrm); change_sig(SIGPROF, prof); arch_switch(); flush_tlb_all(); local_irq_restore(flags); return(current->thread.prev_sched); }
} int new_mm(int from) { struct proc_mm_op copy; int n, fd; fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); if(fd < 0) return(fd); if(from != -1){ copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, .u = { .copy_segments = from } } ); n = os_write_file(fd, ©, sizeof(copy)); if(n != sizeof(copy)) printk("new_mm : /proc/mm copy_segments failed, " "err = %d\n", -n); } return(fd); } void init_idle_skas(void) { cpu_tasks[current_thread->cpu].pid = os_getpid(); default_idle(); } extern void start_kernel(void);