PUBLIC void kill_thread(thread_no_t th) /* stop this thread running */ { struct thread *t; kernel_mode = YES; if (!legal_tid(th)) { kernel_mode--; return; } t = thread_table + th; if (t->status == THREAD_READY || t->status == THREAD_WAITS) alive--; if (t->status == THREAD_WAITS) sleeping--; t->status = THREAD_DEAD; t->waiting = 0; if (DEBUG_LEVEL > 0) printf("Thread %d died\n", th); copy_context(t->original_context, t->context); if (th == current_thread) schedule(); kernel_mode = NO; }
PUBLIC void initialize_threads(void) /* build the thread stacks and their context structures */ { struct thread* t; if (!setjmp(home)) allocate_stack(0, MAX_THREADS); /* save the context in order to restore it at the top of the stack if the thread dies -- to recover stack space */ for_all_threads(t) { copy_context(t->context, t->original_context); } alive = 0; sleeping = 0; to_alarm = 0; }
/* ======================================================================================= ======================================================================================= */ bool run(HWND hDlg) { char src[MAX_PATH], dst[MAX_PATH], dst_name[MAX_PATH], error[2 * MAX_PATH]; char *p; FILE *fin, *fout; int max_particles, line_count; bool result; max_particles = GetDlgItemInt(hDlg, IDC_MAX_PARTICLES, NULL, FALSE); if (max_particles == 0) { MessageBox(hDlg, "Zero max particles is not acceptable.", "Error", MB_OK); return false; } memset(src, 0, sizeof(src)); GetDlgItemText(hDlg, IDC_ORIGINAL_LIST, src, MAX_PATH - 1); if (!file_exists(src)) { return false; } memset(dst_name, 0, sizeof(dst_name)); GetDlgItemText(hDlg, IDC_OUTPUT_LIST, dst_name, sizeof(dst_name)); if (strlen(dst_name) == 0) { MessageBox(hDlg, "Need an output file name.", "Error", MB_OK); return false; } strncpy_s(dst, sizeof(dst), src, _TRUNCATE); p = strrchr(dst, '\\'); if (!p) { MessageBox(hDlg, "Can't find a path delimiter in the source file!", "Error", MB_OK); return false; } p++; *p = 0; strncat_s(dst, sizeof(dst), dst_name, _TRUNCATE); if (!strcmp(src, dst)) { MessageBox(hDlg, "Sorry, not going to overwrite the original list file.", "No Clobbering Originals", MB_OK); return false; } if (file_exists(dst)) { sprintf_s(error, sizeof(error), "The output file\n%s\nalready exists.\n\nOverwrite?", dst); if (IDNO == MessageBox(hDlg, error, "Overwrite Existing File", MB_YESNO)) { return false; } } line_count = count_lines_in_file(hDlg, src); if (line_count < 0) { // error already shown return false; } else if (line_count < 2) { MessageBox(hDlg, "Source file line count is too small to believe", "Error", MB_OK); return false; } if (fopen_s(&fin, src, "rb")) { MessageBox(hDlg, "Error opening original file.", "Error", MB_OK); return false; } if (fopen_s(&fout, dst, "wb")) { fclose(fin); MessageBox(hDlg, "Error opening output file.", "Error", MB_OK); return false; } SetCursor(LoadCursor(NULL, IDC_WAIT)); result = shave(hDlg, line_count, max_particles, fin, fout); fclose(fin); fclose(fout); SetCursor(LoadCursor(NULL, IDC_ARROW)); if (result) { p = strrchr(src, '.'); if (!p) { MessageBox(hDlg, "Internal error, source context", "Error Copying Context", MB_OK); return false; } *p = 0; strncat_s(src, MAX_PATH, ".ctx", _TRUNCATE); if (!file_exists(src)) { MessageBox(hDlg, "Failed to find context file for original.", "Error Copying Context", MB_OK); return false; } p = strrchr(dst, '.'); if (!p) { MessageBox(hDlg, "Internal error, dest context", "Error Copying Context", MB_OK); return false; } *p = 0; strncat_s(dst, MAX_PATH, ".ctx", _TRUNCATE); if (fopen_s(&fin, src, "rb")) { MessageBox(hDlg, "Error opening original context file.", "Error", MB_OK); return false; } if (fopen_s(&fout, dst, "wb")) { fclose(fin); MessageBox(hDlg, "Error opening output context file.", "Error", MB_OK); return false; } result = copy_context(fin, fout); fclose(fin); fclose(fout); if (!result) { MessageBox(hDlg, "Error copying context file.", "Error", MB_OK); } } return result; }
int32_t fork() { /* Time to... fork! * I had spent a long time preparing for this! * now I am done, it's time to start working on fork(). */ int32_t i; proc_t *newproc; /* create a new process structure: */ newproc = kmalloc(sizeof(proc_t)); if (newproc == NULL) return -1; /* set parent */ newproc->parent = curproc; /* initialize descriptors: */ newproc->plist.proc = newproc; newproc->sched.proc = newproc; newproc->irqd.proc = newproc; newproc->semad.proc = newproc; /* create memory: */ if (umem_init(&(newproc->umem))) { kfree(newproc); return -1; /* error. */ } /* inherit parent's memory: */ if (umem_copy(&(curproc->umem), &(newproc->umem))) { umem_free(&(newproc->umem)); kfree(newproc); return -1; /* error. */ } /* create a new kernel stack. */ newproc->kstack = (unsigned char *) kmalloc(KERNEL_STACK_SIZE); if (newproc->kstack == NULL) { umem_free(&(newproc->umem)); kfree(newproc); return -1; /* error. */ } initproc->phy_stack_bot = arch_vmpage_getAddr(NULL, newproc->kstack); /* initialize kernel stack... * this invokes page faults to allocate memory for * the stack early. */ for (i = 0; i < KERNEL_STACK_SIZE; i++) newproc->kstack[i] = 0; /* copy context from parent's stack to child's stack: */ copy_context(newproc); /* copy the set of file descriptors: */ for (i = 0; i < FD_MAX; i++) { if (curproc->file[i] == NULL) { newproc->file[i] = NULL; } else { curproc->file[i]->fcount++; newproc->file[i] = curproc->file[i]; } } /* inherit the current working directory: */ curproc->cwd->fcount++; newproc->cwd = curproc->cwd; /* set pid: */ newproc->pid = ++last_pid; /* inform the scheduler that this is a just-forked process: */ newproc->after_fork = 1; /* initialize inbox */ newproc->inbox_lock = 0; newproc->blocked_for_msg = 0; linkedlist_init(&(newproc->inbox)); /* children */ newproc->blocked_for_child = 0; /* not blocked */ newproc->blocked = 0; newproc->lock_to_unlock = NULL; /* exit status: */ newproc->terminated = 0; newproc->status = 0; /* add the new process to the list of processes: */ linkedlist_addlast((linkedlist*)&proclist, (linknode*)&(newproc->plist)); /* add to scheduler's queue: */ linkedlist_addlast((linkedlist*)&q_ready, (linknode*)&(newproc->sched)); /* call the scheduler */ scheduler(); /* return */ if (curproc == newproc) { return 0; } else { return newproc->pid; } }
int msdos_fault(struct sigcontext *scp) { struct sigcontext new_sct; int reg; unsigned int segment; unsigned short desc; D_printf("MSDOS: msdos_fault, err=%#lx\n", _err); if ((_err & 0xffff) == 0) /* not a selector error */ return msdos_ldt_fault(scp); /* now it is a invalid selector error, try to fix it if it is */ /* caused by an instruction such as mov Sreg,r/m16 */ #define ALL_GDTS 0 #if !ALL_GDTS segment = (_err & 0xfff8); /* only allow using some special GTDs */ switch (segment) { case 0x0040: case 0xa000: case 0xb000: case 0xb800: case 0xc000: case 0xe000: case 0xf000: case 0xbf8: case 0xf800: case 0xff00: case 0x38: // ShellShock installer break; default: return 0; } copy_context(&new_sct, scp, 0); reg = decode_segreg(&new_sct); if (reg == -1) return 0; #else copy_context(&new_sct, scp, 0); reg = decode_modify_segreg_insn(&new_sct, 1, &segment); if (reg == -1) return 0; if (ValidAndUsedSelector(segment)) { /* * The selector itself is OK, but the descriptor (type) is not. * We cannot fix this! So just give up immediately and dont * screw up the context. */ D_printf("MSDOS: msdos_fault: Illegal use of selector %#x\n", segment); return 0; } #endif D_printf("MSDOS: try mov to a invalid selector 0x%04x\n", segment); switch (segment) { case 0x38: /* dos4gw sets VCPI descriptors 0x28, 0x30, 0x38 */ /* The 0x38 is the "flat data" segment (0,4G) */ desc = ConvertSegmentToDescriptor_lim(0, 0xffffffff); break; default: /* any other special cases? */ desc = ConvertSegmentToDescriptor(segment); } if (!desc) return 0; /* OKay, all the sanity checks passed. Now we go and fix the selector */ copy_context(scp, &new_sct, 0); switch (reg) { case es_INDEX: _es = desc; break; case cs_INDEX: _cs = desc; break; case ss_INDEX: _ss = desc; break; case ds_INDEX: _ds = desc; break; case fs_INDEX: _fs = desc; break; case gs_INDEX: _gs = desc; break; } /* let's hope we fixed the thing, and return */ return 1; }