signal.odin 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131
  1. package posix
  2. import "base:intrinsics"
  3. import "core:c"
  4. import "core:c/libc"
  5. when ODIN_OS == .Darwin {
  6. foreign import lib "system:System.framework"
  7. } else {
  8. foreign import lib "system:c"
  9. }
  10. // signal.h - signals
  11. foreign lib {
  12. // LIBC:
  13. /*
  14. Set a signal handler.
  15. func can either be:
  16. - `auto_cast posix.SIG_DFL` setting the default handler for that specific signal
  17. - `auto_cast posix.SIG_IGN` causing the specific signal to be ignored
  18. - a custom signal handler
  19. Returns: SIG_ERR (setting errno), the last value of func on success
  20. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html ]]
  21. */
  22. signal :: proc(sig: Signal, func: proc "c" (Signal)) -> proc "c" (Signal) ---
  23. /*
  24. Raises a signal, calling its handler and then returning.
  25. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html ]]
  26. */
  27. raise :: proc(sig: Signal) -> result ---
  28. // POSIX:
  29. /*
  30. Raise a signal to the process/group specified by pid.
  31. If sig is 0, this function can be used to check if the pid is just checked for validity.
  32. If pid is -1, the signal is sent to all processes that the current process has permission to send.
  33. If pid is negative (not -1), the signal is sent to all processes in the group identifier by the
  34. absolute value.
  35. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html ]]
  36. */
  37. kill :: proc(pid: pid_t, sig: Signal) -> result ---
  38. /*
  39. Shorthand for `kill(-pgrp, sig)` which will kill all processes in the given process group.
  40. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/killpg.html ]]
  41. */
  42. killpg :: proc(pgrp: pid_t, sig: Signal) -> result ---
  43. /*
  44. Writes a language-dependent message to stderror.
  45. Example:
  46. posix.psignal(.SIGSEGV, "that didn't go well")
  47. Possible Output:
  48. that didn't go well: Segmentation fault
  49. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/psignal.html ]]
  50. */
  51. psignal :: proc(signum: Signal, message: cstring) ---
  52. /*
  53. Send a signal to a thread.
  54. As with kill, if sig is 0, only validation (of the pthread_t given) is done and no signal is sent.
  55. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html ]]
  56. */
  57. pthread_kill :: proc(thread: pthread_t, sig: Signal) -> Errno ---
  58. /*
  59. Examine and change blocked signals.
  60. Equivalent to sigprocmask(), without the restriction that the call be made in a single-threaded process.
  61. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html ]]
  62. */
  63. pthread_sigmask :: proc(how: Sig, set: ^sigset_t, oset: ^sigset_t) -> Errno ---
  64. /*
  65. Examine and change blocked signals in a single-threaded process.
  66. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html ]]
  67. */
  68. @(link_name=LSIGPROCMASK)
  69. sigprocmask :: proc(how: Sig, set: ^sigset_t, oldset: ^sigset_t) -> result ---
  70. /*
  71. Examine and change a signal action.
  72. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html ]]
  73. */
  74. @(link_name=LSIGACTION)
  75. sigaction :: proc(sig: Signal, act: ^sigaction_t, oact: ^sigaction_t) -> result ---
  76. @(link_name=LSIGADDSET)
  77. sigaddset :: proc(set: ^sigset_t, signo: Signal) -> result ---
  78. @(link_name=LSIGDELSET)
  79. sigdelset :: proc(^sigset_t, Signal) -> c.int ---
  80. @(link_name=LSIGEMPTYSET)
  81. sigemptyset :: proc(^sigset_t) -> c.int ---
  82. @(link_name=LSIGFILLSET)
  83. sigfillset :: proc(^sigset_t) -> c.int ---
  84. /*
  85. Set and get the signal alternate stack context.
  86. Example:
  87. sigstk := posix.stack_t {
  88. ss_sp = make([^]byte, posix.SIGSTKSZ) or_else panic("allocation failure"),
  89. ss_size = posix.SIGSTKSZ,
  90. ss_flags = {},
  91. }
  92. if posix.sigaltstack(&sigstk, nil) != .OK {
  93. fmt.panicf("sigaltstack failure: %v", posix.strerror(posix.errno()))
  94. }
  95. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaltstack.html ]]
  96. */
  97. @(link_name=LSIGALTSTACK)
  98. sigaltstack :: proc(ss: ^stack_t, oss: ^stack_t) -> result ---
  99. /*
  100. Adds sig to the signal mask of the calling process.
  101. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sighold.html ]]
  102. */
  103. sighold :: proc(sig: Signal) -> result ---
  104. /*
  105. Sets the disposition of sig to SIG_IGN.
  106. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sighold.html ]]
  107. */
  108. sigignore :: proc(sig: Signal) -> result ---
  109. /*
  110. Removes sig from the signal mask of the calling process and suspend the calling process until
  111. a signal is received.
  112. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sighold.html ]]
  113. */
  114. sigpause :: proc(sig: Signal) -> result ---
  115. /*
  116. Removes sig from the signal mask of the calling process.
  117. Returns: always -1.
  118. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sighold.html ]]
  119. */
  120. sigrelse :: proc(sig: Signal) -> result ---
  121. /*
  122. Changes the restart behavior when a function is interrupted by the specified signal.
  123. If flag is true, SA_RESTART is removed, added otherwise.
  124. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/siginterrupt.html ]]
  125. */
  126. siginterrupt :: proc(sig: Signal, flag: b32) -> result ---
  127. /*
  128. Test for a signal in a signal set.
  129. Returns: 1 if it is a member, 0 if not, -1 (setting errno) on failure
  130. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigismember.html ]]
  131. */
  132. @(link_name=LSIGISMEMBER)
  133. sigismember :: proc(set: ^sigset_t, signo: Signal) -> c.int ---
  134. /*
  135. Stores the set of signals that are blocked from delivery to the calling thread and that are pending
  136. on the process or the calling thread.
  137. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigpending.html ]]
  138. */
  139. @(link_name=LSIGPENDING)
  140. sigpending :: proc(set: ^sigset_t) -> result ---
  141. /*
  142. Wait for one of the given signals.
  143. Returns: always -1
  144. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html ]]
  145. */
  146. @(link_name=LSIGSUSPEND)
  147. sigsuspend :: proc(sigmask: ^sigset_t) -> result ---
  148. /*
  149. Wait for queued signals.
  150. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigwait.html ]]
  151. */
  152. sigwait :: proc(set: ^sigset_t, sig: ^Signal) -> Errno ---
  153. /* NOTE: unimplemented on darwin.
  154. void psiginfo(const siginfo_t *, const char *);
  155. int sigqueue(pid_t, int, union sigval);
  156. void (*sigset(int, void (*)(int)))(int);
  157. int sigsuspend(const sigset_t *);
  158. int sigtimedwait(const sigset_t *restrict, siginfo_t *restrict,
  159. const struct timespec *restrict);
  160. int sigwaitinfo(const sigset_t *restrict, siginfo_t *restrict);
  161. */
  162. }
  163. sigval :: struct #raw_union {
  164. sigval_int: c.int, /* [PSX] integer signal value */
  165. sigval_ptr: rawptr, /* [PSX] pointer signal value */
  166. }
  167. Signal :: enum c.int {
  168. NONE,
  169. // LIBC:
  170. // Process abort signal.
  171. SIGABRT = SIGABRT,
  172. // Erronous arithemtic operation.
  173. SIGFPE = SIGFPE,
  174. // Illegal instruction.
  175. SIGILL = SIGILL,
  176. // Terminal interrupt signal.
  177. SIGINT = SIGINT,
  178. // Invalid memory reference.
  179. SIGSEGV = SIGSEGV,
  180. // Termination signal.
  181. SIGTERM = SIGTERM,
  182. // POSIX:
  183. // Process abort signal.
  184. SIGALRM = SIGALRM,
  185. // Access to an undefined portion of a memory object.
  186. SIGBUS = SIGBUS,
  187. // Child process terminated, stopped, or continued.
  188. SIGCHLD = SIGCHLD,
  189. // Continue execution, if stopped.
  190. SIGCONT = SIGCONT,
  191. // Hangup.
  192. SIGHUP = SIGHUP,
  193. // Kill (cannot be caught or ignored).
  194. SIGKILL = SIGKILL,
  195. // Write on a pipe with no one to read it.
  196. SIGPIPE = SIGPIPE,
  197. // Terminal quit signal.
  198. SIGQUIT = SIGQUIT,
  199. // Stop executing (cannot be caught or ignored).
  200. SIGSTOP = SIGSTOP,
  201. // Terminal stop process.
  202. SIGTSTP = SIGTSTP,
  203. // Background process attempting read.
  204. SIGTTIN = SIGTTIN,
  205. // Background process attempting write.
  206. SIGTTOU = SIGTTOU,
  207. // User-defined signal 1.
  208. SIGUSR1 = SIGUSR1,
  209. // User-defined signal 2.
  210. SIGUSR2 = SIGUSR2,
  211. // Pollable event.
  212. SIGPOLL = SIGPOLL,
  213. // Profiling timer expired.
  214. SIGPROF = SIGPROF,
  215. // Bad system call.
  216. SIGSYS = SIGSYS,
  217. // Trace/breakpoint trap.
  218. SIGTRAP = SIGTRAP,
  219. // High bandwidth data is available at a socket.
  220. SIGURG = SIGURG,
  221. // Virtual timer expired.
  222. SIGVTALRM = SIGVTALRM,
  223. // CPU time limit exceeded.
  224. SIGXCPU = SIGXCPU,
  225. // File size limit exceeded.
  226. SIGXFSZ = SIGXFSZ,
  227. }
  228. ILL_Code :: enum c.int {
  229. // Illegal opcode.
  230. ILLOPC = ILL_ILLOPC,
  231. // Illegal operand.
  232. ILLOPN = ILL_ILLOPN,
  233. // Illegal addressing mode.
  234. ILLADR = ILL_ILLADR,
  235. // Illegal trap.
  236. ILLTRP = ILL_ILLTRP,
  237. // Priviledged opcode.
  238. PRVOPC = ILL_PRVOPC,
  239. // Priviledged register.
  240. PRVREG = ILL_PRVREG,
  241. // Coprocessor error.
  242. COPROC = ILL_COPROC,
  243. // Internal stack error.
  244. BADSTK = ILL_BADSTK,
  245. }
  246. FPE_Code :: enum c.int {
  247. // Integer divide by zero.
  248. INTDIV = FPE_INTDIV,
  249. // Integer overflow.
  250. INTOVF = FPE_INTOVF,
  251. // Floating-point divide by zero.
  252. FLTDIV = FPE_FLTDIV,
  253. // Floating-point overflow.
  254. FLTOVF = FPE_FLTOVF,
  255. // Floating-point underflow.
  256. FLTUND = FPE_FLTUND,
  257. // Floating-point inexact result.
  258. FLTRES = FPE_FLTRES,
  259. // Invalid floating-point operation.
  260. FLTINV = FPE_FLTINV,
  261. // Subscript out of range.
  262. FLTSUB = FPE_FLTSUB,
  263. }
  264. SEGV_Code :: enum c.int {
  265. // Address not mapped to object.
  266. MAPERR = SEGV_MAPERR,
  267. // Invalid permissions for mapped object.
  268. ACCERR = SEGV_ACCERR,
  269. }
  270. BUS_Code :: enum c.int {
  271. // Invalid address alignment.
  272. ADRALN = BUS_ADRALN,
  273. // Nonexistent physical address.
  274. ADRERR = BUS_ADRERR,
  275. // Object-specific hardware error.
  276. OBJERR = BUS_OBJERR,
  277. }
  278. TRAP_Code :: enum c.int {
  279. // Process breakpoint.
  280. BRKPT = TRAP_BRKPT,
  281. // Process trace trap.
  282. TRACE = TRAP_TRACE,
  283. }
  284. CLD_Code :: enum c.int {
  285. // Child has exited..
  286. EXITED = CLD_EXITED,
  287. // Child has terminated abnormally and did not create a core file.
  288. KILLED = CLD_KILLED,
  289. // Child has terminated abnormally and created a core file.
  290. DUMPED = CLD_DUMPED,
  291. // Traced child trapped.
  292. TRAPPED = CLD_TRAPPED,
  293. // Child has stopped.
  294. STOPPED = CLD_STOPPED,
  295. // Stopped child has continued.
  296. CONTINUED = CLD_CONTINUED,
  297. }
  298. POLL_Code :: enum c.int {
  299. // Data input is available.
  300. IN = POLL_IN,
  301. // Output buffers available.
  302. OUT = POLL_OUT,
  303. // Input message available.
  304. MSG = POLL_MSG,
  305. // I/O error.
  306. ERR = POLL_ERR,
  307. // High priority input available.
  308. PRI = POLL_PRI,
  309. // Device disconnected.
  310. HUP = POLL_HUP,
  311. }
  312. Any_Code :: enum c.int {
  313. // Signal sent by kill().
  314. USER = SI_USER,
  315. // Signal sent by sigqueue().
  316. QUEUE = SI_QUEUE,
  317. // Signal generated by expiration of a timer set by timer_settime().
  318. TIMER = SI_TIMER,
  319. // Signal generated by completion of an asynchronous I/O request.
  320. ASYNCIO = SI_ASYNCIO,
  321. // Signal generated by arrival of a message on an empty message queue.
  322. MESGQ = SI_MESGQ,
  323. }
  324. SA_Flags_Bits :: enum c.int {
  325. // Do not generate SIGCHLD when children stop or stopped children continue.
  326. NOCLDSTOP = log2(SA_NOCLDSTOP),
  327. // Cause signal delivery to occur on an alternate stack.
  328. ONSTACK = log2(SA_ONSTACK),
  329. // Cause signal disposition to be set to SIG_DFL on entry to signal handlers.
  330. RESETHAND = log2(SA_RESETHAND),
  331. // Cause certain functions to become restartable.
  332. RESTART = log2(SA_RESTART),
  333. // Cause extra information to be passed to signal handlers at the time of receipt of a signal.
  334. SIGINFO = log2(SA_SIGINFO),
  335. // Cause implementation not to create zombie processes or status information on child termination.
  336. NOCLDWAIT = log2(SA_NOCLDWAIT),
  337. // Cause signal not to be automatically blocked on entry to signal handler.
  338. SA_NODEFER = log2(SA_NODEFER),
  339. }
  340. SA_Flags :: bit_set[SA_Flags_Bits; c.int]
  341. SS_Flag_Bits :: enum c.int {
  342. // Process is executing on an alternate signal stack.
  343. ONSTACK = log2(SS_ONSTACK),
  344. // Alternate signal stack is disabled.
  345. DISABLE = log2(SS_DISABLE),
  346. }
  347. SS_Flags :: bit_set[SS_Flag_Bits; c.int]
  348. Sig :: enum c.int {
  349. // Resulting set is the union of the current set and the signal set and the complement of
  350. // the signal set pointed to by the argument.
  351. BLOCK = SIG_BLOCK,
  352. // Resulting set is the intersection of the current set and the complement of the signal set
  353. // pointed to by the argument.
  354. UNBLOCK = SIG_UNBLOCK,
  355. // Resulting set is the signal set pointed to by the argument.
  356. SETMASK = SIG_SETMASK,
  357. }
  358. // Request for default signal handling.
  359. SIG_DFL :: libc.SIG_DFL
  360. // Return value from signal() in case of error.
  361. SIG_ERR :: libc.SIG_ERR
  362. // Request that signal be ignored.
  363. SIG_IGN :: libc.SIG_IGN
  364. SIGABRT :: libc.SIGABRT
  365. SIGFPE :: libc.SIGFPE
  366. SIGILL :: libc.SIGILL
  367. SIGINT :: libc.SIGINT
  368. SIGSEGV :: libc.SIGSEGV
  369. SIGTERM :: libc.SIGTERM
  370. when ODIN_OS == .NetBSD {
  371. @(private) LSIGPROCMASK :: "__sigprocmask14"
  372. @(private) LSIGACTION :: "__sigaction_siginfo"
  373. @(private) LSIGADDSET :: "__sigaddset14"
  374. @(private) LSIGDELSET :: "__sigdelset14"
  375. @(private) LSIGEMPTYSET :: "__sigemptyset14"
  376. @(private) LSIGFILLSET :: "__sigfillset14"
  377. @(private) LSIGALTSTACK :: "__sigaltstack14"
  378. @(private) LSIGISMEMBER :: "__sigismember14"
  379. @(private) LSIGPENDING :: "__sigpending14"
  380. @(private) LSIGSUSPEND :: "__sigsuspend14"
  381. } else {
  382. @(private) LSIGPROCMASK :: "sigprocmask"
  383. @(private) LSIGACTION :: "sigaction"
  384. @(private) LSIGADDSET :: "sigaddset"
  385. @(private) LSIGDELSET :: "sigdelset"
  386. @(private) LSIGEMPTYSET :: "sigemptyset"
  387. @(private) LSIGFILLSET :: "sigfillset"
  388. @(private) LSIGALTSTACK :: "sigaltstack"
  389. @(private) LSIGISMEMBER :: "sigismember"
  390. @(private) LSIGPENDING :: "sigpending"
  391. @(private) LSIGSUSPEND :: "sigsuspend"
  392. }
  393. when ODIN_OS == .Darwin {
  394. // Request that signal be held
  395. SIG_HOLD :: rawptr(uintptr(5))
  396. uid_t :: distinct c.uint32_t
  397. sigset_t :: distinct c.uint32_t
  398. // MOTE: unimplemented on darwin.
  399. //
  400. // SIGRTMIN ::
  401. // SIGRTMAX ::
  402. SIGHUP :: 1
  403. SIGQUIT :: 3
  404. SIGTRAP :: 5
  405. SIGPOLL :: 7
  406. SIGKILL :: 9
  407. SIGBUS :: 10
  408. SIGSYS :: 12
  409. SIGPIPE :: 13
  410. SIGALRM :: 14
  411. SIGURG :: 16
  412. SIGCONT :: 19
  413. SIGSTOP :: 17
  414. SIGTSTP :: 18
  415. SIGCHLD :: 20
  416. SIGTTIN :: 21
  417. SIGTTOU :: 22
  418. SIGXCPU :: 24
  419. SIGXFSZ :: 25
  420. SIGVTALRM :: 26
  421. SIGPROF :: 27
  422. SIGUSR1 :: 30
  423. SIGUSR2 :: 31
  424. // NOTE: this is actually defined as `sigaction`, but due to the function with the same name
  425. // `_t` has been added.
  426. sigaction_t :: struct {
  427. using _: struct #raw_union {
  428. sa_handler: proc "c" (Signal), /* [PSX] signal-catching function or one of the SIG_IGN or SIG_DFL */
  429. sa_sigaction: proc "c" (Signal, ^siginfo_t, rawptr), /* [PSX] signal-catching function */
  430. },
  431. sa_mask: sigset_t, /* [PSX] set of signals to be blocked during execution of the signal handling function */
  432. sa_flags: SA_Flags, /* [PSX] special flags */
  433. }
  434. SIG_BLOCK :: 1
  435. SIG_UNBLOCK :: 2
  436. SIG_SETMASK :: 3
  437. SA_NOCLDSTOP :: 0x0008
  438. SA_ONSTACK :: 0x0001
  439. SA_RESETHAND :: 0x0004
  440. SA_RESTART :: 0x0002
  441. SA_SIGINFO :: 0x0040
  442. SA_NOCLDWAIT :: 0x0020
  443. SA_NODEFER :: 0x0010
  444. SS_ONSTACK :: 0x0001
  445. SS_DISABLE :: 0x0004
  446. MINSIGSTKSZ :: 32768
  447. SIGSTKSZ :: 131072
  448. stack_t :: struct {
  449. ss_sp: rawptr, /* [PSX] stack base or pointer */
  450. ss_size: c.size_t, /* [PSX] stack size */
  451. ss_flags: SS_Flags, /* [PSX] flags */
  452. }
  453. siginfo_t :: struct {
  454. si_signo: Signal, /* [PSX] signal number */
  455. si_errno: Errno, /* [PSX] errno value associated with this signal */
  456. si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */
  457. ill: ILL_Code,
  458. fpe: FPE_Code,
  459. segv: SEGV_Code,
  460. bus: BUS_Code,
  461. trap: TRAP_Code,
  462. chld: CLD_Code,
  463. poll: POLL_Code,
  464. any: Any_Code,
  465. },
  466. si_pid: pid_t, /* [PSX] sending process ID */
  467. si_uid: uid_t, /* [PSX] real user ID of sending process */
  468. si_status: c.int, /* [PSX] exit value or signal */
  469. si_addr: rawptr, /* [PSX] address of faulting instruction */
  470. si_value: sigval, /* [PSX] signal value */
  471. si_band: c.long, /* [PSX] band event for SIGPOLL */
  472. __pad: [7]c.ulong,
  473. }
  474. ILL_ILLOPC :: 1
  475. ILL_ILLOPN :: 4
  476. ILL_ILLADR :: 5
  477. ILL_ILLTRP :: 2
  478. ILL_PRVOPC :: 3
  479. ILL_PRVREG :: 6
  480. ILL_COPROC :: 7
  481. ILL_BADSTK :: 8
  482. FPE_INTDIV :: 7
  483. FPE_INTOVF :: 8
  484. FPE_FLTDIV :: 1
  485. FPE_FLTOVF :: 2
  486. FPE_FLTUND :: 3
  487. FPE_FLTRES :: 4
  488. FPE_FLTINV :: 5
  489. FPE_FLTSUB :: 6
  490. SEGV_MAPERR :: 1
  491. SEGV_ACCERR :: 2
  492. BUS_ADRALN :: 1
  493. BUS_ADRERR :: 2
  494. BUS_OBJERR :: 3
  495. TRAP_BRKPT :: 1
  496. TRAP_TRACE :: 2
  497. CLD_EXITED :: 1
  498. CLD_KILLED :: 2
  499. CLD_DUMPED :: 3
  500. CLD_TRAPPED :: 4
  501. CLD_STOPPED :: 5
  502. CLD_CONTINUED :: 6
  503. POLL_IN :: 1
  504. POLL_OUT :: 2
  505. POLL_MSG :: 3
  506. POLL_ERR :: 4
  507. POLL_PRI :: 5
  508. POLL_HUP :: 6
  509. SI_USER :: 0x10001
  510. SI_QUEUE :: 0x10002
  511. SI_TIMER :: 0x10003
  512. SI_ASYNCIO :: 0x10004
  513. SI_MESGQ :: 0x10005
  514. } else when ODIN_OS == .FreeBSD {
  515. // Request that signal be held
  516. SIG_HOLD :: rawptr(uintptr(3))
  517. uid_t :: distinct c.uint32_t
  518. sigset_t :: struct {
  519. __bits: [4]c.uint32_t,
  520. }
  521. // MOTE: unimplemented on darwin.
  522. //
  523. // SIGRTMIN :: 65
  524. // SIGRTMAX :: 126
  525. SIGHUP :: 1
  526. SIGQUIT :: 3
  527. SIGTRAP :: 5
  528. SIGPOLL :: 7
  529. SIGKILL :: 9
  530. SIGBUS :: 10
  531. SIGSYS :: 12
  532. SIGPIPE :: 13
  533. SIGALRM :: 14
  534. SIGURG :: 16
  535. SIGCONT :: 19
  536. SIGSTOP :: 17
  537. SIGTSTP :: 18
  538. SIGCHLD :: 20
  539. SIGTTIN :: 21
  540. SIGTTOU :: 22
  541. SIGXCPU :: 24
  542. SIGXFSZ :: 25
  543. SIGVTALRM :: 26
  544. SIGPROF :: 27
  545. SIGUSR1 :: 30
  546. SIGUSR2 :: 31
  547. // NOTE: this is actually defined as `sigaction`, but due to the function with the same name
  548. // `_t` has been added.
  549. sigaction_t :: struct {
  550. using _: struct #raw_union {
  551. sa_handler: proc "c" (Signal), /* [PSX] signal-catching function or one of the SIG_IGN or SIG_DFL */
  552. sa_sigaction: proc "c" (Signal, ^siginfo_t, rawptr), /* [PSX] signal-catching function */
  553. },
  554. sa_flags: SA_Flags, /* [PSX] special flags */
  555. sa_mask: sigset_t, /* [PSX] set of signals to be blocked during execution of the signal handling function */
  556. }
  557. SIG_BLOCK :: 1
  558. SIG_UNBLOCK :: 2
  559. SIG_SETMASK :: 3
  560. SA_NOCLDSTOP :: 0x0008
  561. SA_ONSTACK :: 0x0001
  562. SA_RESETHAND :: 0x0004
  563. SA_RESTART :: 0x0002
  564. SA_SIGINFO :: 0x0040
  565. SA_NOCLDWAIT :: 0x0020
  566. SA_NODEFER :: 0x0010
  567. SS_ONSTACK :: 0x0001
  568. SS_DISABLE :: 0x0004
  569. when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm32 {
  570. MINSIGSTKSZ :: 1024 * 4
  571. } else when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 {
  572. MINSIGSTKSZ :: 512 * 4
  573. }
  574. SIGSTKSZ :: MINSIGSTKSZ + 32768
  575. stack_t :: struct {
  576. ss_sp: rawptr, /* [PSX] stack base or pointer */
  577. ss_size: c.size_t, /* [PSX] stack size */
  578. ss_flags: SS_Flags, /* [PSX] flags */
  579. }
  580. siginfo_t :: struct {
  581. si_signo: Signal, /* [PSX] signal number */
  582. si_errno: Errno, /* [PSX] errno value associated with this signal */
  583. si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */
  584. ill: ILL_Code,
  585. fpe: FPE_Code,
  586. segv: SEGV_Code,
  587. bus: BUS_Code,
  588. trap: TRAP_Code,
  589. chld: CLD_Code,
  590. poll: POLL_Code,
  591. any: Any_Code,
  592. },
  593. si_pid: pid_t, /* [PSX] sending process ID */
  594. si_uid: uid_t, /* [PSX] real user ID of sending process */
  595. si_status: c.int, /* [PSX] exit value or signal */
  596. si_addr: rawptr, /* [PSX] address of faulting instruction */
  597. si_value: sigval, /* [PSX] signal value */
  598. using _reason: struct #raw_union {
  599. _fault: struct {
  600. _trapno: c.int, /* machine specific trap code */
  601. },
  602. _timer: struct {
  603. _timerid: c.int,
  604. _overrun: c.int,
  605. },
  606. _mesgq: struct {
  607. _mqd: c.int,
  608. },
  609. using _poll: struct {
  610. si_band: c.long, /* [PSX] band event for SIGPOLL */
  611. },
  612. _capsicum: struct {
  613. _syscall: c.int, /* syscall number for signals delivered as a result of system calls denied by capsicum */
  614. },
  615. __spare__: struct {
  616. __spare1__: c.long,
  617. __spare2__: [7]c.int,
  618. },
  619. },
  620. }
  621. ILL_ILLOPC :: 1
  622. ILL_ILLOPN :: 2
  623. ILL_ILLADR :: 3
  624. ILL_ILLTRP :: 4
  625. ILL_PRVOPC :: 5
  626. ILL_PRVREG :: 6
  627. ILL_COPROC :: 7
  628. ILL_BADSTK :: 8
  629. FPE_INTDIV :: 2
  630. FPE_INTOVF :: 1
  631. FPE_FLTDIV :: 3
  632. FPE_FLTOVF :: 4
  633. FPE_FLTUND :: 5
  634. FPE_FLTRES :: 6
  635. FPE_FLTINV :: 7
  636. FPE_FLTSUB :: 8
  637. SEGV_MAPERR :: 1
  638. SEGV_ACCERR :: 2
  639. BUS_ADRALN :: 1
  640. BUS_ADRERR :: 2
  641. BUS_OBJERR :: 3
  642. TRAP_BRKPT :: 1
  643. TRAP_TRACE :: 2
  644. CLD_EXITED :: 1
  645. CLD_KILLED :: 2
  646. CLD_DUMPED :: 3
  647. CLD_TRAPPED :: 4
  648. CLD_STOPPED :: 5
  649. CLD_CONTINUED :: 6
  650. POLL_IN :: 1
  651. POLL_OUT :: 2
  652. POLL_MSG :: 3
  653. POLL_ERR :: 4
  654. POLL_PRI :: 5
  655. POLL_HUP :: 6
  656. SI_USER :: 0x10001
  657. SI_QUEUE :: 0x10002
  658. SI_TIMER :: 0x10003
  659. SI_ASYNCIO :: 0x10004
  660. SI_MESGQ :: 0x10005
  661. } else when ODIN_OS == .NetBSD {
  662. // Request that signal be held
  663. SIG_HOLD :: rawptr(uintptr(3))
  664. uid_t :: distinct c.uint32_t
  665. sigset_t :: struct {
  666. __bits: [4]c.uint32_t,
  667. }
  668. // MOTE: unimplemented on darwin.
  669. //
  670. // SIGRTMIN :: 33
  671. // SIGRTMAX :: 63
  672. SIGHUP :: 1
  673. SIGQUIT :: 3
  674. SIGTRAP :: 5
  675. SIGPOLL :: 7
  676. SIGKILL :: 9
  677. SIGBUS :: 10
  678. SIGSYS :: 12
  679. SIGPIPE :: 13
  680. SIGALRM :: 14
  681. SIGURG :: 16
  682. SIGCONT :: 19
  683. SIGSTOP :: 17
  684. SIGTSTP :: 18
  685. SIGCHLD :: 20
  686. SIGTTIN :: 21
  687. SIGTTOU :: 22
  688. SIGXCPU :: 24
  689. SIGXFSZ :: 25
  690. SIGVTALRM :: 26
  691. SIGPROF :: 27
  692. SIGUSR1 :: 30
  693. SIGUSR2 :: 31
  694. // NOTE: this is actually defined as `sigaction`, but due to the function with the same name
  695. // `_t` has been added.
  696. sigaction_t :: struct {
  697. using _: struct #raw_union {
  698. sa_handler: proc "c" (Signal), /* [PSX] signal-catching function or one of the SIG_IGN or SIG_DFL */
  699. sa_sigaction: proc "c" (Signal, ^siginfo_t, rawptr), /* [PSX] signal-catching function */
  700. },
  701. sa_mask: sigset_t, /* [PSX] set of signals to be blocked during execution of the signal handling function */
  702. sa_flags: SA_Flags, /* [PSX] special flags */
  703. }
  704. SIG_BLOCK :: 1
  705. SIG_UNBLOCK :: 2
  706. SIG_SETMASK :: 3
  707. SA_NOCLDSTOP :: 0x0008
  708. SA_ONSTACK :: 0x0001
  709. SA_RESETHAND :: 0x0004
  710. SA_RESTART :: 0x0002
  711. SA_SIGINFO :: 0x0040
  712. SA_NOCLDWAIT :: 0x0020
  713. SA_NODEFER :: 0x0010
  714. SS_ONSTACK :: 0x0001
  715. SS_DISABLE :: 0x0004
  716. MINSIGSTKSZ :: 8192
  717. SIGSTKSZ :: MINSIGSTKSZ + 32768
  718. stack_t :: struct {
  719. ss_sp: rawptr, /* [PSX] stack base or pointer */
  720. ss_size: c.size_t, /* [PSX] stack size */
  721. ss_flags: SS_Flags, /* [PSX] flags */
  722. }
  723. @(private)
  724. lwpid_t :: c.int32_t
  725. siginfo_t :: struct #raw_union {
  726. si_pad: [128]byte,
  727. using _info: struct {
  728. si_signo: Signal, /* [PSX] signal number */
  729. si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */
  730. ill: ILL_Code,
  731. fpe: FPE_Code,
  732. segv: SEGV_Code,
  733. bus: BUS_Code,
  734. trap: TRAP_Code,
  735. chld: CLD_Code,
  736. poll: POLL_Code,
  737. any: Any_Code,
  738. },
  739. si_errno: Errno, /* [PSX] errno value associated with this signal */
  740. // #ifdef _LP64
  741. /* In _LP64 the union starts on an 8-byte boundary. */
  742. _pad: c.int,
  743. // #endif
  744. using _reason: struct #raw_union {
  745. using _rt: struct {
  746. _pid: pid_t,
  747. _uid: uid_t,
  748. si_value: sigval, /* [PSX] signal value */
  749. },
  750. using _child: struct {
  751. si_pid: pid_t, /* [PSX] sending process ID */
  752. si_uid: uid_t, /* [PSX] real user ID of sending process */
  753. si_status: c.int, /* [PSX] exit value or signal */
  754. _utime: clock_t,
  755. _stime: clock_t,
  756. },
  757. using _fault: struct {
  758. si_addr: rawptr, /* [PSX] address of faulting instruction */
  759. _trap: c.int,
  760. _trap2: c.int,
  761. _trap3: c.int,
  762. },
  763. using _poll: struct {
  764. si_band: c.long, /* [PSX] band event for SIGPOLL */
  765. _fd: FD,
  766. },
  767. _syscall: struct {
  768. _sysnum: c.int,
  769. _retval: [2]c.int,
  770. _error: c.int,
  771. _args: [8]c.uint64_t,
  772. },
  773. _ptrace_state: struct {
  774. _pe_report_event: c.int,
  775. _option: struct #raw_union {
  776. _pe_other_pid: pid_t,
  777. _pe_lwp: lwpid_t,
  778. },
  779. },
  780. },
  781. },
  782. }
  783. ILL_ILLOPC :: 1
  784. ILL_ILLOPN :: 2
  785. ILL_ILLADR :: 3
  786. ILL_ILLTRP :: 4
  787. ILL_PRVOPC :: 5
  788. ILL_PRVREG :: 6
  789. ILL_COPROC :: 7
  790. ILL_BADSTK :: 8
  791. FPE_INTDIV :: 1
  792. FPE_INTOVF :: 2
  793. FPE_FLTDIV :: 3
  794. FPE_FLTOVF :: 4
  795. FPE_FLTUND :: 5
  796. FPE_FLTRES :: 6
  797. FPE_FLTINV :: 7
  798. FPE_FLTSUB :: 8
  799. SEGV_MAPERR :: 1
  800. SEGV_ACCERR :: 2
  801. BUS_ADRALN :: 1
  802. BUS_ADRERR :: 2
  803. BUS_OBJERR :: 3
  804. TRAP_BRKPT :: 1
  805. TRAP_TRACE :: 2
  806. CLD_EXITED :: 1
  807. CLD_KILLED :: 2
  808. CLD_DUMPED :: 3
  809. CLD_TRAPPED :: 4
  810. CLD_STOPPED :: 5
  811. CLD_CONTINUED :: 6
  812. POLL_IN :: 1
  813. POLL_OUT :: 2
  814. POLL_MSG :: 3
  815. POLL_ERR :: 4
  816. POLL_PRI :: 5
  817. POLL_HUP :: 6
  818. SI_USER :: 0
  819. SI_QUEUE :: -1
  820. SI_TIMER :: -2
  821. SI_ASYNCIO :: -3
  822. SI_MESGQ :: -4
  823. } else when ODIN_OS == .OpenBSD {
  824. // Request that signal be held
  825. SIG_HOLD :: rawptr(uintptr(3))
  826. uid_t :: distinct c.uint32_t
  827. sigset_t :: distinct c.uint32_t
  828. SIGHUP :: 1
  829. SIGQUIT :: 3
  830. SIGTRAP :: 5
  831. SIGPOLL :: 7
  832. SIGKILL :: 9
  833. SIGBUS :: 10
  834. SIGSYS :: 12
  835. SIGPIPE :: 13
  836. SIGALRM :: 14
  837. SIGURG :: 16
  838. SIGCONT :: 19
  839. SIGSTOP :: 17
  840. SIGTSTP :: 18
  841. SIGCHLD :: 20
  842. SIGTTIN :: 21
  843. SIGTTOU :: 22
  844. SIGXCPU :: 24
  845. SIGXFSZ :: 25
  846. SIGVTALRM :: 26
  847. SIGPROF :: 27
  848. SIGUSR1 :: 30
  849. SIGUSR2 :: 31
  850. // NOTE: this is actually defined as `sigaction`, but due to the function with the same name
  851. // `_t` has been added.
  852. sigaction_t :: struct {
  853. using _: struct #raw_union {
  854. sa_handler: proc "c" (Signal), /* [PSX] signal-catching function or one of the SIG_IGN or SIG_DFL */
  855. sa_sigaction: proc "c" (Signal, ^siginfo_t, rawptr), /* [PSX] signal-catching function */
  856. },
  857. sa_mask: sigset_t, /* [PSX] set of signals to be blocked during execution of the signal handling function */
  858. sa_flags: SA_Flags, /* [PSX] special flags */
  859. }
  860. SIG_BLOCK :: 1
  861. SIG_UNBLOCK :: 2
  862. SIG_SETMASK :: 3
  863. SA_NOCLDSTOP :: 0x0008
  864. SA_ONSTACK :: 0x0001
  865. SA_RESETHAND :: 0x0004
  866. SA_RESTART :: 0x0002
  867. SA_SIGINFO :: 0x0040
  868. SA_NOCLDWAIT :: 0x0020
  869. SA_NODEFER :: 0x0010
  870. SS_ONSTACK :: 0x0001
  871. SS_DISABLE :: 0x0004
  872. MINSIGSTKSZ :: 3 << 12
  873. SIGSTKSZ :: MINSIGSTKSZ + (1 << 12) * 4
  874. stack_t :: struct {
  875. ss_sp: rawptr, /* [PSX] stack base or pointer */
  876. ss_size: c.size_t, /* [PSX] stack size */
  877. ss_flags: SS_Flags, /* [PSX] flags */
  878. }
  879. SI_MAXSZ :: 128
  880. SI_PAD :: (SI_MAXSZ / size_of(c.int)) - 3
  881. siginfo_t :: struct {
  882. si_signo: Signal, /* [PSX] signal number */
  883. si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */
  884. ill: ILL_Code,
  885. fpe: FPE_Code,
  886. segv: SEGV_Code,
  887. bus: BUS_Code,
  888. trap: TRAP_Code,
  889. chld: CLD_Code,
  890. poll: POLL_Code,
  891. any: Any_Code,
  892. },
  893. si_errno: Errno, /* [PSX] errno value associated with this signal */
  894. using _data: struct #raw_union {
  895. _pad: [SI_PAD]c.int,
  896. using _proc: struct {
  897. si_pid: pid_t, /* [PSX] sending process ID */
  898. si_uid: uid_t, /* [PSX] real user ID of sending process */
  899. using _pdata: struct #raw_union {
  900. using _kill: struct {
  901. si_value: sigval,
  902. },
  903. using _cld: struct {
  904. _utime: clock_t,
  905. _stime: clock_t,
  906. si_status: c.int,
  907. },
  908. },
  909. },
  910. using _fault: struct {
  911. si_addr: rawptr,
  912. _trapno: c.int,
  913. },
  914. using _file: struct {
  915. _fd: FD,
  916. si_band: c.long, /* [PSX] band event for SIGPOLL */
  917. },
  918. },
  919. }
  920. ILL_ILLOPC :: 1
  921. ILL_ILLOPN :: 2
  922. ILL_ILLADR :: 3
  923. ILL_ILLTRP :: 4
  924. ILL_PRVOPC :: 5
  925. ILL_PRVREG :: 6
  926. ILL_COPROC :: 7
  927. ILL_BADSTK :: 8
  928. FPE_INTDIV :: 1
  929. FPE_INTOVF :: 2
  930. FPE_FLTDIV :: 3
  931. FPE_FLTOVF :: 4
  932. FPE_FLTUND :: 5
  933. FPE_FLTRES :: 6
  934. FPE_FLTINV :: 7
  935. FPE_FLTSUB :: 8
  936. SEGV_MAPERR :: 1
  937. SEGV_ACCERR :: 2
  938. BUS_ADRALN :: 1
  939. BUS_ADRERR :: 2
  940. BUS_OBJERR :: 3
  941. TRAP_BRKPT :: 1
  942. TRAP_TRACE :: 2
  943. CLD_EXITED :: 1
  944. CLD_KILLED :: 2
  945. CLD_DUMPED :: 3
  946. CLD_TRAPPED :: 4
  947. CLD_STOPPED :: 5
  948. CLD_CONTINUED :: 6
  949. POLL_IN :: 1
  950. POLL_OUT :: 2
  951. POLL_MSG :: 3
  952. POLL_ERR :: 4
  953. POLL_PRI :: 5
  954. POLL_HUP :: 6
  955. SI_USER :: 0
  956. SI_QUEUE :: -2
  957. SI_TIMER :: -3
  958. SI_ASYNCIO :: -4 // NOTE: not implemented
  959. SI_MESGQ :: -5 // NOTE: not implemented
  960. } else {
  961. #panic("posix is unimplemented for the current target")
  962. }