1 #ifndef NOTCURSES_COMPAT
2 #define NOTCURSES_COMPAT
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 #include <time.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdint.h>
13 #include <pthread.h>
14 #include <sys/types.h>
15 
16 #define NANOSECS_IN_SEC 1000000000ul
17 
18 #ifdef __APPLE__
19 #define TIMER_ABSTIME 1
20 #endif
21 
22 #ifdef  __MINGW64__
23 static inline char
path_separator(void)24 path_separator(void){
25   return '\\';
26 }
27 #define NL "\r\n"
28 #include <Lmcons.h>
29 #include <winsock2.h>
30 #define tcgetattr(x, y) (0)
31 #define tcsetattr(x, y, z) (0)
32 #define ECHO      0
33 #define ICANON    0
34 #define ICRNL     0
35 #define INLCR     0
36 #define ISIG      0
37 #define TCSAFLUSH 0
38 #define TCSANOW   0
39 #define O_NOCTTY  0
40 #define O_CLOEXEC O_NOINHERIT
41 #define O_NONBLOCK 0
42 #define O_DIRECTORY 0
43 #define S_IFLNK 0
44 #define SA_SIGINFO 0
45 #define SA_RESETHAND 0
46 #define SIGQUIT 0
47 #define SIGCONT 0
48 #define SIGWINCH 0
49 #define SIGSTOP 0
50 #define gettimeofday mingw_gettimeofday
51 #define sigaddset(x, y)
52 typedef struct siginfo_t {
53   int aieeee;
54 } siginfo_t;
55 #define sigset_t int
56 #define nl_langinfo(x) "UTF-8"
57 #define ppoll(w, x, y, z) WSAPoll((w), (x), (y))
58 pid_t waitpid(pid_t pid, int* ret, int flags);
59 struct winsize {
60  unsigned short ws_row;
61  unsigned short ws_col;
62  unsigned short ws_xpixel;
63  unsigned short ws_ypixel;
64 };
65 #define WNOHANG 0
66 #else
67 static inline char
68 path_separator(void){
69   return '/';
70 }
71 #define NL "\n"
72 #include <poll.h>
73 #include <termios.h>
74 #include <sys/wait.h>
75 #include <sys/time.h>
76 #include <sys/mman.h>
77 #include <sys/ioctl.h>
78 #endif
79 
80 // get the default data directory (heap-allocated). on unix, this is compiled
81 // in from builddef.h. on windows, we try to look it up in the registry (it
82 // ought have been written during installation), and fall back to builddef.h.
83 char* notcurses_data_dir(void);
84 
85 // initializes a pthread_cond_t to use CLOCK_MONOTONIC (as opposed to the
86 // default CLOCK_REALTIME) if possible. if not possible, initializes a
87 // regular ol' CLOCK_REALTIME condvar. this eliminates the need for
88 // pthread_cond_clockwait(), which is highly nonportable.
89 int pthread_condmonotonic_init(pthread_cond_t* cond);
90 
91 int set_fd_nonblocking(int fd, unsigned state, unsigned* oldstate);
92 int set_fd_cloexec(int fd, unsigned state, unsigned* oldstate);
93 
94 static inline uint64_t
timespec_to_ns(const struct timespec * ts)95 timespec_to_ns(const struct timespec* ts){
96   return ts->tv_sec * NANOSECS_IN_SEC + ts->tv_nsec;
97 }
98 
99 static inline struct timespec*
ns_to_timespec(uint64_t ns,struct timespec * ts)100 ns_to_timespec(uint64_t ns, struct timespec* ts){
101   ts->tv_sec = ns / NANOSECS_IN_SEC;
102   ts->tv_nsec = ns % NANOSECS_IN_SEC;
103   return ts;
104 }
105 
106 static inline uint64_t
clock_getns(clockid_t clockid)107 clock_getns(clockid_t clockid){
108   struct timespec tspec;
109   if(clock_gettime(clockid, &tspec) < 0){
110     return 0;
111   }
112   return timespec_to_ns(&tspec);
113 }
114 
115 // compatibility wrappers for code available only on certain operating systems.
116 // this file is not installed, but only consumed during compilation. if we're
117 // on an operating system which implements a given function, it won't be built.
118 int clock_nanosleep(clockid_t clockid, int flags,
119                     const struct timespec *request,
120                     struct timespec *remain);
121 
122 __attribute__ ((nonnull (2))) __attribute__ ((malloc))
123 static inline char*
notcurses_data_path(const char * ddir,const char * f)124 notcurses_data_path(const char* ddir, const char* f){
125   char* datadir = NULL;
126   if(ddir == NULL){
127     datadir = notcurses_data_dir();
128     if(datadir == NULL){
129       return NULL;
130     }
131     ddir = datadir;
132   }
133   const size_t dlen = strlen(ddir);
134   // cast is for benefit of c++ callers, sigh
135   char* path = (char*)malloc(dlen + 1 + strlen(f) + 1);
136   if(path == NULL){
137     free(datadir);
138     return NULL;
139   }
140   strcpy(path, ddir);
141   free(datadir);
142   path[dlen] = path_separator();
143   strcpy(path + dlen + 1, f);
144   return path;
145 }
146 
147 #ifdef __cplusplus
148 }
149 #else
150 #ifdef __MINGW64__
151 char* strndup(const char* str, size_t size);
152 #endif
153 #endif
154 
155 #endif
156