Changes in uspace/app/bdsh/input.c [5db9084:b2727f18] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/input.c
r5db9084 rb2727f18 1 /* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> 1 /* 2 * Copyright (c) 2008 Tim Post 3 * Copyright (c) 2011 Jiri Svoboda 4 * Copyright (c) 2011 Martin Sucha 2 5 * All rights reserved. 3 6 * 4 7 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 8 * modification, are permitted provided that the following conditions 9 * are met: 6 10 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * - The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 9 18 * 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. 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 29 */ 30 30 … … 45 45 46 46 #include "config.h" 47 #include "compl.h" 47 48 #include "util.h" 48 49 #include "scli.h" … … 50 51 #include "errors.h" 51 52 #include "exec.h" 53 #include "tok.h" 52 54 53 55 extern volatile unsigned int cli_quit; … … 55 57 /** Text input field. */ 56 58 static tinput_t *tinput; 59 60 /* Private helpers */ 61 static int run_command(char **, cliuser_t *, iostate_t *); 62 static void print_pipe_usage(void); 57 63 58 64 /* Tokenizes input from console, sees if the first word is a built-in, if so 59 65 * invokes the built-in entry point (a[0]) passing all arguments in a[] to 60 66 * the handler */ 61 int tok_input(cliuser_t *usr)67 int process_input(cliuser_t *usr) 62 68 { 63 69 char *cmd[WORD_MAX]; 64 int n = 0, i = 0; 70 token_t tokens_space[WORD_MAX]; 71 token_t *tokens = tokens_space; 65 72 int rc = 0; 66 char *tmp; 73 tokenizer_t tok; 74 unsigned int i, pipe_count, processed_pipes; 75 unsigned int pipe_pos[2]; 76 char *redir_from = NULL; 77 char *redir_to = NULL; 67 78 68 79 if (NULL == usr->line) 69 80 return CL_EFAIL; 70 81 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 82 rc = tok_init(&tok, usr->line, tokens, WORD_MAX); 83 if (rc != EOK) { 84 goto finit; 85 } 86 87 size_t tokens_length; 88 rc = tok_tokenize(&tok, &tokens_length); 89 if (rc != EOK) { 90 goto finit; 91 } 92 93 if (tokens_length > 0 && tokens[0].type == TOKTYPE_SPACE) { 94 tokens++; 95 tokens_length--; 96 } 97 98 if (tokens_length > 0 && tokens[tokens_length-1].type == TOKTYPE_SPACE) { 99 tokens_length--; 100 } 101 102 /* Until full support for pipes is implemented, allow for a simple case: 103 * [from <file> |] command [| to <file>] 104 * 105 * First find the pipes and check that there are no more 106 */ 107 for (i = 0, pipe_count = 0; i < tokens_length; i++) { 108 if (tokens[i].type == TOKTYPE_PIPE) { 109 if (pipe_count >= 2) { 110 print_pipe_usage(); 111 rc = ENOTSUP; 112 goto finit; 113 } 114 pipe_pos[pipe_count] = i; 115 pipe_count++; 116 } 117 } 118 119 unsigned int cmd_token_start = 0; 120 unsigned int cmd_token_end = tokens_length; 121 122 processed_pipes = 0; 123 124 /* Check if the first part (from <file> |) is present */ 125 if (pipe_count > 0 && (pipe_pos[0] == 3 || pipe_pos[0] == 4) && str_cmp(tokens[0].text, "from") == 0) { 126 /* Ignore the first three tokens (from, file, pipe) and set from */ 127 redir_from = tokens[2].text; 128 cmd_token_start = pipe_pos[0]+1; 129 processed_pipes++; 130 } 131 132 /* Check if the second part (| to <file>) is present */ 133 if ((pipe_count - processed_pipes) > 0 && 134 (pipe_pos[processed_pipes] == tokens_length - 4 || 135 (pipe_pos[processed_pipes] == tokens_length - 5 && 136 tokens[tokens_length-4].type == TOKTYPE_SPACE )) && 137 str_cmp(tokens[tokens_length-3].text, "to") == 0) { 138 /* Ignore the last three tokens (pipe, to, file) and set to */ 139 redir_to = tokens[tokens_length-1].text; 140 cmd_token_end = pipe_pos[processed_pipes]; 141 processed_pipes++; 142 } 143 144 if (processed_pipes != pipe_count) { 145 print_pipe_usage(); 146 rc = ENOTSUP; 147 goto finit; 148 } 149 150 /* Convert tokens of the command to string array */ 151 unsigned int cmd_pos = 0; 152 for (i = cmd_token_start; i < cmd_token_end; i++) { 153 if (tokens[i].type != TOKTYPE_SPACE) { 154 cmd[cmd_pos++] = tokens[i].text; 155 } 156 } 157 cmd[cmd_pos++] = NULL; 158 159 if (cmd[0] == NULL) { 160 print_pipe_usage(); 161 rc = ENOTSUP; 162 goto finit; 163 } 164 165 iostate_t new_iostate = { 166 .stdin = stdin, 167 .stdout = stdout, 168 .stderr = stderr 169 }; 170 171 FILE *from = NULL; 172 FILE *to = NULL; 173 174 if (redir_from) { 175 from = fopen(redir_from, "r"); 176 if (from == NULL) { 177 printf("Cannot open file %s\n", redir_from); 178 rc = errno; 179 goto finit_with_files; 180 } 181 new_iostate.stdin = from; 182 } 183 184 185 if (redir_to) { 186 to = fopen(redir_to, "w"); 187 if (to == NULL) { 188 printf("Cannot open file %s\n", redir_to); 189 rc = errno; 190 goto finit_with_files; 191 } 192 new_iostate.stdout = to; 193 } 194 195 rc = run_command(cmd, usr, &new_iostate); 196 197 finit_with_files: 198 if (from != NULL) { 199 fclose(from); 200 } 201 if (to != NULL) { 202 fclose(to); 203 } 204 97 205 finit: 98 206 if (NULL != usr->line) { … … 100 208 usr->line = (char *) NULL; 101 209 } 102 if (NULL != tmp) 103 free(tmp); 210 tok_fini(&tok); 104 211 105 212 return rc; 213 } 214 215 void print_pipe_usage() 216 { 217 printf("Invalid syntax!\n"); 218 printf("Usage of redirection (pipes in the future):\n"); 219 printf("from filename | command ...\n"); 220 printf("from filename | command ... | to filename\n"); 221 printf("command ... | to filename\n"); 222 223 } 224 225 int run_command(char **cmd, cliuser_t *usr, iostate_t *new_iostate) 226 { 227 int id = 0; 228 229 /* We have rubbish */ 230 if (NULL == cmd[0]) { 231 return CL_ENOENT; 232 } 233 234 /* Is it a builtin command ? */ 235 if ((id = (is_builtin(cmd[0]))) > -1) { 236 return run_builtin(id, cmd, usr, new_iostate); 237 } 238 239 /* Is it a module ? */ 240 if ((id = (is_module(cmd[0]))) > -1) { 241 return run_module(id, cmd, new_iostate); 242 } 243 244 /* See what try_exec thinks of it */ 245 return try_exec(cmd[0], cmd, new_iostate); 106 246 } 107 247 … … 110 250 char *str; 111 251 int rc; 112 113 fflush(stdout); 114 console_set_style(fphone(stdout), STYLE_EMPHASIS); 115 printf("%s", usr->prompt); 116 fflush(stdout); 117 console_set_style(fphone(stdout), STYLE_NORMAL); 252 253 tinput_set_prompt(tinput, usr->prompt); 118 254 119 255 rc = tinput_read(tinput, &str); … … 148 284 } 149 285 286 tinput_set_compl_ops(tinput, &compl_ops); 287 150 288 return 0; 151 289 }
Note:
See TracChangeset
for help on using the changeset viewer.