exit.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:14k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/kernel/exit.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6. #include <linux/config.h>
  7. #include <linux/slab.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/smp_lock.h>
  10. #include <linux/module.h>
  11. #include <linux/completion.h>
  12. #include <linux/personality.h>
  13. #include <linux/tty.h>
  14. #include <linux/namespace.h>
  15. #ifdef CONFIG_BSD_PROCESS_ACCT
  16. #include <linux/acct.h>
  17. #endif
  18. #include <asm/uaccess.h>
  19. #include <asm/pgtable.h>
  20. #include <asm/mmu_context.h>
  21. extern void sem_exit (void);
  22. extern struct task_struct *child_reaper;
  23. int getrusage(struct task_struct *, int, struct rusage *);
  24. static void release_task(struct task_struct * p)
  25. {
  26. if (p != current) {
  27. #ifdef CONFIG_SMP
  28. /*
  29.  * Wait to make sure the process isn't on the
  30.  * runqueue (active on some other CPU still)
  31.  */
  32. for (;;) {
  33. task_lock(p);
  34. if (!task_has_cpu(p))
  35. break;
  36. task_unlock(p);
  37. do {
  38. cpu_relax();
  39. barrier();
  40. } while (task_has_cpu(p));
  41. }
  42. task_unlock(p);
  43. #endif
  44. atomic_dec(&p->user->processes);
  45. free_uid(p->user);
  46. unhash_process(p);
  47. release_thread(p);
  48. current->cmin_flt += p->min_flt + p->cmin_flt;
  49. current->cmaj_flt += p->maj_flt + p->cmaj_flt;
  50. current->cnswap += p->nswap + p->cnswap;
  51. /*
  52.  * Potentially available timeslices are retrieved
  53.  * here - this way the parent does not get penalized
  54.  * for creating too many processes.
  55.  *
  56.  * (this cannot be used to artificially 'generate'
  57.  * timeslices, because any timeslice recovered here
  58.  * was given away by the parent in the first place.)
  59.  */
  60. current->counter += p->counter;
  61. if (current->counter >= MAX_COUNTER)
  62. current->counter = MAX_COUNTER;
  63. p->pid = 0;
  64. free_task_struct(p);
  65. } else {
  66. printk("task releasing itselfn");
  67. }
  68. }
  69. /*
  70.  * This checks not only the pgrp, but falls back on the pid if no
  71.  * satisfactory pgrp is found. I dunno - gdb doesn't work correctly
  72.  * without this...
  73.  */
  74. int session_of_pgrp(int pgrp)
  75. {
  76. struct task_struct *p;
  77. int fallback;
  78. fallback = -1;
  79. read_lock(&tasklist_lock);
  80. for_each_task(p) {
  81.   if (p->session <= 0)
  82.   continue;
  83. if (p->pgrp == pgrp) {
  84. fallback = p->session;
  85. break;
  86. }
  87. if (p->pid == pgrp)
  88. fallback = p->session;
  89. }
  90. read_unlock(&tasklist_lock);
  91. return fallback;
  92. }
  93. /*
  94.  * Determine if a process group is "orphaned", according to the POSIX
  95.  * definition in 2.2.2.52.  Orphaned process groups are not to be affected
  96.  * by terminal-generated stop signals.  Newly orphaned process groups are
  97.  * to receive a SIGHUP and a SIGCONT.
  98.  *
  99.  * "I ask you, have you ever known what it is to be an orphan?"
  100.  */
  101. static int will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_task)
  102. {
  103. struct task_struct *p;
  104. read_lock(&tasklist_lock);
  105. for_each_task(p) {
  106. if ((p == ignored_task) || (p->pgrp != pgrp) ||
  107.     (p->state == TASK_ZOMBIE) ||
  108.     (p->p_pptr->pid == 1))
  109. continue;
  110. if ((p->p_pptr->pgrp != pgrp) &&
  111.     (p->p_pptr->session == p->session)) {
  112. read_unlock(&tasklist_lock);
  113.   return 0;
  114. }
  115. }
  116. read_unlock(&tasklist_lock);
  117. return 1; /* (sighing) "Often!" */
  118. }
  119. int is_orphaned_pgrp(int pgrp)
  120. {
  121. return will_become_orphaned_pgrp(pgrp, 0);
  122. }
  123. static inline int has_stopped_jobs(int pgrp)
  124. {
  125. int retval = 0;
  126. struct task_struct * p;
  127. read_lock(&tasklist_lock);
  128. for_each_task(p) {
  129. if (p->pgrp != pgrp)
  130. continue;
  131. if (p->state != TASK_STOPPED)
  132. continue;
  133. retval = 1;
  134. break;
  135. }
  136. read_unlock(&tasklist_lock);
  137. return retval;
  138. }
  139. /*
  140.  * When we die, we re-parent all our children.
  141.  * Try to give them to another thread in our thread
  142.  * group, and if no such member exists, give it to
  143.  * the global child reaper process (ie "init")
  144.  */
  145. static inline void forget_original_parent(struct task_struct * father)
  146. {
  147. struct task_struct * p;
  148. read_lock(&tasklist_lock);
  149. for_each_task(p) {
  150. if (p->p_opptr == father) {
  151. /* We dont want people slaying init */
  152. p->exit_signal = SIGCHLD;
  153. p->self_exec_id++;
  154. /* Make sure we're not reparenting to ourselves */
  155. p->p_opptr = child_reaper;
  156. if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
  157. }
  158. }
  159. read_unlock(&tasklist_lock);
  160. }
  161. static inline void close_files(struct files_struct * files)
  162. {
  163. int i, j;
  164. j = 0;
  165. for (;;) {
  166. unsigned long set;
  167. i = j * __NFDBITS;
  168. if (i >= files->max_fdset || i >= files->max_fds)
  169. break;
  170. set = files->open_fds->fds_bits[j++];
  171. while (set) {
  172. if (set & 1) {
  173. struct file * file = xchg(&files->fd[i], NULL);
  174. if (file)
  175. filp_close(file, files);
  176. }
  177. i++;
  178. set >>= 1;
  179. }
  180. }
  181. }
  182. void put_files_struct(struct files_struct *files)
  183. {
  184. if (atomic_dec_and_test(&files->count)) {
  185. close_files(files);
  186. /*
  187.  * Free the fd and fdset arrays if we expanded them.
  188.  */
  189. if (files->fd != &files->fd_array[0])
  190. free_fd_array(files->fd, files->max_fds);
  191. if (files->max_fdset > __FD_SETSIZE) {
  192. free_fdset(files->open_fds, files->max_fdset);
  193. free_fdset(files->close_on_exec, files->max_fdset);
  194. }
  195. kmem_cache_free(files_cachep, files);
  196. }
  197. }
  198. static inline void __exit_files(struct task_struct *tsk)
  199. {
  200. struct files_struct * files = tsk->files;
  201. if (files) {
  202. task_lock(tsk);
  203. tsk->files = NULL;
  204. task_unlock(tsk);
  205. put_files_struct(files);
  206. }
  207. }
  208. void exit_files(struct task_struct *tsk)
  209. {
  210. __exit_files(tsk);
  211. }
  212. static inline void __put_fs_struct(struct fs_struct *fs)
  213. {
  214. /* No need to hold fs->lock if we are killing it */
  215. if (atomic_dec_and_test(&fs->count)) {
  216. dput(fs->root);
  217. mntput(fs->rootmnt);
  218. dput(fs->pwd);
  219. mntput(fs->pwdmnt);
  220. if (fs->altroot) {
  221. dput(fs->altroot);
  222. mntput(fs->altrootmnt);
  223. }
  224. kmem_cache_free(fs_cachep, fs);
  225. }
  226. }
  227. void put_fs_struct(struct fs_struct *fs)
  228. {
  229. __put_fs_struct(fs);
  230. }
  231. static inline void __exit_fs(struct task_struct *tsk)
  232. {
  233. struct fs_struct * fs = tsk->fs;
  234. if (fs) {
  235. task_lock(tsk);
  236. tsk->fs = NULL;
  237. task_unlock(tsk);
  238. __put_fs_struct(fs);
  239. }
  240. }
  241. void exit_fs(struct task_struct *tsk)
  242. {
  243. __exit_fs(tsk);
  244. }
  245. /*
  246.  * We can use these to temporarily drop into
  247.  * "lazy TLB" mode and back.
  248.  */
  249. struct mm_struct * start_lazy_tlb(void)
  250. {
  251. struct mm_struct *mm = current->mm;
  252. current->mm = NULL;
  253. /* active_mm is still 'mm' */
  254. atomic_inc(&mm->mm_count);
  255. enter_lazy_tlb(mm, current, smp_processor_id());
  256. return mm;
  257. }
  258. void end_lazy_tlb(struct mm_struct *mm)
  259. {
  260. struct mm_struct *active_mm = current->active_mm;
  261. current->mm = mm;
  262. if (mm != active_mm) {
  263. current->active_mm = mm;
  264. activate_mm(active_mm, mm);
  265. }
  266. mmdrop(active_mm);
  267. }
  268. /*
  269.  * Turn us into a lazy TLB process if we
  270.  * aren't already..
  271.  */
  272. static inline void __exit_mm(struct task_struct * tsk)
  273. {
  274. struct mm_struct * mm = tsk->mm;
  275. mm_release();
  276. if (mm) {
  277. atomic_inc(&mm->mm_count);
  278. BUG_ON(mm != tsk->active_mm);
  279. /* more a memory barrier than a real lock */
  280. task_lock(tsk);
  281. tsk->mm = NULL;
  282. task_unlock(tsk);
  283. enter_lazy_tlb(mm, current, smp_processor_id());
  284. mmput(mm);
  285. }
  286. }
  287. void exit_mm(struct task_struct *tsk)
  288. {
  289. __exit_mm(tsk);
  290. }
  291. /*
  292.  * Send signals to all our closest relatives so that they know
  293.  * to properly mourn us..
  294.  */
  295. static void exit_notify(void)
  296. {
  297. struct task_struct * p, *t;
  298. forget_original_parent(current);
  299. /*
  300.  * Check to see if any process groups have become orphaned
  301.  * as a result of our exiting, and if they have any stopped
  302.  * jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
  303.  *
  304.  * Case i: Our father is in a different pgrp than we are
  305.  * and we were the only connection outside, so our pgrp
  306.  * is about to become orphaned.
  307.  */
  308.  
  309. t = current->p_pptr;
  310. if ((t->pgrp != current->pgrp) &&
  311.     (t->session == current->session) &&
  312.     will_become_orphaned_pgrp(current->pgrp, current) &&
  313.     has_stopped_jobs(current->pgrp)) {
  314. kill_pg(current->pgrp,SIGHUP,1);
  315. kill_pg(current->pgrp,SIGCONT,1);
  316. }
  317. /* Let father know we died 
  318.  *
  319.  * Thread signals are configurable, but you aren't going to use
  320.  * that to send signals to arbitary processes. 
  321.  * That stops right now.
  322.  *
  323.  * If the parent exec id doesn't match the exec id we saved
  324.  * when we started then we know the parent has changed security
  325.  * domain.
  326.  *
  327.  * If our self_exec id doesn't match our parent_exec_id then
  328.  * we have changed execution domain as these two values started
  329.  * the same after a fork.
  330.  *
  331.  */
  332. if(current->exit_signal != SIGCHLD &&
  333.     ( current->parent_exec_id != t->self_exec_id  ||
  334.       current->self_exec_id != current->parent_exec_id) 
  335.     && !capable(CAP_KILL))
  336. current->exit_signal = SIGCHLD;
  337. /*
  338.  * This loop does two things:
  339.  *
  340.     * A.  Make init inherit all the child processes
  341.  * B.  Check to see if any process groups have become orphaned
  342.  * as a result of our exiting, and if they have any stopped
  343.  * jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
  344.  */
  345. write_lock_irq(&tasklist_lock);
  346. current->state = TASK_ZOMBIE;
  347. do_notify_parent(current, current->exit_signal);
  348. while (current->p_cptr != NULL) {
  349. p = current->p_cptr;
  350. current->p_cptr = p->p_osptr;
  351. p->p_ysptr = NULL;
  352. p->ptrace = 0;
  353. p->p_pptr = p->p_opptr;
  354. p->p_osptr = p->p_pptr->p_cptr;
  355. if (p->p_osptr)
  356. p->p_osptr->p_ysptr = p;
  357. p->p_pptr->p_cptr = p;
  358. if (p->state == TASK_ZOMBIE)
  359. do_notify_parent(p, p->exit_signal);
  360. /*
  361.  * process group orphan check
  362.  * Case ii: Our child is in a different pgrp
  363.  * than we are, and it was the only connection
  364.  * outside, so the child pgrp is now orphaned.
  365.  */
  366. if ((p->pgrp != current->pgrp) &&
  367.     (p->session == current->session)) {
  368. int pgrp = p->pgrp;
  369. write_unlock_irq(&tasklist_lock);
  370. if (is_orphaned_pgrp(pgrp) && has_stopped_jobs(pgrp)) {
  371. kill_pg(pgrp,SIGHUP,1);
  372. kill_pg(pgrp,SIGCONT,1);
  373. }
  374. write_lock_irq(&tasklist_lock);
  375. }
  376. }
  377. write_unlock_irq(&tasklist_lock);
  378. }
  379. NORET_TYPE void do_exit(long code)
  380. {
  381. struct task_struct *tsk = current;
  382. if (in_interrupt())
  383. panic("Aiee, killing interrupt handler!");
  384. if (!tsk->pid)
  385. panic("Attempted to kill the idle task!");
  386. if (tsk->pid == 1)
  387. panic("Attempted to kill init!");
  388. tsk->flags |= PF_EXITING;
  389. del_timer_sync(&tsk->real_timer);
  390. fake_volatile:
  391. #ifdef CONFIG_BSD_PROCESS_ACCT
  392. acct_process(code);
  393. #endif
  394. __exit_mm(tsk);
  395. lock_kernel();
  396. sem_exit();
  397. __exit_files(tsk);
  398. __exit_fs(tsk);
  399. exit_namespace(tsk);
  400. exit_sighand(tsk);
  401. exit_thread();
  402. if (current->leader)
  403. disassociate_ctty(1);
  404. put_exec_domain(tsk->exec_domain);
  405. if (tsk->binfmt && tsk->binfmt->module)
  406. __MOD_DEC_USE_COUNT(tsk->binfmt->module);
  407. tsk->exit_code = code;
  408. exit_notify();
  409. schedule();
  410. BUG();
  411. /*
  412.  * In order to get rid of the "volatile function does return" message
  413.  * I did this little loop that confuses gcc to think do_exit really
  414.  * is volatile. In fact it's schedule() that is volatile in some
  415.  * circumstances: when current->state = ZOMBIE, schedule() never
  416.  * returns.
  417.  *
  418.  * In fact the natural way to do all this is to have the label and the
  419.  * goto right after each other, but I put the fake_volatile label at
  420.  * the start of the function just in case something /really/ bad
  421.  * happens, and the schedule returns. This way we can try again. I'm
  422.  * not paranoid: it's just that everybody is out to get me.
  423.  */
  424. goto fake_volatile;
  425. }
  426. NORET_TYPE void complete_and_exit(struct completion *comp, long code)
  427. {
  428. if (comp)
  429. complete(comp);
  430. do_exit(code);
  431. }
  432. asmlinkage long sys_exit(int error_code)
  433. {
  434. do_exit((error_code&0xff)<<8);
  435. }
  436. asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
  437. {
  438. int flag, retval;
  439. DECLARE_WAITQUEUE(wait, current);
  440. struct task_struct *tsk;
  441. if (options & ~(WNOHANG|WUNTRACED|__WNOTHREAD|__WCLONE|__WALL))
  442. return -EINVAL;
  443. add_wait_queue(&current->wait_chldexit,&wait);
  444. repeat:
  445. flag = 0;
  446. current->state = TASK_INTERRUPTIBLE;
  447. read_lock(&tasklist_lock);
  448. tsk = current;
  449. do {
  450. struct task_struct *p;
  451.   for (p = tsk->p_cptr ; p ; p = p->p_osptr) {
  452. if (pid>0) {
  453. if (p->pid != pid)
  454. continue;
  455. } else if (!pid) {
  456. if (p->pgrp != current->pgrp)
  457. continue;
  458. } else if (pid != -1) {
  459. if (p->pgrp != -pid)
  460. continue;
  461. }
  462. /* Wait for all children (clone and not) if __WALL is set;
  463.  * otherwise, wait for clone children *only* if __WCLONE is
  464.  * set; otherwise, wait for non-clone children *only*.  (Note:
  465.  * A "clone" child here is one that reports to its parent
  466.  * using a signal other than SIGCHLD.) */
  467. if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
  468.     && !(options & __WALL))
  469. continue;
  470. flag = 1;
  471. switch (p->state) {
  472. case TASK_STOPPED:
  473. if (!p->exit_code)
  474. continue;
  475. if (!(options & WUNTRACED) && !(p->ptrace & PT_PTRACED))
  476. continue;
  477. read_unlock(&tasklist_lock);
  478. retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; 
  479. if (!retval && stat_addr) 
  480. retval = put_user((p->exit_code << 8) | 0x7f, stat_addr);
  481. if (!retval) {
  482. p->exit_code = 0;
  483. retval = p->pid;
  484. }
  485. goto end_wait4;
  486. case TASK_ZOMBIE:
  487. current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;
  488. current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;
  489. read_unlock(&tasklist_lock);
  490. retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
  491. if (!retval && stat_addr)
  492. retval = put_user(p->exit_code, stat_addr);
  493. if (retval)
  494. goto end_wait4; 
  495. retval = p->pid;
  496. if (p->p_opptr != p->p_pptr) {
  497. write_lock_irq(&tasklist_lock);
  498. REMOVE_LINKS(p);
  499. p->p_pptr = p->p_opptr;
  500. SET_LINKS(p);
  501. do_notify_parent(p, SIGCHLD);
  502. write_unlock_irq(&tasklist_lock);
  503. } else
  504. release_task(p);
  505. goto end_wait4;
  506. default:
  507. continue;
  508. }
  509. }
  510. if (options & __WNOTHREAD)
  511. break;
  512. tsk = next_thread(tsk);
  513. } while (tsk != current);
  514. read_unlock(&tasklist_lock);
  515. if (flag) {
  516. retval = 0;
  517. if (options & WNOHANG)
  518. goto end_wait4;
  519. retval = -ERESTARTSYS;
  520. if (signal_pending(current))
  521. goto end_wait4;
  522. schedule();
  523. goto repeat;
  524. }
  525. retval = -ECHILD;
  526. end_wait4:
  527. current->state = TASK_RUNNING;
  528. remove_wait_queue(&current->wait_chldexit,&wait);
  529. return retval;
  530. }
  531. #if !defined(__alpha__) && !defined(__ia64__)
  532. /*
  533.  * sys_waitpid() remains for compatibility. waitpid() should be
  534.  * implemented by calling sys_wait4() from libc.a.
  535.  */
  536. asmlinkage long sys_waitpid(pid_t pid,unsigned int * stat_addr, int options)
  537. {
  538. return sys_wait4(pid, stat_addr, options, NULL);
  539. }
  540. #endif