Changes in uspace/app/bdsh/input.c [79ae36dd:b48d046] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/input.c
r79ae36dd rb48d046 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) 62 { 67 int process_input(cliuser_t *usr) 68 { 69 token_t *tokens = calloc(WORD_MAX, sizeof(token_t)); 70 if (tokens == NULL) 71 return ENOMEM; 72 63 73 char *cmd[WORD_MAX]; 64 int n = 0, i = 0;65 74 int rc = 0; 66 char *tmp; 67 68 if (NULL == usr->line) 75 tokenizer_t tok; 76 unsigned int i, pipe_count, processed_pipes; 77 unsigned int pipe_pos[2]; 78 char *redir_from = NULL; 79 char *redir_to = NULL; 80 81 if (usr->line == NULL) { 82 free(tokens); 69 83 return CL_EFAIL; 70 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 84 } 85 86 rc = tok_init(&tok, usr->line, tokens, WORD_MAX); 87 if (rc != EOK) { 88 goto finit; 89 } 90 91 size_t tokens_length; 92 rc = tok_tokenize(&tok, &tokens_length); 93 if (rc != EOK) { 94 goto finit; 95 } 96 97 if (tokens_length > 0 && tokens[0].type == TOKTYPE_SPACE) { 98 tokens++; 99 tokens_length--; 100 } 101 102 if (tokens_length > 0 && tokens[tokens_length-1].type == TOKTYPE_SPACE) { 103 tokens_length--; 104 } 105 106 /* Until full support for pipes is implemented, allow for a simple case: 107 * [from <file> |] command [| to <file>] 108 * 109 * First find the pipes and check that there are no more 110 */ 111 for (i = 0, pipe_count = 0; i < tokens_length; i++) { 112 if (tokens[i].type == TOKTYPE_PIPE) { 113 if (pipe_count >= 2) { 114 print_pipe_usage(); 115 rc = ENOTSUP; 116 goto finit; 117 } 118 pipe_pos[pipe_count] = i; 119 pipe_count++; 120 } 121 } 122 123 unsigned int cmd_token_start = 0; 124 unsigned int cmd_token_end = tokens_length; 125 126 processed_pipes = 0; 127 128 /* Check if the first part (from <file> |) is present */ 129 if (pipe_count > 0 && (pipe_pos[0] == 3 || pipe_pos[0] == 4) && str_cmp(tokens[0].text, "from") == 0) { 130 /* Ignore the first three tokens (from, file, pipe) and set from */ 131 redir_from = tokens[2].text; 132 cmd_token_start = pipe_pos[0]+1; 133 processed_pipes++; 134 } 135 136 /* Check if the second part (| to <file>) is present */ 137 if ((pipe_count - processed_pipes) > 0 && 138 (pipe_pos[processed_pipes] == tokens_length - 4 || 139 (pipe_pos[processed_pipes] == tokens_length - 5 && 140 tokens[tokens_length-4].type == TOKTYPE_SPACE )) && 141 str_cmp(tokens[tokens_length-3].text, "to") == 0) { 142 /* Ignore the last three tokens (pipe, to, file) and set to */ 143 redir_to = tokens[tokens_length-1].text; 144 cmd_token_end = pipe_pos[processed_pipes]; 145 processed_pipes++; 146 } 147 148 if (processed_pipes != pipe_count) { 149 print_pipe_usage(); 150 rc = ENOTSUP; 151 goto finit; 152 } 153 154 /* Convert tokens of the command to string array */ 155 unsigned int cmd_pos = 0; 156 for (i = cmd_token_start; i < cmd_token_end; i++) { 157 if (tokens[i].type != TOKTYPE_SPACE) { 158 cmd[cmd_pos++] = tokens[i].text; 159 } 160 } 161 cmd[cmd_pos++] = NULL; 162 163 if (cmd[0] == NULL) { 164 print_pipe_usage(); 165 rc = ENOTSUP; 166 goto finit; 167 } 168 169 iostate_t new_iostate = { 170 .stdin = stdin, 171 .stdout = stdout, 172 .stderr = stderr 173 }; 174 175 FILE *from = NULL; 176 FILE *to = NULL; 177 178 if (redir_from) { 179 from = fopen(redir_from, "r"); 180 if (from == NULL) { 181 printf("Cannot open file %s\n", redir_from); 182 rc = errno; 183 goto finit_with_files; 184 } 185 new_iostate.stdin = from; 186 } 187 188 189 if (redir_to) { 190 to = fopen(redir_to, "w"); 191 if (to == NULL) { 192 printf("Cannot open file %s\n", redir_to); 193 rc = errno; 194 goto finit_with_files; 195 } 196 new_iostate.stdout = to; 197 } 198 199 rc = run_command(cmd, usr, &new_iostate); 200 201 finit_with_files: 202 if (from != NULL) { 203 fclose(from); 204 } 205 if (to != NULL) { 206 fclose(to); 207 } 208 97 209 finit: 98 210 if (NULL != usr->line) { … … 100 212 usr->line = (char *) NULL; 101 213 } 102 if (NULL != tmp)103 free(tmp);214 tok_fini(&tok); 215 free(tokens); 104 216 105 217 return rc; 218 } 219 220 void print_pipe_usage() 221 { 222 printf("Invalid syntax!\n"); 223 printf("Usage of redirection (pipes in the future):\n"); 224 printf("from filename | command ...\n"); 225 printf("from filename | command ... | to filename\n"); 226 printf("command ... | to filename\n"); 227 228 } 229 230 int run_command(char **cmd, cliuser_t *usr, iostate_t *new_iostate) 231 { 232 int id = 0; 233 234 /* We have rubbish */ 235 if (NULL == cmd[0]) { 236 return CL_ENOENT; 237 } 238 239 /* Is it a builtin command ? */ 240 if ((id = (is_builtin(cmd[0]))) > -1) { 241 return run_builtin(id, cmd, usr, new_iostate); 242 } 243 244 /* Is it a module ? */ 245 if ((id = (is_module(cmd[0]))) > -1) { 246 return run_module(id, cmd, new_iostate); 247 } 248 249 /* See what try_exec thinks of it */ 250 return try_exec(cmd[0], cmd, new_iostate); 106 251 } 107 252 … … 111 256 int rc; 112 257 113 console_flush(tinput->console); 114 console_set_style(tinput->console, STYLE_EMPHASIS); 115 printf("%s", usr->prompt); 116 console_flush(tinput->console); 117 console_set_style(tinput->console, STYLE_NORMAL); 258 tinput_set_prompt(tinput, usr->prompt); 118 259 119 260 rc = tinput_read(tinput, &str); … … 148 289 } 149 290 291 tinput_set_compl_ops(tinput, &compl_ops); 292 150 293 return 0; 151 294 }
Note:
See TracChangeset
for help on using the changeset viewer.