static int netif_watch_event(netif_watch_t *w, int fd) { struct iovec iov; struct msghdr smsg; struct cmsghdr *cmsg; struct ucred *cred; char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; ssize_t bytes; log_debug(3, "netif_watch_event"); iov.iov_base = w->buf; iov.iov_len = sizeof(w->buf); smsg.msg_name = NULL; smsg.msg_namelen = 0; smsg.msg_iov = &iov; smsg.msg_iovlen = 1; smsg.msg_control = cred_msg; smsg.msg_controllen = sizeof(cred_msg); smsg.msg_flags = MSG_DONTWAIT; if ((bytes = recvmsg(fd, &smsg, 0)) < 0) { if ((errno == EAGAIN) || (errno == EINTR)) { return 1; } log_str("ERROR: netlink recvmsg(): %s", strerror(errno)); return 0; } cmsg = CMSG_FIRSTHDR(&smsg); if ((cmsg == NULL) || (cmsg->cmsg_type != SCM_CREDENTIALS)) { log_str("WARNING: netlink recvmsg(): No sender credentials received, ignoring data."); return 1; } cred = (struct ucred*) CMSG_DATA(cmsg); if (cred->pid != 0) { return 1; } /* Throw event with lowpass filtering */ if (w->timeout_tag) { sys_remove(w->timeout_tag); } w->timeout_tag = sys_timeout(NETIF_WATCH_LOWPASS_DELAY, (sys_func_t) netif_watch_process, w); return 1; }
static void tcp_sock_shutdown_(tcp_sock_t *tcp_sock, int silent) { if (tcp_sock->chan.tag > 0) { sys_remove(tcp_sock->chan.tag); tcp_sock->chan.tag = 0; } if (tcp_sock->chan.fd >= 0) { if (!silent) { log_str("Shutting down connection [%d]", tcp_sock->chan.fd); } shutdown(tcp_sock->chan.fd, 2); close(tcp_sock->chan.fd); tcp_sock->chan.fd = -1; } }
static void _input(hk_pad_t *pad, char *value) { ctx_t *ctx = pad->obj->ctx; int state0 = pad->state; pad->state = atoi(value) ? 1:0; if (((ctx->edge & EDGE_RAISING) && (state0 == 0) && (pad->state == 1)) || ((ctx->edge & EDGE_FALLING) && (state0 == 1) && (pad->state == 0))) { if ((ctx->output->state == 0) || ctx->retrigger) { if (ctx->timeout_tag != 0) { sys_remove(ctx->timeout_tag); } ctx->timeout_tag = sys_timeout(ctx->delay, (sys_func_t) timeout, ctx); if (ctx->output->state == 0) { ctx->output->state = 1; hk_pad_update_int(ctx->output, 1 ^ ctx->inv); } } } }
static void syscall_handler (struct intr_frame *f) { int syscall_number; ASSERT( sizeof(syscall_number) == 4 ); // assuming x86 // The system call number is in the 32-bit word at the caller's stack pointer. memread_user(f->esp, &syscall_number, sizeof(syscall_number)); _DEBUG_PRINTF ("[DEBUG] system call, number = %d!\n", syscall_number); // Store the esp, which is needed in the page fault handler. // refer to exception.c:page_fault() (see manual 4.3.3) thread_current()->current_esp = f->esp; // Dispatch w.r.t system call number // SYS_*** constants are defined in syscall-nr.h switch (syscall_number) { case SYS_HALT: // 0 { sys_halt(); NOT_REACHED(); break; } case SYS_EXIT: // 1 { int exitcode; memread_user(f->esp + 4, &exitcode, sizeof(exitcode)); sys_exit(exitcode); NOT_REACHED(); break; } case SYS_EXEC: // 2 { void* cmdline; memread_user(f->esp + 4, &cmdline, sizeof(cmdline)); int return_code = sys_exec((const char*) cmdline); f->eax = (uint32_t) return_code; break; } case SYS_WAIT: // 3 { pid_t pid; memread_user(f->esp + 4, &pid, sizeof(pid_t)); int ret = sys_wait(pid); f->eax = (uint32_t) ret; break; } case SYS_CREATE: // 4 { const char* filename; unsigned initial_size; bool return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); memread_user(f->esp + 8, &initial_size, sizeof(initial_size)); return_code = sys_create(filename, initial_size); f->eax = return_code; break; } case SYS_REMOVE: // 5 { const char* filename; bool return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_remove(filename); f->eax = return_code; break; } case SYS_OPEN: // 6 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_open(filename); f->eax = return_code; break; } case SYS_FILESIZE: // 7 { int fd, return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_filesize(fd); f->eax = return_code; break; } case SYS_READ: // 8 { int fd, return_code; void *buffer; unsigned size; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &buffer, sizeof(buffer)); memread_user(f->esp + 12, &size, sizeof(size)); return_code = sys_read(fd, buffer, size); f->eax = (uint32_t) return_code; break; } case SYS_WRITE: // 9 { int fd, return_code; const void *buffer; unsigned size; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &buffer, sizeof(buffer)); memread_user(f->esp + 12, &size, sizeof(size)); return_code = sys_write(fd, buffer, size); f->eax = (uint32_t) return_code; break; } case SYS_SEEK: // 10 { int fd; unsigned position; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &position, sizeof(position)); sys_seek(fd, position); break; } case SYS_TELL: // 11 { int fd; unsigned return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_tell(fd); f->eax = (uint32_t) return_code; break; } case SYS_CLOSE: // 12 { int fd; memread_user(f->esp + 4, &fd, sizeof(fd)); sys_close(fd); break; } #ifdef VM case SYS_MMAP: // 13 { int fd; void *addr; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &addr, sizeof(addr)); mmapid_t ret = sys_mmap (fd, addr); f->eax = ret; break; } case SYS_MUNMAP: // 14 { mmapid_t mid; memread_user(f->esp + 4, &mid, sizeof(mid)); sys_munmap(mid); break; } #endif #ifdef FILESYS case SYS_CHDIR: // 15 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_chdir(filename); f->eax = return_code; break; } case SYS_MKDIR: // 16 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_mkdir(filename); f->eax = return_code; break; } case SYS_READDIR: // 17 { int fd; char *name; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &name, sizeof(name)); return_code = sys_readdir(fd, name); f->eax = return_code; break; } case SYS_ISDIR: // 18 { int fd; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_isdir(fd); f->eax = return_code; break; } case SYS_INUMBER: // 19 { int fd; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_inumber(fd); f->eax = return_code; break; } #endif /* unhandled case */ default: printf("[ERROR] system call %d is unimplemented!\n", syscall_number); // ensure that waiting (parent) process should wake up and terminate. sys_exit(-1); break; } }
static void syscall_handler (struct intr_frame *f) { if(f) { stack_address_check(f->esp); // get sys call number off the stack int sys_call_no = get_nth_arg_int(f->esp, 0); DPRINTF("system call! %d\n", sys_call_no); switch(sys_call_no) { case SYS_HALT: power_off(); break; case SYS_EXIT: { int status = get_nth_arg_int(f->esp, 1); thread_current()->exit_status = status; process_terminate(); return; } break; case SYS_EXEC: { char* file_name = (char*)get_nth_arg_ptr(f->esp, 1); user_string_add_range_check_and_terminate(file_name); int tid = sys_exec(file_name); DPRINTF("exec %s, tid = %d\n", file_name, tid); f->eax = tid; } return; case SYS_WAIT: { int pid = get_nth_arg_int(f->esp, 1); int ret = process_wait(pid); DPRINTF("wait for pid %d by %d return %d\n", pid, thread_current()->tid ,ret); f->eax = ret; } return; case SYS_CREATE: { char* file_name = (char*)get_nth_arg_ptr(f->esp, 1); user_string_add_range_check_and_terminate(file_name); int size = get_nth_arg_int(f->esp, 2); DPRINTF("sys_create(%s,%d)\n", file_name, size); f->eax = sys_create(file_name, size); } return; case SYS_REMOVE: { char* file_name = (char*)get_nth_arg_ptr(f->esp, 1); user_string_add_range_check_and_terminate(file_name); DPRINTF("sys_remove(%s)\n", file_name); f->eax = sys_remove(file_name); } return; case SYS_OPEN: { char* file_name = (char*)get_nth_arg_ptr(f->esp, 1); user_string_add_range_check_and_terminate(file_name); DPRINTF("sys_open(%s)\n", file_name); f->eax = sys_open(file_name); } return; case SYS_FILESIZE: { int fd = get_nth_arg_int(f->esp, 1); DPRINTF("sys_filesize(%d)\n", fd); f->eax = sys_filesize(fd); } return; case SYS_READ: { int fd = get_nth_arg_int(f->esp, 1); char* buf = (char*)get_nth_arg_ptr(f->esp, 2); int size = get_nth_arg_int(f->esp, 3); user_add_range_check_and_terminate(buf, size); DPRINTF("sys_read(%d,%s,%d)\n", fd, buf, size); f->eax = sys_read(fd, buf, size); } return; case SYS_WRITE: { int fd = get_nth_arg_int(f->esp, 1); char* buf = (char*)get_nth_arg_ptr(f->esp, 2); int size = get_nth_arg_int(f->esp, 3); user_add_range_check_and_terminate(buf, size); DPRINTF("sys_write(%d,%s,%d)\n", fd, buf, size); f->eax = sys_write(fd, buf, size); } return; case SYS_SEEK: { int fd = get_nth_arg_int(f->esp, 1); unsigned pos = get_nth_arg_int(f->esp, 2); DPRINTF("sys_seek(%d,%d)\n", fd, pos); sys_seek(fd, pos); } return; case SYS_TELL: { int fd = get_nth_arg_int(f->esp, 1); DPRINTF("sys_tell(%d)\n", fd); f->eax = sys_tell(fd); } return; case SYS_CLOSE: { int fd = get_nth_arg_int(f->esp, 1); DPRINTF("sys_close(%d)\n", fd); sys_close(fd); } return; /* case SYS_MMAP: case SYS_MUNMAP: case SYS_CHDIR: case SYS_MKDIR: case SYS_READDIR: case SYS_ISDIR: case SYS_INUMBER: */ default: thread_exit(); break; } } else thread_exit(); }
static void syscall_handler (struct intr_frame *f) { int sys_vector; sys_vector=*(int *)(f->esp); switch(sys_vector) { case SYS_HALT: esp_under_phys_base(f, 0); sys_halt (); break; case SYS_EXIT: if ((void *)((int *)f->esp + 1) >= PHYS_BASE) sys_exit (-1); else sys_exit (*((int *)f->esp + 1)); break; case SYS_EXEC: esp_under_phys_base(f, 1); under_phys_base (*((int **)f->esp + 1)); sys_exec (*((int **)f->esp + 1), f); break; case SYS_WAIT: esp_under_phys_base(f, 1); sys_wait (*((int *)f->esp + 1), f); break; case SYS_CREATE: if ((void*)*((int **)f->esp + 1) == NULL) sys_exit(-1); esp_under_phys_base(f, 2); under_phys_base (*((int **)f->esp + 1)); sys_create (*((int **)f->esp + 1), *((int *)f->esp + 2), f); break; case SYS_REMOVE: esp_under_phys_base(f, 1); under_phys_base (*((int **)f->esp + 1)); sys_remove (*((int **)f->esp + 1), f); break; case SYS_OPEN: if ((void*)*((int **)f->esp + 1) == NULL) sys_exit(-1); esp_under_phys_base(f, 1); under_phys_base (*((int **)f->esp + 1)); sys_open (*((int **)f->esp + 1), f); break; case SYS_FILESIZE: esp_under_phys_base(f, 1); check_fd(*((int *)f->esp + 1), -1, f); sys_filesize (*((int *)f->esp + 1), f); break; case SYS_READ: esp_under_phys_base(f, 3); under_phys_base (*((int **)f->esp + 2)); check_fd(*((int *)f->esp + 1), -1, f) sys_read (*((int *)f->esp + 1), *((int **)f->esp + 2), *((int *)f->esp + 3), f); break; case SYS_WRITE: esp_under_phys_base(f, 3); under_phys_base (*((int **)f->esp + 2)); check_fd(*((int *)f->esp + 1), -1, f) sys_write (*((int *)f->esp + 1), *((int **)f->esp + 2), *((int *)f->esp + 3), f); break; case SYS_SEEK: esp_under_phys_base(f, 2); check_fd(*((int *)f->esp + 1), 0, f) sys_seek (*((int *)f->esp + 1), *((int *)f->esp + 2), f); break; case SYS_TELL: esp_under_phys_base(f, 1); check_fd(*((int *)f->esp + 1), 0, f) sys_tell (*((int *)f->esp + 1), f); break; case SYS_CLOSE: esp_under_phys_base(f, 1); check_fd(*((int *)f->esp + 1), 0, f) sys_close (*((int *)f->esp + 1), f); break; } }
/* Syscall handler calls the appropriate function. */ static void syscall_handler (struct intr_frame *f) { int ret = 0; int *syscall_nr = (int *) f->esp; void *arg1 = (int *) f->esp + 1; void *arg2 = (int *) f->esp + 2; void *arg3 = (int *) f->esp + 3; /* Check validate pointer. */ if (!is_user_vaddr (syscall_nr) || !is_user_vaddr (arg1) || !is_user_vaddr (arg2) || !is_user_vaddr (arg3)) sys_exit (-1); switch (*syscall_nr) { case SYS_HALT: sys_halt (); break; case SYS_EXIT: sys_exit (*(int *) arg1); break; case SYS_EXEC: ret = sys_exec (*(char **) arg1); break; case SYS_WAIT: ret = sys_wait (*(pid_t *) arg1); break; case SYS_CREATE: ret = sys_create (*(char **) arg1, *(unsigned *) arg2); break; case SYS_REMOVE: ret = sys_remove (*(char **) arg1); break; case SYS_OPEN: ret = sys_open (*(char **) arg1); break; case SYS_FILESIZE: ret = sys_filesize (*(int *) arg1); break; case SYS_READ: ret = sys_read (*(int *) arg1, *(void **) arg2, *(unsigned *) arg3); break; case SYS_WRITE: ret = sys_write (*(int *) arg1, *(void **) arg2, *(unsigned *) arg3); break; case SYS_SEEK: sys_seek (*(int *) arg1, *(unsigned *) arg2); break; case SYS_TELL: ret = sys_tell (*(int *) arg1); break; case SYS_CLOSE: sys_close (*(int *) arg1); break; default: printf (" (%s) system call! (%d)\n", thread_name (), *syscall_nr); sys_exit (-1); break; } f->eax = ret; }
static void syscall_handler (struct intr_frame *f) { /* Check to see that we can read supplied user memory pointer, using the check_mem_ptr helper() function, in get_word_from_stack(). If the check fails, the process is terminated. */ int syscall_number = (int)get_word_on_stack(f, 0); switch(syscall_number) { case SYS_HALT: { sys_halt(); break; } case SYS_EXIT: { int status = (int)get_word_on_stack(f, 1); sys_exit(status); /* Returns exit status to the kernel. */ f->eax = status; break; } case SYS_EXEC: { const char *cmd_line = (const char *)get_word_on_stack(f, 1); pid_t pid = sys_exec(cmd_line); /* Returns new processes pid. */ f->eax = pid; break; } case SYS_WAIT: { pid_t pid = (pid_t)get_word_on_stack(f, 1); /* Returns child's exit status (pid argument is pid of this child). */ f->eax = sys_wait(pid); break; } case SYS_CREATE: { const char *filename = (const char *)get_word_on_stack(f, 1); unsigned initial_size = (unsigned)get_word_on_stack(f, 2); /* Returns true to the kernel if creation is successful. */ f->eax = (int)sys_create(filename, initial_size); break; } case SYS_REMOVE: { const char *filename = (const char *)get_word_on_stack(f, 1); /* Returns true if successful, and false otherwise. */ f->eax = sys_remove(filename); break; } case SYS_OPEN: { const char *filename = (const char *)get_word_on_stack(f, 1); /* Returns file descriptor of opened file, or -1 if it could not be opened. */ f->eax = sys_open(filename); break; } case SYS_FILESIZE: { int fd = (int)get_word_on_stack(f, 1); /* Returns size of file in bytes. */ f->eax = sys_filesize(fd); break; } case SYS_READ: { int fd = (int)get_word_on_stack(f, 1); void *buffer = (void *)get_word_on_stack(f, 2); unsigned size = (unsigned)get_word_on_stack(f, 3); /* Returns number of bytes actually read, or -1 if it could not be read. */ f->eax = sys_read(fd, buffer, size, f); break; } case SYS_WRITE: { int fd = (int)get_word_on_stack(f, 1); void *buffer = (void *)get_word_on_stack(f, 2); unsigned size = (unsigned)get_word_on_stack(f, 3); /* Returns number of bytes written. */ f->eax = sys_write(fd, buffer, size); break; } case SYS_SEEK: { int fd = (int)get_word_on_stack(f, 1); unsigned position = (int)get_word_on_stack(f, 2); sys_seek(fd, position); break; } case SYS_TELL: { int fd = (int)get_word_on_stack(f, 1); /* Returns the position of the next byte to be read or written in open file 'fd' (in bytes, from start of file). */ f->eax = sys_tell(fd); break; } case SYS_CLOSE: { int fd = (int)get_word_on_stack(f, 1); sys_close(fd); break; } case SYS_MMAP: { int fd = (int)get_word_on_stack(f, 1); void *addr = (void *)get_word_on_stack(f, 2); f->eax = sys_mmap(fd, addr); break; } case SYS_MUNMAP: { mapid_t mapping = (mapid_t)get_word_on_stack(f, 1); sys_munmap(mapping); break; } default: { NOT_REACHED(); } } }
static void syscall_handler (struct intr_frame *f) { int *sys_call; int *status; int *fd; const char **buf; int *size; const char **file; tid_t *pid; const char **cmd_line; unsigned *initial_size; unsigned *position; void **buffer; sys_call = (int*) f->esp; check_ptr(sys_call); switch(*sys_call) { case SYS_HALT: sys_halt (); break; case SYS_EXIT: status = (int *) get_arg_ptr (f->esp, 1); sys_exit(*status); NOT_REACHED(); break; case SYS_EXEC: cmd_line = (const char **) get_arg_ptr (f->esp, 1); f->eax = sys_exec (*cmd_line); break; case SYS_WAIT: pid = (tid_t *) get_arg_ptr (f->esp, 1); f->eax = sys_wait (*pid); break; case SYS_CREATE: file = (const char **) get_arg_ptr (f->esp, 1); initial_size = (unsigned *) get_arg_ptr (f->esp, 2); f->eax = sys_create (*file, *initial_size); break; case SYS_REMOVE: file = (const char **) get_arg_ptr (f->esp, 1); f->eax = sys_remove (*file); break; case SYS_OPEN: file = (const char **) get_arg_ptr(f->esp, 1); f->eax = sys_open (*file); break; case SYS_FILESIZE: fd = (int *) get_arg_ptr (f->esp, 1); f->eax = sys_filesize (*fd); break; case SYS_READ: fd = (int *) get_arg_ptr (f->esp, 1); buffer = (void **) get_arg_ptr (f->esp, 2); size = (int *) get_arg_ptr (f->esp, 3); f->eax = sys_read (*fd, *buffer, *size); break; case SYS_WRITE: fd = (int *) get_arg_ptr (f->esp, 1); buf = (const void **) get_arg_ptr (f->esp, 2); size = (int *) get_arg_ptr (f->esp, 3); f->eax = sys_write (*fd, *buf, *size); break; case SYS_SEEK: fd = (int *) get_arg_ptr (f->esp, 1); position = (unsigned *) get_arg_ptr (f->esp, 2); sys_seek (*fd, *position); break; case SYS_TELL: fd = (int *) get_arg_ptr (f->esp, 1); f->eax = sys_tell (*fd); break; case SYS_CLOSE: fd = (int *) get_arg_ptr (f->esp, 1); sys_close (*fd); break; default: printf ("Unrecognized system call!\n"); thread_exit (); } }