sys.odin 92 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333
  1. #+build linux
  2. #+no-instrumentation
  3. package linux
  4. import "base:intrinsics"
  5. /*
  6. Read data from file into the buffer
  7. Returns the number of bytes successfully read, which may be less than the size
  8. of the buffer even if the termination is successfull.
  9. Available since Linux 1.0.
  10. Before Linux 3.14, this operation is not atomic (i.e. not thread safe).
  11. */
  12. read :: proc "contextless" (fd: Fd, buf: []u8) -> (int, Errno) {
  13. ret := syscall(SYS_read, fd, raw_data(buf), len(buf))
  14. return errno_unwrap(ret, int)
  15. }
  16. /*
  17. Write the data from a buffer into the file
  18. Returns the number of bytes successfully written, which may be less than the size
  19. of the buffer, even if the termination is successfull
  20. When using direct I/O, error doesn't mean the write has failed. Partial data may
  21. have been written.
  22. If .Eintr is returned, the write operation has failed due to interrupt. You'll probably
  23. need to restart this syscall
  24. Available since Linux 1.0
  25. Before Linux 3.14 this operation is not atomic (i.e. not thread safe)
  26. */
  27. write :: proc "contextless" (fd: Fd, buf: []u8) -> (int, Errno) {
  28. ret := syscall(SYS_write, fd, raw_data(buf), len(buf))
  29. return errno_unwrap(ret, int)
  30. }
  31. /*
  32. Open file, get the file descriptor
  33. Available since Linux 1.0.
  34. On ARM64 available since Linux 2.6.16.
  35. */
  36. open :: proc "contextless" (name: cstring, flags: Open_Flags, mode: Mode = {}) -> (Fd, Errno) {
  37. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  38. ret := syscall(SYS_openat, AT_FDCWD, transmute(uintptr) name, transmute(u32) flags, transmute(u32) mode)
  39. return errno_unwrap(ret, Fd)
  40. } else {
  41. ret := syscall(SYS_open, transmute(uintptr) name, transmute(u32) flags, transmute(u32) mode)
  42. return errno_unwrap(ret, Fd)
  43. }
  44. }
  45. /*
  46. Close the file.
  47. Available since Linux 1.0.
  48. */
  49. close :: proc "contextless" (fd: Fd) -> (Errno) {
  50. ret := syscall(SYS_close, fd)
  51. return Errno(-ret)
  52. }
  53. /*
  54. Get file status.
  55. Returns information about the file in struct pointed to by `stat` parameter.
  56. Available since Linux 1.0
  57. For 32-bit systems a different syscall is used that became available since 2.4.
  58. Not available on ARM64.
  59. */
  60. stat :: proc "contextless" (filename: cstring, stat: ^Stat) -> (Errno) {
  61. when size_of(int) == 8 {
  62. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  63. ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat, 0)
  64. return Errno(-ret)
  65. } else {
  66. ret := syscall(SYS_stat, cast(rawptr) filename, stat)
  67. return Errno(-ret)
  68. }
  69. } else {
  70. ret := syscall(SYS_stat64, cast(rawptr) filename, stat)
  71. return Errno(-ret)
  72. }
  73. }
  74. /*
  75. Get file status from file descriptor.
  76. Returns information about the file in struct pointed to by `stat` parameter.
  77. Available since Linux 1.0.
  78. For 32-bit systems a different syscall is used that became available since 2.4.
  79. */
  80. fstat :: proc "contextless" (fd: Fd, stat: ^Stat) -> (Errno) {
  81. when size_of(int) == 8 {
  82. ret := syscall(SYS_fstat, cast(i32) fd, stat)
  83. return Errno(-ret)
  84. } else {
  85. ret := syscall(SYS_fstat64, cast(i32) fd, stat)
  86. return Errno(-ret)
  87. }
  88. }
  89. /*
  90. Get information about the file that's potentially a symbolic link
  91. The information is returned in a struct pointed to by `stat` parameter.
  92. The difference with stat, fstat is that if the file is a symbolic link,
  93. stat and fstat will dereference the link. lstat doesn't dereference symlinks.
  94. Available since Linux 1.0.
  95. For 32-bit systems a different syscall is used that became available since 2.4.
  96. Not available on arm64.
  97. */
  98. lstat :: proc "contextless" (filename: cstring, stat: ^Stat) -> (Errno) {
  99. when size_of(int) == 8 {
  100. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  101. return fstatat(AT_FDCWD, filename, stat, {.SYMLINK_NOFOLLOW})
  102. } else {
  103. ret := syscall(SYS_lstat, cast(rawptr) filename, stat)
  104. return Errno(-ret)
  105. }
  106. } else {
  107. ret := syscall(SYS_lstat64, cast(rawptr) filename, stat)
  108. return Errno(-ret)
  109. }
  110. }
  111. /*
  112. Wait on event on a file descriptor.
  113. Available since Linux 2.2.
  114. */
  115. poll :: proc "contextless" (fds: []Poll_Fd, timeout: i32) -> (i32, Errno) {
  116. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  117. seconds := cast(uint) timeout / 1000
  118. nanoseconds := cast(uint) (timeout % 1000) * 1_000_000
  119. timeout_spec := Time_Spec{seconds, nanoseconds}
  120. ret := syscall(SYS_ppoll, raw_data(fds), len(fds), &timeout_spec, 0, 0)
  121. return errno_unwrap(ret, i32)
  122. } else {
  123. ret := syscall(SYS_poll, raw_data(fds), len(fds), timeout)
  124. return errno_unwrap(ret, i32)
  125. }
  126. }
  127. /*
  128. Seek the file stream to specified offset.
  129. Available since Linux 1.0.
  130. On 32-bit platforms available since Linux 1.2.
  131. */
  132. lseek :: proc "contextless" (fd: Fd, off: i64, whence: Seek_Whence) -> (i64, Errno) {
  133. when size_of(int) == 8 {
  134. ret := syscall(SYS_lseek, fd, off, whence)
  135. return errno_unwrap(ret, i64)
  136. } else {
  137. result: i64 = ---
  138. lo, hi := compat64_arg_pair(off)
  139. ret := syscall(SYS__llseek, fd, hi, lo, &result, whence)
  140. return result, Errno(-ret)
  141. }
  142. }
  143. /*
  144. Map files into memory.
  145. Available since Linux 1.0.
  146. On 32-bit platforms since Linux 1.0.
  147. */
  148. mmap :: proc "contextless" (addr: uintptr, size: uint, prot: Mem_Protection, flags: Map_Flags, fd: Fd = Fd(-1), offset: i64 = 0) -> (rawptr, Errno) {
  149. when size_of(int) == 8 {
  150. ret := syscall(SYS_mmap, addr, size, transmute(i32) prot, transmute(i32) flags, fd, offset)
  151. return errno_unwrap(ret, rawptr, uintptr)
  152. } else {
  153. ret := syscall(SYS_mmap2, addr, size, transmute(i32) prot, transmute(i32) flags, fd, cast(uintptr)(offset/4096))
  154. return errno_unwrap(ret, rawptr, uintptr)
  155. }
  156. }
  157. /*
  158. Protect memory region.
  159. Available since Linux 1.0.
  160. */
  161. mprotect :: proc "contextless" (addr: rawptr, size: uint, prot: Mem_Protection) -> (Errno) {
  162. ret := syscall(SYS_mprotect, addr, size, transmute(i32) prot)
  163. return Errno(-ret)
  164. }
  165. /*
  166. Unmap memory.
  167. Available since Linux 1.0.
  168. */
  169. munmap :: proc "contextless" (addr: rawptr, size: uint) -> (Errno) {
  170. ret := syscall(SYS_munmap, addr, size)
  171. return Errno(-ret)
  172. }
  173. /*
  174. Extend the data segment size until the address `addr`. Note: you may be
  175. familiar with sbrk(), which is not actually a syscall, so is not
  176. implemented here.
  177. Available since Linux 1.0.
  178. */
  179. brk :: proc "contextless" (addr: uintptr) -> (Errno) {
  180. ret := syscall(SYS_brk, addr)
  181. return Errno(-ret)
  182. }
  183. /*
  184. Returns from signal handlers on some archs.
  185. */
  186. rt_sigreturn :: proc "c" () -> ! {
  187. intrinsics.syscall(uintptr(SYS_rt_sigreturn))
  188. unreachable()
  189. }
  190. /*
  191. Alter an action taken by a process.
  192. */
  193. rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action($T), old_sigaction: ^Sig_Action($U)) -> Errno {
  194. // NOTE(jason): It appears that the restorer is required for i386 and amd64
  195. when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 {
  196. sigaction.flags += {.RESTORER}
  197. }
  198. if sigaction != nil && sigaction.restorer == nil && .RESTORER in sigaction.flags {
  199. sigaction.restorer = rt_sigreturn
  200. }
  201. ret := syscall(SYS_rt_sigaction, sig, sigaction, old_sigaction, size_of(Sig_Set))
  202. return Errno(-ret)
  203. }
  204. /*
  205. Examime and alter blocked signals.
  206. Available since Linux 2.2.
  207. */
  208. rt_sigprocmask :: proc "contextless" (mask_kind: Sig_Mask_Kind, new_set: ^Sig_Set, old_set: ^Sig_Set) -> Errno {
  209. ret := syscall(SYS_rt_sigprocmask, mask_kind, new_set, old_set, size_of(Sig_Set))
  210. return Errno(-ret)
  211. }
  212. /*
  213. Control devices. The ioctl syscall is a bit special because
  214. its argument is usually a pointer to some driver-specific structure.
  215. The request value is device-specific. Consult your LibC implementation's
  216. ioctls.h file to learn more. The returned value of ioctl *may* be an error
  217. code value instead of a memory address depending on the request type.
  218. Available since Linux 1.0.
  219. */
  220. ioctl :: proc "contextless" (fd: Fd, request: u32, arg: uintptr) -> (uintptr) {
  221. ret := syscall(SYS_ioctl, fd, request, arg)
  222. return uintptr(ret)
  223. }
  224. /*
  225. Read the file at a specified offset.
  226. Note, it is not an error to return less bytes than requested.
  227. Available since Linux 2.2.
  228. */
  229. pread :: proc "contextless" (fd: Fd, buf: []u8, offset: i64) -> (int, Errno) {
  230. when ODIN_ARCH == .arm32 {
  231. ret := syscall(SYS_pread64, fd, raw_data(buf), len(buf), 0, compat64_arg_pair(offset))
  232. } else {
  233. ret := syscall(SYS_pread64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset))
  234. }
  235. return errno_unwrap(ret, int)
  236. }
  237. /*
  238. Read the file at a specified offset.
  239. Note, it is not an error to return less bytes than requested.
  240. Available since Linux 2.2.
  241. */
  242. pwrite :: proc "contextless" (fd: Fd, buf: []u8, offset: i64) -> (int, Errno) {
  243. when ODIN_ARCH == .arm32 {
  244. ret := syscall(SYS_pwrite64, fd, raw_data(buf), len(buf), 0, compat64_arg_pair(offset))
  245. } else {
  246. ret := syscall(SYS_pwrite64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset))
  247. }
  248. return errno_unwrap(ret, int)
  249. }
  250. /*
  251. Read the data from file into multiple buffers.
  252. Available since Linux 2.0.
  253. */
  254. readv :: proc "contextless" (fd: Fd, iov: []IO_Vec) -> (int, Errno) {
  255. ret := syscall(SYS_readv, fd, raw_data(iov), len(iov))
  256. return errno_unwrap(ret, int)
  257. }
  258. /*
  259. Write the data from multiple buffers into a file.
  260. Available since Linux 2.0.
  261. */
  262. writev :: proc "contextless" (fd: Fd, iov: []IO_Vec) -> (int, Errno) {
  263. ret := syscall(SYS_writev, fd, raw_data(iov), len(iov))
  264. return errno_unwrap(ret, int)
  265. }
  266. /*
  267. Check user permissions for a file.
  268. If Mode is F_OK, checks whether the file exists.
  269. Similarly, X_OK, W_OK, R_OK check if the file is executable, writeable, readable respectively.
  270. Available since Linux 1.0.
  271. For ARM64 available since Linux 2.6.16.
  272. */
  273. access :: proc "contextless" (name: cstring, mode: Mode = F_OK) -> (Errno) {
  274. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  275. ret := syscall(SYS_faccessat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode)
  276. return Errno(-ret)
  277. } else {
  278. ret := syscall(SYS_access, cast(rawptr) name, transmute(u32) mode)
  279. return Errno(-ret)
  280. }
  281. }
  282. /*
  283. Create a pipe
  284. Available since Linux 2.6.27
  285. */
  286. pipe2 :: proc "contextless" (pipes: ^[2]Fd, flags: Open_Flags) -> (Errno) {
  287. ret := syscall(SYS_pipe2, pipes, transmute(u32) flags)
  288. return Errno(-ret)
  289. }
  290. /*
  291. Yield the processor.
  292. Available since Linux 2.0.
  293. */
  294. sched_yield :: proc "contextless" () {
  295. syscall(SYS_sched_yield)
  296. }
  297. /*
  298. Remap a virtual memory address.
  299. Available since Linux 2.0.
  300. */
  301. mremap :: proc "contextless" (old_addr: rawptr, old_size: uint, new_size: uint, flags: MRemap_Flags, new_addr: uintptr = 0) -> (rawptr, Errno) {
  302. if .FIXED in flags {
  303. ret := syscall(SYS_mremap, old_addr, old_size, new_size, transmute(i32) flags, new_addr)
  304. return errno_unwrap(ret, rawptr, rawptr)
  305. } else {
  306. ret := syscall(SYS_mremap, old_addr, old_size, new_size, transmute(i32) flags)
  307. return errno_unwrap(ret, rawptr, rawptr)
  308. }
  309. }
  310. /*
  311. Sync file with memory map.
  312. Available since Linux 2.0.
  313. */
  314. msync :: proc "contextless" (addr: rawptr, size: uint, flags: MSync_Flags) -> (Errno) {
  315. ret := syscall(SYS_msync, addr, size, transmute(i32) flags)
  316. return Errno(-ret)
  317. }
  318. /*
  319. Determine if pages are resident in memory.
  320. Available since Linux 2.4.
  321. */
  322. mincore :: proc "contextless" (addr: rawptr, size: uint, vec: []b8) -> (Errno) {
  323. ret := syscall(SYS_mincore, addr, size, raw_data(vec))
  324. return Errno(-ret)
  325. }
  326. /*
  327. Give advice about use of memory.
  328. Available since Linux 2.4.
  329. */
  330. madvise :: proc "contextless" (addr: rawptr, size: uint, advice: MAdvice) -> (Errno) {
  331. ret := syscall(SYS_madvise, addr, size, advice)
  332. return Errno(-ret)
  333. }
  334. /*
  335. Allocate a SystemV shared memory segment.
  336. Available since Linux 2.0.
  337. */
  338. shmget :: proc "contextless" (key: Key, size: uint, flags: IPC_Flags) -> (Key, Errno) {
  339. ret := syscall(SYS_shmget, key, size, transmute(i16) flags)
  340. return errno_unwrap(ret, Key)
  341. }
  342. /*
  343. SystemV shared memory segment operations.
  344. Available since Linux 2.0.
  345. */
  346. shmat :: proc "contextless" (key: Key, addr: rawptr, flags: IPC_Flags) -> (rawptr, Errno) {
  347. ret := syscall(SYS_shmat, key, addr, transmute(i16) flags)
  348. return errno_unwrap(ret, rawptr, uintptr)
  349. }
  350. shmctl_ds :: proc "contextless" (key: Key, cmd: IPC_Cmd, buf: ^Shmid_DS) -> (Errno) {
  351. ret := syscall(SYS_shmctl, key, cmd, buf)
  352. return Errno(-ret)
  353. }
  354. shmctl_info :: proc "contextless" (key: Key, cmd: IPC_Cmd, buf: ^Shm_Info) -> (int, Errno) {
  355. ret := syscall(SYS_shmctl, key, cmd, buf)
  356. return errno_unwrap(ret, int)
  357. }
  358. /*
  359. SystemV shared memory control.
  360. Available since Linux 2.0.
  361. */
  362. shmctl :: proc {shmctl_ds, shmctl_info}
  363. /*
  364. Allocate a new file descriptor that refers to the same file as the one provided.
  365. Available since Linux 1.0.
  366. */
  367. dup :: proc "contextless" (fd: Fd) -> (Fd, Errno) {
  368. ret := syscall(SYS_dup, fd)
  369. return errno_unwrap(ret, Fd)
  370. }
  371. /*
  372. Adjust an existing file descriptor to point to the same file as `old`.
  373. Available since Linux 1.0.
  374. On ARM64 available since Linux 2.6.27.
  375. */
  376. dup2 :: proc "contextless" (old: Fd, new: Fd) -> (Fd, Errno) {
  377. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  378. ret := syscall(SYS_dup3, old, new, 0)
  379. return errno_unwrap(ret, Fd)
  380. } else {
  381. ret := syscall(SYS_dup2, old, new)
  382. return errno_unwrap(ret, Fd)
  383. }
  384. }
  385. /*
  386. Wait until the next signal is delivered.
  387. Available since Linux 1.0.
  388. On ARM64 available since Linux 2.6.16.
  389. */
  390. pause :: proc "contextless" () {
  391. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  392. syscall(SYS_ppoll, 0, 0, 0, 0)
  393. } else {
  394. syscall(SYS_pause)
  395. }
  396. }
  397. /*
  398. High-resolution sleep.
  399. Available since Linux 2.0.
  400. */
  401. nanosleep :: proc "contextless" (req: ^Time_Spec, rem: ^Time_Spec) -> (Errno) {
  402. ret := syscall(SYS_nanosleep, req, rem)
  403. return Errno(-ret)
  404. }
  405. /*
  406. Get the value of an internal timer.
  407. Available since Linux 1.0.
  408. */
  409. getitimer :: proc "contextless" (which: ITimer_Which, cur: ^ITimer_Val) -> (Errno) {
  410. ret := syscall(SYS_getitimer, cur)
  411. return Errno(-ret)
  412. }
  413. /*
  414. Set an alarm clock for delivery of a signal.
  415. Available since Linux 1.0.
  416. */
  417. alarm :: proc "contextless" (seconds: u32) -> u32 {
  418. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  419. new := ITimer_Val { value = { seconds = cast(int) seconds } }
  420. old := ITimer_Val {}
  421. syscall(SYS_setitimer, ITimer_Which.REAL, &new, &old)
  422. return u32(old.value.seconds) + u32(new.value.microseconds)
  423. } else {
  424. return cast(u32) syscall(SYS_alarm, seconds)
  425. }
  426. }
  427. /*
  428. Set the value of an internal timer.
  429. Available since Linux 1.0.
  430. */
  431. setitimer :: proc "contextless" (which: ITimer_Which, new: ^ITimer_Val, old: ^ITimer_Val) -> (Errno) {
  432. ret := syscall(SYS_getitimer, new, old)
  433. return Errno(-ret)
  434. }
  435. /*
  436. Returns the thread group ID of the current process.
  437. Note that it doesn't return the pid, despite it's name.
  438. Available since Linux 1.0.
  439. */
  440. getpid :: proc "contextless" () -> Pid {
  441. return cast(Pid) syscall(SYS_getpid)
  442. }
  443. /*
  444. Transfer the data between file descriptors.
  445. Available since Linux 2.2.
  446. On 32-bit platforms available since Linux 2.6.
  447. */
  448. sendfile :: proc "contextless" (out_fd: Fd, in_fd: Fd, offset: ^i64, count: uint) -> (int, Errno) {
  449. when size_of(int) == 8 {
  450. ret := syscall(SYS_sendfile, out_fd, in_fd, offset, count)
  451. return errno_unwrap(ret, int)
  452. } else {
  453. ret := syscall(SYS_sendfile64, out_fd, in_fd, offset, count)
  454. return errno_unwrap(ret, int)
  455. }
  456. }
  457. /*
  458. Create a socket file descriptor.
  459. Available since Linux 2.0.
  460. */
  461. socket :: proc "contextless" (domain: Address_Family, socktype: Socket_Type, sockflags: Socket_FD_Flags, protocol: Protocol) -> (Fd, Errno) {
  462. sock_type_flags: int = cast(int) socktype | cast(int) transmute(i32) sockflags
  463. ret := syscall(SYS_socket, domain, sock_type_flags, protocol)
  464. return errno_unwrap(ret, Fd)
  465. }
  466. /*
  467. Connect the socket to the address.
  468. Available since Linux 2.0.
  469. */
  470. connect :: proc "contextless" (sock: Fd, addr: ^$T) -> (Errno)
  471. where
  472. T == Sock_Addr_In ||
  473. T == Sock_Addr_In6 ||
  474. T == Sock_Addr_Un ||
  475. T == Sock_Addr_Any
  476. {
  477. ret := syscall(SYS_connect, sock, addr, size_of(T))
  478. return Errno(-ret)
  479. }
  480. /*
  481. Accept a pending connection or block until new connection appears.
  482. Depends on Sock_FD_Flags of the `sock` parameter.
  483. Available since Linux 2.0.
  484. */
  485. accept :: proc "contextless" (sock: Fd, addr: ^$T, sockflags: Socket_FD_Flags = {}) -> (Fd, Errno)
  486. where
  487. T == Sock_Addr_In ||
  488. T == Sock_Addr_In6 ||
  489. T == Sock_Addr_Un ||
  490. T == Sock_Addr_Any
  491. {
  492. addr_len: i32 = size_of(T)
  493. ret := syscall(SYS_accept4, sock, addr, &addr_len, transmute(i32) sockflags)
  494. return errno_unwrap(ret, Fd)
  495. }
  496. // TODO(flysand): Rewrite recvfrom and sendto to use default parameters
  497. recvfrom :: proc "contextless" (sock: Fd, buf: []u8, flags: Socket_Msg, addr: ^$T) -> (int, Errno)
  498. where
  499. T == Sock_Addr_In ||
  500. T == Sock_Addr_In6 ||
  501. T == Sock_Addr_Un ||
  502. T == Sock_Addr_Any
  503. {
  504. addr_len: i32 = size_of(T)
  505. ret := syscall(SYS_recvfrom, sock, raw_data(buf), len(buf), transmute(i32) flags, addr, &addr_len)
  506. return errno_unwrap(ret, int)
  507. }
  508. @private
  509. recv_noaddr :: proc "contextless" (sock: Fd, buf: []u8, flags: Socket_Msg) -> (int, Errno) {
  510. ret := syscall(SYS_recvfrom, sock, raw_data(buf), len(buf), transmute(i32) flags, cast(rawptr) nil, cast(uintptr) 0)
  511. return errno_unwrap(ret, int)
  512. }
  513. sendto :: proc "contextless" (sock: Fd, buf: []u8, flags: Socket_Msg, addr: ^$T) -> (int, Errno)
  514. where
  515. T == Sock_Addr_In ||
  516. T == Sock_Addr_In6 ||
  517. T == Sock_Addr_Un ||
  518. T == Sock_Addr_Any
  519. {
  520. ret := syscall(SYS_sendto, sock, raw_data(buf), len(buf), transmute(i32) flags, addr, size_of(T))
  521. return errno_unwrap(ret, int)
  522. }
  523. @private
  524. send_noaddr :: proc "contextless" (sock: Fd, buf: []u8, flags: Socket_Msg) -> (int, Errno) {
  525. ret := syscall(SYS_sendto, sock, raw_data(buf), len(buf), transmute(i32) flags, cast(rawptr) nil, cast(uintptr) 0)
  526. return errno_unwrap(ret, int)
  527. }
  528. /*
  529. Receive a message from a socket.
  530. Available since Linux 2.0.
  531. */
  532. recv :: proc {recvfrom, recv_noaddr}
  533. /*
  534. Send a message through a socket.
  535. Available since Linux 2.0.
  536. */
  537. send :: proc {sendto, send_noaddr}
  538. /*
  539. Send a message on a socket.
  540. Available since Linux 2.0.
  541. */
  542. sendmsg :: proc "contextless" (sock: Fd, msghdr: ^Msg_Hdr, flags: Socket_Msg) -> (int, Errno) {
  543. ret := syscall(SYS_sendmsg, sock, msghdr, transmute(i32) flags)
  544. return errno_unwrap(ret, int)
  545. }
  546. /*
  547. Receive a message on a socket.
  548. Available since Linux 2.0.
  549. */
  550. recvmsg :: proc "contextless" (sock: Fd, msghdr: ^Msg_Hdr, flags: Socket_Msg) -> (int, Errno) {
  551. ret := syscall(SYS_recvmsg, sock, msghdr, transmute(i32) flags)
  552. return errno_unwrap(ret, int)
  553. }
  554. /*
  555. Shutdown a socket.
  556. Available since Linux 2.0.
  557. */
  558. shutdown :: proc "contextless" (sock: Fd, how: Shutdown_How) -> (Errno) {
  559. ret := syscall(SYS_shutdown, sock, how)
  560. return Errno(-ret)
  561. }
  562. /*
  563. Bind a socket to the given local address.
  564. Available since Linux 2.0.
  565. */
  566. bind :: proc "contextless" (sock: Fd, addr: ^$T) -> (Errno)
  567. where
  568. T == Sock_Addr_In ||
  569. T == Sock_Addr_In6 ||
  570. T == Sock_Addr_Un ||
  571. T == Sock_Addr_Any
  572. {
  573. ret := syscall(SYS_bind, sock, addr, size_of(T))
  574. return Errno(-ret)
  575. }
  576. /*
  577. Marks the socket as a socket that listen to connections using accept(2).
  578. Available since Linux 2.0.
  579. */
  580. listen :: proc "contextless" (sock: Fd, queue_len: i32) -> (Errno) {
  581. ret := syscall(SYS_listen, sock, queue_len)
  582. return Errno(-ret)
  583. }
  584. /*
  585. Get socket name (aka it's bound address).
  586. Available since Linux 2.0.
  587. */
  588. getsockname :: proc "contextless" (sock: Fd, addr: ^Sock_Addr_Any) -> (Errno) {
  589. addr_len := size_of(Sock_Addr_Any)
  590. ret := syscall(SYS_getsockname, sock, addr, &addr_len)
  591. return Errno(-ret)
  592. }
  593. /*
  594. Get the name of the connected peer socket.
  595. Available since Linux 2.0.
  596. */
  597. getpeername :: proc "contextless" (sock: Fd, addr: ^Sock_Addr_Any) -> (Errno) {
  598. addr_len := size_of(Sock_Addr_Any)
  599. ret := syscall(SYS_getpeername, sock, addr, &addr_len)
  600. return Errno(-ret)
  601. }
  602. /*
  603. Create a pair of connected sockets.
  604. Available since Linux 2.0.
  605. */
  606. socketpair :: proc "contextless" (domain: Protocol_Family, type: Socket_Type, proto: Protocol, pair: ^[2]Fd) -> (Errno) {
  607. ret := syscall(SYS_socketpair, domain, type, proto, pair)
  608. return Errno(-ret)
  609. }
  610. // TODO(flysand): the parameters are the same, maybe there's a way to make it into a single proc, sacrificing type
  611. // safety slightly
  612. // TODO(flysand): add ability to specify slices
  613. setsockopt_base :: proc "contextless" (sock: Fd, level: int, opt: int, val: $T) -> (Errno)
  614. where
  615. intrinsics.type_is_pointer(T) ||
  616. intrinsics.type_is_multi_pointer(T)
  617. {
  618. val_data := val
  619. val_size := size_of(intrinsics.type_elem_type(T))
  620. ret := syscall(SYS_setsockopt, sock, level, opt, val_data, val_size)
  621. return Errno(-ret)
  622. }
  623. setsockopt_sock :: proc "contextless" (sock: Fd, level: Socket_API_Level_Sock, opt: Socket_Option, val: $T) -> (Errno)
  624. where
  625. intrinsics.type_is_pointer(T) ||
  626. intrinsics.type_is_multi_pointer(T)
  627. {
  628. return setsockopt_base(sock, cast(int) level, cast(int) opt, val)
  629. }
  630. setsockopt_tcp :: proc "contextless" (sock: Fd, level: Socket_API_Level_TCP, opt: Socket_TCP_Option, val: $T) -> (Errno)
  631. where
  632. intrinsics.type_is_pointer(T) ||
  633. intrinsics.type_is_multi_pointer(T)
  634. {
  635. return setsockopt_base(sock, cast(int) level, cast(int) opt, val)
  636. }
  637. setsockopt_udp :: proc "contextless" (sock: Fd, level: Socket_API_Level_UDP, opt: Socket_UDP_Option, val: $T) -> (Errno)
  638. where
  639. intrinsics.type_is_pointer(T) ||
  640. intrinsics.type_is_multi_pointer(T)
  641. {
  642. return setsockopt_base(sock, cast(int) level, cast(int) opt, val)
  643. }
  644. /*
  645. Set socket option for a given socket API level.
  646. Available since Linux 2.0.
  647. */
  648. setsockopt :: proc {
  649. setsockopt_sock,
  650. setsockopt_tcp,
  651. setsockopt_udp,
  652. setsockopt_base,
  653. }
  654. getsockopt_base :: proc "contextless" (sock: Fd, level: int, opt: Socket_Option, val: $T) -> (int, Errno)
  655. where
  656. intrinsics.type_is_pointer(T) ||
  657. intrinsics.type_is_multi_pointer(T)
  658. {
  659. val_data := val
  660. val_size := size_of(T)
  661. ret := syscall(SYS_getsockopt, sock, level, opt, val_data, cast(rawptr) &val_size)
  662. return val_size, Errno(-ret)
  663. }
  664. getsockopt_sock :: proc "contextless" (sock: Fd, level: Socket_API_Level_Sock, opt: Socket_Option, val: ^$T) -> (int, Errno)
  665. where
  666. intrinsics.type_is_pointer(T) ||
  667. intrinsics.type_is_multi_pointer(T)
  668. {
  669. return getsockopt_base(sock, cast(int) level, cast(int) opt, val)
  670. }
  671. getsockopt_tcp :: proc "contextless" (sock: Fd, level: Socket_API_Level_TCP, opt: Socket_TCP_Option, val: ^$T) -> (int, Errno)
  672. where
  673. intrinsics.type_is_pointer(T) ||
  674. intrinsics.type_is_multi_pointer(T)
  675. {
  676. return getsockopt_base(sock, cast(int) level, cast(int) opt, val)
  677. }
  678. getsockopt_udp :: proc "contextless" (sock: Fd, level: Socket_API_Level_UDP, opt: Socket_UDP_Option, val: ^$T) -> (int, Errno)
  679. where
  680. intrinsics.type_is_pointer(T) ||
  681. intrinsics.type_is_multi_pointer(T)
  682. {
  683. return getsockopt_base(sock, cast(int) level, cast(int) opt, val)
  684. }
  685. /*
  686. Get socket option for a given socket API level.
  687. Available since Linux 2.0.
  688. */
  689. getsockopt :: proc {
  690. getsockopt_sock,
  691. getsockopt_tcp,
  692. getsockopt_udp,
  693. getsockopt_base,
  694. }
  695. /*
  696. Creates a copy of the running process.
  697. Available since Linux 1.0.
  698. */
  699. fork :: proc "contextless" () -> (Pid, Errno) {
  700. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  701. ret := syscall(SYS_clone, u64(Signal.SIGCHLD), cast(rawptr) nil, cast(rawptr) nil, cast(rawptr) nil, u64(0))
  702. return errno_unwrap(ret, Pid)
  703. } else {
  704. ret := syscall(SYS_fork)
  705. return errno_unwrap(ret, Pid)
  706. }
  707. }
  708. /*
  709. Create a child process and block parent.
  710. Available since Linux 2.2.
  711. */
  712. vfork :: proc "contextless" () -> Pid {
  713. when ODIN_ARCH != .arm64 && ODIN_ARCH != .riscv64 {
  714. return Pid(syscall(SYS_vfork))
  715. } else {
  716. return Pid(syscall(SYS_clone, Signal.SIGCHLD))
  717. }
  718. }
  719. /*
  720. Replace the current process with another program.
  721. Available since Linux 1.0.
  722. On ARM64 available since Linux 3.19.
  723. */
  724. execve :: proc "contextless" (name: cstring, argv: [^]cstring, envp: [^]cstring) -> (Errno) {
  725. when ODIN_ARCH != .arm64 && ODIN_ARCH != .riscv64 {
  726. ret := syscall(SYS_execve, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp)
  727. return Errno(-ret)
  728. } else {
  729. ret := syscall(SYS_execveat, AT_FDCWD, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, i32(0))
  730. return Errno(-ret)
  731. }
  732. }
  733. /*
  734. Exit the thread with a given exit code.
  735. Available since Linux 1.0.
  736. */
  737. exit :: proc "contextless" (code: i32) -> ! {
  738. syscall(SYS_exit, code)
  739. unreachable()
  740. }
  741. /*
  742. Wait for the process to change state.
  743. Available since Linux 1.0.
  744. */
  745. wait4 :: proc "contextless" (pid: Pid, status: ^u32, options: Wait_Options, rusage: ^RUsage) -> (Pid, Errno) {
  746. ret := syscall(SYS_wait4, pid, status, transmute(u32) options, rusage)
  747. return errno_unwrap(ret, Pid)
  748. }
  749. /*
  750. See `wait4` for documentation.
  751. */
  752. waitpid :: wait4
  753. /*
  754. Send signal to a process.
  755. Available since Linux 1.0.
  756. */
  757. kill :: proc "contextless" (pid: Pid, signal: Signal) -> (Errno) {
  758. ret := syscall(SYS_kill, pid, signal)
  759. return Errno(-ret)
  760. }
  761. /*
  762. Get system information.
  763. Available since Linux 1.0.
  764. */
  765. uname :: proc "contextless" (uts_name: ^UTS_Name) -> (Errno) {
  766. ret := syscall(SYS_uname, uts_name)
  767. return Errno(-ret)
  768. }
  769. /*
  770. Get a SystemV semaphore set identifier.
  771. Available since Linux 2.0.
  772. */
  773. semget :: proc "contextless" (key: Key, n: i32, flags: IPC_Flags) -> (Key, Errno) {
  774. ret := syscall(SYS_semget, key, n, transmute(i16) flags)
  775. return errno_unwrap(ret, Key)
  776. }
  777. /*
  778. SystemV semaphore operations.
  779. Available since Linux 2.0.
  780. */
  781. semop :: proc "contextless" (key: Key, ops: []Sem_Buf) -> (Errno) {
  782. when ODIN_ARCH != .i386 {
  783. ret := syscall(SYS_semop, key, raw_data(ops), len(ops))
  784. return Errno(-ret)
  785. } else {
  786. // Note(flysand): Max time limit, let's not worry about nanoseconds...
  787. max_timespec := Time_Spec {
  788. time_sec = max(uint),
  789. time_nsec = 0,
  790. }
  791. ret := syscall(SYS_semtimedop_time64, key, raw_data(ops), len(ops), &max_timespec)
  792. return Errno(-ret)
  793. }
  794. }
  795. semctl3 :: proc "contextless" (key: Key, semnum: i32, cmd: IPC_Cmd) -> (int, Errno) {
  796. ret := syscall(SYS_semctl, key, semnum, cmd)
  797. return errno_unwrap(ret, int)
  798. }
  799. semctl4 :: proc "contextless" (key: Key, semnum: i32, cmd: IPC_Cmd, semun: ^Sem_Un) -> (int, Errno) {
  800. ret := syscall(SYS_semctl, key, semnum, cmd, semun)
  801. return errno_unwrap(ret, int)
  802. }
  803. /*
  804. SystemV semaphore control operations.
  805. Available since Linux 2.0.
  806. */
  807. semctl :: proc {semctl3, semctl4}
  808. /*
  809. SystemV shared memory operations.
  810. Available since Linux 2.0.
  811. */
  812. shmdt :: proc "contextless" (shmaddr: rawptr) -> (Errno) {
  813. ret := syscall(SYS_shmdt, shmaddr)
  814. return Errno(-ret)
  815. }
  816. /*
  817. Get SystemV message queue identifier.
  818. Available since Linux 2.0.
  819. */
  820. msgget :: proc "contextless" (key: Key, flags: IPC_Flags) -> (Key, Errno) {
  821. ret := syscall(SYS_msgget, key, transmute(i16) flags)
  822. return errno_unwrap(ret, Key)
  823. }
  824. /*
  825. Send message to a SystemV message queue.
  826. Available since Linux 2.0.
  827. */
  828. msgsnd :: proc "contextless" (key: Key, buf: rawptr, size: int, flags: IPC_Flags) -> (Errno) {
  829. ret := syscall(SYS_msgsnd, key, buf, size, transmute(i16) flags)
  830. return Errno(-ret)
  831. }
  832. /*
  833. Receive a message from a SystemV message queue.
  834. Available since Linux 2.0.
  835. */
  836. msgrcv :: proc "contextless" (key: Key, buf: rawptr, size: int, type: uint, flags: IPC_Flags) -> (int, Errno) {
  837. ret := syscall(SYS_msgrcv, key, buf, size, type, transmute(i16) flags)
  838. return errno_unwrap(ret, int)
  839. }
  840. /*
  841. SystemV message control operations.
  842. Available since Linux 2.0.
  843. */
  844. msgctl :: proc "contextless" (key: Key, cmd: IPC_Cmd, buf: ^Msqid_DS) -> (int, Errno) {
  845. ret := syscall(SYS_msgctl, key, cmd, buf)
  846. return errno_unwrap(ret, int)
  847. }
  848. fcntl_dupfd :: proc "contextless" (fd: Fd, cmd: FCntl_Command_DUPFD, newfd: Fd) -> (Fd, Errno) {
  849. ret := syscall(SYS_fcntl, fd, cmd, newfd)
  850. return errno_unwrap(ret, Fd)
  851. }
  852. fcntl_dupfd_cloexec :: proc "contextless" (fd: Fd, cmd: FCntl_Command_DUPFD_CLOEXEC, newfd: Fd) -> (Fd, Errno) {
  853. ret := syscall(SYS_fcntl, fd, cmd, newfd)
  854. return errno_unwrap(ret, Fd)
  855. }
  856. fcntl_getfd :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GETFD) -> (Fd, Errno) {
  857. ret := syscall(SYS_fcntl, fd, cmd)
  858. return errno_unwrap(ret, Fd)
  859. }
  860. fcntl_setfd :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SETFD, newfd: Fd) -> (Errno) {
  861. ret := syscall(SYS_fcntl, fd, cmd, newfd)
  862. return Errno(-ret)
  863. }
  864. fcntl_getfl :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GETFL) -> (Open_Flags, Errno) {
  865. ret := syscall(SYS_fcntl, fd, cmd)
  866. return errno_unwrap(u32(ret), Open_Flags, Open_Flags)
  867. }
  868. fcntl_setfl :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SETFL, flags: Open_Flags) -> (Errno) {
  869. ret := syscall(SYS_fcntl, fd, cmd, transmute(u32) flags)
  870. return Errno(-ret)
  871. }
  872. fcntl_setlk :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SETLK, lock: ^FLock) -> (Errno) {
  873. when size_of(int) == 4 {
  874. ret := syscall(SYS_fcntl64, fd, cmd, lock)
  875. return Errno(-ret)
  876. } else {
  877. ret := syscall(SYS_fcntl, fd, cmd, lock)
  878. return Errno(-ret)
  879. }
  880. }
  881. fcntl_setlkw :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SETLKW, lock: ^FLock) -> (Errno) {
  882. when size_of(int) == 4 {
  883. ret := syscall(SYS_fcntl64, fd, cmd, lock)
  884. return Errno(-ret)
  885. } else {
  886. ret := syscall(SYS_fcntl, fd, cmd, lock)
  887. return Errno(-ret)
  888. }
  889. }
  890. fcntl_getlk :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GETLK, lock: ^FLock) -> (Errno) {
  891. when size_of(int) == 4 {
  892. ret := syscall(SYS_fcntl64, fd, cmd, lock)
  893. return Errno(-ret)
  894. } else {
  895. ret := syscall(SYS_fcntl, fd, cmd, lock)
  896. return Errno(-ret)
  897. }
  898. }
  899. fcntl_getown_ex :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GETOWN_EX, owner: ^F_Owner) -> (Errno) {
  900. ret := syscall(SYS_fcntl, fd, cmd, owner)
  901. return Errno(-ret)
  902. }
  903. fcntl_setown_ex :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SETOWN_EX, owner: ^F_Owner) -> (Errno) {
  904. ret := syscall(SYS_fcntl, fd, cmd, owner)
  905. return Errno(-ret)
  906. }
  907. fcntl_getsig :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GETSIG) -> (Signal, Errno) {
  908. ret := syscall(SYS_fcntl, fd, cmd)
  909. return errno_unwrap(ret, Signal)
  910. }
  911. fcntl_setsig :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SETSIG, sig: Signal) -> (Errno) {
  912. ret := syscall(SYS_fcntl, fd, cmd, sig)
  913. return Errno(-ret)
  914. }
  915. fcntl_setlease :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SETLEASE, lease: FD_Lease) -> (Errno) {
  916. ret := syscall(SYS_fcntl, fd, cmd, lease)
  917. return Errno(-ret)
  918. }
  919. fcntl_getlease :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GETLEASE) -> (FD_Lease, Errno) {
  920. ret := syscall(SYS_fcntl, fd, cmd)
  921. return errno_unwrap(ret, FD_Lease)
  922. }
  923. fcntl_notify :: proc "contextless" (fd: Fd, cmd: FCntl_Command_NOTIFY, notifications: FD_Notifications) -> (Errno) {
  924. ret := syscall(SYS_fcntl, fd, cmd)
  925. return Errno(-ret)
  926. }
  927. fcntl_setpipe_sz :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SETPIPE_SZ, sz: i32) -> (i32, Errno) {
  928. ret := syscall(SYS_fcntl, fd, cmd, sz)
  929. return errno_unwrap(ret, i32)
  930. }
  931. fcntl_getpipe_sz :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GETPIPE_SZ) -> (i32, Errno) {
  932. ret := syscall(SYS_fcntl, fd, cmd)
  933. return errno_unwrap(ret, i32)
  934. }
  935. fcntl_add_seals :: proc "contextless" (fd: Fd, cmd: FCntl_Command_ADD_SEALS, seal: Seal) -> (Errno) {
  936. ret := syscall(SYS_fcntl, fd, cmd, transmute(i32) seal)
  937. return Errno(-ret)
  938. }
  939. fcntl_get_seals :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GET_SEALS) -> (Seal, Errno) {
  940. ret := syscall(SYS_fcntl, fd, cmd)
  941. return errno_unwrap(i32(ret), Seal, Seal)
  942. }
  943. fcntl_get_rw_hint :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GET_RW_HINT, hint: ^RW_Hint) -> (Errno) {
  944. ret := syscall(SYS_fcntl, fd, cmd, hint)
  945. return Errno(-ret)
  946. }
  947. fcntl_set_rw_hint :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SET_RW_HINT, hint: ^RW_Hint) -> (Errno) {
  948. ret := syscall(SYS_fcntl, fd, cmd, hint)
  949. return Errno(-ret)
  950. }
  951. fcntl_get_file_rw_hint :: proc "contextless" (fd: Fd, cmd: FCntl_Command_GET_FILE_RW_HINT, hint: ^RW_Hint) -> (Errno) {
  952. ret := syscall(SYS_fcntl, fd, cmd, hint)
  953. return Errno(-ret)
  954. }
  955. fcntl_set_file_rw_hint :: proc "contextless" (fd: Fd, cmd: FCntl_Command_SET_FILE_RW_HINT, hint: ^RW_Hint) -> (Errno) {
  956. ret := syscall(SYS_fcntl, fd, cmd, hint)
  957. return Errno(-ret)
  958. }
  959. fcntl :: proc {
  960. fcntl_dupfd,
  961. fcntl_dupfd_cloexec,
  962. fcntl_getfd,
  963. fcntl_setfd,
  964. fcntl_getfl,
  965. fcntl_setfl,
  966. fcntl_setlk,
  967. fcntl_setlkw,
  968. fcntl_getlk,
  969. fcntl_getown_ex,
  970. fcntl_setown_ex,
  971. fcntl_getsig,
  972. fcntl_setsig,
  973. fcntl_setlease,
  974. fcntl_getlease,
  975. fcntl_notify,
  976. fcntl_setpipe_sz,
  977. fcntl_getpipe_sz,
  978. fcntl_add_seals,
  979. fcntl_get_seals,
  980. fcntl_get_rw_hint,
  981. fcntl_set_rw_hint,
  982. fcntl_get_file_rw_hint,
  983. fcntl_set_file_rw_hint,
  984. }
  985. /*
  986. Apply or remove advisory lock on an open file.
  987. Available since Linux 2.0.
  988. */
  989. flock :: proc "contextless" (fd: Fd, operation: FLock_Op) -> (Errno) {
  990. ret := syscall(SYS_flock, fd, transmute(i32) operation)
  991. return Errno(-ret)
  992. }
  993. /*
  994. Sync state of the file with the storage device.
  995. Available since Linux 1.0.
  996. */
  997. fsync :: proc "contextless" (fd: Fd) -> (Errno) {
  998. ret := syscall(SYS_fsync, fd)
  999. return Errno(-ret)
  1000. }
  1001. /*
  1002. Synchronize the state of the file with the storage device. Similar to `fsync`,
  1003. except does not flush the metadata.
  1004. Available since Linux 2.0.
  1005. */
  1006. fdatasync :: proc "contextless" (fd: Fd) -> (Errno) {
  1007. ret := syscall(SYS_fdatasync, fd)
  1008. return Errno(-ret)
  1009. }
  1010. /*
  1011. Truncate a file to specified length.
  1012. Available since Linux 1.0.
  1013. On 32-bit architectures available since Linux 2.4.
  1014. */
  1015. truncate :: proc "contextless" (name: cstring, length: i64) -> (Errno) {
  1016. when ODIN_ARCH == .arm32 {
  1017. ret := syscall(SYS_truncate64, cast(rawptr) name, 0, compat64_arg_pair(length))
  1018. return Errno(-ret)
  1019. } else when size_of(int) == 4 {
  1020. ret := syscall(SYS_truncate64, cast(rawptr) name, compat64_arg_pair(length))
  1021. return Errno(-ret)
  1022. } else {
  1023. ret := syscall(SYS_truncate, cast(rawptr) name, compat64_arg_pair(length))
  1024. return Errno(-ret)
  1025. }
  1026. }
  1027. /*
  1028. Truncate a file specified by file descriptor to specified length.
  1029. On 32-bit architectures available since 2.4.
  1030. */
  1031. ftruncate :: proc "contextless" (fd: Fd, length: i64) -> (Errno) {
  1032. when ODIN_ARCH == .arm32 {
  1033. ret := syscall(SYS_ftruncate64, fd, 0, compat64_arg_pair(length))
  1034. return Errno(-ret)
  1035. } else when size_of(int) == 4 {
  1036. ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length))
  1037. return Errno(-ret)
  1038. } else {
  1039. ret := syscall(SYS_ftruncate, fd, compat64_arg_pair(length))
  1040. return Errno(-ret)
  1041. }
  1042. }
  1043. /*
  1044. Retrieve the contents of the directory specified by dirfd.
  1045. Returns the number of bytes written.
  1046. Available since Linux 2.4.
  1047. */
  1048. getdents :: proc "contextless" (dirfd: Fd, buf: []u8) -> (int, Errno) {
  1049. ret := syscall(SYS_getdents64, dirfd, raw_data(buf), len(buf))
  1050. return errno_unwrap(ret, int)
  1051. }
  1052. /*
  1053. Get current working directory.
  1054. Available since Linux 1.0.
  1055. */
  1056. getcwd :: proc "contextless" (buf: []u8) -> (int, Errno) {
  1057. ret := syscall(SYS_getcwd, raw_data(buf), len(buf))
  1058. return errno_unwrap(ret, int)
  1059. }
  1060. /*
  1061. Change working directory to the directory specified by path.
  1062. Available since Linux 1.0.
  1063. */
  1064. chdir :: proc "contextless" (path: cstring) -> (Errno) {
  1065. ret := syscall(SYS_chdir, cast(rawptr) path)
  1066. return Errno(-ret)
  1067. }
  1068. /*
  1069. Change working directory to the directory specified by dirfd.
  1070. Available since Linux 1.0.
  1071. */
  1072. fchdir :: proc "contextless" (fd: Fd) -> (Errno) {
  1073. ret := syscall(SYS_fchdir, fd)
  1074. return Errno(-ret)
  1075. }
  1076. /*
  1077. Rename (move) the file.
  1078. Available since Linux 1.0.
  1079. On ARM64 available since Linux 2.6.16.
  1080. */
  1081. rename :: proc "contextless" (old: cstring, new: cstring) -> (Errno) {
  1082. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1083. ret := syscall(SYS_renameat, AT_FDCWD, cast(rawptr) old, AT_FDCWD, cast(rawptr) new)
  1084. return Errno(-ret)
  1085. } else {
  1086. ret := syscall(SYS_rename, cast(rawptr) old, cast(rawptr) new)
  1087. return Errno(-ret)
  1088. }
  1089. }
  1090. /*
  1091. Creates a directory.
  1092. Available since Linux 1.0.
  1093. On ARM64 available since Linux 2.6.16.
  1094. */
  1095. mkdir :: proc "contextless" (name: cstring, mode: Mode) -> (Errno) {
  1096. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1097. ret := syscall(SYS_mkdirat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode)
  1098. return Errno(-ret)
  1099. } else {
  1100. ret := syscall(SYS_mkdir, cast(rawptr) name, transmute(u32) mode)
  1101. return Errno(-ret)
  1102. }
  1103. }
  1104. /*
  1105. Remove a directory specified by name.
  1106. Available since Linux 1.0.
  1107. On ARM64 available since Linux 2.6.16.
  1108. */
  1109. rmdir :: proc "contextless" (name: cstring) -> (Errno) {
  1110. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1111. ret := syscall(SYS_unlinkat, AT_FDCWD, cast(rawptr) name, transmute(i32) FD_Flags{.REMOVEDIR})
  1112. return Errno(-ret)
  1113. } else {
  1114. ret := syscall(SYS_rmdir, cast(rawptr) name)
  1115. return Errno(-ret)
  1116. }
  1117. }
  1118. /*
  1119. Create a file.
  1120. Available since Linux 1.0.
  1121. On ARM64 available since Linux 2.6.16.
  1122. */
  1123. creat :: proc "contextless" (name: cstring, mode: Mode) -> (Fd, Errno) {
  1124. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1125. return openat(AT_FDCWD, name, {.CREAT, .WRONLY,.TRUNC}, mode)
  1126. } else {
  1127. ret := syscall(SYS_creat, cast(rawptr) name, transmute(u32) mode)
  1128. return errno_unwrap(ret, Fd)
  1129. }
  1130. }
  1131. /*
  1132. Create a hard link on a file.
  1133. Available since Linux 1.0.
  1134. On ARM64 available since Linux 2.6.16.
  1135. */
  1136. link :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
  1137. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1138. ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath, 0)
  1139. return Errno(-ret)
  1140. } else {
  1141. ret := syscall(SYS_link, cast(rawptr) target, cast(rawptr) linkpath)
  1142. return Errno(-ret)
  1143. }
  1144. }
  1145. /*
  1146. Delete a name, and possible a file it refers to.
  1147. Available since Linux 1.0.
  1148. On ARM64 available since Linux 2.6.16.
  1149. */
  1150. unlink :: proc "contextless" (name: cstring) -> (Errno) {
  1151. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1152. ret := syscall(SYS_unlinkat, AT_FDCWD, cast(rawptr) name, 0)
  1153. return Errno(-ret)
  1154. } else {
  1155. ret := syscall(SYS_unlink, cast(rawptr) name)
  1156. return Errno(-ret)
  1157. }
  1158. }
  1159. /*
  1160. Create a symbolic link.
  1161. Available since Linux 1.0.
  1162. On arm64 available since Linux 2.6.16.
  1163. */
  1164. symlink :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
  1165. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1166. ret := syscall(SYS_symlinkat, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath)
  1167. return Errno(-ret)
  1168. } else {
  1169. ret := syscall(SYS_symlink, cast(rawptr) target, cast(rawptr) linkpath)
  1170. return Errno(-ret)
  1171. }
  1172. }
  1173. /*
  1174. Read the value of a symbolic link.
  1175. Available since Linux 1.0.
  1176. On arm64 available since Linux 2.6.16.
  1177. */
  1178. readlink :: proc "contextless" (name: cstring, buf: []u8) -> (int, Errno) {
  1179. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1180. ret := syscall(SYS_readlinkat, AT_FDCWD, cast(rawptr) name, raw_data(buf), len(buf))
  1181. return errno_unwrap(ret, int)
  1182. } else {
  1183. ret := syscall(SYS_readlink, cast(rawptr) name, raw_data(buf), len(buf))
  1184. return errno_unwrap(ret, int)
  1185. }
  1186. }
  1187. /*
  1188. Change file permissions.
  1189. Available since Linux 1.0.
  1190. On ARM64 available since Linux 2.6.16.
  1191. */
  1192. chmod :: proc "contextless" (name: cstring, mode: Mode) -> (Errno) {
  1193. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1194. ret := syscall(SYS_fchmodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode)
  1195. return Errno(-ret)
  1196. } else {
  1197. ret := syscall(SYS_chmod, cast(rawptr) name, transmute(u32) mode)
  1198. return Errno(-ret)
  1199. }
  1200. }
  1201. /*
  1202. Change file permissions through a file descriptor.
  1203. Available since Linux 1.0.
  1204. */
  1205. fchmod :: proc "contextless" (fd: Fd, mode: Mode) -> (Errno) {
  1206. ret := syscall(SYS_fchmod, fd, transmute(u32) mode)
  1207. return Errno(-ret)
  1208. }
  1209. /*
  1210. Change ownership of a file.
  1211. Available since Linux 2.2.
  1212. On 32-bit architectures available since Linux 2.4.
  1213. On ARM64 available since Linux 2.6.16.
  1214. */
  1215. chown :: proc "contextless" (name: cstring, uid: Uid, gid: Gid) -> (Errno) {
  1216. when size_of(int) == 4 {
  1217. ret := syscall(SYS_chown32, cast(rawptr) name, uid, gid)
  1218. return Errno(-ret)
  1219. } else when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1220. ret := syscall(SYS_fchownat, AT_FDCWD, cast(rawptr) name, uid, gid, 0)
  1221. return Errno(-ret)
  1222. } else {
  1223. ret := syscall(SYS_chown, cast(rawptr) name, uid, gid)
  1224. return Errno(-ret)
  1225. }
  1226. }
  1227. /*
  1228. Change ownership of a file by file descriptor.
  1229. Available since Linux 1.0.
  1230. On 32-bit architecvtures available since Linux 2.4.
  1231. */
  1232. fchown :: proc "contextless" (fd: Fd, uid: Uid, gid: Gid) -> (Errno) {
  1233. when size_of(int) == 4 {
  1234. ret := syscall(SYS_fchown32, fd, uid, gid)
  1235. return Errno(-ret)
  1236. } else {
  1237. ret := syscall(SYS_fchown, fd, uid, gid)
  1238. return Errno(-ret)
  1239. }
  1240. }
  1241. /*
  1242. Change ownership of a file. Unlike chown, if a file is a symlink dooesn't dereference it.
  1243. Available since Linux 1.0.
  1244. On 32-bit architectures available since Linux 2.4.
  1245. On ARM64 available since Linux 2.6.16.
  1246. */
  1247. lchown :: proc "contextless" (name: cstring, uid: Uid, gid: Gid) -> (Errno) {
  1248. when size_of(int) == 4 {
  1249. ret := syscall(SYS_lchown32, cast(rawptr) name, uid, gid)
  1250. return Errno(-ret)
  1251. } else when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1252. ret := syscall(SYS_fchownat, AT_FDCWD, cast(rawptr) name, uid, gid, transmute(i32) FD_Flags{.SYMLINK_NOFOLLOW})
  1253. return Errno(-ret)
  1254. } else {
  1255. ret := syscall(SYS_lchown, cast(rawptr) name, uid, gid)
  1256. return Errno(-ret)
  1257. }
  1258. }
  1259. /*
  1260. Set file mode creation mask.
  1261. Available since Linux 1.0.
  1262. */
  1263. umask :: proc "contextless" (mask: Mode) -> Mode {
  1264. ret := syscall(SYS_umask, transmute(u32) mask)
  1265. return transmute(Mode) cast(u32) ret
  1266. }
  1267. /*
  1268. Get current time.
  1269. Available since Linux 1.0.
  1270. */
  1271. gettimeofday :: proc "contextless" (tv: ^Time_Val) -> (Errno) {
  1272. ret := syscall(SYS_gettimeofday, tv, rawptr(nil))
  1273. return Errno(-ret)
  1274. }
  1275. /*
  1276. Get limits on resources.
  1277. Available since Linux 1.0.
  1278. */
  1279. getrlimit :: proc "contextless" (kind: RLimit_Kind, resource: ^RLimit) -> (Errno) {
  1280. ret := syscall(SYS_getrlimit, kind, resource)
  1281. return Errno(-ret)
  1282. }
  1283. /*
  1284. Get resource usage.
  1285. Available since Linux 1.0.
  1286. */
  1287. getrusage :: proc "contextless" (who: RUsage_Who, rusage: ^RUsage) -> (Errno) {
  1288. ret := syscall(SYS_getrusage, who, rusage)
  1289. return Errno(-ret)
  1290. }
  1291. /*
  1292. Get information about the system.
  1293. Available since Linux 1.0.
  1294. */
  1295. sysinfo :: proc "contextless" (sysinfo: ^Sys_Info) -> (Errno) {
  1296. ret := syscall(SYS_sysinfo, sysinfo)
  1297. return Errno(-ret)
  1298. }
  1299. /*
  1300. Get current process times.
  1301. Available since Linux 1.0.
  1302. */
  1303. times :: proc "contextless" (tms: ^Tms) -> (Errno) {
  1304. ret := syscall(SYS_times, cast(rawptr) tms)
  1305. return Errno(-ret)
  1306. }
  1307. ptrace_traceme :: proc "contextless" (rq: PTrace_Traceme_Type) -> (Errno) {
  1308. ret := syscall(SYS_ptrace, rq)
  1309. return Errno(-ret)
  1310. }
  1311. ptrace_peek :: proc "contextless" (rq: PTrace_Peek_Type, pid: Pid, addr: uintptr) -> (uint, Errno) {
  1312. res: uint = ---
  1313. ret := syscall(SYS_ptrace, rq, pid, addr, &res)
  1314. return res, Errno(-ret)
  1315. }
  1316. ptrace_poke :: proc "contextless" (rq: PTrace_Poke_Type, pid: Pid, addr: uintptr, data: uint) -> (Errno) {
  1317. ret := syscall(SYS_ptrace, rq, pid, addr, data)
  1318. return Errno(-ret)
  1319. }
  1320. ptrace_getregs :: proc "contextless" (rq: PTrace_Getregs_Type, pid: Pid, buf: ^User_Regs) -> (Errno) {
  1321. ret := syscall(SYS_ptrace, rq, pid, 0, buf)
  1322. return Errno(-ret)
  1323. }
  1324. ptrace_getfpregs :: proc "contextless" (rq: PTrace_Getfpregs_Type, pid: Pid, buf: ^User_FP_Regs) -> (Errno) {
  1325. ret := syscall(SYS_ptrace, rq, pid, 0, buf)
  1326. return Errno(-ret)
  1327. }
  1328. ptrace_getfpxregs :: proc "contextless" (rq: PTrace_Getfpxregs_Type, pid: Pid, buf: ^User_FPX_Regs) -> (Errno) {
  1329. ret := syscall(SYS_ptrace, rq, pid, 0, buf)
  1330. return Errno(-ret)
  1331. }
  1332. ptrace_setregs :: proc "contextless" (rq: PTrace_Setregs_Type, pid: Pid, buf: ^User_Regs) -> (Errno) {
  1333. ret := syscall(SYS_ptrace, rq, pid, 0, buf)
  1334. return Errno(-ret)
  1335. }
  1336. ptrace_setfpregs :: proc "contextless" (rq: PTrace_Setfpregs_Type, pid: Pid, buf: ^User_FP_Regs) -> (Errno) {
  1337. ret := syscall(SYS_ptrace, rq, pid, 0, buf)
  1338. return Errno(-ret)
  1339. }
  1340. ptrace_setfpxregs :: proc "contextless" (rq: PTrace_Setfpxregs_Type, pid: Pid, buf: ^User_FPX_Regs) -> (Errno) {
  1341. ret := syscall(SYS_ptrace, rq, pid, 0, buf)
  1342. return Errno(-ret)
  1343. }
  1344. ptrace_getregset :: proc "contextless" (rq: PTrace_Getregset_Type, pid: Pid, note: PTrace_Note_Type, buf: ^IO_Vec) -> (Errno) {
  1345. ret := syscall(SYS_ptrace, rq, pid, note, buf)
  1346. return Errno(-ret)
  1347. }
  1348. ptrace_setregset :: proc "contextless" (rq: PTrace_Setregset_Type, pid: Pid, note: PTrace_Note_Type, buf: ^IO_Vec) -> (Errno) {
  1349. ret := syscall(SYS_ptrace, rq, pid, note, buf)
  1350. return Errno(-ret)
  1351. }
  1352. ptrace_getsiginfo :: proc "contextless" (rq: PTrace_Getsiginfo_Type, pid: Pid, si: ^Sig_Info) -> (Errno) {
  1353. ret := syscall(SYS_ptrace, rq, pid, si, rawptr(nil))
  1354. return Errno(-ret)
  1355. }
  1356. ptrace_peeksiginfo :: proc "contextless" (rq: PTrace_Peeksiginfo_Type, pid: Pid, si: ^Sig_Info) -> (Errno) {
  1357. ret := syscall(SYS_ptrace, rq, pid, si, rawptr(nil))
  1358. return Errno(-ret)
  1359. }
  1360. ptrace_getsigmask :: proc "contextless" (rq: PTrace_Getsigmask_Type, pid: Pid, sigmask: ^Sig_Set) -> (Errno) {
  1361. ret := syscall(SYS_ptrace, rq, pid, size_of(Sig_Set), sigmask)
  1362. return Errno(-ret)
  1363. }
  1364. ptrace_setsigmask :: proc "contextless" (rq: PTrace_Setsigmask_Type, pid: Pid, sigmask: ^Sig_Set) -> (Errno) {
  1365. ret := syscall(SYS_ptrace, rq, pid, size_of(Sig_Set), sigmask)
  1366. return Errno(-ret)
  1367. }
  1368. ptrace_setoptions :: proc "contextless" (rq: PTrace_Setoptions_Type, pid: Pid, options: PTrace_Options) -> (Errno) {
  1369. ret := syscall(SYS_ptrace, rq, pid, 0, transmute(u32) options)
  1370. return Errno(-ret)
  1371. }
  1372. ptrace_geteventmsg :: proc "contextless" (rq: PTrace_Geteventmsg_Type, pid: Pid, msg: ^uint) -> (Errno) {
  1373. ret := syscall(SYS_ptrace, rq, pid, msg, rawptr(nil))
  1374. return Errno(-ret)
  1375. }
  1376. ptrace_cont :: proc "contextless" (rq: PTrace_Cont_Type, pid: Pid, sig: Signal) -> (Errno) {
  1377. ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
  1378. return Errno(-ret)
  1379. }
  1380. ptrace_singlestep :: proc "contextless" (rq: PTrace_Singlestep_Type, pid: Pid, sig: Signal) -> (Errno) {
  1381. ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
  1382. return Errno(-ret)
  1383. }
  1384. ptrace_syscall :: proc "contextless" (rq: PTrace_Syscall_Type, pid: Pid, sig: Signal) -> (Errno) {
  1385. ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
  1386. return Errno(-ret)
  1387. }
  1388. ptrace_sysemu :: proc "contextless" (rq: PTrace_Sysemu_Type, pid: Pid, sig: Signal) -> (Errno) {
  1389. ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
  1390. return Errno(-ret)
  1391. }
  1392. ptrace_sysemu_singlestep :: proc "contextless" (rq: PTrace_Sysemu_Singlestep_Type, pid: Pid, sig: Signal) -> (Errno) {
  1393. ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
  1394. return Errno(-ret)
  1395. }
  1396. ptrace_listen :: proc "contextless" (rq: PTrace_Listen_Type, pid: Pid) -> (Errno) {
  1397. ret := syscall(SYS_ptrace, rq, pid, 0, rawptr(nil))
  1398. return Errno(-ret)
  1399. }
  1400. ptrace_interrupt :: proc "contextless" (rq: PTrace_Interrupt_Type, pid: Pid) -> (Errno) {
  1401. ret := syscall(SYS_ptrace, rq, pid, 0, rawptr(nil))
  1402. return Errno(-ret)
  1403. }
  1404. ptrace_attach :: proc "contextless" (rq: PTrace_Attach_Type, pid: Pid) -> (Errno) {
  1405. ret := syscall(SYS_ptrace, rq, pid, 0, rawptr(nil))
  1406. return Errno(-ret)
  1407. }
  1408. ptrace_seize :: proc "contextless" (rq: PTrace_Seize_Type, pid: Pid, opt: PTrace_Options) -> (Errno) {
  1409. ret := syscall(SYS_ptrace, rq, pid, 0, transmute(u32) opt, rawptr(nil))
  1410. return Errno(-ret)
  1411. }
  1412. // TODO(flysand): ptrace_seccomp_get_filter
  1413. ptrace_detach :: proc "contextless" (rq: PTrace_Detach_Type, pid: Pid, sig: Signal) -> (Errno) {
  1414. ret := syscall(SYS_ptrace, rq, pid, 0, sig)
  1415. return Errno(-ret)
  1416. }
  1417. // TODO(flysand): ptrace_get_thread_area
  1418. // TODO(flysand): ptrace_set_thread_area
  1419. // TODO(flysand): ptrace_get_syscall_info
  1420. /*
  1421. Trace process.
  1422. */
  1423. ptrace :: proc {
  1424. ptrace_traceme,
  1425. ptrace_peek,
  1426. ptrace_poke,
  1427. ptrace_getregs,
  1428. ptrace_getfpregs,
  1429. ptrace_getfpxregs,
  1430. ptrace_setregs,
  1431. ptrace_setfpregs,
  1432. ptrace_setfpxregs,
  1433. ptrace_getregset,
  1434. ptrace_setregset,
  1435. ptrace_getsiginfo,
  1436. ptrace_peeksiginfo,
  1437. ptrace_getsigmask,
  1438. ptrace_setsigmask,
  1439. ptrace_setoptions,
  1440. ptrace_geteventmsg,
  1441. ptrace_cont,
  1442. ptrace_singlestep,
  1443. ptrace_syscall,
  1444. ptrace_sysemu,
  1445. ptrace_sysemu_singlestep,
  1446. ptrace_listen,
  1447. ptrace_interrupt,
  1448. ptrace_attach,
  1449. ptrace_seize,
  1450. ptrace_detach,
  1451. }
  1452. /*
  1453. Get real user ID.
  1454. Available since Linux 1.0.
  1455. On 32-bit platforms available since Linux 2.4.
  1456. */
  1457. getuid :: proc "contextless" () -> Uid {
  1458. when size_of(int) == 8 {
  1459. return cast(Uid) syscall(SYS_getuid)
  1460. } else {
  1461. return cast(Uid) syscall(SYS_getuid32)
  1462. }
  1463. }
  1464. /*
  1465. Read or clear kernel message ring buffer.
  1466. Available since Linux 1.0.
  1467. */
  1468. syslog :: proc "contextless" (act: Syslog_Action, buf: []u8) -> (int, Errno) {
  1469. ret := syscall(SYS_syslog, act, raw_data(buf), len(buf))
  1470. return errno_unwrap(ret, int)
  1471. }
  1472. /*
  1473. Get real group ID.
  1474. Available since Linux 1.0.
  1475. On 32-bit platforms available since Linux 2.4.
  1476. */
  1477. getgid :: proc "contextless" () -> Gid {
  1478. when size_of(int) == 8 {
  1479. return cast(Gid) syscall(SYS_getgid)
  1480. } else {
  1481. return cast(Gid) syscall(SYS_getgid32)
  1482. }
  1483. }
  1484. /*
  1485. Set effective User ID.
  1486. Available since Linux 1.0.
  1487. On 32-bit platforms available since Linux 2.4.
  1488. */
  1489. @(require_results)
  1490. setuid :: proc "contextless" (uid: Uid) -> (Errno) {
  1491. when size_of(int) == 8 {
  1492. ret := syscall(SYS_setuid, uid)
  1493. return Errno(-ret)
  1494. } else {
  1495. ret := syscall(SYS_setuid32, uid)
  1496. return Errno(-ret)
  1497. }
  1498. }
  1499. /*
  1500. Set effective group id.
  1501. If the process is privileged also sets real group id.
  1502. Available since Linux 1.0.
  1503. On 32-bit platforms available since Linux 2.4.
  1504. */
  1505. @(require_results)
  1506. setgid :: proc "contextless" (gid: Gid) -> (Errno) {
  1507. when size_of(int) == 8 {
  1508. ret := syscall(SYS_setgid, gid)
  1509. return Errno(-ret)
  1510. } else {
  1511. ret := syscall(SYS_setgid32, gid)
  1512. return Errno(-ret)
  1513. }
  1514. }
  1515. /*
  1516. Get effective user ID.
  1517. Available since Linux 1.0.
  1518. On 32-bit platforms available since Linux 2.4.
  1519. */
  1520. geteuid :: proc "contextless" () -> Uid {
  1521. when size_of(int) == 8 {
  1522. return cast(Uid) syscall(SYS_geteuid)
  1523. } else {
  1524. return cast(Uid) syscall(SYS_geteuid32)
  1525. }
  1526. }
  1527. /*
  1528. Get effective group ID.
  1529. Available since Linux 1.0.
  1530. On 32-bit platforms available since Linux 2.4.
  1531. */
  1532. getegid :: proc "contextless" () -> Gid {
  1533. when size_of(int) == 8 {
  1534. return cast(Gid) syscall(SYS_getegid)
  1535. } else {
  1536. return cast(Gid) syscall(SYS_getegid32)
  1537. }
  1538. }
  1539. /*
  1540. Set process group.
  1541. Available since Linux 1.0.
  1542. */
  1543. setpgid :: proc "contextless" (pid: Pid, pgid: Pid) -> (Errno) {
  1544. ret := syscall(SYS_setpgid, pid, pgid)
  1545. return Errno(-ret)
  1546. }
  1547. /*
  1548. Get the parent process ID.
  1549. Available since Linux 1.0.
  1550. */
  1551. getppid :: proc "contextless" () -> Pid {
  1552. return cast(Pid) syscall(SYS_getppid)
  1553. }
  1554. /*
  1555. Get process group.
  1556. Available since Linux 1.0.
  1557. */
  1558. getpgrp :: proc "contextless" () -> (Pid, Errno) {
  1559. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1560. ret := syscall(SYS_getpgid, 0)
  1561. return errno_unwrap(ret, Pid)
  1562. } else {
  1563. ret := syscall(SYS_getpgrp)
  1564. return errno_unwrap(ret, Pid)
  1565. }
  1566. }
  1567. /*
  1568. Create a session and set the process group ID.
  1569. Available since Linux 2.0.
  1570. */
  1571. setsid :: proc "contextless" () -> (Pid, Errno) {
  1572. ret := syscall(SYS_setsid)
  1573. return errno_unwrap(ret, Pid)
  1574. }
  1575. /*
  1576. Set real and/or effective user id.
  1577. If any of the arguments is -1, the corresponding id is not changed.
  1578. Available since Linux 1.0.
  1579. On 32-bit platforms available since Linux 2.4.
  1580. */
  1581. @(require_results)
  1582. setreuid :: proc "contextless" (real: Uid, effective: Uid) -> (Errno) {
  1583. when size_of(int) == 8 {
  1584. ret := syscall(SYS_setreuid, real, effective)
  1585. return Errno(-ret)
  1586. } else {
  1587. ret := syscall(SYS_setreuid32, real, effective)
  1588. return Errno(-ret)
  1589. }
  1590. }
  1591. /*
  1592. Set real and/or effective group id.
  1593. If any of the arguments is -1, the corresponding id is not changed.
  1594. Available since Linux 1.0.
  1595. On 32-bit platforms available since Linux 2.4.
  1596. */
  1597. @(require_results)
  1598. setregid :: proc "contextless" (real: Gid, effective: Gid) -> (Errno) {
  1599. when size_of(int) == 8 {
  1600. ret := syscall(SYS_setregid, real, effective)
  1601. return Errno(-ret)
  1602. } else {
  1603. ret := syscall(SYS_setregid32, real, effective)
  1604. return Errno(-ret)
  1605. }
  1606. }
  1607. /*
  1608. Get supplementary group IDs.
  1609. Available since Linux 1.0.
  1610. On 32-bit platforms available since Linux 2.4.
  1611. */
  1612. getgroups :: proc "contextless" (gids: []Gid) -> (int, Errno) {
  1613. when size_of(int) == 8 {
  1614. ret := syscall(SYS_getgroups, len(gids), raw_data(gids))
  1615. return errno_unwrap(ret, int)
  1616. } else {
  1617. ret := syscall(SYS_getgroups32, len(gids), raw_data(gids))
  1618. return errno_unwrap(ret, int)
  1619. }
  1620. }
  1621. /*
  1622. Set supplementary group IDs.
  1623. Available since Linux 1.0.
  1624. On 32-bit platforms available since Linux 2.4.
  1625. */
  1626. setgroups :: proc "contextless" (gids: []Gid) -> (Errno) {
  1627. when size_of(int) == 8 {
  1628. ret := syscall(SYS_setgroups, len(gids), raw_data(gids))
  1629. return Errno(-ret)
  1630. } else {
  1631. ret := syscall(SYS_setgroups32, len(gids), raw_data(gids))
  1632. return Errno(-ret)
  1633. }
  1634. }
  1635. /*
  1636. Set real, effective and/or saved user id.
  1637. If any of the arguments is -1, the corresponding id is not changed.
  1638. Available since Linux 2.2.
  1639. On 32-bit platforms available since Linux 2.4.
  1640. */
  1641. @(require_results)
  1642. setresuid :: proc "contextless" (real: Uid, effective: Uid, saved: Uid) -> (Errno) {
  1643. when size_of(int) == 8 {
  1644. ret := syscall(SYS_setresuid, real, effective, saved)
  1645. return Errno(-ret)
  1646. } else {
  1647. ret := syscall(SYS_setresuid32, real, effective, saved)
  1648. return Errno(-ret)
  1649. }
  1650. }
  1651. /*
  1652. Get real, effective and saved user id.
  1653. Available since Linux 2.2.
  1654. On 32-bit platforms available since Linux 2.4.
  1655. */
  1656. getresuid :: proc "contextless" (real: ^Uid, effective: ^Uid, saved: ^Uid) -> (Errno) {
  1657. when size_of(int) == 8 {
  1658. ret := syscall(SYS_getresuid, cast(rawptr) real, cast(rawptr) effective, cast(rawptr) saved)
  1659. return Errno(-ret)
  1660. } else {
  1661. ret := syscall(SYS_getresuid32, cast(rawptr) real, cast(rawptr) effective, cast(rawptr) saved)
  1662. return Errno(-ret)
  1663. }
  1664. }
  1665. /*
  1666. Set real, effective and/or saved group id.
  1667. If any of the arguments is -1, the corresponding id is not changed.
  1668. Available since Linux 2.2.
  1669. On 32-bit platforms available since Linux 2.4.
  1670. */
  1671. @(require_results)
  1672. setresgid :: proc "contextless" (real: Gid, effective: Gid, saved: Uid) -> (Errno) {
  1673. when size_of(int) == 8 {
  1674. ret := syscall(SYS_setresgid, real, effective, saved)
  1675. return Errno(-ret)
  1676. } else {
  1677. ret := syscall(SYS_setresgid32, real, effective, saved)
  1678. return Errno(-ret)
  1679. }
  1680. }
  1681. /*
  1682. Get real, effective and saved group id.
  1683. Available since Linux 2.2.
  1684. On 32-bit platforms available since Linux 2.4.
  1685. */
  1686. getresgid :: proc "contextless" (real: ^Gid, effective: ^Gid, saved: ^Gid) -> (Errno) {
  1687. when size_of(int) == 8 {
  1688. ret := syscall(SYS_getresgid, cast(rawptr) real, cast(rawptr) effective, cast(rawptr) saved)
  1689. return Errno(-ret)
  1690. } else {
  1691. ret := syscall(SYS_getresgid32, cast(rawptr) real, cast(rawptr) effective, cast(rawptr) saved)
  1692. return Errno(-ret)
  1693. }
  1694. }
  1695. /*
  1696. Get process group.
  1697. Available since Linux 1.0.
  1698. */
  1699. getpgid :: proc "contextless" (pid: Pid) -> (Pid, Errno) {
  1700. ret := syscall(SYS_getpgid, pid)
  1701. return errno_unwrap(ret, Pid)
  1702. }
  1703. /*
  1704. Get session ID of the calling process.
  1705. Available since Linux 2.0.
  1706. */
  1707. getsid :: proc "contextless" (pid: Pid) -> (Pid, Errno) {
  1708. ret := syscall(SYS_getsid, pid)
  1709. return errno_unwrap(ret, Pid)
  1710. }
  1711. // TODO(flysand): capget
  1712. // TODO(flysand): capset
  1713. /*
  1714. Examine pending signals.
  1715. Available since Linux 2.2.
  1716. */
  1717. rt_sigpending :: proc "contextless" (sigs: ^Sig_Set) -> Errno {
  1718. ret := syscall(SYS_rt_sigpending, sigs, size_of(Sig_Set))
  1719. return Errno(-ret)
  1720. }
  1721. /*
  1722. Synchronously wait for queued signals.
  1723. Available since Linux 2.2.
  1724. */
  1725. rt_sigtimedwait :: proc "contextless" (sigs: ^Sig_Set, info: ^Sig_Info, time_sus: ^Time_Spec) -> (Signal, Errno) {
  1726. ret := syscall(SYS_rt_sigtimedwait, sigs, info, time_sus, size_of(Sig_Set))
  1727. return errno_unwrap(ret, Signal)
  1728. }
  1729. /*
  1730. Send signal information to a process.
  1731. Available since Linux 2.2.
  1732. */
  1733. rt_sigqueueinfo :: proc "contextless" (pid: Pid, sig: Signal, si: ^Sig_Info) -> (Errno) {
  1734. ret := syscall(SYS_rt_sigqueueinfo, pid, sig, si)
  1735. return Errno(-ret)
  1736. }
  1737. /*
  1738. Replace the signal mask for a value with the new mask until a signal is received.
  1739. Available since Linux 2.2.
  1740. */
  1741. rt_sigsuspend :: proc "contextless" (sigset: ^Sig_Set) -> Errno {
  1742. ret := syscall(SYS_rt_sigsuspend, sigset, size_of(Sig_Set))
  1743. return Errno(-ret)
  1744. }
  1745. /*
  1746. Set or get signal stack context.
  1747. Available since Linux 2.2.
  1748. */
  1749. sigaltstack :: proc "contextless" (stack: ^Sig_Stack, old_stack: ^Sig_Stack) -> (Errno) {
  1750. ret := syscall(SYS_sigaltstack, stack, old_stack)
  1751. return Errno(-ret)
  1752. }
  1753. /*
  1754. Create a special or ordinary file.
  1755. `mode` parameter contains both the the file mode and the type of the node to create.
  1756. -> Add one of S_IFSOCK, S_IFBLK, S_IFFIFO, S_IFCHR to mode.
  1757. Available since Linux 1.0.
  1758. On ARM64 available since Linux 2.6.16.
  1759. */
  1760. mknod :: proc "contextless" (name: cstring, mode: Mode, dev: Dev) -> (Errno) {
  1761. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  1762. ret := syscall(SYS_mknodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode, cast(uint) dev)
  1763. return Errno(-ret)
  1764. } else {
  1765. ret := syscall(SYS_mknod, cast(rawptr) name, transmute(u32) mode, cast(uint) dev)
  1766. return Errno(-ret)
  1767. }
  1768. }
  1769. /*
  1770. Set the process execution domain.
  1771. Available since Linux 1.2.
  1772. */
  1773. personality :: proc "contextless" (personality: uint) -> (uint, Errno) {
  1774. ret := syscall(SYS_personality, personality)
  1775. return errno_unwrap(ret, uint)
  1776. }
  1777. // TODO(flysand): ustat
  1778. /*
  1779. Query information about filesystem.
  1780. Available since Linux 1.0.
  1781. For 32-bit systems a different syscall is used that became available since 2.6.
  1782. */
  1783. statfs :: proc "contextless" (path: cstring, statfs: ^Stat_FS) -> (Errno) {
  1784. when size_of(int) == 8 {
  1785. ret := syscall(SYS_statfs, transmute(uintptr) path, statfs)
  1786. return Errno(-ret)
  1787. } else {
  1788. ret := syscall(SYS_statfs64, cast(rawptr) path, size_of(Stat_FS), statfs)
  1789. return Errno(-ret)
  1790. }
  1791. }
  1792. /*
  1793. Query information about filesystem by file descriptor.
  1794. Available since Linux 1.0.
  1795. For 32-bit systems a different syscall is used that became available since 2.6.
  1796. */
  1797. fstatfs :: proc "contextless" (fd: Fd, statfs: ^Stat_FS) -> (Errno) {
  1798. when size_of(int) == 8 {
  1799. ret := syscall(SYS_fstatfs, fd, statfs)
  1800. return Errno(-ret)
  1801. } else {
  1802. ret := syscall(SYS_fstatfs64, fd, size_of(Stat_FS), statfs)
  1803. return Errno(-ret)
  1804. }
  1805. }
  1806. // TODO(flysand): sysfs
  1807. /*
  1808. Get priority on user, process group or process.
  1809. Available since Linux 1.0.
  1810. */
  1811. getpriority :: proc "contextless" (which: Priority_Which, who: i32) -> (i32, Errno) {
  1812. ret := syscall(SYS_getpriority, which, who)
  1813. prio, err := errno_unwrap(ret, i32)
  1814. // NOTE(flysand): getpriority will return `20 - priority` to avoid returning
  1815. // negative priorities as errors
  1816. prio = 20 - prio
  1817. return prio, err
  1818. }
  1819. /*
  1820. Set priority on user, process group or process.
  1821. Available since Linux 1.0.
  1822. */
  1823. setpriority :: proc "contextless" (which: Priority_Which, who: i32, prio: i32) -> (Errno) {
  1824. ret := syscall(SYS_setpriority, which, who, prio)
  1825. return Errno(-ret)
  1826. }
  1827. // TODO(flysand): sched_setparam
  1828. // TODO(flysand): sched_getparam
  1829. // TODO(flysand): sched_setscheduler
  1830. // TODO(flysand): sched_getscheduler
  1831. // TODO(flysand): sched_get_priority_max
  1832. // TODO(flysand): sched_get_priority_min
  1833. // TODO(flysand): sched_rr_get_interval
  1834. /*
  1835. Lock and memory.
  1836. Available since Linux 2.0.
  1837. If flags specified, available since Linux 4.4.
  1838. */
  1839. mlock :: proc "contextless" (addr: rawptr, size: uint, flags: MLock_Flags = {}) -> (Errno) {
  1840. // Pretty darn recent syscall, better call simpler version if we can
  1841. if flags > {} {
  1842. ret := syscall(SYS_mlock2, addr, size, transmute(i32) flags)
  1843. return Errno(-ret)
  1844. } else {
  1845. ret := syscall(SYS_mlock, addr, size)
  1846. return Errno(-ret)
  1847. }
  1848. }
  1849. /*
  1850. Unlock memory.
  1851. Available since Linux 2.0.
  1852. */
  1853. munlock :: proc "contextless" (addr: rawptr, size: uint) -> (Errno) {
  1854. ret := syscall(SYS_munlock, addr, size)
  1855. return Errno(-ret)
  1856. }
  1857. /*
  1858. Lock all memory.
  1859. Available since Linux 2.0.
  1860. */
  1861. mlockall :: proc "contextless" (flags: MLock_Flags = {}) -> (Errno) {
  1862. ret := syscall(SYS_mlockall, transmute(i32) flags)
  1863. return Errno(-ret)
  1864. }
  1865. /*
  1866. Unlock all memory.
  1867. Available since Linux 2.0.
  1868. */
  1869. munlockall :: proc "contextless" () -> (Errno) {
  1870. ret := syscall(SYS_munlockall)
  1871. return Errno(-ret)
  1872. }
  1873. /*
  1874. Virtually hangup the current terminal
  1875. Available since Linux 1.0.
  1876. */
  1877. vhangup :: proc "contextless" () -> (Errno) {
  1878. ret := syscall(SYS_vhangup)
  1879. return Errno(-ret)
  1880. }
  1881. when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 {
  1882. /*
  1883. Get or set local descriptor table
  1884. Available since Linux 2.1
  1885. */
  1886. modify_ldt :: proc "contextless" (func: i32, ptr: rawptr, bytecount: uint) -> (int, Errno) {
  1887. ret := syscall(SYS_modify_ldt, func, ptr, bytecount)
  1888. return errno_unwrap(ret, int)
  1889. }
  1890. }
  1891. /*
  1892. Change the root mount
  1893. Available since Linux 2.3.41
  1894. */
  1895. pivot_root :: proc "contextless" (new_root: cstring, old_root: cstring) -> (Errno) {
  1896. ret := syscall(SYS_pivot_root, cast(rawptr) new_root, cast(rawptr) old_root)
  1897. return Errno(-ret)
  1898. }
  1899. // TODO(flysand): _sysctl
  1900. // Deprecated and discouraged
  1901. /*
  1902. Operations on a process or thread
  1903. Available since Linux 2.1.57
  1904. */
  1905. prctl :: proc "contextless" (op: i32, args: ..uint) -> (Errno) {
  1906. assert_contextless(len(args) <= 4)
  1907. ret := syscall(SYS_prctl, op, args[0], args[1], args[2], args[3])
  1908. return Errno(-ret)
  1909. }
  1910. when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 {
  1911. /*
  1912. Set architecture-specific thread state
  1913. Available since Linux 2.6.19
  1914. */
  1915. arch_prctl :: proc "contextless" (op: i32, addr: uint) -> (Errno) {
  1916. ret := syscall(SYS_arch_prctl, op, addr)
  1917. return Errno(-ret)
  1918. }
  1919. }
  1920. /*
  1921. Display or set the kernel time variables
  1922. Available since Linux 1.0.
  1923. */
  1924. adjtimex :: proc "contextless" (buf: ^Timex) -> (Clock_State, Errno) {
  1925. ret := syscall(SYS_adjtimex)
  1926. return errno_unwrap(ret, Clock_State)
  1927. }
  1928. /*
  1929. Set limits on resources.
  1930. Available since Linux 1.0.
  1931. */
  1932. setrlimit :: proc "contextless" (kind: RLimit_Kind, resource: ^RLimit) -> (Errno) {
  1933. ret := syscall(SYS_setrlimit, kind, resource)
  1934. return Errno(-ret)
  1935. }
  1936. /*
  1937. Change root directory
  1938. Available since Linux 1.0.
  1939. */
  1940. chroot :: proc "contextless" (pathname: cstring) -> (Errno) {
  1941. ret := syscall(SYS_chroot, cast(rawptr) pathname)
  1942. return Errno(-ret)
  1943. }
  1944. /*
  1945. Commit filesystem caches to disk
  1946. Available since Linux 1.0.
  1947. */
  1948. sync :: proc "contextless" () -> (Errno) {
  1949. ret := syscall(SYS_sync)
  1950. return Errno(-ret)
  1951. }
  1952. /*
  1953. Switch process accounting on or off
  1954. Available since Linux 2.3.23
  1955. */
  1956. acct :: proc "contextless" (filename: cstring) -> (Errno) {
  1957. ret := syscall(SYS_acct, cast(rawptr) filename)
  1958. return Errno(-ret)
  1959. }
  1960. /*
  1961. Set Time
  1962. Available since Linux 1.0
  1963. */
  1964. settimeofday :: proc "contextless" (tv: ^Time_Val) -> (Errno) {
  1965. ret := syscall(SYS_settimeofday, tv, rawptr(nil))
  1966. return Errno(-ret)
  1967. }
  1968. /*
  1969. Mount filesystem
  1970. Available since Linux 1.0
  1971. */
  1972. mount :: proc "contextless" (source: cstring, target: cstring, filesystemtype: cstring, mountflags: Mount_Flags, data: rawptr) -> (Errno) {
  1973. ret := syscall(SYS_mount, cast(rawptr) source, cast(rawptr) target, cast(rawptr) filesystemtype, transmute(uint) mountflags, data)
  1974. return Errno(-ret)
  1975. }
  1976. /*
  1977. Unmount filesystem
  1978. Available since Linux 2.1
  1979. */
  1980. umount2 :: proc "contextless" (target: cstring, flags: Umount2_Flags) -> (Errno) {
  1981. ret := syscall(SYS_umount2, cast(rawptr) target, transmute(u32) flags)
  1982. return Errno(-ret)
  1983. }
  1984. /*
  1985. Start swapping to file/device
  1986. Available since Linux 2.0
  1987. */
  1988. swapon :: proc "contextless" (path: cstring, swapflags: Swap_Flags) -> (Errno) {
  1989. ret := syscall(SYS_swapon, cast(rawptr) path, transmute(u32) swapflags)
  1990. return Errno(-ret)
  1991. }
  1992. /*
  1993. Stop swapping to file/device
  1994. Available since Linux 2.0
  1995. */
  1996. swapoff :: proc "contextless" (path: cstring) -> (Errno) {
  1997. ret := syscall(SYS_swapoff, cast(rawptr) path)
  1998. return Errno(-ret)
  1999. }
  2000. /*
  2001. Reboot or enable/disable Ctrl-Alt-Del
  2002. Available since Linux 1.0
  2003. */
  2004. reboot :: proc "contextless" (magic: Reboot_Magic, magic2: Reboot_Magic, op: Reboot_Operation, arg: rawptr) -> (Errno) {
  2005. ret := syscall(SYS_reboot, cast(i32)magic, cast(i32)magic2, cast(i32)op, arg)
  2006. return Errno(-ret)
  2007. }
  2008. /*
  2009. Set hostname.
  2010. Note: to get the host name, use `uname` syscall.
  2011. Available since Linux 1.0.
  2012. */
  2013. sethostname :: proc "contextless" (hostname: string) -> (Errno) {
  2014. ret := syscall(SYS_sethostname, raw_data(hostname), len(hostname))
  2015. return Errno(-ret)
  2016. }
  2017. /*
  2018. Set domain name.
  2019. Note: to get the domain name, use `uname` syscall.
  2020. Available since Linux 2.2.
  2021. */
  2022. setdomainname :: proc "contextless" (name: string) -> (Errno) {
  2023. ret := syscall(SYS_setdomainname, raw_data(name), len(name))
  2024. return Errno(-ret)
  2025. }
  2026. // TODO(flysand): iopl
  2027. // deprecated
  2028. when ODIN_ARCH == .amd64 || ODIN_ARCH == .i386 {
  2029. /*
  2030. Set port input/output permissions
  2031. Available since Linux 1.0
  2032. */
  2033. ioperm :: proc "contextless" (form: u32, num: u32, turn_on: i32) -> (Errno) {
  2034. ret := syscall(SYS_ioperm, form, num, turn_on)
  2035. return Errno(-ret)
  2036. }
  2037. }
  2038. /*
  2039. Load a kernel module
  2040. Available since Linux 2.2
  2041. */
  2042. init_module :: proc "contextless" (module_image: rawptr, size: u32, param_values: cstring) -> (Errno) {
  2043. ret := syscall(SYS_init_module, module_image, size, cast(rawptr) param_values)
  2044. return Errno(-ret)
  2045. }
  2046. /*
  2047. Unload a kernel module
  2048. Available since Linux 2.2
  2049. */
  2050. delete_module :: proc "contextless" (name: cstring, flags: u32) -> (Errno) {
  2051. ret := syscall(SYS_delete_module, cast(rawptr) name, flags)
  2052. return Errno(-ret)
  2053. }
  2054. /*
  2055. Manipulate disk quotas
  2056. Available since Linux 2.0
  2057. */
  2058. quotactl :: proc "contextless" (op: i32, special: cstring, id: i32, addr: rawptr) -> (Errno) {
  2059. ret := syscall(SYS_quotactl, op, cast(rawptr) special, id, addr)
  2060. return Errno(-ret)
  2061. }
  2062. // TODO(flysand): nfsservctl
  2063. /// No longer present after 3.1
  2064. // TODO(flysand): getpmsg
  2065. // TODO(flysand): putpmsg
  2066. // TODO(flysand): afs_syscall
  2067. // TODO(flysand): tuxcall
  2068. // TODO(flysand): security
  2069. /*
  2070. Returns the thread ID of the current process
  2071. This is what the kernel calls "pid".
  2072. Let me insert a tiny rant here, this terminology is confusing:
  2073. sometimes pid refers to a thread, and other times it refers
  2074. to a thread group (process group?)
  2075. Anyway, this syscall is available since Linux 1.0
  2076. */
  2077. gettid :: proc "contextless" () -> Pid {
  2078. return cast(Pid) syscall(SYS_gettid)
  2079. }
  2080. /*
  2081. Initiate a file readahead into page cache
  2082. Available since Linux 2.1
  2083. */
  2084. readahead :: proc "contextless" (fd: Fd, offset: int, count: uint) -> (Errno) {
  2085. ret := syscall(SYS_readahead, fd, offset, count)
  2086. return Errno(-ret)
  2087. }
  2088. /*
  2089. Set an extended attribute value
  2090. Available since Linux 2.6.25
  2091. */
  2092. setxattr :: proc "contextless" (path: cstring, name: cstring, value: rawptr, size: uint, flags: i32) -> (Errno) {
  2093. ret := syscall(SYS_setxattr, cast(rawptr) path, cast(rawptr) name, value, size, flags)
  2094. return Errno(-ret)
  2095. }
  2096. /*
  2097. Set an extended attribute value
  2098. Available since Linux 2.6.25
  2099. */
  2100. lsetxattr :: proc "contextless" (path: cstring, name: cstring, value: rawptr, size: uint, flags: i32) -> (Errno) {
  2101. ret := syscall(SYS_lsetxattr, cast(rawptr) path, cast(rawptr) name, value, size, flags)
  2102. return Errno(-ret)
  2103. }
  2104. /*
  2105. Set an extended attribute value
  2106. Available since Linux 2.6.25
  2107. */
  2108. fsetxattr :: proc "contextless" (fd: Fd, name: cstring, value: rawptr, size: uint, flags: i32) -> (Errno) {
  2109. ret := syscall(SYS_fsetxattr, fd, cast(rawptr) name, value, size, flags)
  2110. return Errno(-ret)
  2111. }
  2112. /*
  2113. Retrieve an extended attribute
  2114. Available since Linux 2.6.25
  2115. */
  2116. getxattr :: proc "contextless" (path: cstring, name: cstring, value: rawptr, size: uint) -> (Errno) {
  2117. ret := syscall(SYS_getxattr, cast(rawptr) path, cast(rawptr) name, value, size)
  2118. return Errno(-ret)
  2119. }
  2120. /*
  2121. Retrieve an extended attribute
  2122. Available since Linux 2.6.25
  2123. */
  2124. lgetxattr :: proc "contextless" (path: cstring, name: cstring, value: rawptr, size: uint) -> (Errno) {
  2125. ret := syscall(SYS_lgetxattr, cast(rawptr) path, cast(rawptr) name, value, size)
  2126. return Errno(-ret)
  2127. }
  2128. /*
  2129. Retrieve an extended attribute
  2130. Available since Linux 2.6.25
  2131. */
  2132. fgetxattr :: proc "contextless" (fd: Fd, name: cstring, value: rawptr, size: uint) -> (Errno) {
  2133. ret := syscall(SYS_fgetxattr, fd, cast(rawptr) name, value, size)
  2134. return Errno(-ret)
  2135. }
  2136. /*
  2137. List extended attribute names
  2138. Available since Linux 2.6.25
  2139. */
  2140. listxattr :: proc "contextless" (path: cstring, list: cstring, size: uint) -> (Errno) {
  2141. ret := syscall(SYS_listxattr, cast(rawptr) path, cast(rawptr) list, size)
  2142. return Errno(-ret)
  2143. }
  2144. /*
  2145. List extended attribute names
  2146. Available since Linux 2.6.25
  2147. */
  2148. llistxattr :: proc "contextless" (path: cstring, list: cstring, size: uint) -> (Errno) {
  2149. ret := syscall(SYS_llistxattr, cast(rawptr) path, cast(rawptr) list, size)
  2150. return Errno(-ret)
  2151. }
  2152. /*
  2153. List extended attribute names
  2154. Available since Linux 2.6.25
  2155. */
  2156. flistxattr :: proc "contextless" (fd: Fd, list: cstring, size: uint) -> (Errno) {
  2157. ret := syscall(SYS_flistxattr, fd, cast(rawptr) list, size)
  2158. return Errno(-ret)
  2159. }
  2160. /*
  2161. Remove an extended attribute
  2162. Available since Linux 2.6.25
  2163. */
  2164. removexattr :: proc "contextless" (path: cstring, name: cstring) -> (Errno) {
  2165. ret := syscall(SYS_removexattr, cast(rawptr) path, cast(rawptr) name)
  2166. return Errno(-ret)
  2167. }
  2168. /*
  2169. Remove an extended attribute
  2170. Available since Linux 2.6
  2171. */
  2172. lremovexattr :: proc "contextless" (path: cstring, name: cstring) -> (Errno) {
  2173. ret := syscall(SYS_lremovexattr, cast(rawptr) path, cast(rawptr) name)
  2174. return Errno(-ret)
  2175. }
  2176. /*
  2177. Remove an extended attribute
  2178. Available since Linux 2.6.25
  2179. */
  2180. fremovexattr :: proc "contextless" (fd: Fd, name: cstring) -> (Errno) {
  2181. ret := syscall(SYS_fremovexattr, fd, cast(rawptr) name)
  2182. return Errno(-ret)
  2183. }
  2184. /*
  2185. Get current time in seconds.
  2186. Available since Linux 1.0.
  2187. */
  2188. time :: proc "contextless" (tloc: ^uint) -> (Errno) {
  2189. when ODIN_ARCH != .arm64 && ODIN_ARCH != .riscv64 {
  2190. ret := syscall(SYS_time, tloc)
  2191. return Errno(-ret)
  2192. } else {
  2193. ts: Time_Spec
  2194. ret := syscall(SYS_clock_gettime, Clock_Id.REALTIME, &ts)
  2195. tloc^ = ts.time_sec
  2196. return Errno(-ret)
  2197. }
  2198. }
  2199. /*
  2200. Wait on a futex until it's signaled.
  2201. */
  2202. futex_wait :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Type, flags: Futex_Flags, val: u32, timeout: ^Time_Spec = nil) -> (Errno) {
  2203. futex_flags := cast(u32) op + transmute(u32) flags
  2204. ret := syscall(SYS_futex, futex, futex_flags, val, timeout)
  2205. return Errno(-ret)
  2206. }
  2207. /*
  2208. Wake up other threads on a futex
  2209. n_wakeup specifies the number of processes to wakeup. Specify max(i32) to wake up all processes waiting
  2210. */
  2211. futex_wake :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Type, flags: Futex_Flags, n_wakeup: i32) -> (int, Errno) {
  2212. futex_flags := cast(u32) op + transmute(u32) flags
  2213. ret := syscall(SYS_futex, futex, futex_flags, n_wakeup)
  2214. return errno_unwrap(ret, int)
  2215. }
  2216. // NOTE(flysand): futex_fd is racy, so not implemented
  2217. /*
  2218. Requeues processes waiting on futex `futex` to wait on futex `requeue_futex`
  2219. `requeue_threshold` specifies the maximum amount of waiters to wake up, the rest of the waiters will be requeued
  2220. `requeue_max` specifies the maximum amount of waiters that are required at `requeue_futex`
  2221. The operation blocks until the `requeue_max` requirement is satisfied
  2222. If the value of the mutex is not equal to `val`, fails with EAGAIN before any further checks
  2223. Returns the total number of waiters that have been woken up plus the number of waiters requeued.
  2224. */
  2225. futex_cmp_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Cmp_Requeue_Type, flags: Futex_Flags, requeue_threshold: u32,
  2226. requeue_max: i32, requeue_futex: ^Futex, val: i32) -> (int, Errno) {
  2227. futex_flags := cast(u32) op + transmute(u32) flags
  2228. ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex, val)
  2229. return errno_unwrap(ret, int)
  2230. }
  2231. /*
  2232. See `futex_cmp_requeue`, this function does the same thing but doesn't check the value of the futex.
  2233. Returns the total number of waiters that have been woken up.
  2234. */
  2235. futex_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Requeue_Type, flags: Futex_Flags, requeue_threshold: u32,
  2236. requeue_max: i32, requeue_futex: ^Futex) -> (int, Errno) {
  2237. futex_flags := cast(u32) op + transmute(u32) flags
  2238. ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex)
  2239. return errno_unwrap(ret, int)
  2240. }
  2241. /*
  2242. Okay, for this one, see the man pages, the description for it is pretty long and very specific. It's sole.
  2243. purpose is to allow implementing conditional values sync primitive, it seems like.
  2244. */
  2245. futex_wake_op :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Op_Type, flags: Futex_Flags, wakeup: i32,
  2246. dst_wakeup, dst: ^Futex, futex_op: u32) -> (int, Errno) {
  2247. futex_flags := cast(u32) op + transmute(u32) flags
  2248. ret := syscall(SYS_futex, futex, futex_flags, wakeup, dst_wakeup, dst, futex_op)
  2249. return errno_unwrap(ret, int)
  2250. }
  2251. /*
  2252. Same as wait, but mask specifies bits that must be equal for the mutex to wake up.
  2253. */
  2254. futex_wait_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Bitset_Type, flags: Futex_Flags, val: u32,
  2255. timeout: ^Time_Spec, mask: u32) -> (int, Errno) {
  2256. futex_flags := cast(u32) op + transmute(u32) flags
  2257. ret := syscall(SYS_futex, futex, futex_flags, val, timeout, 0, mask)
  2258. return errno_unwrap(ret, int)
  2259. }
  2260. /*
  2261. Wake up on bitset.
  2262. */
  2263. futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Type, flags: Futex_Flags, n_wakeup: u32, mask: u32) -> (int, Errno) {
  2264. futex_flags := cast(u32) op + transmute(u32) flags
  2265. ret := syscall(SYS_futex, futex, futex_flags, n_wakeup, 0, 0, mask)
  2266. return errno_unwrap(ret, int)
  2267. }
  2268. // TODO(flysand): Priority inheritance (PI) futicees
  2269. futex :: proc{
  2270. futex_wait,
  2271. futex_wake,
  2272. futex_cmp_requeue,
  2273. futex_requeue,
  2274. futex_wake_op,
  2275. futex_wait_bitset,
  2276. futex_wake_bitset,
  2277. }
  2278. // TODO(flysand): sched_setaffinity
  2279. // TODO(flysand): sched_getaffinity
  2280. // TODO(flysand): set_thread_area
  2281. // TODO(flysand): io_setup
  2282. // TODO(flysand): io_destroy
  2283. // TODO(flysand): io_getevents
  2284. // TODO(flysand): io_submit
  2285. // TODO(flysand): io_cancel
  2286. // TODO(flysand): get_thread_area
  2287. // TODO(flysand): lookup_dcookie
  2288. /*
  2289. Open an epoll file descriptor.
  2290. The `size` argument is ignored but must be greater than zero.
  2291. Available since Linux 2.6.
  2292. */
  2293. epoll_create :: proc(size: i32 = 1) -> (Fd, Errno) {
  2294. when ODIN_ARCH != .arm64 && ODIN_ARCH != .riscv64 {
  2295. ret := syscall(SYS_epoll_create, i32(1))
  2296. return errno_unwrap(ret, Fd)
  2297. } else {
  2298. ret := syscall(SYS_epoll_create1, i32(0))
  2299. return errno_unwrap(ret, Fd)
  2300. }
  2301. }
  2302. // TODO(flysand): remap_file_pages
  2303. /*
  2304. Set the address of the futex that's gonna be waken when.
  2305. current thread terminates.
  2306. Available since Linux 2.6.
  2307. */
  2308. set_tid_address :: proc "contextless" (tidptr: ^u32) {
  2309. syscall(SYS_set_tid_address, tidptr)
  2310. }
  2311. // TODO(flysand): semtimedop
  2312. // TODO(flysand): fadvise64
  2313. /*
  2314. Create POSIX per-process timer.
  2315. Available since Linux 2.6.
  2316. */
  2317. timer_create :: proc "contextless" (clock_id: Clock_Id, sigevent: ^Sig_Event, timer: ^Timer) -> (Errno) {
  2318. ret := syscall(SYS_timer_create, clock_id, sigevent, timer)
  2319. return Errno(-ret)
  2320. }
  2321. /*
  2322. Get the state of the POSIX per-process timer.
  2323. Available since Linux 2.6.
  2324. */
  2325. timer_gettime :: proc "contextless" (timer: Timer, curr_value: ^ITimer_Spec) -> (Errno) {
  2326. ret := syscall(SYS_timer_gettime, timer, curr_value)
  2327. return Errno(-ret)
  2328. }
  2329. /*
  2330. Arm/disarm the state of the POSIX per-process timer.
  2331. Available since Linux 2.6.
  2332. */
  2333. timer_settime :: proc "contextless" (timer: Timer, flags: ITimer_Flags, #no_alias new_value, old_value: ^ITimer_Spec) -> (Errno) {
  2334. ret := syscall(SYS_timer_settime, timer, transmute(u32) flags, new_value, old_value)
  2335. return Errno(-ret)
  2336. }
  2337. /*
  2338. Get overrun count of the POSIX per-process timer.
  2339. Available since Linux 2.6.
  2340. */
  2341. timer_getoverrun :: proc "contextless" (timer: Timer) -> (int, Errno) {
  2342. ret := syscall(SYS_timer_getoverrun, timer)
  2343. return errno_unwrap(ret, int)
  2344. }
  2345. /*
  2346. Delete a POSIX per-process timer.
  2347. Available since Linux 2.6.
  2348. */
  2349. timer_delete :: proc "contextless" (timer: Timer) -> (Errno) {
  2350. ret := syscall(SYS_timer_delete, timer)
  2351. return Errno(-ret)
  2352. }
  2353. /*
  2354. Set the time of the specified clock.
  2355. Available since Linux 2.6.
  2356. */
  2357. clock_settime :: proc "contextless" (clock: Clock_Id, ts: ^Time_Spec) -> (Errno) {
  2358. ret := syscall(SYS_clock_settime, clock, ts)
  2359. return Errno(-ret)
  2360. }
  2361. /*
  2362. Retrieve the time of the specified clock.
  2363. Available since Linux 2.6.
  2364. */
  2365. clock_gettime :: proc "contextless" (clock: Clock_Id) -> (ts: Time_Spec, err: Errno) {
  2366. ret := syscall(SYS_clock_gettime, clock, &ts)
  2367. err = Errno(-ret)
  2368. return
  2369. }
  2370. /*
  2371. Finds the resolution of the specified clock.
  2372. Available since Linux 2.6.
  2373. */
  2374. clock_getres :: proc "contextless" (clock: Clock_Id) -> (res: Time_Spec, err: Errno) {
  2375. ret := syscall(SYS_clock_getres, clock, &res)
  2376. err = Errno(-ret)
  2377. return
  2378. }
  2379. /*
  2380. Sleep for an interval specified with nanosecond precision.
  2381. Available since Linux 2.6.
  2382. */
  2383. clock_nanosleep :: proc "contextless" (clock: Clock_Id, flags: ITimer_Flags, request: ^Time_Spec, remain: ^Time_Spec) -> (Errno) {
  2384. ret := syscall(SYS_clock_nanosleep, clock, transmute(u32) flags, request, remain)
  2385. return Errno(-ret)
  2386. }
  2387. /*
  2388. Exit the thread group.
  2389. Available since Linux 2.6.
  2390. */
  2391. exit_group :: proc "contextless" (code: i32) -> ! {
  2392. syscall(SYS_exit_group, code)
  2393. unreachable()
  2394. }
  2395. /*
  2396. Wait for an I/O event on an epoll file descriptor.
  2397. `timeout` is specified in milliseconds.
  2398. Available since Linux 2.6.
  2399. */
  2400. epoll_wait :: proc(epfd: Fd, events: [^]EPoll_Event, count: i32, timeout: i32) -> (i32, Errno) {
  2401. when ODIN_ARCH != .arm64 && ODIN_ARCH != .riscv64 {
  2402. ret := syscall(SYS_epoll_wait, epfd, events, count, timeout)
  2403. return errno_unwrap(ret, i32)
  2404. } else {
  2405. // Convert milliseconds to nanosecond timespec
  2406. timeout_ns := Time_Spec {
  2407. time_sec = uint(timeout * 1000),
  2408. time_nsec = 0,
  2409. }
  2410. ret := syscall(SYS_epoll_pwait, epfd, events, count, &timeout_ns, rawptr(nil))
  2411. return errno_unwrap(ret, i32)
  2412. }
  2413. }
  2414. /*
  2415. Control interface for an epoll file descriptor.
  2416. Available since Linux 2.6.
  2417. */
  2418. epoll_ctl :: proc(epfd: Fd, op: EPoll_Ctl_Opcode, fd: Fd, event: ^EPoll_Event) -> (Errno) {
  2419. ret := syscall(SYS_epoll_ctl, epfd, op, fd, event)
  2420. return Errno(-ret)
  2421. }
  2422. /*
  2423. Send a signal to a specific thread in a thread group.
  2424. Available since Linux 2.6.
  2425. */
  2426. tgkill :: proc "contextless" (tgid, tid: Pid, sig: Signal) -> (Errno) {
  2427. ret := syscall(SYS_tgkill, tgid, tid, sig)
  2428. return Errno(-ret)
  2429. }
  2430. // TODO(flysand): utimes
  2431. // TODO(flysand): vserver
  2432. // TODO(flysand): mbind
  2433. // TODO(flysand): set_mempolicy
  2434. // TODO(flysand): get_mempolicy
  2435. // TODO(flysand): mq_open
  2436. // TODO(flysand): mq_unlink
  2437. // TODO(flysand): mq_timedsend
  2438. // TODO(flysand): mq_timedreceive
  2439. // TODO(flysand): mq_notify
  2440. // TODO(flysand): mq_getsetattr
  2441. // TODO(flysand): kexec_load
  2442. /*
  2443. Wait on process, process group or pid file descriptor.
  2444. Available since Linux 2.6.10.
  2445. */
  2446. waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options, rusage: ^RUsage) -> (Errno) {
  2447. ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options, rusage)
  2448. return Errno(-ret)
  2449. }
  2450. // TODO(flysand): add_key
  2451. // TODO(flysand): request_key
  2452. // TODO(flysand): keyctl
  2453. // TODO(flysand): ioprio_set
  2454. // TODO(flysand): ioprio_get
  2455. inotify_init :: proc "contextless" () -> (Fd, Errno) {
  2456. when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
  2457. ret := syscall(SYS_inotify_init1, 0)
  2458. return errno_unwrap(ret, Fd)
  2459. } else {
  2460. ret := syscall(SYS_inotify_init)
  2461. return errno_unwrap(ret, Fd)
  2462. }
  2463. }
  2464. inotify_init1 :: proc "contextless" (flags: Inotify_Init_Flags) -> (Fd, Errno) {
  2465. ret := syscall(SYS_inotify_init1, transmute(i32)flags)
  2466. return errno_unwrap(ret, Fd)
  2467. }
  2468. inotify_add_watch :: proc "contextless" (fd: Fd, pathname: cstring, mask: Inotify_Event_Mask) -> (Wd, Errno) {
  2469. ret := syscall(SYS_inotify_add_watch, fd, transmute(uintptr) pathname, transmute(u32) mask)
  2470. return errno_unwrap(ret, Wd)
  2471. }
  2472. inotify_rm_watch :: proc "contextless" (fd: Fd, wd: Wd) -> (Errno) {
  2473. ret := syscall(SYS_inotify_rm_watch, fd, wd)
  2474. return Errno(-ret)
  2475. }
  2476. // TODO(flysand): migrate_pages
  2477. /*
  2478. Open file at the specified file descriptor.
  2479. Available since Linux 2.6.16.
  2480. */
  2481. openat :: proc "contextless" (fd: Fd, name: cstring, flags: Open_Flags, mode: Mode = {}) -> (Fd, Errno) {
  2482. ret := syscall(SYS_openat, fd, transmute(uintptr) name, transmute(u32) flags, transmute(u32) mode)
  2483. return errno_unwrap(ret, Fd)
  2484. }
  2485. /*
  2486. Create a directory relative to specified dirfd.
  2487. Available since Linux 2.6.16.
  2488. */
  2489. mkdirat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode) -> (Errno) {
  2490. ret := syscall(SYS_mkdirat, dirfd, cast(rawptr) name, transmute(u32) mode)
  2491. return Errno(-ret)
  2492. }
  2493. /*
  2494. Create a special or ordinary file wrt given directory specified by dirfd.
  2495. Available since Linux 2.6.16.
  2496. */
  2497. mknodat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode, dev: Dev) -> (Errno) {
  2498. ret := syscall(SYS_mknodat, dirfd, cast(rawptr) name, transmute(u32) mode, cast(uint) dev)
  2499. return Errno(-ret)
  2500. }
  2501. /*
  2502. Change the ownership of the file specified relative to directory.
  2503. Available since Linux 2.6.16.
  2504. */
  2505. fchownat :: proc "contextless" (dirfd: Fd, name: cstring, uid: Uid, gid: Gid) -> (Errno) {
  2506. ret := syscall(SYS_fchownat, dirfd, cast(rawptr) name, uid, gid)
  2507. return Errno(-ret)
  2508. }
  2509. /*
  2510. Get information about a file at a specific directory.
  2511. Available since Linux 2.6.16.
  2512. */
  2513. fstatat :: proc "contextless" (dirfd: Fd, name: cstring, stat: ^Stat, flags: FD_Flags) -> (Errno) {
  2514. when size_of(int) == 4 {
  2515. ret := syscall(SYS_fstatat64, dirfd, cast(rawptr) name, stat, transmute(i32) flags)
  2516. return Errno(-ret)
  2517. } else when ODIN_ARCH == .amd64 {
  2518. ret := syscall(SYS_newfstatat, dirfd, cast(rawptr) name, stat, transmute(i32) flags)
  2519. return Errno(-ret)
  2520. } else {
  2521. ret := syscall(SYS_fstatat, dirfd, cast(rawptr) name, stat, transmute(i32) flags)
  2522. return Errno(-ret)
  2523. }
  2524. }
  2525. /*
  2526. Remove a directory entry relative to a directory file descriptor.
  2527. Available since Linux 2.6.16.
  2528. */
  2529. unlinkat :: proc "contextless" (dirfd: Fd, name: cstring, flags: FD_Flags) -> (Errno) {
  2530. ret := syscall(SYS_unlinkat, dirfd, cast(rawptr) name, transmute(i32) flags)
  2531. return Errno(-ret)
  2532. }
  2533. /*
  2534. Rename the file with names relative to the specified dirfd's.
  2535. Available since Linux 2.6.16.
  2536. */
  2537. renameat :: proc "contextless" (oldfd: Fd, old: cstring, newfd: Fd, new: cstring) -> (Errno) {
  2538. ret := syscall(SYS_renameat, oldfd, cast(rawptr) old, newfd, cast(rawptr) new)
  2539. return Errno(-ret)
  2540. }
  2541. /*
  2542. Creates a hard link on a file relative to specified dirfd.
  2543. Available since Linux 2.6.16.
  2544. */
  2545. linkat :: proc "contextless" (target_dirfd: Fd, oldpath: cstring, link_dirfd: Fd, link: cstring, flags: FD_Flags) -> (Errno) {
  2546. ret := syscall(SYS_linkat, target_dirfd, cast(rawptr) oldpath, link_dirfd, cast(rawptr) link, transmute(i32) flags)
  2547. return Errno(-ret)
  2548. }
  2549. /*
  2550. Create a symbolic link at specified dirfd.
  2551. Available since Linux 2.6.16.
  2552. */
  2553. symlinkat :: proc "contextless" (target: cstring, dirfd: Fd, linkpath: cstring) -> (Errno) {
  2554. ret := syscall(SYS_symlinkat, cast(rawptr) target, dirfd, cast(rawptr) linkpath)
  2555. return Errno(-ret)
  2556. }
  2557. /*
  2558. Read the value of a symbolic link at given dirfd.
  2559. Available since Linux 2.6.16.
  2560. */
  2561. readlinkat :: proc "contextless" (dirfd: Fd, name: cstring, buf: []u8) -> (int, Errno) {
  2562. ret := syscall(SYS_readlinkat, dirfd, cast(rawptr) name, raw_data(buf), len(buf))
  2563. return errno_unwrap(ret, int)
  2564. }
  2565. /*
  2566. Change the file mode at a specified file descriptor.
  2567. Available since Linux 2.6.16.
  2568. */
  2569. fchmodat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode, flags: FD_Flags) -> (Errno) {
  2570. ret := syscall(SYS_fchmodat, cast(rawptr) name, transmute(u32) mode, transmute(i32) flags)
  2571. return Errno(-ret)
  2572. }
  2573. /*
  2574. Checks the user permissions for a file at specified dirfd.
  2575. Available since Linux 2.6.16.
  2576. */
  2577. faccessat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK) -> (Errno) {
  2578. ret := syscall(SYS_faccessat, dirfd, cast(rawptr) name, transmute(u32) mode)
  2579. return Errno(-ret)
  2580. }
  2581. /*
  2582. Wait for events on a file descriptor.
  2583. Available since Linux 2.6.16.
  2584. */
  2585. ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) {
  2586. ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
  2587. return errno_unwrap(ret, i32)
  2588. }
  2589. // TODO(flysand): unshare
  2590. // TODO(flysand): set_robust_list
  2591. // TODO(flysand): get_robust_list
  2592. /*
  2593. Transfer the data between file descriptors.
  2594. Available since Linux 2.6.17.
  2595. */
  2596. splice :: proc "contextless" (fd_in: Fd, off_in: ^i64, fd_out: Fd, off_out: ^i64, len: uint, flags: Splice_Flags) -> (int, Errno) {
  2597. ret := syscall(SYS_splice, fd_in, off_in, fd_out, off_out, len, transmute(u32) flags)
  2598. return errno_unwrap(ret, int)
  2599. }
  2600. /*
  2601. Transfer the data between file descriptors.
  2602. Available since Linux 2.6.16.
  2603. */
  2604. tee :: proc "contextless" (fd_in: Fd, fd_out: Fd, len: uint, flags: Splice_Flags) -> (int, Errno) {
  2605. ret := syscall(SYS_tee, fd_in, fd_out, len, transmute(u32) flags)
  2606. return errno_unwrap(ret, int)
  2607. }
  2608. // TODO(flysand): sync_file_range
  2609. // TODO(flysand): vmsplice
  2610. // TODO(flysand): move_pages
  2611. /*
  2612. Change file timestamps with nanosecond precision.
  2613. **utimes** must point to an array of two `Time_Spec`'s. The "utime" is the
  2614. last access time, the second is last modification time.
  2615. Available since Linux 2.6.22.
  2616. */
  2617. utimensat :: proc "contextless" (dirfd: Fd, name: cstring, utimes: [^]Time_Spec, flags: FD_Flags) -> (Errno) {
  2618. ret := syscall(SYS_utimensat, dirfd, cast(rawptr) name, utimes, transmute(i32) flags)
  2619. return Errno(-ret)
  2620. }
  2621. /*
  2622. Wait for an I/O event on an epoll file descriptor.
  2623. Available since Linux 2.6.
  2624. */
  2625. epoll_pwait :: proc(epfd: Fd, events: [^]EPoll_Event, count: i32, timeout: i32, sigmask: ^Sig_Set) -> (i32, Errno) {
  2626. ret := syscall(SYS_epoll_pwait, epfd, events, count, timeout, sigmask)
  2627. return errno_unwrap(ret, i32)
  2628. }
  2629. // TODO(flysand): signalfd
  2630. /*
  2631. Create Linux file descriptor based timer.
  2632. Available since Linux 2.6.25
  2633. */
  2634. timerfd_create :: proc "contextless" (clock_id: Clock_Id, flags: Open_Flags) -> (Fd, Errno) {
  2635. ret := syscall(SYS_timerfd_create, clock_id, transmute(u32)flags)
  2636. return errno_unwrap2(ret, Fd)
  2637. }
  2638. // TODO(flysand): eventfd
  2639. // TODO(flysand): fallocate
  2640. /*
  2641. Arm/disarm the state of the Linux file descriptor based timer.
  2642. Available since Linux 2.6.25
  2643. */
  2644. timerfd_settime :: proc "contextless" (fd: Fd, flags: ITimer_Flags, new_value: ^ITimer_Spec, old_value: ^ITimer_Spec) -> Errno {
  2645. ret := syscall(SYS_timerfd_settime, fd, transmute(u32)flags, new_value, old_value)
  2646. return Errno(-ret)
  2647. }
  2648. /*
  2649. Get the state of the Linux file descriptor based timer.
  2650. Available since Linux 2.6.25
  2651. */
  2652. timerfd_gettime :: proc "contextless" (fd: Fd, curr_value: ^ITimer_Spec) -> Errno {
  2653. ret := syscall(SYS_timerfd_gettime, fd, curr_value)
  2654. return Errno(-ret)
  2655. }
  2656. // TODO(flysand): accept4
  2657. // TODO(flysand): signalfd4
  2658. // TODO(flysand): eventfd2
  2659. epoll_create1 :: proc(flags: EPoll_Flags) -> (Fd, Errno) {
  2660. ret := syscall(SYS_epoll_create1, transmute(i32) flags)
  2661. return errno_unwrap(ret, Fd)
  2662. }
  2663. /*
  2664. Adjust an existing file descriptor to point to the same file as `old`.
  2665. In addition to dup2 allows to pass O_CLOEXEC flag.
  2666. Available since Linux 2.6.27.
  2667. */
  2668. dup3 :: proc "contextless" (old: Fd, new: Fd, flags: Open_Flags) -> (Fd, Errno) {
  2669. ret := syscall(SYS_dup3, old, new, transmute(i32) flags)
  2670. return errno_unwrap(ret, Fd)
  2671. }
  2672. // TODO(flysand): inotify_init1
  2673. // TODO(flysand): preadv
  2674. // TODO(flysand): pwritev
  2675. /// Send signal information to a thread
  2676. /// Available since Linux 2.2
  2677. rt_tgsigqueueinfo :: proc "contextless" (tgid: Pid, pid: Pid, sig: Signal, si: ^Sig_Info) -> (Errno) {
  2678. ret := syscall(SYS_rt_tgsigqueueinfo, tgid, pid, sig, si)
  2679. return Errno(-ret)
  2680. }
  2681. /*
  2682. Set up performance monitoring.
  2683. Available since Linux 2.6.31.
  2684. */
  2685. perf_event_open :: proc "contextless" (attr: ^Perf_Event_Attr, pid: Pid, cpu: int, group_fd: Fd, flags: Perf_Flags = {}) -> (Fd, Errno) {
  2686. ret := syscall(SYS_perf_event_open, attr, pid, cpu, group_fd, transmute(uint) flags)
  2687. return errno_unwrap(ret, Fd)
  2688. }
  2689. /*
  2690. Receive multiple messages from a socket.
  2691. Available since Linux 2.6.33.
  2692. */
  2693. recvmmsg :: proc "contextless" (sock: Fd, msg_vec: []MMsg_Hdr, flags: Socket_Msg) -> (int, Errno) {
  2694. ret := syscall(SYS_recvmmsg, sock, raw_data(msg_vec), len(msg_vec), transmute(i32) flags)
  2695. return errno_unwrap(ret, int)
  2696. }
  2697. // TODO(flysand): fanotify_init
  2698. // TODO(flysand): fanotify_mark
  2699. // TODO(flysand): prlimit64
  2700. // TODO(flysand): name_to_handle_at
  2701. // TODO(flysand): open_by_handle_at
  2702. // TODO(flysand): clock_adjtime
  2703. // TODO(flysand): syncfs
  2704. /*
  2705. Send multiple messages on a socket.
  2706. Available since Linux 3.0.
  2707. */
  2708. sendmmsg :: proc "contextless" (sock: Fd, msg_vec: []MMsg_Hdr, flags: Socket_Msg) -> (int, Errno) {
  2709. ret := syscall(SYS_sendmmsg, sock, raw_data(msg_vec), len(msg_vec), transmute(i32) flags)
  2710. return errno_unwrap(ret, int)
  2711. }
  2712. // TODO(flysand): setns
  2713. // TODO(flysand): getcpu
  2714. // TODO(flysand): process_vm_readv
  2715. // TODO(flysand): process_vm_writev
  2716. // TODO(flysand): kcmp
  2717. // TODO(flysand): finit_module
  2718. // TODO(flysand): sched_setattr
  2719. // TODO(flysand): sched_getattr
  2720. /*
  2721. Rename the file with names relative to the specified dirfd's with other options.
  2722. Available since Linux 3.15.
  2723. */
  2724. renameat2 :: proc "contextless" (oldfd: Fd, old: cstring, newfd: Fd, new: cstring, flags: Rename_Flags) -> (Errno) {
  2725. ret := syscall(SYS_renameat2, oldfd, cast(rawptr) old, newfd, cast(rawptr) new, transmute(u32) flags)
  2726. return Errno(-ret)
  2727. }
  2728. // TODO(flysand): seccomp
  2729. getrandom :: proc "contextless" (buf: []u8, flags: Get_Random_Flags) -> (int, Errno) {
  2730. ret := syscall(SYS_getrandom, raw_data(buf), len(buf), transmute(i32) flags)
  2731. return errno_unwrap(ret, int)
  2732. }
  2733. // TODO(flysand): memfd_create
  2734. // TODO(flysand): kexec_file_load
  2735. // TODO(flysand): bpf
  2736. /*
  2737. Execute program relative to a directory file descriptor.
  2738. Available since Linux 3.19.
  2739. */
  2740. execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring, flags: Execveat_Flags = {}) -> (Errno) {
  2741. ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, transmute(i32) flags)
  2742. return Errno(-ret)
  2743. }
  2744. // TODO(flysand): userfaultfd
  2745. // TODO(flysand): membarrier
  2746. // TODO(flysand): mlock2
  2747. // TODO(flysand): copy_file_range
  2748. // TODO(flysand): preadv2
  2749. // TODO(flysand): pwritev2
  2750. // TODO(flysand): pkey_mprotect
  2751. // TODO(flysand): pkey_alloc
  2752. // TODO(flysand): pkey_free
  2753. /*
  2754. Query extended information about the file
  2755. The file can be specified as:
  2756. - absolute pathname: `dir` parameter is ignored
  2757. - relatvie pathname: `dir` parameter specifies the base directory's fd
  2758. - file descriptor: `AT_EMPTY_PATH` is passed in flags, pathname is empty, `dir` specifies the file descriptor
  2759. Available since Linux 4.11
  2760. */
  2761. statx :: proc "contextless" (dir: Fd, pathname: cstring, flags: FD_Flags, mask: Statx_Mask, statx: ^Statx) -> (Errno) {
  2762. ret := syscall(SYS_statx, dir, transmute(uintptr) pathname, transmute(i32) flags, transmute(u32) mask, statx)
  2763. return Errno(-ret)
  2764. }
  2765. // TODO(flysand): io_pgetevents
  2766. // TODO(flysand): rseq
  2767. // TODO(flysand): pidfd_send_signal
  2768. /*
  2769. Setup a context for performing asynchronous I/O.
  2770. Available since Linux 5.1
  2771. */
  2772. io_uring_setup :: proc "contextless" (entries: u32, params: ^IO_Uring_Params) -> (Fd, Errno) {
  2773. ret := syscall(SYS_io_uring_setup, entries, params)
  2774. return errno_unwrap(ret, Fd)
  2775. }
  2776. /*
  2777. Initiate and/or complete I/O using the shared submission and completion queues.
  2778. Available since Linux 5.1
  2779. */
  2780. io_uring_enter :: proc "contextless" (fd: Fd, to_submit: u32, min_complete: u32, flags: IO_Uring_Enter_Flags, sig: ^Sig_Set) -> (int, Errno) {
  2781. ret := syscall(SYS_io_uring_enter, fd, to_submit, min_complete, transmute(u32)flags, sig, size_of(Sig_Set) if sig != nil else 0)
  2782. return errno_unwrap(ret, int)
  2783. }
  2784. /*
  2785. Initiate and.or complete I/O using the shared submission and completion queues.
  2786. Available since Linux 5.11
  2787. */
  2788. io_uring_enter2 :: proc "contextless" (fd: Fd, to_submit: u32, min_complete: u32, flags: IO_Uring_Enter_Flags, arg: ^IO_Uring_Getevents_Arg) -> (int, Errno) {
  2789. assert_contextless(.EXT_ARG in flags)
  2790. ret := syscall(SYS_io_uring_enter, fd, to_submit, min_complete, transmute(u32)flags, arg, size_of(IO_Uring_Getevents_Arg))
  2791. return errno_unwrap(ret, int)
  2792. }
  2793. /*
  2794. Register files or user buffers for asynchronous I/O.
  2795. Available since Linux 5.1
  2796. */
  2797. io_uring_register :: proc "contextless" (fd: Fd, opcode: IO_Uring_Register_Opcode, arg: rawptr, nr_args: u32) -> Errno {
  2798. ret := syscall(SYS_io_uring_register, fd, opcode, arg, nr_args)
  2799. return Errno(-ret)
  2800. }
  2801. // TODO(flysand): open_tree
  2802. // TODO(flysand): move_mount
  2803. // TODO(flysand): fsopen
  2804. // TODO(flysand): fsconfig
  2805. // TODO(flysand): fsmount
  2806. // TODO(flysand): fspick
  2807. /*
  2808. Creates a new PID file descriptor.
  2809. The process identified by `pid` must be a pid group leader.
  2810. The returned `pidfd` has `CLOEXEC` semantics.
  2811. Available since Linux 5.3.
  2812. */
  2813. pidfd_open :: proc "contextless" (pid: Pid, flags: Pid_FD_Flags) -> (Pid_FD, Errno) {
  2814. ret := syscall(SYS_pidfd_open, pid, transmute(i32) flags)
  2815. return errno_unwrap(ret, Pid_FD)
  2816. }
  2817. // TODO(flysand): clone3 (probably not this PR)
  2818. /*
  2819. Close the range of files as an atomic operation.
  2820. The range of file descriptors is inclusive, and may contain invalid file descriptors.
  2821. Available since Linux 5.9.
  2822. */
  2823. close_range :: proc "contextless" (lo: Fd, hi: Fd, flags: Close_Range_Flags) -> (Errno) {
  2824. ret := syscall(SYS_close_range, lo, hi, transmute(u32) flags)
  2825. return Errno(-ret)
  2826. }
  2827. // TODO(flysand): openat2
  2828. /*
  2829. Get a file descriptor from another process.
  2830. - `fd` refers to a file descriptor number to get.
  2831. - `flags` must be zero.
  2832. Available since Linux 5.3.
  2833. */
  2834. pidfd_getfd :: proc "contextless" (pidfd: Pid_FD, fd: Fd, flags: i32 = 0) -> (Fd, Errno) {
  2835. ret := syscall(SYS_pidfd_getfd, pidfd, fd, flags)
  2836. return errno_unwrap(ret, Fd)
  2837. }
  2838. /*
  2839. Checks the user permissions for a file at specified dirfd (with flags).
  2840. Available since Linux 5.8.
  2841. */
  2842. faccessat2 :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK, flags: FD_Flags = FD_Flags{}) -> (Errno) {
  2843. ret := syscall(SYS_faccessat2, dirfd, cast(rawptr) name, transmute(u32) mode, transmute(i32) flags)
  2844. return Errno(-ret)
  2845. }
  2846. // TODO(flysand): process_madvise
  2847. /*
  2848. Wait for an I/O event on an epoll file descriptor.
  2849. Available since Linux 2.6.
  2850. */
  2851. epoll_pwait2 :: proc(epfd: Fd, events: [^]EPoll_Event, count: i32, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) {
  2852. ret := syscall(SYS_epoll_pwait2, epfd, events, count, timeout, sigmask)
  2853. return errno_unwrap(ret, i32)
  2854. }
  2855. // TODO(flysand): mount_setattr
  2856. // TODO(flysand): quotactl_fd
  2857. // TODO(flysand): landlock_create_ruleset
  2858. // TODO(flysand): landlock_add_rule
  2859. // TODO(flysand): landlock_restrict_self
  2860. // TODO(flysand): memfd_secret
  2861. // TODO(flysand): process_mrelease
  2862. // TODO(flysand): futex_waitv
  2863. // TODO(flysand): set_mempolicy_home_node
  2864. // TODO(flysand): cachestat
  2865. // TODO(flysand): fchmodat2
  2866. // TODO(flysand): map_shadow_stack
  2867. when ODIN_ARCH == .riscv64 {
  2868. /*
  2869. Probe for RISC-V Hardware Support.
  2870. Available since Linux 6.4.
  2871. TODO: cpu_set_t
  2872. See: https://docs.kernel.org/arch/riscv/hwprobe.html
  2873. */
  2874. riscv_hwprobe :: proc "contextless" (pairs: [^]RISCV_HWProbe, pair_count: uint, cpu_count: uint, cpus: rawptr /* cpu_set_t */, flags: RISCV_HWProbe_Flags) -> Errno {
  2875. ret := syscall(SYS_riscv_hwprobe, pairs, pair_count, cpu_count, cpus, transmute(u32)flags)
  2876. return Errno(-ret)
  2877. }
  2878. }