init.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include <assert.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <sys/wait.h>
  6. #include <unistd.h>
  7. #define print(str) write(STDERR_FILENO, str, _strlen(str))
  8. static size_t _strlen(const char* str) {
  9. size_t len = 0;
  10. while (str[len] != '\0') {
  11. len++;
  12. }
  13. return len;
  14. }
  15. static __attribute__((used)) size_t strlen(const char* s) {
  16. size_t len = 0;
  17. while (*s++)
  18. ++len;
  19. return len;
  20. }
  21. static __attribute__((used)) void* memcpy(void* dst, const void* src,
  22. size_t n) {
  23. uint8_t* d = (uint8_t*)dst;
  24. const uint8_t* s = (const uint8_t*)src;
  25. for (size_t i = 0; i < n; ++i)
  26. d[i] = s[i];
  27. return dst;
  28. }
  29. int main(int argc, char** argv) {
  30. int fd = 0;
  31. // Assumes three file descriptors open.
  32. while ((fd = open("/dev/console", 0)) >= 0) {
  33. if (fd >= 3) {
  34. close(fd);
  35. break;
  36. }
  37. }
  38. print("***** GBOS INIT SYSTEM *****\n");
  39. _run_sh:;
  40. pid_t sh_pid = fork();
  41. if (sh_pid < 0) {
  42. print("[init] unable to fork(), exiting...\n");
  43. return -1;
  44. }
  45. // child
  46. if (sh_pid == 0) {
  47. pid_t sid = setsid();
  48. if (sid < 0) {
  49. print("[init] unable to setsid, exiting...\n");
  50. return -1;
  51. }
  52. char* shell_argv[128] = {};
  53. if (argc < 2)
  54. shell_argv[0] = "/bin/sh";
  55. else
  56. shell_argv[0] = argv[1];
  57. for (int i = 2; i < argc; ++i)
  58. shell_argv[i - 1] = argv[i];
  59. execve(shell_argv[0], shell_argv, environ);
  60. print("[init] unable to run sh, exiting...\n");
  61. return -1;
  62. }
  63. int ret, pid;
  64. for (;;) {
  65. pid = wait(&ret);
  66. char* buf = NULL;
  67. assert(asprintf(&buf, "[init] pid%d has exited with code %d\n", pid,
  68. ret) >= 0);
  69. print(buf);
  70. free(buf);
  71. // sh
  72. if (pid == sh_pid)
  73. goto _run_sh;
  74. }
  75. return 0;
  76. }