Annotation of sbbs/xpdev/filewrap.c, revision 1.1.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.