37 std::cerr <<
"faudes_invalid(): " << msg << std:endl;
46 static std::string faudes_pathsep_str =
"/";
47 return faudes_pathsep_str;
55 static std::string faudes_pathseps_str =
"/\\:";
56 return faudes_pathseps_str;
59 static std::string faudes_pathsep_str =
"";
60 if(faudes_pathsep_str==
"")
62 return faudes_pathsep_str;
67 static std::string faudes_pathsep_str =
"/";
68 return faudes_pathsep_str;
87 for(pos=0; pos<res.size(); ++pos) {
99 std::string res=rPath;
102 if(res.size()==0)
return res;
105 for(pos=0; pos<res.size(); ++pos) {
112 if((res.at(0)==
'\\') && isalpha(res.at(1)) && (res.at(2)==
'\\')) {
113 res = res.at(1) +
":" + res.substr(2,std::string::npos);
117 if(res.find(
' ')!=std::string::npos) {
118 res =
"\"" + res +
"\"";
129#include <linux/limits.h>
137 char buf[(PATH_MAX)+1];
138 char* wd =getcwd(buf,PATH_MAX);
139 if(wd==
nullptr)
return res;
144 return (chdir(nwd.c_str())==0 ? 0 : -1);
152 DWORD ret = GetCurrentDirectory(MAX_PATH, buf);
153 if((ret == 0) || (ret>MAX_PATH))
return res;
159 if(nwd.size()+1>MAX_PATH)
161 strncpy(buf,nwd.c_str(),MAX_PATH-1);
162 if(!SetCurrentDirectory(buf))
182 std::flush(std::cout);
183 std::flush(std::cerr);
185 xcmd=
"cmd /c \"" + xcmd +
"\"";
187 int res = std::system(xcmd.c_str());
189 FD_WARN(
"Command '" << xcmd <<
"' returned non-zero");
198 signal(SIGTERM, sighandler);
201 signal(SIGINT, sighandler);
204 signal(SIGQUIT, sighandler);
207 signal(SIGHUP, sighandler);
210 signal(SIGABRT, sighandler);
217 return strsignal(sig);
245#if defined(FAUDES_POSIX)
246void faudes_gettimeofday(faudes_systime_t* now) {
248 gettimeofday(&nowval,0);
249 now->tv_sec=nowval.tv_sec;
250 now->tv_nsec=nowval.tv_usec * 1000;
254#if defined(FAUDES_WINDOWS)
255void faudes_gettimeofday(faudes_systime_t* now) {
257 nowval= timeGetTime();
258 now->tv_sec=nowval / 1000;
259 now->tv_nsec=(nowval % 1000) *1000000;
266void faudes_diffsystime(
const faudes_systime_t& end,
const faudes_systime_t& begin, faudes_systime_t* res) {
267 res->tv_sec = end.tv_sec-begin.tv_sec;
268 res->tv_nsec = end.tv_nsec-begin.tv_nsec;
269 if(res->tv_nsec <= 0){
271 res->tv_nsec += 1000000000;
276void faudes_diffsystime(
const faudes_systime_t& end,
const faudes_systime_t& begin, faudes_mstime_t* res) {
277 *res = 1000*( end.tv_sec-begin.tv_sec);
278 *res += (end.tv_nsec-begin.tv_nsec) / 1000000;
282void faudes_sumsystime(
const faudes_systime_t& begin,
const faudes_systime_t& duration, faudes_systime_t* res) {
283 res->tv_sec = begin.tv_sec + duration.tv_sec;
284 res->tv_nsec = begin.tv_nsec + duration.tv_nsec;
285 if(res->tv_nsec >= 1000000000) {
287 res->tv_nsec-=1000000000;
293 faudes_systime_t now;
294 faudes_gettimeofday(&now);
295 faudes_systime_t delta;
296 delta.tv_sec = msecs/1000;
297 delta.tv_nsec = (msecs % 1000) *1000000;
303 faudes_systime_t now;
304 faudes_gettimeofday(&now);
305 faudes_systime_t delta;
306 delta.tv_sec = usecs/1000000;
307 delta.tv_nsec = (usecs % 1000000) * 1000;
318int faudes_closesocket(
int fd) {
321int faudes_setsockopt(
int fd,
int level,
int optname,
const void *optval, socklen_t optlen) {
322 return setsockopt(fd,level,optname,optval,optlen);
324int faudes_getsockopt(
int fd,
int level,
int optname,
void *optval, socklen_t *optlen) {
325 return getsockopt(fd,level,optname,optval,optlen);
327int faudes_getsocket_error(
int fd) {
329 socklen_t len =
sizeof(opt);
330 int res = getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &len) < 0 ? -1 : 0;
334int faudes_setsocket_nonblocking(
int fd,
bool noblo) {
335 int sopt=fcntl(fd, F_GETFL, NULL);
336 if(sopt<0)
return -1;
338 int rc=fcntl(fd, F_SETFL, sopt|O_NONBLOCK);
339 return rc < 0 ? -1 : 0;
341 int rc=fcntl(fd, F_SETFL, sopt& (~O_NONBLOCK));
342 return rc < 0 ? -1 : 0;
347typedef int socklen_t;
348int faudes_closesocket(
int fd) {
349 return closesocket(fd);
351int faudes_setsockopt(
int fd,
int level,
int optname,
const void *optval, socklen_t optlen) {
352 return setsockopt(fd,level,optname,(
char*) optval,optlen);
354int faudes_getsockopt(
int fd,
int level,
int optname,
void *optval, socklen_t *optlen) {
355 return getsockopt(fd,level,optname,(
char*) optval,optlen);
357int faudes_getsocket_error(
int fd) {
359 socklen_t len =
sizeof(opt);
360 int res = getsockopt(fd, SOL_SOCKET, SO_ERROR, (
char*) &opt, &len) < 0 ? -1 : 0;
364int faudes_setsocket_nonblocking(
int fd,
bool noblo) {
365 unsigned long onoff=0;
367 return ioctlsocket(fd, FIONBIO, &onoff) == SOCKET_ERROR ? -1 : 0;
371#error option network not available on generic platform
382typedef pthread_t faudes_thread_t;
384int faudes_thread_create(faudes_thread_t *thr,
void *(*fnct)(
void *),
void *arg){
387 pthread_attr_init(&attr);
388 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
390 int ret = pthread_create(thr, &attr, fnct, arg);
392 pthread_attr_destroy(&attr);
393 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
395faudes_thread_t faudes_thread_current(
void) {
396 return pthread_self();
398int faudes_thread_detach(faudes_thread_t thr) {
399 return pthread_detach(thr)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
401int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) {
402 return pthread_equal(thr0, thr1);
404void faudes_thread_exit(
void* res) {
407int faudes_thread_join(faudes_thread_t thr,
void **res) {
408 return pthread_join(thr, res) == 0 ? FAUDES_THREAD_ERROR : FAUDES_THREAD_SUCCESS;
418DWORD faudes_thread_tlsidx=TLS_OUT_OF_INDEXES;
421static unsigned WINAPI faudes_thread_wrapper(
void *argfth) {
423 faudes_thread_t fthread = (faudes_thread_t) argfth;
425 TlsSetValue(faudes_thread_tlsidx,fthread);
427 void *(*fnct)(
void*) = fthread->mFnct;
428 void *arg = fthread->mArg;
430 void* res = fnct(arg);
432 faudes_thread_exit(res);
438int faudes_thread_create(faudes_thread_t *thr,
void *(*fnct)(
void *),
void *arg){
440 if(faudes_thread_tlsidx==TLS_OUT_OF_INDEXES)
441 faudes_thread_tlsidx=TlsAlloc();
442 if(faudes_thread_tlsidx==TLS_OUT_OF_INDEXES)
443 return FAUDES_THREAD_ERROR;
445 *thr = (faudes_thread_t) malloc(
sizeof(faudes_thread_record_t));
446 if(!*thr)
return FAUDES_THREAD_ERROR;
448 (*thr)->mFnct = fnct;
452 (*thr)->mHandle = (HANDLE) _beginthreadex(NULL, 0, faudes_thread_wrapper, (
void*) (*thr), 0, NULL);
454 return (*thr)->mHandle ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
458faudes_thread_t faudes_thread_current(
void) {
460 faudes_thread_t fthread = (faudes_thread_t) TlsGetValue(faudes_thread_tlsidx);
466int faudes_thread_detach(faudes_thread_t thr) {
467 CloseHandle(thr->mHandle);
470 return FAUDES_THREAD_SUCCESS;
474int faudes_thread_equal(faudes_thread_t thr0, faudes_thread_t thr1) {
476 if( (thr0==NULL) && (thr1=NULL) )
return true;
477 if( (thr0==NULL) || (thr1=NULL) )
return false;
479 return thr0->mHandle == thr1->mHandle;
483void faudes_thread_exit(
void *res) {
485 faudes_thread_t fthread = (faudes_thread_t) TlsGetValue(faudes_thread_tlsidx);
486 if(fthread) fthread->mRes=res;
492int faudes_thread_join(faudes_thread_t thr,
void **res) {
496 DWORD rc = WaitForSingleObject(thr->mHandle, INFINITE);
498 if( (rc!=WAIT_FAILED) && (res)) *res = thr->mRes;
502 if(rc == WAIT_FAILED)
return FAUDES_THREAD_ERROR;
503 return FAUDES_THREAD_SUCCESS;
514int faudes_mutex_init(faudes_mutex_t* mtx){
515 return pthread_mutex_init(mtx, NULL)==0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
517void faudes_mutex_destroy(faudes_mutex_t* mtx){
518 pthread_mutex_destroy(mtx);
520int faudes_mutex_lock(faudes_mutex_t *mtx) {
521 return pthread_mutex_lock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
523int faudes_mutex_trylock(faudes_mutex_t *mtx){
524 return (pthread_mutex_trylock(mtx) == 0) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
526int faudes_mutex_unlock(faudes_mutex_t *mtx){
527 return pthread_mutex_unlock(mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
535int faudes_mutex_init(faudes_mutex_t *mtx){
536 InitializeCriticalSection(mtx);
537 return FAUDES_THREAD_SUCCESS;
539void faudes_mutex_destroy(faudes_mutex_t *mtx){
540 DeleteCriticalSection(mtx);
542int faudes_mutex_lock(faudes_mutex_t *mtx) {
543 EnterCriticalSection(mtx);
544 return FAUDES_THREAD_SUCCESS;
546int faudes_mutex_trylock(faudes_mutex_t *mtx){
547 return TryEnterCriticalSection(mtx) ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
549int faudes_mutex_unlock(faudes_mutex_t *mtx){
550 LeaveCriticalSection(mtx);
551 return FAUDES_THREAD_SUCCESS;
560int faudes_cond_init(faudes_cond_t* cond) {
561 return pthread_cond_init(cond, NULL) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
563void faudes_cond_destroy(faudes_cond_t* cond) {
564 pthread_cond_destroy(cond);
566int faudes_cond_signal(faudes_cond_t *cond){
567 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
569int faudes_cond_broadcast(faudes_cond_t *cond) {
570 return pthread_cond_signal(cond) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
572int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) {
573 return pthread_cond_wait(cond, mtx) == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
575int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx,
const faudes_systime_t *abstime) {
576 int ret = pthread_cond_timedwait(cond, mtx, abstime);
577 if(ret == ETIMEDOUT)
return FAUDES_THREAD_TIMEOUT;
578 return ret == 0 ? FAUDES_THREAD_SUCCESS : FAUDES_THREAD_ERROR;
581int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) {
582 faudes_systime_t abstime;
584 return faudes_cond_timedwait(cond,mtx,&abstime);
599#define EVENT_SIGNAL 0
600#define EVENT_BROADCAST 1
603int faudes_cond_init(faudes_cond_t* cond) {
605 cond->mWaitersCount = 0;
606 InitializeCriticalSection(&cond->mWaitersCountMutex);
608 cond->mEvents[EVENT_SIGNAL]=CreateEvent(NULL, FALSE, FALSE, NULL);
610 cond->mEvents[EVENT_BROADCAST] = CreateEvent(NULL, TRUE, FALSE, NULL);
612 if(cond->mEvents[EVENT_SIGNAL] != NULL)
613 if(cond->mEvents[EVENT_BROADCAST] != NULL)
614 return FAUDES_THREAD_SUCCESS;
616 if(cond->mEvents[EVENT_SIGNAL] != NULL)
617 CloseHandle(cond->mEvents[EVENT_SIGNAL]);
618 if(cond->mEvents[EVENT_BROADCAST] != NULL)
619 CloseHandle(cond->mEvents[EVENT_BROADCAST]);
620 cond->mEvents[EVENT_BROADCAST] = NULL;
621 cond->mEvents[EVENT_SIGNAL]=NULL;
622 return FAUDES_THREAD_ERROR;
626void faudes_cond_destroy(faudes_cond_t* cond) {
627 if(cond->mEvents[EVENT_SIGNAL] != NULL)
628 CloseHandle(cond->mEvents[EVENT_SIGNAL]);
629 if(cond->mEvents[EVENT_BROADCAST] != NULL)
630 CloseHandle(cond->mEvents[EVENT_BROADCAST]);
631 DeleteCriticalSection(&cond->mWaitersCountMutex);
635int faudes_cond_signal(faudes_cond_t *cond){
638 EnterCriticalSection(&cond->mWaitersCountMutex);
639 waiters = (cond->mWaitersCount > 0);
640 LeaveCriticalSection(&cond->mWaitersCountMutex);
643 if(SetEvent(cond->mEvents[EVENT_SIGNAL]) == 0)
644 return FAUDES_THREAD_ERROR;
646 return FAUDES_THREAD_SUCCESS;
650int faudes_cond_broadcast(faudes_cond_t *cond) {
653 EnterCriticalSection(&cond->mWaitersCountMutex);
654 waiters = (cond->mWaitersCount > 0);
655 LeaveCriticalSection(&cond->mWaitersCountMutex);
658 if(SetEvent(cond->mEvents[EVENT_BROADCAST]) == 0)
659 return FAUDES_THREAD_ERROR;
661 return FAUDES_THREAD_SUCCESS;
665int faudes_cond_reltimedwait(faudes_cond_t *cond, faudes_mutex_t *mtx, faudes_mstime_t duration) {
667 EnterCriticalSection(&cond->mWaitersCountMutex);
668 ++ cond->mWaitersCount;
669 LeaveCriticalSection(&cond->mWaitersCountMutex);
671 LeaveCriticalSection(mtx);
673 int res = WaitForMultipleObjects(2, cond->mEvents, FALSE, (DWORD) duration);
675 EnterCriticalSection(&cond->mWaitersCountMutex);
677 -- cond->mWaitersCount;
680 (res == (WAIT_OBJECT_0 + EVENT_BROADCAST)) &&
681 (cond->mWaitersCount == 0);
682 LeaveCriticalSection(&cond->mWaitersCountMutex);
684 if(last) ResetEvent(cond->mEvents[EVENT_BROADCAST]);
686 EnterCriticalSection(mtx);
688 if(res == (
int) WAIT_TIMEOUT)
689 return FAUDES_THREAD_TIMEOUT;
690 if(res == (
int) WAIT_FAILED)
691 return FAUDES_THREAD_ERROR;
692 return FAUDES_THREAD_SUCCESS;
696int faudes_cond_wait(faudes_cond_t *cond, faudes_mutex_t *mtx) {
697 return faudes_cond_reltimedwait(cond, mtx, INFINITE);
701int faudes_cond_timedwait(faudes_cond_t *cond, faudes_mutex_t *mtx,
const faudes_systime_t *abstime) {
703 faudes_systime_t now;
704 faudes_gettimeofday(&now);
706 DWORD rels = abstime->tv_sec - now.tv_sec;
708 if(rels > (4294967295u/1000)-1) rels = 4294967295u/1000-1;
710 DWORD relms = rels*1000 + (abstime->tv_nsec - now.tv_nsec + 500000) / 1000000;
712 return faudes_cond_reltimedwait(cond, mtx, relms);