Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 21b0013 in mainline


Ignore:
Timestamp:
2021-08-08T12:57:21Z (3 months ago)
Author:
Manuele Conti <manuele.conti@…>
Children:
932c640
Parents:
a106037
Message:

Start adding bdsh full pipes support

Location:
uspace/app/bdsh
Files:
3 edited

Legend:

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

    ra106037 r21b0013  
    6363/* Private helpers */
    6464static int run_command(char **, cliuser_t *, iostate_t *);
    65 static void print_pipe_usage(void);
    6665
    6766typedef struct {
     
    6968        alias_t *alias;
    7069} alias_hup_t;
    71 
     70#if 0
    7271static bool find_alias_hup(alias_t *alias, list_t *alias_hups)
    7372{
     
    8079        return false;
    8180}
    82 
     81#endif
    8382/*
    8483 * Tokenizes input from console, sees if the first word is a built-in, if so
     
    8887static errno_t process_input_nohup(cliuser_t *usr, list_t *alias_hups, size_t count_executed_hups)
    8988{
     89        char *cmd[WORD_MAX];
     90        size_t cmd_argc = 0;
     91        errno_t rc = EOK;
     92        tokenizer_t tok;
     93        unsigned int i, pipe_count;
     94        unsigned int pipe_pos[2];
     95        char *redir_from = NULL;
     96        char *redir_to = NULL;
     97
    9098        if (count_executed_hups >= HUBS_MAX) {
    9199                cli_error(CL_EFAIL, "%s: maximal alias hubs reached\n", PACKAGE_NAME);
     
    98106        token_t *tokens = tokens_buf;
    99107
    100         char *cmd[WORD_MAX];
    101         errno_t rc = EOK;
    102         tokenizer_t tok;
    103         unsigned int i, pipe_count, processed_pipes;
    104         unsigned int pipe_pos[2];
    105         char *redir_from = NULL;
    106         char *redir_to = NULL;
    107 
    108108        if (usr->line == NULL) {
    109109                free(tokens_buf);
     
    131131        }
    132132
    133         /*
    134          * Until full support for pipes is implemented, allow for a simple case:
    135          * [from <file> |] command [| to <file>]
    136          *
    137          * First find the pipes and check that there are no more
    138          */
     133        cmd_argc = tokens_length;
    139134        for (i = 0, pipe_count = 0; i < tokens_length; i++) {
    140                 if (tokens[i].type == TOKTYPE_PIPE) {
    141                         if (pipe_count >= 2) {
    142                                 print_pipe_usage();
    143                                 rc = ENOTSUP;
    144                                 goto finit;
    145                         }
    146                         pipe_pos[pipe_count] = i;
    147                         pipe_count++;
    148                 }
     135                switch (tokens[i].type) {
     136                case  TOKTYPE_PIPE:
     137                        pipe_pos[pipe_count++] = i;
     138                        cmd_argc = i;
     139                        redir_to = (char *)"/tmp/pipe";
     140                        break;
     141
     142                case TOKTYPE_RDIN:
     143                        redir_from = tokens[i + 1].text;
     144                        cmd_argc = i;
     145                        break;
     146
     147                case TOKTYPE_RDOU:
     148                        redir_to = tokens[i + 1].text;
     149                        cmd_argc = i;
     150                        break;
     151
     152                default:
     153                        break;
     154                }
     155
    149156        }
    150157
    151158        unsigned int cmd_token_start = 0;
    152         unsigned int cmd_token_end = tokens_length;
    153 
    154         processed_pipes = 0;
    155 
    156         /* Check if the first part (from <file> |) is present */
    157         if (pipe_count > 0 && (pipe_pos[0] == 3 || pipe_pos[0] == 4) && str_cmp(tokens[0].text, "from") == 0) {
    158                 /* Ignore the first three tokens (from, file, pipe) and set from */
    159                 redir_from = tokens[2].text;
    160                 cmd_token_start = pipe_pos[0] + 1;
    161                 processed_pipes++;
    162         }
    163 
    164         /* Check if the second part (| to <file>) is present */
    165         if ((pipe_count - processed_pipes) > 0 &&
    166             (pipe_pos[processed_pipes] == tokens_length - 4 ||
    167             (pipe_pos[processed_pipes] == tokens_length - 5 &&
    168             tokens[tokens_length - 4].type == TOKTYPE_SPACE)) &&
    169             str_cmp(tokens[tokens_length - 3].text, "to") == 0) {
    170                 /* Ignore the last three tokens (pipe, to, file) and set to */
    171                 redir_to = tokens[tokens_length - 1].text;
    172                 cmd_token_end = pipe_pos[processed_pipes];
    173                 processed_pipes++;
    174         }
    175 
    176         if (processed_pipes != pipe_count) {
    177                 print_pipe_usage();
    178                 rc = ENOTSUP;
    179                 goto finit;
    180         }
    181 
    182         /* Convert tokens of the command to string array */
    183         unsigned int cmd_pos = 0;
    184         for (i = cmd_token_start; i < cmd_token_end; i++) {
    185                 if (tokens[i].type != TOKTYPE_SPACE) {
    186                         cmd[cmd_pos++] = tokens[i].text;
    187                 }
    188         }
    189         cmd[cmd_pos++] = NULL;
    190 
    191         if (cmd[0] == NULL) {
    192                 print_pipe_usage();
    193                 rc = ENOTSUP;
    194                 goto finit;
    195         }
    196 
     159        unsigned int cmd_token_end = cmd_argc;
     160
     161#if 0
    197162        /* test if the passed cmd is an alias */
    198163        odlink_t *alias_link = odict_find_eq(&alias_dict, (void *)cmd[0], NULL);
     
    244209                }
    245210        }
     211#endif
    246212
    247213        iostate_t new_iostate = {
     
    274240        }
    275241
     242        for (unsigned p = 0; p < pipe_count; p++) {
     243                /* Convert tokens of the command to string array */
     244                unsigned int cmd_pos = 0;
     245                for (i = cmd_token_start; i < cmd_token_end; i++) {
     246                        if (tokens[i].type != TOKTYPE_SPACE) {
     247                                cmd[cmd_pos++] = tokens[i].text;
     248                        }
     249                }
     250                cmd[cmd_pos++] = NULL;
     251
     252                if (cmd[0] == NULL) {
     253                        printf("Command not found.\n");
     254                        rc = ENOTSUP;
     255                        goto finit;
     256                }
     257
     258                if (p < pipe_count - 1) {
     259                        new_iostate.stdout = to;
     260                } else {
     261                        new_iostate.stdin = to;
     262                }
     263
     264                if (run_command(cmd, usr, &new_iostate) == 0) {
     265                        rc = EOK;
     266                } else {
     267                        rc = EINVAL;
     268                }
     269
     270                // Restore the Standard Input, Output and Error file descriptors
     271                new_iostate.stdin = stdin;
     272                new_iostate.stdout = stdout;
     273                new_iostate.stderr = stderr;
     274
     275                cmd_token_start = cmd_token_end + 1;
     276                cmd_token_end = (p < pipe_count - 1) ? pipe_pos[p + 1] : tokens_length;
     277        }
     278
     279        unsigned int cmd_pos = 0;
     280        for (i = cmd_token_start; i < cmd_token_end; i++) {
     281                if (tokens[i].type != TOKTYPE_SPACE) {
     282                        cmd[cmd_pos++] = tokens[i].text;
     283                }
     284        }
     285        cmd[cmd_pos++] = NULL;
     286
     287        if (cmd[0] == NULL) {
     288                printf("Command not found.\n");
     289                rc = ENOTSUP;
     290                goto finit;
     291        }
     292
     293        if (pipe_count) {
     294                fseek(to, 0, SEEK_SET);
     295                new_iostate.stdin = to;
     296        }
     297
     298
    276299        if (run_command(cmd, usr, &new_iostate) == 0) {
    277300                rc = EOK;
     
    312335
    313336        return rc;
    314 }
    315 
    316 void print_pipe_usage(void)
    317 {
    318         printf("Invalid syntax!\n");
    319         printf("Usage of redirection (pipes in the future):\n");
    320         printf("from filename | command ...\n");
    321         printf("from filename | command ... | to filename\n");
    322         printf("command ... | to filename\n");
    323 
    324337}
    325338
  • uspace/app/bdsh/tok.c

    ra106037 r21b0013  
    138138                                return rc;
    139139                        }
    140                 } else if (next_char == '\'') {
     140                } else if (next_char == '<') {
     141                        if (tok_pending_chars(tok)) {
     142                                rc = tok_push_token(tok);
     143                                if (rc != EOK) {
     144                                        return rc;
     145                                }
     146                        }
     147
     148                        tok_start_token(tok, TOKTYPE_RDIN);
     149
     150                        rc = tok_push_char(tok, tok_get_char(tok));
     151                        if (rc != EOK) {
     152                                return rc;
     153                        }
     154                        tok_get_char(tok);
     155                        rc = tok_push_token(tok);
     156                        if (rc != EOK) {
     157                                return rc;
     158                        }
     159                } else if (next_char == '>') {
     160                        if (tok_pending_chars(tok)) {
     161                                rc = tok_push_token(tok);
     162                                if (rc != EOK) {
     163                                        return rc;
     164                                }
     165                        }
     166
     167                        tok_start_token(tok, TOKTYPE_RDOU);
     168
     169                        rc = tok_push_char(tok, tok_get_char(tok));
     170                        if (rc != EOK) {
     171                                return rc;
     172                        }
     173                        tok_get_char(tok);
     174                        rc = tok_push_token(tok);
     175                        if (rc != EOK) {
     176                                return rc;
     177                        }
     178                }  else if (next_char == '\'') {
    141179                        /*
    142180                         * A string starts with a quote (') and ends again with a quote.
  • uspace/app/bdsh/tok.h

    ra106037 r21b0013  
    3333        TOKTYPE_TEXT,
    3434        TOKTYPE_PIPE,
     35        TOKTYPE_RDIN,
     36        TOKTYPE_RDOU,
     37        TOKTYPE_RDAP,
    3538        TOKTYPE_SPACE
    3639} token_type_t;
Note: See TracChangeset for help on using the changeset viewer.