diff options
author | LAN-TW <lantw44@gmail.com> | 2013-11-08 17:31:35 +0800 |
---|---|---|
committer | b01902062 <b01902062@linux5.csie.ntu.edu.tw> | 2013-11-08 17:32:08 +0800 |
commit | 328e88167e396b8d72e88019c67b7391ad7f601a (patch) | |
tree | 9884301d4e23630c5fc7e8098f508a228ac134bd | |
parent | d3160db062ac5ed2106b317ade5e6ccf4afcd958 (diff) | |
download | cn2013-328e88167e396b8d72e88019c67b7391ad7f601a.tar.gz cn2013-328e88167e396b8d72e88019c67b7391ad7f601a.tar.zst cn2013-328e88167e396b8d72e88019c67b7391ad7f601a.zip |
HW1: 支援寫入 TA pipe 檔案,並修正 parse command memory leak
-rw-r--r-- | hw1/shell-builtin.c | 13 | ||||
-rw-r--r-- | hw1/shell-builtin.h | 1 | ||||
-rw-r--r-- | hw1/shell.c | 84 | ||||
-rw-r--r-- | hw1/shell.h | 6 |
4 files changed, 93 insertions, 11 deletions
diff --git a/hw1/shell-builtin.c b/hw1/shell-builtin.c index 599f2c2..7d5abb0 100644 --- a/hw1/shell-builtin.c +++ b/hw1/shell-builtin.c @@ -7,6 +7,7 @@ #include "xwrap.h" #include <errno.h> +#include <inttypes.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -25,6 +26,7 @@ const RasShellBuiltin ras_shell_builtins[] = { RAS_SHELL_BUILTIN_ENTRY (set), RAS_SHELL_BUILTIN_ENTRY (setenv), RAS_SHELL_BUILTIN_ENTRY (shopt), + RAS_SHELL_BUILTIN_ENTRY (tapipe), RAS_SHELL_BUILTIN_ENTRY (umask), RAS_SHELL_BUILTIN_ENTRY (unset), RAS_SHELL_BUILTIN_ENTRY (unsetenv), @@ -215,6 +217,17 @@ int ras_shell_builtin_umask (int argc, char* argv[], RasShell* shell) { return 0; } +int ras_shell_builtin_tapipe (int argc, char* argv[], RasShell* shell) { + ListNode* iter = list_node_front (shell->saved_list); + for (; iter != NULL; iter = list_next (iter)) { + RasShellSaved* saved = list_data (iter); + printf ("Command %" PRIu64 " input == " + "Command %" PRIu64 " output (%s)\n", + saved->to, saved->from, saved->cmdorg); + } + return 0; +} + int ras_shell_builtin_unset (int argc, char* argv[], RasShell* shell) { fputs ("This command has not been implemented. Try `unsetenv\'.\n", stderr); return 1; diff --git a/hw1/shell-builtin.h b/hw1/shell-builtin.h index f965359..8fb1a77 100644 --- a/hw1/shell-builtin.h +++ b/hw1/shell-builtin.h @@ -26,6 +26,7 @@ RAS_SHELL_BUILTIN_DECL (pwd); RAS_SHELL_BUILTIN_DECL (set); RAS_SHELL_BUILTIN_DECL (setenv); RAS_SHELL_BUILTIN_DECL (shopt); +RAS_SHELL_BUILTIN_DECL (tapipe); RAS_SHELL_BUILTIN_DECL (umask); RAS_SHELL_BUILTIN_DECL (unset); RAS_SHELL_BUILTIN_DECL (unsetenv); diff --git a/hw1/shell.c b/hw1/shell.c index f9728c4..d5791ba 100644 --- a/hw1/shell.c +++ b/hw1/shell.c @@ -37,12 +37,6 @@ #define STR(x) ((char*)(x)) typedef struct { - uint64_t count; - char* reason; - char file[]; -} RasShellSaved; - -typedef struct { Array* arg; /* NULL-terminated string array */ Array* redir_stdin; /* string */ Array* redir_stdout; /* string */ @@ -103,6 +97,7 @@ static void complete_string (Array*** ws, int* append, *ws[*append] = array_create (sizeof (char), 0); } } + printf ("%d\n", *append); *append = APPEND_STR; } @@ -207,6 +202,10 @@ static int ras_shell_cmd_parse ( } } + if (append != APPEND_STR) { + array_free (str); + } + complete_component (ws, &append, &comp, cmd, allow_empty, false); return 0; @@ -239,7 +238,50 @@ static void ras_shell_cmd_print (RasShellCmd* cmd) { } } -static int ras_shell_cmd_run (RasShellCmd* cmd, RasShell* shell) { +static int ras_shell_cmd_save ( + RasShellCmd* cmd, RasShell* shell, const char* cmdstr, int num) { + + char* outfile = xsprintf ("%s/%" PRIu64, shell->saved_tmpdir, shell->count); + int outfd = open (outfile, O_WRONLY | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + + if (outfd < 0 && errno == ENOENT) { + mkdir (shell->saved_tmpdir, S_IRWXU); + outfd = open (outfile, O_WRONLY | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + } + + if (outfd < 0) { + free (outfile); + return outfd; + } + + free (outfile); + + RasShellSaved saved = { + .from = shell->count, + .to = shell->count + num, + .cmdorg = xstrdup (cmdstr) + }; + bool inserted = false; + ListNode* iter = list_node_front (shell->saved_list); + + for (; iter != NULL; iter = list_next (iter)) { + if (RAS_SHELL_SAVED (list_data (iter))->to > saved.to) { + list_insert_prev (shell->saved_list, iter, &saved, sizeof (saved)); + inserted = true; + } + } + + if (!inserted) { + list_pushback (shell->saved_list, &saved, sizeof (saved)); + } + + return outfd; +} + +static int ras_shell_cmd_run ( + RasShellCmd* cmd, RasShell* shell, const char* cmdstr) { ListNode* iter = list_node_front (cmd->argrp); pid_t child; @@ -291,13 +333,17 @@ static int ras_shell_cmd_run (RasShellCmd* cmd, RasShell* shell) { } if (array_getlen (comp->tapipe)) { int tpnum; - sscanf (STR (array_data (comp->tapipe)) + 1, "%d", &tpnum); - if (tpnum < 1) { + if (sscanf (STR (array_data (comp->tapipe)), "%d", &tpnum) < 1) { fprintf (stderr, "%s: invalid TA pipe number `%s\'\n", shell->name, STR (array_data (comp->tapipe))); break; } - // TODO: TA pipe handling + outfile = ras_shell_cmd_save (cmd, shell, cmdstr, tpnum); + if (outfile < 0) { + fprintf (stderr, "%s: cannot setup TA pipe: %s\n", + shell->name, strerror (errno)); + break; + } } } @@ -360,6 +406,18 @@ static int ras_shell_cmd_run (RasShellCmd* cmd, RasShell* shell) { } else { /* child */ + struct sigaction sa = { + .sa_handler = SIG_DFL, + .sa_flags = 0 + }; + sigemptyset (&sa.sa_mask); + sigaction (SIGINT, &sa, NULL); + sigaction (SIGQUIT, &sa, NULL); + sigaction (SIGTSTP, &sa, NULL); + sigaction (SIGTTOU, &sa, NULL); + sigaction (SIGPIPE, &sa, NULL); + sigaction (SIGHUP, &sa, NULL); + pid_t pid = getpid (); if (cmd->pgid == 0) { cmd->pgid = pid; @@ -555,6 +613,10 @@ static int ras_shell_init (RasShell* shell, int argc, char* argv[]) { } static void ras_shell_destroy (RasShell* shell) { + ListNode* iter = list_node_front (shell->saved_list); + for (; iter != NULL; iter = list_next (iter)) { + free (RAS_SHELL_SAVED (list_data (iter))->cmdorg); + } list_free (shell->saved_list); free (shell->saved_tmpdir); free (shell->user_name); @@ -641,7 +703,7 @@ int ras_shell_main (int argc, char* argv[]) { ras_shell_cmd_print (&cmd); } - shell.last_rval = ras_shell_cmd_run (&cmd, &shell); + shell.last_rval = ras_shell_cmd_run (&cmd, &shell, array_data (cmdstr)); array_free (cmdstr); ras_shell_cmd_destroy (&cmd); diff --git a/hw1/shell.h b/hw1/shell.h index 4b9e343..5e5142c 100644 --- a/hw1/shell.h +++ b/hw1/shell.h @@ -28,6 +28,12 @@ typedef struct { struct termios tmode; /* shell terminal mode */ } RasShell; +typedef struct { + uint64_t from; + uint64_t to; + char* cmdorg; +} RasShellSaved; + typedef int (*RasShellFunc) (int argc, char* argv[], RasShell* shell); typedef char* (*RasShellRead) (void* data); |