int usys_kill(int *err, uuprocess_t *u, int pid, int sig) { (void) u; hal_mutex_lock(&proc_lock); //panic("kill is not implemented"); uuprocess_t * p = proc_by_pid(pid); if(!p) { hal_mutex_unlock(&proc_lock); *err = ESRCH; return -1; } //int ret = 0; sig_send( &p->signals, sig ); hal_mutex_unlock(&proc_lock); //if(ret) *err = EINVAL; //return ret; return 0; }
int usys_waitpid(int *err, uuprocess_t *u, int pid, int *status, int options) { int retpid = -1; (void) status; (void) options; hal_mutex_lock(&proc_lock); if( pid <= 0 ) { *err = EINVAL; retpid = -1; } else { uuprocess_t * p = proc_by_pid(pid); if( p == 0 || (p->ppid != u->pid ) ) { *err = ECHILD; retpid = -1; goto finish; } } #warning impl finish: hal_mutex_unlock(&proc_lock); return retpid; }
/** * C side of page fault handler. * * @param errcode errorcode pushed on stack by the fault * @param cr3 value of cr3 register (location of fault) */ void handle_page_fault(u32 errcode, u32 cr2, u32 eip, u32 *ebp) { u32 *cr3 = get_pagedir(); kerror(ERR_MEDERR, "Page fault at 0x%08X --> 0x%08X (%s%s%s%s%s)", cr2, pgdir_get_page_entry(cr3, (void *)cr2) & 0xFFFFF000, ((errcode & 0x01) ? "present" : "non-present"), ((errcode & 0x02) ? ", write" : ", read"), ((errcode & 0x04) ? ", user-mode" : ", kernel-mode"), ((errcode & 0x08) ? ", modified reserved field" : ""), ((errcode & 0x10) ? ", instruction fetch" : "")); kerror(ERR_MEDERR, " -> EIP: %08X", eip); if(cr2 >= (u32)firstframe) { int frame = (cr2 - (u32)firstframe) / 0x1000; kerror(ERR_MEDERR, " -> On frame %08X(%d)", frame, frame); } else kerror(ERR_MEDERR, " -> Occurred in kernel-space, not in the page frames"); kerror(ERR_MEDERR, " -> Page flags: 0x%03X", pgdir_get_page_entry(cr3, (void *)cr2) & 0xFFF); kerror(ERR_MEDERR, " -> Page Directory: 0x%08X", cr3); kerror(ERR_MEDERR, " -> Kernel pagedir: 0x%08X", kernel_cr3); if(tasking) { int pid = current_pid; int p = proc_by_pid(pid); if(p == -1) { kerror(ERR_MEDERR, "Failed to get process index from pid (%d)", pid); for(;;); } kerror(ERR_MEDERR, " -> Caused by process %d [%s]", pid, procs[p].name); if(((cr2 < procs[p].stack_beg) && (cr2 > procs[p].stack_end - STACK_SIZE)) || // Remember, the x86 stack is upside-down ((cr2 < procs[p].stack_beg + STACK_SIZE) && (cr2 > procs[p].stack_end))) { kerror(ERR_MEDERR, " -> Caused a stack overflow and is being dealt with", pid); } if(ebp != NULL) { stack_trace(5, ebp, eip); } exit(1); } if(ebp != NULL) { stack_trace(5, ebp, eip); } kpanic("Page fault, multitasking not enabled, nothing to do to fix this."); for(;;); }
int uu_create_process( int ppid ) { hal_mutex_lock(&proc_lock); uuprocess_t *p = get_proc(); assert(p); memset( p, 0, sizeof(uuprocess_t) ); p->pid = get_pid(); p->ppid = p->pid; p->pgrp_pid = p->pid; p->sess_pid = p->pid; p->uid = p->euid = p->gid = p->egid = 0; // Let it be root at start p->umask = 0664; int i; for( i = 0; i < MAX_UU_TID; i++ ) p->tids[i] = -1; uuprocess_t * parent = proc_by_pid(ppid); if( parent ) { p->ppid = ppid; p->pgrp_pid = parent->pgrp_pid; p->sess_pid = parent->sess_pid; p->ctty = parent->ctty; p->cwd_file = copy_uufile( parent->cwd_file ); memcpy( p->cwd_path, parent->cwd_path, FS_MAX_PATH_LEN ); p->umask = parent->umask; } else { //reopen_stdioe( p, "/dev/tty" ); strlcpy( p->cwd_path, "/", FS_MAX_PATH_LEN ); } sig_init( &(p->signals) ); // Mostly created, do final things SHOW_FLOW( 11, "ctty %p", p->ctty ); // allways, while there is no files inherited reopen_stdioe( p, "/dev/tty" ); hal_mutex_unlock(&proc_lock); return p->pid; };
static int pid_used(int pid) { /* int i; for( i = 0; i < MAX_UU_PROC; i++ ) if( proc[i].pid == pid ) return 1; return 0; */ return proc_by_pid(pid) != 0; }
// Add thread to process. errno_t uu_proc_add_thread( int pid, int tid ) { errno_t rc = 0; assert( tid >= 0 ); assert( pid > 0 ); /* // TODO t_set_pid phantom_thread_t *t = get_thread(tid); assert( t ); assert( t->u == 0 ); */ hal_mutex_lock(&proc_lock); rc = t_set_pid( tid, pid ); if( rc ) goto finish; uuprocess_t * p = proc_by_pid(pid); if( !p ) { hal_mutex_unlock(&proc_lock); return ESRCH; } int done = 0; int i; for( i = 0; i < MAX_UU_TID; i++ ) { if( p->tids[i] >= 0 ) continue; p->tids[i] = tid; p->ntids++; done = 1; break; } //t->u = p; t_current_set_death_handler(uu_proc_thread_kill); if(!done) panic("out of thread slots for proc"); finish: hal_mutex_unlock(&proc_lock); return rc; }
// TODO no interlock - process can be klled when we use it - use pool for processes! void syscall_sw(struct trap_state *st) { //phantom_thread_t *t = GET_CURRENT_THREAD(); //uuprocess_t *u = t->u; tid_t tid = get_current_tid(); pid_t pid; assert( !t_get_pid( tid, &pid )); uuprocess_t *u = proc_by_pid(pid); /* int ret; if( (ret = setjmp(u->signal_jmpbuf)) ) { execute_signals(u, st); return; } */ do_syscall_sw( u, st ); execute_signals(u, st); }
errno_t uu_proc_setargs( int pid, const char **av, const char **env ) { errno_t r = 0; hal_mutex_lock(&proc_lock); uuprocess_t * u = proc_by_pid(pid); if( u ) { if(u->argv) free_argv(u->argv); if(u->envp) free_argv(u->envp); u->argv = dup_argv( &u->argc, av, 0 ); u->envp = dup_argv( 0, env, 0 ); flatten_argv( u->cmd, MAX_UU_CMD, u->argv ); } else r = ESRCH; hal_mutex_unlock(&proc_lock); return r; }
// remove (dead) thread from process. errno_t uu_proc_rm_thread( int pid, int tid ) { assert( tid >= 0 ); hal_mutex_lock(&proc_lock); uuprocess_t * p = proc_by_pid(pid); if( !p ) { hal_mutex_unlock(&proc_lock); return ESRCH; } assert(p->ntids > 0); int done = 0; int i; for( i = 0; i < MAX_UU_TID; i++ ) { if( p->tids[i] != tid ) continue; p->tids[i] = -1; p->ntids--; done = 1; break; } if(!done) panic("not proc's thread"); if( p->ntids <= 0 ) uu_proc_death(p); hal_mutex_unlock(&proc_lock); return 0; }
errno_t uu_proc_set_exec( int pid, struct exe_module *em) { assert(em); // Caller must increment assert( em->refcount > 0 ); errno_t r = 0; hal_mutex_lock(&proc_lock); uuprocess_t * p = proc_by_pid(pid); if( p ) { if( p->em ) { // todo unlink em SHOW_ERROR( 0, "Process %d already has em", pid ); } p->em = em; p->mem_start = em->mem_start; p->mem_end = em->mem_end; const char *name = "?"; if( p->argv[0] ) name = p->argv[0]; strlcpy( em->name, name, MAX_UU_CMD ); } else r = ESRCH; hal_mutex_unlock(&proc_lock); return r; }
static int nl_handle_msg(struct cn_msg *cn_hdr) { /* The event to consider */ struct proc_event *ev; /* Return codes */ int ret = 0; /* Get the event data. We only care about two event types. */ ev = (struct proc_event*)cn_hdr->data; switch (ev->what) { case PROC_EVENT_NONE: g_debug("netlink: successfully subscribed for listening to proc events"); netlink_proc_listening = TRUE; break; // quite seldom events on old processes changing important parameters case PROC_EVENT_UID: // skip threads if(ev->event_data.id.process_tgid != ev->event_data.id.process_pid) break; u_trace("UID Event: PID = %d, tGID = %d, rUID = %d," " eUID = %d", ev->event_data.id.process_pid, ev->event_data.id.process_tgid, ev->event_data.id.r.ruid, ev->event_data.id.e.euid); process_new(ev->event_data.id.process_pid, FALSE); break; case PROC_EVENT_GID: // skip threads if(ev->event_data.id.process_tgid != ev->event_data.id.process_pid) break; u_trace("GID Event: PID = %d, tGID = %d, rGID = %d," " eGID = %d", ev->event_data.id.process_pid, ev->event_data.id.process_tgid, ev->event_data.id.r.rgid, ev->event_data.id.e.egid); process_new(ev->event_data.id.process_pid, FALSE); break; case PROC_EVENT_EXIT: // skip threads if(ev->event_data.exit.process_tgid != ev->event_data.exit.process_pid) break; u_trace("EXIT Event: PID = %d", ev->event_data.exit.process_pid); //g_ptr_array_foreach(stack, remove_pid_from_stack, &pid); // if the pid was found in the new stack, pid is set to 0 to indicate // the removal process_remove_by_pid(ev->event_data.exit.process_pid); break; case PROC_EVENT_EXEC: // skip threads if(ev->event_data.exec.process_tgid != ev->event_data.exec.process_pid) break; u_trace("EXEC Event: PID = %d, tGID = %d", ev->event_data.exec.process_pid, ev->event_data.exec.process_tgid); process_new_delay(ev->event_data.exec.process_tgid, 0); break; case PROC_EVENT_FORK: // we skip new threads for now // FIXME need filter block to get those events if(ev->event_data.fork.parent_tgid != ev->event_data.fork.child_pid) break; u_trace("FORK Event: PARENT = %d PID = %d tGID = %d", ev->event_data.fork.parent_tgid, ev->event_data.fork.child_pid, ev->event_data.fork.child_tgid); // parent does not mean the parent of the new proc, but the parent of // the forking process. so we lookup the parent of the forking process // first u_proc *rparent = proc_by_pid(ev->event_data.fork.parent_tgid); if(rparent) { u_proc_ensure(rparent, BASIC, NOUPDATE); process_new_delay(ev->event_data.fork.child_tgid, rparent->proc->ppid); //ev->event_data.fork.parent_pid); } else process_new_delay(ev->event_data.fork.child_tgid, 0); break; default: return 0; } return ret; }