|
|
1.1 root 1: /* 1.1.1.2 ! root 2: * linux/kernel/fork.c ! 3: * ! 4: * (C) 1991 Linus Torvalds ! 5: */ ! 6: ! 7: /* 1.1 root 8: * 'fork.c' contains the help-routines for the 'fork' system call 9: * (see also system_call.s), and some misc functions ('verify_area'). 10: * Fork is rather simple, once you get the hang of it, but the memory 11: * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()' 12: */ 13: #include <errno.h> 14: 15: #include <linux/sched.h> 16: #include <linux/kernel.h> 17: #include <asm/segment.h> 18: #include <asm/system.h> 19: 20: extern void write_verify(unsigned long address); 21: 22: long last_pid=0; 23: 24: void verify_area(void * addr,int size) 25: { 26: unsigned long start; 27: 28: start = (unsigned long) addr; 29: size += start & 0xfff; 30: start &= 0xfffff000; 31: start += get_base(current->ldt[2]); 32: while (size>0) { 33: size -= 4096; 34: write_verify(start); 35: start += 4096; 36: } 37: } 38: 39: int copy_mem(int nr,struct task_struct * p) 40: { 41: unsigned long old_data_base,new_data_base,data_limit; 42: unsigned long old_code_base,new_code_base,code_limit; 43: 44: code_limit=get_limit(0x0f); 45: data_limit=get_limit(0x17); 46: old_code_base = get_base(current->ldt[1]); 47: old_data_base = get_base(current->ldt[2]); 48: if (old_data_base != old_code_base) 49: panic("We don't support separate I&D"); 50: if (data_limit < code_limit) 51: panic("Bad data_limit"); 52: new_data_base = new_code_base = nr * 0x4000000; 53: set_base(p->ldt[1],new_code_base); 54: set_base(p->ldt[2],new_data_base); 55: if (copy_page_tables(old_data_base,new_data_base,data_limit)) { 56: free_page_tables(new_data_base,data_limit); 57: return -ENOMEM; 58: } 59: return 0; 60: } 61: 62: /* 63: * Ok, this is the main fork-routine. It copies the system process 64: * information (task[nr]) and sets up the necessary registers. It 65: * also copies the data segment in it's entirety. 66: */ 67: int copy_process(int nr,long ebp,long edi,long esi,long gs,long none, 68: long ebx,long ecx,long edx, 69: long fs,long es,long ds, 70: long eip,long cs,long eflags,long esp,long ss) 71: { 72: struct task_struct *p; 73: int i; 74: struct file *f; 75: 76: p = (struct task_struct *) get_free_page(); 77: if (!p) 78: return -EAGAIN; 79: *p = *current; /* NOTE! this doesn't copy the supervisor stack */ 80: p->state = TASK_RUNNING; 81: p->pid = last_pid; 82: p->father = current->pid; 83: p->counter = p->priority; 84: p->signal = 0; 85: p->alarm = 0; 86: p->leader = 0; /* process leadership doesn't inherit */ 87: p->utime = p->stime = 0; 88: p->cutime = p->cstime = 0; 89: p->start_time = jiffies; 90: p->tss.back_link = 0; 91: p->tss.esp0 = PAGE_SIZE + (long) p; 92: p->tss.ss0 = 0x10; 93: p->tss.eip = eip; 94: p->tss.eflags = eflags; 95: p->tss.eax = 0; 96: p->tss.ecx = ecx; 97: p->tss.edx = edx; 98: p->tss.ebx = ebx; 99: p->tss.esp = esp; 100: p->tss.ebp = ebp; 101: p->tss.esi = esi; 102: p->tss.edi = edi; 103: p->tss.es = es & 0xffff; 104: p->tss.cs = cs & 0xffff; 105: p->tss.ss = ss & 0xffff; 106: p->tss.ds = ds & 0xffff; 107: p->tss.fs = fs & 0xffff; 108: p->tss.gs = gs & 0xffff; 109: p->tss.ldt = _LDT(nr); 110: p->tss.trace_bitmap = 0x80000000; 111: if (last_task_used_math == current) 112: __asm__("fnsave %0"::"m" (p->tss.i387)); 113: if (copy_mem(nr,p)) { 114: free_page((long) p); 115: return -EAGAIN; 116: } 117: for (i=0; i<NR_OPEN;i++) 118: if (f=p->filp[i]) 119: f->f_count++; 120: if (current->pwd) 121: current->pwd->i_count++; 122: if (current->root) 123: current->root->i_count++; 124: set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss)); 125: set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt)); 126: task[nr] = p; /* do this last, just in case */ 127: return last_pid; 128: } 129: 130: int find_empty_process(void) 131: { 132: int i; 133: 134: repeat: 135: if ((++last_pid)<0) last_pid=1; 136: for(i=0 ; i<NR_TASKS ; i++) 137: if (task[i] && task[i]->pid == last_pid) goto repeat; 138: for(i=1 ; i<NR_TASKS ; i++) 139: if (!task[i]) 140: return i; 141: return -EAGAIN; 142: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.