-
Notifications
You must be signed in to change notification settings - Fork 0
/
read_cmd.c
69 lines (57 loc) · 1.92 KB
/
read_cmd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **read_cmd(int *argc, bool *exec_bg) {
const int BUFSIZE = 1024;
const char TOK_DELIM[] = " \t\r\n\a";
int arg_cnt = 0, max_argc = 10;
// char input[BUFSIZE];
char *input = malloc(sizeof(char) * BUFSIZE);
char **argv = malloc(max_argc * sizeof(char *));
// input
printf("rcsh> ");
if (fgets(input, BUFSIZE, stdin) == NULL) {
return NULL;
}
input[strlen(input) - 1] = '\0';
// バックグラウンド実行のフラグを設定
// 同時に引数から&記号を削除
char *pos_and;
if ((pos_and = strchr(input, '&')) != NULL) {
*exec_bg = true;
*pos_and = '\0';
}
// strtokは2回目の呼び出しではTOK_DELIMを一切含まない最初の部分をinputから切り出す
//この際word直後のTOK_DELIM文字は\0に置き換えられる
char *word = strtok(input, TOK_DELIM);
argv[arg_cnt++] = word;
while ((word = strtok(NULL, TOK_DELIM))) {
argv[arg_cnt++] = word;
//引数の個数が配列の要素数より多かった時の対処
if (arg_cnt >= max_argc) {
max_argc *= 2;
// reallocは第1引数の内容をコピーした新しい領域を返す.
argv = realloc(argv, max_argc * sizeof(char *));
if (argv == NULL) {
fprintf(stderr, "rcsh: allocation error\n");
exit(1);
}
}
}
// execvは最後にNULLが入っていないと動作しないので末尾にNULLを追加
if (argv[arg_cnt] != NULL) {
argv = realloc(argv, (arg_cnt + 1) * sizeof(char *));
argv[arg_cnt] = NULL;
}
// 入力が\nなど空白だった場合の処理
if (argv[0] == NULL) {
arg_cnt--;
}
*argc = arg_cnt;
return argv;
}
void free_argv(char **argv) {
free(*argv);
free(argv);
}