Changeset 53829


Ignore:
Timestamp:
Jul 15, 2009, 3:52:12 AM (10 years ago)
Author:
toby@…
Message:

move flock to a separate file

Location:
trunk/base/src/pextlib1.0
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/src/pextlib1.0/Makefile

    r53828 r53829  
    33        fs-traverse.o strcasecmp.o vercomp.o filemap.o \
    44        sha1cmd.o curl.o rmd160cmd.o readline.o uid.o \
    5         tracelib.o tty.o sysctl.o readdir.o pipe.o
     5        tracelib.o tty.o sysctl.o readdir.o pipe.o flock.o
    66SHLIB_NAME= Pextlib${SHLIB_SUFFIX}
    77INSTALLDIR= ${DESTDIR}${datadir}/macports/Tcl/pextlib1.0
  • trunk/base/src/pextlib1.0/Pextlib.c

    r53743 r53829  
    6363#include <pwd.h>
    6464
    65 #if HAVE_SYS_FILE_H
    66 #include <sys/file.h>
    67 #endif
    68 
    6965#if HAVE_SYS_TYPES_H
    7066#include <sys/types.h>
     
    109105#include "readdir.h"
    110106#include "pipe.h"
     107#include "flock.h"
    111108
    112109#if HAVE_CRT_EXTERNS_H
     
    373370
    374371        return status;
    375 }
    376 
    377 int FlockCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
    378 {
    379         static const char errorstr[] = "use one of \"-shared\", \"-exclusive\", or \"-unlock\", and optionally \"-noblock\"";
    380         int operation = 0, fd, i, ret;
    381         int errnoval = 0;
    382         int oshared = 0, oexclusive = 0, ounlock = 0, onoblock = 0;
    383 #if defined(HAVE_LOCKF) && !defined(HAVE_FLOCK)
    384         off_t curpos;
    385 #endif
    386         char *res;
    387         Tcl_Channel channel;
    388         ClientData handle;
    389 
    390         if (objc < 3 || objc > 4) {
    391                 Tcl_WrongNumArgs(interp, 1, objv, "channelId switches");
    392                 return TCL_ERROR;
    393         }
    394 
    395         if ((channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), NULL)) == NULL)
    396                 return TCL_ERROR;
    397 
    398         if (Tcl_GetChannelHandle(channel, TCL_READABLE|TCL_WRITABLE, &handle) != TCL_OK) {
    399                 Tcl_SetResult(interp, "error getting channel handle", TCL_STATIC);
    400                 return TCL_ERROR;
    401         }
    402         fd = (int)(intptr_t)handle;
    403 
    404         for (i = 2; i < objc; i++) {
    405                 char *arg = Tcl_GetString(objv[i]);
    406                 if (!strcmp(arg, "-shared")) {
    407                   oshared = 1;
    408                 } else if (!strcmp(arg, "-exclusive")) {
    409                   oexclusive = 1;
    410                 } else if (!strcmp(arg, "-unlock")) {
    411                   ounlock = 1;
    412                 } else if (!strcmp(arg, "-noblock")) {
    413                   onoblock = 1;
    414                 }
    415         }
    416 
    417         /* verify the arguments */
    418 
    419         if((oshared + oexclusive + ounlock) != 1) {
    420           /* only one of the options should have been specified */
    421           Tcl_SetResult(interp, (void *) &errorstr, TCL_STATIC);
    422           return TCL_ERROR;
    423         }
    424 
    425         if(onoblock && ounlock) {
    426           /* should not be specified together */
    427           Tcl_SetResult(interp, "-noblock cannot be used with -unlock", TCL_STATIC);
    428           return TCL_ERROR;
    429         }
    430          
    431 #if HAVE_FLOCK
    432         /* prefer flock if present */
    433         if(oshared) operation |= LOCK_SH;
    434 
    435         if(oexclusive) operation |= LOCK_EX;
    436 
    437         if(ounlock) operation |= LOCK_UN;
    438 
    439         if(onoblock) operation |= LOCK_NB;
    440 
    441         ret = flock(fd, operation);
    442         if(ret == -1) {
    443           errnoval = errno;
    444         }
    445 #else
    446 #if HAVE_LOCKF
    447         if(ounlock) operation = F_ULOCK;
    448 
    449         /* lockf semantics don't map to shared locks. */
    450         if(oshared || oexclusive) {
    451           if(onoblock) {
    452             operation = F_TLOCK;
    453           } else {
    454             operation = F_LOCK;
    455           }
    456         }
    457 
    458         curpos = lseek(fd, 0, SEEK_CUR);
    459         if(curpos == -1) {
    460                 Tcl_SetResult(interp, (void *) "Seek error", TCL_STATIC);
    461                 return TCL_ERROR;
    462         }
    463 
    464         ret = lockf(fd, operation, 0); /* lock entire file */
    465 
    466         curpos = lseek(fd, curpos, SEEK_SET);
    467         if(curpos == -1) {
    468                 Tcl_SetResult(interp, (void *) "Seek error", TCL_STATIC);
    469                 return TCL_ERROR;
    470         }
    471 
    472         if(ret == -1) {
    473           errnoval = errno;
    474           if((oshared || oexclusive)) {
    475             /* map the errno val to what we would expect for flock */
    476             if(onoblock && errnoval == EAGAIN) {
    477               /* on some systems, EAGAIN=EWOULDBLOCK, but lets be safe */
    478               errnoval = EWOULDBLOCK;
    479             } else if(errnoval == EINVAL) {
    480               errnoval = EOPNOTSUPP;
    481             }
    482           }
    483         }
    484 #else
    485 #error no available locking implementation
    486 #endif /* HAVE_LOCKF */
    487 #endif /* HAVE_FLOCK */
    488 
    489         if (ret != 0)
    490         {
    491                 switch(errnoval) {
    492                         case EAGAIN:
    493                                 res = "EAGAIN";
    494                                 break;
    495                         case EBADF:
    496                                 res = "EBADF";
    497                                 break;
    498                         case EINVAL:
    499                                 res = "EINVAL";
    500                                 break;
    501                         case EOPNOTSUPP:
    502                                 res = "EOPNOTSUPP";
    503                                 break;
    504                         default:
    505                                 res = strerror(errno);
    506                                 break;
    507                 }
    508                 Tcl_SetResult(interp, (void *) res, TCL_STATIC);
    509                 return TCL_ERROR;
    510         }
    511         return TCL_OK;
    512372}
    513373
Note: See TracChangeset for help on using the changeset viewer.