• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
fCreate(int * plock,const char * file)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 
fDestroy(int lock)64 void fDestroy(int lock)
65 {
66 
67   if(lock < 0)
68     return;
69 
70   close(lock);
71 
72   return;
73 }
74 
fFind(int * plock,const char * file)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 
fLock(int lock)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 
fUnlock(int lock)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 
mCreate(pthread_mutex_t * mutex)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 
mDestroy(pthread_mutex_t * mutex)126 void mDestroy(pthread_mutex_t *mutex)
127 {
128 
129   pthread_mutex_destroy(mutex);
130 
131   return;
132 }
133 
mLock(pthread_mutex_t * mutex)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 
mUnlock(pthread_mutex_t * mutex)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 
cCreate(pthread_cond_t * cond)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 
cDestroy(pthread_cond_t * cond)166 void cDestroy(pthread_cond_t *cond)
167 {
168   pthread_cond_destroy(cond);
169 
170   return;
171 }
172 
cWait(pthread_cond_t * cond,pthread_mutex_t * mutex)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 
cBroadcast(pthread_cond_t * cond)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 
cSignal(pthread_cond_t * cond)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