35 std::cerr <<
"faudes_invalid(): " << msg << std:endl;
44 static std::string faudes_pathsep_str =
"/";
45 return faudes_pathsep_str;
53 static std::string faudes_pathsep_str =
"/";
54 return faudes_pathsep_str;
62 static std::string faudes_pathseps_str =
"\\:/";
63 return faudes_pathseps_str;
66 static std::string faudes_pathsep_str =
"";
67 if(faudes_pathsep_str==
"")
69 return faudes_pathsep_str;
78 signal(SIGTERM, sighandler);
81 signal(SIGINT, sighandler);
84 signal(SIGQUIT, sighandler);
87 signal(SIGHUP, sighandler);
90 signal(SIGABRT, sighandler);
97 return strsignal(sig);
109 #ifdef FAUDES_WINDOWS
113 #ifdef FAUDES_GENERIC
120 #ifdef FAUDES_SYSTIME
126 #if defined(FAUDES_POSIX)
127 void faudes_gettimeofday(faudes_systime_t* now) {
129 gettimeofday(&nowval,0);
130 now->tv_sec=nowval.tv_sec;
131 now->tv_nsec=nowval.tv_usec * 1000;
135 #if defined(FAUDES_WINDOWS)
136 void faudes_gettimeofday(faudes_systime_t* now) {
138 nowval= timeGetTime();
139 now->tv_sec=nowval / 1000;
140 now->tv_nsec=(nowval % 1000) *1000000;
147 void faudes_diffsystime(
const faudes_systime_t& end,
const faudes_systime_t& begin, faudes_systime_t* res) {
148 res->tv_sec = end.tv_sec-begin.tv_sec;
149 res->tv_nsec = end.tv_nsec-begin.tv_nsec;
150 if(res->tv_nsec <= 0){
152 res->tv_nsec += 1000000000;
157 void faudes_diffsystime(
const faudes_systime_t& end,
const faudes_systime_t& begin, faudes_mstime_t* res) {
158 *res = 1000*( end.tv_sec-begin.tv_sec);
159 *res += (end.tv_nsec-begin.tv_nsec) / 1000000;
163 void faudes_sumsystime(
const faudes_systime_t& begin,
const faudes_systime_t& duration, faudes_systime_t* res) {
164 res->tv_sec = begin.tv_sec + duration.tv_sec;
165 res->tv_nsec = begin.tv_nsec + duration.tv_nsec;
166 if(res->tv_nsec >= 1000000000) {
168 res->tv_nsec-=1000000000;
174 faudes_systime_t now;
175 faudes_gettimeofday(&now);
176 faudes_systime_t delta;
177 delta.tv_sec = msecs/1000;
178 delta.tv_nsec = (msecs % 1000) *1000000;
184 faudes_systime_t now;
185 faudes_gettimeofday(&now);
186 faudes_systime_t delta;
187 delta.tv_sec = usecs/1000000;
188 delta.tv_nsec = (usecs % 1000000) * 1000;
196 #ifdef FAUDES_NETWORK
199 int faudes_closesocket(
int fd) {
202 int faudes_setsockopt(
int fd,
int level,
int optname,
const void *optval, socklen_t optlen) {
203 return setsockopt(fd,level,optname,optval,optlen);
205 int faudes_getsockopt(
int fd,
int level,
int optname,
void *optval, socklen_t *optlen) {
206 return getsockopt(fd,level,optname,optval,optlen);
208 int faudes_getsocket_error(
int fd) {
210 socklen_t len =
sizeof(opt);
211 int res = getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &len) < 0 ? -1 : 0;
215 int faudes_setsocket_nonblocking(
int fd,
bool noblo) {
216 int sopt=fcntl(fd, F_GETFL, NULL);
217 if(sopt<0)
return -1;
219 int rc=fcntl(fd, F_SETFL, sopt|O_NONBLOCK);
220 return rc < 0 ? -1 : 0;
222 int rc=fcntl(fd, F_SETFL, sopt& (~O_NONBLOCK));
223 return rc < 0 ? -1 : 0;
227 #ifdef FAUDES_WINDOWS
228 typedef int socklen_t;
229 int faudes_closesocket(
int fd) {
230 return closesocket(fd);
232 int faudes_setsockopt(
int fd,
int level,
int optname,
const void *optval, socklen_t optlen) {
233 return setsockopt(fd,level,optname,(
char*) optval,optlen);
235 int faudes_getsockopt(
int fd,
int level,
int optname,
void *optval, socklen_t *optlen) {
236 return getsockopt(fd,level,optname,(
char*) optval,optlen);
238 int faudes_getsocket_error(
int fd) {
240 socklen_t len =
sizeof(opt);
241 int res = getsockopt(fd, SOL_SOCKET, SO_ERROR, (
char*) &opt, &len) < 0 ? -1 : 0;
245 int faudes_setsocket_nonblocking(
int fd,
bool noblo) {
246 unsigned long onoff=0;
248 return ioctlsocket(fd, FIONBIO, &onoff) == SOCKET_ERROR ? -1 : 0;
251 #ifdef FAUDES_GENERIC
252 #error option network not available on generic platform
260 #ifdef FAUDES_THREADS
263 typedef pthread_t faudes_thread_t;
265 int faudes_thread_create(faudes_thread_t *thr,
void *(*fnct)(
void *),
void *arg){
268 pthread_attr_init(&attr);
269 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
271 int ret = pthread_create(thr, &attr, fnct, arg);
273 pthread_attr_destroy(&attr);
274 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
276 faudes_thread_t faudes_thread_current(
void) {
277 return pthread_self();
279 int faudes_thread_detach(faudes_thread_t thr) {
280 return pthread_detach(thr)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
282 int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) {
283 return pthread_equal(thr0, thr1);
285 void faudes_thread_exit(
void* res) {
288 int faudes_thread_join(faudes_thread_t thr,
void **res) {
289 return pthread_join(thr, res) == 0 ? FAUDES_THREAD_ERROR : FAUDES_THREAD_SUCCESS;
295 #ifdef FAUDES_THREADS
296 #ifdef FAUDES_WINDOWS
299 DWORD faudes_thread_tlsidx=TLS_OUT_OF_INDEXES;
302 static unsigned WINAPI faudes_thread_wrapper(
void *argfth) {
304 faudes_thread_t fthread = (faudes_thread_t) argfth;
306 TlsSetValue(faudes_thread_tlsidx,fthread);
308 void *(*fnct)(
void*) = fthread->mFnct;
309 void *arg = fthread->mArg;
311 void* res = fnct(arg);
313 faudes_thread_exit(res);
319 int faudes_thread_create(faudes_thread_t *thr,
void *(*fnct)(
void *),
void *arg){
321 if(faudes_thread_tlsidx==TLS_OUT_OF_INDEXES)
322 faudes_thread_tlsidx=TlsAlloc();
323 if(faudes_thread_tlsidx==TLS_OUT_OF_INDEXES)
324 return FAUDES_THREAD_ERROR;
326 *thr = (faudes_thread_t) malloc(
sizeof(faudes_thread_record_t));
327 if(!*thr)
return FAUDES_THREAD_ERROR;
329 (*thr)->mFnct = fnct;
333 (*thr)->mHandle = (HANDLE) _beginthreadex(NULL, 0, faudes_thread_wrapper, (
void*) (*thr), 0, NULL);
335 return (*thr)->mHandle ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
339 faudes_thread_t faudes_thread_current(
void) {
341 faudes_thread_t fthread = (faudes_thread_t) TlsGetValue(faudes_thread_tlsidx);
347 int faudes_thread_detach(faudes_thread_t thr) {
348 CloseHandle(thr->mHandle);
351 return FAUDES_THREAD_SUCCESS;
355 int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) {
357 if( (thr0==NULL) && (thr1=NULL) )
return true;
358 if( (thr0==NULL) || (thr1=NULL) )
return false;
360 return thr0->mHandle == thr1->mHandle;
364 void faudes_thread_exit(
void *res) {
366 faudes_thread_t fthread = (faudes_thread_t) TlsGetValue(faudes_thread_tlsidx);
367 if(fthread) fthread->mRes=res;
373 int faudes_thread_join(faudes_thread_t thr,
void **res) {
377 DWORD rc = WaitForSingleObject(thr->mHandle, INFINITE);
379 if( (rc!=WAIT_FAILED) && (res)) *res = thr->mRes;
383 if(rc == WAIT_FAILED)
return FAUDES_THREAD_ERROR;
384 return FAUDES_THREAD_SUCCESS;
393 #ifdef FAUDES_THREADS
395 int faudes_mutex_init(faudes_mutex_t* mtx){
396 return pthread_mutex_init(mtx, NULL)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
398 void faudes_mutex_destroy(faudes_mutex_t* mtx){
399 pthread_mutex_destroy(mtx);
401 int faudes_mutex_lock(faudes_mutex_t *mtx) {
402 return pthread_mutex_lock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
404 int faudes_mutex_trylock(faudes_mutex_t *mtx){
405 return (pthread_mutex_trylock(mtx) == 0) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
407 int faudes_mutex_unlock(faudes_mutex_t *mtx){
408 return pthread_mutex_unlock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
414 #ifdef FAUDES_THREADS
415 #ifdef FAUDES_WINDOWS
416 int faudes_mutex_init(faudes_mutex_t *mtx){
417 InitializeCriticalSection(mtx);
418 return FAUDES_THREAD_SUCCESS;
420 void faudes_mutex_destroy(faudes_mutex_t *mtx){
421 DeleteCriticalSection(mtx);
423 int faudes_mutex_lock(faudes_mutex_t *mtx) {
424 EnterCriticalSection(mtx);
425 return FAUDES_THREAD_SUCCESS;
427 int faudes_mutex_trylock(faudes_mutex_t *mtx){
428 return TryEnterCriticalSection(mtx) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
430 int faudes_mutex_unlock(faudes_mutex_t *mtx){
431 LeaveCriticalSection(mtx);
432 return FAUDES_THREAD_SUCCESS;
439 #ifdef FAUDES_THREADS
441 int faudes_cond_init(faudes_cond_t* cond) {
442 return pthread_cond_init(cond, NULL) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
444 void faudes_cond_destroy(faudes_cond_t* cond) {
445 pthread_cond_destroy(cond);
447 int faudes_cond_signal(faudes_cond_t *cond){
448 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
450 int faudes_cond_broadcast(faudes_cond_t *cond) {
451 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
453 int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) {
454 return pthread_cond_wait(cond, mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
456 int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx,
const faudes_systime_t *abstime) {
457 int ret = pthread_cond_timedwait(cond, mtx, abstime);
458 if(ret == ETIMEDOUT)
return FAUDES_THREAD_TIMEOUT;
459 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
462 int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) {
463 faudes_systime_t abstime;
465 return faudes_cond_timedwait(cond,mtx,&abstime);
476 #ifdef FAUDES_THREADS
477 #ifdef FAUDES_WINDOWS
480 #define EVENT_SIGNAL 0
481 #define EVENT_BROADCAST 1
484 int faudes_cond_init(faudes_cond_t* cond) {
486 cond->mWaitersCount = 0;
487 InitializeCriticalSection(&cond->mWaitersCountMutex);
489 cond->mEvents[EVENT_SIGNAL]=CreateEvent(NULL, FALSE, FALSE, NULL);
491 cond->mEvents[EVENT_BROADCAST] = CreateEvent(NULL, TRUE, FALSE, NULL);
493 if(cond->mEvents[EVENT_SIGNAL] != NULL)
494 if(cond->mEvents[EVENT_BROADCAST] != NULL)
495 return FAUDES_THREAD_SUCCESS;
497 if(cond->mEvents[EVENT_SIGNAL] != NULL)
498 CloseHandle(cond->mEvents[EVENT_SIGNAL]);
499 if(cond->mEvents[EVENT_BROADCAST] != NULL)
500 CloseHandle(cond->mEvents[EVENT_BROADCAST]);
501 cond->mEvents[EVENT_BROADCAST] = NULL;
502 cond->mEvents[EVENT_SIGNAL]=NULL;
503 return FAUDES_THREAD_ERROR;
507 void faudes_cond_destroy(faudes_cond_t* cond) {
508 if(cond->mEvents[EVENT_SIGNAL] != NULL)
509 CloseHandle(cond->mEvents[EVENT_SIGNAL]);
510 if(cond->mEvents[EVENT_BROADCAST] != NULL)
511 CloseHandle(cond->mEvents[EVENT_BROADCAST]);
512 DeleteCriticalSection(&cond->mWaitersCountMutex);
516 int faudes_cond_signal(faudes_cond_t *cond){
519 EnterCriticalSection(&cond->mWaitersCountMutex);
520 waiters = (cond->mWaitersCount > 0);
521 LeaveCriticalSection(&cond->mWaitersCountMutex);
524 if(SetEvent(cond->mEvents[EVENT_SIGNAL]) == 0)
525 return FAUDES_THREAD_ERROR;
527 return FAUDES_THREAD_SUCCESS;
531 int faudes_cond_broadcast(faudes_cond_t *cond) {
534 EnterCriticalSection(&cond->mWaitersCountMutex);
535 waiters = (cond->mWaitersCount > 0);
536 LeaveCriticalSection(&cond->mWaitersCountMutex);
539 if(SetEvent(cond->mEvents[EVENT_BROADCAST]) == 0)
540 return FAUDES_THREAD_ERROR;
542 return FAUDES_THREAD_SUCCESS;
546 int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) {
548 EnterCriticalSection(&cond->mWaitersCountMutex);
549 ++ cond->mWaitersCount;
550 LeaveCriticalSection(&cond->mWaitersCountMutex);
552 LeaveCriticalSection(mtx);
554 int res = WaitForMultipleObjects(2, cond->mEvents, FALSE, (DWORD) duration);
556 EnterCriticalSection(&cond->mWaitersCountMutex);
558 -- cond->mWaitersCount;
561 (res == (WAIT_OBJECT_0 + EVENT_BROADCAST)) &&
562 (cond->mWaitersCount == 0);
563 LeaveCriticalSection(&cond->mWaitersCountMutex);
565 if(last) ResetEvent(cond->mEvents[EVENT_BROADCAST]);
567 EnterCriticalSection(mtx);
569 if(res == (
int) WAIT_TIMEOUT)
570 return FAUDES_THREAD_TIMEOUT;
571 if(res == (
int) WAIT_FAILED)
572 return FAUDES_THREAD_ERROR;
573 return FAUDES_THREAD_SUCCESS;
577 int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) {
578 return faudes_cond_reltimedwait(cond, mtx, INFINITE);
582 int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx,
const faudes_systime_t *abstime) {
584 faudes_systime_t now;
585 faudes_gettimeofday(&now);
587 DWORD rels = abstime->tv_sec - now.tv_sec;
589 if(rels > (4294967295u/1000)-1) rels = 4294967295u/1000-1;
591 DWORD relms = rels*1000 + (abstime->tv_nsec - now.tv_nsec + 500000) / 1000000;
593 return faudes_cond_reltimedwait(cond, mtx, relms);