OS2021_Project1.Shell
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

400 строки
7.4 KiB

3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
3 лет назад
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/wait.h>
  5. #include <sys/stat.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include <dirent.h>
  9. #include <signal.h>
  10. #include <errno.h>
  11. #include <fcntl.h>
  12. #include "yeeshell.h"
  13. /* record cmdline history */
  14. char *history[CMDLINE_HISTORY_MAX_QUANTITY];
  15. int cmdline_amount = 0;
  16. int main()
  17. {
  18. char *cmdline = NULL, *pwd = NULL;
  19. char *args[ARGS_MAX_QUANTITY];
  20. int status = 1;
  21. pwd = (char *)calloc(PATH_MAX_SIZE, sizeof(char));
  22. for (int i = 0; i < CMDLINE_HISTORY_MAX_QUANTITY; i++)
  23. {
  24. history[i] = (char *)calloc(CMDLINE_MAX_SIZE, sizeof(char));
  25. }
  26. /* execute the shell's read, parse and execution loop */
  27. do
  28. {
  29. if (!getcwd(pwd, PATH_MAX_SIZE))
  30. {
  31. printf("yeeshell: The current path cannot be obtained!\n");
  32. exit(0);
  33. }
  34. printf("[root@yeeshell %s]# ", pwd);
  35. cmdline = readline();
  36. strcpy(history[cmdline_amount++], cmdline);
  37. status = execute(cmdline, args);
  38. free(cmdline);
  39. } while (status);
  40. for (int i = 0; i < CMDLINE_HISTORY_MAX_QUANTITY; i++)
  41. {
  42. free(history[i]);
  43. }
  44. exit(EXIT_SUCCESS);
  45. }
  46. char *readline()
  47. {
  48. char *cmdline = NULL;
  49. ssize_t bufsize = 0;
  50. getline(&cmdline, &bufsize, stdin);
  51. return cmdline;
  52. }
  53. int parseline(char *cmdline, char **args)
  54. {
  55. static char array[CMDLINE_MAX_SIZE]; /* holds local copy of command line */
  56. char *buf = array; /* ptr that traverses command line */
  57. char *delim; /* points to first space delimiter */
  58. int argc; /* number of args */
  59. int bg; /* background job? */
  60. strcpy(buf, cmdline);
  61. buf[strlen(buf) - 1] = ' '; /* replace trailing '\n' with space */
  62. while (*buf && (*buf == ' ')) /* ignore leading spaces */
  63. {
  64. buf++;
  65. }
  66. /* Build the argv list */
  67. argc = 0;
  68. if (*buf == '\'')
  69. {
  70. buf++;
  71. delim = strchr(buf, '\'');
  72. }
  73. else
  74. {
  75. delim = strchr(buf, ' ');
  76. }
  77. while (delim)
  78. {
  79. args[argc++] = buf;
  80. *delim = '\0';
  81. buf = delim + 1;
  82. while (*buf && (*buf == ' ')) /* ignore spaces */
  83. {
  84. buf++;
  85. }
  86. if (*buf == '\'')
  87. {
  88. buf++;
  89. delim = strchr(buf, '\'');
  90. }
  91. else
  92. {
  93. delim = strchr(buf, ' ');
  94. }
  95. }
  96. args[argc] = NULL;
  97. if (argc == 0) /* ignore blank line */
  98. {
  99. return 1;
  100. }
  101. /* should the job run in the background? */
  102. if ((bg = (*args[argc - 1] == '&')) != 0)
  103. {
  104. args[--argc] = NULL;
  105. }
  106. return bg;
  107. }
  108. int check_redirect(char **args, char *redirect_filename, char **redirect_args)
  109. {
  110. int i = 0, j = 0, redirect_flag = REDIRECT_NO;
  111. while (args[i] != NULL)
  112. {
  113. if (!strcmp(args[i], ">"))
  114. {
  115. redirect_flag = REDIRECT_OUT;
  116. break;
  117. }
  118. else if (!strcmp(args[i], "<"))
  119. {
  120. redirect_flag = REDIRECT_IN;
  121. break;
  122. }
  123. i++;
  124. }
  125. if ((redirect_flag == 1) || (redirect_flag == 2))
  126. {
  127. strcpy(redirect_filename, args[i + 1]);
  128. for (j = 0; j < i; j++)
  129. {
  130. redirect_args[j] = args[j];
  131. }
  132. }
  133. return redirect_flag;
  134. }
  135. int check_pipe(char **args, char **pipe_arg_1, char **pipe_arg_2)
  136. {
  137. int pipe_flag = 0, i = 0, j = 0;
  138. while (args[i] != NULL)
  139. {
  140. if (!strcmp(args[i], "|"))
  141. {
  142. pipe_flag = 1;
  143. break;
  144. }
  145. pipe_arg_1[j++] = args[i++];
  146. }
  147. pipe_arg_1[j] = NULL;
  148. j = 0;
  149. i++;
  150. while (args[i] != NULL)
  151. {
  152. pipe_arg_2[j++] = args[i++];
  153. }
  154. pipe_arg_2[j] = NULL;
  155. return pipe_flag;
  156. }
  157. int execute(char *cmdline, char **args)
  158. {
  159. int bg = 0, i = 0, redirect_flag = 0, fd = 1, pipe_num = 0;
  160. pid_t pid;
  161. char *redirect_filename = NULL;
  162. char *redirect_args[ARGS_MAX_QUANTITY];
  163. char *pipe_arg_1[ARGS_MAX_QUANTITY];
  164. char *pipe_arg_2[ARGS_MAX_QUANTITY];
  165. redirect_filename = (char *)calloc(REDIRECT_FILENAME_MAX_SIZE, sizeof(char));
  166. memset(redirect_args, NULL, sizeof(redirect_args));
  167. bg = parseline(cmdline, args);
  168. redirect_flag = check_redirect(args, redirect_filename, redirect_args);
  169. pipe_num = check_pipe(args, pipe_arg_1, pipe_arg_2);
  170. if (args[0] == NULL)
  171. {
  172. return 1;
  173. }
  174. if (pipe_num == 0) /* no pipe */
  175. {
  176. if (!built_in(args)) /* built-in cmd? */
  177. {
  178. if ((pid = fork()) == 0) /* Child process */
  179. {
  180. if (redirect_flag == 1) /* redirect? */
  181. {
  182. fd = open(redirect_filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR);
  183. close(1);
  184. dup(fd);
  185. }
  186. else if (redirect_flag == 2)
  187. {
  188. fd = open(redirect_filename, O_RDONLY, S_IRUSR);
  189. close(0);
  190. dup(fd);
  191. }
  192. if ((redirect_flag == 1) || (redirect_flag == 2))
  193. {
  194. if (execvp(redirect_args[0], redirect_args) <= 0)
  195. {
  196. printf("%s: Command not found\n", args[0]);
  197. exit(0);
  198. }
  199. close(fd);
  200. }
  201. else
  202. {
  203. if (execvp(args[0], args) <= 0)
  204. {
  205. printf("%s: Command not found\n", args[0]);
  206. exit(0);
  207. }
  208. }
  209. }
  210. else /* parent process */
  211. {
  212. if (bg)
  213. {
  214. signal(SIGCHLD, SIG_IGN);
  215. }
  216. else
  217. {
  218. waitpid(pid, NULL, 0);
  219. }
  220. return 1;
  221. }
  222. }
  223. }
  224. else
  225. {
  226. int fds[2];
  227. pipe(fds);
  228. pid_t prog_1, prog_2;
  229. printf("%s %s %s %s", pipe_arg_1[0], pipe_arg_1[1], pipe_arg_1[2], pipe_arg_1[3]);
  230. if ((prog_1 = fork()) == 0) /* Child process 1 */
  231. {
  232. close(1);
  233. dup(fds[1]);
  234. close(fds[0]);
  235. close(fds[1]);
  236. if (execvp(pipe_arg_1[0], pipe_arg_1) <= 0)
  237. {
  238. printf("%s: Command not found\n", pipe_arg_1[0]);
  239. exit(0);
  240. }
  241. }
  242. if ((prog_2 = fork()) == 0) /* Child process 1 */
  243. {
  244. dup2(fds[0], 0);
  245. close(fds[0]);
  246. close(fds[1]);
  247. if (execvp(pipe_arg_2[0], pipe_arg_2) <= 0)
  248. {
  249. printf("%s: Command not found\n", pipe_arg_2[0]);
  250. exit(0);
  251. }
  252. }
  253. close(fds[0]);
  254. close(fds[1]);
  255. waitpid(prog_1, NULL, 0);
  256. waitpid(prog_2, NULL, 0);
  257. return 1;
  258. }
  259. return 0;
  260. }
  261. int built_in(char **args)
  262. {
  263. if (!strcmp(args[0], "exit"))
  264. {
  265. exit(0);
  266. }
  267. else if (!strcmp(args[0], "cd"))
  268. {
  269. return builtin_cd(args);
  270. }
  271. else if (!strcmp(args[0], "history"))
  272. {
  273. return builtin_history(args);
  274. }
  275. else if (!strcmp(args[0], "mytop"))
  276. {
  277. int flag = builtin_mytop();
  278. if (flag == -1)
  279. {
  280. printf("yeeshell: unable to get memory info.\n");
  281. }
  282. else if (flag == -2)
  283. {
  284. printf("yeeshell: unable to get CPU info.\n");
  285. }
  286. return flag;
  287. }
  288. else
  289. {
  290. return 0;
  291. }
  292. }
  293. int builtin_cd(char **args)
  294. {
  295. if (args[1] == NULL)
  296. {
  297. return 1;
  298. }
  299. else
  300. {
  301. if (chdir(args[1]) != 0)
  302. {
  303. perror("yeeshell");
  304. }
  305. return 1;
  306. }
  307. }
  308. int builtin_history(char **args)
  309. {
  310. int n = 0;
  311. if (args[1] == NULL)
  312. {
  313. n = cmdline_amount;
  314. }
  315. else
  316. {
  317. n = atoi(args[1]) < cmdline_amount ? atoi(args[1]) : cmdline_amount;
  318. }
  319. printf("ID\tCommandline\n");
  320. for (int i = 0; i < n; i++)
  321. {
  322. printf("%d\t%s\n", i + 1, history[i]);
  323. }
  324. return 1;
  325. }
  326. int builtin_mytop()
  327. {
  328. int memory_flag = 0, CPU_flag = 0;
  329. memory_flag = mytop_memory();
  330. CPU_flag = mytop_CPU();
  331. if (!memory_flag)
  332. {
  333. return -1;
  334. }
  335. else if (!CPU_flag)
  336. {
  337. return -2;
  338. }
  339. else
  340. {
  341. return 1;
  342. }
  343. }
  344. int mytop_memory()
  345. {
  346. FILE *fp = NULL;
  347. int pagesize;
  348. long total = 0, free = 0, cached = 0;
  349. if ((fp = fopen("/proc/meminfo", "r")) == NULL)
  350. {
  351. return 0;
  352. }
  353. fscanf(fp, "%u %lu %lu %lu", &pagesize, &total, &free, &cached);
  354. fclose(fp);
  355. printf("memmory(KBytes):\t%ld total\t%ld free\t%ld cached\n", (pagesize * total) / 1024, (pagesize * free) / 1024, (pagesize * cached) / 1024);
  356. return 1;
  357. }
  358. int mytop_CPU()
  359. {
  360. }