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