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);
193 #ifdef FAUDES_WINDOWS
197 #ifdef FAUDES_GENERIC
204 #ifdef FAUDES_SYSTIME
210 #if defined(FAUDES_POSIX)
211 void faudes_gettimeofday(faudes_systime_t* now) {
213 gettimeofday(&nowval,0);
214 now->tv_sec=nowval.tv_sec;
215 now->tv_nsec=nowval.tv_usec * 1000;
219 #if defined(FAUDES_WINDOWS)
220 void faudes_gettimeofday(faudes_systime_t* now) {
222 nowval= timeGetTime();
223 now->tv_sec=nowval / 1000;
224 now->tv_nsec=(nowval % 1000) *1000000;
231 void faudes_diffsystime(
const faudes_systime_t& end,
const faudes_systime_t& begin, faudes_systime_t* res) {
232 res->tv_sec = end.tv_sec-begin.tv_sec;
233 res->tv_nsec = end.tv_nsec-begin.tv_nsec;
234 if(res->tv_nsec <= 0){
236 res->tv_nsec += 1000000000;
241 void faudes_diffsystime(
const faudes_systime_t& end,
const faudes_systime_t& begin, faudes_mstime_t* res) {
242 *res = 1000*( end.tv_sec-begin.tv_sec);
243 *res += (end.tv_nsec-begin.tv_nsec) / 1000000;
247 void faudes_sumsystime(
const faudes_systime_t& begin,
const faudes_systime_t& duration, faudes_systime_t* res) {
248 res->tv_sec = begin.tv_sec + duration.tv_sec;
249 res->tv_nsec = begin.tv_nsec + duration.tv_nsec;
250 if(res->tv_nsec >= 1000000000) {
252 res->tv_nsec-=1000000000;
258 faudes_systime_t now;
259 faudes_gettimeofday(&now);
260 faudes_systime_t delta;
261 delta.tv_sec = msecs/1000;
262 delta.tv_nsec = (msecs % 1000) *1000000;
268 faudes_systime_t now;
269 faudes_gettimeofday(&now);
270 faudes_systime_t delta;
271 delta.tv_sec = usecs/1000000;
272 delta.tv_nsec = (usecs % 1000000) * 1000;
280 #ifdef FAUDES_NETWORK
283 int faudes_closesocket(
int fd) {
286 int faudes_setsockopt(
int fd,
int level,
int optname,
const void *optval, socklen_t optlen) {
287 return setsockopt(fd,level,optname,optval,optlen);
289 int faudes_getsockopt(
int fd,
int level,
int optname,
void *optval, socklen_t *optlen) {
290 return getsockopt(fd,level,optname,optval,optlen);
292 int faudes_getsocket_error(
int fd) {
294 socklen_t len =
sizeof(opt);
295 int res = getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &len) < 0 ? -1 : 0;
299 int faudes_setsocket_nonblocking(
int fd,
bool noblo) {
300 int sopt=fcntl(fd, F_GETFL, NULL);
301 if(sopt<0)
return -1;
303 int rc=fcntl(fd, F_SETFL, sopt|O_NONBLOCK);
304 return rc < 0 ? -1 : 0;
306 int rc=fcntl(fd, F_SETFL, sopt& (~O_NONBLOCK));
307 return rc < 0 ? -1 : 0;
311 #ifdef FAUDES_WINDOWS
312 typedef int socklen_t;
313 int faudes_closesocket(
int fd) {
314 return closesocket(fd);
316 int faudes_setsockopt(
int fd,
int level,
int optname,
const void *optval, socklen_t optlen) {
317 return setsockopt(fd,level,optname,(
char*) optval,optlen);
319 int faudes_getsockopt(
int fd,
int level,
int optname,
void *optval, socklen_t *optlen) {
320 return getsockopt(fd,level,optname,(
char*) optval,optlen);
322 int faudes_getsocket_error(
int fd) {
324 socklen_t len =
sizeof(opt);
325 int res = getsockopt(fd, SOL_SOCKET, SO_ERROR, (
char*) &opt, &len) < 0 ? -1 : 0;
329 int faudes_setsocket_nonblocking(
int fd,
bool noblo) {
330 unsigned long onoff=0;
332 return ioctlsocket(fd, FIONBIO, &onoff) == SOCKET_ERROR ? -1 : 0;
335 #ifdef FAUDES_GENERIC
336 #error option network not available on generic platform
344 #ifdef FAUDES_THREADS
347 typedef pthread_t faudes_thread_t;
349 int faudes_thread_create(faudes_thread_t *thr,
void *(*fnct)(
void *),
void *arg){
352 pthread_attr_init(&attr);
353 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
355 int ret = pthread_create(thr, &attr, fnct, arg);
357 pthread_attr_destroy(&attr);
358 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
360 faudes_thread_t faudes_thread_current(
void) {
361 return pthread_self();
363 int faudes_thread_detach(faudes_thread_t thr) {
364 return pthread_detach(thr)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
366 int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) {
367 return pthread_equal(thr0, thr1);
369 void faudes_thread_exit(
void* res) {
372 int faudes_thread_join(faudes_thread_t thr,
void **res) {
373 return pthread_join(thr, res) == 0 ? FAUDES_THREAD_ERROR : FAUDES_THREAD_SUCCESS;
379 #ifdef FAUDES_THREADS
380 #ifdef FAUDES_WINDOWS
383 DWORD faudes_thread_tlsidx=TLS_OUT_OF_INDEXES;
386 static unsigned WINAPI faudes_thread_wrapper(
void *argfth) {
388 faudes_thread_t fthread = (faudes_thread_t) argfth;
390 TlsSetValue(faudes_thread_tlsidx,fthread);
392 void *(*fnct)(
void*) = fthread->mFnct;
393 void *arg = fthread->mArg;
395 void* res = fnct(arg);
397 faudes_thread_exit(res);
403 int faudes_thread_create(faudes_thread_t *thr,
void *(*fnct)(
void *),
void *arg){
405 if(faudes_thread_tlsidx==TLS_OUT_OF_INDEXES)
406 faudes_thread_tlsidx=TlsAlloc();
407 if(faudes_thread_tlsidx==TLS_OUT_OF_INDEXES)
408 return FAUDES_THREAD_ERROR;
410 *thr = (faudes_thread_t) malloc(
sizeof(faudes_thread_record_t));
411 if(!*thr)
return FAUDES_THREAD_ERROR;
413 (*thr)->mFnct = fnct;
417 (*thr)->mHandle = (HANDLE) _beginthreadex(NULL, 0, faudes_thread_wrapper, (
void*) (*thr), 0, NULL);
419 return (*thr)->mHandle ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
423 faudes_thread_t faudes_thread_current(
void) {
425 faudes_thread_t fthread = (faudes_thread_t) TlsGetValue(faudes_thread_tlsidx);
431 int faudes_thread_detach(faudes_thread_t thr) {
432 CloseHandle(thr->mHandle);
435 return FAUDES_THREAD_SUCCESS;
439 int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) {
441 if( (thr0==NULL) && (thr1=NULL) )
return true;
442 if( (thr0==NULL) || (thr1=NULL) )
return false;
444 return thr0->mHandle == thr1->mHandle;
448 void faudes_thread_exit(
void *res) {
450 faudes_thread_t fthread = (faudes_thread_t) TlsGetValue(faudes_thread_tlsidx);
451 if(fthread) fthread->mRes=res;
457 int faudes_thread_join(faudes_thread_t thr,
void **res) {
461 DWORD rc = WaitForSingleObject(thr->mHandle, INFINITE);
463 if( (rc!=WAIT_FAILED) && (res)) *res = thr->mRes;
467 if(rc == WAIT_FAILED)
return FAUDES_THREAD_ERROR;
468 return FAUDES_THREAD_SUCCESS;
477 #ifdef FAUDES_THREADS
479 int faudes_mutex_init(faudes_mutex_t* mtx){
480 return pthread_mutex_init(mtx, NULL)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
482 void faudes_mutex_destroy(faudes_mutex_t* mtx){
483 pthread_mutex_destroy(mtx);
485 int faudes_mutex_lock(faudes_mutex_t *mtx) {
486 return pthread_mutex_lock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
488 int faudes_mutex_trylock(faudes_mutex_t *mtx){
489 return (pthread_mutex_trylock(mtx) == 0) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
491 int faudes_mutex_unlock(faudes_mutex_t *mtx){
492 return pthread_mutex_unlock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
498 #ifdef FAUDES_THREADS
499 #ifdef FAUDES_WINDOWS
500 int faudes_mutex_init(faudes_mutex_t *mtx){
501 InitializeCriticalSection(mtx);
502 return FAUDES_THREAD_SUCCESS;
504 void faudes_mutex_destroy(faudes_mutex_t *mtx){
505 DeleteCriticalSection(mtx);
507 int faudes_mutex_lock(faudes_mutex_t *mtx) {
508 EnterCriticalSection(mtx);
509 return FAUDES_THREAD_SUCCESS;
511 int faudes_mutex_trylock(faudes_mutex_t *mtx){
512 return TryEnterCriticalSection(mtx) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
514 int faudes_mutex_unlock(faudes_mutex_t *mtx){
515 LeaveCriticalSection(mtx);
516 return FAUDES_THREAD_SUCCESS;
523 #ifdef FAUDES_THREADS
525 int faudes_cond_init(faudes_cond_t* cond) {
526 return pthread_cond_init(cond, NULL) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
528 void faudes_cond_destroy(faudes_cond_t* cond) {
529 pthread_cond_destroy(cond);
531 int faudes_cond_signal(faudes_cond_t *cond){
532 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
534 int faudes_cond_broadcast(faudes_cond_t *cond) {
535 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
537 int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) {
538 return pthread_cond_wait(cond, mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
540 int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx,
const faudes_systime_t *abstime) {
541 int ret = pthread_cond_timedwait(cond, mtx, abstime);
542 if(ret == ETIMEDOUT)
return FAUDES_THREAD_TIMEOUT;
543 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
546 int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) {
547 faudes_systime_t abstime;
549 return faudes_cond_timedwait(cond,mtx,&abstime);
560 #ifdef FAUDES_THREADS
561 #ifdef FAUDES_WINDOWS
564 #define EVENT_SIGNAL 0
565 #define EVENT_BROADCAST 1
568 int faudes_cond_init(faudes_cond_t* cond) {
570 cond->mWaitersCount = 0;
571 InitializeCriticalSection(&cond->mWaitersCountMutex);
573 cond->mEvents[EVENT_SIGNAL]=CreateEvent(NULL, FALSE, FALSE, NULL);
575 cond->mEvents[EVENT_BROADCAST] = CreateEvent(NULL, TRUE, FALSE, NULL);
577 if(cond->mEvents[EVENT_SIGNAL] != NULL)
578 if(cond->mEvents[EVENT_BROADCAST] != NULL)
579 return FAUDES_THREAD_SUCCESS;
581 if(cond->mEvents[EVENT_SIGNAL] != NULL)
582 CloseHandle(cond->mEvents[EVENT_SIGNAL]);
583 if(cond->mEvents[EVENT_BROADCAST] != NULL)
584 CloseHandle(cond->mEvents[EVENT_BROADCAST]);
585 cond->mEvents[EVENT_BROADCAST] = NULL;
586 cond->mEvents[EVENT_SIGNAL]=NULL;
587 return FAUDES_THREAD_ERROR;
591 void faudes_cond_destroy(faudes_cond_t* cond) {
592 if(cond->mEvents[EVENT_SIGNAL] != NULL)
593 CloseHandle(cond->mEvents[EVENT_SIGNAL]);
594 if(cond->mEvents[EVENT_BROADCAST] != NULL)
595 CloseHandle(cond->mEvents[EVENT_BROADCAST]);
596 DeleteCriticalSection(&cond->mWaitersCountMutex);
600 int faudes_cond_signal(faudes_cond_t *cond){
603 EnterCriticalSection(&cond->mWaitersCountMutex);
604 waiters = (cond->mWaitersCount > 0);
605 LeaveCriticalSection(&cond->mWaitersCountMutex);
608 if(SetEvent(cond->mEvents[EVENT_SIGNAL]) == 0)
609 return FAUDES_THREAD_ERROR;
611 return FAUDES_THREAD_SUCCESS;
615 int faudes_cond_broadcast(faudes_cond_t *cond) {
618 EnterCriticalSection(&cond->mWaitersCountMutex);
619 waiters = (cond->mWaitersCount > 0);
620 LeaveCriticalSection(&cond->mWaitersCountMutex);
623 if(SetEvent(cond->mEvents[EVENT_BROADCAST]) == 0)
624 return FAUDES_THREAD_ERROR;
626 return FAUDES_THREAD_SUCCESS;
630 int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) {
632 EnterCriticalSection(&cond->mWaitersCountMutex);
633 ++ cond->mWaitersCount;
634 LeaveCriticalSection(&cond->mWaitersCountMutex);
636 LeaveCriticalSection(mtx);
638 int res = WaitForMultipleObjects(2, cond->mEvents, FALSE, (DWORD) duration);
640 EnterCriticalSection(&cond->mWaitersCountMutex);
642 -- cond->mWaitersCount;
645 (res == (WAIT_OBJECT_0 + EVENT_BROADCAST)) &&
646 (cond->mWaitersCount == 0);
647 LeaveCriticalSection(&cond->mWaitersCountMutex);
649 if(last) ResetEvent(cond->mEvents[EVENT_BROADCAST]);
651 EnterCriticalSection(mtx);
653 if(res == (
int) WAIT_TIMEOUT)
654 return FAUDES_THREAD_TIMEOUT;
655 if(res == (
int) WAIT_FAILED)
656 return FAUDES_THREAD_ERROR;
657 return FAUDES_THREAD_SUCCESS;
661 int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) {
662 return faudes_cond_reltimedwait(cond, mtx, INFINITE);
666 int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx,
const faudes_systime_t *abstime) {
668 faudes_systime_t now;
669 faudes_gettimeofday(&now);
671 DWORD rels = abstime->tv_sec - now.tv_sec;
673 if(rels > (4294967295u/1000)-1) rels = 4294967295u/1000-1;
675 DWORD relms = rels*1000 + (abstime->tv_nsec - now.tv_nsec + 500000) / 1000000;
677 return faudes_cond_reltimedwait(cond, mtx, relms);