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
----------------------------------------------------------------------------