| /* |
| * Copyright 2001-2004 Brandon Long |
| * All Rights Reserved. |
| * |
| * ClearSilver Templating System |
| * |
| * This code is made available under the terms of the ClearSilver License. |
| * http://www.clearsilver.net/license.hdf |
| * |
| */ |
| |
| #include "cs_config.h" |
| |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <string.h> |
| #include <errno.h> |
| |
| #include "neo_misc.h" |
| #include "neo_err.h" |
| #include "neo_files.h" |
| #include "ulocks.h" |
| |
| NEOERR *fCreate(int *plock, const char *file) |
| { |
| NEOERR *err; |
| int lock; |
| char *p; |
| |
| *plock = -1; |
| |
| /* note the default mode of 666 is possibly a security hole in that |
| * someone else can grab your lock and DoS you. For internal use, who |
| * cares? |
| */ |
| if((lock = open(file, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT|O_EXCL, 0666)) < 0) |
| { |
| if (errno == ENOENT) |
| { |
| p = strrchr (file, '/'); |
| if (p != NULL) |
| { |
| *p = '\0'; |
| err = ne_mkdirs(file, 0777); |
| *p = '/'; |
| if (err != STATUS_OK) return nerr_pass(err); |
| lock = open(file, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0666); |
| } |
| } |
| if (errno == EEXIST) |
| return nerr_pass(fFind(plock, file)); |
| |
| if (lock < 0) |
| return nerr_raise_errno (NERR_IO, "Unable to open lock file %s", file); |
| } |
| |
| *plock = lock; |
| |
| return STATUS_OK; |
| } |
| |
| void fDestroy(int lock) |
| { |
| |
| if(lock < 0) |
| return; |
| |
| close(lock); |
| |
| return; |
| } |
| |
| NEOERR *fFind(int *plock, const char *file) |
| { |
| int lock; |
| |
| *plock = -1; |
| |
| if((lock = open(file, O_WRONLY|O_NDELAY|O_APPEND, 0666)) < 0) { |
| if (errno == ENOENT) |
| return nerr_raise (NERR_NOT_FOUND, "Unable to find lock file %s", file); |
| return nerr_raise_errno (NERR_IO, "Unable to open lock file %s", file); |
| } |
| |
| *plock = lock; |
| |
| return STATUS_OK; |
| } |
| |
| NEOERR *fLock(int lock) |
| { |
| |
| if(lockf(lock, F_LOCK, 0) < 0) |
| return nerr_raise_errno (NERR_LOCK, "File lock failed"); |
| |
| return STATUS_OK; |
| } |
| |
| void fUnlock(int lock) |
| { |
| |
| if(lock < 0) |
| return; |
| |
| lockf(lock, F_ULOCK, 0); |
| |
| return; |
| } |
| |
| #ifdef HAVE_PTHREADS |
| |
| NEOERR *mCreate(pthread_mutex_t *mutex) |
| { |
| int err; |
| |
| if((err = pthread_mutex_init(mutex, NULL))) { |
| return nerr_raise (NERR_LOCK, "Unable to initialize mutex: %s", |
| strerror(err)); |
| } |
| |
| return STATUS_OK; |
| } |
| |
| void mDestroy(pthread_mutex_t *mutex) |
| { |
| |
| pthread_mutex_destroy(mutex); |
| |
| return; |
| } |
| |
| NEOERR *mLock(pthread_mutex_t *mutex) |
| { |
| int err; |
| |
| if((err = pthread_mutex_lock(mutex))) |
| return nerr_raise(NERR_LOCK, "Mutex lock failed: %s", strerror(err)); |
| |
| return STATUS_OK; |
| } |
| |
| NEOERR *mUnlock(pthread_mutex_t *mutex) |
| { |
| int err; |
| |
| if((err = pthread_mutex_unlock(mutex))) |
| return nerr_raise(NERR_LOCK, "Mutex unlock failed: %s", strerror(err)); |
| |
| return STATUS_OK; |
| } |
| |
| NEOERR *cCreate(pthread_cond_t *cond) |
| { |
| int err; |
| |
| if((err = pthread_cond_init(cond, NULL))) { |
| return nerr_raise(NERR_LOCK, "Unable to initialize condition variable: %s", |
| strerror(err)); |
| } |
| |
| return STATUS_OK; |
| } |
| |
| void cDestroy(pthread_cond_t *cond) |
| { |
| pthread_cond_destroy(cond); |
| |
| return; |
| } |
| |
| NEOERR *cWait(pthread_cond_t *cond, pthread_mutex_t *mutex) |
| { |
| int err; |
| |
| if((err = pthread_cond_wait(cond, mutex))) |
| return nerr_raise(NERR_LOCK, "Condition wait failed: %s", strerror(err)); |
| |
| return STATUS_OK; |
| } |
| |
| NEOERR *cBroadcast(pthread_cond_t *cond) |
| { |
| int err; |
| |
| if((err = pthread_cond_broadcast(cond))) |
| return nerr_raise(NERR_LOCK, "Condition broadcast failed: %s", |
| strerror(err)); |
| |
| return STATUS_OK; |
| } |
| |
| NEOERR *cSignal(pthread_cond_t *cond) |
| { |
| int err; |
| |
| if((err = pthread_cond_signal(cond))) |
| return nerr_raise (NERR_LOCK, "Condition signal failed: %s", strerror(err)); |
| |
| return STATUS_OK; |
| } |
| |
| #endif |