XXX - move to kern_proc.c? */
| 410 | |
| 411 | /* XXX - move to kern_proc.c? */ |
| 412 | static int |
| 413 | filt_procattach(struct knote *kn) |
| 414 | { |
| 415 | struct proc *p; |
| 416 | int error; |
| 417 | bool exiting, immediate; |
| 418 | |
| 419 | exiting = immediate = false; |
| 420 | if (kn->kn_sfflags & NOTE_EXIT) |
| 421 | p = pfind_any(kn->kn_id); |
| 422 | else |
| 423 | p = pfind(kn->kn_id); |
| 424 | if (p == NULL) |
| 425 | return (ESRCH); |
| 426 | if (p->p_flag & P_WEXIT) |
| 427 | exiting = true; |
| 428 | |
| 429 | if ((error = p_cansee(curthread, p))) { |
| 430 | PROC_UNLOCK(p); |
| 431 | return (error); |
| 432 | } |
| 433 | |
| 434 | kn->kn_ptr.p_proc = p; |
| 435 | kn->kn_flags |= EV_CLEAR; /* automatically set */ |
| 436 | |
| 437 | /* |
| 438 | * Internal flag indicating registration done by kernel for the |
| 439 | * purposes of getting a NOTE_CHILD notification. |
| 440 | */ |
| 441 | if (kn->kn_flags & EV_FLAG2) { |
| 442 | kn->kn_flags &= ~EV_FLAG2; |
| 443 | kn->kn_data = kn->kn_sdata; /* ppid */ |
| 444 | kn->kn_fflags = NOTE_CHILD; |
| 445 | kn->kn_sfflags &= ~(NOTE_EXIT | NOTE_EXEC | NOTE_FORK); |
| 446 | immediate = true; /* Force immediate activation of child note. */ |
| 447 | } |
| 448 | /* |
| 449 | * Internal flag indicating registration done by kernel (for other than |
| 450 | * NOTE_CHILD). |
| 451 | */ |
| 452 | if (kn->kn_flags & EV_FLAG1) { |
| 453 | kn->kn_flags &= ~EV_FLAG1; |
| 454 | } |
| 455 | |
| 456 | knlist_add(p->p_klist, kn, 1); |
| 457 | |
| 458 | /* |
| 459 | * Immediately activate any child notes or, in the case of a zombie |
| 460 | * target process, exit notes. The latter is necessary to handle the |
| 461 | * case where the target process, e.g. a child, dies before the kevent |
| 462 | * is registered. |
| 463 | */ |
| 464 | if (immediate || (exiting && filt_proc(kn, NOTE_EXIT))) |
| 465 | KNOTE_ACTIVATE(kn, 0); |
| 466 | |
| 467 | PROC_UNLOCK(p); |
| 468 | |
| 469 | return (0); |
nothing calls this directly
no test coverage detected