unistd.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include <errno.h>
  2. #include <priv-vars.h>
  3. #include <stdarg.h>
  4. #include <stdint.h>
  5. #include <sys/ioctl.h>
  6. #include <unistd.h>
  7. #include <syscall.h>
  8. ssize_t read(int fd, void* buf, size_t count)
  9. {
  10. ssize_t ret = syscall3(SYS_read, fd, (uint32_t)buf, count);
  11. if (ret < 0) {
  12. errno = -ret;
  13. return -1;
  14. }
  15. return ret;
  16. }
  17. ssize_t write(int fd, const void* buf, size_t count)
  18. {
  19. ssize_t ret = syscall3(SYS_write, fd, (uint32_t)buf, count);
  20. if (ret < 0) {
  21. errno = -ret;
  22. return -1;
  23. }
  24. return ret;
  25. }
  26. int dup(int oldfd)
  27. {
  28. int ret = syscall1(SYS_dup, oldfd);
  29. if (ret < 0) {
  30. errno = -ret;
  31. return -1;
  32. }
  33. return ret;
  34. }
  35. int dup2(int oldfd, int newfd)
  36. {
  37. int ret = syscall2(SYS_dup2, oldfd, newfd);
  38. if (ret < 0) {
  39. errno = -ret;
  40. return -1;
  41. }
  42. return ret;
  43. }
  44. int pipe(int pipefd[2])
  45. {
  46. int ret = syscall1(SYS_pipe, (uint32_t)pipefd);
  47. if (ret < 0) {
  48. errno = -ret;
  49. return -1;
  50. }
  51. return ret;
  52. }
  53. int close(int fd)
  54. {
  55. int ret = syscall1(SYS_close, fd);
  56. if (ret < 0) {
  57. errno = -ret;
  58. return -1;
  59. }
  60. return ret;
  61. }
  62. _Noreturn void _exit(int code)
  63. {
  64. (void)syscall1(SYS_exit, code);
  65. // if syscall failed
  66. for (;;);
  67. }
  68. pid_t fork(void)
  69. {
  70. pid_t ret = syscall0(SYS_fork);
  71. if (ret < 0) {
  72. errno = -ret;
  73. return -1;
  74. }
  75. return ret;
  76. }
  77. int execve(const char* pathname, char* const argv[], char* const envp[])
  78. {
  79. int ret = syscall3(SYS_execve, (uint32_t)pathname, (uint32_t)argv, (uint32_t)envp);
  80. if (ret < 0) {
  81. errno = -ret;
  82. return -1;
  83. }
  84. return ret;
  85. }
  86. // unsigned int sleep(unsigned int seconds)
  87. // {
  88. // return syscall1(SYS_sleep, seconds);
  89. // }
  90. int chdir(const char* path)
  91. {
  92. int ret = syscall1(SYS_chdir, (uint32_t)path);
  93. if (ret < 0) {
  94. errno = -ret;
  95. return -1;
  96. }
  97. return ret;
  98. }
  99. char* getcwd(char* buf, size_t bufsize)
  100. {
  101. return (char*)syscall2(SYS_getcwd, (uint32_t)buf, bufsize);
  102. }
  103. pid_t getpid(void)
  104. {
  105. pid_t ret = syscall0(SYS_getpid);
  106. if (ret < 0) {
  107. errno = -ret;
  108. return -1;
  109. }
  110. return ret;
  111. }
  112. pid_t getppid(void)
  113. {
  114. pid_t ret = syscall0(SYS_getppid);
  115. if (ret < 0) {
  116. errno = -ret;
  117. return -1;
  118. }
  119. return ret;
  120. }
  121. int setpgid(pid_t pid, pid_t pgid)
  122. {
  123. int ret = syscall2(SYS_setpgid, pid, pgid);
  124. if (ret < 0) {
  125. errno = -ret;
  126. return -1;
  127. }
  128. return ret;
  129. }
  130. pid_t setsid(void)
  131. {
  132. pid_t ret = syscall0(SYS_setsid);
  133. if (ret < 0) {
  134. errno = -ret;
  135. return -1;
  136. }
  137. return ret;
  138. }
  139. pid_t getsid(pid_t pid)
  140. {
  141. pid_t ret = syscall1(SYS_getsid, pid);
  142. if (ret < 0) {
  143. errno = -ret;
  144. return -1;
  145. }
  146. return ret;
  147. }
  148. pid_t tcgetpgrp(int fd)
  149. {
  150. pid_t pgrp;
  151. return ioctl(fd, TIOCGPGRP, &pgrp);
  152. }
  153. int tcsetpgrp(int fd, pid_t pgrp)
  154. {
  155. return ioctl(fd, TIOCSPGRP, &pgrp);
  156. }
  157. int ioctl(int fd, unsigned long request, ...)
  158. {
  159. int ret = -EINVAL;
  160. va_list args;
  161. va_start(args, request);
  162. switch (request) {
  163. case TIOCGPGRP:
  164. ret = syscall3(SYS_ioctl, fd, request, va_arg(args, uint32_t));
  165. break;
  166. case TIOCSPGRP:
  167. ret = syscall3(SYS_ioctl, fd, request, va_arg(args, uint32_t));
  168. break;
  169. default:
  170. break;
  171. }
  172. va_end(args);
  173. if (ret < 0) {
  174. errno = -ret;
  175. return -1;
  176. }
  177. return ret;
  178. }
  179. static inline void* _sys_brk(void* addr)
  180. {
  181. return (void*)syscall1(SYS_brk, (uint32_t)addr);
  182. }
  183. void** __start_brk_location(void)
  184. {
  185. static void* __start_brk = NULL;
  186. return &__start_brk;
  187. }
  188. void** __curr_brk_location(void)
  189. {
  190. static void* __curr_brk = NULL;
  191. return &__curr_brk;
  192. }
  193. int brk(void* addr)
  194. {
  195. void* new_brk = _sys_brk(addr);
  196. if (new_brk == curr_brk) {
  197. errno = 0;
  198. return -1;
  199. }
  200. if (new_brk != addr) {
  201. errno = ENOMEM;
  202. return -1;
  203. }
  204. return 0;
  205. }
  206. void* sbrk(ssize_t increment)
  207. {
  208. if (brk(curr_brk + increment) == 0)
  209. return curr_brk += increment;
  210. return (void*)-1;
  211. }
  212. int isatty(int fd)
  213. {
  214. return tcgetpgrp(fd) != -1;
  215. }
  216. char** environ;