posix.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /*
  2. * This file is part of Jehanne.
  3. *
  4. * Copyright (C) 2017-2020 Giacomo Tesio <giacomo@tesio.it>
  5. *
  6. * This is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as
  8. * published by the Free Software Foundation, version 3 of the License.
  9. *
  10. * Jehanne is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * This API is designed to help porting other POSIX compliant C
  20. * libraries (such as newlib or musl) to Jehanne, so that they can be
  21. * used to port further software.
  22. *
  23. * POSIX_* functions provide a facade between the Jehanne's libc and
  24. * the POSIX 1-2008 semantics.
  25. *
  26. * libposix_* functions provide non-standard widely used functions
  27. * (eg. libposix_getdents) and configuration points.
  28. *
  29. * #include <u.h>
  30. * #include <posix.h>
  31. *
  32. * Defining _LIBPOSIX_H before the include allow you to just get
  33. * data structure definition.
  34. */
  35. #ifndef _LIBPOSIX_DEF
  36. #define _LIBPOSIX_DEF
  37. struct timespec
  38. {
  39. long tv_sec;
  40. long tv_nsec;
  41. };
  42. /* dirent alias of stat(5) message.
  43. * We (ab)use the fact that both 9P and Jehanne are little endian.
  44. * With the new file protocol this might change.
  45. */
  46. struct __attribute__((__packed__)) dirent
  47. {
  48. unsigned short d_reclen;
  49. unsigned short __pad1__; /* don't use */
  50. unsigned int __pad2__; /* don't use */
  51. unsigned char d_type;
  52. unsigned int d_version;
  53. unsigned long d_ino;
  54. unsigned int d_mode;
  55. unsigned int __pad3__; /* don't use */
  56. unsigned int __pad4__; /* don't use */
  57. unsigned long d_filesize;
  58. unsigned short d_namlen;
  59. char d_name[];
  60. };
  61. #define _DIRENT_HAVE_D_RECLEN
  62. #define _DIRENT_HAVE_D_TYPE
  63. #define _DIRENT_HAVE_D_VERSION
  64. #define _DIRENT_HAVE_D_MODE
  65. #define _DIRENT_HAVE_D_FILESIZE
  66. #define _DIRENT_HAVE_D_NAMLEN
  67. #undef _DIRENT_HAVE_D_OFF
  68. #define DT_UNKNOWN 0
  69. #define DT_FIFO 1
  70. #define DT_CHR 2
  71. #define DT_DIR 4
  72. #define DT_BLK 6
  73. #define DT_REG 8
  74. #define DT_LNK 10
  75. #define DT_SOCK 12
  76. #define DT_WHT 14
  77. /* getrusage who */
  78. typedef enum PosixRUsages
  79. {
  80. PosixRUsageSelf = 0,
  81. PosixRUsageChildren = 1,
  82. PosixRUsageUnknown = -1
  83. } PosixRUsages;
  84. /* errno values */
  85. #define _APW_ERRNO_H // skip the POSIX part, we just need the enum
  86. #include <apw/errno.h>
  87. #undef _APW_ERRNO_H
  88. /* signals */
  89. typedef unsigned long PosixSignalMask;
  90. typedef enum PosixSigProcMaskAction
  91. {
  92. PosixSPMSetMask = 0,
  93. PosixSPMBlock = 1,
  94. PosixSPMUnblock = 2
  95. } PosixSigProcMaskAction;
  96. #define PosixNumberOfSignals (sizeof(PosixSignalMask)*7)
  97. typedef enum PosixSignals
  98. {
  99. PosixSIGABRT = 1,
  100. PosixSIGALRM,
  101. PosixSIGBUS,
  102. PosixSIGCHLD,
  103. PosixSIGCONT,
  104. PosixSIGFPE,
  105. PosixSIGHUP,
  106. PosixSIGILL,
  107. PosixSIGINT,
  108. PosixSIGKILL,
  109. PosixSIGPIPE,
  110. PosixSIGQUIT,
  111. PosixSIGSEGV,
  112. PosixSIGSTOP,
  113. PosixSIGTERM,
  114. PosixSIGTSTP,
  115. PosixSIGTTIN,
  116. PosixSIGTTOU,
  117. PosixSIGUSR1,
  118. PosixSIGUSR2,
  119. PosixSIGPOLL,
  120. PosixSIGPROF,
  121. PosixSIGSYS,
  122. PosixSIGTRAP,
  123. PosixSIGURG,
  124. PosixSIGVTALRM,
  125. PosixSIGXCPU,
  126. PosixSIGXFSZ,
  127. /* Optional Signals */
  128. PosixSIGIOT,
  129. PosixSIGEMT,
  130. PosixSIGSTKFLT,
  131. PosixSIGIO,
  132. PosixSIGPWR,
  133. PosixSIGINFO,
  134. PosixSIGLOST,
  135. PosixSIGWINCH,
  136. PosixSIGUNUSED,
  137. PosixSIGRTMIN,
  138. PosixSIGRTMAX = PosixNumberOfSignals
  139. } PosixSignals;
  140. typedef enum PosixSigActionFlags
  141. {
  142. /* supported flags */
  143. PosixSAFSigInfo = 1<<0,
  144. PosixSAFRestart = 1<<1,
  145. PosixSAFNoChildrenStop = 1<<2,
  146. PosixSAFResetHandler = 1<<3,
  147. PosixSAFNoChildrenWait = 1<<4,
  148. /* ignored flags */
  149. PosixSAFNoDefer = 1<<16, /* notes are not reentrant */
  150. PosixSAFOnStack = 1<<17,
  151. PosixSAFDisable = 1<<18
  152. } PosixSigActionFlags;
  153. typedef enum PosixSigInfoCodes
  154. {
  155. PosixSIUser = 1,
  156. PosixSIQueue,
  157. PosixSITimer,
  158. PosixSIAsyncIO,
  159. PosixSIMsgQueued,
  160. PosixSIFaultMapError,
  161. PosixSIFaultAccessError,
  162. PosixSIChildExited,
  163. PosixSIChildKilled,
  164. PosixSIChildDumped,
  165. PosixSIChildTrapped,
  166. PosixSIChildStopped,
  167. PosixSIChildContinued
  168. } PosixSigInfoCodes;
  169. union sigval {
  170. int sival_int; /* Integer signal value */
  171. void* sival_ptr; /* Pointer signal value */
  172. void* _si_addr; /* Address of faulting address */
  173. int _si_status; /* Child exit status */
  174. uintptr_t _sival_raw; /* Raw value */
  175. };
  176. struct sigevent {
  177. int sigev_notify; /* Notification type */
  178. int sigev_signo; /* Signal number */
  179. union sigval sigev_value; /* Signal value */
  180. void (*sigev_notify_function)( union sigval );
  181. /* Notification function */
  182. long *sigev_notify_attributes; /* Notification Attributes */
  183. };
  184. typedef struct {
  185. int si_signo; /* Signal number */
  186. int si_code; /* Cause of the signal */
  187. int si_errno;
  188. int si_pid; /* Pid of sender */
  189. int si_uid; /* Uid of sender */
  190. union sigval si_value; /* Signal value */
  191. } PosixSignalInfo;
  192. #define si_addr si_value._si_addr
  193. #define si_status si_value._si_status
  194. typedef void (*PosixSigHandler)(int);
  195. typedef void (*PosixSigAction)(int, PosixSignalInfo *, void * );
  196. struct sigaction {
  197. int sa_flags; /* Special flags to affect behavior of signal */
  198. PosixSignalMask sa_mask; /* Additional set of signals to be blocked */
  199. /* during execution of signal-catching */
  200. /* function. */
  201. union {
  202. PosixSigHandler _handler; /* SIG_DFL, SIG_IGN, or pointer to a function */
  203. PosixSigAction _sigaction;
  204. } _signal_handlers;
  205. };
  206. #define sa_handler _signal_handlers._handler
  207. #define sa_sigaction _signal_handlers._sigaction
  208. typedef enum PosixFDCmds
  209. {
  210. PosixFDCDupFD = 1,
  211. PosixFDCDupFDCloseOnExec,
  212. PosixFDCGetFD,
  213. PosixFDCSetFD,
  214. PosixFDCGetFL,
  215. PosixFDCSetFL
  216. } PosixFDCmds;
  217. /* https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html
  218. */
  219. typedef enum PosixSysConfNames
  220. {
  221. /* Posix 1 */
  222. PosixSCNArgMax = 1, // _SC_ARG_MAX
  223. PosixSCNChildMax, // _SC_CHILD_MAX
  224. PosixSCNHostNameMax, // _SC_HOST_NAME_MAX
  225. PosixSCNLoginNameMax, // _SC_LOGIN_NAME_MAX
  226. PosixSCNClockTicks, // _SC_CLK_TCK
  227. PosixSCNOpenMax, // _SC_OPEN_MAX
  228. PosixSCNPageSize, // _SC_PAGESIZE
  229. PosixSCNPosixVersion, // _SC_VERSION
  230. /* Posix 2 */
  231. PosixSCNLineMax // _SC_LINE_MAX
  232. } PosixSysConfNames;
  233. #endif /* _LIBPOSIX_DEF */
  234. #ifndef _LIBPOSIX_H
  235. #define _LIBPOSIX_H
  236. typedef unsigned long clock_t;
  237. #define __POSIX_EXIT_PREFIX "posix error "
  238. #define __POSIX_EXIT_SIGNAL_PREFIX "terminated by posix signal "
  239. #define __POSIX_SIGNAL_PREFIX "posix: "
  240. extern unsigned int POSIX_alarm(int *errnop, unsigned int seconds);
  241. extern int POSIX_access(int *errnop, const char *path, int amode);
  242. extern int POSIX_dup(int *errnop, int fildes);
  243. extern int POSIX_dup2(int *errnop, int fildes, int fildes2);
  244. extern void POSIX_exit(int code) __attribute__((noreturn));
  245. extern int POSIX_chmod(int *errnop, const char *path, int mode);
  246. extern int POSIX_fchmodat(int *errnop, int fd, const char *path, long mode, int flag);
  247. extern int POSIX_chown(int *errnop, const char *pathname, int owner, int group);
  248. extern int POSIX_fchownat(int *errnop, int fd, const char *path, int owner, int group, int flag);
  249. extern int POSIX_lchown(int *errnop, const char *path, int owner, int group);
  250. extern int POSIX_chdir(int *errnop, const char *path);
  251. extern int POSIX_fchdir(int *errnop, int fd);
  252. extern int POSIX_mkdir(int *errnop, const char *path, int mode);
  253. extern int POSIX_close(int *errnop, int file);
  254. extern int POSIX_execve(int *errnop, const char *name, char * const*argv, char * const*env);
  255. extern int POSIX_fork(int *errnop);
  256. extern int POSIX_getrusage(int *errnop, PosixRUsages who, void *r_usage);
  257. extern char* POSIX_getcwd(int *errnop, char *buf, int size);
  258. extern char* POSIX_getlogin(int *errnop);
  259. extern int POSIX_getlogin_r(int *errnop, char *name, int namesize);
  260. extern char* POSIX_getpass(int *errnop, const char *prompt);
  261. extern int POSIX_getpid(int *errnop);
  262. extern int POSIX_getppid(int *errnop);
  263. extern int POSIX_isatty(int *errnop, int file);
  264. extern int POSIX_kill(int *errnop, int pid, int sig);
  265. extern int POSIX_link(int *errnop, const char *existingPath, const char *newPath);
  266. extern off_t POSIX_lseek(int *errnop, int fd, off_t pos, int whence);
  267. extern int POSIX_open(int *errnop, const char *name, int flags, int mode);
  268. extern long POSIX_pread(int *errnop, int fd, char *buf, size_t len, long offset);
  269. extern long POSIX_pwrite(int *errnop, int fd, const char *buf, size_t len, long offset);
  270. extern long POSIX_read(int *errnop, int fd, char *buf, size_t len);
  271. extern int POSIX_stat(int *errnop, const char *file, void *stat);
  272. extern int POSIX_fstat(int *errnop, int file, void *stat);
  273. extern int POSIX_lstat(int *errnop, const char *file, void *stat);
  274. extern clock_t POSIX_times(int *errnop, void *tms);
  275. extern int POSIX_unlink(int *errnop, const char *name);
  276. extern int POSIX_wait(int *errnop, int *status);
  277. extern int POSIX_waitpid(int *errnop, int pid, int *status, int options);
  278. extern long POSIX_write(int *errnop, int fd, const void *buf, size_t len);
  279. extern int POSIX_gettimeofday(int *errnop, void *timeval, void *timezone);
  280. extern char* POSIX_getenv(int *errnop, const char *name);
  281. extern int POSIX_setenv(int *errnop, const char *name, const char *value, int overwrite);
  282. extern int POSIX_unsetenv(int *errnop, const char *name);
  283. extern void *POSIX_sbrk(int *errnop, ptrdiff_t incr);
  284. extern void * POSIX_malloc(int *errnop, size_t size);
  285. extern void *POSIX_realloc(int *errnop, void *ptr, size_t size);
  286. extern void *POSIX_calloc(int *errnop, size_t nelem, size_t size);
  287. extern void POSIX_free(void *ptr);
  288. extern unsigned int POSIX_sleep(unsigned int seconds);
  289. extern int POSIX_pipe(int *errnop, int fildes[2]);
  290. extern int POSIX_umask(int *errnop, int mask);
  291. extern int POSIX_fcntl(int *errnop, int fd, PosixFDCmds cmd, uintptr_t arg);
  292. extern long POSIX_sysconf(int *errnop, PosixSysConfNames name);
  293. extern int POSIX_rmdir(int *errnop, const char *name);
  294. extern int POSIX_sigaddset(int *errnop, PosixSignalMask *set, int signo);
  295. extern int POSIX_sigdelset(int *errnop, PosixSignalMask *set, int signo);
  296. extern int POSIX_sigismember(int *errnop, const PosixSignalMask *set, int signo);
  297. extern int POSIX_sigfillset(int *errnop, PosixSignalMask *set);
  298. extern int POSIX_sigemptyset(int *errnop, PosixSignalMask *set);
  299. extern int POSIX_sigprocmask(int *errnop, PosixSigProcMaskAction how, const PosixSignalMask *set, PosixSignalMask *oset);
  300. extern int POSIX_sigpending(int *errnop, PosixSignalMask *set);
  301. extern int POSIX_sigsuspend(int *errnop, const PosixSignalMask *mask);
  302. extern int POSIX_sigaction(int *errnop, int signo, const struct sigaction *act, struct sigaction *old);
  303. extern int POSIX_sigtimedwait(int *errnop, const PosixSignalMask *set, PosixSignalInfo *info, const struct timespec *timeout);
  304. extern int POSIX_sigqueue(int *errnop, int pid, int signo, const union sigval value);
  305. extern int POSIX_getuid(int *errnop);
  306. extern int POSIX_geteuid(int *errnop);
  307. extern int POSIX_setuid(int *errnop, int uid);
  308. extern int POSIX_seteuid(int *errnop, int euid);
  309. extern int POSIX_setreuid(int *errnop, int ruid, int euid);
  310. extern int POSIX_getgid(int *errnop);
  311. extern int POSIX_getegid(int *errnop);
  312. extern int POSIX_setgid(int *errnop, int gid);
  313. extern int POSIX_setegid(int *errnop, int egid);
  314. extern int POSIX_setregid(int *errnop, int rgid, int egid);
  315. extern int POSIX_getpgrp(int *errnop);
  316. extern int POSIX_getpgid(int *errnop, int pid);
  317. extern int POSIX_setpgid(int *errnop, int pid, int pgid);
  318. extern int POSIX_getsid(int *errnop, int pid);
  319. extern int POSIX_setsid(int *errnop);
  320. extern int POSIX_tcgetpgrp(int *errnop, int fd);
  321. extern int POSIX_tcsetpgrp(int *errnop, int fd, int pgrp);
  322. extern int libposix_getdents(int *errnop, int fd, char *buf, int buf_bytes);
  323. extern PosixError libposix_translate_kernel_errors(const char *msg);
  324. /* Library initialization
  325. */
  326. /* Initialize libposix. Should call
  327. *
  328. * libposix_define_errno to set the value of each PosixError
  329. * libposix_define_at_fdcwd to set the value of AT_FDCWD (for fchmodat)
  330. * libposix_translate_error to translate error strings to PosixError
  331. * libposix_set_stat_reader
  332. * libposix_set_tms_reader
  333. * libposix_set_timeval_reader
  334. * libposix_set_timezone_reader
  335. */
  336. typedef void (*PosixInit)(int argc, char *argv[]);
  337. extern void libposix_init(int argc, char *argv[], PosixInit init) __attribute__((noreturn));
  338. /* Translate an error string to a PosixError, in the context of the
  339. * calling function (typically a pointer to a POSIX_* function).
  340. *
  341. * Must return 0 if unable to identify a PosixError.
  342. *
  343. * Translators are tried in reverse registration order.
  344. */
  345. typedef PosixError (*PosixErrorTranslator)(char* error, uintptr_t caller);
  346. /* Register a translation between Jehanne error strings and PosixErrors.
  347. * If caller is not zero, it is a pointer to the calling
  348. * functions to consider. Otherwise the translation will be tried whenever
  349. * for any caller, after the specialized ones.
  350. */
  351. extern int libposix_translate_error(PosixErrorTranslator translation, uintptr_t caller);
  352. /* define the value of AT_FDCWD according to the library headers */
  353. extern int libposix_define_at_fdcwd(int AT_FDCWD);
  354. /* define the value of O_NONBLOCK according to the library headers */
  355. extern int libposix_define_ononblock(int O_NONBLOCK);
  356. /* define the value of a specific PosixError according to the library headers */
  357. extern int libposix_define_errno(PosixError e, int errno);
  358. /* Map a Dir to the stat structure expected by the library.
  359. *
  360. * Must return 0 on success or a PosixError on failure.
  361. */
  362. typedef PosixError (*PosixStatReader)(void *statp, const Dir *dir);
  363. extern int libposix_set_stat_reader(PosixStatReader reader);
  364. /* Map a time provided by times() tms structure
  365. * expected by the library.
  366. *
  367. * Must return 0 on success or a PosixError on failure.
  368. */
  369. typedef PosixError (*PosixTMSReader)(void *tms,
  370. unsigned int proc_userms, unsigned int proc_sysms,
  371. unsigned int children_userms, unsigned int children_sysms);
  372. extern int libposix_set_tms_reader(PosixTMSReader reader);
  373. /* Map a time provided by gmtime() or localtime() to a timeval
  374. * expected by the library.
  375. *
  376. * Must return 0 on success or a PosixError on failure.
  377. */
  378. typedef PosixError (*PosixTimevalReader)(void *timeval, const Tm *time);
  379. extern int libposix_set_timeval_reader(PosixTimevalReader reader);
  380. /* Map a time provided by gmtime() or localtime() to a timezone
  381. * expected by the library.
  382. *
  383. * Must return 0 on success or a PosixError on failure.
  384. */
  385. typedef PosixError (*PosixTimezoneReader)(void *timezone, const Tm *time);
  386. extern int libposix_set_timezone_reader(PosixTimezoneReader reader);
  387. /* Map the POSIX_open flag and mode to Jehanne's arguments to open
  388. * or create. It's also used in chmod to translate mode.
  389. *
  390. * omode is a pointer to the open/create omode argument
  391. * cperm is a pointer to the create perm argument that must be filled
  392. * only if omode is nil or O_CREATE has been set in mode.
  393. *
  394. * Must return 0 on success or a PosixError on failure.
  395. *
  396. * In flag:
  397. * - O_CLOEXEC must be mapped to OCEXEC in omode
  398. * - O_TRUNC must be mapped to OTRUNC in omode
  399. * - O_APPEND|O_CREAT must be mapped to DMAPPEND in cperm
  400. * - O_APPEND without O_CREAT must return PosixENOTSUP
  401. * - O_EXCL|O_CREAT must be mapped to DMEXCL in cperm
  402. * - O_EXCL without O_CREAT it must return PosixENOTSUP
  403. * - O_SEARCH must be mapped to OEXEC|DMDIR in omode
  404. * - O_DIRECTORY|O_CREAT must return PosixEINVAL
  405. * - O_DIRECTORY without O_CREAT must be mapped to DMDIR in omode
  406. * - O_DSYNC, O_NOCTTY, O_NOFOLLOW, O_NONBLOCK, O_RSYNC, O_SYNC
  407. * and O_TTY_INIT must be ignored
  408. * - S_ISUID, S_ISGID, S_ISVTX must be ignored
  409. */
  410. typedef PosixError (*PosixOpenTranslator)(int flag, int mode, long *omode, long *cperm);
  411. extern int libposix_translate_open(PosixOpenTranslator translation);
  412. extern int libposix_translate_seek_whence(int seek_set, int seek_cur, int seek_end);
  413. extern int libposix_translate_access_mode(int f_ok, int r_ok, int w_ok, int x_ok);
  414. /* Map the main exit status received by POSIX_exit to the exit status
  415. * string for Jehanne.
  416. *
  417. * Must return nil if unable to translate the status, so that the
  418. * default translation strategy will be adopted.
  419. */
  420. typedef char* (*PosixExitStatusTranslator)(int status);
  421. extern int libposix_translate_exit_status(PosixExitStatusTranslator translator);
  422. /* Execute process disposition (executed when main returns)
  423. */
  424. typedef void (*PosixProcessDisposer)(int status);
  425. extern int libposix_on_process_disposition(PosixProcessDisposer dispose);
  426. /* Enable SIGCHLD emulation
  427. */
  428. extern int libposix_emulate_SIGCHLD(void);
  429. /* Define of WCONTINUED, WNOHANG and WUNTRACED bit flags.
  430. *
  431. * Note that WCONTINUED and WUNTRACED are not yet supported by libposix
  432. * and thus defining them cause an error.
  433. */
  434. int libposix_set_wait_options(int wcontinued, int wnohang, int wuntraced);
  435. #endif /* _LIBPOSIX_H */