Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright 2001-2004 Brandon Long
      3  * All Rights Reserved.
      4  *
      5  * ClearSilver Templating System
      6  *
      7  * This code is made available under the terms of the ClearSilver License.
      8  * http://www.clearsilver.net/license.hdf
      9  *
     10  */
     11 
     12 #include "cs_config.h"
     13 
     14 #include <sys/types.h>
     15 #include <sys/stat.h>
     16 #include <fcntl.h>
     17 #include <unistd.h>
     18 #include <string.h>
     19 #include <errno.h>
     20 
     21 #include "neo_misc.h"
     22 #include "neo_err.h"
     23 #include "neo_files.h"
     24 #include "ulocks.h"
     25 
     26 NEOERR *fCreate(int *plock, const char *file)
     27 {
     28   NEOERR *err;
     29   int lock;
     30   char *p;
     31 
     32   *plock = -1;
     33 
     34   /* note the default mode of 666 is possibly a security hole in that
     35    * someone else can grab your lock and DoS you.  For internal use, who
     36    * cares?
     37    */
     38   if((lock = open(file, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT|O_EXCL, 0666)) < 0)
     39   {
     40     if (errno == ENOENT)
     41     {
     42       p = strrchr (file, '/');
     43       if (p != NULL)
     44       {
     45 	*p = '\0';
     46 	err = ne_mkdirs(file, 0777);
     47 	*p = '/';
     48 	if (err != STATUS_OK) return nerr_pass(err);
     49 	lock = open(file, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0666);
     50       }
     51     }
     52     if (errno == EEXIST)
     53       return nerr_pass(fFind(plock, file));
     54 
     55     if (lock < 0)
     56       return nerr_raise_errno (NERR_IO, "Unable to open lock file %s", file);
     57   }
     58 
     59   *plock = lock;
     60 
     61   return STATUS_OK;
     62 }
     63 
     64 void fDestroy(int lock)
     65 {
     66 
     67   if(lock < 0)
     68     return;
     69 
     70   close(lock);
     71 
     72   return;
     73 }
     74 
     75 NEOERR *fFind(int *plock, const char *file)
     76 {
     77   int lock;
     78 
     79   *plock = -1;
     80 
     81   if((lock = open(file, O_WRONLY|O_NDELAY|O_APPEND, 0666)) < 0) {
     82     if (errno == ENOENT)
     83       return nerr_raise (NERR_NOT_FOUND, "Unable to find lock file %s", file);
     84     return nerr_raise_errno (NERR_IO, "Unable to open lock file %s", file);
     85   }
     86 
     87   *plock = lock;
     88 
     89   return STATUS_OK;
     90 }
     91 
     92 NEOERR *fLock(int lock)
     93 {
     94 
     95   if(lockf(lock, F_LOCK, 0) < 0)
     96     return nerr_raise_errno (NERR_LOCK, "File lock failed");
     97 
     98   return STATUS_OK;
     99 }
    100 
    101 void fUnlock(int lock)
    102 {
    103 
    104   if(lock < 0)
    105     return;
    106 
    107   lockf(lock, F_ULOCK, 0);
    108 
    109   return;
    110 }
    111 
    112 #ifdef HAVE_PTHREADS
    113 
    114 NEOERR *mCreate(pthread_mutex_t *mutex)
    115 {
    116   int err;
    117 
    118   if((err = pthread_mutex_init(mutex, NULL))) {
    119     return nerr_raise (NERR_LOCK, "Unable to initialize mutex: %s",
    120 	strerror(err));
    121   }
    122 
    123   return STATUS_OK;
    124 }
    125 
    126 void mDestroy(pthread_mutex_t *mutex)
    127 {
    128 
    129   pthread_mutex_destroy(mutex);
    130 
    131   return;
    132 }
    133 
    134 NEOERR *mLock(pthread_mutex_t *mutex)
    135 {
    136   int err;
    137 
    138   if((err = pthread_mutex_lock(mutex)))
    139     return nerr_raise(NERR_LOCK, "Mutex lock failed: %s", strerror(err));
    140 
    141   return STATUS_OK;
    142 }
    143 
    144 NEOERR *mUnlock(pthread_mutex_t *mutex)
    145 {
    146   int err;
    147 
    148   if((err = pthread_mutex_unlock(mutex)))
    149     return nerr_raise(NERR_LOCK, "Mutex unlock failed: %s", strerror(err));
    150 
    151   return STATUS_OK;
    152 }
    153 
    154 NEOERR *cCreate(pthread_cond_t *cond)
    155 {
    156   int err;
    157 
    158   if((err = pthread_cond_init(cond, NULL))) {
    159     return nerr_raise(NERR_LOCK, "Unable to initialize condition variable: %s",
    160 	strerror(err));
    161   }
    162 
    163   return STATUS_OK;
    164 }
    165 
    166 void cDestroy(pthread_cond_t *cond)
    167 {
    168   pthread_cond_destroy(cond);
    169 
    170   return;
    171 }
    172 
    173 NEOERR *cWait(pthread_cond_t *cond, pthread_mutex_t *mutex)
    174 {
    175   int err;
    176 
    177   if((err = pthread_cond_wait(cond, mutex)))
    178     return nerr_raise(NERR_LOCK, "Condition wait failed: %s", strerror(err));
    179 
    180   return STATUS_OK;
    181 }
    182 
    183 NEOERR *cBroadcast(pthread_cond_t *cond)
    184 {
    185   int err;
    186 
    187   if((err = pthread_cond_broadcast(cond)))
    188     return nerr_raise(NERR_LOCK, "Condition broadcast failed: %s",
    189 	strerror(err));
    190 
    191   return STATUS_OK;
    192 }
    193 
    194 NEOERR *cSignal(pthread_cond_t *cond)
    195 {
    196   int err;
    197 
    198   if((err = pthread_cond_signal(cond)))
    199     return nerr_raise (NERR_LOCK, "Condition signal failed: %s", strerror(err));
    200 
    201   return STATUS_OK;
    202 }
    203 
    204 #endif
    205