poole@forty2.UUCP (Simon Poole) (03/14/89)
echo x - fs/Makefile.cdiff gres '^X' '' > fs/Makefile.cdiff << '/' X*** Makefile Thu Mar 2 23:36:33 1989 X--- ../Makefile Thu Mar 2 23:45:07 1989 X*************** X*** 9,15 **** X path.o mount.o link.o super.o inode.o cache.o filedes.o \ X stadir.o protect.o time.o misc.o utility.o table.o putc.o X HDR = ../h/callnr.h ../h/com.h ../h/const.h ../h/error.h \ X! ../h/signal.h ../h/stat.h ../h/type.h \ X buf.h const.h dev.h file.h fproc.h \ X glo.h inode.h param.h super.h type.h X ALL = fs.mix X--- 9,15 ---- X path.o mount.o link.o super.o inode.o cache.o filedes.o \ X stadir.o protect.o time.o misc.o utility.o table.o putc.o X HDR = ../h/callnr.h ../h/com.h ../h/const.h ../h/error.h \ X! ../h/fcntl.h ../h/signal.h ../h/stat.h ../h/type.h \ X buf.h const.h dev.h file.h fproc.h \ X glo.h inode.h param.h super.h type.h X ALL = fs.mix / echo x - fs/cache.c.cdiff gres '^X' '' > fs/cache.c.cdiff << '/' X*** cache.c Thu Mar 5 21:25:02 1989 X--- ../cache.c Thu Mar 5 21:29:26 1989 X*************** X*** 260,266 **** X X if (bp->b_dev != NO_DEV) { X pos = (long) bp->b_blocknr * BLOCK_SIZE; X! r = dev_io(rw_flag, bp->b_dev, pos, BLOCK_SIZE, FS_PROC_NR, bp->b_data); X if (r < 0) { X dev = bp->b_dev; X if (r != EOF) { X--- 260,266 ---- X X if (bp->b_dev != NO_DEV) { X pos = (long) bp->b_blocknr * BLOCK_SIZE; X! r = dev_io(rw_flag, FALSE, bp->b_dev, pos, BLOCK_SIZE, FS_PROC_NR, bp->b_data); X if (r < 0) { X dev = bp->b_dev; X if (r != EOF) { / echo x - fs/const.h.cdiff gres '^X' '' > fs/const.h.cdiff << '/' X*** const.h Thu Feb 8 00:13:32 1989 X--- ../const.h Thu Feb 7 00:07:10 1989 X*************** X*** 24,30 **** X #define NORMAL 0 /* forces get_block to do disk read */ X #define NO_READ 1 /* prevents get_block from doing disk read */ X X! #define XPIPE 0 /* used in fp_task when suspended on pipe */ X #define NO_BIT (bit_nr) 0 /* returned by alloc_bit() to signal failure */ X #define DUP_MASK 0100 /* mask to distinguish dup2 from dup */ X X--- 24,32 ---- X #define NORMAL 0 /* forces get_block to do disk read */ X #define NO_READ 1 /* prevents get_block from doing disk read */ X X! #define XPIPE -(NR_TASKS+1) /* used in fp_task when suspended on pipe */ X! #define XOPEN -(NR_TASKS+2) /* used in fp_task when suspended in open */ X! X #define NO_BIT (bit_nr) 0 /* returned by alloc_bit() to signal failure */ X #define DUP_MASK 0100 /* mask to distinguish dup2 from dup */ X / echo x - fs/device.c.cdiff gres '^X' '' > fs/device.c.cdiff << '/' X*** device.c Thu Mar 5 21:32:14 1989 X--- ../device.c Thu Mar 5 22:00:14 1989 X*************** X*** 33,41 **** X /*===========================================================================* X * dev_open * X *===========================================================================*/ X! PUBLIC int dev_open(dev, mod) X! dev_nr dev; /* which device to open */ X! int mod; /* how to open it */ X { X /* Special files may need special processing upon open. */ X X--- 33,42 ---- X /*===========================================================================* X * dev_open * X *===========================================================================*/ X! PUBLIC int dev_open(dev, mod, nonblock) X! dev_nr dev; /* which device to open */ X! int mod; /* how to open it */ X! int nonblock; /* TRUE if nonblocking open */ X { X /* Special files may need special processing upon open. */ X X*************** X*** 62,69 **** X /*===========================================================================* X * dev_io * X *===========================================================================*/ X! PUBLIC int dev_io(rw_flag, dev, pos, bytes, proc, buff) X! int rw_flag; /* READING or WRITING */ X dev_nr dev; /* major-minor device number */ X long pos; /* byte position */ X int bytes; /* how many bytes to transfer */ X--- 63,71 ---- X /*===========================================================================* X * dev_io * X *===========================================================================*/ X! PUBLIC int dev_io(rw_flag, nonblock, dev, pos, bytes, proc, buff) X! int rw_flag; /* READING or WRITING */ X! int nonblock; /* TRUE if nonblocking op */ X dev_nr dev; /* major-minor device number */ X long pos; /* byte position */ X int bytes; /* how many bytes to transfer */ X*************** X*** 81,86 **** X--- 83,89 ---- X dev_mess.PROC_NR = proc; X dev_mess.ADDRESS = buff; X dev_mess.COUNT = bytes; X+ dev_mess.TTY_FLAGS = nonblock; /* temporary kludge */ X X /* Call the task. */ X (*dmap[major].dmap_rw)(task, &dev_mess); / echo x - fs/file.h.cdiff gres '^X' '' > fs/file.h.cdiff << '/' X*** file.h Thu Feb 9 19:13:07 1989 X--- ../file.h Thu Feb 11 23:50:20 1989 X*************** X*** 4,9 **** X--- 4,10 ---- X X EXTERN struct filp { X mask_bits filp_mode; /* RW bits, telling how file is opened */ X+ int filp_flags; /* flags from open and fcntl */ X int filp_count; /* how many file descriptors share this slot? */ X struct inode *filp_ino; /* pointer to the inode */ X file_pos filp_pos; /* file position */ / echo x - fs/filedes.c.cdif gres '^X' '' > fs/filedes.c.cdif << '/' X*** filedes.c Thu Feb 12 00:47:22 1989 X--- ../filedes.c Thu Feb 12 16:38:40 1989 X*************** X*** 19,25 **** X /*===========================================================================* X * get_fd * X *===========================================================================*/ X! PUBLIC int get_fd(bits, k, fpt) X mask_bits bits; /* mode of the file to be created (RWX bits) */ X int *k; /* place to return file descriptor */ X struct filp **fpt; /* place to return filp slot */ X--- 19,26 ---- X /*===========================================================================* X * get_fd * X *===========================================================================*/ X! PUBLIC int get_fd(start, bits, k, fpt) X! int start; /* start of search (used for F_DUPFD) */ X mask_bits bits; /* mode of the file to be created (RWX bits) */ X int *k; /* place to return file descriptor */ X struct filp **fpt; /* place to return filp slot */ X*************** X*** 35,41 **** X *k = -1; /* we need a way to tell if file desc found */ X X /* Search the fproc table for a free file descriptor. */ X! for (i = 0; i < NR_FDS; i++) { X if (fp->fp_filp[i] == NIL_FILP) { X /* A file descriptor has been located. */ X *k = i; X--- 36,42 ---- X *k = -1; /* we need a way to tell if file desc found */ X X /* Search the fproc table for a free file descriptor. */ X! for (i = start; i < NR_FDS; i++) { X if (fp->fp_filp[i] == NIL_FILP) { X /* A file descriptor has been located. */ X *k = i; X*************** X*** 51,56 **** X--- 52,58 ---- X if (f->filp_count == 0) { X f->filp_mode = bits; X f->filp_pos = 0L; X+ f->filp_flags = 0; X *fpt = f; X return(OK); X } / echo x - fs/inode.c.cdiff gres '^X' '' > fs/inode.c.cdiff << '/' X*** inode.c Thu Feb 7 21:56:40 1989 X--- ../inode.c Thu Feb 12 13:38:47 1989 X*************** X*** 83,91 **** X /* i_nlinks == 0 means free the inode. */ X truncate(rip); /* return all the disk blocks */ X rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */ X! rip->i_pipe = NO_PIPE; X! free_inode(rip->i_dev, rip->i_num); X! } X X if (rip->i_dirt == DIRTY) rw_inode(rip, WRITING); X } X--- 83,92 ---- X /* i_nlinks == 0 means free the inode. */ X truncate(rip); /* return all the disk blocks */ X rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */ X! free_inode(rip->i_dev, rip->i_num); X! } X! else if (rip->i_pipe == I_PIPE) truncate(rip); X! rip->i_pipe = NO_PIPE; /* should always be cleared */ X X if (rip->i_dirt == DIRTY) rw_inode(rip, WRITING); X } / echo x - fs/misc.c.cdiff gres '^X' '' > fs/misc.c.cdiff << '/' X*** misc.c Thu Feb 6 23:40:22 1989 X--- ../misc.c Thu Feb 14 00:20:00 1989 X*************** X*** 4,9 **** X--- 4,10 ---- X * X * The entry points into this file are X * do_dup: perform the DUP system call X+ * do_fcntl: perform the FCNTL system call X * do_sync: perform the SYNC system call X * do_fork: adjust the tables after MM has performed a FORK system call X * do_exit: a process has exited; note that in the tables X*************** X*** 16,21 **** X--- 17,23 ---- X #include "../h/callnr.h" X #include "../h/com.h" X #include "../h/error.h" X+ #include "../h/fcntl.h" X #include "const.h" X #include "type.h" X #include "buf.h" X*************** X*** 35,54 **** X /* Perform the dup(fd) or dup(fd,fd2) system call. */ X X register int rfd; X! register struct fproc *rfp; X struct filp *dummy; X int r; X extern struct filp *get_filp(); X X /* Is the file descriptor valid? */ X rfd = fd & ~DUP_MASK; /* kill off dup2 bit, if on */ X! rfp = fp; X! if (get_filp(rfd) == NIL_FILP) return(err_code); X X /* Distinguish between dup and dup2. */ X if (fd == rfd) { /* bit not on */ X /* dup(fd) */ X! if ( (r = get_fd(0, &fd2, &dummy)) != OK) return(r); X } else { X /* dup2(fd, fd2) */ X if (fd2 < 0 || fd2 >= NR_FDS) return(EBADF); X--- 37,55 ---- X /* Perform the dup(fd) or dup(fd,fd2) system call. */ X X register int rfd; X! register struct filp *f; X struct filp *dummy; X int r; X extern struct filp *get_filp(); X X /* Is the file descriptor valid? */ X rfd = fd & ~DUP_MASK; /* kill off dup2 bit, if on */ X! if ((f = get_filp(rfd)) == NIL_FILP) return(err_code); X X /* Distinguish between dup and dup2. */ X if (fd == rfd) { /* bit not on */ X /* dup(fd) */ X! if ( (r = get_fd(0, 0, &fd2, &dummy)) != OK) return(r); X } else { X /* dup2(fd, fd2) */ X if (fd2 < 0 || fd2 >= NR_FDS) return(EBADF); X*************** X*** 58,68 **** X } X X /* Success. Set up new file descriptors. */ X! rfp->fp_filp[fd2] = rfp->fp_filp[rfd]; X! rfp->fp_filp[fd2]->filp_count++; X return(fd2); X } X X X /*===========================================================================* X * do_sync * X--- 59,105 ---- X } X X /* Success. Set up new file descriptors. */ X! f->filp_count++; X! fp->fp_filp[fd2] = f; X return(fd2); X } X X+ /*===========================================================================* X+ * do_fcntl * X+ *===========================================================================*/ X+ PUBLIC int do_fcntl() X+ { X+ /* Perform the fcntl(fd, request, addr) system call. */ X+ X+ register struct filp *f; X+ int new_fd; X+ struct filp *dummy; X+ int r; X+ extern struct filp *get_filp(); X+ X+ /* Is the file descriptor valid? */ X+ if ((f = get_filp(fd)) == NIL_FILP) return(err_code); X+ X+ switch (request) { X+ case F_DUPFD: /* DUP */ X+ if (addr < 0 || addr >= NR_FDS) break; X+ if ((r = get_fd(addr, 0, &new_fd, &dummy)) != OK) return(r); X+ f->filp_count++; X+ fp->fp_filp[new_fd] = f; X+ return(new_fd); X+ case F_GETFD: /* get close-on-exec flag */ X+ break; X+ case F_SETFD: /* set close-on-exec flag */ X+ break; X+ case F_GETFL: /* get file status flags */ X+ return(f->filp_flags); X+ case F_SETFL: /* set file status flags */ X+ f->filp_flags = (f->filp_flags & ~F_FL_LEGAL) | (addr & F_FL_LEGAL); X+ return(OK); X+ } X+ return(EINVAL); X+ } X+ X X /*===========================================================================* X * do_sync * X*************** X*** 165,171 **** X { X /* Perform the file system portion of the exit(status) system call. */ X X! register int i, exitee; X X /* Only MM may do the EXIT call directly. */ X if (who != MM_PROC_NR) return(ERROR); X--- 202,208 ---- X { X /* Perform the file system portion of the exit(status) system call. */ X X! register int i, exitee, task; X X /* Only MM may do the EXIT call directly. */ X if (who != MM_PROC_NR) return(ERROR); X*************** X*** 179,185 **** X tty_exit(); X X if (fp->fp_suspended == SUSPENDED) { X! if (fp->fp_task == XPIPE) susp_count--; X pro = exitee; X do_unpause(); X fp->fp_suspended = NOT_SUSPENDED; X--- 216,223 ---- X tty_exit(); X X if (fp->fp_suspended == SUSPENDED) { X! task = -fp->fp_task; X! if (task == XPIPE || task == XOPEN) susp_count--; X pro = exitee; X do_unpause(); X fp->fp_suspended = NOT_SUSPENDED; / echo x - fs/open.c gres '^X' '' > fs/open.c << '/' X/* This file contains the procedures for creating, opening, closing, and X * seeking on files. X * X * The entry points into this file are X * do_creat: perform the CREAT system call X * do_mknod: perform the MKNOD system call X * do_open: perform the OPEN system call X * do_close: perform the CLOSE system call X * do_lseek: perform the LSEEK system call X */ X X#include "../h/const.h" X#include "../h/type.h" X#include "../h/callnr.h" X#include "../h/error.h" X#include "../h/fcntl.h" X#include "const.h" X#include "type.h" X#include "buf.h" X#include "file.h" X#include "fproc.h" X#include "glo.h" X#include "inode.h" X#include "param.h" X XPRIVATE char mode_map[] = {R_BIT, W_BIT, R_BIT|W_BIT, 0}; X X/*===========================================================================* X * do_creat * X *===========================================================================*/ XPUBLIC int do_creat() X{ X/* Perform the creat(name, mode) system call. */ X /* get name */ X if (fetch_name(name, name_length, M3) != OK) return(err_code); X return common_open(O_WRONLY | O_CREAT | O_TRUNC, (mask_bits) mode); X} X X X/*===========================================================================* X * do_mknod * X *===========================================================================*/ XPUBLIC int do_mknod() X{ X/* Perform the mknod(name, mode, addr) system call. */ X X register mask_bits bits; X struct inode *new_node(); X X /* only super_user may make nodes other than fifo's */ X if (!super_user && (mode & I_TYPE != I_NAMED_PIPE)) return(EPERM); X if (fetch_name(name1, name1_length, M1) != OK) return(err_code); X bits = (mode & I_TYPE) | (mode & ALL_MODES & fp->fp_umask); X put_inode(new_node(user_path, bits, (zone_nr) addr)); X return(err_code); X} X X X/*===========================================================================* X * new_node * X *===========================================================================*/ XPRIVATE struct inode *new_node(path, bits, z0) Xchar *path; /* pointer to path name */ Xmask_bits bits; /* mode of the new inode */ Xzone_nr z0; /* zone number 0 for new inode */ X{ X/* This function is called by common_open() and do_mknod(). In both cases it X * allocates a new inode, makes a directory entry for it on the path 'path', X * and initializes it. It returns a pointer to the inode if it can do this; X * err_code is set to OK or EEXIST. If it can't, it returns NIL_INODE and X * 'err_code' contains the appropriate message. X */ X X register struct inode *rlast_dir_ptr, *rip; X register int r; X char string[NAME_SIZE]; X extern struct inode *alloc_inode(), *advance(), *last_dir(); X X /* See if the path can be opened down to the last directory. */ X if ((rlast_dir_ptr = last_dir(path, string)) == NIL_INODE) return(NIL_INODE); X X /* The final directory is accessible. Get final component of the path. */ X rip = advance(rlast_dir_ptr, string); X if ( rip == NIL_INODE && err_code == ENOENT) { X /* Last path component does not exist. Make new directory entry. */ X if ( (rip = alloc_inode(rlast_dir_ptr->i_dev, bits)) == NIL_INODE) { X /* Can't creat new inode: out of inodes. */ X put_inode(rlast_dir_ptr); X return(NIL_INODE); X } X X /* Force inode to the disk before making directory entry to make X * the system more robust in the face of a crash: an inode with X * no directory entry is much better than the opposite. X */ X rip->i_nlinks++; X rip->i_zone[0] = z0; X rw_inode(rip, WRITING); /* force inode to disk now */ X X /* New inode acquired. Try to make directory entry. */ X if ((r = search_dir(rlast_dir_ptr, string, &rip->i_num,ENTER)) != OK) { X put_inode(rlast_dir_ptr); X rip->i_nlinks--; /* pity, have to free disk inode */ X rip->i_dirt = DIRTY; /* dirty inodes are written out */ X put_inode(rip); /* this call frees the inode */ X err_code = r; X return(NIL_INODE); X } X X } else { X /* Either last component exists, or there is some problem. */ X if (rip != NIL_INODE) X r = EEXIST; X else X r = err_code; X } X X /* Return the directory inode and exit. */ X put_inode(rlast_dir_ptr); X err_code = r; X return(rip); X} X X X/*===========================================================================* X * do_open * X *===========================================================================*/ XPUBLIC int do_open() X{ X/* Perform the open(name, flags,...) system call. */ X X int create_mode = 0; X int r; X X /* check if mode flags are legal */ X if (mode & ~O_LEGAL) return(EINVAL); X X /* if O_CREAT is set, open has three parameters, otherwise two */ X if (mode & O_CREAT) { X create_mode = c_mode; X r = fetch_name(c_name, name1_length, M1); X } X else r = fetch_name(name, name_length, M3); X X if (r != OK) return(err_code); /* name was bad */ X return common_open(mode, (mask_bits) create_mode); X} X X X/*===========================================================================* X * common_open * X *===========================================================================*/ XPRIVATE int common_open(oflags, omode) Xregister int oflags; Xmask_bits omode; X{ X/* common code from do_creat and do_open */ X X register struct inode *rip; X register int r; X register mask_bits bits; X struct filp *fil_ptr; X int exist = TRUE; X int trunc; X extern struct inode *eat_path(); X X X /* remap the bottom two bits of oflags */ X bits = (mask_bits) mode_map[oflags & 3]; X /* See if file descriptor and filp slots are available. */ X if ( (r = get_fd(0, bits, &fd, &fil_ptr)) != OK) return(r); X X /* if O_CREATE is set, try to make the file */ X if (oflags & O_CREAT) { X /* Create a new inode by calling new_node(). */ X omode = I_REGULAR | (omode & ALL_MODES & fp->fp_umask); X rip = new_node(user_path, omode, NO_ZONE); X r = err_code; X if (r == OK) exist = FALSE; /* we just created the file */ X else if (r != EEXIST) return(r); /* other error */ X else exist = !(oflags & O_EXCL); /* file exists, if the O_EXCL X flag is set this is an error */ X } X else /* Scan path name. */ X if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code); X X X /* only do the normal open code if we didn't just create the file */ X if (exist) { X X /* O_TRUNC and O_CREAT implies W_BIT */ X if (trunc = (oflags & (O_TRUNC | O_CREAT))) bits |= W_BIT; X X /* check protections */ X if ((r = forbidden(rip, bits, 0)) == OK) { X /* X * Opening regular files, X * directories and special files are different. X */ X switch (rip->i_mode & I_TYPE) { X case I_REGULAR: /* truncate regular file if O_TRUNC */ X if (trunc) truncate(rip); X break; X X case I_DIRECTORY: /* can only read directories */ X r = bits & W_BIT ? EISDIR : OK; X break; X X case I_CHAR_SPECIAL: X case I_BLOCK_SPECIAL: X r = dev_open((dev_nr) rip->i_zone[0], (int) bits, X oflags & O_NONBLOCK); X break; X X case I_NAMED_PIPE: X r = pipe_open(rip, bits, oflags); X break; X } X } X } X X /* If error, return inode. */ X if (r != OK) { X put_inode(rip); X return(r); X } X X /* Claim the file descriptor and filp slot and fill them in. */ X fp->fp_filp[fd] = fil_ptr; X fil_ptr->filp_count = 1; X fil_ptr->filp_ino = rip; X fil_ptr->filp_flags = oflags; X return(fd); X} X X/*===========================================================================* X * pipe_open * X *===========================================================================*/ XPRIVATE int pipe_open(rip, bits, oflags) Xregister struct inode *rip; Xregister mask_bits bits; Xregister int oflags; X{ X/* this function is called from do_creat and do_open, it checks if X * there is at least one reader/writer pair for the pipe, if not X * it suspends the caller, otherwise it revives all other blocked X * processes hanging on the pipe. X */ X X if (find_filp(rip, bits & W_BIT ? R_BIT : W_BIT) == NIL_FILP) { X if (oflags & O_NONBLOCK) X return bits & W_BIT ? ENXIO : OK; X suspend(XOPEN); /* suspend caller */ X } X else if (susp_count > 0) {/* revive blocked processes */ X release(rip, OPEN, susp_count); X release(rip, CREAT, susp_count); X } X rip->i_pipe = I_PIPE; X X return OK ; X} X X X/*===========================================================================* X * do_close * X *===========================================================================*/ XPUBLIC int do_close() X{ X/* Perform the close(fd) system call. */ X X register struct filp *rfilp; X register struct inode *rip; X int rw; X int mode_word; X extern struct filp *get_filp(); X X /* First locate the inode that belongs to the file descriptor. */ X if ( (rfilp = get_filp(fd)) == NIL_FILP) return(err_code); X rip = rfilp->filp_ino; /* 'rip' points to the inode */ X X /* Check to see if the file is special. */ X mode_word = rip->i_mode & I_TYPE; X if (mode_word == I_CHAR_SPECIAL || mode_word == I_BLOCK_SPECIAL) { X if (mode_word == I_BLOCK_SPECIAL) { X /* Invalidate cache entries unless special is mounted or ROOT.*/ X do_sync(); /* purge cache */ X if (mounted(rip) == FALSE) invalidate((dev_nr) rip->i_zone[0]); X } X dev_close((dev_nr) rip->i_zone[0]); X } X X /* If the inode being closed is a pipe, release everyone hanging on it. */ X if (rip->i_pipe) { X rw = (rfilp->filp_mode & R_BIT ? WRITE : READ); X release(rip, rw, NR_PROCS); X } X X /* If a write has been done, the inode is already marked as DIRTY. */ X if (--rfilp->filp_count == 0) put_inode(rip); X X fp->fp_filp[fd] = NIL_FILP; X return(OK); X} X X X/*===========================================================================* X * do_lseek * X *===========================================================================*/ XPUBLIC int do_lseek() X{ X/* Perform the lseek(ls_fd, offset, whence) system call. */ X X register struct filp *rfilp; X register file_pos pos; X extern struct filp *get_filp(); X X /* Check to see if the file descriptor is valid. */ X if ( (rfilp = get_filp(ls_fd)) == NIL_FILP) return(err_code); X X /* No lseek on pipes. */ X if (rfilp->filp_ino->i_pipe == I_PIPE) return(ESPIPE); X X /* The value of 'whence' determines the algorithm to use. */ X switch(whence) { X case 0: pos = offset; break; X case 1: pos = rfilp->filp_pos + offset; break; X case 2: pos = rfilp->filp_ino->i_size + offset; break; X default: return(EINVAL); X } X if (pos < (file_pos) 0) return(EINVAL); X X rfilp->filp_ino->i_seek = ISEEK; /* inhibit read ahead */ X rfilp->filp_pos = pos; X X reply_l1 = pos; /* insert the long into the output message */ X return(OK); X} / echo x - fs/param.h.cdiff gres '^X' '' > fs/param.h.cdiff << '/' X*** param.h Thu Feb 9 23:15:02 1989 X--- ../param.h Thu Feb 9 23:25:50 1989 X*************** X*** 16,21 **** X--- 16,23 ---- X #define ls_fd m.m2_i1 X #define mk_mode m.m1_i2 X #define mode m.m3_i2 X+ #define c_mode m.m1_i3 X+ #define c_name m.m1_p1 X #define name m.m3_p1 X #define name1 m.m1_p1 X #define name2 m.m1_p2 / echo x - fs/pipe.c.cdiff gres '^X' '' > fs/pipe.c.cdiff << '/' X*** pipe.c Thu Feb 6 01:10:36 1989 X--- ../pipe.c Thu Feb 12 22:36:07 1989 X*************** X*** 19,24 **** X--- 19,25 ---- X #include "../h/com.h" X #include "../h/error.h" X #include "../h/signal.h" X+ #include "../h/fcntl.h" X #include "const.h" X #include "type.h" X #include "file.h" X*************** X*** 46,55 **** X X /* Acquire two file descriptors. */ X rfp = fp; X! if ( (r = get_fd(R_BIT, &fil_des[0], &fil_ptr0)) != OK) return(r); X! rfp->fp_filp[fil_des[0]] = fil_ptr0; X! fil_ptr0->filp_count = 1; X! if ( (r = get_fd(W_BIT, &fil_des[1], &fil_ptr1)) != OK) { X rfp->fp_filp[fil_des[0]] = NIL_FILP; X fil_ptr0->filp_count = 0; X return(r); X--- 47,56 ---- X X /* Acquire two file descriptors. */ X rfp = fp; X! if ( (r = get_fd(0, R_BIT, &fil_des[0], &fil_ptr0)) != OK) return(r); X! rfp->fp_filp[fil_des[0]] = fil_ptr0; X! fil_ptr0->filp_count = 1; X! if ( (r = get_fd(0, W_BIT, &fil_des[1], &fil_ptr1)) != OK) { X rfp->fp_filp[fil_des[0]] = NIL_FILP; X fil_ptr0->filp_count = 0; X return(r); X*************** X*** 81,89 **** X /*===========================================================================* X * pipe_check * X *===========================================================================*/ X! PUBLIC int pipe_check(rip, rw_flag, virgin, bytes, position) X! register struct inode *rip; /* the inode of the pipe */ X! int rw_flag; /* READING or WRITING */ X int virgin; /* 1 if no data transferred yet, else 0 */ X register int bytes; /* bytes to be read or written (all chunks) */ X register file_pos *position; /* pointer to current file position */ X--- 82,91 ---- X /*===========================================================================* X * pipe_check * X *===========================================================================*/ X! PUBLIC int pipe_check(rip, rw_flag, oflags, virgin, bytes, position) X! register struct inode *rip; /* the inode of the pipe */ X! int rw_flag; /* READING or WRITING */ X! int oflags; /* flags set by open or fcntl */ X int virgin; /* 1 if no data transferred yet, else 0 */ X register int bytes; /* bytes to be read or written (all chunks) */ X register file_pos *position; /* pointer to current file position */ X*************** X*** 96,113 **** X X extern struct filp *find_filp(); X X /* If reading, check for empty pipe. */ X if (rw_flag == READING) { X if (*position >= rip->i_size) { X /* Process is reading from an empty pipe. */ X if (find_filp(rip, W_BIT) != NIL_FILP) { X /* Writer exists; suspend rdr if no data already read.*/ X! if (virgin) suspend(XPIPE); /* block reader */ X! X! /* If need be, activate sleeping writer. */ X! if (susp_count > 0) release(rip, WRITE, 1); X! } X! return(0); X } X } else { X /* Process is writing to a pipe. */ X--- 98,119 ---- X X extern struct filp *find_filp(); X X+ int r = 0; X+ X /* If reading, check for empty pipe. */ X if (rw_flag == READING) { X if (*position >= rip->i_size) { X /* Process is reading from an empty pipe. */ X if (find_filp(rip, W_BIT) != NIL_FILP) { X /* Writer exists; suspend rdr if no data already read.*/ X! if (virgin) { X! if (oflags & O_NONBLOCK) r = EAGAIN; X! else suspend(XPIPE); /* block reader */ X! } X! /* If need be, activate sleeping writers. */ X! if (susp_count > 0) release(rip, WRITE, susp_count); X! } X! return(r); X } X } else { X /* Process is writing to a pipe. */ X*************** X*** 119,130 **** X } X X if (*position + bytes > PIPE_SIZE) { X suspend(XPIPE); /* stop writer -- pipe full */ X return(0); X } X X! /* Writing to an empty pipe. Search for suspended reader. */ X! if (*position == 0) release(rip, READ, 1); X } X X return(1); X--- 125,137 ---- X } X X if (*position + bytes > PIPE_SIZE) { X+ if (oflags & O_NONBLOCK) return(EAGAIN); X suspend(XPIPE); /* stop writer -- pipe full */ X return(0); X } X X! /* Writing to an empty pipe. Search for suspended readers. */ X! if (*position == 0) release(rip, READ, susp_count); X } X X return(1); X*************** X*** 143,149 **** X * but they are needed for pipes, and it is not worth making the distinction.) X */ X X! if (task == XPIPE) susp_count++; /* count procs suspended on pipe */ X fp->fp_suspended = SUSPENDED; X fp->fp_fd = fd << 8 | fs_call; X fp->fp_buffer = buffer; X--- 150,156 ---- X * but they are needed for pipes, and it is not worth making the distinction.) X */ X X! if (task == XPIPE || task == XOPEN) susp_count++;/* count procs suspended on pipe */ X fp->fp_suspended = SUSPENDED; X fp->fp_fd = fd << 8 | fs_call; X fp->fp_buffer = buffer; X*************** X*** 192,197 **** X--- 199,205 ---- X */ X X register struct fproc *rfp; X+ register int task; X X if (proc_nr < 0 || proc_nr >= NR_PROCS) panic("revive err", proc_nr); X rfp = &fproc[proc_nr]; X*************** X*** 202,216 **** X * For TTY revival, the work is already done, for pipes it is not: the proc X * must be restarted so it can try again. X */ X! if (rfp->fp_task == XPIPE) { X /* Revive a process suspended on a pipe. */ X rfp->fp_revived = REVIVING; X reviving++; /* process was waiting on pipe */ X } else { X! /* Revive a process suspended on TTY or other device. */ X! rfp->fp_suspended = NOT_SUSPENDED; X! rfp->fp_nbytes = bytes; /* pretend it only wants what there is */ X! reply(proc_nr, bytes); /* unblock the process */ X } X } X X--- 210,229 ---- X * For TTY revival, the work is already done, for pipes it is not: the proc X * must be restarted so it can try again. X */ X! task = -rfp->fp_task; X! if (task == XPIPE) { X /* Revive a process suspended on a pipe. */ X rfp->fp_revived = REVIVING; X reviving++; /* process was waiting on pipe */ X } else { X! rfp->fp_suspended = NOT_SUSPENDED; X! if (task == XOPEN) /* process blocked in open or create */ X! reply(proc_nr, rfp->fp_fd>>8); X! else { X! /* Revive a process suspended on TTY or other device. */ X! rfp->fp_nbytes = bytes; /* pretend it only wants what there is */ X! reply(proc_nr, bytes); /* unblock the process */ X! } X } X } X X*************** X*** 238,253 **** X task = -rfp->fp_task; X X if (task != XPIPE) { X! fild = (rfp->fp_fd >> 8) & BYTE; /* extract file descriptor */ X! if (fild < 0 || fild >= NR_FDS) panic("unpause err 2", NO_NUM); X! f = rfp->fp_filp[fild]; X! dev = f->filp_ino->i_zone[0]; /* device on which proc is hanging */ X! mess.TTY_LINE = (dev >> MINOR) & BYTE; X! mess.PROC_NR = proc_nr; X! mess.m_type = CANCEL; X! rw_dev(task, &mess); X! revive(proc_nr, EINTR); /* signal interrupted call */ X! } X! X! return(OK); X! } X--- 251,268 ---- X task = -rfp->fp_task; X X if (task != XPIPE) { X! if (task != XOPEN) { X! fild = (rfp->fp_fd >> 8) & BYTE;/* extract file descriptor */ X! if (fild < 0 || fild >= NR_FDS) panic("unpause err 2", NO_NUM); X! f = rfp->fp_filp[fild]; X! dev = f->filp_ino->i_zone[0]; /* device on which proc is hanging */ X! mess.TTY_LINE = (dev >> MINOR) & BYTE; X! mess.PROC_NR = proc_nr; X! mess.m_type = CANCEL; X! rw_dev(task, &mess); X! } X! rfp->fp_suspended = NOT_SUSPENDED; X! reply(proc_nr, EINTR); /* signal interrupted call */ X! } X! return(OK); X! } / echo x - fs/read.c.cdiff gres '^X' '' > fs/read.c.cdiff << '/' X*** read.c Thu Feb 7 20:07:23 1989 X--- ../read.c Thu Mar 5 21:29:26 1989 X*************** X*** 15,20 **** X--- 15,21 ---- X #include "../h/type.h" X #include "../h/com.h" X #include "../h/error.h" X+ #include "../h/fcntl.h" X #include "const.h" X #include "type.h" X #include "buf.h" X*************** X*** 52,59 **** X register struct filp *f; X register file_pos bytes_left, f_size; X register unsigned off, cum_io; X! file_pos position; X! int r, chunk, virg, mode_word, usr, seg; X struct filp *wf; X extern struct super_block *get_super(); X extern struct filp *find_filp(), *get_filp(); X--- 53,61 ---- X register struct filp *f; X register file_pos bytes_left, f_size; X register unsigned off, cum_io; X! register int oflags; X! file_pos position; X! int r, chunk, virg, mode_word, usr, seg, regular; X struct filp *wf; X extern struct super_block *get_super(); X extern struct filp *find_filp(), *get_filp(); X*************** X*** 77,105 **** X return(EBADF); X position = f->filp_pos; X if (position < (file_pos) 0) return(EINVAL); X rip = f->filp_ino; X f_size = rip->i_size; X r = OK; X cum_io = 0; X virg = TRUE; X mode_word = rip->i_mode & I_TYPE; X if (mode_word == I_BLOCK_SPECIAL && f_size == 0) f_size = MAX_P_LONG; X rdwt_err = OK; /* set to EIO if disk error occurs */ X X /* Check for character special files. */ X if (mode_word == I_CHAR_SPECIAL) { X! if ((r = dev_io(rw_flag, (dev_nr) rip->i_zone[0], (long) position, X! nbytes, who, buffer)) >= 0) { X cum_io = r; X position += r; X r = OK; X } X } else { X if (rw_flag == WRITING && mode_word != I_BLOCK_SPECIAL) { X /* Check in advance to see if file will grow too big. */ X if (position > get_super(rip->i_dev)->s_max_size - nbytes ) X return(EFBIG); X X /* Clear the zone containing present EOF if hole about X * to be created. This is necessary because all unwritten X * blocks prior to the EOF must read as zeros. X--- 79,114 ---- X return(EBADF); X position = f->filp_pos; X if (position < (file_pos) 0) return(EINVAL); X+ oflags = f->filp_flags; X rip = f->filp_ino; X f_size = rip->i_size; X r = OK; X cum_io = 0; X virg = TRUE; X mode_word = rip->i_mode & I_TYPE; X+ regular = mode_word == I_REGULAR || mode_word == I_NAMED_PIPE; X+ X if (mode_word == I_BLOCK_SPECIAL && f_size == 0) f_size = MAX_P_LONG; X rdwt_err = OK; /* set to EIO if disk error occurs */ X X /* Check for character special files. */ X if (mode_word == I_CHAR_SPECIAL) { X! if ((r = dev_io(rw_flag, oflags & O_NONBLOCK, (dev_nr) rip->i_zone[0], X! (long) position, nbytes, who, buffer)) >= 0) { X cum_io = r; X position += r; X r = OK; X } X } else { X+ X if (rw_flag == WRITING && mode_word != I_BLOCK_SPECIAL) { X /* Check in advance to see if file will grow too big. */ X if (position > get_super(rip->i_dev)->s_max_size - nbytes ) X return(EFBIG); X X+ /* check for O_APPEND flag */ X+ if (oflags & O_APPEND) position = f_size; X+ X /* Clear the zone containing present EOF if hole about X * to be created. This is necessary because all unwritten X * blocks prior to the EOF must read as zeros. X*************** X*** 108,114 **** X } X X /* Pipes are a little different. Check. */ X! if (rip->i_pipe && (r = pipe_check(rip, rw_flag, virg, X nbytes, &position)) <= 0) return(r); X X /* Split the transfer into chunks that don't span two blocks. */ X--- 117,123 ---- X } X X /* Pipes are a little different. Check. */ X! if (rip->i_pipe && (r = pipe_check(rip, rw_flag, oflags, virg, X nbytes, &position)) <= 0) return(r); X X /* Split the transfer into chunks that don't span two blocks. */ X*************** X*** 140,147 **** X X /* On write, update file size and access time. */ X if (rw_flag == WRITING) { X! if (mode_word != I_CHAR_SPECIAL && mode_word != I_BLOCK_SPECIAL && X! position > f_size) X rip->i_size = position; X rip->i_modtime = clock_time(); X rip->i_dirt = DIRTY; X--- 149,155 ---- X X /* On write, update file size and access time. */ X if (rw_flag == WRITING) { X! if ((regular || mode_word == I_DIRECTORY) && position > f_size) X rip->i_size = position; X rip->i_modtime = clock_time(); X rip->i_dirt = DIRTY; X*************** X*** 157,167 **** X X /* Check to see if read-ahead is called for, and if so, set it up. */ X if (rw_flag == READING && rip->i_seek == NO_SEEK && position % BLOCK_SIZE == 0 X! && (mode_word == I_REGULAR || mode_word == I_DIRECTORY)) { X rdahed_inode = rip; X rdahedpos = position; X } X! if (mode_word == I_REGULAR) rip->i_seek = NO_SEEK; X X if (rdwt_err != OK) r = rdwt_err; /* check for disk error */ X if (rdwt_err == EOF) r = cum_io; X--- 165,175 ---- X X /* Check to see if read-ahead is called for, and if so, set it up. */ X if (rw_flag == READING && rip->i_seek == NO_SEEK && position % BLOCK_SIZE == 0 X! && (regular || mode_word == I_DIRECTORY)) { X rdahed_inode = rip; X rdahedpos = position; X } X! if (regular) rip->i_seek = NO_SEEK; X X if (rdwt_err != OK) r = rdwt_err; /* check for disk error */ X if (rdwt_err == EOF) r = cum_io; / echo x - fs/table.c.cdiff gres '^X' '' > fs/table.c.cdiff << '/' X*** table.c Thu Feb 11 02:01:02 1989 X--- ../table.c Thu Feb 11 02:01:10 1989 X*************** X*** 27,33 **** X extern do_ioctl(), do_link(), do_lseek(), do_mknod(), do_mount(), do_open(); X extern do_pipe(), do_read(), do_revive(), do_set(), do_stat(), do_stime(); X extern do_sync(), do_time(), do_tims(), do_umask(), do_umount(), do_unlink(); X! extern do_unpause(), do_utime(), do_write(), no_call(), no_sys(); X X extern char fstack[]; X char *stackpt = &fstack[FS_STACK_BYTES]; /* initial stack pointer */ X--- 27,33 ---- X extern do_ioctl(), do_link(), do_lseek(), do_mknod(), do_mount(), do_open(); X extern do_pipe(), do_read(), do_revive(), do_set(), do_stat(), do_stime(); X extern do_sync(), do_time(), do_tims(), do_umask(), do_umount(), do_unlink(); X! extern do_unpause(), do_utime(), do_write(), do_fcntl(), no_call(), no_sys(); X X extern char fstack[]; X char *stackpt = &fstack[FS_STACK_BYTES]; /* initial stack pointer */ X*************** X*** 88,94 **** X no_sys, /* 52 = (phys) */ X no_sys, /* 53 = (lock) */ X do_ioctl, /* 54 = ioctl */ X! no_sys, /* 55 = unused */ X no_sys, /* 56 = (mpx) */ X no_sys, /* 57 = unused */ X no_sys, /* 58 = unused */ X--- 88,94 ---- X no_sys, /* 52 = (phys) */ X no_sys, /* 53 = (lock) */ X do_ioctl, /* 54 = ioctl */ X! do_fcntl, /* 55 = fcntl */ X no_sys, /* 56 = (mpx) */ X no_sys, /* 57 = unused */ X no_sys, /* 58 = unused */ / -- ---------------------------------------------------------------------------- UUCP: ...mcvax!cernvax!forty2!poole Simon Poole BITNET: K538915@CZHRZU1A ----------------------------------------------------------------------------