You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
4.1 KiB
C
195 lines
4.1 KiB
C
#include "compat/compat.h"
|
|
#include <builddef.h>
|
|
#include <pthread.h>
|
|
#ifdef __MINGW32__
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <synchapi.h>
|
|
#include <handleapi.h>
|
|
#include <processthreadsapi.h>
|
|
#include <stdio.h>
|
|
|
|
char* notcurses_data_dir(void){
|
|
const char key[] = "Software\\Notcurses\\DataDir";
|
|
DWORD plen = 0;
|
|
LSTATUS r = RegGetValueA(HKEY_CURRENT_USER, key,
|
|
NULL, RRF_RT_REG_SZ, NULL,
|
|
NULL, &plen);
|
|
if(r){
|
|
goto err;
|
|
}
|
|
char* val = malloc(plen + 1);
|
|
if(val == NULL){
|
|
goto err;
|
|
}
|
|
r = RegGetValueA(HKEY_CURRENT_USER, key, NULL, RRF_RT_REG_SZ, NULL, val, &plen);
|
|
if(r){
|
|
free(val);
|
|
goto err;
|
|
}
|
|
return val;
|
|
|
|
err:
|
|
return strdup(NOTCURSES_SHARE); // fall back to build path
|
|
}
|
|
|
|
char* strndup(const char* str, size_t size){
|
|
if(size == 0){
|
|
return NULL;
|
|
}
|
|
// t is how many bytes we're copying from the old string (not including
|
|
// any NUL terminator). it cannot be larger than strlen(str), nor can it
|
|
// be larger than size.
|
|
size_t t = strlen(str);
|
|
if(t > size){
|
|
t = size;
|
|
}
|
|
char* r = malloc(t + 1);
|
|
if(r){
|
|
if(t){
|
|
memcpy(r, str, t);
|
|
}
|
|
r[t] = '\0';
|
|
}
|
|
return r;
|
|
}
|
|
|
|
int set_fd_nonblocking(int fd, unsigned state, unsigned* oldstate){ // FIXME
|
|
(void)fd;
|
|
(void)state;
|
|
(void)oldstate;
|
|
return 0;
|
|
}
|
|
|
|
int set_fd_cloexec(int fd, unsigned state, unsigned* oldstate){ // FIXME
|
|
(void)fd;
|
|
(void)state;
|
|
(void)oldstate;
|
|
return 0;
|
|
}
|
|
|
|
pid_t waitpid(pid_t pid, int* state, int options){ // FIXME
|
|
(void)options;
|
|
(void)pid;
|
|
(void)state;
|
|
/*
|
|
WaitForSingleObject(pid, INFINITE);
|
|
long unsigned pstate;
|
|
GetExitCodeProcess(pid, &pstate);
|
|
*state = pstate;
|
|
CloseHandle(pid);
|
|
return pid;
|
|
*/
|
|
return 0;
|
|
}
|
|
#else // not windows
|
|
#include <time.h>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
char* notcurses_data_dir(void){
|
|
return strdup(NOTCURSES_SHARE);
|
|
}
|
|
|
|
int set_fd_nonblocking(int fd, unsigned state, unsigned* oldstate){
|
|
int flags = fcntl(fd, F_GETFL);
|
|
if(flags < 0){
|
|
return -1;
|
|
}
|
|
if(oldstate){
|
|
*oldstate = flags & O_NONBLOCK;
|
|
}
|
|
if(state){
|
|
if(flags & O_NONBLOCK){
|
|
return 0;
|
|
}
|
|
flags |= O_NONBLOCK;
|
|
}else{
|
|
if(!(flags & O_NONBLOCK)){
|
|
return 0;
|
|
}
|
|
flags &= ~O_NONBLOCK;
|
|
}
|
|
if(fcntl(fd, F_SETFL, flags)){
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int set_fd_cloexec(int fd, unsigned state, unsigned* oldstate){
|
|
int flags = fcntl(fd, F_GETFD);
|
|
if(flags < 0){
|
|
return -1;
|
|
}
|
|
if(oldstate){
|
|
*oldstate = flags & O_CLOEXEC;
|
|
}
|
|
if(state){
|
|
if(flags & O_CLOEXEC){
|
|
return 0;
|
|
}
|
|
flags |= O_CLOEXEC;
|
|
}else{
|
|
if(!(flags & O_CLOEXEC)){
|
|
return 0;
|
|
}
|
|
flags &= ~O_CLOEXEC;
|
|
}
|
|
if(fcntl(fd, F_SETFD, flags)){
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
#if !defined(__DragonFly_version) || __DragonFly_version < 500907
|
|
// clock_nanosleep is unavailable on DragonFly BSD and Mac OS X
|
|
int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *request,
|
|
struct timespec *remain){
|
|
struct timespec now;
|
|
if(clock_gettime(clockid, &now)){
|
|
return -1;
|
|
}
|
|
uint64_t nowns = timespec_to_ns(&now);
|
|
uint64_t targns = timespec_to_ns(request);
|
|
if(flags != TIMER_ABSTIME){
|
|
targns += nowns;
|
|
}
|
|
if(nowns < targns){
|
|
uint64_t waitns = targns - nowns;
|
|
struct timespec waitts = {
|
|
.tv_sec = waitns / 1000000000,
|
|
.tv_nsec = waitns % 1000000000,
|
|
};
|
|
return nanosleep(&waitts, remain);
|
|
}
|
|
return 0;
|
|
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
// initializes a pthread_cond_t to use CLOCK_MONOTONIC (as opposed to the
|
|
// default CLOCK_REALTIME) if possible. if not possible, initializes a
|
|
// regular ol' CLOCK_REALTIME condvar.
|
|
int pthread_condmonotonic_init(pthread_cond_t* cond){
|
|
pthread_condattr_t cat;
|
|
if(pthread_condattr_init(&cat)){
|
|
return -1;
|
|
}
|
|
// FIXME we need a solution for this on macos/windows
|
|
#ifndef __APPLE__
|
|
#ifndef __MINGW32__
|
|
if(pthread_condattr_setclock(&cat, CLOCK_MONOTONIC)){
|
|
pthread_condattr_destroy(&cat);
|
|
return -1;
|
|
}
|
|
#endif
|
|
#endif
|
|
if(pthread_cond_init(cond, &cat)){
|
|
pthread_condattr_destroy(&cat);
|
|
return -1;
|
|
}
|
|
pthread_condattr_destroy(&cat);
|
|
return 0;
|
|
}
|