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