arm: make r9 and r3 allocatable
[ajla.git] / os.h
bloba8c77fc8db7a4dfc1d01d4e9033ba31cfcaefab2
1 /*
2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
19 #ifndef AJLA_OS_H
20 #define AJLA_OS_H
22 #include "list.h"
23 #include "tree.h"
24 #include "thread.h"
26 #if defined(OS_OS2)
28 #include "thread.h"
30 #ifdef HAVE_SYS_TIME_H
31 #include <sys/time.h>
32 #endif
33 #include <sys/stat.h>
34 #include <fcntl.h>
36 #define NO_DIR_HANDLES
38 typedef long long os_off_t;
39 typedef int64_t os_time_t;
40 typedef struct {
41 uint32_t st_mode;
42 uint32_t st_dev;
43 uint8_t st_ino;
44 uint8_t st_nlink;
45 os_off_t st_size;
46 os_off_t st_blocks;
47 uint32_t st_blksize;
48 os_time_t st_atime;
49 os_time_t st_ctime;
50 os_time_t st_mtime;
51 uint8_t st_uid;
52 uint8_t st_gid;
53 uint8_t st_rdev;
54 } os_stat_t;
56 typedef struct {
57 unsigned f_bsize;
58 unsigned f_frsize;
59 uint64_t f_blocks;
60 uint64_t f_bfree;
61 uint64_t f_bavail;
62 uint64_t f_files;
63 uint64_t f_ffree;
64 uint64_t f_favail;
65 unsigned long f_fsid;
66 unsigned f_flag;
67 unsigned f_namemax;
68 } os_statvfs_t;
70 typedef struct {
71 int tc_flags;
72 } os_termios_t;
74 typedef struct {
75 char sysname[65];
76 char release[65];
77 char version[65];
78 char machine[65];
79 } os_utsname_t;
81 typedef struct os2_handle *handle_t;
82 #define handle_is_valid(h) ((h) != NULL)
83 #define handle_none NULL
84 uintptr_t os_handle_to_number(handle_t h);
85 handle_t os_number_to_handle(uintptr_t n, bool sckt, ajla_error_t *err);
87 typedef char *dir_handle_t;
88 #define dir_handle_is_valid(h) ((h) != NULL)
89 #define dir_none NULL
91 typedef unsigned char sig_state_t;
92 typedef unsigned signal_seq_t;
94 #define OS_HAS_DLOPEN
95 struct dl_handle_t;
96 struct dl_handle_t *os_dlopen(const char *filename, ajla_error_t *err, char **err_msg);
97 void os_dlclose(struct dl_handle_t *dlh);
98 bool os_dlsym(struct dl_handle_t *dlh, const char *symbol, void **result);
100 #define os_getaddrinfo_is_thread_safe() false
102 ULONG APIENTRY os2_exception_handler(PEXCEPTIONREPORTRECORD, struct _EXCEPTIONREGISTRATIONRECORD *, PCONTEXTRECORD, PVOID);
104 #elif defined(OS_WIN32)
106 #include <sys/stat.h>
107 #include <fcntl.h>
109 #define NO_DIR_HANDLES
111 typedef int64_t os_off_t;
112 typedef int64_t os_time_t;
114 typedef struct {
115 uint32_t st_mode;
116 uint32_t st_dev;
117 uint64_t st_ino;
118 uint32_t st_nlink;
119 os_off_t st_size;
120 os_off_t st_blocks;
121 uint32_t st_blksize;
122 os_time_t st_atime;
123 os_time_t st_ctime;
124 os_time_t st_mtime;
125 uint8_t st_uid;
126 uint8_t st_gid;
127 uint8_t st_rdev;
128 } os_stat_t;
130 typedef struct {
131 unsigned f_bsize;
132 unsigned f_frsize;
133 uint64_t f_blocks;
134 uint64_t f_bfree;
135 uint64_t f_bavail;
136 uint64_t f_files;
137 uint64_t f_ffree;
138 uint64_t f_favail;
139 unsigned long f_fsid;
140 unsigned f_flag;
141 unsigned f_namemax;
142 } os_statvfs_t;
144 typedef struct {
145 int tc_flags;
146 } os_termios_t;
148 typedef struct {
149 char sysname[65];
150 char release[65];
151 char version[129];
152 char machine[65];
153 } os_utsname_t;
155 typedef struct win32_handle *handle_t;
156 #define handle_is_valid(h) ((h) != NULL)
157 #define handle_none NULL
158 uintptr_t os_handle_to_number(handle_t h);
159 handle_t os_number_to_handle(uintptr_t n, bool sckt, ajla_error_t *err);
161 typedef char *dir_handle_t;
162 #define dir_handle_is_valid(h) ((h) != NULL)
163 #define dir_none NULL
165 typedef unsigned char sig_state_t;
166 typedef uint64_t signal_seq_t;
168 #ifndef O_NONBLOCK
169 #define O_NONBLOCK 0x40000000
170 #endif
172 #ifdef _MSC_VER
173 #undef S_IFIFO
174 #undef S_IFCHR
175 #undef S_IFDIR
176 #undef S_IFBLK
177 #undef S_IFREG
178 #undef S_IFLNK
179 #undef S_IFSOCK
180 #undef S_IFMT
181 #define S_IFIFO 0010000
182 #define S_IFCHR 0020000
183 #define S_IFDIR 0040000
184 #define S_IFBLK 0060000
185 #define S_IFREG 0100000
186 #define S_IFLNK 0120000
187 #define S_IFSOCK 0140000
188 #define S_IFMT 0170000
189 #define S_ISFIFO(x) (((x) & S_IFMT) == S_IFIFO)
190 #define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR)
191 #define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
192 #define S_ISBLK(x) (((x) & S_IFMT) == S_IFBLK)
193 #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
194 #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
195 #define S_ISSOCK(x) (((x) & S_IFMT) == S_IFSOCK)
196 #endif
198 #define OS_HAS_MMAP
199 int os_getpagesize(void);
200 void *os_mmap(void *ptr, size_t size, int prot, int flags, handle_t h, os_off_t off, ajla_error_t *err);
201 void os_munmap(void *ptr, size_t size, bool file);
202 bool os_mprotect(void *ptr, size_t size, int prot, ajla_error_t *err);
203 #define MAP_FAILED ((void *)-1)
204 #define PROT_NONE 0
205 #define PROT_READ 1
206 #define PROT_WRITE 2
207 #define PROT_EXEC 4
208 #define MAP_ANONYMOUS 1
209 #define MAP_PRIVATE 2
210 #define MAP_FIXED 4
211 #define MAP_EXCL 8
212 #define MAP_NORESERVE 16
213 #define MAP_ALIGNED(x) (32 * (x))
214 #define MAP_ALIGNED_BITS(m) ((m) >> 5)
216 #define OS_HAS_DLOPEN
217 struct dl_handle_t;
218 struct dl_handle_t *os_dlopen(const char *filename, ajla_error_t *err, char **err_msg);
219 void os_dlclose(struct dl_handle_t *dlh);
220 bool os_dlsym(struct dl_handle_t *dlh, const char *symbol, void **result);
222 bool os_getaddrinfo_is_thread_safe(void);
224 void os_get_environment(char **str, size_t *l);
226 #else
228 #ifdef HAVE_SYS_TIME_H
229 #include <sys/time.h>
230 #endif
231 #ifdef HAVE_SIGNAL_H
232 #include <signal.h>
233 #endif
234 #ifdef HAVE_UCONTEXT_H
235 #include <ucontext.h>
236 #endif
237 #if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
238 #include <sys/utsname.h>
239 #endif
240 #include <sys/stat.h>
241 #ifdef HAVE_SYS_STATVFS_H
242 #include <sys/statvfs.h>
243 #elif defined(HAVE_SYS_VFS_H)
244 #include <sys/vfs.h>
245 #endif
246 #include <termios.h>
248 #if !defined(HAVE_FCHDIR) || defined(OS_DOS) || defined(OS_CYGWIN) || defined(UNUSUAL_NO_DIR_HANDLES)
249 #define NO_DIR_HANDLES
250 #endif
252 #if defined(__hpux) && !defined(__LP64__)
253 #if defined(HAVE_FSTAT64) && defined(HAVE_FSTATVFS64) && defined(HAVE_FTRUNCATE64) && defined(HAVE_LSEEK64) && defined(HAVE_LSTAT64) && defined(HAVE_MMAP64) && defined(HAVE_OPEN64) && defined(HAVE_PREAD64) && defined(HAVE_PWRITE64) && defined(HAVE_STAT64) && defined(HAVE_STATVFS64) && defined(HAVE_TRUNCATE64)
254 #define OS_USE_LARGEFILE64_SOURCE
255 #endif
256 #endif
258 #ifdef OS_USE_LARGEFILE64_SOURCE
259 typedef off64_t os_off_t;
260 typedef struct stat64 os_stat_t;
261 typedef struct statvfs64 os_statvfs_t;
262 #else
263 typedef off_t os_off_t;
264 typedef struct stat os_stat_t;
265 #if defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)
266 typedef struct statvfs os_statvfs_t;
267 #endif
268 #endif
270 #if !defined(OS_USE_LARGEFILE64_SOURCE) && !defined(HAVE_STATVFS) && !defined(HAVE_FSTATVFS)
271 typedef struct {
272 unsigned f_bsize;
273 unsigned f_frsize;
274 uint64_t f_blocks;
275 uint64_t f_bfree;
276 uint64_t f_bavail;
277 uint64_t f_files;
278 uint64_t f_ffree;
279 uint64_t f_favail;
280 unsigned long f_fsid;
281 unsigned f_flag;
282 unsigned f_namemax;
283 } os_statvfs_t;
284 #endif
286 typedef time_t os_time_t;
287 typedef struct termios os_termios_t;
289 #if defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME)
290 typedef struct utsname os_utsname_t;
291 #else
292 typedef struct {
293 char sysname[65];
294 char release[65];
295 char version[65];
296 char machine[65];
297 } os_utsname_t;
298 #endif
300 typedef int handle_t;
301 #define handle_is_valid(h) ((h) >= 0)
302 #define handle_none -1
303 #define os_handle_to_number(h) ((uintptr_t)(h))
304 handle_t os_number_to_handle(uintptr_t n, bool sckt, ajla_error_t *err);
306 #ifndef NO_DIR_HANDLES
307 typedef int dir_handle_t;
308 #define dir_handle_is_valid(h) ((h) >= 0)
309 #define dir_none (-1)
310 #else
311 typedef char *dir_handle_t;
312 #define dir_handle_is_valid(h) ((h) != NULL)
313 #define dir_none NULL
314 #endif
316 #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MMAP)
317 #include <sys/mman.h>
318 #define OS_HAS_MMAP
319 int os_getpagesize(void);
320 void *os_mmap(void *ptr, size_t size, int prot, int flags, handle_t h, os_off_t off, ajla_error_t *err);
321 void os_munmap(void *ptr, size_t size, bool file);
322 bool os_mprotect(void *ptr, size_t size, int prot, ajla_error_t *err);
323 #ifndef MAP_FAILED
324 #define MAP_FAILED ((void *)-1)
325 #endif
326 #ifndef MAP_ANONYMOUS
327 #define MAP_ANONYMOUS MAP_ANON
328 #endif
329 #ifndef MAP_NORESERVE
330 #define MAP_NORESERVE 0
331 #endif
332 #if defined(__linux__) && defined(HAVE_MREMAP)
333 #define OS_HAS_MREMAP
334 void *os_mremap(void *old_ptr, size_t old_size, size_t new_size, int flags, void *new_ptr, ajla_error_t *err);
335 #endif
336 #endif
338 #if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T) && defined(HAVE_SIGFILLSET)
339 typedef sigset_t sig_state_t;
340 #define USE_SIGPROCMASK
341 #else
342 typedef int sig_state_t;
343 #endif
344 typedef sig_atomic_t signal_seq_t;
345 #ifdef HAVE_SIGACTION
346 #define OS_HAS_SIGNALS
347 #endif
349 #if defined(OS_HAS_SIGNALS) && defined(SA_SIGINFO) && defined(HAVE_UCONTEXT_H)
350 #define OS_SUPPORTS_TRAPS (!dll)
351 #else
352 #define OS_SUPPORTS_TRAPS 0
353 #endif
355 #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
356 #define OS_HAS_DLOPEN
357 struct dl_handle_t;
358 struct dl_handle_t *os_dlopen(const char *filename, ajla_error_t *err, char **err_msg);
359 void os_dlclose(struct dl_handle_t *dlh);
360 bool os_dlsym(struct dl_handle_t *dlh, const char *symbol, void **result);
361 #endif
363 #if defined(HAVE_GETADDRINFO) && (defined(HAVE_HAVE_GETNAMEINFO) || !defined(HAVE_GETHOSTBYADDR))
364 #define os_getaddrinfo_is_thread_safe() true
365 #else
366 #define os_getaddrinfo_is_thread_safe() false
367 #endif
369 #endif
372 uint32_t os_get_last_error(void);
373 uint32_t os_get_last_socket_error(void);
376 void os_code_invalidate_cache(uint8_t *code, size_t code_size, bool set_exec);
377 void *os_code_map(uint8_t *code, size_t code_size, ajla_error_t *err);
378 void os_code_unmap(void *mapped_code, size_t code_size);
381 static inline char os_path_separator(void)
383 #if defined(OS_DOS) || defined(OS_OS2) || defined(OS_WIN32)
384 return '\\';
385 #else
386 return '/';
387 #endif
390 static inline bool os_is_path_separator(char c)
392 #if defined(OS_DOS) || defined(OS_OS2) || defined(OS_WIN32) || defined(OS_CYGWIN)
393 if (c == '\\' || c == ':')
394 return true;
395 #endif
396 return c == '/';
399 static inline bool os_is_env_separator(char c)
401 #if defined(OS_DOS) || defined(OS_OS2) || defined(OS_WIN32)
402 return c == ';';
403 #endif
404 return c == ':';
407 bool os_path_is_absolute(const char *path);
410 extern dir_handle_t os_cwd;
411 bool os_set_cwd(dir_handle_t h, ajla_error_t *err);
412 void os_set_original_cwd(void);
415 void os_block_signals(sig_state_t *set);
416 void os_unblock_signals(const sig_state_t *set);
417 void os_stop(void);
418 void os_background(void);
419 bool os_foreground(void);
421 void os_set_cloexec(handle_t h);
422 handle_t os_open(dir_handle_t dir, const char *path, int flags, int mode, ajla_error_t *err);
423 bool os_pipe(handle_t result[2], int nonblock_flags, ajla_error_t *err);
424 void os_close_handle(handle_t h);
425 void os_close(handle_t h);
426 unsigned os_n_std_handles(void);
427 handle_t os_get_std_handle(unsigned p);
428 #define OS_RW_ERROR -1
429 #define OS_RW_WOULDBLOCK -2
430 ssize_t os_read(handle_t h, char *buffer, int size, ajla_error_t *err);
431 ssize_t os_write(handle_t h, const char *buffer, int size, ajla_error_t *err);
432 ssize_t os_pread(handle_t h, char *buffer, int size, os_off_t off, ajla_error_t *err);
433 ssize_t os_pwrite(handle_t h, const char *buffer, int size, os_off_t off, ajla_error_t *err);
434 bool os_lseek(handle_t, unsigned mode, os_off_t off, os_off_t *result, ajla_error_t *err);
435 bool os_ftruncate(handle_t h, os_off_t size, ajla_error_t *err);
436 bool os_fallocate(handle_t h, os_off_t position, os_off_t size, ajla_error_t *err);
437 bool os_clone_range(handle_t src_h, os_off_t src_pos, handle_t dst_h, os_off_t dst_pos, os_off_t len, ajla_error_t *err);
438 bool os_fsync(handle_t h, unsigned mode, ajla_error_t *err);
439 int os_charset(void);
440 int os_charset_console(void);
441 struct console_read_packet {
442 int32_t type;
443 union {
444 struct {
445 int32_t vkey;
446 int32_t key;
447 int32_t ctrl;
448 int32_t cp;
449 } k;
450 struct {
451 int32_t x, y;
452 int32_t prev_buttons, buttons;
453 int32_t wx, wy;
454 int32_t soft_cursor;
455 } m;
456 } u;
458 #define CONSOLE_PACKET_ENTRIES (sizeof(struct console_read_packet) / sizeof(int32_t))
459 ssize_t os_read_console_packet(handle_t h, struct console_read_packet *result, ajla_error_t *err);
460 struct console_write_packet {
461 int32_t type;
462 union {
463 struct {
464 int32_t x, y;
465 int32_t n_chars;
466 int32_t data[FLEXIBLE_ARRAY_GCC];
467 } c;
468 struct {
469 int32_t x, y;
470 int32_t end;
471 } p;
472 struct {
473 int32_t v;
474 int32_t end;
475 } v;
476 } u;
478 bool os_write_console_packet(handle_t h, struct console_write_packet *packet, ajla_error_t *err);
480 dir_handle_t os_dir_root(ajla_error_t *err);
481 dir_handle_t os_dir_cwd(ajla_error_t *err);
482 dir_handle_t os_dir_open(dir_handle_t dir, const char *path, int flags, ajla_error_t *err);
483 void os_dir_close(dir_handle_t h);
484 char *os_dir_path(dir_handle_t h, ajla_error_t *err);
486 bool os_dir_read(dir_handle_t h, char ***files, size_t *n_files, ajla_error_t *err);
487 void os_dir_free(char **files, size_t n_files);
489 unsigned os_dev_t_major(dev_t dev);
490 unsigned os_dev_t_minor(dev_t dev);
491 bool os_fstat(handle_t h, os_stat_t *st, ajla_error_t *err);
492 bool os_stat(dir_handle_t dir, const char *path, bool lnk, os_stat_t *st, ajla_error_t *err);
493 char *os_readlink(dir_handle_t dir, const char *path, ajla_error_t *err);
494 bool os_fstatvfs(handle_t h, os_statvfs_t *st, ajla_error_t *err);
495 bool os_dstatvfs(dir_handle_t dir, os_statvfs_t *st, ajla_error_t *err);
496 bool os_dir_action(dir_handle_t dir, const char *path, int action, int mode, ajla_time_t major, ajla_time_t minor, const char *syml, ajla_error_t *err);
497 bool os_dir2_action(dir_handle_t dir, const char *path, int action, dir_handle_t src_dir, const char *src_path, ajla_error_t *err);
498 bool os_drives(char **drives, size_t *drives_l, ajla_error_t *err);
500 bool os_tcgetattr(handle_t h, os_termios_t *t, ajla_error_t *err);
501 bool os_tcsetattr(handle_t h, const os_termios_t *t, ajla_error_t *err);
502 void os_tcflags(os_termios_t *t, int flags);
503 bool os_tty_size(handle_t h, int *nx, int *ny, int *ox, int *oy, ajla_error_t *err);
504 const char *os_get_path_to_exe(void);
506 ajla_time_t os_time_t_to_ajla_time(os_time_t sec);
507 #ifdef HAVE_STRUCT_TIMESPEC
508 ajla_time_t os_timespec_to_ajla_time(const struct timespec *ts);
509 #endif
510 ajla_time_t os_time_real(void);
511 ajla_time_t os_time_monotonic(void);
512 bool os_time_to_calendar(ajla_time_t t, bool local, int *year, int *month, int *day, int *hour, int *min, int *sec, int *usec, int *yday, int *wday, int *is_dst, ajla_error_t *err);
513 bool os_calendar_to_time(bool local, int year, int month, int day, int hour, int min, int sec, int usec, int is_dst, ajla_time_t *t, ajla_error_t *err);
515 const char *os_get_flavor(void);
516 void os_get_uname(os_utsname_t *un);
517 bool os_kernel_version(const char *sys, const char *vers);
518 char *os_get_host_name(ajla_error_t *err);
520 struct proc_handle;
522 struct proc_handle *os_proc_spawn(dir_handle_t wd, const char *path, size_t n_handles, handle_t *src, int *target, char * const args[], char *envc, ajla_error_t *err);
523 void os_proc_free_handle(struct proc_handle *ph);
524 bool os_proc_register_wait(struct proc_handle *ph, mutex_t **mutex_to_lock, struct list *list_entry, int *status);
525 void os_proc_check_all(void);
527 int os_signal_handle(const char *str, signal_seq_t *seq, ajla_error_t *err);
528 void os_signal_unhandle(int sig);
529 signal_seq_t os_signal_seq(int sig);
530 bool os_signal_wait(int sig, signal_seq_t seq, mutex_t **mutex_to_lock, struct list *list_entry);
531 void os_signal_check_all(void);
532 #if defined(OS_HAS_SIGNALS) && defined(SA_SIGINFO)
533 void os_signal_trap(int sig, void (*handler)(int, siginfo_t *, void *));
534 void os_signal_untrap(int sig);
535 #endif
537 handle_t os_socket(int domain, int type, int protocol, ajla_error_t *err);
538 bool os_bind_connect(bool bnd, handle_t h, unsigned char *addr, size_t addr_len, ajla_error_t *err);
539 bool os_connect_completed(handle_t h, ajla_error_t *err);
540 bool os_listen(handle_t h, ajla_error_t *err);
541 int os_accept(handle_t h, handle_t *result, ajla_error_t *err);
542 bool os_getsockpeername(bool peer, handle_t h, unsigned char **addr, size_t *addr_len, ajla_error_t *err);
543 struct address {
544 unsigned char *address;
545 size_t address_length;
546 struct tree_entry entry;
548 ssize_t os_recvfrom(handle_t h, char *buffer, size_t len, int flags, unsigned char **addr, size_t *addr_len, ajla_error_t *err);
549 ssize_t os_sendto(handle_t h, const char *buffer, size_t len, int flags, unsigned char *addr, size_t addr_len, ajla_error_t *err);
550 bool os_getsockopt(handle_t h, int level, int option, char **buffer, size_t *buffer_len, ajla_error_t *err);
551 bool os_setsockopt(handle_t h, int level, int option, const char *buffer, size_t buffer_len, ajla_error_t *err);
552 bool os_getaddrinfo(const char *host, int port, struct address **result, size_t *result_l, ajla_error_t *err);
553 char *os_getnameinfo(unsigned char *addr, size_t addr_len, ajla_error_t *err);
555 const char *os_decode_error(ajla_error_t error, char *(*tls_buffer)(void));
557 #if !defined(OS_DOS)
558 #define OS_HAVE_NOTIFY_PIPE
559 extern handle_t os_notify_pipe[2];
560 void os_notify(void);
561 bool os_drain_notify_pipe(void);
562 void os_shutdown_notify_pipe(void);
563 #else
564 static inline void os_notify(void) { }
565 static inline void os_shutdown_notify_pipe(void) { }
566 #endif
568 #if defined(OS_DOS)
569 bool dos_poll_devices(void);
570 void dos_yield(void);
571 void dos_wait_on_packet(mutex_t **mutex_to_lock, struct list *list_entry);
572 void dos_init(void);
573 void dos_done(void);
574 #endif
576 void os_init(void);
577 void os_init_multithreaded(void);
578 void os_done_multithreaded(void);
579 void os_done(void);
581 #endif