03950 #include "../h/param.h" 03951 #include "../h/systm.h" 03952 #include "../h/dir.h" 03953 #include "../h/user.h" 03954 #include "../h/reg.h" 03955 #include "../h/inode.h" 03956 #include "../h/proc.h" 03957 #include "../h/timeb.h" 03958 03959 /* 03960 * Everything in this file is a routine implementing a system call. 03961 */ 03962 03963 /* 03964 * return the current time (old-style entry) 03965 */ 03966 gtime() 03967 { 03968 u.u_r.r_time = time; 03969 } 03970 03971 /* 03972 * New time entry-- return TOD with milliseconds, timezone, 03973 * DST flag 03974 */ 03975 ftime() 03976 { 03977 register struct a { 03978 struct timeb *tp; 03979 } *uap; 03980 struct timeb t; 03981 register unsigned ms; 03982 03983 uap = (struct a *)u.u_ap; 03984 spl7(); 03985 t.time = time; 03986 ms = lbolt; 03987 spl0(); 03988 if (ms > HZ) { 03989 ms -= HZ; 03990 t.time++; 03991 } 03992 t.millitm = (1000*ms)/HZ; 03993 t.timezone = TIMEZONE; 03994 t.dstflag = DSTFLAG; 03995 if (copyout((caddr_t)&t, (caddr_t)uap->tp, sizeof(t)) < 0) 03996 u.u_error = EFAULT; 03997 } 03998 03999 /* 04000 * Set the time 04001 */ 04002 stime() 04003 { 04004 register struct a { 04005 time_t time; 04006 } *uap; 04007 04008 uap = (struct a *)u.u_ap; 04009 if(suser()) 04010 time = uap->time; 04011 } 04012 04013 setuid() 04014 { 04015 register uid; 04016 register struct a { 04017 int uid; 04018 } *uap; 04019 04020 uap = (struct a *)u.u_ap; 04021 uid = uap->uid; 04022 if(u.u_ruid == uid || suser()) { 04023 u.u_uid = uid; 04024 u.u_procp->p_uid = uid; 04025 u.u_ruid = uid; 04026 } 04027 } 04028 04029 getuid() 04030 { 04031 04032 u.u_r.r_val1 = u.u_ruid; 04033 u.u_r.r_val2 = u.u_uid; 04034 } 04035 04036 setgid() 04037 { 04038 register gid; 04039 register struct a { 04040 int gid; 04041 } *uap; 04042 04043 uap = (struct a *)u.u_ap; 04044 gid = uap->gid; 04045 if(u.u_rgid == gid || suser()) { 04046 u.u_gid = gid; 04047 u.u_rgid = gid; 04048 } 04049 } 04050 04051 getgid() 04052 { 04053 04054 u.u_r.r_val1 = u.u_rgid; 04055 u.u_r.r_val2 = u.u_gid; 04056 } 04057 04058 getpid() 04059 { 04060 u.u_r.r_val1 = u.u_procp->p_pid; 04061 u.u_r.r_val2 = u.u_procp->p_ppid; 04062 } 04063 04064 sync() 04065 { 04066 04067 update(); 04068 } 04069 04070 nice() 04071 { 04072 register n; 04073 register struct a { 04074 int niceness; 04075 } *uap; 04076 04077 uap = (struct a *)u.u_ap; 04078 n = uap->niceness; 04079 if(n < 0 && !suser()) 04080 n = 0; 04081 n += u.u_procp->p_nice; 04082 if(n >= 2*NZERO) 04083 n = 2*NZERO -1; 04084 if(n < 0) 04085 n = 0; 04086 u.u_procp->p_nice = n; 04087 } 04088 04089 /* 04090 * Unlink system call. 04091 * Hard to avoid races here, especially 04092 * in unlinking directories. 04093 */ 04094 unlink() 04095 { 04096 register struct inode *ip, *pp; 04097 struct a { 04098 char *fname; 04099 }; 04100 04101 pp = namei(uchar, 2); 04102 if(pp == NULL) 04103 return; 04104 /* 04105 * Check for unlink(".") 04106 * to avoid hanging on the iget 04107 */ 04108 if (pp->i_number == u.u_dent.d_ino) { 04109 ip = pp; 04110 ip->i_count++; 04111 } else 04112 ip = iget(pp->i_dev, u.u_dent.d_ino); 04113 if(ip == NULL) 04114 goto out1; 04115 if((ip->i_mode&IFMT)==IFDIR && !suser()) 04116 goto out; 04117 /* 04118 * Don't unlink a mounted file. 04119 */ 04120 if (ip->i_dev != pp->i_dev) { 04121 u.u_error = EBUSY; 04122 goto out; 04123 } 04124 if (ip->i_flag&ITEXT) 04125 xrele(ip); /* try once to free text */ 04126 if (ip->i_flag&ITEXT && ip->i_nlink==1) { 04127 u.u_error = ETXTBSY; 04128 goto out; 04129 } 04130 u.u_offset -= sizeof(struct direct); 04131 u.u_base = (caddr_t)&u.u_dent; 04132 u.u_count = sizeof(struct direct); 04133 u.u_dent.d_ino = 0; 04134 writei(pp); 04135 ip->i_nlink--; 04136 ip->i_flag |= ICHG; 04137 04138 out: 04139 iput(ip); 04140 out1: 04141 iput(pp); 04142 } 04143 chdir() 04144 { 04145 chdirec(&u.u_cdir); 04146 } 04147 04148 chroot() 04149 { 04150 if (suser()) 04151 chdirec(&u.u_rdir); 04152 } 04153 04154 chdirec(ipp) 04155 register struct inode **ipp; 04156 { 04157 register struct inode *ip; 04158 struct a { 04159 char *fname; 04160 }; 04161 04162 ip = namei(uchar, 0); 04163 if(ip == NULL) 04164 return; 04165 if((ip->i_mode&IFMT) != IFDIR) { 04166 u.u_error = ENOTDIR; 04167 goto bad; 04168 } 04169 if(access(ip, IEXEC)) 04170 goto bad; 04171 prele(ip); 04172 if (*ipp) { 04173 plock(*ipp); 04174 iput(*ipp); 04175 } 04176 *ipp = ip; 04177 return; 04178 04179 bad: 04180 iput(ip); 04181 } 04182 04183 chmod() 04184 { 04185 register struct inode *ip; 04186 register struct a { 04187 char *fname; 04188 int fmode; 04189 } *uap; 04190 04191 uap = (struct a *)u.u_ap; 04192 if ((ip = owner()) == NULL) 04193 return; 04194 ip->i_mode &= ~07777; 04195 if (u.u_uid) 04196 uap->fmode &= ~ISVTX; 04197 ip->i_mode |= uap->fmode&07777; 04198 ip->i_flag |= ICHG; 04199 if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0) 04200 xrele(ip); 04201 iput(ip); 04202 } 04203 04204 chown() 04205 { 04206 register struct inode *ip; 04207 register struct a { 04208 char *fname; 04209 int uid; 04210 int gid; 04211 } *uap; 04212 04213 uap = (struct a *)u.u_ap; 04214 if (!suser() || (ip = owner()) == NULL) 04215 return; 04216 ip->i_uid = uap->uid; 04217 ip->i_gid = uap->gid; 04218 ip->i_flag |= ICHG; 04219 iput(ip); 04220 } 04221 04222 ssig() 04223 { 04224 register a; 04225 struct a { 04226 int signo; 04227 int fun; 04228 } *uap; 04229 04230 uap = (struct a *)u.u_ap; 04231 a = uap->signo; 04232 if(a<=0 || a>=NSIG || a==SIGKIL) { 04233 u.u_error = EINVAL; 04234 return; 04235 } 04236 u.u_r.r_val1 = u.u_signal[a]; 04237 u.u_signal[a] = uap->fun; 04238 u.u_procp->p_sig &= ~(1<<(a-1)); 04239 } 04240 04241 kill() 04242 { 04243 register struct proc *p, *q; 04244 register a; 04245 register struct a { 04246 int pid; 04247 int signo; 04248 } *uap; 04249 int f, priv; 04250 04251 uap = (struct a *)u.u_ap; 04252 f = 0; 04253 a = uap->pid; 04254 priv = 0; 04255 if (a==-1 && u.u_uid==0) { 04256 priv++; 04257 a = 0; 04258 } 04259 q = u.u_procp; 04260 for(p = &proc[0]; p < &proc[NPROC]; p++) { 04261 if(p->p_stat == NULL) 04262 continue; 04263 if(a != 0 && p->p_pid != a) 04264 continue; 04265 if(a==0 && ((p->p_pgrp!=q->p_pgrp&&priv==0) || p<=&proc[1])) 04266 continue; 04267 if(u.u_uid != 0 && u.u_uid != p->p_uid) 04268 continue; 04269 f++; 04270 psignal(p, uap->signo); 04271 } 04272 if(f == 0) 04273 u.u_error = ESRCH; 04274 } 04275 04276 times() 04277 { 04278 register struct a { 04279 time_t (*times)[4]; 04280 } *uap; 04281 04282 uap = (struct a *)u.u_ap; 04283 if (copyout((caddr_t)&u.u_utime, (caddr_t)uap->times, sizeof(*uap->times)) < 0) 04284 u.u_error = EFAULT; 04285 } 04286 04287 profil() 04288 { 04289 register struct a { 04290 short *bufbase; 04291 unsigned bufsize; 04292 unsigned pcoffset; 04293 unsigned pcscale; 04294 } *uap; 04295 04296 uap = (struct a *)u.u_ap; 04297 u.u_prof.pr_base = uap->bufbase; 04298 u.u_prof.pr_size = uap->bufsize; 04299 u.u_prof.pr_off = uap->pcoffset; 04300 u.u_prof.pr_scale = uap->pcscale; 04301 } 04302 04303 /* 04304 * alarm clock signal 04305 */ 04306 alarm() 04307 { 04308 register struct proc *p; 04309 register c; 04310 register struct a { 04311 int deltat; 04312 } *uap; 04313 04314 uap = (struct a *)u.u_ap; 04315 p = u.u_procp; 04316 c = p->p_clktim; 04317 p->p_clktim = uap->deltat; 04318 u.u_r.r_val1 = c; 04319 } 04320 04321 /* 04322 * indefinite wait. 04323 * no one should wakeup(&u) 04324 */ 04325 pause() 04326 { 04327 04328 for(;;) 04329 sleep((caddr_t)&u, PSLEP); 04330 } 04331 04332 /* 04333 * mode mask for creation of files 04334 */ 04335 umask() 04336 { 04337 register struct a { 04338 int mask; 04339 } *uap; 04340 register t; 04341 04342 uap = (struct a *)u.u_ap; 04343 t = u.u_cmask; 04344 u.u_cmask = uap->mask & 0777; 04345 u.u_r.r_val1 = t; 04346 } 04347 04348 /* 04349 * Set IUPD and IACC times on file. 04350 * Can't set ICHG. 04351 */ 04352 utime() 04353 { 04354 register struct a { 04355 char *fname; 04356 time_t *tptr; 04357 } *uap; 04358 register struct inode *ip; 04359 time_t tv[2]; 04360 04361 uap = (struct a *)u.u_ap; 04362 if ((ip = owner()) == NULL) 04363 return; 04364 if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) { 04365 u.u_error = EFAULT; 04366 return; 04367 } 04368 ip->i_flag |= IACC|IUPD|ICHG; 04369 iupdat(ip, &tv[0], &tv[1]); 04370 iput(ip); 04371 } 04372 04373 04374 04375 04376 04377 04378 04379 04380 04381 04382 04383 04384 04385 04386 04387 04388 04389 04390 04391 04392 04393 04394 04395 04396 04397 04398 04399