📄 linux_0
字号:
578 * sys_waitpid() remains for compatibility. waitpid() should be
579 * implemented by calling sys_wait4() from libc.a.
580 */
581 asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
582 {
583 return sys_wait4(pid, stat_addr, options, NULL);
584 }
585
------------------------------
1 /*
2 * linux/kernel/fork.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7 /*
8 * 'fork.c' contains the help-routines for the 'fork' system call
9 * (see also system_call.s).
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
14 #include <linux/errno.h>
15 #include <linux/sched.h>
16 #include <linux/kernel.h>
17 #include <linux/mm.h>
18 #include <linux/stddef.h>
19 #include <linux/unistd.h>
20 #include <linux/segment.h>
21 #include <linux/ptrace.h>
22 #include <linux/malloc.h>
23 #include <linux/ldt.h>
24
25 #include <asm/segment.h>
26 #include <asm/system.h>
27
28 asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
29
30 /* These should maybe be in <linux/tasks.h> */
31
32 #define MAX_TASKS_PER_USER (NR_TASKS/2)
33 #define MIN_TASKS_LEFT_FOR_ROOT 4
34
35 extern int shm_fork(struct task_struct *, struct task_struct *);
36 long last_pid=0;
37
38 static int find_empty_process(void)
39 {
40 int free_task;
41 int i, tasks_free;
42 int this_user_tasks;
43
44 repeat:
45 if ((++last_pid) & 0xffff8000)
46 last_pid=1;
47 this_user_tasks = 0;
48 tasks_free = 0;
49 free_task = -EAGAIN;
50 i = NR_TASKS;
51 while (--i > 0) {
52 if (!task[i]) {
53 free_task = i;
54 tasks_free++;
55 continue;
56 }
57 if (task[i]->uid == current->uid)
58 this_user_tasks++;
59 if (task[i]->pid == last_pid || task[i]->pgrp == last_pid ||
60 task[i]->session == last_pid)
61 goto repeat;
62 }
63 if (tasks_free <= MIN_TASKS_LEFT_FOR_ROOT ||
64 this_user_tasks > MAX_TASKS_PER_USER)
65 if (current->uid)
66 return -EAGAIN;
67 return free_task;
68 }
69
70 static struct file * copy_fd(struct file * old_file)
71 {
72 struct file * new_file = get_empty_filp();
73 int error;
74
75 if (new_file) {
76 memcpy(new_file,old_file,sizeof(struct file));
77 new_file->f_count = 1;
78 if (new_file->f_inode)
79 new_file->f_inode->i_count++;
80 if (new_file->f_op && new_file->f_op->open) {
81 error = new_file->f_op->open(new_file->f_inode,new_file);
82 if (error) {
83 iput(new_file->f_inode);
84 new_file->f_count = 0;
85 new_file = NULL;
86 }
87 }
88 }
89 return new_file;
90 }
91
92 int dup_mmap(struct task_struct * tsk)
93 {
94 struct vm_area_struct * mpnt, **p, *tmp;
95
96 tsk->mmap = NULL;
97 tsk->stk_vma = NULL;
98 p = &tsk->mmap;
99 for (mpnt = current->mmap ; mpnt ; mpnt = mpnt->vm_next) {
100 tmp = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
101 if (!tmp)
102 return -ENOMEM;
103 *tmp = *mpnt;
104 tmp->vm_task = tsk;
105 tmp->vm_next = NULL;
106 if (tmp->vm_inode)
107 tmp->vm_inode->i_count++;
108 *p = tmp;
109 p = &tmp->vm_next;
110 if (current->stk_vma == mpnt)
111 tsk->stk_vma = tmp;
112 }
113 return 0;
114 }
115
116 #define IS_CLONE (regs.orig_eax == __NR_clone)
117 #define copy_vm(p) ((clone_flags & COPYVM)?copy_page_tables(p):clone_page_tables(p))
118
119 /*
120 * Ok, this is the main fork-routine. It copies the system process
121 * information (task[nr]) and sets up the necessary registers. It
122 * also copies the data segment in its entirety.
123 */
124 asmlinkage int sys_fork(struct pt_regs regs)
125 {
126 struct pt_regs * childregs;
127 struct task_struct *p;
128 int i,nr;
129 struct file *f;
130 unsigned long clone_flags = COPYVM | SIGCHLD;
131
132 if(!(p = (struct task_struct*)__get_free_page(GFP_KERNEL)))
133 goto bad_fork;
134 nr = find_empty_process();
135 if (nr < 0)
136 goto bad_fork_free;
137 task[nr] = p;
138 *p = *current;
139 p->did_exec = 0;
140 p->kernel_stack_page = 0;
141 p->state = TASK_UNINTERRUPTIBLE;
142 p->flags &= ~(PF_PTRACED|PF_TRACESYS);
143 p->pid = last_pid;
144 p->swappable = 1;
145 p->p_pptr = p->p_opptr = current;
146 p->p_cptr = NULL;
147 SET_LINKS(p);
148 p->signal = 0;
149 p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
150 p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
151 p->leader = 0; /* process leadership doesn't inherit */
152 p->utime = p->stime = 0;
153 p->cutime = p->cstime = 0;
154 p->min_flt = p->maj_flt = 0;
155 p->cmin_flt = p->cmaj_flt = 0;
156 p->start_time = jiffies;
157 /*
158 * set up new TSS and kernel stack
159 */
160 if (!(p->kernel_stack_page = get_free_page(GFP_KERNEL)))
161 goto bad_fork_cleanup;
162 *(unsigned long *)p->kernel_stack_page = STACK_MAGIC;
163 p->tss.es = KERNEL_DS;
164 p->tss.cs = KERNEL_CS;
165 p->tss.ss = KERNEL_DS;
166 p->tss.ds = KERNEL_DS;
167 p->tss.fs = USER_DS;
168 p->tss.gs = KERNEL_DS;
169 p->tss.ss0 = KERNEL_DS;
170 p->tss.esp0 = p->kernel_stack_page + PAGE_SIZE;
171 p->tss.tr = _TSS(nr);
172 childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1;
173 p->tss.esp = (unsigned long) childregs;
174 p->tss.eip = (unsigned long) ret_from_sys_call;
175 *childregs = regs;
176 childregs->eax = 0;
177 p->tss.back_link = 0;
178 p->tss.eflags = regs.eflags & 0xffffcfff; /* iopl is always 0 for a new process */
179 if (IS_CLONE) {
180 if (regs.ebx)
181 childregs->esp = regs.ebx;
182 clone_flags = regs.ecx;
183 if (childregs->esp == regs.esp)
184 clone_flags |= COPYVM;
185 }
186 p->exit_signal = clone_flags & CSIGNAL;
187 p->tss.ldt = _LDT(nr);
188 if (p->ldt) {
189 p->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
190 if (p->ldt != NULL)
191 memcpy(p->ldt, current->ldt, LDT_ENTRIES*LDT_ENTRY_SIZE);
192 }
193 p->tss.bitmap = offsetof(struct tss_struct,io_bitmap);
194 for (i = 0; i < IO_BITMAP_SIZE+1 ; i++) /* IO bitmap is actually SIZE+1 */
195 p->tss.io_bitmap[i] = ~0;
196 if (last_task_used_math == current)
197 __asm__("clts ; fnsave %0 ; frstor %0":"=m" (p->tss.i387));
198 p->semun = NULL; p->shm = NULL;
199 if (copy_vm(p) || shm_fork(current, p))
200 goto bad_fork_cleanup;
201 if (clone_flags & COPYFD) {
202 for (i=0; i<NR_OPEN;i++)
203 if ((f = p->filp[i]) != NULL)
204 p->filp[i] = copy_fd(f);
205 } else {
206 for (i=0; i<NR_OPEN;i++)
207 if ((f = p->filp[i]) != NULL)
208 f->f_count++;
209 }
210 if (current->pwd)
211 current->pwd->i_count++;
212 if (current->root)
213 current->root->i_count++;
214 if (current->executable)
215 current->executable->i_count++;
216 dup_mmap(p);
217 set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
218 if (p->ldt)
219 set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,p->ldt, 512);
220 else
221 set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&default_ldt, 1);
222
223 p->counter = current->counter >> 1;
224 p->state = TASK_RUNNING; /* do this last, just in case */
225 return p->pid;
226 bad_fork_cleanup:
227 task[nr] = NULL;
228 REMOVE_LINKS(p);
229 free_page(p->kernel_stack_page);
230 bad_fork_free:
231 free_page((long) p);
232 bad_fork:
233 return -EAGAIN;
234 }
235
---------------------------------
1 /*
2 * linux/kernel/info.c
3 *
4 * Copyright (C) 1992 Darren Senn
5 */
6
7 /* This implements the sysinfo() system call */
8
9 #include <asm/segment.h>
10
11 #include <linux/sched.h>
12 #include <linux/string.h>
13 #include <linux/unistd.h>
14 #include <linux/types.h>
15 #include <linux/mm.h>
16
17 asmlinkage int sys_sysinfo(struct sysinfo *info)
18 {
19 int error;
20 struct sysinfo val;
21 struct task_struct **p;
22
23 error = verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo));
24 if (error)
25 return error;
26 memset((char *)&val, 0, sizeof(struct sysinfo));
27
28 val.uptime = jiffies / HZ;
29
30 val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
31 val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
32 val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
33
34 for (p = &LAST_TASK; p > &FIRST_TASK; p--)
35 if (*p) val.procs++;
36
37 si_meminfo(&val);
38 si_swapinfo(&val);
39
40 memcpy_tofs(info, &val, sizeof(struct sysinfo));
41 return 0;
42 }
43
-------------------------
1 /*
2 * linux/kernel/ioport.c
3 *
4 * This contains the io-permission bitmap code - written by obz, with changes
5 * by Linus.
6 */
7
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/types.h>
12 #include <linux/ioport.h>
13
14 static unsigned long ioport_registrar[IO_BITMAP_SIZE] = {0, /* ... */};
15
16 #define _IODEBUG
17
18 #ifdef IODEBUG
19 static char * ios(unsigned long l)
20 {
21 static char str[33] = { '\0' };
22 int i;
23 unsigned long mask;
24
25 for (i = 0, mask = 0x80000000; i < 32; ++i, mask >>= 1)
26 str[i] = (l & mask) ? '1' : '';
27 return str;
28 }
29
30 static void dump_io_bitmap(void)
31 {
32 int i, j;
33 int numl = sizeof(current->tss.io_bitmap) >> 2;
34
35 for (i = j = 0; j < numl; ++i)
36 {
37 printk("%4d [%3x]: ", 64*i, 64*i);
38 printk("%s ", ios(current->tss.io_bitmap[j++]));
39 if (j < numl)
40 printk("%s", ios(current->tss.io_bitmap[j++]));
41 printk("\n");
42 }
43 }
44 #endif
45
46 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
47 asmlinkage void set_bitmap(unsigned long *bitmap,
48 short base, short extent, int new_value)
49 {
50 int mask;
51 unsigned long *bitmap_base = bitmap + (base >> 5);
52 unsigned short low_index = base & 0x1f;
53 int length = low_index + extent;
54
55 if (low_index != 0) {
56 mask = (~0 << low_index);
57 if (length < 32)
58 mask &= ~(~0 << length);
59 if (new_value)
60 *bitmap_base++ |= mask;
61 else
62 *bitmap_base++ &= ~mask;
63 length -= 32;
64 }
65
66 mask = (new_value ? ~0 : 0);
67 while (length >= 32) {
68 *bitmap_base++ = mask;
69 length -= 32;
70 }
71
72 if (length > 0) {
73 mask = ~(~0 << length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -