sh.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <sys/wait.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #define print(str) write(STDOUT_FILENO, str, strlen(str))
  6. // struct cmd {
  7. // enum {
  8. // pipe,
  9. // list,
  10. // } op;
  11. // struct cmd* left;
  12. // struct cmd* right;
  13. // struct token* tk;
  14. // };
  15. // struct token {
  16. // char* start;
  17. // size_t len;
  18. // struct token* next;
  19. // };
  20. // static inline int betwn(char c, char s, char e)
  21. // {
  22. // return c >= s && c <= e;
  23. // }
  24. // static inline int is_num(char c)
  25. // {
  26. // return betwn(c, '0', '9');
  27. // }
  28. // static inline int check_token(char c)
  29. // {
  30. // return betwn(c, 'a', 'z') || betwn(c, 'A', 'Z') || (c == '_');
  31. // }
  32. // static inline int read_token(char* buf, struct token** cur)
  33. // {
  34. // char* p = buf;
  35. // for (; *p && (check_token(*p) || (p != buf && is_num(*p))); ++p) {
  36. // (*cur)->start = buf;
  37. // ++(*cur)->len;
  38. // }
  39. // if ((*cur)->start) {
  40. // (*cur)->next = *cur + 1;
  41. // *cur = (*cur)->next;
  42. // }
  43. // return p - buf;
  44. // }
  45. int main(int argc, const char** argv)
  46. {
  47. (void)argc, (void)argv;
  48. char buf[512] = {};
  49. print("sh # ");
  50. for (;;) {
  51. int n = read(STDIN_FILENO, buf, sizeof(buf));
  52. char token[1024] = {};
  53. char* args[128] = { token, 0 };
  54. int j = 0;
  55. int k = 1;
  56. for (int i = 0; i < n; ++i) {
  57. if (buf[i] == ' ') {
  58. token[j++] = 0;
  59. args[k++] = token + j;
  60. continue;
  61. }
  62. if (buf[i] == '\n') {
  63. token[j++] = 0;
  64. if (strcmp(args[0], "exit") == 0)
  65. return 0;
  66. pid_t pid = fork();
  67. if (pid == 0) {
  68. char* envp[] = { NULL };
  69. int ret = execve(args[0], args, envp);
  70. char _b[128];
  71. snprintf(_b, sizeof(_b), "sh: execve() failed with code %d\n", ret);
  72. print(_b);
  73. return -1;
  74. }
  75. int code;
  76. wait(&code);
  77. char _b[128];
  78. snprintf(_b, sizeof(_b), "sh (%d) # ", code);
  79. print(_b);
  80. j = 0;
  81. k = 1;
  82. memset(args, 0x00, sizeof(args));
  83. args[0] = token;
  84. continue;
  85. }
  86. token[j++] = buf[i];
  87. }
  88. }
  89. return 0;
  90. }