sys_thread_t sys_thread_new(const char* name, lwip_thread_fn thread, void* arg, int stacksize, int prio) { LWIP_UNUSED_ARG(name); LWIP_UNUSED_ARG(stacksize); LWIP_UNUSED_ARG(prio); return sys_clone((int (*)(void*)) thread, NULL, CLONE_VM | CLONE_FILES | CLONE_FS | CLONE_SIGHAND, arg); }
static int local_clone (int (*fn)(void *), void *arg, ...) { /* Leave 4kB of gap between the callers stack and the new clone. This * should be more than sufficient for the caller to call waitpid() until * the cloned thread terminates. * * It is important that we set the CLONE_UNTRACED flag, because newer * versions of "gdb" otherwise attempt to attach to our thread, and will * attempt to reap its status codes. This subsequently results in the * caller hanging indefinitely in waitpid(), waiting for a change in * status that will never happen. By setting the CLONE_UNTRACED flag, we * prevent "gdb" from stealing events, but we still expect the thread * lister to fail, because it cannot PTRACE_ATTACH to the process that * is being debugged. This is OK and the error code will be reported * correctly. */ return sys_clone(fn, (char *)&arg - 4096, CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED, arg, 0, 0, 0); }
int init(void) { tty_read_init(); inode_t* ino_outp; if(unlikely((ino_outp = vfs_mkdev("tty", 0, S_IFCHR | 0666)) == NULL)) return -1; inode_t* ino_inp; if(unlikely((ino_inp = vfs_mkdev("tty", 1, S_IFCHR | 0666)) == NULL)) return -1; struct tty_context* tio = (struct tty_context*) kmalloc(sizeof(struct tty_context), GFP_KERNEL); if(unlikely(!tio)) { kprintf(ERROR "tty: no memory left!"); return -1; } memset(tio, 0, sizeof(struct tty_context)); tio->ios.c_iflag = TTYDEF_IFLAG; tio->ios.c_oflag = TTYDEF_OFLAG; tio->ios.c_cflag = TTYDEF_CFLAG; tio->ios.c_lflag = TTYDEF_LFLAG; tio->ios.c_cc[VEOF] = CEOF; tio->ios.c_cc[VEOL] = CEOL; tio->ios.c_cc[VERASE] = CERASE; tio->ios.c_cc[VINTR] = CINTR; tio->ios.c_cc[VKILL] = CKILL; tio->ios.c_cc[VMIN] = CMIN; tio->ios.c_cc[VQUIT] = CQUIT; tio->ios.c_cc[VSUSP] = CSUSP; tio->ios.c_cc[VTIME] = CTIME; tio->ios.c_cc[VSTART] = CSTART; tio->ios.c_cc[VSTOP] = CSTOP; tio->ios.__c_ispeed = tio->ios.__c_ospeed = TTYDEF_SPEED; tio->winsize.ws_row = 25; tio->winsize.ws_col = 80; tio->winsize.ws_xpixel = 80 * 8; tio->winsize.ws_ypixel = 25 * 16; tio->lined = 0; tio->output = 1; tio->outlen = 0; fifo_init(&tio->in, TTY_BUFSIZ, O_NONBLOCK); fifo_init(&tio->uin, TTY_BUFSIZ, O_NONBLOCK); ino_outp->read = tty_read; ino_outp->write = tty_output_write; ino_outp->ioctl = tty_ioctl; ino_outp->userdata = (void*) tio; ino_inp->read = tty_read; ino_inp->write = tty_input_write; ino_inp->ioctl = tty_ioctl; ino_inp->userdata = (void*) tio; extern int tty_daemon(void*); if(sys_clone(tty_daemon, NULL, CLONE_VM | CLONE_FILES | CLONE_FS | CLONE_SIGHAND, NULL) < 0) kprintf(ERROR "tty: daemon could not start! Some actions like keystroke's binding will be disabled\n"); sys_symlink("/dev/tty1", "/dev/stdin"); sys_symlink("/dev/tty0", "/dev/stdout"); sys_symlink("/dev/tty0", "/dev/stderr"); sys_symlink("/dev/tty0", "/dev/tty"); /* fallback */ return 0; }