init.c 1.4 KB

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