1: /*
   2:  *	SCCS id	@(#)sys4.c	2.1 (Berkeley)	9/4/83
   3:  */
   4: 
   5: #include "param.h"
   6: #include <sys/systm.h>
   7: #include <sys/dir.h>
   8: #include <sys/user.h>
   9: #include <sys/reg.h>
  10: #include <sys/inode.h>
  11: #include <sys/proc.h>
  12: #include <sys/timeb.h>
  13: #include <sys/quota.h>
  14: #ifdef  UCB_AUTOBOOT
  15: #include <sys/reboot.h>
  16: #include <sys/filsys.h>
  17: #endif
  18: 
  19: /*
  20:  * Everything in this file is a routine implementing a system call.
  21:  */
  22: 
  23: /*
  24:  * return the current time (old-style entry)
  25:  */
  26: gtime()
  27: {
  28:     u.u_r.r_time = time;
  29: }
  30: 
  31: /*
  32:  * New time entry-- return TOD with milliseconds, timezone,
  33:  * DST flag
  34:  */
  35: ftime()
  36: {
  37:     struct a {
  38:         struct  timeb *tp;
  39:     };
  40:     struct timeb t;
  41:     register unsigned ms;
  42: 
  43:     (void) _spl7();
  44:     t.time = time;
  45:     ms = lbolt;
  46:     (void) _spl0();
  47:     if (ms > hz) {
  48:         ms -= hz;
  49:         t.time++;
  50:     }
  51:     t.millitm = (1000*ms)/hz;
  52:     t.timezone = timezone;
  53:     t.dstflag = dstflag;
  54:     if (copyout((caddr_t)&t, (caddr_t)(((struct a *) u.u_ap)->tp), sizeof(t)) < 0)
  55:         u.u_error = EFAULT;
  56: }
  57: 
  58: /*
  59:  * Set the time
  60:  */
  61: stime()
  62: {
  63:     register struct a {
  64:         time_t  time;
  65:     } *uap;
  66: 
  67:     if (suser()) {
  68:         uap = (struct a *)u.u_ap;
  69:         bootime += uap->time - time;
  70:         time = uap->time;
  71:     }
  72: }
  73: 
  74: setuid()
  75: {
  76:     register uid;
  77:     struct a {
  78:         int uid;
  79:     };
  80: 
  81:     uid = ((struct a *) u.u_ap)->uid;
  82:     if (u.u_ruid == uid || u.u_uid == uid || suser()) {
  83:         u.u_uid = uid;
  84:         u.u_procp->p_uid = uid;
  85:         u.u_ruid = uid;
  86:     }
  87: }
  88: 
  89: getuid()
  90: {
  91:     u.u_r.r_val1 = u.u_ruid;
  92:     u.u_r.r_val2 = u.u_uid;
  93: }
  94: 
  95: setgid()
  96: {
  97:     register gid;
  98:     struct a {
  99:         int gid;
 100:     };
 101: 
 102:     gid = ((struct a *) u.u_ap)->gid;
 103:     if (u.u_rgid == gid || u.u_gid == gid || suser()) {
 104:         u.u_gid = gid;
 105:         u.u_rgid = gid;
 106:     }
 107: }
 108: 
 109: getgid()
 110: {
 111:     u.u_r.r_val1 = u.u_rgid;
 112:     u.u_r.r_val2 = u.u_gid;
 113: }
 114: 
 115: getpid()
 116: {
 117:     u.u_r.r_val1 = u.u_procp->p_pid;
 118:     u.u_r.r_val2 = u.u_procp->p_ppid;
 119: }
 120: 
 121: nice()
 122: {
 123:     register oldnice, newnice;
 124:     register struct a {
 125:         int niceness;
 126:     } *uap;
 127: 
 128:     uap = (struct a *)u.u_ap;
 129: 
 130:     oldnice = u.u_procp->p_nice;
 131:     newnice = oldnice + uap->niceness;
 132:     if (newnice >= 2 * NZERO)
 133:         newnice = 2 * NZERO - 1;
 134:     if (newnice < 0)
 135:         newnice = 0;
 136:     if (newnice < oldnice && !suser())  /* tsk tsk */
 137:         newnice = oldnice;
 138:     u.u_procp->p_nice = newnice;
 139: }
 140: 
 141: /*
 142:  * Unlink system call.
 143:  * Hard to avoid races here, especially
 144:  * in unlinking directories.
 145:  */
 146: unlink()
 147: {
 148:     register struct inode *ip, *pp;
 149: 
 150: #ifndef UCB_SYMLINKS
 151:     pp = namei(uchar, DELETE);
 152: #else
 153:     pp = namei(uchar, DELETE, 0);
 154: #endif
 155:     if (pp == NULL)
 156:         return;
 157:     /*
 158: 	 * Check for unlink(".")
 159: 	 * to avoid hanging on the iget
 160: 	 */
 161:     if (pp->i_number == u.u_dent.d_ino) {
 162:         ip = pp;
 163:         ip->i_count++;
 164:     } else
 165:         ip = iget(pp->i_dev, u.u_dent.d_ino);
 166:     if (ip == NULL)
 167:         goto out1;
 168: #ifdef UCB_QUOTAS
 169:     /*
 170: 	 * Only superuser can unlink directories or a quota
 171: 	 */
 172:     if (((ip->i_mode & IFMT) == IFDIR || isquot(ip)) && !suser())
 173: #else
 174:     if ((ip->i_mode&IFMT)==IFDIR && !suser())
 175: #endif
 176:         goto out;
 177:     /*
 178: 	 * Don't unlink a mounted file.
 179: 	 */
 180:     if (ip->i_dev != pp->i_dev) {
 181:         u.u_error = EBUSY;
 182:         goto out;
 183:     }
 184:     if (ip->i_flag&ITEXT)
 185:         xrele(ip);  /* try once to free text */
 186:     if (ip->i_flag&ITEXT && ip->i_nlink==1) {
 187:         u.u_error = ETXTBSY;
 188:         goto out;
 189:     }
 190:     /*
 191: 	 * sticky bit on a directory means only
 192: 	 * owner or super-user may remove file - for /tmp, etc.
 193: 	 */
 194:     if ((pp->i_mode & ISVTX) && !own(ip))
 195:         goto out;
 196:     u.u_offset -= sizeof(struct direct);
 197:     u.u_base = (caddr_t)&u.u_dent;
 198:     u.u_count = sizeof(struct direct);
 199:     u.u_dent.d_ino = 0;
 200:     writei(pp);
 201:     ip->i_nlink--;
 202: #ifdef UCB_QUOTAS
 203:     /*
 204: 	 * make unlinks force deallocation of blocks in quota
 205: 	 */
 206:     if (ip->i_nlink <= 0)
 207:         qcopy(pp, ip);
 208: #endif
 209:     ip->i_flag |= ICHG;
 210: 
 211: out:
 212:     iput(ip);
 213: out1:
 214:     iput(pp);
 215: }
 216: chdir()
 217: {
 218:     chdirec(&u.u_cdir);
 219: }
 220: 
 221: chroot()
 222: {
 223:     if (suser())
 224:         chdirec(&u.u_rdir);
 225: }
 226: 
 227: chdirec(ipp)
 228: register struct inode **ipp;
 229: {
 230:     register struct inode *ip;
 231: 
 232: #ifndef UCB_SYMLINKS
 233:     ip = namei(uchar, LOOKUP);
 234: #else
 235:     ip = namei(uchar, LOOKUP, 1);
 236: #endif
 237:     if (ip == NULL)
 238:         return;
 239:     if ((ip->i_mode&IFMT) != IFDIR) {
 240:         u.u_error = ENOTDIR;
 241:         goto bad;
 242:     }
 243:     if (access(ip, IEXEC))
 244:         goto bad;
 245:     prele(ip);
 246:     if (*ipp) {
 247:         plock(*ipp);
 248:         iput(*ipp);
 249:     }
 250:     *ipp = ip;
 251:     return;
 252: 
 253: bad:
 254:     iput(ip);
 255: }
 256: 
 257: chmod()
 258: {
 259:     register struct inode *ip;
 260:     register struct a {
 261:         char    *fname;
 262:         int fmode;
 263:     } *uap;
 264: 
 265: #ifndef UCB_SYMLINKS
 266:     if ((ip = owner()) == NULL)
 267: #else
 268:     if ((ip = owner(1)) == NULL)
 269: #endif
 270:         return;
 271:     ip->i_mode &= ~07777;
 272:     uap = (struct a *)u.u_ap;
 273:     if (u.u_uid)
 274:         uap->fmode &= ~ISVTX;
 275:     ip->i_mode |= uap->fmode & 07777;
 276:     ip->i_flag |= ICHG;
 277:     if (ip->i_flag & ITEXT && (ip->i_mode & ISVTX)==0)
 278:         xrele(ip);
 279:     iput(ip);
 280: }
 281: 
 282: chown()
 283: {
 284:     register struct inode *ip;
 285:     register struct a {
 286:         char    *fname;
 287:         int uid;
 288:         int gid;
 289:     } *uap;
 290: 
 291: #ifndef UCB_SYMLINKS
 292:     if (!suser() || (ip = namei(uchar, LOOKUP)) == NULL)
 293: #else
 294:     if (!suser() || (ip = namei(uchar, LOOKUP, 0)) == NULL)
 295: #endif
 296:         return;
 297:     uap = (struct a *)u.u_ap;
 298:     ip->i_uid = uap->uid;
 299:     ip->i_gid = uap->gid;
 300:     ip->i_flag |= ICHG;
 301:     iput(ip);
 302: }
 303: 
 304: ssig()
 305: {
 306: #ifdef  MENLO_JCL
 307:     register int (*f)();
 308:     register struct a {
 309:         int signo;
 310:         int (*fun)();
 311:     } *uap;
 312:     register struct proc *p = u.u_procp;
 313:     register a;
 314:     long sigmask;
 315: 
 316:     uap = (struct a *)u.u_ap;
 317:     a = uap->signo & SIGNUMMASK;
 318:     f = uap->fun;
 319:     if (a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP ||
 320:         a==SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) {
 321:         u.u_error = EINVAL;
 322:         return;
 323:     }
 324:     if ((uap->signo &~ SIGNUMMASK) || (f != SIG_DFL && f != SIG_IGN &&
 325:         SIGISDEFER(f)))
 326:         p->p_flag |= SNUSIG;
 327:     /*
 328: 	 * Don't clobber registers if we are to simulate
 329: 	 * a ret+rti.
 330: 	 */
 331:     if ((uap->signo&SIGDORTI) == 0)
 332:         u.u_r.r_val1 = (int)u.u_signal[a];
 333:     /*
 334: 	 * Change setting atomically.
 335: 	 */
 336:     (void) _spl6();
 337:     sigmask = 1L << (a-1);
 338:     if (f == SIG_IGN)
 339:         p->p_sig &= ~sigmask;       /* never to be seen again */
 340:     u.u_signal[a] = f;
 341:     if (f != SIG_DFL && f != SIG_IGN && f != SIG_HOLD)
 342:         f = SIG_CATCH;
 343:     if ((int)f & 1)
 344:         p->p_siga0 |= sigmask;
 345:     else
 346:         p->p_siga0 &= ~sigmask;
 347:     if ((int)f & 2)
 348:         p->p_siga1 |= sigmask;
 349:     else
 350:         p->p_siga1 &= ~sigmask;
 351:     (void) _spl0();
 352:     /*
 353: 	 * Now handle options.
 354: 	 */
 355:     if (uap->signo & SIGDOPAUSE) {
 356:         /*
 357: 		 * Simulate a PDP11 style wait instrution which
 358: 		 * atomically lowers priority, enables interrupts
 359: 		 * and hangs.
 360: 		 */
 361:         pause();
 362:         /*NOTREACHED*/
 363:     }
 364:     if (uap->signo & SIGDORTI)
 365:         u.u_eosys = SIMULATERTI;
 366: #else
 367:     register a;
 368:     struct a {
 369:         int signo;
 370:         int fun;
 371:     } *uap;
 372: 
 373:     uap = (struct a *)u.u_ap;
 374:     a = uap->signo;
 375:     if (a<=0 || a>=NSIG || a==SIGKILL) {
 376:         u.u_error = EINVAL;
 377:         return;
 378:     }
 379:     u.u_r.r_val1 = u.u_signal[a];
 380:     u.u_signal[a] = uap->fun;
 381:     u.u_procp->p_sig &= ~(1<<(a-1));
 382: #endif
 383: }
 384: 
 385: kill()
 386: {
 387: #ifdef  MENLO_JCL
 388:     register struct proc *p;
 389:     register a, sig;
 390:     register struct a {
 391:         int pid;
 392:         int signo;
 393:     } *uap;
 394:     int f, priv;
 395: 
 396:     f = 0;
 397:     priv = 0;
 398:     uap = (struct a *)u.u_ap;
 399:     a = uap->pid;
 400:     sig = uap->signo;
 401:     if (sig < 0)
 402:         /*
 403: 		 * A negative signal means send to process group.
 404: 		 */
 405:         uap->signo = -uap->signo;
 406:     if (uap->signo == 0 || uap->signo > NSIG) {
 407:         u.u_error = EINVAL;
 408:         return;
 409:     }
 410:     if (a > 0 && sig > 0) {
 411:         for(p = &proc[0]; p <= maxproc; p++)
 412:             if ( p->p_pid == a)
 413:                 goto found;
 414:         p = 0;
 415: found:
 416:         if (p == 0 || u.u_uid && u.u_uid != p->p_uid) {
 417:             u.u_error = ESRCH;
 418:             return;
 419:         }
 420:         psignal(p, uap->signo);
 421:         return;
 422:     }
 423:     if (a==-1 && u.u_uid==0) {
 424:         priv++;
 425:         a = 0;
 426:         sig = -1;       /* like sending to pgrp */
 427:     } else if (a==0) {
 428:         /*
 429: 		 * Zero process id means send to my process group.
 430: 		 */
 431:         sig = -1;
 432:         a = u.u_procp->p_pgrp;
 433:         if (a == 0) {
 434:             u.u_error = EINVAL;
 435:             return;
 436:         }
 437:     }
 438:     for(p = &proc[0]; p <= maxproc; p++) {
 439:         if (p->p_stat == NULL)
 440:             continue;
 441:         if (sig > 0) {
 442:             if (p->p_pid != a)
 443:                 continue;
 444:         } else if (p->p_pgrp!=a && priv==0 || p<=&proc[1] ||
 445:             (priv && p==u.u_procp))
 446:             continue;
 447:         if (u.u_uid != 0 && u.u_uid != p->p_uid &&
 448:             (uap->signo != SIGCONT || !inferior(p)))
 449:             continue;
 450:         f++;
 451:         psignal(p, uap->signo);
 452:     }
 453: #else
 454:     register struct proc *p, *q;
 455:     register a;
 456:     register struct a {
 457:         int pid;
 458:         int signo;
 459:     } *uap;
 460:     int f, priv;
 461: 
 462:     f = 0;
 463:     uap = (struct a *)u.u_ap;
 464:     a = uap->pid;
 465:     priv = 0;
 466:     if (a==-1 && u.u_uid==0) {
 467:         priv++;
 468:         a = 0;
 469:     }
 470:     q = u.u_procp;
 471:     for(p = &proc[0]; p <= maxproc; p++) {
 472:         if (p->p_stat == NULL)
 473:             continue;
 474:         if (a != 0 && p->p_pid != a)
 475:             continue;
 476:         if (a==0 && ((p->p_pgrp!=q->p_pgrp&&priv==0) || p<=&proc[1]))
 477:             continue;
 478:         if (priv && p==u.u_procp)
 479:             continue;
 480:         if (u.u_uid != 0 && u.u_uid != p->p_uid)
 481:             continue;
 482:         f++;
 483:         psignal(p, uap->signo);
 484:     }
 485: #endif
 486:     if (f == 0)
 487:         u.u_error = ESRCH;
 488: }
 489: 
 490: times()
 491: {
 492:     register struct a {
 493:         time_t  (*times)[4];
 494:     } *uap;
 495: 
 496:     uap = (struct a *)u.u_ap;
 497:     if (copyout((caddr_t)&u.u_utime, (caddr_t)uap->times,
 498:         sizeof(*uap->times)) < 0)
 499:         u.u_error = EFAULT;
 500: }
 501: 
 502: profil()
 503: {
 504:     register struct a {
 505:         short   *bufbase;
 506:         unsigned bufsize;
 507:         unsigned pcoffset;
 508:         unsigned pcscale;
 509:     } *uap;
 510: 
 511:     uap = (struct a *)u.u_ap;
 512:     u.u_prof.pr_base = uap->bufbase;
 513:     u.u_prof.pr_size = uap->bufsize;
 514:     u.u_prof.pr_off = uap->pcoffset;
 515:     u.u_prof.pr_scale = uap->pcscale;
 516: }
 517: 
 518: /*
 519:  * alarm clock signal
 520:  */
 521: alarm()
 522: {
 523:     register struct proc *p;
 524:     register c;
 525:     struct a {
 526:         int deltat;
 527:     };
 528: 
 529:     p = u.u_procp;
 530:     c = p->p_clktim;
 531:     p->p_clktim = ((struct a *) u.u_ap)->deltat;
 532:     u.u_r.r_val1 = c;
 533: }
 534: 
 535: /*
 536:  * indefinite wait.
 537:  * no one should wakeup(&u)
 538:  */
 539: pause()
 540: {
 541: 
 542:     for(;;)
 543:         sleep((caddr_t)&u, PSLEP);
 544: }
 545: 
 546: /*
 547:  * mode mask for creation of files
 548:  */
 549: umask()
 550: {
 551:     struct a {
 552:         int mask;
 553:     };
 554: 
 555:     u.u_r.r_val1 = u.u_cmask;
 556:     u.u_cmask = ((struct a *)u.u_ap)->mask & 0777;
 557: }
 558: 
 559: /*
 560:  * Set IUPD and IACC times on file.
 561:  * Can't set ICHG.
 562:  */
 563: utime()
 564: {
 565:     struct a {
 566:         char    *fname;
 567:         time_t  *tptr;
 568:     };
 569:     register struct inode *ip;
 570:     time_t tv[2];
 571: 
 572: #ifndef UCB_SYMLINKS
 573:     if ((ip = owner()) == NULL)
 574: #else
 575:     if ((ip = owner(1)) == NULL)
 576: #endif
 577:         return;
 578:     if (copyin((caddr_t)((struct a *) u.u_ap)->tptr, (caddr_t)tv, sizeof(tv))) {
 579:         u.u_error = EFAULT;
 580:     } else {
 581:         ip->i_flag |= IACC|IUPD|ICHG;
 582: #ifdef UCB_FSFIX
 583:         iupdat(ip, &tv[0], &tv[1], 0);
 584: #else
 585:         iupdat(ip, &tv[0], &tv[1]);
 586: #endif
 587:     }
 588:     iput(ip);
 589: }
 590: 
 591: #ifdef CGL_RTP
 592: /*
 593:  * make/unmake this process into a real time one.
 594:  */
 595: rtp()
 596: {
 597:     register struct proc *p;
 598:     struct a {
 599:         int flag;
 600:     };
 601: 
 602:     if (u.u_gid != 0 && !suser()) {
 603:         u.u_error = EPERM;
 604:         return;
 605:     }
 606:     p = u.u_procp;
 607:     if (((struct a *) u.u_ap)->flag) {
 608:         if (rtpp != NULL) {
 609:             u.u_error = EBUSY;  /* exclusive use error */
 610:             return;
 611:         }
 612:         p->p_flag |= SULOCK;
 613:         rtpp = p;
 614:     } else {
 615:         p->p_flag &= ~SULOCK;
 616:         rtpp = NULL;
 617:     }
 618: }
 619: #endif
 620: 
 621: #ifdef  MENLO_JCL
 622: /*
 623:  * Setpgrp on specified process and its descendants.
 624:  * Pid of zero implies current process.
 625:  * Pgrp of zero is getpgrp system call returning
 626:  * current process group.
 627:  */
 628: setpgrp()
 629: {
 630:     register struct proc *top;
 631:     register struct a {
 632:         int pid;
 633:         int pgrp;
 634:     } *uap;
 635: 
 636:     uap = (struct a *)u.u_ap;
 637:     if (uap->pid==0)
 638:         top = u.u_procp;
 639:     else {
 640:         for(top = &proc[0]; top <= maxproc; top++)
 641:             if ( uap->pid == top->p_pid)
 642:                 goto found1;
 643:         top = 0;
 644: found1:
 645:         if (top == 0) {
 646:             u.u_error = ESRCH;
 647:             return;
 648:         }
 649:     }
 650:     if (uap->pgrp <= 0) {
 651:         u.u_r.r_val1 = top->p_pgrp;
 652:         return;
 653:     }
 654:     if (top->p_uid != u.u_uid && u.u_uid && !inferior(top))
 655:         u.u_error = EPERM;
 656:     else
 657:         top->p_pgrp = uap->pgrp;
 658: }
 659: 
 660: spgrp(top, npgrp)
 661: register struct proc *top;
 662: {
 663:     register struct proc *pp, *p;
 664:     int f = 0;
 665: 
 666:     for (p = top; npgrp == -1 || u.u_uid == p->p_uid ||
 667:         !u.u_uid || inferior(p); p = pp) {
 668:         if (npgrp == -1) {
 669: #define bit(a)  (1L<<(a-1))
 670:             p->p_sig &= ~(bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
 671:             p->p_flag |= SDETACH;
 672:         } else
 673:             p->p_pgrp = npgrp;
 674:         f++;
 675:         /*
 676: 		 * Search for children.
 677: 		 */
 678:         for (pp = &proc[0]; pp <= maxproc; pp++)
 679:             if (pp->p_pptr == p)
 680:                 goto cont;
 681:         /*
 682: 		 * Search for siblings.
 683: 		 */
 684:         for (; p != top; p = p->p_pptr)
 685:             for (pp = p + 1; pp <= maxproc; pp++)
 686:                 if (pp->p_pptr == p->p_pptr)
 687:                     goto cont;
 688:         break;
 689:     cont:
 690:         ;
 691:     }
 692:     return (f);
 693: }
 694: 
 695: /*
 696:  * Is p an inferior of the current process?
 697:  */
 698: inferior(p)
 699: register struct proc *p;
 700: {
 701: 
 702:     for (; p != u.u_procp; p = p->p_pptr)
 703:         if (p <= &proc[1])
 704:             return (0);
 705:     return (1);
 706: }
 707: 
 708: #endif
 709: 
 710: #ifdef  UCB_AUTOBOOT
 711: reboot()
 712: {
 713:     register struct filsys *fp;
 714:     struct a {
 715:         dev_t   dev;
 716:         int opt;
 717:     };
 718: 
 719:     if (suser()) {
 720:         /*
 721: 		 *  Force the root filesystem's superblock to be updated,
 722: 		 *  so the date will be as current as possible after
 723: 		 *  rebooting.
 724: 		 */
 725:         if (fp = getfs(rootdev))
 726:             fp->s_fmod = 1;
 727:         boot((struct a *)u.u_ap->dev,(struct a *)u.u_ap->opt);
 728:     }
 729: }
 730: #endif

Defined functions

alarm defined in line 521; used 2 times
chdir defined in line 216; used 2 times
chdirec defined in line 227; used 2 times
chmod defined in line 257; used 2 times
chown defined in line 282; used 2 times
chroot defined in line 221; used 2 times
ftime defined in line 35; used 2 times
getgid defined in line 109; used 2 times
getpid defined in line 115; used 2 times
getuid defined in line 89; used 2 times
gtime defined in line 26; used 2 times
inferior defined in line 698; used 3 times
kill defined in line 385; used 2 times
nice defined in line 121; used 2 times
pause defined in line 539; used 3 times
profil defined in line 502; used 2 times
reboot defined in line 711; never used
rtp defined in line 595; never used
setgid defined in line 95; used 2 times
setpgrp defined in line 628; never used
setuid defined in line 74; used 2 times
spgrp defined in line 660; used 1 times
ssig defined in line 304; used 2 times
stime defined in line 61; used 2 times
times defined in line 490; used 5 times
umask defined in line 549; used 2 times
unlink defined in line 146; used 2 times
utime defined in line 563; used 2 times

Defined struct's

a defined in line 714; used 40 times

Defined macros

bit defined in line 669; used 3 times
  • in line 670(3)
Last modified: 1983-09-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1415
Valid CSS Valid XHTML 1.0 Strict