|
|
1.1 ! root 1: /* $Header: /y/coh.386/RCS/fd.c,v 1.5 93/04/14 10:06:26 root Exp $ */ ! 2: /* (lgl- ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.37 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: -lgl) */ ! 15: /* ! 16: * Coherent. ! 17: * File descriptor routines. ! 18: * ! 19: * $Log: fd.c,v $ ! 20: * Revision 1.5 93/04/14 10:06:26 root ! 21: * r75 ! 22: * ! 23: * Revision 1.3 92/06/10 12:52:39 hal ! 24: * First record locking changes. ! 25: * ! 26: * Revision 1.2 92/01/06 11:59:07 hal ! 27: * Compile with cc.mwc. ! 28: * ! 29: * Revision 1.1 88/03/24 16:13:43 src ! 30: * Initial revision ! 31: * ! 32: */ ! 33: #include <sys/coherent.h> ! 34: #include <errno.h> ! 35: #include <fcntl.h> ! 36: #include <sys/fd.h> ! 37: #include <sys/inode.h> ! 38: ! 39: /* ! 40: * Given a file number, return the file descriptor. ! 41: */ ! 42: FD * ! 43: fdget(fd) ! 44: register unsigned fd; ! 45: { ! 46: register FD *fdp; ! 47: ! 48: if (fd>=NOFILE || (fdp=u.u_filep[fd])==NULL) { ! 49: u.u_error = EBADF; ! 50: return (NULL); ! 51: } ! 52: return (fdp); ! 53: } ! 54: ! 55: /* ! 56: * NIGEL: To help fix some stupid bugs with uopen (), I have split the ! 57: * fdopen () routine into three parts; one for resource allocation, one for ! 58: * setting the inode member and opening the inode, and one for finishing up ! 59: * an open. ! 60: */ ! 61: ! 62: /* ! 63: * This function finds a free slot in the process file descriptor table and ! 64: * fills it in with a partially initialised entry. ! 65: * ! 66: * This function returns a file descriptor number on success, -1 on failure. ! 67: */ ! 68: ! 69: int fdalloc () ! 70: { ! 71: int i; ! 72: ! 73: for (i = 0 ; i < sizeof (u.u_filep) / sizeof (* u.u_filep) ; i ++) { ! 74: if (u.u_filep [i] == NULL) { ! 75: FD * filep; ! 76: ! 77: if ((filep = u.u_filep [i] = kalloc (sizeof (FD))) ! 78: == NULL) { ! 79: /* ! 80: * Insufficient resources! ! 81: */ ! 82: ! 83: u.u_error = EAGAIN; ! 84: return -1; ! 85: } ! 86: ! 87: filep->f_flag = 0; ! 88: filep->f_flag2 = 0; ! 89: filep->f_refc = 0; ! 90: filep->f_seek = 0; ! 91: filep->f_ip = NULL; ! 92: ! 93: return i; ! 94: } ! 95: } ! 96: ! 97: u.u_error = EMFILE; ! 98: return -1; ! 99: } ! 100: ! 101: /* ! 102: * This function performs the second half of the file open process by filling ! 103: * in the inode member of the file table entry and requesting that the inode be ! 104: * opened. ! 105: * ! 106: * This function returns -1 on error, 0 on success. ! 107: */ ! 108: ! 109: int fdinit (fd, ip, mode) ! 110: int fd; ! 111: INODE * ip; ! 112: int mode; ! 113: { ! 114: FD * filep; ! 115: ! 116: if ((filep = fdget (fd)) == NULL) ! 117: return -1; ! 118: ! 119: iopen (ip, mode); ! 120: ! 121: if (u.u_error != 0) ! 122: return -1; ! 123: ! 124: filep->f_ip = ip; ! 125: filep->f_flag = mode; ! 126: filep->f_refc = 1; ! 127: ! 128: return 0; ! 129: } ! 130: ! 131: ! 132: /* ! 133: * This function finalises an open; normally this does nothing, but if there ! 134: * has been an error, this code will take care of deallocating the entry. ! 135: * ! 136: * This function returns the file descriptor number on success, or -1 on error. ! 137: */ ! 138: ! 139: int fdfinish (fd) ! 140: int fd; ! 141: { ! 142: FD * filep; ! 143: ! 144: if ((filep = fdget (fd)) == NULL) ! 145: return -1; ! 146: ! 147: if (filep->f_refc == 0) { ! 148: /* ! 149: * The open never really succeeded, release resources. ! 150: */ ! 151: ! 152: kfree (filep); ! 153: u.u_filep [fd] = NULL; ! 154: fd = -1; ! 155: } ! 156: ! 157: return fd; ! 158: } ! 159: ! 160: ! 161: /* ! 162: * Given an inode, and a mode containing permission flags, open the ! 163: * inode with the appropriate permissions and return a file descriptor ! 164: * containing it. ! 165: */ ! 166: fdopen(ip, mode) ! 167: register INODE *ip; ! 168: { ! 169: int fd; ! 170: ! 171: if ((fd = fdalloc ()) >= 0) { ! 172: fdinit (fd, ip, mode); ! 173: fd = fdfinish (fd); ! 174: } ! 175: ! 176: return fd; ! 177: } ! 178: ! 179: ! 180: /* ! 181: * Close the given file number. ! 182: */ ! 183: fdclose(fd) ! 184: register unsigned fd; ! 185: { ! 186: register FD *fdp; ! 187: static FLOCK flock = { F_UNLCK, 0, 0, 0 }; ! 188: ! 189: if (fd>=NOFILE || (fdp=u.u_filep[fd])==NULL) { ! 190: u.u_error = EBADF; ! 191: return; ! 192: } ! 193: if (fdp->f_ip->i_rl != NULL) ! 194: rlock(fdp, F_SETLK, &flock); /* delete all record locks */ ! 195: u.u_filep[fd] = NULL; ! 196: if (fdp->f_refc == 0) ! 197: panic("fdclose()"); ! 198: if (--fdp->f_refc == 0) { ! 199: iclose(fdp->f_ip, fdp->f_flag); ! 200: kfree(fdp); ! 201: } ! 202: } ! 203: ! 204: /* ! 205: * Assuming we have made a copy of the user area, increment the reference ! 206: * of all open files. (used in fork). ! 207: */ ! 208: fdadupl() ! 209: { ! 210: register FD **fdpp; ! 211: register FD *fdp; ! 212: ! 213: for (fdpp=u.u_filep; fdpp<&u.u_filep[NOFILE]; fdpp++) { ! 214: if ((fdp=*fdpp) == NULL) ! 215: continue; ! 216: fdp->f_refc++; ! 217: } ! 218: } ! 219: ! 220: /* ! 221: * Close all open files in the current process. ! 222: */ ! 223: fdaclose() ! 224: { ! 225: register int fd; ! 226: ! 227: for (fd=0; fd<NOFILE; fd++) { ! 228: if (u.u_filep[fd] == NULL) ! 229: continue; ! 230: fdclose(fd); ! 231: } ! 232: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.