stdio.odin 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. package posix
  2. import "core:c"
  3. import "core:c/libc"
  4. when ODIN_OS == .Darwin {
  5. foreign import lib "system:System.framework"
  6. } else {
  7. foreign import lib "system:c"
  8. }
  9. // stdio.h - standard buffered input/output
  10. foreign lib {
  11. /*
  12. Generates a string that, when used as a pathname,
  13. refers to the current controlling terminal for the current process.
  14. If s is nil, the returned string might be static and overwritten by subsequent calls or other factors.
  15. If s is not nil, s is assumed len(s) >= L_ctermid.
  16. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/ctermid.html ]]
  17. */
  18. ctermid :: proc(s: [^]byte) -> cstring ---
  19. /*
  20. Equivalent to fprintf but output is written to the file descriptor.
  21. Return: number of bytes written, negative (setting errno) on failure
  22. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dprintf.html ]]
  23. */
  24. dprintf :: proc(fildse: FD, format: cstring, #c_vararg args: ..any) -> c.int ---
  25. /*
  26. Equivalent to fprintf but output is written to s, it is the user's responsibility to
  27. ensure there is enough space.
  28. Return: number of bytes written, negative (setting errno) on failure
  29. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dprintf.html ]]
  30. */
  31. sprintf :: proc(s: [^]byte, format: cstring, #c_vararg args: ..any) -> c.int ---
  32. /*
  33. Associate a stream with a file descriptor.
  34. Returns: nil (setting errno) on failure, the stream on success
  35. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopen.html ]]
  36. */
  37. fdopen :: proc(fildes: FD, mode: cstring) -> ^FILE ---
  38. /*
  39. Map a stream pointer to a file descriptor.
  40. Returns: the file descriptor or -1 (setting errno) on failure
  41. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/fileno.html ]]
  42. */
  43. fileno :: proc(stream: ^FILE) -> FD ---
  44. /*
  45. Locks a file.
  46. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/flockfile.html ]]
  47. */
  48. flockfile :: proc(file: ^FILE) ---
  49. /*
  50. Tries to lock a file.
  51. Returns: 0 if it could be locked, non-zero if it couldn't
  52. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/flockfile.html ]]
  53. */
  54. ftrylockfile :: proc(file: ^FILE) -> c.int ---
  55. /*
  56. Unlocks a file.
  57. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/flockfile.html ]]
  58. */
  59. funlockfile :: proc(file: ^FILE) ---
  60. /*
  61. Open a memory buffer stream.
  62. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/fmemopen.html ]]
  63. */
  64. fmemopen :: proc(buf: [^]byte, size: c.size_t, mode: cstring) -> ^FILE ---
  65. /*
  66. Reposition a file-position indicator in a stream.
  67. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseeko.html ]]
  68. */
  69. fseeko :: proc(stream: ^FILE, offset: off_t, whence: Whence) -> result ---
  70. /*
  71. Return the file offset in a stream.
  72. Returns: the current file offset, -1 (setting errno) on error
  73. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftello.html ]]
  74. */
  75. ftello :: proc(^FILE) -> off_t ---
  76. /*
  77. Open a dynamic memory buffer stream.
  78. Returns: nil (setting errno) on failure, the stream on success
  79. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/open_memstream.html ]]
  80. */
  81. open_memstream :: proc(bufp: ^[^]byte, sizep: ^c.size_t) -> ^FILE ---
  82. /*
  83. Equivalent to getc but unaffected by locks.
  84. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
  85. */
  86. getc_unlocked :: proc(stream: ^FILE) -> c.int ---
  87. /*
  88. Equivalent to getchar but unaffected by locks.
  89. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
  90. */
  91. getchar_unlocked :: proc() -> c.int ---
  92. /*
  93. Equivalent to putc but unaffected by locks.
  94. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
  95. */
  96. putc_unlocked :: proc(ch: c.int, stream: ^FILE) -> c.int ---
  97. /*
  98. Equivalent to putchar but unaffected by locks.
  99. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
  100. */
  101. putchar_unlocked :: proc(ch: c.int) -> c.int ---
  102. /*
  103. Read a delimited record from the stream.
  104. Returns: the number of bytes written or -1 on failure/EOF
  105. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html ]]
  106. */
  107. getdelim :: proc(lineptr: ^cstring, n: ^c.size_t, delimiter: c.int, stream: ^FILE) -> c.ssize_t ---
  108. /*
  109. Read a line delimited record from the stream.
  110. Returns: the number of bytes written or -1 on failure/EOF
  111. Example:
  112. fp := posix.fopen(#file, "r")
  113. if fp == nil {
  114. posix.exit(1)
  115. }
  116. line: cstring
  117. length: uint
  118. for {
  119. read := posix.getline(&line, &length, fp)
  120. if read == -1 do break
  121. posix.printf("Retrieved line of length %zu :\n", read)
  122. posix.printf("%s", line)
  123. }
  124. if posix.ferror(fp) != 0 {
  125. /* handle error */
  126. }
  127. posix.free(rawptr(line))
  128. posix.fclose(fp)
  129. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html ]]
  130. */
  131. getline :: proc(lineptr: ^cstring, n: ^c.size_t, stream: ^FILE) -> c.ssize_t ---
  132. /*
  133. Get a string from the stdin stream.
  134. It is up to the user to make sure s is big enough.
  135. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/gets.html ]]
  136. */
  137. gets :: proc(s: [^]byte) -> cstring ---
  138. /*
  139. Create a name for a temporary file.
  140. Returns: an allocated cstring that needs to be freed, nil on failure
  141. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/tempnam.html ]]
  142. */
  143. tempnam :: proc(dir: cstring, pfx: cstring) -> cstring ---
  144. /*
  145. Executes the command specified, creating a pipe and returning a pointer to a stream that can
  146. read or write from/to the pipe.
  147. Returns: nil (setting errno) on failure or a pointer to the stream
  148. Example:
  149. fp := posix.popen("ls *", "r")
  150. if fp == nil {
  151. /* Handle error */
  152. }
  153. path: [1024]byte
  154. for posix.fgets(raw_data(path[:]), len(path), fp) != nil {
  155. posix.printf("%s", &path)
  156. }
  157. status := posix.pclose(fp)
  158. if status == -1 {
  159. /* Error reported by pclose() */
  160. } else {
  161. /* Use functions described under wait() to inspect `status` in order
  162. to determine success/failure of the command executed by popen() */
  163. }
  164. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ]]
  165. */
  166. popen :: proc(command: cstring, mode: cstring) -> ^FILE ---
  167. /*
  168. Closes a pipe stream to or from a process.
  169. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pclose.html ]]
  170. */
  171. pclose :: proc(stream: ^FILE) -> c.int ---
  172. /*
  173. Equivalent to rename but relative directories are resolved from their respective fds.
  174. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/renameat.html ]]
  175. */
  176. renameat :: proc(oldfd: FD, old: cstring, newfd: FD, new: cstring) -> result ---
  177. }
  178. clearerr :: libc.clearerr
  179. fclose :: libc.fclose
  180. feof :: libc.feof
  181. ferror :: libc.ferror
  182. fflush :: libc.fflush
  183. fgetc :: libc.fgetc
  184. fgetpos :: libc.fgetpos
  185. fgets :: libc.fgets
  186. fopen :: libc.fopen
  187. fprintf :: libc.fprintf
  188. fputc :: libc.fputc
  189. fread :: libc.fread
  190. freopen :: libc.freopen
  191. fscanf :: libc.fscanf
  192. fseek :: libc.fseek
  193. fsetpos :: libc.fsetpos
  194. ftell :: libc.ftell
  195. fwrite :: libc.fwrite
  196. getc :: libc.getc
  197. getchar :: libc.getchar
  198. perror :: libc.perror
  199. printf :: libc.printf
  200. putc :: libc.puts
  201. putchar :: libc.putchar
  202. puts :: libc.puts
  203. remove :: libc.remove
  204. rename :: libc.rename
  205. rewind :: libc.rewind
  206. scanf :: libc.scanf
  207. setbuf :: libc.setbuf
  208. setvbuf :: libc.setvbuf
  209. snprintf :: libc.snprintf
  210. sscanf :: libc.sscanf
  211. tmpfile :: libc.tmpfile
  212. tmpnam :: libc.tmpnam
  213. vfprintf :: libc.vfprintf
  214. vfscanf :: libc.vfscanf
  215. vprintf :: libc.vprintf
  216. vscanf :: libc.vscanf
  217. vsnprintf :: libc.vsnprintf
  218. vsprintf :: libc.vsprintf
  219. vsscanf :: libc.vsscanf
  220. ungetc :: libc.ungetc
  221. to_stream :: libc.to_stream
  222. Whence :: libc.Whence
  223. FILE :: libc.FILE
  224. fpos_t :: libc.fpos_t
  225. BUFSIZ :: libc.BUFSIZ
  226. _IOFBF :: libc._IOFBF
  227. _IOLBF :: libc._IOLBF
  228. _IONBF :: libc._IONBF
  229. SEEK_CUR :: libc.SEEK_CUR
  230. SEEK_END :: libc.SEEK_END
  231. SEEK_SET :: libc.SEEK_SET
  232. FILENAME_MAX :: libc.FILENAME_MAX
  233. FOPEN_MAX :: libc.FOPEN_MAX
  234. TMP_MAX :: libc.TMP_MAX
  235. EOF :: libc.EOF
  236. stderr := libc.stderr
  237. stdin := libc.stdin
  238. stdout := libc.stdout
  239. when ODIN_OS == .Darwin {
  240. L_ctermid :: 1024
  241. L_tmpnam :: 1024
  242. P_tmpdir :: "/var/tmp/"
  243. } else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
  244. L_ctermid :: 1024
  245. L_tmpnam :: 1024
  246. P_tmpdir :: "/tmp/"
  247. } else {
  248. #panic("posix is unimplemented for the current target")
  249. }