Changeset f1fae414 in mainline for uspace/app/bdsh/input.c


Ignore:
Timestamp:
2011-06-22T01:34:53Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8d7e82c1, cac458f
Parents:
72ec8cc (diff), bf172825 (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.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/input.c

    r72ec8cc rf1fae414  
    1 /* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
     1/*
     2 * Copyright (c) 2008 Tim Post
    23 * All rights reserved.
    34 *
    45 * 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:
    68 *
    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.
    916 *
    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.
    2927 */
    3028
     
    5048#include "errors.h"
    5149#include "exec.h"
     50#include "tok.h"
    5251
    5352extern volatile unsigned int cli_quit;
     
    5554/** Text input field. */
    5655static tinput_t *tinput;
     56
     57/* Private helpers */
     58static int run_command(char **, cliuser_t *, iostate_t *);
     59static void print_pipe_usage(void);
    5760
    5861/* Tokenizes input from console, sees if the first word is a built-in, if so
    5962 * invokes the built-in entry point (a[0]) passing all arguments in a[] to
    6063 * the handler */
    61 int tok_input(cliuser_t *usr)
     64int process_input(cliuser_t *usr)
    6265{
    6366        char *cmd[WORD_MAX];
    64         int n = 0, i = 0;
    6567        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;
    6774
    6875        if (NULL == usr->line)
    6976                return CL_EFAIL;
    7077
    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       
     172finit_with_files:
     173        if (from != NULL) {
     174                fclose(from);
     175        }
     176        if (to != NULL) {
     177                fclose(to);
     178        }
     179       
    97180finit:
    98181        if (NULL != usr->line) {
     
    100183                usr->line = (char *) NULL;
    101184        }
    102         if (NULL != tmp)
    103                 free(tmp);
     185        tok_fini(&tok);
    104186
    105187        return rc;
     188}
     189
     190void 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
     200int 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);
    106221}
    107222
Note: See TracChangeset for help on using the changeset viewer.