Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/os/session.c
+++ new/usr/src/uts/common/os/session.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
20 20 */
21 21 /*
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 27 /* All Rights Reserved */
28 28
29 29
30 -#pragma ident "%Z%%M% %I% %E% SMI"
31 -
32 30 #include <sys/types.h>
33 31 #include <sys/sysmacros.h>
34 32 #include <sys/param.h>
35 33 #include <sys/systm.h>
36 34 #include <sys/file.h>
37 35 #include <sys/vnode.h>
38 36 #include <sys/errno.h>
39 37 #include <sys/signal.h>
40 38 #include <sys/cred.h>
41 39 #include <sys/policy.h>
42 40 #include <sys/conf.h>
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
43 41 #include <sys/debug.h>
44 42 #include <sys/proc.h>
45 43 #include <sys/session.h>
46 44 #include <sys/kmem.h>
47 45 #include <sys/cmn_err.h>
48 46 #include <sys/strsubr.h>
49 47 #include <sys/fs/snode.h>
50 48
51 49 sess_t session0 = {
52 50 &pid0, /* s_sidp */
53 - {0}, /* s_lock */
51 + {{NULL}}, /* s_lock */
54 52 1, /* s_ref */
55 53 B_FALSE, /* s_sighuped */
56 54 B_FALSE, /* s_exit */
57 - 0, /* s_exit_cv */
55 + {0}, /* s_exit_cv */
58 56 0, /* s_cnt */
59 - 0, /* s_cnt_cv */
57 + {0}, /* s_cnt_cv */
60 58 NODEV, /* s_dev */
61 59 NULL, /* s_vp */
62 60 NULL /* s_cred */
63 61 };
64 62
65 63 void
66 64 sess_hold(proc_t *p)
67 65 {
68 66 ASSERT(MUTEX_HELD(&pidlock) || MUTEX_HELD(&p->p_splock));
69 67 mutex_enter(&p->p_sessp->s_lock);
70 68 p->p_sessp->s_ref++;
71 69 mutex_exit(&p->p_sessp->s_lock);
72 70 }
73 71
74 72 void
75 73 sess_rele(sess_t *sp, boolean_t pidlock_held)
76 74 {
77 75 ASSERT(MUTEX_HELD(&pidlock) || !pidlock_held);
78 76
79 77 mutex_enter(&sp->s_lock);
80 78
81 79 ASSERT(sp->s_ref != 0);
82 80 if (--sp->s_ref > 0) {
83 81 mutex_exit(&sp->s_lock);
84 82 return;
85 83 }
86 84 ASSERT(sp->s_ref == 0);
87 85
88 86 /*
89 87 * It's ok to free this session structure now because we know
90 88 * that no one else can have a pointer to it. We know this
91 89 * to be true because the only time that s_ref can possibly
92 90 * be incremented is when pidlock or p_splock is held AND there
93 91 * is a proc_t that points to that session structure. In that
94 92 * case we are guaranteed that the s_ref is at least 1 since there
95 93 * is a proc_t that points to it. So when s_ref finally drops to
96 94 * zero then no one else has a reference (and hence pointer) to
97 95 * this session structure and there is no valid proc_t pointing
98 96 * to this session structure anymore so, no one can acquire a
99 97 * reference (and pointer) to this session structure so it's
100 98 * ok to free it here.
101 99 */
102 100
103 101 if (sp == &session0)
104 102 panic("sp == &session0");
105 103
106 104 /* make sure there are no outstanding holds */
107 105 ASSERT(sp->s_cnt == 0);
108 106
109 107 /* make sure there is no exit in progress */
110 108 ASSERT(!sp->s_exit);
111 109
112 110 /* make sure someone already freed any ctty */
113 111 ASSERT(sp->s_vp == NULL);
114 112 ASSERT(sp->s_dev == NODEV);
115 113
116 114 if (!pidlock_held)
117 115 mutex_enter(&pidlock);
118 116 PID_RELE(sp->s_sidp);
119 117 if (!pidlock_held)
120 118 mutex_exit(&pidlock);
121 119
122 120 mutex_destroy(&sp->s_lock);
123 121 cv_destroy(&sp->s_cnt_cv);
124 122 kmem_free(sp, sizeof (sess_t));
125 123 }
126 124
127 125 sess_t *
128 126 tty_hold(void)
129 127 {
130 128 proc_t *p = curproc;
131 129 sess_t *sp;
132 130 boolean_t got_sig = B_FALSE;
133 131
134 132 /* make sure the caller isn't holding locks they shouldn't */
135 133 ASSERT(MUTEX_NOT_HELD(&pidlock));
136 134
137 135 for (;;) {
138 136 mutex_enter(&p->p_splock); /* protect p->p_sessp */
139 137 sp = p->p_sessp;
140 138 mutex_enter(&sp->s_lock); /* protect sp->* */
141 139
142 140 /* make sure the caller isn't holding locks they shouldn't */
143 141 ASSERT((sp->s_vp == NULL) ||
144 142 MUTEX_NOT_HELD(&sp->s_vp->v_stream->sd_lock));
145 143
146 144 /*
147 145 * If the session leader process is not exiting (and hence
148 146 * not trying to release the session's ctty) then we can
149 147 * safely grab a hold on the current session structure
150 148 * and return it. If on the other hand the session leader
151 149 * process is exiting and clearing the ctty then we'll
152 150 * wait till it's done before we loop around and grab a
153 151 * hold on the session structure.
154 152 */
155 153 if (!sp->s_exit)
156 154 break;
157 155
158 156 /* need to hold the session so it can't be freed */
159 157 sp->s_ref++;
160 158 mutex_exit(&p->p_splock);
161 159
162 160 /* Wait till the session leader is done */
163 161 if (!cv_wait_sig(&sp->s_exit_cv, &sp->s_lock))
164 162 got_sig = B_TRUE;
165 163
166 164 /*
167 165 * Now we need to drop our hold on the session structure,
168 166 * but we can't hold any locks when we do this because
169 167 * sess_rele() may need to acquire pidlock.
170 168 */
171 169 mutex_exit(&sp->s_lock);
172 170 sess_rele(sp, B_FALSE);
173 171
174 172 if (got_sig)
175 173 return (NULL);
176 174 }
177 175
178 176 /* whew, we finally got a hold */
179 177 sp->s_cnt++;
180 178 sp->s_ref++;
181 179 mutex_exit(&sp->s_lock);
182 180 mutex_exit(&p->p_splock);
183 181 return (sp);
184 182 }
185 183
186 184 void
187 185 tty_rele(sess_t *sp)
188 186 {
189 187 /* make sure the caller isn't holding locks they shouldn't */
190 188 ASSERT(MUTEX_NOT_HELD(&pidlock));
191 189
192 190 mutex_enter(&sp->s_lock);
193 191 if ((--sp->s_cnt) == 0)
194 192 cv_broadcast(&sp->s_cnt_cv);
195 193 mutex_exit(&sp->s_lock);
196 194
197 195 sess_rele(sp, B_FALSE);
198 196 }
199 197
200 198 void
201 199 sess_create(void)
202 200 {
203 201 proc_t *p = curproc;
204 202 sess_t *sp, *old_sp;
205 203
206 204 sp = kmem_zalloc(sizeof (sess_t), KM_SLEEP);
207 205
208 206 mutex_init(&sp->s_lock, NULL, MUTEX_DEFAULT, NULL);
209 207 cv_init(&sp->s_cnt_cv, NULL, CV_DEFAULT, NULL);
210 208
211 209 /*
212 210 * we need to grap p_lock to protect p_pgidp because
213 211 * /proc looks at p_pgidp while holding only p_lock.
214 212 *
215 213 * we don't need to hold p->p_sessp->s_lock or get a hold on the
216 214 * session structure since we're not actually updating any of
217 215 * the contents of the old session structure.
218 216 */
219 217 mutex_enter(&pidlock);
220 218 mutex_enter(&p->p_lock);
221 219 mutex_enter(&p->p_splock);
222 220
223 221 pgexit(p);
224 222
225 223 sp->s_sidp = p->p_pidp;
226 224 sp->s_ref = 1;
227 225 sp->s_dev = NODEV;
228 226
229 227 old_sp = p->p_sessp;
230 228 p->p_sessp = sp;
231 229
232 230 pgjoin(p, p->p_pidp);
233 231 PID_HOLD(p->p_pidp);
234 232
235 233 mutex_exit(&p->p_splock);
236 234 mutex_exit(&p->p_lock);
237 235 mutex_exit(&pidlock);
238 236
239 237 sess_rele(old_sp, B_FALSE);
240 238 }
241 239
242 240 /*
243 241 * Note that sess_ctty_clear() resets all the fields in the session
244 242 * structure but doesn't release any holds or free any objects
245 243 * that the session structure might currently point to. it is the
246 244 * callers responsibility to do this.
247 245 */
248 246 static void
249 247 sess_ctty_clear(sess_t *sp, stdata_t *stp)
250 248 {
251 249 /*
252 250 * Assert that we hold all the necessary locks. We also need
253 251 * to be holding proc_t->p_splock for the process associated
254 252 * with this session, but since we don't have a proc pointer
255 253 * passed in we can't assert this here.
256 254 */
257 255 ASSERT(MUTEX_HELD(&stp->sd_lock) && MUTEX_HELD(&pidlock) &&
258 256 MUTEX_HELD(&sp->s_lock));
259 257
260 258 /* reset the session structure members to defaults */
261 259 sp->s_sighuped = B_FALSE;
262 260 sp->s_dev = NODEV;
263 261 sp->s_vp = NULL;
264 262 sp->s_cred = NULL;
265 263
266 264 /* reset the stream session and group pointers */
267 265 stp->sd_pgidp = NULL;
268 266 stp->sd_sidp = NULL;
269 267 }
270 268
271 269 static void
272 270 sess_ctty_set(proc_t *p, sess_t *sp, stdata_t *stp)
273 271 {
274 272 cred_t *crp;
275 273
276 274 /* Assert that we hold all the necessary locks. */
277 275 ASSERT(MUTEX_HELD(&stp->sd_lock) && MUTEX_HELD(&pidlock) &&
278 276 MUTEX_HELD(&p->p_splock) && MUTEX_HELD(&sp->s_lock));
279 277
280 278 /* get holds on structures */
281 279 mutex_enter(&p->p_crlock);
282 280 crhold(crp = p->p_cred);
283 281 mutex_exit(&p->p_crlock);
284 282 PID_HOLD(sp->s_sidp); /* requires pidlock */
285 283 PID_HOLD(sp->s_sidp); /* requires pidlock */
286 284
287 285 /* update the session structure members */
288 286 sp->s_vp = makectty(stp->sd_vnode);
289 287 sp->s_dev = sp->s_vp->v_rdev;
290 288 sp->s_cred = crp;
291 289
292 290 /* update the stream emebers */
293 291 stp->sd_flag |= STRISTTY; /* just to be sure */
294 292 stp->sd_sidp = sp->s_sidp;
295 293 stp->sd_pgidp = sp->s_sidp;
296 294 }
297 295
298 296 int
299 297 strctty(stdata_t *stp)
300 298 {
301 299 sess_t *sp;
302 300 proc_t *p = curproc;
303 301 boolean_t got_sig = B_FALSE;
304 302
305 303 /*
306 304 * We are going to try to make stp the default ctty for the session
307 305 * associated with curproc. Not only does this require holding a
308 306 * bunch of locks but it also requires waiting for any outstanding
309 307 * holds on the session structure (acquired via tty_hold()) to be
310 308 * released. Hence, we have the following for(;;) loop that will
311 309 * acquire our locks, do some sanity checks, and wait for the hold
312 310 * count on the session structure to hit zero. If we get a signal
313 311 * while waiting for outstanding holds to be released then we abort
314 312 * the operation and return.
315 313 */
316 314 for (;;) {
317 315 mutex_enter(&stp->sd_lock); /* protects sd_pgidp/sd_sidp */
318 316 mutex_enter(&pidlock); /* protects p_pidp */
319 317 mutex_enter(&p->p_splock); /* protects p_sessp */
320 318 sp = p->p_sessp;
321 319 mutex_enter(&sp->s_lock); /* protects sp->* */
322 320
323 321 if (((stp->sd_flag & (STRHUP|STRDERR|STWRERR|STPLEX)) != 0) ||
324 322 (stp->sd_sidp != NULL) || /* stp already ctty? */
325 323 (p->p_pidp != sp->s_sidp) || /* we're not leader? */
326 324 (sp->s_vp != NULL)) { /* session has ctty? */
327 325 mutex_exit(&sp->s_lock);
328 326 mutex_exit(&p->p_splock);
329 327 mutex_exit(&pidlock);
330 328 mutex_exit(&stp->sd_lock);
331 329 return (ENOTTY);
332 330 }
333 331
334 332 /* sanity check. we can't be exiting right now */
335 333 ASSERT(!sp->s_exit);
336 334
337 335 /*
338 336 * If no one else has a hold on this session structure
339 337 * then we now have exclusive access to it, so break out
340 338 * of this loop and update the session structure.
341 339 */
342 340 if (sp->s_cnt == 0)
343 341 break;
344 342
345 343 /* need to hold the session so it can't be freed */
346 344 sp->s_ref++;
347 345
348 346 /* ain't locking order fun? */
349 347 mutex_exit(&p->p_splock);
350 348 mutex_exit(&pidlock);
351 349 mutex_exit(&stp->sd_lock);
352 350
353 351 if (!cv_wait_sig(&sp->s_cnt_cv, &sp->s_lock))
354 352 got_sig = B_TRUE;
355 353 mutex_exit(&sp->s_lock);
356 354 sess_rele(sp, B_FALSE);
357 355
358 356 if (got_sig)
359 357 return (EINTR);
360 358 }
361 359
362 360 /* set the session ctty bindings */
363 361 sess_ctty_set(p, sp, stp);
364 362
365 363 mutex_exit(&sp->s_lock);
366 364 mutex_exit(&p->p_splock);
367 365 mutex_exit(&pidlock);
368 366 mutex_exit(&stp->sd_lock);
369 367 return (0);
370 368 }
371 369
372 370 /*
373 371 * freectty_lock() attempts to acquire the army of locks required to free
374 372 * the ctty associated with a given session leader process. If it returns
375 373 * successfully the following locks will be held:
376 374 * sd_lock, pidlock, p_splock, s_lock
377 375 *
378 376 * as a secondary bit of convenience, freectty_lock() will also return
379 377 * pointers to the session, ctty, and ctty stream associated with the
380 378 * specified session leader process.
381 379 */
382 380 static boolean_t
383 381 freectty_lock(proc_t *p, sess_t **spp, vnode_t **vpp, stdata_t **stpp,
384 382 boolean_t at_exit)
385 383 {
386 384 sess_t *sp;
387 385 vnode_t *vp;
388 386 stdata_t *stp;
389 387
390 388 mutex_enter(&pidlock); /* protect p_pidp */
391 389 mutex_enter(&p->p_splock); /* protect p->p_sessp */
392 390 sp = p->p_sessp;
393 391 mutex_enter(&sp->s_lock); /* protect sp->* */
394 392
395 393 if ((sp->s_sidp != p->p_pidp) || /* we're not leader? */
396 394 (sp->s_vp == NULL)) { /* no ctty? */
397 395 mutex_exit(&sp->s_lock);
398 396 mutex_exit(&p->p_splock);
399 397 mutex_exit(&pidlock);
400 398 return (B_FALSE);
401 399 }
402 400
403 401 vp = sp->s_vp;
404 402 stp = sp->s_vp->v_stream;
405 403
406 404 if (at_exit) {
407 405 /* stop anyone else calling tty_hold() */
408 406 sp->s_exit = B_TRUE;
409 407 } else {
410 408 /*
411 409 * due to locking order we have to grab stp->sd_lock before
412 410 * grabbing all the other proc/session locks. but after we
413 411 * drop all our current locks it's possible that someone
414 412 * could come in and change our current session or close
415 413 * the current ctty (vp) there by making sp or stp invalid.
416 414 * (a VN_HOLD on vp won't protect stp because that only
417 415 * prevents the vnode from being freed not closed.) so
418 416 * to prevent this we bump s_ref and s_cnt here.
419 417 *
420 418 * course this doesn't matter if we're the last thread in
421 419 * an exiting process that is the session leader, since no
422 420 * one else can change our session or free our ctty.
423 421 */
424 422 sp->s_ref++; /* hold the session structure */
425 423 sp->s_cnt++; /* protect vp and stp */
426 424 }
427 425
428 426 /* drop our session locks */
429 427 mutex_exit(&sp->s_lock);
430 428 mutex_exit(&p->p_splock);
431 429 mutex_exit(&pidlock);
432 430
433 431 /* grab locks in the right order */
434 432 mutex_enter(&stp->sd_lock); /* protects sd_pgidp/sd_sidp */
435 433 mutex_enter(&pidlock); /* protect p_pidp */
436 434 mutex_enter(&p->p_splock); /* protects p->p_sessp */
437 435 mutex_enter(&sp->s_lock); /* protects sp->* */
438 436
439 437 /* if the session has changed, abort mission */
440 438 if (sp != p->p_sessp) {
441 439 /*
442 440 * this can't happen during process exit since we're the
443 441 * only thread in the process and we sure didn't change
444 442 * our own session at this point.
445 443 */
446 444 ASSERT(!at_exit);
447 445
448 446 /* release our locks and holds */
449 447 mutex_exit(&sp->s_lock);
450 448 mutex_exit(&p->p_splock);
451 449 mutex_exit(&pidlock);
452 450 mutex_exit(&stp->sd_lock);
453 451 tty_rele(sp);
454 452 return (B_FALSE);
455 453 }
456 454
457 455 /*
458 456 * sanity checks. none of this should have changed since we had
459 457 * holds on the current ctty.
460 458 */
461 459 ASSERT(sp->s_sidp == p->p_pidp); /* we're the leader */
462 460 ASSERT(sp->s_vp != NULL); /* a ctty exists */
463 461 ASSERT(vp == sp->s_vp);
464 462 ASSERT(stp == sp->s_vp->v_stream);
465 463
466 464 /* release our holds */
467 465 if (!at_exit) {
468 466 if ((--(sp)->s_cnt) == 0)
469 467 cv_broadcast(&sp->s_cnt_cv);
470 468 sp->s_ref--;
471 469 ASSERT(sp->s_ref > 0);
472 470 }
473 471
474 472 /* return our pointers */
475 473 *spp = sp;
476 474 *vpp = vp;
477 475 *stpp = stp;
478 476
479 477 return (B_TRUE);
480 478 }
481 479
482 480 /*
483 481 * Returns B_FALSE if no signal is sent to the process group associated with
484 482 * this ctty. Returns B_TRUE if a signal is sent to the process group.
485 483 * If it return B_TRUE it also means that all the locks we were holding
486 484 * were dropped so that we could send the signal.
487 485 */
488 486 static boolean_t
489 487 freectty_signal(proc_t *p, sess_t *sp, stdata_t *stp, boolean_t at_exit)
490 488 {
491 489 /* Assert that we hold all the necessary locks. */
492 490 ASSERT(MUTEX_HELD(&stp->sd_lock) && MUTEX_HELD(&pidlock) &&
493 491 MUTEX_HELD(&p->p_splock) && MUTEX_HELD(&sp->s_lock));
494 492
495 493 /* check if we already signaled this group */
496 494 if (sp->s_sighuped)
497 495 return (B_FALSE);
498 496
499 497 sp->s_sighuped = B_TRUE;
500 498
501 499 if (!at_exit) {
502 500 /*
503 501 * once again, we're about to drop our army of locks and we
504 502 * don't want sp or stp to be freed. (see the comment in
505 503 * freectty_lock())
506 504 */
507 505 sp->s_ref++; /* hold the session structure */
508 506 sp->s_cnt++; /* protect vp and stp */
509 507 }
510 508
511 509 /* can't hold these locks while calling pgsignal() */
512 510 mutex_exit(&sp->s_lock);
513 511 mutex_exit(&p->p_splock);
514 512 mutex_exit(&pidlock);
515 513
516 514 /* signal anyone in the foreground process group */
517 515 pgsignal(stp->sd_pgidp, SIGHUP);
518 516
519 517 /* signal anyone blocked in poll on this stream */
520 518 if (!(stp->sd_flag & STRHUP))
521 519 strhup(stp);
522 520
523 521 mutex_exit(&stp->sd_lock);
524 522
525 523 /* release our holds */
526 524 if (!at_exit)
527 525 tty_rele(sp);
528 526
529 527 return (B_TRUE);
530 528 }
531 529
532 530 int
533 531 freectty(boolean_t at_exit)
534 532 {
535 533 proc_t *p = curproc;
536 534 stdata_t *stp;
537 535 vnode_t *vp;
538 536 cred_t *cred;
539 537 sess_t *sp;
540 538 struct pid *pgidp, *sidp;
541 539 boolean_t got_sig = B_FALSE;
542 540
543 541 /*
544 542 * If the current process is a session leader we are going to
545 543 * try to release the ctty associated our current session. To
546 544 * do this we need to acquire a bunch of locks, signal any
547 545 * processes in the forground that are associated with the ctty,
548 546 * and make sure no one has any outstanding holds on the current
549 547 * session * structure (acquired via tty_hold()). Hence, we have
550 548 * the following for(;;) loop that will do all this work for
551 549 * us and break out when the hold count on the session structure
552 550 * hits zero.
553 551 */
554 552 for (;;) {
555 553 if (!freectty_lock(p, &sp, &vp, &stp, at_exit))
556 554 return (EIO);
557 555
558 556 if (freectty_signal(p, sp, stp, at_exit)) {
559 557 /* loop around to re-acquire locks */
560 558 continue;
561 559 }
562 560
563 561 /*
564 562 * Only a session leader process can free a ctty. So if
565 563 * we've made it here we know we're a session leader and
566 564 * if we're not actively exiting it impossible for another
567 565 * thread in this process to be exiting. (Because that
568 566 * thread would have already stopped all other threads
569 567 * in the current process.)
570 568 */
571 569 ASSERT(at_exit || !sp->s_exit);
572 570
573 571 /*
574 572 * If no one else has a hold on this session structure
575 573 * then we now have exclusive access to it, so break out
576 574 * of this loop and update the session structure.
577 575 */
578 576 if (sp->s_cnt == 0)
579 577 break;
580 578
581 579 if (!at_exit) {
582 580 /* need to hold the session so it can't be freed */
583 581 sp->s_ref++;
584 582 }
585 583
586 584 /* ain't locking order fun? */
587 585 mutex_exit(&p->p_splock);
588 586 mutex_exit(&pidlock);
589 587 mutex_exit(&stp->sd_lock);
590 588
591 589 if (at_exit) {
592 590 /*
593 591 * if we're exiting then we can't allow this operation
594 592 * to fail so we do a cw_wait() instead of a
595 593 * cv_wait_sig(). if there are threads with active
596 594 * holds on this ctty that are blocked, then
597 595 * they should only be blocked in a cv_wait_sig()
598 596 * and hopefully they were in the foreground process
599 597 * group and recieved the SIGHUP we sent above. of
600 598 * course it's possible that they weren't in the
601 599 * foreground process group and didn't get our
602 600 * signal (or they could be stopped by job control
603 601 * in which case our signal wouldn't matter until
604 602 * they are restarted). in this case we won't
605 603 * exit until someone else sends them a signal.
606 604 */
607 605 cv_wait(&sp->s_cnt_cv, &sp->s_lock);
608 606 mutex_exit(&sp->s_lock);
609 607 continue;
610 608 }
611 609
612 610 if (!cv_wait_sig(&sp->s_cnt_cv, &sp->s_lock)) {
613 611 got_sig = B_TRUE;
614 612 }
615 613
616 614 mutex_exit(&sp->s_lock);
617 615 sess_rele(sp, B_FALSE);
618 616
619 617 if (got_sig)
620 618 return (EINTR);
621 619 }
622 620 ASSERT(sp->s_cnt == 0);
623 621
624 622 /* save some pointers for later */
625 623 cred = sp->s_cred;
626 624 pgidp = stp->sd_pgidp;
627 625 sidp = stp->sd_sidp;
628 626
629 627 /* clear the session ctty bindings */
630 628 sess_ctty_clear(sp, stp);
631 629
632 630 /* wake up anyone blocked in tty_hold() */
633 631 if (at_exit) {
634 632 ASSERT(sp->s_exit);
635 633 sp->s_exit = B_FALSE;
636 634 cv_broadcast(&sp->s_exit_cv);
637 635 }
638 636
639 637 /* we can drop these locks now */
640 638 mutex_exit(&sp->s_lock);
641 639 mutex_exit(&p->p_splock);
642 640 mutex_exit(&pidlock);
643 641 mutex_exit(&stp->sd_lock);
644 642
645 643 /* This is the only remaining thread with access to this vnode */
646 644 (void) VOP_CLOSE(vp, 0, 1, (offset_t)0, cred, NULL);
647 645 VN_RELE(vp);
648 646 crfree(cred);
649 647
650 648 /* release our holds on assorted structures and return */
651 649 mutex_enter(&pidlock);
652 650 PID_RELE(pgidp);
653 651 PID_RELE(sidp);
654 652 mutex_exit(&pidlock);
655 653
656 654 return (1);
657 655 }
658 656
659 657 /*
660 658 * ++++++++++++++++++++++++
661 659 * ++ SunOS4.1 Buyback ++
662 660 * ++++++++++++++++++++++++
663 661 *
664 662 * vhangup: Revoke access of the current tty by all processes
665 663 * Used by privileged users to give a "clean" terminal at login
666 664 */
667 665 int
668 666 vhangup(void)
669 667 {
670 668 if (secpolicy_sys_config(CRED(), B_FALSE) != 0)
671 669 return (set_errno(EPERM));
672 670 /*
673 671 * This routine used to call freectty() under a condition that
674 672 * could never happen. So this code has never actually done
675 673 * anything, and evidently nobody has ever noticed.
676 674 */
677 675 return (0);
678 676 }
679 677
680 678 dev_t
681 679 cttydev(proc_t *pp)
682 680 {
683 681 sess_t *sp;
684 682 dev_t dev;
685 683
686 684 mutex_enter(&pp->p_splock); /* protects p->p_sessp */
687 685 sp = pp->p_sessp;
688 686
689 687 #ifdef DEBUG
690 688 mutex_enter(&sp->s_lock); /* protects sp->* */
691 689 if (sp->s_vp == NULL)
692 690 ASSERT(sp->s_dev == NODEV);
693 691 else
694 692 ASSERT(sp->s_dev != NODEV);
695 693 mutex_exit(&sp->s_lock);
696 694 #endif /* DEBUG */
697 695
698 696 dev = sp->s_dev;
699 697 mutex_exit(&pp->p_splock);
700 698 return (dev);
701 699 }
702 700
703 701 void
704 702 ctty_clear_sighuped(void)
705 703 {
706 704 ASSERT(MUTEX_HELD(&pidlock) || MUTEX_HELD(&curproc->p_splock));
707 705 curproc->p_sessp->s_sighuped = B_FALSE;
708 706 }
↓ open down ↓ |
639 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX