init.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <sys/wait.h>
  8. #define print(str) write(STDERR_FILENO, str, strlen(str))
  9. int main(int argc, char** argv)
  10. {
  11. int fd = 0;
  12. // Assumes three file descriptors open.
  13. while((fd = open("/dev/console", 0)) >= 0){
  14. if(fd >= 3){
  15. close(fd);
  16. break;
  17. }
  18. }
  19. print("***** GBOS INIT SYSTEM *****\n");
  20. _run_sh:;
  21. pid_t sh_pid = fork();
  22. if (sh_pid < 0) {
  23. print("[init] unable to fork(), exiting...\n");
  24. return -1;
  25. }
  26. // child
  27. if (sh_pid == 0) {
  28. pid_t sid = setsid();
  29. if (sid < 0) {
  30. print("[init] unable to setsid, exiting...\n");
  31. return -1;
  32. }
  33. char* shell_argv[128] = {};
  34. char* envp[1] = { NULL };
  35. if (argc < 2)
  36. shell_argv[0] = "/bin/sh";
  37. else
  38. shell_argv[0] = argv[1];
  39. for (int i = 2; i < argc; ++i)
  40. shell_argv[i - 1] = argv[i];
  41. execve(shell_argv[0], shell_argv, envp);
  42. print("[init] unable to run sh, exiting...\n");
  43. return -1;
  44. }
  45. int ret, pid;
  46. for (;;) {
  47. pid = wait(&ret);
  48. char* buf = NULL;
  49. assert(asprintf(&buf, "[init] pid%d has exited with code %d\n", pid, ret) >= 0);
  50. print(buf);
  51. free(buf);
  52. // sh
  53. if (pid == sh_pid)
  54. goto _run_sh;
  55. }
  56. return 0;
  57. }