Changeset 54d4b9e in mainline for uspace/app/bdsh/input.c
- Timestamp:
- 2011-06-17T17:53:05Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dec55ce
- Parents:
- 8d12065 (diff), 98caf49 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/input.c
r8d12065 r54d4b9e 1 /* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> 1 /* 2 * Copyright (c) 2008 Tim Post 2 3 * All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions 7 * are met: 6 8 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 9 16 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of the original program's authors nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 27 */ 30 28 … … 50 48 #include "errors.h" 51 49 #include "exec.h" 50 #include "tok.h" 52 51 53 52 extern volatile unsigned int cli_quit; … … 55 54 /** Text input field. */ 56 55 static tinput_t *tinput; 56 57 /* Private helpers */ 58 static int run_command(char **, cliuser_t *, iostate_t *); 59 static void print_pipe_usage(void); 57 60 58 61 /* Tokenizes input from console, sees if the first word is a built-in, if so 59 62 * invokes the built-in entry point (a[0]) passing all arguments in a[] to 60 63 * the handler */ 61 int tok_input(cliuser_t *usr)64 int process_input(cliuser_t *usr) 62 65 { 63 66 char *cmd[WORD_MAX]; 64 int n = 0, i = 0;65 67 int rc = 0; 66 char *tmp; 68 tokenizer_t tok; 69 int i, pipe_count, processed_pipes; 70 int pipe_pos[2]; 71 char **actual_cmd; 72 char *redir_from = NULL; 73 char *redir_to = NULL; 67 74 68 75 if (NULL == usr->line) 69 76 return CL_EFAIL; 70 77 71 tmp = str_dup(usr->line); 72 73 cmd[n] = strtok(tmp, " "); 74 while (cmd[n] && n < WORD_MAX) { 75 cmd[++n] = strtok(NULL, " "); 76 } 77 78 /* We have rubbish */ 79 if (NULL == cmd[0]) { 80 rc = CL_ENOENT; 81 goto finit; 82 } 83 84 /* Its a builtin command ? */ 85 if ((i = (is_builtin(cmd[0]))) > -1) { 86 rc = run_builtin(i, cmd, usr); 87 goto finit; 88 /* Its a module ? */ 89 } else if ((i = (is_module(cmd[0]))) > -1) { 90 rc = run_module(i, cmd); 91 goto finit; 92 } 93 94 /* See what try_exec thinks of it */ 95 rc = try_exec(cmd[0], cmd); 96 78 rc = tok_init(&tok, usr->line, cmd, WORD_MAX); 79 if (rc != EOK) { 80 goto finit; 81 } 82 83 rc = tok_tokenize(&tok); 84 if (rc != EOK) { 85 goto finit; 86 } 87 88 /* Until full support for pipes is implemented, allow for a simple case: 89 * [from <file> |] command [| to <file>] 90 * 91 * First find the pipes and check that there are no more 92 */ 93 int cmd_length = 0; 94 for (i = 0, pipe_count = 0; cmd[i] != NULL; i++, cmd_length++) { 95 if (cmd[i][0] == '|') { 96 if (pipe_count >= 2) { 97 print_pipe_usage(); 98 rc = ENOTSUP; 99 goto finit; 100 } 101 pipe_pos[pipe_count] = i; 102 pipe_count++; 103 } 104 } 105 106 actual_cmd = cmd; 107 processed_pipes = 0; 108 109 /* Check if the first part (from <file> |) is present */ 110 if (pipe_count > 0 && pipe_pos[0] == 2 && str_cmp(cmd[0], "from") == 0) { 111 /* Ignore the first three tokens (from, file, pipe) and set from */ 112 redir_from = cmd[1]; 113 actual_cmd = cmd + 3; 114 processed_pipes++; 115 } 116 117 /* Check if the second part (| to <file>) is present */ 118 if ((pipe_count - processed_pipes) > 0 && 119 pipe_pos[processed_pipes] == cmd_length - 3 && 120 str_cmp(cmd[cmd_length-2], "to") == 0) { 121 /* Ignore the last three tokens (pipe, to, file) and set to */ 122 redir_to = cmd[cmd_length-1]; 123 cmd[cmd_length-3] = NULL; 124 cmd_length -= 3; 125 processed_pipes++; 126 } 127 128 if (processed_pipes != pipe_count) { 129 print_pipe_usage(); 130 rc = ENOTSUP; 131 goto finit; 132 } 133 134 if (actual_cmd[0] == NULL) { 135 print_pipe_usage(); 136 rc = ENOTSUP; 137 goto finit; 138 } 139 140 iostate_t new_iostate = { 141 .stdin = stdin, 142 .stdout = stdout, 143 .stderr = stderr 144 }; 145 146 FILE *from = NULL; 147 FILE *to = NULL; 148 149 if (redir_from) { 150 from = fopen(redir_from, "r"); 151 if (from == NULL) { 152 printf("Cannot open file %s\n", redir_from); 153 rc = errno; 154 goto finit_with_files; 155 } 156 new_iostate.stdin = from; 157 } 158 159 160 if (redir_to) { 161 to = fopen(redir_to, "w"); 162 if (to == NULL) { 163 printf("Cannot open file %s\n", redir_to); 164 rc = errno; 165 goto finit_with_files; 166 } 167 new_iostate.stdout = to; 168 } 169 170 rc = run_command(cmd, usr, &new_iostate); 171 172 finit_with_files: 173 if (from != NULL) { 174 fclose(from); 175 } 176 if (to != NULL) { 177 fclose(to); 178 } 179 97 180 finit: 98 181 if (NULL != usr->line) { … … 100 183 usr->line = (char *) NULL; 101 184 } 102 if (NULL != tmp) 103 free(tmp); 185 tok_fini(&tok); 104 186 105 187 return rc; 188 } 189 190 void print_pipe_usage() 191 { 192 printf("Invalid syntax!\n"); 193 printf("Usage of redirection (pipes in the future):\n"); 194 printf("from filename | command ...\n"); 195 printf("from filename | command ... | to filename\n"); 196 printf("command ... | to filename\n"); 197 198 } 199 200 int run_command(char **cmd, cliuser_t *usr, iostate_t *new_iostate) 201 { 202 int id = 0; 203 204 /* We have rubbish */ 205 if (NULL == cmd[0]) { 206 return CL_ENOENT; 207 } 208 209 /* Is it a builtin command ? */ 210 if ((id = (is_builtin(cmd[0]))) > -1) { 211 return run_builtin(id, cmd, usr, new_iostate); 212 } 213 214 /* Is it a module ? */ 215 if ((id = (is_module(cmd[0]))) > -1) { 216 return run_module(id, cmd, new_iostate); 217 } 218 219 /* See what try_exec thinks of it */ 220 return try_exec(cmd[0], cmd, new_iostate); 106 221 } 107 222
Note:
See TracChangeset
for help on using the changeset viewer.