exit.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:14k
源码类别:

嵌入式Linux

开发平台:

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