Annotation of coherent/b/STREAMS/coh.386/fd.c, revision 1.1.1.1

1.1       root        1: /* $Header: /ker/coh.386/RCS/fd.c,v 2.4 93/07/26 15:09:56 nigel 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 2.4  93/07/26  15:09:56  nigel
                     21:  * Nigel's R80
                     22:  * 
                     23:  * Revision 1.5  93/04/14  10:06:26  root
                     24:  * r75
                     25:  * 
                     26:  * Revision 1.3  92/06/10  12:52:39  hal
                     27:  * First record locking changes.
                     28:  * 
                     29:  * Revision 1.2  92/01/06  11:59:07  hal
                     30:  * Compile with cc.mwc.
                     31:  * 
                     32:  * Revision 1.1        88/03/24  16:13:43      src
                     33:  * Initial revision
                     34:  * 
                     35:  */
                     36: 
                     37: #include <common/ccompat.h>
                     38: #include <sys/debug.h>
                     39: #include <sys/coherent.h>
                     40: #include <sys/errno.h>
                     41: #include <fcntl.h>
                     42: #include <sys/fd.h>
                     43: #include <sys/inode.h>
                     44: 
                     45: /*
                     46:  * Operations for converting from tagged to untagged "pointer to system file
                     47:  * table entry" and vice versa.
                     48:  */
                     49: 
                     50: enum {
                     51:        TAGMASK         = sizeof (int) - 1
                     52: };
                     53: 
                     54: #define        MAKE_TAGGED_FD(untag,flag) \
                     55:        (ASSERT (((int) (untag) & TAGMASK) == 0), \
                     56:         ASSERT (((flag) & ~ TAGMASK) == 0), \
                     57:         (tagfd_t) ((unsigned long) (untag) + (flag)))
                     58: 
                     59: #define        GET_UNTAGGED_FD(tagged) \
                     60:        ((FD *) ((unsigned long) (tagged) & ~ TAGMASK))
                     61: 
                     62: #define        GET_TAGGED_FLAG(tagged) \
                     63:        ((int) (tagged) & TAGMASK)
                     64: 
                     65: /*
                     66:  * Given a file number, return the file descriptor. Now that file descriptors
                     67:  * stored in the U area have their low bits tagged to store flag information
                     68:  * that is FD-specific (gotta avoid that space crunch in the U area), this
                     69:  * interface deals with masking out any extra stuff and returning a plain
                     70:  * pointer.
                     71:  */
                     72: 
                     73: #if    __USE_PROTO__
                     74: FD * fdget (fd_t fd)
                     75: #else
                     76: FD *
                     77: fdget (fd)
                     78: fd_t           fd;
                     79: #endif
                     80: {
                     81:        FD            * fdp;
                     82: 
                     83:        if (fd >= NOFILE ||
                     84:            (fdp = GET_UNTAGGED_FD (u.u_filep [fd])) == NULL) {
                     85:                u.u_error = EBADF;
                     86:                return NULL;
                     87:        }
                     88:        return fdp;
                     89: }
                     90: 
                     91: 
                     92: /*
                     93:  * Return tag bits from file descriptor.
                     94:  */
                     95: 
                     96: #if    __USE_PROTO__
                     97: int fdgetflags (fd_t fd)
                     98: #else
                     99: int
                    100: fdgetflags (fd)
                    101: fd_t           fd;
                    102: #endif
                    103: {
                    104:        if (fd >= NOFILE || u.u_filep [fd] == NULL) {
                    105:                u.u_error = EBADF;
                    106:                return -1;
                    107:        }
                    108:        return GET_TAGGED_FLAG (u.u_filep [fd]);
                    109: }
                    110: 
                    111: 
                    112: /*
                    113:  * This function allows clients to set the flag bits.
                    114:  */
                    115: 
                    116: #if    __USE_PROTO__
                    117: int fdsetflags (fd_t fd, int flags)
                    118: #else
                    119: int
                    120: fdsetflags (fd, flags)
                    121: fd_t           fd;
                    122: int            flags;
                    123: #endif
                    124: {
                    125:        if (fd >= NOFILE || u.u_filep [fd] == NULL) {
                    126:                u.u_error = EBADF;
                    127:                return -1;
                    128:        }
                    129:        if ((flags & ~ TAGMASK) != 0) {
                    130:                u.u_error = EINVAL;
                    131:                return -1;
                    132:        }
                    133: 
                    134:        u.u_filep [fd] = MAKE_TAGGED_FD (GET_UNTAGGED_FD (u.u_filep [fd]),
                    135:                                         flags);
                    136:        return 0;
                    137: }
                    138: 
                    139: 
                    140: /*
                    141:  * This function performs something similar to the F_DUPFD function of
                    142:  * fcntl ()... this functionality is needed several places internally.
                    143:  */
                    144: 
                    145: #if    __USE_PROTO__
                    146: fd_t fddup (fd_t old, fd_t base)
                    147: #else
                    148: fd_t
                    149: fddup (old, base)
                    150: fd_t           old;
                    151: fd_t           base;
                    152: #endif
                    153: {
                    154:        while (base < NOFILE)
                    155:                if (u.u_filep [base] == NULL) {
                    156:                        FD            * fdp = fdget (old);
                    157: 
                    158:                        if (fdp == NULL)
                    159:                                return ERROR_FD;
                    160:                        u.u_filep [base] = MAKE_TAGGED_FD (fdp, 0);
                    161:                        fdp->f_refc ++;
                    162:                        return base;
                    163:                } else
                    164:                        base ++;
                    165: 
                    166:        u.u_error = EMFILE;
                    167:        return ERROR_FD;
                    168: }
                    169: 
                    170: 
                    171: /*
                    172:  * This function finds a free slot in the process file descriptor table and
                    173:  * fills it in with a partially initialised entry.
                    174:  *
                    175:  * This function returns a file descriptor number on success, -1 on failure.
                    176:  */
                    177: 
                    178: #if    __USE_PROTO__
                    179: fd_t fdalloc (void)
                    180: #else
                    181: fd_t
                    182: fdalloc ()
                    183: #endif
                    184: {
                    185:        int             i;
                    186: 
                    187:        for (i = 0 ; i < sizeof (u.u_filep) / sizeof (* u.u_filep) ; i ++) {
                    188:                if (u.u_filep [i] == NULL) {
                    189:                        FD            * filep;
                    190: 
                    191:                        if ((filep = kalloc (sizeof (FD))) == NULL) {
                    192:                                /*
                    193:                                 * Insufficient resources!
                    194:                                 */
                    195: 
                    196:                                u.u_error = EAGAIN;
                    197:                                return ERROR_FD;
                    198:                        }
                    199: 
                    200:                        u.u_filep [i] = MAKE_TAGGED_FD (filep, 0);
                    201: 
                    202:                        filep->f_flag = 0;
                    203:                        filep->f_refc = 0;
                    204:                        filep->f_seek = 0;
                    205:                        filep->f_ip = NULL;
                    206: 
                    207:                        return i;
                    208:                }
                    209:        }
                    210: 
                    211:        u.u_error = EMFILE;
                    212:        return ERROR_FD;
                    213: }
                    214: 
                    215: 
                    216: /*
                    217:  * This function performs the second half of the file open process by filling
                    218:  * in the inode member of the file table entry and requesting that the inode be
                    219:  * opened.
                    220:  *
                    221:  * This function returns -1 on error, 0 on success.
                    222:  */
                    223: 
                    224: #if    __USE_PROTO__
                    225: int fdinit (fd_t fd, INODE * ip, int mode)
                    226: #else
                    227: int
                    228: fdinit (fd, ip, mode)
                    229: fd_t           fd;
                    230: INODE        * ip;
                    231: int            mode;
                    232: #endif
                    233: {
                    234:        FD            * filep;
                    235: 
                    236:        if ((filep = fdget (fd)) == NULL)
                    237:                return -1;
                    238: 
                    239:        iopen (ip, mode);
                    240: 
                    241:        if (u.u_error != 0)
                    242:                return -1;
                    243: 
                    244:        filep->f_ip = ip;
                    245:        filep->f_flag = mode;
                    246:        filep->f_refc = 1;
                    247: 
                    248:        return 0;
                    249: }
                    250: 
                    251: 
                    252: /*
                    253:  * This function finalises an open; normally this does nothing, but if there
                    254:  * has been an error, this code will take care of deallocating the entry.
                    255:  *
                    256:  * This function returns the file descriptor number on success, or -1 on error.
                    257:  */
                    258: 
                    259: #if    __USE_PROTO__
                    260: fd_t fdfinish (fd_t fd)
                    261: #else
                    262: fd_t
                    263: fdfinish (fd)
                    264: fd_t           fd;
                    265: #endif
                    266: {
                    267:        FD            * filep;
                    268: 
                    269:        if ((filep = fdget (fd)) == NULL)
                    270:                return ERROR_FD;
                    271: 
                    272:        if (filep->f_refc == 0) {
                    273:                /*
                    274:                 * The open never really succeeded, release resources.
                    275:                 */
                    276: 
                    277:                kfree (filep);
                    278:                u.u_filep [fd] = NULL;
                    279:                fd = ERROR_FD;
                    280:        }
                    281: 
                    282:        return fd;
                    283: }
                    284: 
                    285: 
                    286: /*
                    287:  * Given an inode, and a mode containing permission flags, open the
                    288:  * inode with the appropriate permissions and return a file descriptor
                    289:  * containing it.
                    290:  */
                    291: 
                    292: #if    __USE_PROTO__
                    293: fd_t fdopen (INODE * ip, int mode)
                    294: #else
                    295: fd_t
                    296: fdopen (ip, mode)
                    297: INODE        * ip;
                    298: int            mode;
                    299: #endif
                    300: {
                    301:        int             fd;
                    302: 
                    303:        if ((fd = fdalloc ()) != ERROR_FD) {
                    304:                fdinit (fd, ip, mode);
                    305:                fd = fdfinish (fd);
                    306:        }
                    307: 
                    308:        return fd;
                    309: }
                    310: 
                    311: 
                    312: /*
                    313:  * Close the given file number.
                    314:  */
                    315: 
                    316: #if    __USE_PROTO__
                    317: void fdclose (unsigned fd)
                    318: #else
                    319: void
                    320: fdclose(fd)
                    321: unsigned       fd;
                    322: #endif
                    323: {
                    324:        register FD *fdp;
                    325:        static  struct flock    flock = { F_UNLCK, 0, 0, 0 };
                    326: 
                    327:        if (fd >= NOFILE ||
                    328:            (fdp = GET_UNTAGGED_FD (u.u_filep [fd])) == NULL) {
                    329:                u.u_error = EBADF;
                    330:                return;
                    331:        }
                    332: 
                    333:        if (fdp->f_ip->i_rl != NULL)
                    334:                rlock (fdp, F_SETLK, & flock);  /* delete all record locks */
                    335: 
                    336:        u.u_filep[fd] = NULL;
                    337: 
                    338:        if (fdp->f_refc == 0)
                    339:                panic("fdclose()");
                    340: 
                    341:        if (-- fdp->f_refc == 0) {
                    342:                iclose (fdp->f_ip, fdp->f_flag);
                    343:                kfree (fdp);
                    344:        }
                    345: }
                    346: 
                    347: 
                    348: /*
                    349:  * Assuming we have made a copy of the user area, increment the reference
                    350:  * of all open files.  (used in fork).
                    351:  */
                    352: 
                    353: #if    __USE_PROTO__
                    354: void fdadupl (void)
                    355: #else
                    356: void
                    357: fdadupl ()
                    358: #endif
                    359: {
                    360:        int             i;
                    361: 
                    362:        for (i = 0 ; i < NOFILE ; i ++)
                    363:                if (u.u_filep [i] != NULL)
                    364:                        GET_UNTAGGED_FD (u.u_filep [i])->f_refc ++;
                    365: }
                    366: 
                    367: 
                    368: /*
                    369:  * Close all open files in the current process.
                    370:  */
                    371: 
                    372: #if    __USE_PROTO__
                    373: void fdaclose (void)
                    374: #else
                    375: void
                    376: fdaclose()
                    377: #endif
                    378: {
                    379:        int             fd;
                    380: 
                    381:        for (fd = 0 ; fd < NOFILE ; fd ++)
                    382:                if (u.u_filep [fd] != NULL)
                    383:                        fdclose (fd);
                    384: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.