summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-11-08 22:23:05 +0800
committerLAN-TW <lantw44@gmail.com>2013-11-08 22:23:05 +0800
commitfd763cb09eb6432e37c8431f27f5cad4f7d1a970 (patch)
tree3a4fc53d921d1181328f36b8805e60848a10e05a
parentb7eb7efd85d58c1aa73799cea25de5faecbec734 (diff)
downloadcn2013-fd763cb09eb6432e37c8431f27f5cad4f7d1a970.tar.gz
cn2013-fd763cb09eb6432e37c8431f27f5cad4f7d1a970.tar.zst
cn2013-fd763cb09eb6432e37c8431f27f5cad4f7d1a970.zip
HW1: 用 POSIX 的 getline 函式代替原本的讀取輸入函式、修正 memory leak
-rw-r--r--hw1/shell.c61
1 files changed, 32 insertions, 29 deletions
diff --git a/hw1/shell.c b/hw1/shell.c
index 327706b..3cbecc2 100644
--- a/hw1/shell.c
+++ b/hw1/shell.c
@@ -81,7 +81,7 @@ static void ras_shell_cmd_comp_destroy (RasShellCmdComp* comp) {
array_free (comp->tapipe);
}
-static void complete_string (Array*** ws, int* append,
+static void complete_string (Array*** ws, int* append, bool* committed,
RasShellCmdComp* comp, bool allow_empty, bool reinit) {
if (!allow_empty && array_getmax (*ws[*append]) <= 0) {
@@ -95,15 +95,18 @@ static void complete_string (Array*** ws, int* append,
array_pushback (comp->arg, &str);
if (reinit) {
*ws[*append] = array_create (sizeof (char), 0);
+ *committed = false;
+ } else {
+ *committed = true;
}
}
*append = APPEND_STR;
}
-static void complete_component (Array*** ws, int* append,
+static void complete_component (Array*** ws, int* append, bool* committed,
RasShellCmdComp* comp, RasShellCmd* cmd, bool allow_empty, bool reinit) {
- complete_string (ws, append, comp, allow_empty, reinit);
+ complete_string (ws, append, committed, comp, allow_empty, reinit);
char* null = NULL;
array_pushback (comp->arg, &null);
@@ -121,6 +124,7 @@ static int ras_shell_cmd_parse (
bool is_escaped = false;
bool ignore_esc = false;
bool allow_empty = false;
+ bool committed = false;
char quote_char = '\0';
int append = APPEND_STR; /* current working string */
@@ -163,7 +167,7 @@ static int ras_shell_cmd_parse (
}
if (isspace (*p)) {
/* complete a string */
- complete_string (ws, &append, &comp, allow_empty, true);
+ complete_string (ws, &append, &committed, &comp, allow_empty, true);
allow_empty = false;
continue;
}
@@ -193,7 +197,8 @@ static int ras_shell_cmd_parse (
append = APPEND_TAPIPE;
} else {
/* complete a component */
- complete_component (ws, &append, &comp, cmd, allow_empty, true);
+ complete_component (ws, &append, &committed,
+ &comp, cmd, allow_empty, true);
}
continue;
default:
@@ -201,12 +206,11 @@ static int ras_shell_cmd_parse (
}
}
- if (append != APPEND_STR) {
+ complete_component (ws, &append, &committed, &comp, cmd, allow_empty, false);
+ if (!committed) {
array_free (str);
}
- complete_component (ws, &append, &comp, cmd, allow_empty, false);
-
return 0;
}
@@ -291,11 +295,7 @@ static int ras_shell_cmd_run (
if (saved->to == shell->count) {
if (!tamatched) {
char* myname = xstrdup ("tacat");
- tacomp.arg = array_create (sizeof (char*), 0);
- tacomp.redir_stdin = array_create (sizeof (char), 0);
- tacomp.redir_stdout = array_create (sizeof (char), 0);
- tacomp.redir_stderr = array_create (sizeof (char), 0);
- tacomp.tapipe = array_create (sizeof (char), 0);
+ ras_shell_cmd_comp_init (&tacomp);
array_pushback (tacomp.arg, &myname);
tamatched = true;
}
@@ -699,44 +699,47 @@ int ras_shell_main (int argc, char* argv[]) {
fflush (stdout);
free (cwd);
- Array* cmdstr = NULL;
+ char* cmdstr = NULL;
+ size_t cmdsize = 0;
RasShellCmd cmd;
- cmdstr = array_readline ();
- if (cmdstr == NULL || feof (stdin)) {
- shell.req_exit = true;
- shell.req_exit_status = 0;
- array_free (cmdstr);
+ if (getline (&cmdstr, &cmdsize, stdin) < 0) {
+ if (feof (stdin)) {
+ shell.req_exit = true;
+ shell.req_exit_status = 0;
+ free (cmdstr);
+ }
continue;
}
+
bool empty = true;
- for (char* p = array_data (cmdstr); *p != '\0'; p++) {
+ for (char* p = cmdstr; *p != '\0'; p++) {
if (!isspace (*p)) {
empty = false;
break;
}
}
if (empty) {
- array_free (cmdstr);
+ free (cmdstr);
shell.count--;
continue;
}
if (shell.attr_rshell) {
- if (strchr (STR (array_data (cmdstr)), '/') != NULL) {
+ if (strchr (cmdstr, '/') != NULL) {
fprintf (stderr,
"%s: you are not permitted to use `/\' in command\n",
shell.name);
- array_free (cmdstr);
+ free (cmdstr);
continue;
}
}
if (ras_shell_cmd_parse (
- &cmd, array_data (cmdstr), ras_shell_cmd_read, NULL) < 0) {
- fprintf (stderr, "%s: cannot parse command `%s\'\n",
- shell.name, STR (array_data (cmdstr)));
- array_free (cmdstr);
+ &cmd, cmdstr, ras_shell_cmd_read, NULL) < 0) {
+ fprintf (stderr, "%s: cannot parse command `%s\'\n",
+ shell.name, cmdstr);
+ free (cmdstr);
continue;
}
@@ -744,9 +747,9 @@ int ras_shell_main (int argc, char* argv[]) {
ras_shell_cmd_print (&cmd);
}
- shell.last_rval = ras_shell_cmd_run (&cmd, &shell, array_data (cmdstr));
+ shell.last_rval = ras_shell_cmd_run (&cmd, &shell, cmdstr);
- array_free (cmdstr);
+ free (cmdstr);
ras_shell_cmd_destroy (&cmd);
}