diff options
author | LAN-TW <lantw44@gmail.com> | 2013-11-08 22:23:05 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-11-08 22:23:05 +0800 |
commit | fd763cb09eb6432e37c8431f27f5cad4f7d1a970 (patch) | |
tree | 3a4fc53d921d1181328f36b8805e60848a10e05a | |
parent | b7eb7efd85d58c1aa73799cea25de5faecbec734 (diff) | |
download | cn2013-fd763cb09eb6432e37c8431f27f5cad4f7d1a970.tar.gz cn2013-fd763cb09eb6432e37c8431f27f5cad4f7d1a970.tar.zst cn2013-fd763cb09eb6432e37c8431f27f5cad4f7d1a970.zip |
HW1: 用 POSIX 的 getline 函式代替原本的讀取輸入函式、修正 memory leak
-rw-r--r-- | hw1/shell.c | 61 |
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); } |