linux-bk/kernel/exit.c
<<
>>
Prefs
   1/*
   2 *  linux/kernel/exit.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 */
   6
   7#include <linux/config.h>
   8#include <linux/mm.h>
   9#include <linux/slab.h>
  10#include <linux/interrupt.h>
  11#include <linux/smp_lock.h>
  12#include <linux/module.h>
  13#include <linux/completion.h>
  14#include <linux/personality.h>
  15#include <linux/tty.h>
  16#include <linux/namespace.h>
  17#include <linux/security.h>
  18#include <linux/acct.h>
  19#include <linux/file.h>
  20#include <linux/binfmts.h>
  21#include <linux/ptrace.h>
  22
  23#include <asm/uaccess.h>
  24#include <asm/pgtable.h>
  25#include <asm/mmu_context.h>
  26
  27extern void sem_exit (void);
  28extern struct task_struct *child_reaper;
  29
  30int getrusage(struct task_struct *, int, struct rusage *);
  31
  32static struct dentry * __unhash_process(struct task_struct *p)
  33{
  34        struct dentry *proc_dentry;
  35        nr_threads--;
  36        detach_pid(p, PIDTYPE_PID);
  37        if (thread_group_leader(p)) {
  38                detach_pid(p, PIDTYPE_PGID);
  39                detach_pid(p, PIDTYPE_SID);
  40        }
  41
  42        REMOVE_LINKS(p);
  43        p->pid = 0;
  44        proc_dentry = p->proc_dentry;
  45        if (unlikely(proc_dentry != NULL)) {
  46                spin_lock(&dcache_lock);
  47                if (!list_empty(&proc_dentry->d_hash)) {
  48                        dget_locked(proc_dentry);
  49                        list_del_init(&proc_dentry->d_hash);
  50                } else
  51                        proc_dentry = NULL;
  52                spin_unlock(&dcache_lock);
  53        }
  54        return proc_dentry;
  55}
  56
  57void release_task(struct task_struct * p)
  58{
  59        struct dentry *proc_dentry;
  60
  61        if (p->state != TASK_ZOMBIE)
  62                BUG();
  63        if (p != current)
  64                wait_task_inactive(p);
  65        atomic_dec(&p->user->processes);
  66        security_ops->task_free_security(p);
  67        free_uid(p->user);
  68        if (unlikely(p->ptrace)) {
  69                write_lock_irq(&tasklist_lock);
  70                __ptrace_unlink(p);
  71                write_unlock_irq(&tasklist_lock);
  72        }
  73        BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
  74        write_lock_irq(&tasklist_lock);
  75        __exit_sighand(p);
  76        proc_dentry = __unhash_process(p);
  77        p->parent->cutime += p->utime + p->cutime;
  78        p->parent->cstime += p->stime + p->cstime;
  79        p->parent->cmin_flt += p->min_flt + p->cmin_flt;
  80        p->parent->cmaj_flt += p->maj_flt + p->cmaj_flt;
  81        p->parent->cnswap += p->nswap + p->cnswap;
  82        sched_exit(p);
  83        write_unlock_irq(&tasklist_lock);
  84
  85        if (unlikely(proc_dentry != NULL)) {
  86                shrink_dcache_parent(proc_dentry);
  87                dput(proc_dentry);
  88        }
  89        release_thread(p);
  90        put_task_struct(p);
  91}
  92
  93/* we are using it only for SMP init */
  94
  95void unhash_process(struct task_struct *p)
  96{
  97        struct dentry *proc_dentry;
  98
  99        write_lock_irq(&tasklist_lock);
 100        proc_dentry = __unhash_process(p);
 101        write_unlock_irq(&tasklist_lock);
 102
 103        if (unlikely(proc_dentry != NULL)) {
 104                shrink_dcache_parent(proc_dentry);
 105                dput(proc_dentry);
 106        }
 107}
 108
 109/*
 110 * This checks not only the pgrp, but falls back on the pid if no
 111 * satisfactory pgrp is found. I dunno - gdb doesn't work correctly
 112 * without this...
 113 */
 114int session_of_pgrp(int pgrp)
 115{
 116        struct task_struct *p;
 117        struct list_head *l;
 118        struct pid *pid;
 119        int sid = -1;
 120
 121        read_lock(&tasklist_lock);
 122        for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid)
 123                if (p->session > 0) {
 124                        sid = p->session;
 125                        break;
 126                }
 127        read_unlock(&tasklist_lock);
 128        return sid;
 129}
 130
 131/*
 132 * Determine if a process group is "orphaned", according to the POSIX
 133 * definition in 2.2.2.52.  Orphaned process groups are not to be affected
 134 * by terminal-generated stop signals.  Newly orphaned process groups are
 135 * to receive a SIGHUP and a SIGCONT.
 136 *
 137 * "I ask you, have you ever known what it is to be an orphan?"
 138 */
 139static int __will_become_orphaned_pgrp(int pgrp, task_t *ignored_task)
 140{
 141        struct task_struct *p;
 142        struct list_head *l;
 143        struct pid *pid;
 144        int ret = 1;
 145
 146        for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
 147                if (p == ignored_task
 148                                || p->state == TASK_ZOMBIE 
 149                                || p->real_parent->pid == 1)
 150                        continue;
 151                if (p->real_parent->pgrp != pgrp
 152                            && p->real_parent->session == p->session) {
 153                        ret = 0;
 154                        break;
 155                }
 156        }
 157        return ret;     /* (sighing) "Often!" */
 158}
 159
 160static int will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_task)
 161{
 162        int retval;
 163
 164        read_lock(&tasklist_lock);
 165        retval = __will_become_orphaned_pgrp(pgrp, ignored_task);
 166        read_unlock(&tasklist_lock);
 167
 168        return retval;
 169}
 170
 171int is_orphaned_pgrp(int pgrp)
 172{
 173        return will_become_orphaned_pgrp(pgrp, 0);
 174}
 175
 176static inline int __has_stopped_jobs(int pgrp)
 177{
 178        int retval = 0;
 179        struct task_struct *p;
 180        struct list_head *l;
 181        struct pid *pid;
 182
 183        for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
 184                if (p->state != TASK_STOPPED)
 185                        continue;
 186                retval = 1;
 187                break;
 188        }
 189        return retval;
 190}
 191
 192static inline int has_stopped_jobs(int pgrp)
 193{
 194        int retval;
 195
 196        read_lock(&tasklist_lock);
 197        retval = __has_stopped_jobs(pgrp);
 198        read_unlock(&tasklist_lock);
 199
 200        return retval;
 201}
 202
 203/**
 204 * reparent_to_init() - Reparent the calling kernel thread to the init task.
 205 *
 206 * If a kernel thread is launched as a result of a system call, or if
 207 * it ever exits, it should generally reparent itself to init so that
 208 * it is correctly cleaned up on exit.
 209 *
 210 * The various task state such as scheduling policy and priority may have
 211 * been inherited from a user process, so we reset them to sane values here.
 212 *
 213 * NOTE that reparent_to_init() gives the caller full capabilities.
 214 */
 215void reparent_to_init(void)
 216{
 217        write_lock_irq(&tasklist_lock);
 218
 219        ptrace_unlink(current);
 220        /* Reparent to init */
 221        REMOVE_LINKS(current);
 222        current->parent = child_reaper;
 223        current->real_parent = child_reaper;
 224        SET_LINKS(current);
 225
 226        /* Set the exit signal to SIGCHLD so we signal init on exit */
 227        current->exit_signal = SIGCHLD;
 228
 229        if ((current->policy == SCHED_NORMAL) && (task_nice(current) < 0))
 230                set_user_nice(current, 0);
 231        /* cpus_allowed? */
 232        /* rt_priority? */
 233        /* signals? */
 234        security_ops->task_reparent_to_init(current);
 235        memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim)));
 236        current->user = INIT_USER;
 237
 238        write_unlock_irq(&tasklist_lock);
 239}
 240
 241/*
 242 *      Put all the gunge required to become a kernel thread without
 243 *      attached user resources in one place where it belongs.
 244 */
 245
 246void daemonize(void)
 247{
 248        struct fs_struct *fs;
 249
 250
 251        /*
 252         * If we were started as result of loading a module, close all of the
 253         * user space pages.  We don't need them, and if we didn't close them
 254         * they would be locked into memory.
 255         */
 256        exit_mm(current);
 257
 258        current->session = 1;
 259        current->pgrp = 1;
 260        current->tty = NULL;
 261
 262        /* Become as one with the init task */
 263
 264        exit_fs(current);       /* current->fs->count--; */
 265        fs = init_task.fs;
 266        current->fs = fs;
 267        atomic_inc(&fs->count);
 268        exit_files(current);
 269        current->files = init_task.files;
 270        atomic_inc(&current->files->count);
 271
 272        reparent_to_init();
 273}
 274
 275static inline void close_files(struct files_struct * files)
 276{
 277        int i, j;
 278
 279        j = 0;
 280        for (;;) {
 281                unsigned long set;
 282                i = j * __NFDBITS;
 283                if (i >= files->max_fdset || i >= files->max_fds)
 284                        break;
 285                set = files->open_fds->fds_bits[j++];
 286                while (set) {
 287                        if (set & 1) {
 288                                struct file * file = xchg(&files->fd[i], NULL);
 289                                if (file)
 290                                        filp_close(file, files);
 291                        }
 292                        i++;
 293                        set >>= 1;
 294                }
 295        }
 296}
 297
 298void put_files_struct(struct files_struct *files)
 299{
 300        if (atomic_dec_and_test(&files->count)) {
 301                close_files(files);
 302                /*
 303                 * Free the fd and fdset arrays if we expanded them.
 304                 */
 305                if (files->fd != &files->fd_array[0])
 306                        free_fd_array(files->fd, files->max_fds);
 307                if (files->max_fdset > __FD_SETSIZE) {
 308                        free_fdset(files->open_fds, files->max_fdset);
 309                        free_fdset(files->close_on_exec, files->max_fdset);
 310                }
 311                kmem_cache_free(files_cachep, files);
 312        }
 313}
 314
 315static inline void __exit_files(struct task_struct *tsk)
 316{
 317        struct files_struct * files = tsk->files;
 318
 319        if (files) {
 320                task_lock(tsk);
 321                tsk->files = NULL;
 322                task_unlock(tsk);
 323                put_files_struct(files);
 324        }
 325}
 326
 327void exit_files(struct task_struct *tsk)
 328{
 329        __exit_files(tsk);
 330}
 331
 332static inline void __put_fs_struct(struct fs_struct *fs)
 333{
 334        /* No need to hold fs->lock if we are killing it */
 335        if (atomic_dec_and_test(&fs->count)) {
 336                dput(fs->root);
 337                mntput(fs->rootmnt);
 338                dput(fs->pwd);
 339                mntput(fs->pwdmnt);
 340                if (fs->altroot) {
 341                        dput(fs->altroot);
 342                        mntput(fs->altrootmnt);
 343                }
 344                kmem_cache_free(fs_cachep, fs);
 345        }
 346}
 347
 348void put_fs_struct(struct fs_struct *fs)
 349{
 350        __put_fs_struct(fs);
 351}
 352
 353static inline void __exit_fs(struct task_struct *tsk)
 354{
 355        struct fs_struct * fs = tsk->fs;
 356
 357        if (fs) {
 358                task_lock(tsk);
 359                tsk->fs = NULL;
 360                task_unlock(tsk);
 361                __put_fs_struct(fs);
 362        }
 363}
 364
 365void exit_fs(struct task_struct *tsk)
 366{
 367        __exit_fs(tsk);
 368}
 369
 370/*
 371 * We can use these to temporarily drop into
 372 * "lazy TLB" mode and back.
 373 */
 374struct mm_struct * start_lazy_tlb(void)
 375{
 376        struct mm_struct *mm = current->mm;
 377        current->mm = NULL;
 378        /* active_mm is still 'mm' */
 379        atomic_inc(&mm->mm_count);
 380        enter_lazy_tlb(mm, current, smp_processor_id());
 381        return mm;
 382}
 383
 384void end_lazy_tlb(struct mm_struct *mm)
 385{
 386        struct mm_struct *active_mm = current->active_mm;
 387
 388        current->mm = mm;
 389        if (mm != active_mm) {
 390                current->active_mm = mm;
 391                activate_mm(active_mm, mm);
 392        }
 393        mmdrop(active_mm);
 394}
 395
 396/*
 397 * Turn us into a lazy TLB process if we
 398 * aren't already..
 399 */
 400static inline void __exit_mm(struct task_struct * tsk)
 401{
 402        struct mm_struct * mm = tsk->mm;
 403
 404        mm_release();
 405        if (mm) {
 406                atomic_inc(&mm->mm_count);
 407                if (mm != tsk->active_mm) BUG();
 408                /* more a memory barrier than a real lock */
 409                task_lock(tsk);
 410                tsk->mm = NULL;
 411                enter_lazy_tlb(mm, current, smp_processor_id());
 412                task_unlock(tsk);
 413                mmput(mm);
 414        }
 415}
 416
 417void exit_mm(struct task_struct *tsk)
 418{
 419        __exit_mm(tsk);
 420}
 421
 422static inline void choose_new_parent(task_t *p, task_t *reaper, task_t *child_reaper)
 423{
 424        /* Make sure we're not reparenting to ourselves.  */
 425        if (p == reaper)
 426                p->real_parent = child_reaper;
 427        else
 428                p->real_parent = reaper;
 429        if (p->parent == p->real_parent)
 430                BUG();
 431}
 432
 433static inline void reparent_thread(task_t *p, task_t *father, int traced)
 434{
 435        /* We dont want people slaying init.  */
 436        if (p->exit_signal != -1)
 437                p->exit_signal = SIGCHLD;
 438        p->self_exec_id++;
 439
 440        if (p->pdeath_signal)
 441                send_sig(p->pdeath_signal, p, 0);
 442
 443        /* Move the child from its dying parent to the new one.  */
 444        if (unlikely(traced)) {
 445                /* Preserve ptrace links if someone else is tracing this child.  */
 446                list_del_init(&p->ptrace_list);
 447                if (p->parent != p->real_parent)
 448                        list_add(&p->ptrace_list, &p->real_parent->ptrace_children);
 449        } else {
 450                /* If this child is being traced, then we're the one tracing it
 451                 * anyway, so let go of it.
 452                 */
 453                p->ptrace = 0;
 454                list_del_init(&p->sibling);
 455                p->parent = p->real_parent;
 456                list_add_tail(&p->sibling, &p->parent->children);
 457
 458                /* If we'd notified the old parent about this child's death,
 459                 * also notify the new parent.
 460                 */
 461                if (p->state == TASK_ZOMBIE && p->exit_signal != -1)
 462                        do_notify_parent(p, p->exit_signal);
 463        }
 464
 465        /*
 466         * process group orphan check
 467         * Case ii: Our child is in a different pgrp
 468         * than we are, and it was the only connection
 469         * outside, so the child pgrp is now orphaned.
 470         */
 471        if ((p->pgrp != father->pgrp) &&
 472            (p->session == father->session)) {
 473                int pgrp = p->pgrp;
 474
 475                if (__will_become_orphaned_pgrp(pgrp, 0) && __has_stopped_jobs(pgrp)) {
 476                        __kill_pg_info(SIGHUP, (void *)1, pgrp);
 477                        __kill_pg_info(SIGCONT, (void *)1, pgrp);
 478                }
 479        }
 480}
 481
 482/*
 483 * When we die, we re-parent all our children.
 484 * Try to give them to another thread in our thread
 485 * group, and if no such member exists, give it to
 486 * the global child reaper process (ie "init")
 487 */
 488static inline void forget_original_parent(struct task_struct * father)
 489{
 490        struct task_struct *p, *reaper = father;
 491        struct list_head *_p, *_n;
 492
 493        reaper = father->group_leader;
 494        if (reaper == father)
 495                reaper = child_reaper;
 496
 497        /*
 498         * There are only two places where our children can be:
 499         *
 500         * - in our child list
 501         * - in our ptraced child list
 502         *
 503         * Search them and reparent children.
 504         */
 505        list_for_each_safe(_p, _n, &father->children) {
 506                p = list_entry(_p,struct task_struct,sibling);
 507                if (father == p->real_parent) {
 508                        choose_new_parent(p, reaper, child_reaper);
 509                        reparent_thread(p, father, 0);
 510                } else {
 511                        ptrace_unlink (p);
 512                        if (p->state == TASK_ZOMBIE && p->exit_signal != -1)
 513                                do_notify_parent(p, p->exit_signal);
 514                }
 515        }
 516        list_for_each_safe(_p, _n, &father->ptrace_children) {
 517                p = list_entry(_p,struct task_struct,ptrace_list);
 518                choose_new_parent(p, reaper, child_reaper);
 519                reparent_thread(p, father, 1);
 520        }
 521}
 522
 523/*
 524 * Send signals to all our closest relatives so that they know
 525 * to properly mourn us..
 526 */
 527static void exit_notify(void)
 528{
 529        struct task_struct *t;
 530
 531        write_lock_irq(&tasklist_lock);
 532
 533        /*
 534         * This does two things:
 535         *
 536         * A.  Make init inherit all the child processes
 537         * B.  Check to see if any process groups have become orphaned
 538         *      as a result of our exiting, and if they have any stopped
 539         *      jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
 540         */
 541
 542        forget_original_parent(current);
 543        BUG_ON(!list_empty(&current->children));
 544
 545        /*
 546         * Check to see if any process groups have become orphaned
 547         * as a result of our exiting, and if they have any stopped
 548         * jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
 549         *
 550         * Case i: Our father is in a different pgrp than we are
 551         * and we were the only connection outside, so our pgrp
 552         * is about to become orphaned.
 553         */
 554         
 555        t = current->parent;
 556        
 557        if ((t->pgrp != current->pgrp) &&
 558            (t->session == current->session) &&
 559            __will_become_orphaned_pgrp(current->pgrp, current) &&
 560            __has_stopped_jobs(current->pgrp)) {
 561                __kill_pg_info(SIGHUP, (void *)1, current->pgrp);
 562                __kill_pg_info(SIGCONT, (void *)1, current->pgrp);
 563        }
 564
 565        /* Let father know we died 
 566         *
 567         * Thread signals are configurable, but you aren't going to use
 568         * that to send signals to arbitary processes. 
 569         * That stops right now.
 570         *
 571         * If the parent exec id doesn't match the exec id we saved
 572         * when we started then we know the parent has changed security
 573         * domain.
 574         *
 575         * If our self_exec id doesn't match our parent_exec_id then
 576         * we have changed execution domain as these two values started
 577         * the same after a fork.
 578         *      
 579         */
 580        
 581        if (current->exit_signal != SIGCHLD && current->exit_signal != -1 &&
 582            ( current->parent_exec_id != t->self_exec_id  ||
 583              current->self_exec_id != current->parent_exec_id) 
 584            && !capable(CAP_KILL))
 585                current->exit_signal = SIGCHLD;
 586
 587
 588        if (current->exit_signal != -1)
 589                do_notify_parent(current, current->exit_signal);
 590
 591        current->state = TASK_ZOMBIE;
 592        /*
 593         * No need to unlock IRQs, we'll schedule() immediately
 594         * anyway. In the preemption case this also makes it
 595         * impossible for the task to get runnable again (thus
 596         * the "_raw_" unlock - to make sure we don't try to
 597         * preempt here).
 598         */
 599        _raw_write_unlock(&tasklist_lock);
 600}
 601
 602NORET_TYPE void do_exit(long code)
 603{
 604        struct task_struct *tsk = current;
 605
 606        if (in_interrupt())
 607                panic("Aiee, killing interrupt handler!");
 608        if (!tsk->pid)
 609                panic("Attempted to kill the idle task!");
 610        if (tsk->pid == 1)
 611                panic("Attempted to kill init!");
 612        tsk->flags |= PF_EXITING;
 613        del_timer_sync(&tsk->real_timer);
 614
 615        if (unlikely(preempt_count()))
 616                printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
 617                                current->comm, current->pid,
 618                                preempt_count());
 619
 620fake_volatile:
 621        acct_process(code);
 622        __exit_mm(tsk);
 623
 624        sem_exit();
 625        __exit_files(tsk);
 626        __exit_fs(tsk);
 627        exit_namespace(tsk);
 628        exit_thread();
 629
 630        if (current->leader)
 631                disassociate_ctty(1);
 632
 633        put_exec_domain(tsk->thread_info->exec_domain);
 634        if (tsk->binfmt && tsk->binfmt->module)
 635                __MOD_DEC_USE_COUNT(tsk->binfmt->module);
 636
 637        tsk->exit_code = code;
 638        exit_notify();
 639        preempt_disable();
 640        if (current->exit_signal == -1)
 641                release_task(current);
 642        schedule();
 643        BUG();
 644/*
 645 * In order to get rid of the "volatile function does return" message
 646 * I did this little loop that confuses gcc to think do_exit really
 647 * is volatile. In fact it's schedule() that is volatile in some
 648 * circumstances: when current->state = ZOMBIE, schedule() never
 649 * returns.
 650 *
 651 * In fact the natural way to do all this is to have the label and the
 652 * goto right after each other, but I put the fake_volatile label at
 653 * the start of the function just in case something /really/ bad
 654 * happens, and the schedule returns. This way we can try again. I'm
 655 * not paranoid: it's just that everybody is out to get me.
 656 */
 657        goto fake_volatile;
 658}
 659
 660NORET_TYPE void complete_and_exit(struct completion *comp, long code)
 661{
 662        if (comp)
 663                complete(comp);
 664        
 665        do_exit(code);
 666}
 667
 668asmlinkage long sys_exit(int error_code)
 669{
 670        do_exit((error_code&0xff)<<8);
 671}
 672
 673/*
 674 * this kills every thread in the thread group. Note that any externally
 675 * wait4()-ing process will get the correct exit code - even if this 
 676 * thread is not the thread group leader.
 677 */
 678asmlinkage long sys_exit_group(int error_code)
 679{
 680        unsigned int exit_code = (error_code & 0xff) << 8;
 681
 682        if (!list_empty(&current->thread_group)) {
 683                struct signal_struct *sig = current->sig;
 684
 685                spin_lock_irq(&sig->siglock);
 686                if (sig->group_exit) {
 687                        spin_unlock_irq(&sig->siglock);
 688
 689                        /* another thread was faster: */
 690                        do_exit(sig->group_exit_code);
 691                }
 692                sig->group_exit = 1;
 693                sig->group_exit_code = exit_code;
 694                __broadcast_thread_group(current, SIGKILL);
 695                spin_unlock_irq(&sig->siglock);
 696        }
 697
 698        do_exit(exit_code);
 699}
 700
 701static int eligible_child(pid_t pid, int options, task_t *p)
 702{
 703        if (pid > 0) {
 704                if (p->pid != pid)
 705                        return 0;
 706        } else if (!pid) {
 707                if (p->pgrp != current->pgrp)
 708                        return 0;
 709        } else if (pid != -1) {
 710                if (p->pgrp != -pid)
 711                        return 0;
 712        }
 713
 714        /*
 715         * Do not consider detached threads that are
 716         * not ptraced:
 717         */
 718        if (p->exit_signal == -1 && !p->ptrace)
 719                return 0;
 720
 721        /* Wait for all children (clone and not) if __WALL is set;
 722         * otherwise, wait for clone children *only* if __WCLONE is
 723         * set; otherwise, wait for non-clone children *only*.  (Note:
 724         * A "clone" child here is one that reports to its parent
 725         * using a signal other than SIGCHLD.) */
 726        if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
 727            && !(options & __WALL))
 728                return 0;
 729        /*
 730         * Do not consider thread group leaders that are
 731         * in a non-empty thread group:
 732         */
 733        if (current->tgid != p->tgid && delay_group_leader(p))
 734                return 2;
 735
 736        if (security_ops->task_wait(p))
 737                return 0;
 738
 739        return 1;
 740}
 741
 742asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
 743{
 744        int flag, retval;
 745        DECLARE_WAITQUEUE(wait, current);
 746        struct task_struct *tsk;
 747
 748        if (options & ~(WNOHANG|WUNTRACED|__WNOTHREAD|__WCLONE|__WALL))
 749                return -EINVAL;
 750
 751        add_wait_queue(&current->wait_chldexit,&wait);
 752repeat:
 753        flag = 0;
 754        current->state = TASK_INTERRUPTIBLE;
 755        read_lock(&tasklist_lock);
 756        tsk = current;
 757        do {
 758                struct task_struct *p;
 759                struct list_head *_p;
 760                int ret;
 761
 762                list_for_each(_p,&tsk->children) {
 763                        p = list_entry(_p,struct task_struct,sibling);
 764
 765                        ret = eligible_child(pid, options, p);
 766                        if (!ret)
 767                                continue;
 768                        flag = 1;
 769
 770                        switch (p->state) {
 771                        case TASK_STOPPED:
 772                                if (!p->exit_code)
 773                                        continue;
 774                                if (!(options & WUNTRACED) && !(p->ptrace & PT_PTRACED))
 775                                        continue;
 776                                read_unlock(&tasklist_lock);
 777
 778                                /* move to end of parent's list to avoid starvation */
 779                                write_lock_irq(&tasklist_lock);
 780                                remove_parent(p);
 781                                add_parent(p, p->parent);
 782                                write_unlock_irq(&tasklist_lock);
 783                                retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; 
 784                                if (!retval && stat_addr) 
 785                                        retval = put_user((p->exit_code << 8) | 0x7f, stat_addr);
 786                                if (!retval) {
 787                                        p->exit_code = 0;
 788                                        retval = p->pid;
 789                                }
 790                                goto end_wait4;
 791                        case TASK_ZOMBIE:
 792                                /*
 793                                 * Eligible but we cannot release it yet:
 794                                 */
 795                                if (ret == 2)
 796                                        continue;
 797                                read_unlock(&tasklist_lock);
 798                                retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
 799                                if (!retval && stat_addr) {
 800                                        if (p->sig->group_exit)
 801                                                retval = put_user(p->sig->group_exit_code, stat_addr);
 802                                        else
 803                                                retval = put_user(p->exit_code, stat_addr);
 804                                }
 805                                if (retval)
 806                                        goto end_wait4; 
 807                                retval = p->pid;
 808                                if (p->real_parent != p->parent) {
 809                                        write_lock_irq(&tasklist_lock);
 810                                        __ptrace_unlink(p);
 811                                        do_notify_parent(p, SIGCHLD);
 812                                        write_unlock_irq(&tasklist_lock);
 813                                } else
 814                                        release_task(p);
 815                                goto end_wait4;
 816                        default:
 817                                continue;
 818                        }
 819                }
 820                if (!flag) {
 821                        list_for_each (_p,&tsk->ptrace_children) {
 822                                p = list_entry(_p,struct task_struct,ptrace_list);
 823                                if (!eligible_child(pid, options, p))
 824                                        continue;
 825                                flag = 1;
 826                                break;
 827                        }
 828                }
 829                if (options & __WNOTHREAD)
 830                        break;
 831                tsk = next_thread(tsk);
 832                if (tsk->sig != current->sig)
 833                        BUG();
 834        } while (tsk != current);
 835        read_unlock(&tasklist_lock);
 836        if (flag) {
 837                retval = 0;
 838                if (options & WNOHANG)
 839                        goto end_wait4;
 840                retval = -ERESTARTSYS;
 841                if (signal_pending(current))
 842                        goto end_wait4;
 843                schedule();
 844                goto repeat;
 845        }
 846        retval = -ECHILD;
 847end_wait4:
 848        current->state = TASK_RUNNING;
 849        remove_wait_queue(&current->wait_chldexit,&wait);
 850        return retval;
 851}
 852
 853#if !defined(__alpha__) && !defined(__ia64__) && !defined(__arm__)
 854
 855/*
 856 * sys_waitpid() remains for compatibility. waitpid() should be
 857 * implemented by calling sys_wait4() from libc.a.
 858 */
 859asmlinkage long sys_waitpid(pid_t pid,unsigned int * stat_addr, int options)
 860{
 861        return sys_wait4(pid, stat_addr, options, NULL);
 862}
 863
 864#endif
 865
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.