1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 30 #pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.25 */ 31 32 #include <sys/types.h> 33 #include <sys/sysmacros.h> 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/vfs.h> 37 #include <sys/cred.h> 38 #include <sys/vnode.h> 39 #include <sys/file.h> 40 #include <sys/errno.h> 41 #include <sys/kmem.h> 42 #include <sys/user.h> 43 #include <sys/buf.h> 44 #include <sys/var.h> 45 #include <sys/conf.h> 46 #include <sys/debug.h> 47 #include <sys/proc.h> 48 #include <sys/signal.h> 49 #include <sys/siginfo.h> 50 #include <sys/acct.h> 51 #include <sys/procset.h> 52 #include <sys/cmn_err.h> 53 #include <sys/fault.h> 54 #include <sys/syscall.h> 55 #include <sys/ucontext.h> 56 #include <sys/procfs.h> 57 #include <sys/session.h> 58 #include <sys/task.h> 59 #include <sys/project.h> 60 #include <sys/pool.h> 61 #include <sys/zone.h> 62 #include <sys/contract/process_impl.h> 63 64 id_t getmyid(idtype_t); 65 int checkprocset(procset_t *); 66 static kthread_t *getlwpptr(id_t); 67 int procinset(proc_t *, procset_t *); 68 static int lwpinset(proc_t *, procset_t *, kthread_t *, int *); 69 70 /* 71 * The dotoprocs function locates the process(es) specified 72 * by the procset structure pointed to by psp. funcp points to a 73 * function which dotoprocs will call for each process in the 74 * specified set. The arguments to this function will be a pointer 75 * to the current process from the set and arg. 76 * If the called function returns -1, it means that processing of the 77 * procset should stop and a normal (non-error) return should be made 78 * to the caller of dotoprocs. 79 * If the called function returns any other non-zero value the search 80 * is terminated and the function's return value is returned to 81 * the caller of dotoprocs. This will normally be an error code. 82 * Otherwise, dotoprocs will return zero after processing the entire 83 * process set unless no processes were found in which case ESRCH will 84 * be returned. 85 */ 86 int 87 dotoprocs(procset_t *psp, int (*funcp)(), char *arg) 88 { 89 proc_t *prp; /* A process from the set */ 90 int error; 91 int nfound; /* Nbr of processes found. */ 92 proc_t *lastprp; /* Last proc found. */ 93 94 ASSERT(funcp != NULL); 95 96 /* 97 * Check that the procset_t is valid. 98 */ 99 error = checkprocset(psp); 100 if (error) { 101 return (error); 102 } 103 /* 104 * Check for the special value P_MYID in either operand 105 * and replace it with the correct value. We don't check 106 * for an error return from getmyid() because the idtypes 107 * have been validated by the checkprocset() call above. 108 */ 109 mutex_enter(&pidlock); 110 if (psp->p_lid == P_MYID) { 111 psp->p_lid = getmyid(psp->p_lidtype); 112 } 113 if (psp->p_rid == P_MYID) { 114 psp->p_rid = getmyid(psp->p_ridtype); 115 } 116 117 /* 118 * If psp only acts on a single proc, we can reduce pidlock hold time 119 * by avoiding a needless scan of the entire proc list. Although 120 * there are many procset_t combinations which might boil down to a 121 * single proc, the most common case is an AND operation where one 122 * side is a specific pid, and the other side is P_ALL, so that is 123 * the case for which we will provide a fast path. Other cases could 124 * be added in a similar fashion if they were to become significant 125 * pidlock bottlenecks. 126 * 127 * Perform the check symmetrically: either the left or right side may 128 * specify a pid, with the opposite side being 'all'. 129 */ 130 if (psp->p_op == POP_AND) { 131 if (((psp->p_lidtype == P_PID) && (psp->p_ridtype == P_ALL)) || 132 ((psp->p_ridtype == P_PID) && (psp->p_lidtype == P_ALL))) { 133 id_t pid; 134 135 pid = (psp->p_lidtype == P_PID) ? 136 psp->p_lid : psp->p_rid; 137 if (((prp = prfind((pid_t)pid)) == NULL) || 138 (prp->p_stat == SIDL || prp->p_stat == SZOMB || 139 prp->p_tlist == NULL || prp->p_flag & SSYS)) { 140 /* 141 * Specified proc doesn't exist or should 142 * not be operated on. 143 * Don't need to make HASZONEACCESS check 144 * here since prfind() takes care of that. 145 */ 146 mutex_exit(&pidlock); 147 return (ESRCH); 148 } 149 /* 150 * Operate only on the specified proc. It's okay 151 * if it's init. 152 */ 153 error = (*funcp)(prp, arg); 154 mutex_exit(&pidlock); 155 if (error == -1) 156 error = 0; 157 return (error); 158 } 159 } 160 161 nfound = 0; 162 error = 0; 163 164 for (prp = practive; prp != NULL; prp = prp->p_next) { 165 /* 166 * If caller is in a non-global zone, skip processes 167 * in other zones. 168 */ 169 if (!HASZONEACCESS(curproc, prp->p_zone->zone_id)) 170 continue; 171 if (prp->p_stat == SIDL || prp->p_stat == SZOMB || 172 prp->p_tlist == NULL || prp->p_flag & SSYS) 173 continue; 174 if (procinset(prp, psp)) { 175 nfound++; 176 lastprp = prp; 177 if (prp != proc_init) { 178 error = (*funcp)(prp, arg); 179 if (error == -1) { 180 mutex_exit(&pidlock); 181 return (0); 182 } else if (error) { 183 mutex_exit(&pidlock); 184 return (error); 185 } 186 } 187 } 188 } 189 if (nfound == 0) { 190 mutex_exit(&pidlock); 191 return (ESRCH); 192 } 193 if (nfound == 1 && lastprp == proc_init) 194 error = (*funcp)(lastprp, arg); 195 if (error == -1) 196 error = 0; 197 mutex_exit(&pidlock); 198 return (error); 199 } 200 201 /* 202 * Check if a procset_t is valid. Return zero or an errno. 203 */ 204 int 205 checkprocset(procset_t *psp) 206 { 207 switch (psp->p_lidtype) { 208 case P_LWPID: 209 case P_PID: 210 case P_PPID: 211 case P_PGID: 212 case P_SID: 213 case P_TASKID: 214 case P_CID: 215 case P_UID: 216 case P_GID: 217 case P_PROJID: 218 case P_POOLID: 219 case P_ZONEID: 220 case P_CTID: 221 case P_ALL: 222 break; 223 default: 224 return (EINVAL); 225 } 226 227 switch (psp->p_ridtype) { 228 case P_LWPID: 229 case P_PID: 230 case P_PPID: 231 case P_PGID: 232 case P_SID: 233 case P_TASKID: 234 case P_CID: 235 case P_UID: 236 case P_GID: 237 case P_PROJID: 238 case P_POOLID: 239 case P_ZONEID: 240 case P_CTID: 241 case P_ALL: 242 break; 243 default: 244 return (EINVAL); 245 } 246 247 switch (psp->p_op) { 248 case POP_DIFF: 249 case POP_AND: 250 case POP_OR: 251 case POP_XOR: 252 break; 253 default: 254 return (EINVAL); 255 } 256 257 return (0); 258 } 259 260 /* 261 * procinset returns 1 if the process pointed to 262 * by pp is in the process set specified by psp, otherwise 0 is returned. 263 * The caller should check that the process is not exiting and is not 264 * in the SYS scheduling class. 265 * 266 * This function expects to be called with a valid procset_t. 267 * The set should be checked using checkprocset() before calling 268 * this function. 269 */ 270 int 271 procinset(proc_t *pp, procset_t *psp) 272 { 273 int loperand = 0; 274 int roperand = 0; 275 int lwplinproc = 0; 276 int lwprinproc = 0; 277 kthread_t *tp = proctot(pp); 278 279 switch (psp->p_lidtype) { 280 281 case P_LWPID: 282 if (pp == ttoproc(curthread)) 283 if (getlwpptr(psp->p_lid) != NULL) 284 lwplinproc++; 285 break; 286 287 case P_PID: 288 if (pp->p_pid == psp->p_lid) 289 loperand++; 290 break; 291 292 case P_PPID: 293 if (pp->p_ppid == psp->p_lid) 294 loperand++; 295 break; 296 297 case P_PGID: 298 if (pp->p_pgrp == psp->p_lid) 299 loperand++; 300 break; 301 302 case P_SID: 303 mutex_enter(&pp->p_splock); 304 if (pp->p_sessp->s_sid == psp->p_lid) 305 loperand++; 306 mutex_exit(&pp->p_splock); 307 break; 308 309 case P_CID: 310 ASSERT(tp != NULL); 311 /* This case is broken for now. Need to be fixed XXX */ 312 if (tp->t_cid == psp->p_lid) 313 /* 314 * if (checkcid(psp->p_lid)) 315 */ 316 loperand++; 317 break; 318 319 case P_TASKID: 320 if (pp->p_task->tk_tkid == psp->p_lid) 321 loperand++; 322 break; 323 324 case P_UID: 325 mutex_enter(&pp->p_crlock); 326 if (crgetuid(pp->p_cred) == psp->p_lid) 327 loperand++; 328 mutex_exit(&pp->p_crlock); 329 break; 330 331 case P_GID: 332 mutex_enter(&pp->p_crlock); 333 if (crgetgid(pp->p_cred) == psp->p_lid) 334 loperand++; 335 mutex_exit(&pp->p_crlock); 336 break; 337 338 case P_PROJID: 339 if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 340 loperand++; 341 break; 342 343 case P_POOLID: 344 if (pp->p_pool->pool_id == psp->p_lid) 345 loperand++; 346 break; 347 348 case P_ZONEID: 349 if (pp->p_zone->zone_id == psp->p_lid) 350 loperand++; 351 break; 352 353 case P_CTID: 354 if (PRCTID(pp) == psp->p_lid) 355 loperand++; 356 break; 357 358 case P_ALL: 359 loperand++; 360 break; 361 362 default: 363 #ifdef DEBUG 364 cmn_err(CE_WARN, "procinset called with bad set"); 365 return (0); 366 #else 367 return (0); 368 #endif 369 } 370 371 switch (psp->p_ridtype) { 372 373 case P_LWPID: 374 if (pp == ttoproc(curthread)) 375 if (getlwpptr(psp->p_rid) != NULL) 376 lwprinproc++; 377 break; 378 379 case P_PID: 380 if (pp->p_pid == psp->p_rid) 381 roperand++; 382 break; 383 384 case P_PPID: 385 if (pp->p_ppid == psp->p_rid) 386 roperand++; 387 break; 388 389 case P_PGID: 390 if (pp->p_pgrp == psp->p_rid) 391 roperand++; 392 break; 393 394 case P_SID: 395 mutex_enter(&pp->p_splock); 396 if (pp->p_sessp->s_sid == psp->p_rid) 397 roperand++; 398 mutex_exit(&pp->p_splock); 399 break; 400 401 case P_TASKID: 402 if (pp->p_task->tk_tkid == psp->p_rid) 403 roperand++; 404 break; 405 406 case P_CID: 407 ASSERT(tp != NULL); 408 /* This case is broken for now. Need to be fixed XXX */ 409 if (tp->t_cid == psp->p_rid) 410 /* 411 * if (checkcid(psp->p_rid)) 412 */ 413 roperand++; 414 break; 415 416 case P_UID: 417 mutex_enter(&pp->p_crlock); 418 if (crgetuid(pp->p_cred) == psp->p_rid) 419 roperand++; 420 mutex_exit(&pp->p_crlock); 421 break; 422 423 case P_GID: 424 mutex_enter(&pp->p_crlock); 425 if (crgetgid(pp->p_cred) == psp->p_rid) 426 roperand++; 427 mutex_exit(&pp->p_crlock); 428 break; 429 430 case P_PROJID: 431 if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 432 roperand++; 433 break; 434 435 case P_POOLID: 436 if (pp->p_pool->pool_id == psp->p_rid) 437 roperand++; 438 break; 439 440 case P_ZONEID: 441 if (pp->p_zone->zone_id == psp->p_rid) 442 roperand++; 443 break; 444 445 case P_CTID: 446 if (PRCTID(pp) == psp->p_rid) 447 roperand++; 448 break; 449 450 case P_ALL: 451 roperand++; 452 break; 453 454 default: 455 #ifdef DEBUG 456 cmn_err(CE_WARN, "procinset called with bad set"); 457 return (0); 458 #else 459 return (0); 460 #endif 461 } 462 463 switch (psp->p_op) { 464 465 case POP_DIFF: 466 if (loperand && !lwprinproc && !roperand) 467 return (1); 468 else 469 return (0); 470 471 case POP_AND: 472 if (loperand && roperand) 473 return (1); 474 else 475 return (0); 476 477 case POP_OR: 478 if (loperand || roperand) 479 return (1); 480 else 481 return (0); 482 483 case POP_XOR: 484 if ((loperand && !lwprinproc && !roperand) || 485 (roperand && !lwplinproc && !loperand)) 486 return (1); 487 else 488 return (0); 489 490 default: 491 #ifdef DEBUG 492 cmn_err(CE_WARN, "procinset called with bad set"); 493 return (0); 494 #else 495 return (0); 496 #endif 497 } 498 /* NOTREACHED */ 499 } 500 501 /* 502 * lwpinset returns 1 if the thread pointed to 503 * by tp is in the process set specified by psp and is not in 504 * the sys scheduling class - otherwise 0 is returned. 505 * 506 * This function expects to be called with a valid procset_t. 507 * The set should be checked using checkprocset() before calling 508 * this function. 509 */ 510 int 511 lwpinset(proc_t *pp, procset_t *psp, kthread_t *tp, int *done) 512 { 513 int loperand = 0; 514 int roperand = 0; 515 int lwplinset = 0; 516 int lwprinset = 0; 517 518 ASSERT(ttoproc(tp) == pp); 519 520 /* 521 * If process is in the sys class return (0). 522 */ 523 if (proctot(pp)->t_cid == 0) { 524 return (0); 525 } 526 527 switch (psp->p_lidtype) { 528 529 case P_LWPID: 530 if (tp->t_tid == psp->p_lid) 531 lwplinset ++; 532 break; 533 534 case P_PID: 535 if (pp->p_pid == psp->p_lid) 536 loperand++; 537 break; 538 539 case P_PPID: 540 if (pp->p_ppid == psp->p_lid) 541 loperand++; 542 break; 543 544 case P_PGID: 545 if (pp->p_pgrp == psp->p_lid) 546 loperand++; 547 break; 548 549 case P_SID: 550 mutex_enter(&pp->p_splock); 551 if (pp->p_sessp->s_sid == psp->p_lid) 552 loperand++; 553 mutex_exit(&pp->p_splock); 554 break; 555 556 case P_TASKID: 557 if (pp->p_task->tk_tkid == psp->p_lid) 558 loperand++; 559 break; 560 561 case P_CID: 562 if (tp->t_cid == psp->p_lid) 563 loperand++; 564 break; 565 566 case P_UID: 567 mutex_enter(&pp->p_crlock); 568 if (crgetuid(pp->p_cred) == psp->p_lid) 569 loperand++; 570 mutex_exit(&pp->p_crlock); 571 break; 572 573 case P_GID: 574 mutex_enter(&pp->p_crlock); 575 if (crgetgid(pp->p_cred) == psp->p_lid) 576 loperand++; 577 mutex_exit(&pp->p_crlock); 578 break; 579 580 case P_PROJID: 581 if (pp->p_task->tk_proj->kpj_id == psp->p_lid) 582 loperand++; 583 break; 584 585 case P_POOLID: 586 if (pp->p_pool->pool_id == psp->p_lid) 587 loperand++; 588 break; 589 590 case P_ZONEID: 591 if (pp->p_zone->zone_id == psp->p_lid) 592 loperand++; 593 break; 594 595 case P_CTID: 596 if (PRCTID(pp) == psp->p_lid) 597 loperand++; 598 break; 599 600 case P_ALL: 601 loperand++; 602 break; 603 604 default: 605 #ifdef DEBUG 606 cmn_err(CE_WARN, "lwpinset called with bad set"); 607 return (0); 608 #else 609 return (0); 610 #endif 611 } 612 613 switch (psp->p_ridtype) { 614 615 case P_LWPID: 616 if (tp->t_tid == psp->p_rid) 617 lwprinset ++; 618 break; 619 620 case P_PID: 621 if (pp->p_pid == psp->p_rid) 622 roperand++; 623 break; 624 625 case P_PPID: 626 if (pp->p_ppid == psp->p_rid) 627 roperand++; 628 break; 629 630 case P_PGID: 631 if (pp->p_pgrp == psp->p_rid) 632 roperand++; 633 break; 634 635 case P_SID: 636 mutex_enter(&pp->p_splock); 637 if (pp->p_sessp->s_sid == psp->p_rid) 638 roperand++; 639 mutex_exit(&pp->p_splock); 640 break; 641 642 case P_TASKID: 643 if (pp->p_task->tk_tkid == psp->p_rid) 644 roperand++; 645 break; 646 647 case P_CID: 648 if (tp->t_cid == psp->p_rid) 649 roperand++; 650 break; 651 652 case P_UID: 653 mutex_enter(&pp->p_crlock); 654 if (crgetuid(pp->p_cred) == psp->p_rid) 655 roperand++; 656 mutex_exit(&pp->p_crlock); 657 break; 658 659 case P_GID: 660 mutex_enter(&pp->p_crlock); 661 if (crgetgid(pp->p_cred) == psp->p_rid) 662 roperand++; 663 mutex_exit(&pp->p_crlock); 664 break; 665 666 case P_PROJID: 667 if (pp->p_task->tk_proj->kpj_id == psp->p_rid) 668 roperand++; 669 break; 670 671 case P_POOLID: 672 if (pp->p_pool->pool_id == psp->p_rid) 673 roperand++; 674 break; 675 676 case P_ZONEID: 677 if (pp->p_zone->zone_id == psp->p_rid) 678 roperand++; 679 break; 680 681 case P_CTID: 682 if (PRCTID(pp) == psp->p_rid) 683 roperand++; 684 break; 685 686 case P_ALL: 687 roperand++; 688 break; 689 690 default: 691 #ifdef DEBUG 692 cmn_err(CE_WARN, "lwpinset called with bad set"); 693 return (0); 694 #else 695 return (0); 696 #endif 697 } 698 699 if (lwplinset && lwprinset) 700 *done = 1; 701 702 switch (psp->p_op) { 703 704 case POP_DIFF: 705 if ((loperand || lwplinset) && !(lwprinset || roperand)) 706 return (1); 707 else 708 return (0); 709 710 case POP_AND: 711 if ((loperand || lwplinset) && (roperand || lwprinset)) 712 return (1); 713 else 714 return (0); 715 716 case POP_OR: 717 if (loperand || roperand || lwplinset || lwprinset) 718 return (1); 719 else 720 return (0); 721 722 case POP_XOR: 723 if (((loperand || lwplinset) && 724 !(lwprinset || roperand)) || 725 ((roperand || lwprinset) && 726 !(lwplinset || loperand))) 727 return (1); 728 else 729 return (0); 730 731 default: 732 #ifdef DEBUG 733 cmn_err(CE_WARN, "lwpinset called with bad set"); 734 return (0); 735 #else 736 return (0); 737 #endif 738 } 739 /* NOTREACHED */ 740 } 741 /* 742 * Check for common cases of procsets which specify only the 743 * current process. cur_inset_only() returns B_TRUE when 744 * the current process is the only one in the set. B_FALSE 745 * is returned to indicate that this may not be the case. 746 */ 747 boolean_t 748 cur_inset_only(procset_t *psp) 749 { 750 if (((psp->p_lidtype == P_PID && 751 (psp->p_lid == P_MYID || 752 psp->p_lid == ttoproc(curthread)->p_pid)) || 753 ((psp->p_lidtype == P_LWPID) && 754 (psp->p_lid == P_MYID || 755 psp->p_lid == curthread->t_tid))) && 756 psp->p_op == POP_AND && psp->p_ridtype == P_ALL) 757 return (B_TRUE); 758 759 if (((psp->p_ridtype == P_PID && 760 (psp->p_rid == P_MYID || 761 psp->p_rid == ttoproc(curthread)->p_pid)) || 762 ((psp->p_ridtype == P_LWPID) && 763 (psp->p_rid == P_MYID || 764 psp->p_rid == curthread->t_tid))) && 765 psp->p_op == POP_AND && psp->p_lidtype == P_ALL) 766 return (B_TRUE); 767 768 return (B_FALSE); 769 } 770 771 id_t 772 getmyid(idtype_t idtype) 773 { 774 proc_t *pp; 775 uid_t uid; 776 gid_t gid; 777 pid_t sid; 778 779 pp = ttoproc(curthread); 780 781 switch (idtype) { 782 case P_LWPID: 783 return (curthread->t_tid); 784 785 case P_PID: 786 return (pp->p_pid); 787 788 case P_PPID: 789 return (pp->p_ppid); 790 791 case P_PGID: 792 return (pp->p_pgrp); 793 794 case P_SID: 795 mutex_enter(&pp->p_splock); 796 sid = pp->p_sessp->s_sid; 797 mutex_exit(&pp->p_splock); 798 return (sid); 799 800 case P_TASKID: 801 return (pp->p_task->tk_tkid); 802 803 case P_CID: 804 return (curthread->t_cid); 805 806 case P_UID: 807 mutex_enter(&pp->p_crlock); 808 uid = crgetuid(pp->p_cred); 809 mutex_exit(&pp->p_crlock); 810 return (uid); 811 812 case P_GID: 813 mutex_enter(&pp->p_crlock); 814 gid = crgetgid(pp->p_cred); 815 mutex_exit(&pp->p_crlock); 816 return (gid); 817 818 case P_PROJID: 819 return (pp->p_task->tk_proj->kpj_id); 820 821 case P_POOLID: 822 return (pp->p_pool->pool_id); 823 824 case P_ZONEID: 825 return (pp->p_zone->zone_id); 826 827 case P_CTID: 828 return (PRCTID(pp)); 829 830 case P_ALL: 831 /* 832 * The value doesn't matter for P_ALL. 833 */ 834 return (0); 835 836 default: 837 return (-1); 838 } 839 } 840 841 static kthread_t * 842 getlwpptr(id_t id) 843 { 844 proc_t *p; 845 kthread_t *t; 846 847 if (id == P_MYID) 848 t = curthread; 849 else { 850 p = ttoproc(curthread); 851 mutex_enter(&p->p_lock); 852 t = idtot(p, id); 853 mutex_exit(&p->p_lock); 854 } 855 856 return (t); 857 } 858 859 /* 860 * The dotolwp function locates the LWP(s) specified by the procset structure 861 * pointed to by psp. If funcp is non-NULL then it points to a function 862 * which dotolwp will call for each LWP in the specified set. 863 * LWPIDs specified in the procset structure always refer to lwps in curproc. 864 * The arguments for this function must be "char *arg", and "kthread_t *tp", 865 * where tp is a pointer to the current thread from the set. 866 * Note that these arguments are passed to the function in reversed order 867 * than the order of arguments passed by dotoprocs() to its callback function. 868 * Also note that there are two separate cases where this routine returns zero. 869 * In the first case no mutex is grabbed, in the second the p_lock mutex 870 * is NOT RELEASED. The priocntl code is expecting this behaviour. 871 */ 872 int 873 dotolwp(procset_t *psp, int (*funcp)(), char *arg) 874 { 875 int error = 0; 876 int nfound = 0; 877 kthread_t *tp; 878 proc_t *pp; 879 int done = 0; 880 881 /* 882 * Check that the procset_t is valid. 883 */ 884 error = checkprocset(psp); 885 if (error) { 886 return (error); 887 } 888 889 mutex_enter(&pidlock); 890 891 /* 892 * Check for the special value P_MYID in either operand 893 * and replace it with the correct value. We don't check 894 * for an error return from getmyid() because the idtypes 895 * have been validated by the checkprocset() call above. 896 */ 897 if (psp->p_lid == P_MYID) { 898 psp->p_lid = getmyid(psp->p_lidtype); 899 } 900 if (psp->p_rid == P_MYID) { 901 psp->p_rid = getmyid(psp->p_ridtype); 902 } 903 904 pp = ttoproc(curthread); 905 906 if (procinset(pp, psp)) { 907 mutex_exit(&pidlock); 908 return (0); 909 } 910 mutex_enter(&pp->p_lock); 911 if ((tp = pp->p_tlist) == NULL) { 912 mutex_exit(&pp->p_lock); 913 mutex_exit(&pidlock); 914 return (0); 915 } 916 do { 917 if (lwpinset(pp, psp, tp, &done)) { 918 nfound ++; 919 error = (*funcp)(arg, tp); 920 if (error) { 921 mutex_exit(&pp->p_lock); 922 mutex_exit(&pidlock); 923 return (error); 924 } 925 } 926 } while (((tp = tp->t_forw) != pp->p_tlist) && !done); 927 928 if (nfound == 0) { 929 mutex_exit(&pp->p_lock); 930 mutex_exit(&pidlock); 931 return (ESRCH); 932 } 933 934 mutex_exit(&pidlock); 935 return (error); 936 } 937