Changeset ae45201 in mainline


Ignore:
Timestamp:
2011-06-11T21:32:54Z (13 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6ea9a1d
Parents:
28ee877e
Message:

Allow redirecting output of tasks to file in bdsh

Location:
uspace
Files:
5 edited

Legend:

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

    r28ee877e rae45201  
    112112}
    113113
    114 unsigned int try_exec(char *cmd, char **argv)
     114unsigned int try_exec(char *cmd, char **argv, FILE **files)
    115115{
    116116        task_id_t tid;
    117117        task_exit_t texit;
    118118        char *tmp;
    119         int rc, retval;
     119        int rc, retval, i;
     120        fdi_node_t file_nodes[3];
     121        fdi_node_t *file_nodes_p[4];
    120122
    121123        tmp = str_dup(find_command(cmd));
    122124        free(found);
     125       
     126        for (i = 0; i < 3 && files[i] != NULL; i++) {
     127                if (fnode(files[i], &file_nodes[i]) == EOK) {
     128                        file_nodes_p[i] = &file_nodes[i];
     129                }
     130                else {
     131                        file_nodes_p[i] = NULL;
     132                }
     133        }
     134        file_nodes_p[i] = NULL;
    123135
    124         rc = task_spawnv(&tid, tmp, (const char **) argv);
     136        rc = task_spawnvf(&tid, tmp, (const char **) argv, file_nodes_p);
    125137        free(tmp);
    126138
  • uspace/app/bdsh/exec.h

    r28ee877e rae45201  
    44#include <task.h>
    55
    6 extern unsigned int try_exec(char *, char **);
     6extern unsigned int try_exec(char *, char **, FILE **);
    77
    88#endif
  • uspace/app/bdsh/input.c

    r28ee877e rae45201  
    5858
    5959/* Private helpers */
    60 static int run_command(char **, cliuser_t *);
     60static int run_command(char **, cliuser_t *, FILE **);
     61static void print_pipe_usage(void);
    6162
    6263/* Tokenizes input from console, sees if the first word is a built-in, if so
     
    6869        int rc = 0;
    6970        tokenizer_t tok;
     71        int i, pipe_count, processed_pipes;
     72        int pipe_pos[2];
     73        char **actual_cmd;
     74        char *redir_from = NULL;
     75        char *redir_to = NULL;
    7076
    7177        if (NULL == usr->line)
     
    8288        }
    8389       
    84         rc = run_command(cmd, usr);
     90        /* Until full support for pipes is implemented, allow for a simple case:
     91         * [from <file> |] command [| to <file>]
     92         *
     93         * First find the pipes and check that there are no more
     94         */
     95        int cmd_length = 0;
     96        for (i = 0, pipe_count = 0; cmd[i] != NULL; i++, cmd_length++) {
     97                if (cmd[i][0] == '|') {
     98                        if (pipe_count >= 2) {
     99                                print_pipe_usage();
     100                                rc = ENOTSUP;
     101                                goto finit;
     102                        }
     103                        pipe_pos[pipe_count] = i;
     104                        pipe_count++;
     105                }
     106        }
     107       
     108        actual_cmd = cmd;
     109        processed_pipes = 0;
     110       
     111        /* Check if the first part (from <file> |) is present */
     112        if (pipe_count > 0 && pipe_pos[0] == 2 && str_cmp(cmd[0], "from") == 0) {
     113                /* Ignore the first three tokens (from, file, pipe) and set from */
     114                redir_from = cmd[1];
     115                actual_cmd = cmd + 3;
     116                processed_pipes++;
     117        }
     118       
     119        /* Check if the second part (| to <file>) is present */
     120        if ((pipe_count - processed_pipes) > 0 &&
     121            pipe_pos[processed_pipes] == cmd_length - 3 &&
     122            str_cmp(cmd[cmd_length-2], "to") == 0) {
     123                /* Ignore the last three tokens (pipe, to, file) and set to */
     124                redir_to = cmd[cmd_length-1];
     125                cmd[cmd_length-3] = NULL;
     126                cmd_length -= 3;
     127                processed_pipes++;
     128        }
     129       
     130        if (processed_pipes != pipe_count) {
     131                print_pipe_usage();
     132                rc = ENOTSUP;
     133                goto finit;
     134        }
     135       
     136        if (actual_cmd[0] == NULL) {
     137                print_pipe_usage();
     138                rc = ENOTSUP;
     139                goto finit;
     140        }
     141       
     142        FILE *files[4];
     143        files[0] = stdin;
     144        files[1] = stdout;
     145        files[2] = stderr;
     146        files[3] = 0;
     147       
     148        if (redir_from) {
     149                FILE *from = fopen(redir_from, "r");
     150                if (from == NULL) {
     151                        printf("Cannot open file %s\n", redir_from);
     152                        rc = errno;
     153                        goto finit;
     154                }
     155                files[0] = from;
     156        }
     157       
     158        if (redir_to) {
     159                FILE *to = fopen(redir_to, "w");
     160                if (to == NULL) {
     161                        printf("Cannot open file %s\n", redir_to);
     162                        rc = errno;
     163                        goto finit;
     164                }
     165                files[1] = to;
     166        }
     167       
     168        rc = run_command(cmd, usr, files);
    85169       
    86170finit:
     
    94178}
    95179
    96 int run_command(char **cmd, cliuser_t *usr)
     180void print_pipe_usage()
     181{
     182        printf("Invalid syntax!\n");
     183        printf("Usage of redirection (pipes in the future):\n");
     184        printf("from filename | command ...\n");
     185        printf("from filename | command ... | to filename\n");
     186        printf("command ... | to filename\n");
     187       
     188}
     189
     190int run_command(char **cmd, cliuser_t *usr, FILE *files[])
    97191{
    98192        int id = 0;
     
    114208
    115209        /* See what try_exec thinks of it */
    116         return try_exec(cmd[0], cmd);
     210        return try_exec(cmd[0], cmd, files);
    117211}
    118212
  • uspace/lib/c/generic/task.c

    r28ee877e rae45201  
    101101int task_spawnv(task_id_t *id, const char *path, const char *const args[])
    102102{
    103         /* Connect to a program loader. */
    104         loader_t *ldr = loader_connect();
    105         if (ldr == NULL)
    106                 return EREFUSED;
    107        
    108         /* Get task ID. */
    109         task_id_t task_id;
    110         int rc = loader_get_task_id(ldr, &task_id);
    111         if (rc != EOK)
    112                 goto error;
    113        
    114         /* Send spawner's current working directory. */
    115         rc = loader_set_cwd(ldr);
    116         if (rc != EOK)
    117                 goto error;
    118        
    119         /* Send program pathname. */
    120         rc = loader_set_pathname(ldr, path);
    121         if (rc != EOK)
    122                 goto error;
    123        
    124         /* Send arguments. */
    125         rc = loader_set_args(ldr, args);
    126         if (rc != EOK)
    127                 goto error;
    128        
    129103        /* Send default files */
    130104        fdi_node_t *files[4];
     
    150124        files[3] = NULL;
    151125       
     126        return task_spawnvf(id, path, args, files);
     127}
     128
     129/** Create a new task by running an executable from the filesystem.
     130 *
     131 * This is really just a convenience wrapper over the more complicated
     132 * loader API. Arguments are passed as a null-terminated array of strings.
     133 * Files are passed as null-terminated array of pointers to fdi_node_t.
     134 *
     135 * @param id    If not NULL, the ID of the task is stored here on success.
     136 * @param path  Pathname of the binary to execute.
     137 * @param argv  Command-line arguments.
     138 * @param files Standard files to use.
     139 *
     140 * @return Zero on success or negative error code.
     141 *
     142 */
     143int task_spawnvf(task_id_t *id, const char *path, const char *const args[],
     144    fdi_node_t *const files[])
     145{
     146        /* Connect to a program loader. */
     147        loader_t *ldr = loader_connect();
     148        if (ldr == NULL)
     149                return EREFUSED;
     150       
     151        /* Get task ID. */
     152        task_id_t task_id;
     153        int rc = loader_get_task_id(ldr, &task_id);
     154        if (rc != EOK)
     155                goto error;
     156       
     157        /* Send spawner's current working directory. */
     158        rc = loader_set_cwd(ldr);
     159        if (rc != EOK)
     160                goto error;
     161       
     162        /* Send program pathname. */
     163        rc = loader_set_pathname(ldr, path);
     164        if (rc != EOK)
     165                goto error;
     166       
     167        /* Send arguments. */
     168        rc = loader_set_args(ldr, args);
     169        if (rc != EOK)
     170                goto error;
     171       
     172        /* Send files */
    152173        rc = loader_set_files(ldr, files);
    153174        if (rc != EOK)
     
    169190       
    170191        return EOK;
    171        
    172192error:
    173193        /* Error exit */
  • uspace/lib/c/include/task.h

    r28ee877e rae45201  
    3737
    3838#include <sys/types.h>
     39#include <vfs/vfs.h>
    3940
    4041typedef uint64_t task_id_t;
     
    5152extern task_id_t task_spawn(const char *, const char *const[], int *);
    5253extern int task_spawnv(task_id_t *, const char *path, const char *const []);
     54extern int task_spawnvf(task_id_t *, const char *path, const char *const [],
     55    fdi_node_t *const []);
    5356extern int task_spawnl(task_id_t *, const char *path, ...);
    5457
Note: See TracChangeset for help on using the changeset viewer.