Annotation of coherent/b/STREAMS/coh.386/fd.c, revision 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.