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_pathseps_str =
"/\\:";
54 return faudes_pathseps_str;
57 static std::string faudes_pathsep_str =
"";
58 if(faudes_pathsep_str==
"")
60 return faudes_pathsep_str;
65 static std::string faudes_pathsep_str =
"/";
66 return faudes_pathsep_str;
85 for(pos=0; pos<res.size(); ++pos) {
97 std::string res=rPath;
101 for(pos=0; pos<res.size(); ++pos) {
118 char buf[(PATH_MAX)+1];
119 char* wd =getcwd(buf,PATH_MAX);
120 if(wd==
nullptr)
return res;
125 return (chdir(nwd.c_str())==0 ? 0 : -1);
128 #ifdef FAUDES_WINDOWS
133 DWORD ret = GetCurrentDirectory(MAX_PATH, buf);
134 if((ret == 0) || (ret>MAX_PATH))
return res;
140 if(nwd.size()+1>MAX_PATH)
142 strncpy(buf,nwd.c_str(),MAX_PATH-1);
143 if(!SetCurrentDirectory(buf))
148 #ifdef FAUDES_GENERIC
163 signal(SIGTERM, sighandler);
166 signal(SIGINT, sighandler);
169 signal(SIGQUIT, sighandler);
172 signal(SIGHUP, sighandler);
175 signal(SIGABRT, sighandler);
182 return strsignal(sig);
184 #ifdef FAUDES_WINDOWS
194 #ifdef FAUDES_WINDOWS
198 #ifdef FAUDES_GENERIC
205 #ifdef FAUDES_SYSTIME
211 #if defined(FAUDES_POSIX)
212 void faudes_gettimeofday(faudes_systime_t* now) {
214 gettimeofday(&nowval,0);
215 now->tv_sec=nowval.tv_sec;
216 now->tv_nsec=nowval.tv_usec * 1000;
220 #if defined(FAUDES_WINDOWS)
221 void faudes_gettimeofday(faudes_systime_t* now) {
223 nowval= timeGetTime();
224 now->tv_sec=nowval / 1000;
225 now->tv_nsec=(nowval % 1000) *1000000;
232 void faudes_diffsystime(
const faudes_systime_t& end,
const faudes_systime_t& begin, faudes_systime_t* res) {
233 res->tv_sec = end.tv_sec-begin.tv_sec;
234 res->tv_nsec = end.tv_nsec-begin.tv_nsec;
235 if(res->tv_nsec <= 0){
237 res->tv_nsec += 1000000000;
242 void faudes_diffsystime(
const faudes_systime_t& end,
const faudes_systime_t& begin, faudes_mstime_t* res) {
243 *res = 1000*( end.tv_sec-begin.tv_sec);
244 *res += (end.tv_nsec-begin.tv_nsec) / 1000000;
248 void faudes_sumsystime(
const faudes_systime_t& begin,
const faudes_systime_t& duration, faudes_systime_t* res) {
249 res->tv_sec = begin.tv_sec + duration.tv_sec;
250 res->tv_nsec = begin.tv_nsec + duration.tv_nsec;
251 if(res->tv_nsec >= 1000000000) {
253 res->tv_nsec-=1000000000;
259 faudes_systime_t now;
260 faudes_gettimeofday(&now);
261 faudes_systime_t delta;
262 delta.tv_sec = msecs/1000;
263 delta.tv_nsec = (msecs % 1000) *1000000;
269 faudes_systime_t now;
270 faudes_gettimeofday(&now);
271 faudes_systime_t delta;
272 delta.tv_sec = usecs/1000000;
273 delta.tv_nsec = (usecs % 1000000) * 1000;
281 #ifdef FAUDES_NETWORK
284 int faudes_closesocket(
int fd) {
287 int faudes_setsockopt(
int fd,
int level,
int optname,
const void *optval, socklen_t optlen) {
288 return setsockopt(fd,level,optname,optval,optlen);
290 int faudes_getsockopt(
int fd,
int level,
int optname,
void *optval, socklen_t *optlen) {
291 return getsockopt(fd,level,optname,optval,optlen);
293 int faudes_getsocket_error(
int fd) {
295 socklen_t len =
sizeof(opt);
296 int res = getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &len) < 0 ? -1 : 0;
300 int faudes_setsocket_nonblocking(
int fd,
bool noblo) {
301 int sopt=fcntl(fd, F_GETFL, NULL);
302 if(sopt<0)
return -1;
304 int rc=fcntl(fd, F_SETFL, sopt|O_NONBLOCK);
305 return rc < 0 ? -1 : 0;
307 int rc=fcntl(fd, F_SETFL, sopt& (~O_NONBLOCK));
308 return rc < 0 ? -1 : 0;
312 #ifdef FAUDES_WINDOWS
313 typedef int socklen_t;
314 int faudes_closesocket(
int fd) {
315 return closesocket(fd);
317 int faudes_setsockopt(
int fd,
int level,
int optname,
const void *optval, socklen_t optlen) {
318 return setsockopt(fd,level,optname,(
char*) optval,optlen);
320 int faudes_getsockopt(
int fd,
int level,
int optname,
void *optval, socklen_t *optlen) {
321 return getsockopt(fd,level,optname,(
char*) optval,optlen);
323 int faudes_getsocket_error(
int fd) {
325 socklen_t len =
sizeof(opt);
326 int res = getsockopt(fd, SOL_SOCKET, SO_ERROR, (
char*) &opt, &len) < 0 ? -1 : 0;
330 int faudes_setsocket_nonblocking(
int fd,
bool noblo) {
331 unsigned long onoff=0;
333 return ioctlsocket(fd, FIONBIO, &onoff) == SOCKET_ERROR ? -1 : 0;
336 #ifdef FAUDES_GENERIC
337 #error option network not available on generic platform
345 #ifdef FAUDES_THREADS
348 typedef pthread_t faudes_thread_t;
350 int faudes_thread_create(faudes_thread_t *thr,
void *(*fnct)(
void *),
void *arg){
353 pthread_attr_init(&attr);
354 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
356 int ret = pthread_create(thr, &attr, fnct, arg);
358 pthread_attr_destroy(&attr);
359 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
361 faudes_thread_t faudes_thread_current(
void) {
362 return pthread_self();
364 int faudes_thread_detach(faudes_thread_t thr) {
365 return pthread_detach(thr)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
367 int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) {
368 return pthread_equal(thr0, thr1);
370 void faudes_thread_exit(
void* res) {
373 int faudes_thread_join(faudes_thread_t thr,
void **res) {
374 return pthread_join(thr, res) == 0 ? FAUDES_THREAD_ERROR : FAUDES_THREAD_SUCCESS;
380 #ifdef FAUDES_THREADS
381 #ifdef FAUDES_WINDOWS
384 DWORD faudes_thread_tlsidx=TLS_OUT_OF_INDEXES;
387 static unsigned WINAPI faudes_thread_wrapper(
void *argfth) {
389 faudes_thread_t fthread = (faudes_thread_t) argfth;
391 TlsSetValue(faudes_thread_tlsidx,fthread);
393 void *(*fnct)(
void*) = fthread->mFnct;
394 void *arg = fthread->mArg;
396 void* res = fnct(arg);
398 faudes_thread_exit(res);
404 int faudes_thread_create(faudes_thread_t *thr,
void *(*fnct)(
void *),
void *arg){
406 if(faudes_thread_tlsidx==TLS_OUT_OF_INDEXES)
407 faudes_thread_tlsidx=TlsAlloc();
408 if(faudes_thread_tlsidx==TLS_OUT_OF_INDEXES)
409 return FAUDES_THREAD_ERROR;
411 *thr = (faudes_thread_t) malloc(
sizeof(faudes_thread_record_t));
412 if(!*thr)
return FAUDES_THREAD_ERROR;
414 (*thr)->mFnct = fnct;
418 (*thr)->mHandle = (HANDLE) _beginthreadex(NULL, 0, faudes_thread_wrapper, (
void*) (*thr), 0, NULL);
420 return (*thr)->mHandle ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
424 faudes_thread_t faudes_thread_current(
void) {
426 faudes_thread_t fthread = (faudes_thread_t) TlsGetValue(faudes_thread_tlsidx);
432 int faudes_thread_detach(faudes_thread_t thr) {
433 CloseHandle(thr->mHandle);
436 return FAUDES_THREAD_SUCCESS;
440 int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) {
442 if( (thr0==NULL) && (thr1=NULL) )
return true;
443 if( (thr0==NULL) || (thr1=NULL) )
return false;
445 return thr0->mHandle == thr1->mHandle;
449 void faudes_thread_exit(
void *res) {
451 faudes_thread_t fthread = (faudes_thread_t) TlsGetValue(faudes_thread_tlsidx);
452 if(fthread) fthread->mRes=res;
458 int faudes_thread_join(faudes_thread_t thr,
void **res) {
462 DWORD rc = WaitForSingleObject(thr->mHandle, INFINITE);
464 if( (rc!=WAIT_FAILED) && (res)) *res = thr->mRes;
468 if(rc == WAIT_FAILED)
return FAUDES_THREAD_ERROR;
469 return FAUDES_THREAD_SUCCESS;
478 #ifdef FAUDES_THREADS
480 int faudes_mutex_init(faudes_mutex_t* mtx){
481 return pthread_mutex_init(mtx, NULL)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
483 void faudes_mutex_destroy(faudes_mutex_t* mtx){
484 pthread_mutex_destroy(mtx);
486 int faudes_mutex_lock(faudes_mutex_t *mtx) {
487 return pthread_mutex_lock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
489 int faudes_mutex_trylock(faudes_mutex_t *mtx){
490 return (pthread_mutex_trylock(mtx) == 0) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
492 int faudes_mutex_unlock(faudes_mutex_t *mtx){
493 return pthread_mutex_unlock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
499 #ifdef FAUDES_THREADS
500 #ifdef FAUDES_WINDOWS
501 int faudes_mutex_init(faudes_mutex_t *mtx){
502 InitializeCriticalSection(mtx);
503 return FAUDES_THREAD_SUCCESS;
505 void faudes_mutex_destroy(faudes_mutex_t *mtx){
506 DeleteCriticalSection(mtx);
508 int faudes_mutex_lock(faudes_mutex_t *mtx) {
509 EnterCriticalSection(mtx);
510 return FAUDES_THREAD_SUCCESS;
512 int faudes_mutex_trylock(faudes_mutex_t *mtx){
513 return TryEnterCriticalSection(mtx) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
515 int faudes_mutex_unlock(faudes_mutex_t *mtx){
516 LeaveCriticalSection(mtx);
517 return FAUDES_THREAD_SUCCESS;
524 #ifdef FAUDES_THREADS
526 int faudes_cond_init(faudes_cond_t* cond) {
527 return pthread_cond_init(cond, NULL) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
529 void faudes_cond_destroy(faudes_cond_t* cond) {
530 pthread_cond_destroy(cond);
532 int faudes_cond_signal(faudes_cond_t *cond){
533 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
535 int faudes_cond_broadcast(faudes_cond_t *cond) {
536 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
538 int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) {
539 return pthread_cond_wait(cond, mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
541 int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx,
const faudes_systime_t *abstime) {
542 int ret = pthread_cond_timedwait(cond, mtx, abstime);
543 if(ret == ETIMEDOUT)
return FAUDES_THREAD_TIMEOUT;
544 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
547 int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) {
548 faudes_systime_t abstime;
550 return faudes_cond_timedwait(cond,mtx,&abstime);
561 #ifdef FAUDES_THREADS
562 #ifdef FAUDES_WINDOWS
565 #define EVENT_SIGNAL 0
566 #define EVENT_BROADCAST 1
569 int faudes_cond_init(faudes_cond_t* cond) {
571 cond->mWaitersCount = 0;
572 InitializeCriticalSection(&cond->mWaitersCountMutex);
574 cond->mEvents[EVENT_SIGNAL]=CreateEvent(NULL, FALSE, FALSE, NULL);
576 cond->mEvents[EVENT_BROADCAST] = CreateEvent(NULL, TRUE, FALSE, NULL);
578 if(cond->mEvents[EVENT_SIGNAL] != NULL)
579 if(cond->mEvents[EVENT_BROADCAST] != NULL)
580 return FAUDES_THREAD_SUCCESS;
582 if(cond->mEvents[EVENT_SIGNAL] != NULL)
583 CloseHandle(cond->mEvents[EVENT_SIGNAL]);
584 if(cond->mEvents[EVENT_BROADCAST] != NULL)
585 CloseHandle(cond->mEvents[EVENT_BROADCAST]);
586 cond->mEvents[EVENT_BROADCAST] = NULL;
587 cond->mEvents[EVENT_SIGNAL]=NULL;
588 return FAUDES_THREAD_ERROR;
592 void faudes_cond_destroy(faudes_cond_t* cond) {
593 if(cond->mEvents[EVENT_SIGNAL] != NULL)
594 CloseHandle(cond->mEvents[EVENT_SIGNAL]);
595 if(cond->mEvents[EVENT_BROADCAST] != NULL)
596 CloseHandle(cond->mEvents[EVENT_BROADCAST]);
597 DeleteCriticalSection(&cond->mWaitersCountMutex);
601 int faudes_cond_signal(faudes_cond_t *cond){
604 EnterCriticalSection(&cond->mWaitersCountMutex);
605 waiters = (cond->mWaitersCount > 0);
606 LeaveCriticalSection(&cond->mWaitersCountMutex);
609 if(SetEvent(cond->mEvents[EVENT_SIGNAL]) == 0)
610 return FAUDES_THREAD_ERROR;
612 return FAUDES_THREAD_SUCCESS;
616 int faudes_cond_broadcast(faudes_cond_t *cond) {
619 EnterCriticalSection(&cond->mWaitersCountMutex);
620 waiters = (cond->mWaitersCount > 0);
621 LeaveCriticalSection(&cond->mWaitersCountMutex);
624 if(SetEvent(cond->mEvents[EVENT_BROADCAST]) == 0)
625 return FAUDES_THREAD_ERROR;
627 return FAUDES_THREAD_SUCCESS;
631 int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) {
633 EnterCriticalSection(&cond->mWaitersCountMutex);
634 ++ cond->mWaitersCount;
635 LeaveCriticalSection(&cond->mWaitersCountMutex);
637 LeaveCriticalSection(mtx);
639 int res = WaitForMultipleObjects(2, cond->mEvents, FALSE, (DWORD) duration);
641 EnterCriticalSection(&cond->mWaitersCountMutex);
643 -- cond->mWaitersCount;
646 (res == (WAIT_OBJECT_0 + EVENT_BROADCAST)) &&
647 (cond->mWaitersCount == 0);
648 LeaveCriticalSection(&cond->mWaitersCountMutex);
650 if(last) ResetEvent(cond->mEvents[EVENT_BROADCAST]);
652 EnterCriticalSection(mtx);
654 if(res == (
int) WAIT_TIMEOUT)
655 return FAUDES_THREAD_TIMEOUT;
656 if(res == (
int) WAIT_FAILED)
657 return FAUDES_THREAD_ERROR;
658 return FAUDES_THREAD_SUCCESS;
662 int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) {
663 return faudes_cond_reltimedwait(cond, mtx, INFINITE);
667 int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx,
const faudes_systime_t *abstime) {
669 faudes_systime_t now;
670 faudes_gettimeofday(&now);
672 DWORD rels = abstime->tv_sec - now.tv_sec;
674 if(rels > (4294967295u/1000)-1) rels = 4294967295u/1000-1;
676 DWORD relms = rels*1000 + (abstime->tv_nsec - now.tv_nsec + 500000) / 1000000;
678 return faudes_cond_reltimedwait(cond, mtx, relms);