dbraun@cadavr.intel.com (Doug Braun ~) (11/29/88)
UZI, Part 2 of 5: #!/bin/sh # #Run this file through sh to get: # scall1.c echo -n 'Extracting scall1.c ... ' sed 's/^X//' > scall1.c << 'EOF_scall1.c' X/************************************************** XUZI (Unix Z80 Implementation) Kernel: scall1.c X***************************************************/ X X X/*LINTLIBRARY*/ X#include "unix.h" X#include "extern.h" X X X/******************************************* Xopen(name, flag) Xchar *name; Xregister int16 flag; X*********************************************/ X X#define name (char *)udata.u_argn1 X#define flag (int16)udata.u_argn X X_open() X{ X int16 uindex; X register int16 oftindex; X register inoptr ino; X register int16 perm; X inoptr n_open(); X X if (flag < 0 || flag > 2) X { X udata.u_error = EINVAL; X return (-1); X } X if ((uindex = uf_alloc()) == -1) X return (-1); X X if ((oftindex = oft_alloc()) == -1) X goto nooft; X X ifnot (ino = n_open(name,NULLINOPTR)) X goto cantopen; X X of_tab[oftindex].o_inode = ino; X X perm = getperm(ino); X if (((flag == O_RDONLY || flag == O_RDWR) && !(perm & OTH_RD)) || X ((flag == O_WRONLY || flag == O_RDWR) && !(perm & OTH_WR))) X { X udata.u_error = EPERM; X goto cantopen; X } X X if (getmode(ino) == F_DIR && X (flag == O_WRONLY || flag == O_RDWR)) X { X udata.u_error = EISDIR; X goto cantopen; X } X X if (isdevice(ino) && d_open((int)ino->c_node.i_addr[0]) != 0) X { X udata.u_error = ENXIO; X goto cantopen; X } X X udata.u_files[uindex] = oftindex; X X of_tab[oftindex].o_ptr.o_offset = 0; X of_tab[oftindex].o_ptr.o_blkno = 0; X of_tab[oftindex].o_access = flag; X X return (uindex); X Xcantopen: X oft_deref(oftindex); /* This will call i_deref() */ Xnooft: X udata.u_files[uindex] = -1; X return (-1); X} X X#undef name X#undef flag X X X X/********************************************* Xclose(uindex) Xint16 uindex; X**********************************************/ X X#define uindex (int16)udata.u_argn X X_close() X{ X return(doclose(uindex)); X} X X#undef uindex X X Xdoclose(uindex) Xint16 uindex; X{ X register int16 oftindex; X inoptr ino; X inoptr getinode(); X X ifnot(ino = getinode(uindex)) X return(-1); X oftindex = udata.u_files[uindex]; X X if (isdevice(ino) X /* && ino->c_refs == 1 && of_tab[oftindex].o_refs == 1 */ ) X d_close((int)(ino->c_node.i_addr[0])); X X udata.u_files[uindex] = -1; X oft_deref(oftindex); X X return(0); X} X X X X/**************************************** Xcreat(name, mode) Xchar *name; Xint16 mode; X*****************************************/ X X#define name (char *)udata.u_argn1 X#define mode (int16)udata.u_argn X X_creat() X{ X register inoptr ino; X register int16 uindex; X register int16 oftindex; X inoptr parent; X register int16 j; X inoptr n_open(); X inoptr newfile(); X X parent = NULLINODE; X X if ((uindex = uf_alloc()) == -1) X return (-1); X if ((oftindex = oft_alloc()) == -1) X return (-1); X X if (ino = n_open(name,&parent)) /* The file exists */ X { X i_deref(parent); X if (getmode(ino) == F_DIR) X { X i_deref(ino); X udata.u_error = EISDIR; X goto nogood; X } X ifnot (getperm(ino) & OTH_WR) X { X i_deref(ino); X udata.u_error = EACCES; X goto nogood; X } X if (getmode(ino) == F_REG) X { X /* Truncate the file to zero length */ X f_trunc(ino); X /* Reset any oft pointers */ X for (j=0; j < OFTSIZE; ++j) X if (of_tab[j].o_inode == ino) X of_tab[j].o_ptr.o_blkno = of_tab[j].o_ptr.o_offset = 0; X } X X } X else X { X if (parent && (ino = newfile(parent,name))) X /* Parent was derefed in newfile */ X { X ino->c_node.i_mode = (F_REG | (mode & MODE_MASK & ~udata.u_mask)); X setftime(ino, A_TIME|M_TIME|C_TIME); X /* The rest of the inode is initialized in newfile() */ X wr_inode(ino); X } X else X { X /* Doesn't exist and can't make it */ X if (parent) X i_deref(parent); X goto nogood; X } X } X X udata.u_files[uindex] = oftindex; X X of_tab[oftindex].o_ptr.o_offset = 0; X of_tab[oftindex].o_ptr.o_blkno = 0; X of_tab[oftindex].o_inode = ino; X of_tab[oftindex].o_access = O_WRONLY; X X return (uindex); X Xnogood: X oft_deref(oftindex); X return (-1); X X} X X#undef name X#undef mode X X X X/******************************************** Xpipe(fildes) Xint fildes[]; X*******************************************/ X X#define fildes (int *)udata.u_argn X X_pipe() X{ X register int16 u1, u2, oft1, oft2; X register inoptr ino; X inoptr i_open(); X X if ((u1 = uf_alloc()) == -1) X goto nogood2; X if ((oft1 = oft_alloc()) == -1) X goto nogood2; X udata.u_files[u1] = oft1; X X if ((u2 = uf_alloc()) == -1) X goto nogood; X if ((oft2 = oft_alloc()) == -1) X { X oft_deref(oft1); X goto nogood; X } X X ifnot (ino = i_open(ROOTDEV, 0)) X { X oft_deref(oft1); X oft_deref(oft2); X goto nogood; X } X X udata.u_files[u2] = oft2; X X of_tab[oft1].o_ptr.o_offset = 0; X of_tab[oft1].o_ptr.o_blkno = 0; X of_tab[oft1].o_inode = ino; X of_tab[oft1].o_access = O_RDONLY; X X of_tab[oft2].o_ptr.o_offset = 0; X of_tab[oft2].o_ptr.o_blkno = 0; X of_tab[oft2].o_inode = ino; X of_tab[oft2].o_access = O_WRONLY; X X ++ino->c_refs; X ino->c_node.i_mode = F_PIPE | 0777; /* No permissions necessary on pipes */ X ino->c_node.i_nlink = 0; /* a pipe is not in any directory */ X X *fildes = u1; X *(fildes+1) = u2; X return (0); X Xnogood: X udata.u_files[u1] = -1; Xnogood2: X return(-1); X X} X X#undef fildes X X X X/******************************************** Xlink(name1, name2) Xchar *name1; Xchar *name2; X*********************************************/ X X#define name1 (char *)udata.u_argn1 X#define name2 (char *)udata.u_argn X X_link() X{ X register inoptr ino; X register inoptr ino2; X inoptr parent2; X char *filename(); X inoptr n_open(); X X ifnot (ino = n_open(name1,NULLINOPTR)) X return(-1); X X if (getmode(ino) == F_DIR && !super()) X { X udata.u_error = EPERM; X goto nogood; X } X X /* Make sure file2 doesn't exist, and get its parent */ X if (ino2 = n_open(name2,&parent2)) X { X i_deref(ino2); X i_deref(parent2); X udata.u_error = EEXIST; X goto nogood; X } X X ifnot (parent2) X goto nogood; X X if (ino->c_dev != parent2->c_dev) X { X i_deref(parent2); X udata.u_error = EXDEV; X goto nogood; X } X X if (ch_link(parent2,"",filename(name2),ino) == 0) X goto nogood; X X X /* Update the link count. */ X ++ino->c_node.i_nlink; X wr_inode(ino); X setftime(ino, C_TIME); X X i_deref(parent2); X i_deref(ino); X return(0); X Xnogood: X i_deref(ino); X return(-1); X X} X X#undef name1 X#undef name2 X X X X/********************************************************** Xunlink(path) Xchar *path; X**************************************************/ X X#define path (char *)udata.u_argn X X_unlink() X{ X register inoptr ino; X inoptr pino; X char *filename(); X inoptr i_open(); X inoptr n_open(); X X ino = n_open(path,&pino); X X ifnot (pino && ino) X { X udata.u_error = ENOENT; X return (-1); X } X X if (getmode(ino) == F_DIR && !super()) X { X udata.u_error = EPERM; X goto nogood; X } X X /* Remove the directory entry */ X X if (ch_link(pino,filename(path),"",NULLINODE) == 0) X goto nogood; X X /* Decrease the link count of the inode */ X X ifnot (ino->c_node.i_nlink--) X { X ino->c_node.i_nlink += 2; X warning("_unlink: bad nlink"); X } X setftime(ino, C_TIME); X i_deref(pino); X i_deref(ino); X return(0); X Xnogood: X i_deref(pino); X i_deref(ino); X return(-1); X} X X#undef path X X X X/***************************************************** Xread(d, buf, nbytes) Xint16 d; Xchar *buf; Xuint16 nbytes; X**********************************************/ X X#define d (int16)udata.u_argn2 X#define buf (char *)udata.u_argn1 X#define nbytes (uint16)udata.u_argn X X_read() X{ X register inoptr ino; X inoptr rwsetup(); X X /* Set up u_base, u_offset, ino; check permissions, file num. */ X if ((ino = rwsetup(1)) == NULLINODE) X return (-1); /* bomb out if error */ X X readi(ino); X updoff(); X X return (udata.u_count); X} X X#undef d X#undef buf X#undef nbytes X X X/*********************************** Xwrite(d, buf, nbytes) Xint16 d; Xchar *buf; Xuint16 nbytes; X***********************************/ X X#define d (int16)udata.u_argn2 X#define buf (char *)udata.u_argn1 X#define nbytes (uint16)udata.u_argn X X_write() X{ X register inoptr ino; X off_t *offp; X inoptr rwsetup(); X X /* Set up u_base, u_offset, ino; check permissions, file num. */ X if ((ino = rwsetup(0)) == NULLINODE) X return (-1); /* bomb out if error */ X X writei(ino); X updoff(); X X return (udata.u_count); X} X X#undef d X#undef buf X#undef nbytes X X X Xinoptr Xrwsetup(rwflag) Xint rwflag; X{ X register inoptr ino; X register struct oft *oftp; X inoptr getinode(); X X udata.u_base = (char *)udata.u_argn1; /* buf */ X udata.u_count = (uint16)udata.u_argn; /* nbytes */ X X if ((ino = getinode(udata.u_argn2)) == NULLINODE) X return (NULLINODE); X X oftp = of_tab + udata.u_files[udata.u_argn2]; X if (oftp->o_access == (rwflag ? O_WRONLY : O_RDONLY)) X { X udata.u_error = EBADF; X return (NULLINODE); X } X X setftime(ino, rwflag ? A_TIME : (A_TIME | M_TIME | C_TIME)); X X /* Initialize u_offset from file pointer */ X udata.u_offset.o_blkno = oftp->o_ptr.o_blkno; X udata.u_offset.o_offset = oftp->o_ptr.o_offset; X X return (ino); X} X X X Xreadi(ino) Xregister inoptr ino; X{ X register uint16 amount; X register uint16 toread; X register blkno_t pblk; X register char *bp; X int dev; X int ispipe; X char *bread(); X char *zerobuf(); X blkno_t bmap(); X X dev = ino->c_dev; X ispipe = 0; X switch (getmode(ino)) X { X X case F_DIR: X case F_REG: X X /* See of end of file will limit read */ X toread = udata.u_count = X ino->c_node.i_size.o_blkno-udata.u_offset.o_blkno >= 64 ? X udata.u_count : X min(udata.u_count, X 512*(ino->c_node.i_size.o_blkno-udata.u_offset.o_blkno) + X (ino->c_node.i_size.o_offset-udata.u_offset.o_offset)); X goto loop; X X case F_PIPE: X ispipe = 1; X while (psize(ino) == 0) X { X if (ino->c_refs == 1) /* No writers */ X break; X /* Sleep if empty pipe */ X psleep(ino); X } X toread = udata.u_count = min(udata.u_count, psize(ino)); X goto loop; X X case F_BDEV: X toread = udata.u_count; X dev = *(ino->c_node.i_addr); X X loop: X while (toread) X { X if ((pblk = bmap(ino, udata.u_offset.o_blkno, 1)) != NULLBLK) X bp = bread(dev, pblk, 0); X else X bp = zerobuf(); X X bcopy(bp+udata.u_offset.o_offset, udata.u_base, X (amount = min(toread, 512 - udata.u_offset.o_offset))); X brelse(bp); X X udata.u_base += amount; X addoff(&udata.u_offset, amount); X if (ispipe && udata.u_offset.o_blkno >= 18) X udata.u_offset.o_blkno = 0; X toread -= amount; X if (ispipe) X { X addoff(&(ino->c_node.i_size), -amount); X wakeup(ino); X } X } X X break; X X case F_CDEV: X udata.u_count = cdread(ino->c_node.i_addr[0]); X X if (udata.u_count != -1) X addoff(&udata.u_offset, udata.u_count); X break; X X default: X udata.u_error = ENODEV; X } X} X X X X/* Writei (and readi) need more i/o error handling */ X Xwritei(ino) Xregister inoptr ino; X{ X register uint16 amount; X register uint16 towrite; X register char *bp; X int ispipe; X blkno_t pblk; X int created; /* Set by bmap if newly allocated block used */ X int dev; X char *zerobuf(); X char *bread(); X blkno_t bmap(); X X dev = ino->c_dev; X X switch (getmode(ino)) X { X X case F_BDEV: X dev = *(ino->c_node.i_addr); X case F_DIR: X case F_REG: X ispipe = 0; X towrite = udata.u_count; X goto loop; X X case F_PIPE: X ispipe = 1; X while ((towrite = udata.u_count) > (16*512) - psize(ino)) X { X if (ino->c_refs == 1) /* No readers */ X { X udata.u_count = -1; X udata.u_error = EPIPE; X ssig(udata.u_ptab, SIGPIPE); X return; X } X /* Sleep if empty pipe */ X psleep(ino); X } X X /* Sleep if empty pipe */ X goto loop; X X loop: X X while (towrite) X { X amount = min(towrite, 512 - udata.u_offset.o_offset); X X X if ((pblk = bmap(ino, udata.u_offset.o_blkno, 0)) == NULLBLK) X break; /* No space to make more blocks */ X X /* If we are writing an entire block, we don't care X about its previous contents */ X bp = bread(dev, pblk, (amount == 512)); X X bcopy(udata.u_base, bp+udata.u_offset.o_offset, amount); X bawrite(bp); X X udata.u_base += amount; X addoff(&udata.u_offset, amount); X if(ispipe) X { X if (udata.u_offset.o_blkno >= 18) X udata.u_offset.o_blkno = 0; X addoff(&(ino->c_node.i_size), amount); X /* Wake up any readers */ X wakeup(ino); X } X towrite -= amount; X } X X /* Update size if file grew */ X ifnot (ispipe) X { X if ( udata.u_offset.o_blkno > ino->c_node.i_size.o_blkno || X (udata.u_offset.o_blkno == ino->c_node.i_size.o_blkno && X udata.u_offset.o_offset > ino->c_node.i_size.o_offset)) X { X ino->c_node.i_size.o_blkno = udata.u_offset.o_blkno; X ino->c_node.i_size.o_offset = udata.u_offset.o_offset; X ino->c_dirty = 1; X } X } X X break; X X case F_CDEV: X udata.u_count = cdwrite(ino->c_node.i_addr[0]); X X if (udata.u_count != -1) X addoff(&udata.u_offset, udata.u_count); X break; X X default: X udata.u_error = ENODEV; X } X X} X X Xmin(a, b) Xint a, b; X{ X return ( a < b ? a : b); X} X X Xpsize(ino) Xinoptr ino; X{ X return (512*ino->c_node.i_size.o_blkno+ino->c_node.i_size.o_offset); X} X X X Xaddoff(ofptr, amount) Xoff_t *ofptr; Xint amount; X{ X if (amount >= 0) X { X ofptr->o_offset += amount % 512; X if (ofptr->o_offset >= 512) X { X ofptr->o_offset -= 512; X ++ofptr->o_blkno; X } X ofptr->o_blkno += amount/512; X } X else X { X ofptr->o_offset -= (-amount) % 512; X if (ofptr->o_offset < 0) X { X ofptr->o_offset += 512; X --ofptr->o_blkno; X } X ofptr->o_blkno -= (-amount)/512; X } X} X X Xupdoff() X{ X register off_t *offp; X X /* Update current file pointer */ X offp = &of_tab[udata.u_files[udata.u_argn2]].o_ptr; X offp->o_blkno = udata.u_offset.o_blkno; X offp->o_offset = udata.u_offset.o_offset; X} X X X X/**************************************** Xseek(file,offset,flag) Xint16 file; Xuint16 offset; Xint16 flag; X*****************************************/ X X#define file (int16)udata.u_argn2 X#define offset (uint16)udata.u_argn1 X#define flag (int16)udata.u_argn X X_seek() X{ X register inoptr ino; X register int16 oftno; X register uint16 retval; X inoptr getinode(); X X if ((ino = getinode(file)) == NULLINODE) X return(-1); X X if (getmode(ino) == F_PIPE) X { X udata.u_error = ESPIPE; X return(-1); X } X X oftno = udata.u_files[file]; X X X if (flag <= 2) X retval = of_tab[oftno].o_ptr.o_offset; X else X retval = of_tab[oftno].o_ptr.o_blkno; X X switch(flag) X { X case 0: X of_tab[oftno].o_ptr.o_blkno = 0; X of_tab[oftno].o_ptr.o_offset = offset; X break; X case 1: X of_tab[oftno].o_ptr.o_offset += offset; X break; X case 2: X of_tab[oftno].o_ptr.o_blkno = ino->c_node.i_size.o_blkno; X of_tab[oftno].o_ptr.o_offset = ino->c_node.i_size.o_offset + offset; X break; X case 3: X of_tab[oftno].o_ptr.o_blkno = offset; X break; X case 4: X of_tab[oftno].o_ptr.o_blkno += offset; X break; X case 5: X of_tab[oftno].o_ptr.o_blkno = ino->c_node.i_size.o_blkno + offset; X break; X default: X udata.u_error = EINVAL; X return(-1); X } X X while ((unsigned)of_tab[oftno].o_ptr.o_offset >= 512) X { X of_tab[oftno].o_ptr.o_offset -= 512; X ++of_tab[oftno].o_ptr.o_blkno; X } X X return((int16)retval); X} X X#undef file X#undef offset X#undef flag X X X X/************************************ Xchdir(dir) Xchar *dir; X************************************/ X X#define dir (char *)udata.u_argn X X_chdir() X{ X register inoptr newcwd; X inoptr n_open(); X X ifnot (newcwd = n_open(dir,NULLINOPTR)) X return(-1); X X if (getmode(newcwd) != F_DIR) X { X udata.u_error = ENOTDIR; X i_deref(newcwd); X return(-1); X } X i_deref(udata.u_cwd); X udata.u_cwd = newcwd; X return(0); X} X X#undef dir X X X X/************************************* Xmknod(name,mode,dev) Xchar *name; Xint16 mode; Xint16 dev; X***************************************/ X X#define name (char *)udata.u_argn2 X#define mode (int16)udata.u_argn1 X#define dev (int16)udata.u_argn X X_mknod() X{ X register inoptr ino; X inoptr parent; X inoptr n_open(); X inoptr newfile(); X X udata.u_error = 0; X ifnot (super()) X { X udata.u_error = EPERM; X return(-1); X } X X if (ino = n_open(name,&parent)) X { X udata.u_error = EEXIST; X goto nogood; X } X X ifnot (parent) X { X udata.u_error = ENOENT; X goto nogood3; X } X X ifnot (ino = newfile(parent,name)) X goto nogood2; X X /* Initialize mode and dev */ X ino->c_node.i_mode = mode & ~udata.u_mask; X ino->c_node.i_addr[0] = isdevice(ino) ? dev : 0; X setftime(ino, A_TIME|M_TIME|C_TIME); X wr_inode(ino); X X i_deref(ino); X return (0); X Xnogood: X i_deref(ino); Xnogood2: X i_deref(parent); Xnogood3: X return (-1); X} X X#undef name X#undef mode X#undef dev X X X X/**************************************** Xsync() X***************************************/ X X_sync() X{ X register j; X register inoptr ino; X register char *buf; X char *bread(); X X /* Write out modified inodes */ X X for (ino=i_tab; ino < i_tab+ITABSIZE; ++ino) X if ((ino->c_refs) > 0 && ino->c_dirty != 0) X { X wr_inode(ino); X ino->c_dirty = 0; X } X X /* Write out modified super blocks */ X /* This fills the rest of the super block with garbage. */ X X for (j=0; j < NDEVS; ++j) X { X if (fs_tab[j].s_mounted == SMOUNTED && fs_tab[j].s_fmod) X { X fs_tab[j].s_fmod = 0; X buf = bread(j, 1, 1); X bcopy((char *)&fs_tab[j], buf, 512); X bfree(buf, 2); X } X } X X bufsync(); /* Clear buffer pool */ X} X X X/**************************************** Xaccess(path,mode) Xchar *path; Xint16 mode; X****************************************/ X X#define path (char *)udata.u_argn1 X#define mode (int16)udata.u_argn X X_access() X{ X register inoptr ino; X register int16 euid; X register int16 egid; X register int16 retval; X inoptr n_open(); X X if ((mode & 07) && !*(path)) X { X udata.u_error = ENOENT; X return (-1); X } X X /* Temporarily make eff. id real id. */ X euid = udata.u_euid; X egid = udata.u_egid; X udata.u_euid = udata.u_ptab->p_uid; X udata.u_egid = udata.u_gid; X X ifnot (ino = n_open(path,NULLINOPTR)) X { X retval = -1; X goto nogood; X } X X retval = 0; X if (~getperm(ino) & (mode&07)) X { X udata.u_error = EPERM; X retval = -1; X } X X i_deref(ino); Xnogood: X udata.u_euid = euid; X udata.u_egid = egid; X X return(retval); X} X X#undef path X#undef mode X X X X/******************************************* Xchmod(path,mode) Xchar *path; Xint16 mode; X*******************************************/ X X#define path (char *)udata.u_argn1 X#define mode (int16)udata.u_argn X X_chmod() X{ X X inoptr ino; X inoptr n_open(); X X ifnot (ino = n_open(path,NULLINOPTR)) X return (-1); X X if (ino->c_node.i_uid != udata.u_euid && !super()) X { X i_deref(ino); X udata.u_error = EPERM; X return(-1); X } X X ino->c_node.i_mode = (mode & MODE_MASK) | (ino->c_node.i_mode & F_MASK); X setftime(ino, C_TIME); X i_deref(ino); X return(0); X} X X#undef path X#undef mode X X X X/*********************************************** Xchown(path, owner, group) Xchar *path; Xint owner; Xint group; X**********************************************/ X X#define path (char *)udata.u_argn2 X#define owner (int16)udata.u_argn1 X#define group (int16)udata.u_argn X X_chown() X{ X register inoptr ino; X inoptr n_open(); X X ifnot (ino = n_open(path,NULLINOPTR)) X return (-1); X X if (ino->c_node.i_uid != udata.u_euid && !super()) X { X i_deref(ino); X udata.u_error = EPERM; X return(-1); X } X X ino->c_node.i_uid = owner; X ino->c_node.i_gid = group; X setftime(ino, C_TIME); X i_deref(ino); X return(0); X} X X#undef path X#undef owner X#undef group X X X X/************************************** Xstat(path,buf) Xchar *path; Xchar *buf; X****************************************/ X X#define path (char *)udata.u_argn1 X#define buf (char *)udata.u_argn X X_stat() X{ X X register inoptr ino; X inoptr n_open(); X X ifnot (valadr(buf,sizeof(struct stat)) && (ino = n_open(path,NULLINOPTR))) X { X return (-1); X } X X stcpy(ino,buf); X i_deref(ino); X return(0); X} X X#undef path X#undef buf X X X X/******************************************** Xfstat(fd, buf) Xint16 fd; Xchar *buf; X********************************************/ X X#define fd (int16)udata.u_argn1 X#define buf (char *)udata.u_argn X X_fstat() X{ X register inoptr ino; X inoptr getinode(); X X ifnot (valadr(buf,sizeof(struct stat))) X return(-1); X X if ((ino = getinode(fd)) == NULLINODE) X return(-1); X X stcpy(ino,buf); X return(0); X} X X#undef fd X#undef buf X X X/* Utility for stat and fstat */ Xstcpy(ino, buf) Xinoptr ino; Xchar *buf; X{ X /* violently system-dependent */ X bcopy((char *)&(ino->c_dev), buf, 12); X bcopy((char *)&(ino->c_node.i_addr[0]), buf+12, 2); X bcopy((char *)&(ino->c_node.i_size), buf+14, 16); X} X X X X/************************************ Xdup(oldd) Xint16 oldd; X************************************/ X X#define oldd (uint16)udata.u_argn X X_dup() X{ X register int newd; X inoptr getinode(); X X if (getinode(oldd) == NULLINODE) X return(-1); X X if ((newd = uf_alloc()) == -1) X return (-1); X X udata.u_files[newd] = udata.u_files[oldd]; X ++of_tab[udata.u_files[oldd]].o_refs; X X return(newd); X} X X#undef oldd X X X X/**************************************** Xdup2(oldd, newd) Xint16 oldd; Xint16 newd; X****************************************/ X X#define oldd (int16)udata.u_argn1 X#define newd (int16)udata.u_argn X X_dup2() X{ X inoptr getinode(); X X if (getinode(oldd) == NULLINODE) X return(-1); X X if (newd < 0 || newd >= UFTSIZE) X { X udata.u_error = EBADF; X return (-1); X } X X ifnot (udata.u_files[newd] & 0x80) X doclose(newd); X X udata.u_files[newd] = udata.u_files[oldd]; X ++of_tab[udata.u_files[oldd]].o_refs; X X return(0); X} X X#undef oldd X#undef newd X X X X/************************************** Xumask(mask) Xint mask; X*************************************/ X X#define mask (int16)udata.u_argn X X_umask() X{ X register int omask; X X omask = udata.u_mask; X udata.u_mask = mask & 0777; X return(omask); X} X X#undef mask X X X X/* Special system call returns super-block of given Xfilesystem for users to determine free space, etc. XShould be replaced with a sync() followed by a read Xof block 1 of the device. */ X X/*********************************************** Xgetfsys(dev,buf) Xint16 dev; Xstruct filesys *buf; X**************************************************/ X X#define dev (int16)udata.u_argn1 X#define buf (struct filesys *)udata.u_argn X X_getfsys() X{ X if (dev < 0 || dev >= NDEVS || fs_tab[dev].s_mounted != SMOUNTED) X { X udata.u_error = ENXIO; X return(-1); X } X X bcopy((char *)&fs_tab[dev],(char *)buf,sizeof(struct filesys)); X return(0); X} X X#undef dev X#undef buf X X X X/**************************************** Xioctl(fd, request, data) Xint fd; Xint request; Xchar *data; X*******************************************/ X X#define fd (int)udata.u_argn2 X#define request (int)udata.u_argn1 X#define data (char *)udata.u_argn X X_ioctl() X{ X X register inoptr ino; X register int dev; X inoptr getinode(); X X if ((ino = getinode(fd)) == NULLINODE) X return(-1); X X ifnot (isdevice(ino)) X { X udata.u_error = ENOTTY; X return(-1); X } X X ifnot (getperm(ino) & OTH_WR) X { X udata.u_error = EPERM; X return(-1); X } X X dev = ino->c_node.i_addr[0]; X X if (d_ioctl(dev, request,data)) X return(-1); X return(0); X} X X#undef fd X#undef request X#undef data X X X X/* This implementation of mount ignores the rwflag */ X X/***************************************** Xmount(spec, dir, rwflag) Xchar *spec; Xchar *dir; Xint rwflag; X*******************************************/ X X#define spec (char *)udata.u_argn2 X#define dir (char *)udata.u_argn1 X#define rwflag (int)udata.u_argn X X_mount() X{ X register inoptr sino, dino; X register int dev; X inoptr n_open(); X X ifnot(super()) X { X udata.u_error = EPERM; X return (-1); X } X X ifnot (sino = n_open(spec,NULLINOPTR)) X return (-1); X X ifnot (dino = n_open(dir,NULLINOPTR)) X { X i_deref(sino); X return (-1); X } X X if (getmode(sino) != F_BDEV) X { X udata.u_error = ENOTBLK; X goto nogood; X } X X if (getmode(dino) != F_DIR) X { X udata.u_error = ENOTDIR; X goto nogood; X } X X dev = (int)sino->c_node.i_addr[0]; X X if ( dev >= NDEVS || d_open(dev)) X { X udata.u_error = ENXIO; X goto nogood; X } X X if (fs_tab[dev].s_mounted || dino->c_refs != 1 || dino->c_num == ROOTINODE) X { X udata.u_error = EBUSY; X goto nogood; X } X X _sync(); X X if (fmount(dev,dino)) X { X udata.u_error = EBUSY; X goto nogood; X } X X i_deref(dino); X i_deref(sino); X return(0); X Xnogood: X i_deref(dino); X i_deref(sino); X return (-1); X} X X#undef spec X#undef dir X#undef rwflag X X X X/****************************************** Xumount(spec) Xchar *spec; X******************************************/ X X#define spec (char *)udata.u_argn X X_umount() X{ X register inoptr sino; X register int dev; X register inoptr ptr; X inoptr n_open(); X X ifnot(super()) X { X udata.u_error = EPERM; X return (-1); X } X X ifnot (sino = n_open(spec,NULLINOPTR)) X return (-1); X X if (getmode(sino) != F_BDEV) X { X udata.u_error = ENOTBLK; X goto nogood; X } X X dev = (int)sino->c_node.i_addr[0]; X ifnot (validdev(dev)) X { X udata.u_error = ENXIO; X goto nogood; X } X X if (!fs_tab[dev].s_mounted) X { X udata.u_error = EINVAL; X goto nogood; X } X X for (ptr = i_tab; ptr < i_tab+ITABSIZE; ++ptr) X if (ptr->c_refs > 0 && ptr->c_dev == dev) X { X udata.u_error = EBUSY; X goto nogood; X } X X _sync(); X fs_tab[dev].s_mounted = 0; X i_deref(fs_tab[dev].s_mntpt); X X i_deref(sino); X return(0); X Xnogood: X i_deref(sino); X return (-1); X} X X#undef spec X EOF_scall1.c echo 'Done' exit 0 Doug Braun Intel Corp CAD 408 765-4279 / decwrl \ | hplabs | -| oliveb |- !intelca!mipos3!cadev4!dbraun | amd | \ qantel /