Annotation of sbbs/xpdev/filewrap.c, revision 1.1

1.1     ! root        1: /* filewrap.c */
        !             2: 
        !             3: /* File-related system-call wrappers */
        !             4: 
        !             5: /* $Id: filewrap.c,v 1.29 2004/07/20 23:26:58 rswindell Exp $ */
        !             6: 
        !             7: /****************************************************************************
        !             8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !            10:  *                                                                                                                                                     *
        !            11:  * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            12:  *                                                                                                                                                     *
        !            13:  * This library is free software; you can redistribute it and/or                       *
        !            14:  * modify it under the terms of the GNU Lesser General Public License          *
        !            15:  * as published by the Free Software Foundation; either version 2                      *
        !            16:  * of the License, or (at your option) any later version.                                      *
        !            17:  * See the GNU Lesser General Public License for more details: lgpl.txt or     *
        !            18:  * http://www.fsf.org/copyleft/lesser.html                                                                     *
        !            19:  *                                                                                                                                                     *
        !            20:  * Anonymous FTP access to the most recent released source is available at     *
        !            21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            22:  *                                                                                                                                                     *
        !            23:  * Anonymous CVS access to the development source and modification history     *
        !            24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            26:  *     (just hit return, no password is necessary)                                                     *
        !            27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            28:  *                                                                                                                                                     *
        !            29:  * For Synchronet coding style and modification guidelines, see                                *
        !            30:  * http://www.synchro.net/source.html                                                                          *
        !            31:  *                                                                                                                                                     *
        !            32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            33:  * format) via e-mail to [email protected]                                                                      *
        !            34:  *                                                                                                                                                     *
        !            35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            36:  ****************************************************************************/
        !            37: 
        !            38: /* OS-specific */
        !            39: #if defined(__unix__)
        !            40: 
        !            41: #include <stdarg.h>            /* va_list */
        !            42: #include <string.h>     /* strlen() */
        !            43: #include <unistd.h>     /* getpid() */
        !            44: #include <fcntl.h>      /* fcntl() file/record locking */
        !            45: #include <sys/file.h>  /* L_SET for Solaris */
        !            46: #include <errno.h>
        !            47: #include <sys/param.h> /* BSD */
        !            48: 
        !            49: #endif
        !            50: 
        !            51: /* ANSI */
        !            52: #include <sys/types.h> /* _dev_t */
        !            53: #include <sys/stat.h>  /* struct stat */
        !            54: 
        !            55: #include "filewrap.h"  /* Verify prototypes */
        !            56: 
        !            57: /****************************************************************************/
        !            58: /* Returns the modification time of the file in 'fd'                                           */
        !            59: /****************************************************************************/
        !            60: time_t DLLCALL filetime(int fd)
        !            61: {
        !            62:        struct stat st;
        !            63: 
        !            64:        if(fstat(fd, &st)!=0)
        !            65:                return(-1);
        !            66: 
        !            67:        return(st.st_mtime);
        !            68: }
        !            69: 
        !            70: #if defined(__unix__) && !defined(__BORLANDC__)
        !            71: 
        !            72: /****************************************************************************/
        !            73: /* Returns the length of the file in 'fd'                                                                      */
        !            74: /****************************************************************************/
        !            75: long DLLCALL filelength(int fd)
        !            76: {
        !            77:        struct stat st;
        !            78: 
        !            79:        if(fstat(fd, &st)!=0)
        !            80:                return(-1L);
        !            81: 
        !            82:        return(st.st_size);
        !            83: }
        !            84: 
        !            85: /* Sets a lock on a portion of a file */
        !            86: int DLLCALL lock(int fd, long pos, long len)
        !            87: {
        !            88:        #if defined(F_SANERDLCKNO) || !defined(BSD)
        !            89:                struct flock alock;
        !            90: 
        !            91:        #ifndef F_SANEWRLCKNO
        !            92:                int     flags;
        !            93:                if((flags=fcntl(fd,F_GETFL))==-1)
        !            94:                        return -1;
        !            95: 
        !            96:                if(flags==O_RDONLY)
        !            97:                        alock.l_type = F_RDLCK; /* set read lock to prevent writes */
        !            98:                else
        !            99:                        alock.l_type = F_WRLCK; /* set write lock to prevent all access */
        !           100:        #else
        !           101:                alock.l_type = F_SANEWRLCKNO;
        !           102:        #endif
        !           103:                alock.l_whence = L_SET;         /* SEEK_SET */
        !           104:                alock.l_start = pos;
        !           105:                alock.l_len = (int)len;
        !           106: 
        !           107:                if(fcntl(fd, F_SETLK, &alock)==-1 && errno != EINVAL)
        !           108:                        return(-1);
        !           109:        #endif
        !           110: 
        !           111:        #if !defined(F_SANEWRLCKNO) && !defined(__QNX__) && !defined(__solaris__)
        !           112:                /* use flock (doesn't work over NFS) */
        !           113:                if(flock(fd,LOCK_EX|LOCK_NB)!=0 && errno != EOPNOTSUPP)
        !           114:                        return(-1);
        !           115:        #endif
        !           116: 
        !           117:                return(0);
        !           118: }
        !           119: 
        !           120: /* Removes a lock from a file record */
        !           121: int DLLCALL unlock(int fd, long pos, long len)
        !           122: {
        !           123: 
        !           124: #if defined(F_SANEUNLCK) || !defined(BSD)
        !           125:        struct flock alock;
        !           126: #ifdef F_SANEUNLCK
        !           127:        alock.l_type = F_SANEUNLCK;   /* remove the lock */
        !           128: #else
        !           129:        alock.l_type = F_UNLCK;   /* remove the lock */
        !           130: #endif
        !           131:        alock.l_whence = L_SET;
        !           132:        alock.l_start = pos;
        !           133:        alock.l_len = (int)len;
        !           134:        if(fcntl(fd, F_SETLK, &alock)==-1 && errno != EINVAL)
        !           135:                return(-1);
        !           136: #endif
        !           137: 
        !           138: #if !defined(F_SANEUNLCK) && !defined(__QNX__) && !defined(__solaris__)
        !           139:        /* use flock (doesn't work over NFS) */
        !           140:        if(flock(fd,LOCK_UN|LOCK_NB)!=0 && errno != EOPNOTSUPP)
        !           141:                return(-1);
        !           142: #endif
        !           143: 
        !           144:        return(0);
        !           145: }
        !           146: 
        !           147: /* Opens a file in specified sharing (file-locking) mode */
        !           148: #if !defined(__QNX__)
        !           149: int DLLCALL sopen(const char *fn, int access, int share, ...)
        !           150: {
        !           151:        int fd;
        !           152:        int pmode=S_IREAD;
        !           153: #ifndef F_SANEWRLCKNO
        !           154:        int     flock_op=LOCK_NB;       /* non-blocking */
        !           155: #endif
        !           156: #if defined(F_SANEWRLCKNO) || !defined(BSD)
        !           157:        struct flock alock;
        !           158: #endif
        !           159:     va_list ap;
        !           160: 
        !           161:     if(access&O_CREAT) {
        !           162:         va_start(ap,share);
        !           163:         pmode = va_arg(ap,unsigned int);
        !           164:         va_end(ap);
        !           165:     }
        !           166: 
        !           167:        if ((fd = open(fn, access, pmode)) < 0)
        !           168:                return -1;
        !           169: 
        !           170:        if (share == SH_DENYNO) /* no lock needed */
        !           171:                return fd;
        !           172: #if defined(F_SANEWRLCKNO) || !defined(BSD)
        !           173:        /* use fcntl (doesn't work correctly with threads) */
        !           174:        alock.l_type = share;
        !           175:        alock.l_whence = L_SET;
        !           176:        alock.l_start = 0;
        !           177:        alock.l_len = 0;       /* lock to EOF */
        !           178: 
        !           179:        if(fcntl(fd, F_SETLK, &alock)==-1 && errno != EINVAL) { /* EINVAL means the file does not support locking */
        !           180:                close(fd);
        !           181:                return -1;
        !           182:        }
        !           183: #endif
        !           184: 
        !           185: #if !defined(F_SANEWRLCKNO) && !defined(__QNX__) && !defined(__solaris__)
        !           186:        /* use flock (doesn't work over NFS) */
        !           187:        if(share==SH_DENYRW)
        !           188:                flock_op|=LOCK_EX;
        !           189:        else   /* SH_DENYWR */
        !           190:                flock_op|=LOCK_SH;
        !           191:        if(flock(fd,flock_op)!=0 && errno != EOPNOTSUPP) { /* That object doesn't do locks */
        !           192:                if(errno==EWOULDBLOCK) 
        !           193:                        errno=EAGAIN;
        !           194:                close(fd);
        !           195:                return(-1);
        !           196:        }
        !           197: #endif
        !           198: 
        !           199:        return fd;
        !           200: }
        !           201: #endif /* !QNX */
        !           202: 
        !           203: #elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__DMC__)
        !           204: 
        !           205: #include <io.h>                                /* tell */
        !           206: #include <stdio.h>                     /* SEEK_SET */
        !           207: #include <sys/locking.h>       /* _locking */
        !           208: 
        !           209: /* Fix MinGW locking.h typo */
        !           210: #if defined LK_UNLOCK && !defined LK_UNLCK
        !           211:        #define LK_UNLCK LK_UNLOCK
        !           212: #endif
        !           213: 
        !           214: int DLLCALL lock(int file, long offset, long size) 
        !           215: {
        !           216:        int     i;
        !           217:        long    pos;
        !           218:    
        !           219:        pos=tell(file);
        !           220:        if(offset!=pos)
        !           221:                lseek(file, offset, SEEK_SET);
        !           222:        i=_locking(file,LK_NBLCK,size);
        !           223:        if(offset!=pos)
        !           224:                lseek(file, pos, SEEK_SET);
        !           225:        return(i);
        !           226: }
        !           227: 
        !           228: int DLLCALL unlock(int file, long offset, long size)
        !           229: {
        !           230:        int     i;
        !           231:        long    pos;
        !           232:    
        !           233:        pos=tell(file);
        !           234:        if(offset!=pos)
        !           235:                lseek(file, offset, SEEK_SET);
        !           236:        i=_locking(file,LK_UNLCK,size);
        !           237:        if(offset!=pos)
        !           238:                lseek(file, pos, SEEK_SET);
        !           239:        return(i);
        !           240: }
        !           241: 
        !           242: #endif /* !Unix && (MSVC || MinGW) */
        !           243: 
        !           244: #ifdef __unix__
        !           245: FILE *_fsopen(char *pszFilename, char *pszMode, int shmode)
        !           246: {
        !           247:        int file;
        !           248:        int Mode=0;
        !           249:        char *p;
        !           250:        
        !           251:        for(p=pszMode;*p;p++)  {
        !           252:                switch (*p)  {
        !           253:                        case 'r':
        !           254:                                Mode |= 1;
        !           255:                                break;
        !           256:                        case 'w':
        !           257:                                Mode |= 2;
        !           258:                                break;
        !           259:                        case 'a':
        !           260:                                Mode |= 4;
        !           261:                                break;
        !           262:                        case '+':
        !           263:                                Mode |= 8;
        !           264:                                break;
        !           265:                        case 'b':
        !           266:                        case 't':
        !           267:                                break;
        !           268:                        default:
        !           269:                                errno=EINVAL;
        !           270:                        return(NULL);
        !           271:                }
        !           272:        }
        !           273:        switch(Mode)  {
        !           274:                case 1:
        !           275:                        Mode=O_RDONLY;
        !           276:                        break;
        !           277:                case 2:
        !           278:                        Mode=O_WRONLY|O_CREAT|O_TRUNC;
        !           279:                        break;
        !           280:                case 4:
        !           281:                        Mode=O_APPEND|O_WRONLY|O_CREAT;
        !           282:                        break;
        !           283:                case 9:
        !           284:                        Mode=O_RDWR|O_CREAT;
        !           285:                        break;
        !           286:                case 10:
        !           287:                        Mode=O_RDWR|O_CREAT|O_TRUNC;
        !           288:                        break;
        !           289:                case 12:
        !           290:                        Mode=O_RDWR|O_APPEND|O_CREAT;
        !           291:                        break;
        !           292:                default:
        !           293:                        errno=EINVAL;
        !           294:                        return(NULL);
        !           295:        }
        !           296:        if(Mode&O_CREAT)
        !           297:                file=sopen(pszFilename,Mode,shmode,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
        !           298:        else
        !           299:                file=sopen(pszFilename,Mode,shmode);
        !           300:        if(file==-1)
        !           301:                return(NULL);
        !           302:        return(fdopen(file,pszMode));
        !           303: }
        !           304: #endif

unix.superglobalmegacorp.com

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