init.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. if (argc < 2)
  35. shell_argv[0] = "/bin/sh";
  36. else
  37. shell_argv[0] = argv[1];
  38. for (int i = 2; i < argc; ++i)
  39. shell_argv[i - 1] = argv[i];
  40. execve(shell_argv[0], shell_argv, environ);
  41. print("[init] unable to run sh, exiting...\n");
  42. return -1;
  43. }
  44. int ret, pid;
  45. for (;;) {
  46. pid = wait(&ret);
  47. char* buf = NULL;
  48. assert(asprintf(&buf, "[init] pid%d has exited with code %d\n", pid, ret) >= 0);
  49. print(buf);
  50. free(buf);
  51. // sh
  52. if (pid == sh_pid)
  53. goto _run_sh;
  54. }
  55. return 0;
  56. }