Changes in uspace/app/bdsh/input.c [b48d046:5db9084] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/input.c
rb48d046 r5db9084 1 /* 2 * Copyright (c) 2008 Tim Post 3 * Copyright (c) 2011 Jiri Svoboda 4 * Copyright (c) 2011 Martin Sucha 1 /* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> 5 2 * All rights reserved. 6 3 * 7 4 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 5 * modification, are permitted provided that the following conditions are met: 10 6 * 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. 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 18 9 * 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. 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. 29 29 */ 30 30 … … 45 45 46 46 #include "config.h" 47 #include "compl.h"48 47 #include "util.h" 49 48 #include "scli.h" … … 51 50 #include "errors.h" 52 51 #include "exec.h" 53 #include "tok.h"54 52 55 53 extern volatile unsigned int cli_quit; … … 58 56 static tinput_t *tinput; 59 57 60 /* Private helpers */61 static int run_command(char **, cliuser_t *, iostate_t *);62 static void print_pipe_usage(void);63 64 58 /* Tokenizes input from console, sees if the first word is a built-in, if so 65 59 * invokes the built-in entry point (a[0]) passing all arguments in a[] to 66 60 * the handler */ 67 int process_input(cliuser_t *usr)61 int tok_input(cliuser_t *usr) 68 62 { 69 token_t *tokens = calloc(WORD_MAX, sizeof(token_t));70 if (tokens == NULL)71 return ENOMEM;72 73 63 char *cmd[WORD_MAX]; 64 int n = 0, i = 0; 74 65 int rc = 0; 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; 66 char *tmp; 80 67 81 if (usr->line == NULL) { 82 free(tokens); 68 if (NULL == usr->line) 83 69 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, " "); 84 76 } 85 77 86 rc = tok_init(&tok, usr->line, tokens, WORD_MAX); 87 if (rc != EOK) { 78 /* We have rubbish */ 79 if (NULL == cmd[0]) { 80 rc = CL_ENOENT; 88 81 goto finit; 89 82 } 90 91 size_t tokens_length; 92 rc = tok_tokenize(&tok, &tokens_length); 93 if (rc != EOK) { 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); 94 91 goto finit; 95 92 } 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 93 94 /* See what try_exec thinks of it */ 95 rc = try_exec(cmd[0], cmd); 96 209 97 finit: 210 98 if (NULL != usr->line) { … … 212 100 usr->line = (char *) NULL; 213 101 } 214 tok_fini(&tok);215 free(tokens);102 if (NULL != tmp) 103 free(tmp); 216 104 217 105 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);251 106 } 252 107 … … 255 110 char *str; 256 111 int rc; 257 258 tinput_set_prompt(tinput, usr->prompt); 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); 259 118 260 119 rc = tinput_read(tinput, &str); … … 289 148 } 290 149 291 tinput_set_compl_ops(tinput, &compl_ops);292 293 150 return 0; 294 151 }
Note:
See TracChangeset
for help on using the changeset viewer.