Changeset bb9ec2d in mainline


Ignore:
Timestamp:
2017-03-07T20:47:35Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a737667e
Parents:
e796dc8
git-author:
Jiri Zarevucky <zarevucky.jiri@…> (2017-03-07 20:47:35)
git-committer:
Jakub Jermar <jakub@…> (2017-03-07 20:47:35)
Message:

Merge from lp:~zarevucky-jiri/helenos/vfs-2.5/ revision 1941-1944

Original commit messages:

1944: Jiri Zarevucky 2013-08-06 Replace legacy file descriptor presetting with inbox.
1943: Jiri Zarevucky 2013-08-06 Do not preserve open state when passing file descriptor to another task. Allow receiver to specify, whether the descriptor is low or high.
1942: Jiri Zarevucky 2013-08-06 C style.
1941: Jiri Zarevucky 2013-08-06 Make loader accept file reference instead of a pathname.

Modifications:

  • Keep version of elf_load_file() that accepts file name
  • Changes required for loading dynamically linked executables
  • Update to newer list_foreach
Location:
uspace
Files:
2 added
24 edited

Legend:

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

    re796dc8 rbb9ec2d  
    101101        char *tmp;
    102102        int rc, retval, i;
    103         int file_handles[3];
    104         int *file_handles_p[4];
     103        int file_handles[3] = { -1, -1, -1 };
    105104        FILE *files[3];
    106105
     
    113112       
    114113        for (i = 0; i < 3 && files[i] != NULL; i++) {
    115                 if (vfs_fhandle(files[i], &file_handles[i]) == EOK) {
    116                         file_handles_p[i] = &file_handles[i];
    117                 }
    118                 else {
    119                         file_handles_p[i] = NULL;
    120                 }
     114                vfs_fhandle(files[i], &file_handles[i]);
    121115        }
    122         file_handles_p[i] = NULL;
    123116
    124         rc = task_spawnvf(&tid, &twait, tmp, (const char **) argv, file_handles_p);
     117        rc = task_spawnvf(&tid, &twait, tmp, (const char **) argv,
     118            file_handles[0], file_handles[1], file_handles[2]);
    125119        free(tmp);
    126120
  • uspace/app/trace/trace.c

    re796dc8 rbb9ec2d  
    513513
    514514        /* Send program pathname */
    515         rc = loader_set_pathname(ldr, path);
     515        rc = loader_set_program_path(ldr, path);
    516516        if (rc != EOK)
    517517                goto error;
     
    523523
    524524        /* Send default files */
    525         int *files[4];
    526525        int fd_stdin;
    527526        int fd_stdout;
    528527        int fd_stderr;
    529528       
    530         if ((stdin != NULL) && (vfs_fhandle(stdin, &fd_stdin) == EOK))
    531                 files[0] = &fd_stdin;
    532         else
    533                 files[0] = NULL;
    534        
    535         if ((stdout != NULL) && (vfs_fhandle(stdout, &fd_stdout) == EOK))
    536                 files[1] = &fd_stdout;
    537         else
    538                 files[1] = NULL;
    539        
    540         if ((stderr != NULL) && (vfs_fhandle(stderr, &fd_stderr) == EOK))
    541                 files[2] = &fd_stderr;
    542         else
    543                 files[2] = NULL;
    544        
    545         files[3] = NULL;
    546        
    547         rc = loader_set_files(ldr, files);
    548         if (rc != EOK)
    549                 goto error;
    550 
     529        if ((stdin != NULL) && (vfs_fhandle(stdin, &fd_stdin) == EOK)) {
     530                rc = loader_add_inbox(ldr, "stdin", fd_stdin);
     531                if (rc != EOK)
     532                        goto error;
     533        }
     534       
     535        if ((stdout != NULL) && (vfs_fhandle(stdout, &fd_stdout) == EOK)) {
     536                rc = loader_add_inbox(ldr, "stdout", fd_stdout);
     537                if (rc != EOK)
     538                        goto error;
     539        }
     540       
     541        if ((stderr != NULL) && (vfs_fhandle(stderr, &fd_stderr) == EOK)) {
     542                rc = loader_add_inbox(ldr, "stderr", fd_stderr);
     543                if (rc != EOK)
     544                        goto error;
     545        }
     546       
    551547        /* Load the program. */
    552548        rc = loader_load_program(ldr);
  • uspace/lib/c/Makefile

    re796dc8 rbb9ec2d  
    151151        generic/rcu.c \
    152152        generic/setjmp.c \
     153        generic/vfs/inbox.c \
    153154        generic/stack.c \
    154155        generic/stacktrace.c \
  • uspace/lib/c/generic/elf/elf_load.c

    re796dc8 rbb9ec2d  
    4141#include <stdio.h>
    4242#include <stdlib.h>
     43#include <vfs/vfs.h>
    4344
    4445#ifdef CONFIG_RTLD
     
    5051/** Load ELF program.
    5152 *
    52  * @param file_name File name
     53 * @param file File handle
    5354 * @param info Place to store ELF program information
    5455 * @return EOK on success or non-zero error code
    5556 */
    56 int elf_load(const char *file_name, elf_info_t *info)
     57int elf_load(int file, elf_info_t *info)
    5758{
    5859#ifdef CONFIG_RTLD
     
    6162        int rc;
    6263
    63         rc = elf_load_file(file_name, 0, 0, &info->finfo);
     64        rc = elf_load_file(file, 0, 0, &info->finfo);
    6465        if (rc != EE_OK) {
    6566                DPRINTF("Failed to load executable '%s'.\n", file_name);
  • uspace/lib/c/generic/elf/elf_mod.c

    re796dc8 rbb9ec2d  
    9292 *
    9393 */
    94 static int elf_load_file2(int file, size_t so_bias, eld_flags_t flags, elf_finfo_t *info)
     94int elf_load_file(int file, size_t so_bias, eld_flags_t flags, elf_finfo_t *info)
    9595{
    9696        elf_ld_t elf;
     
    112112}
    113113
    114 int elf_load_file(const char *path, size_t so_bias, eld_flags_t flags, elf_finfo_t *info)
     114int elf_load_file_name(const char *path, size_t so_bias, eld_flags_t flags,
     115    elf_finfo_t *info)
    115116{
    116117        int file = vfs_lookup(path);
    117         int rc = elf_load_file2(file, so_bias, flags, info);
     118        int rc = elf_load_file(file, so_bias, flags, info);
    118119        close(file);
    119120        return rc;
  • uspace/lib/c/generic/io/io.c

    re796dc8 rbb9ec2d  
    4545#include <vfs/vfs.h>
    4646#include <vfs/vfs_sess.h>
     47#include <vfs/inbox.h>
    4748#include <ipc/loc.h>
    4849#include <adt/list.h>
     
    101102static LIST_INITIALIZE(files);
    102103
    103 void __stdio_init(int filc)
    104 {
    105         if (filc > 0) {
    106                 stdin = fdopen(0, "r");
     104void __stdio_init(void)
     105{
     106        /* The first three standard file descriptors are assigned for compatibility.
     107         * This will probably be removed later.
     108         */
     109         
     110        int infd = inbox_get("stdin");
     111        if (infd >= 0) {
     112                int stdinfd = vfs_clone(infd, false);
     113                assert(stdinfd == 0);
     114                _vfs_open(stdinfd, MODE_READ);
     115                stdin = fdopen(stdinfd, "r");
    107116        } else {
    108117                stdin = &stdin_null;
     
    110119        }
    111120       
    112         if (filc > 1) {
    113                 stdout = fdopen(1, "w");
     121        int outfd = inbox_get("stdout");
     122        if (outfd >= 0) {
     123                int stdoutfd = vfs_clone(outfd, false);
     124                assert(stdoutfd <= 1);
     125                while (stdoutfd < 1) {
     126                        stdoutfd = vfs_clone(outfd, false);
     127                }
     128                _vfs_open(stdoutfd, MODE_APPEND);
     129                stdout = fdopen(stdoutfd, "a");
    114130        } else {
    115131                stdout = &stdout_kio;
     
    117133        }
    118134       
    119         if (filc > 2) {
    120                 stderr = fdopen(2, "w");
     135        int errfd = inbox_get("stderr");
     136        if (errfd >= 0) {
     137                int stderrfd = vfs_clone(errfd, false);
     138                assert(stderrfd <= 2);
     139                while (stderrfd < 2) {
     140                        stderrfd = vfs_clone(errfd, false);
     141                }
     142                _vfs_open(stderrfd, MODE_APPEND);
     143                stderr = fdopen(stderrfd, "a");
    121144        } else {
    122145                stderr = &stderr_kio;
  • uspace/lib/c/generic/libc.c

    re796dc8 rbb9ec2d  
    107107                argc = 0;
    108108                argv = NULL;
    109                 __stdio_init(0);
     109                __stdio_init();
    110110        } else {
    111111                argc = __pcb->argc;
    112112                argv = __pcb->argv;
    113                 __stdio_init(__pcb->filc);
     113                __inbox_init(__pcb->inbox, __pcb->inbox_entries);
     114                __stdio_init();
    114115                (void) chdir(__pcb->cwd);
    115116        }
  • uspace/lib/c/generic/loader.c

    re796dc8 rbb9ec2d  
    147147}
    148148
    149 /** Set pathname of the program to load.
    150  *
    151  * Sets the name of the program file to load. The name can be relative
    152  * to the current working directory (it will be absolutized before
    153  * sending to the loader).
     149/** Set the program to load.
    154150 *
    155151 * @param ldr  Loader connection structure.
    156  * @param path Pathname of the program file.
    157  *
    158  * @return Zero on success or negative error code.
    159  *
    160  */
    161 int loader_set_pathname(loader_t *ldr, const char *path)
    162 {
    163         size_t pa_len;
    164         char *pa = vfs_absolutize(path, &pa_len);
    165         if (!pa)
    166                 return ENOMEM;
    167        
    168         /* Send program pathname */
    169         async_exch_t *exch = async_exchange_begin(ldr->sess);
    170        
     152 * @param name Name to set for the spawned program.
     153 * @param file Program file.
     154 *
     155 * @return Zero on success or negative error code.
     156 *
     157 */
     158int loader_set_program(loader_t *ldr, const char *name, int file)
     159{
     160        async_exch_t *exch = async_exchange_begin(ldr->sess);
     161
    171162        ipc_call_t answer;
    172         aid_t req = async_send_0(exch, LOADER_SET_PATHNAME, &answer);
    173         sysarg_t rc = async_data_write_start(exch, (void *) pa, pa_len);
    174        
    175         async_exchange_end(exch);
    176         free(pa);
    177        
     163        aid_t req = async_send_0(exch, LOADER_SET_PROGRAM, &answer);
     164
     165        sysarg_t rc = async_data_write_start(exch, name, str_size(name) + 1);
     166        if (rc == EOK) {
     167                async_exch_t *vfs_exch = vfs_exchange_begin();
     168                rc = vfs_pass_handle(vfs_exch, file, exch);
     169                vfs_exchange_end(vfs_exch);
     170        }
     171
     172        async_exchange_end(exch);
     173
    178174        if (rc != EOK) {
    179175                async_forget(req);
    180176                return (int) rc;
    181177        }
    182        
     178
    183179        async_wait_for(req, &rc);
    184180        return (int) rc;
    185181}
     182
     183/** Set the program to load by path.
     184 *
     185 * @param ldr  Loader connection structure.
     186 * @param path Program path.
     187 *
     188 * @return Zero on success or negative error code.
     189 *
     190 */
     191int loader_set_program_path(loader_t *ldr, const char *path)
     192{
     193        const char *name = str_rchr(path, '/');
     194        if (name == NULL) {
     195                name = path;
     196        } else {
     197                name++;
     198        }
     199       
     200        int fd = vfs_lookup(path);
     201        if (fd < 0) {
     202                return fd;
     203        }
     204       
     205        int rc = loader_set_program(ldr, name, fd);
     206        close(fd);
     207        return rc;
     208}
     209
    186210
    187211/** Set command-line arguments for the program.
     
    244268}
    245269
    246 /** Set preset files for the program.
    247  *
    248  * Sets the vector of preset files to be passed to the loaded
    249  * program. By convention, the first three files represent stdin,
    250  * stdout and stderr respectively.
    251  *
    252  * @param ldr   Loader connection structure.
    253  * @param files NULL-terminated array of pointers to files.
    254  *
    255  * @return Zero on success or negative error code.
    256  *
    257  */
    258 int loader_set_files(loader_t *ldr, int * const files[])
    259 {
    260         /* Send serialized files to the loader */
     270/** Add a file to the task's inbox.
     271 *
     272 * @param ldr        Loader connection structure.
     273 * @param name       Identification of the file.
     274 * @param file       The file's descriptor.
     275 *
     276 * @return Zero on success or negative error code.
     277 *
     278 */
     279int loader_add_inbox(loader_t *ldr, const char *name, int file)
     280{
    261281        async_exch_t *exch = async_exchange_begin(ldr->sess);
    262282        async_exch_t *vfs_exch = vfs_exchange_begin();
    263283       
    264         int i;
    265         for (i = 0; files[i]; i++);
    266 
    267         ipc_call_t answer;
    268         aid_t req = async_send_1(exch, LOADER_SET_FILES, i, &answer);
    269 
    270         sysarg_t rc = EOK;
    271        
    272         for (i = 0; files[i]; i++) {
    273                 rc = vfs_pass_handle(vfs_exch, *files[i], exch);
    274                 if (rc != EOK)
    275                         break;
    276         }
    277        
    278         vfs_exchange_end(vfs_exch);
    279         async_exchange_end(exch);
    280 
    281         if (rc != EOK) {
    282                 async_forget(req);
    283                 return (int) rc;
    284         }
    285        
    286         async_wait_for(req, &rc);
     284        aid_t req = async_send_0(exch, LOADER_ADD_INBOX, NULL);
     285       
     286        sysarg_t rc = async_data_write_start(exch, name, str_size(name) + 1);
     287        if (rc == EOK) {
     288                rc = vfs_pass_handle(vfs_exch, file, exch);
     289        }
     290       
     291        async_exchange_end(vfs_exch);
     292        async_exchange_end(exch);
     293       
     294        if (rc == EOK) {
     295                async_wait_for(req, &rc);
     296        } else {
     297                async_forget(req);
     298        }
     299       
    287300        return (int) rc;
    288301}
  • uspace/lib/c/generic/private/io.h

    re796dc8 rbb9ec2d  
    3636#define LIBC_PRIVATE_IO_H_
    3737
    38 extern void __stdio_init(int);
     38#include <loader/pcb.h>
     39
     40extern void __stdio_init(void);
    3941extern void __stdio_done(void);
     42
     43extern void __inbox_init(struct pcb_inbox_entry *entries, int count);
    4044
    4145#endif
  • uspace/lib/c/generic/rtld/module.c

    re796dc8 rbb9ec2d  
    196196        DPRINTF("load '%s' at 0x%x\n", name_buf, m->bias);
    197197
    198         rc = elf_load_file(name_buf, m->bias, ELDF_RW, &info);
     198        rc = elf_load_file_name(name_buf, m->bias, ELDF_RW, &info);
    199199        if (rc != EE_OK) {
    200200                printf("Failed to load '%s'\n", name_buf);
  • uspace/lib/c/generic/task.c

    re796dc8 rbb9ec2d  
    107107{
    108108        /* Send default files */
    109         int *files[4];
    110         int fd_stdin;
    111         int fd_stdout;
    112         int fd_stderr;
    113        
    114         if ((stdin != NULL) && (vfs_fhandle(stdin, &fd_stdin) == EOK))
    115                 files[0] = &fd_stdin;
    116         else
    117                 files[0] = NULL;
    118        
    119         if ((stdout != NULL) && (vfs_fhandle(stdout, &fd_stdout) == EOK))
    120                 files[1] = &fd_stdout;
    121         else
    122                 files[1] = NULL;
    123        
    124         if ((stderr != NULL) && (vfs_fhandle(stderr, &fd_stderr) == EOK))
    125                 files[2] = &fd_stderr;
    126         else
    127                 files[2] = NULL;
    128        
    129         files[3] = NULL;
    130        
    131         return task_spawnvf(id, wait, path, args, files);
     109       
     110        int fd_stdin = -1;
     111        int fd_stdout = -1;
     112        int fd_stderr = -1;
     113       
     114        if (stdin != NULL) {
     115                (void) vfs_fhandle(stdin, &fd_stdin);
     116        }
     117       
     118        if (stdout != NULL) {
     119                (void) vfs_fhandle(stdout, &fd_stdout);
     120        }
     121
     122        if (stderr != NULL) {
     123                (void) vfs_fhandle(stderr, &fd_stderr);
     124        }
     125       
     126        return task_spawnvf(id, wait, path, args, fd_stdin, fd_stdout,
     127            fd_stderr);
    132128}
    133129
     
    138134 * Files are passed as null-terminated array of pointers to fdi_node_t.
    139135 *
    140  * @param id    If not NULL, the ID of the task is stored here on success.
    141  * @param wait  If not NULL, setup waiting for task's return value and store
    142  *              the information necessary for waiting here on success.
    143  * @param path  Pathname of the binary to execute.
    144  * @param argv  Command-line arguments.
    145  * @param files Standard files to use.
     136 * @param id      If not NULL, the ID of the task is stored here on success.
     137 * @param wait    If not NULL, setup waiting for task's return value and store
     138 * @param path    Pathname of the binary to execute.
     139 * @param argv    Command-line arguments.
     140 * @param std_in  File to use as stdin.
     141 * @param std_out File to use as stdout.
     142 * @param std_err File to use as stderr.
    146143 *
    147144 * @return Zero on success or negative error code.
     
    149146 */
    150147int task_spawnvf(task_id_t *id, task_wait_t *wait, const char *path,
    151     const char *const args[], int *const files[])
     148    const char *const args[], int fd_stdin, int fd_stdout, int fd_stderr)
    152149{
    153150        /* Connect to a program loader. */
     
    169166                goto error;
    170167       
    171         /* Send program pathname. */
    172         rc = loader_set_pathname(ldr, path);
     168        /* Send program binary. */
     169        rc = loader_set_program_path(ldr, path);
    173170        if (rc != EOK)
    174171                goto error;
     
    180177       
    181178        /* Send files */
    182         rc = loader_set_files(ldr, files);
    183         if (rc != EOK)
    184                 goto error;
     179        if (fd_stdin >= 0) {
     180                rc = loader_add_inbox(ldr, "stdin", fd_stdin);
     181                if (rc != EOK)
     182                        goto error;
     183        }
     184       
     185        if (fd_stdout >= 0) {
     186                rc = loader_add_inbox(ldr, "stdout", fd_stdout);
     187                if (rc != EOK)
     188                        goto error;
     189        }
     190       
     191        if (fd_stderr >= 0) {
     192                rc = loader_add_inbox(ldr, "stderr", fd_stderr);
     193                if (rc != EOK)
     194                        goto error;
     195        }               
    185196       
    186197        /* Load the program. */
  • uspace/lib/c/generic/vfs/vfs.c

    re796dc8 rbb9ec2d  
    11621162}
    11631163
    1164 int vfs_receive_handle()
     1164int vfs_receive_handle(bool high_descriptor)
    11651165{
    11661166        ipc_callid_t callid;
     
    11751175
    11761176        sysarg_t ret;
    1177         sysarg_t rc = async_req_0_1(vfs_exch, VFS_IN_WAIT_HANDLE, &ret);
     1177        sysarg_t rc = async_req_1_1(vfs_exch, VFS_IN_WAIT_HANDLE, high_descriptor, &ret);
    11781178
    11791179        async_exchange_end(vfs_exch);
  • uspace/lib/c/include/elf/elf_load.h

    re796dc8 rbb9ec2d  
    4545} elf_info_t;
    4646
    47 extern int elf_load(const char *, elf_info_t *);
     47extern int elf_load(int, elf_info_t *);
    4848extern void elf_set_pcb(elf_info_t *, pcb_t *);
    4949
  • uspace/lib/c/include/elf/elf_mod.h

    re796dc8 rbb9ec2d  
    108108
    109109extern const char *elf_error(unsigned int);
    110 extern int elf_load_file(const char *, size_t, eld_flags_t, elf_finfo_t *);
     110extern int elf_load_file(int, size_t, eld_flags_t, elf_finfo_t *);
     111extern int elf_load_file_name(const char *, size_t, eld_flags_t, elf_finfo_t *);
    111112
    112113#endif
  • uspace/lib/c/include/ipc/loader.h

    re796dc8 rbb9ec2d  
    4242        LOADER_GET_TASKID,
    4343        LOADER_SET_CWD,
    44         LOADER_SET_PATHNAME,
     44        LOADER_SET_PROGRAM,
    4545        LOADER_SET_ARGS,
    46         LOADER_SET_FILES,
     46        LOADER_ADD_INBOX,
    4747        LOADER_LOAD,
    4848        LOADER_RUN
  • uspace/lib/c/include/loader/loader.h

    re796dc8 rbb9ec2d  
    4747extern int loader_get_task_id(loader_t *, task_id_t *);
    4848extern int loader_set_cwd(loader_t *);
    49 extern int loader_set_pathname(loader_t *, const char *);
     49extern int loader_set_program(loader_t *, const char *, int);
     50extern int loader_set_program_path(loader_t *, const char *);
    5051extern int loader_set_args(loader_t *, const char *const[]);
    51 extern int loader_set_files(loader_t *, int *const[]);
     52extern int loader_add_inbox(loader_t *, const char *, int);
    5253extern int loader_load_program(loader_t *);
    5354extern int loader_run(loader_t *);
  • uspace/lib/c/include/loader/pcb.h

    re796dc8 rbb9ec2d  
    4141typedef void (*entry_point_t)(void);
    4242
     43struct pcb_inbox_entry {
     44        char *name;
     45        int file;
     46};
     47
    4348/** Program Control Block.
    4449 *
     
    6065        char **argv;
    6166       
    62         /** Number of preset files. */
    63         unsigned int filc;
     67        /** List of inbox files. */
     68        struct pcb_inbox_entry *inbox;
     69        int inbox_entries;
    6470       
    6571        /*
  • uspace/lib/c/include/task.h

    re796dc8 rbb9ec2d  
    5757    const char *const []);
    5858extern int task_spawnvf(task_id_t *, task_wait_t *, const char *path,
    59     const char *const [], int *const []);
     59    const char *const [], int, int, int);
    6060extern int task_spawn(task_id_t *, task_wait_t *, const char *path, int,
    6161    va_list ap);
  • uspace/lib/c/include/vfs/vfs.h

    re796dc8 rbb9ec2d  
    6363extern void vfs_exchange_end(async_exch_t *);
    6464
    65 extern int _vfs_walk(int parent, const char *path, int flags);
    66 extern int _vfs_open(int file, int mode);
    67 extern int vfs_lookup(const char *path);
     65extern int _vfs_walk(int, const char *, int);
     66extern int _vfs_open(int, int);
     67extern int vfs_lookup(const char *);
    6868
    69 extern int vfs_pass_handle(async_exch_t *vfs_exch, int file, async_exch_t *exch);
    70 extern int vfs_receive_handle(void);
     69extern int vfs_pass_handle(async_exch_t *, int, async_exch_t *);
     70extern int vfs_receive_handle(bool);
    7171
    72 extern int vfs_clone(int file, bool high_descriptor);
    73 
     72extern int vfs_clone(int, bool);
    7473
    7574#endif
  • uspace/lib/pcut/src/os/helenos.c

    re796dc8 rbb9ec2d  
    170170        snprintf(test_number_argument, MAX_TEST_NUMBER_WIDTH, "-t%d", test->id);
    171171
    172         int *files[4];
    173         int fd_stdin = fileno(stdin);
    174         files[0] = &fd_stdin;
    175         files[1] = &tempfile;
    176         files[2] = &tempfile;
    177         files[3] = NULL;
    178 
    179172        const char *const arguments[3] = {
    180173                self_path,
     
    186179
    187180        task_wait_t test_task_wait;
    188         int rc = task_spawnvf(&test_task_id, &test_task_wait, self_path, arguments, files);
     181        int rc = task_spawnvf(&test_task_id, &test_task_wait, self_path, arguments,
     182            fileno(stdin), tempfile, tempfile);
    189183        if (rc != EOK) {
    190184                status = TEST_OUTCOME_ERROR;
  • uspace/srv/loader/main.c

    re796dc8 rbb9ec2d  
    6262#include <elf/elf_load.h>
    6363#include <vfs/vfs.h>
     64#include <vfs/inbox.h>
    6465
    6566#define DPRINTF(...)
    6667
    67 /** Pathname of the file that will be loaded */
    68 static char *pathname = NULL;
     68/** File that will be loaded */
     69static char *progname = NULL;
     70static int program_fd = -1;
    6971
    7072/** The Program control block */
     
    8183static char *arg_buf = NULL;
    8284
    83 /** Number of preset files */
    84 static unsigned int filc = 0;
     85/** Inbox entries. */
     86static struct pcb_inbox_entry inbox[INBOX_MAX_ENTRIES];
     87static int inbox_entries = 0;
    8588
    8689static elf_info_t prog_info;
     
    130133}
    131134
    132 /** Receive a call setting pathname of the program to execute.
    133  *
    134  * @param rid
    135  * @param request
    136  */
    137 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
    138 {
    139         char *buf;
    140         int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL);
    141        
    142         if (rc == EOK) {
    143                 if (pathname != NULL)
    144                         free(pathname);
    145                
    146                 pathname = buf;
    147         }
    148        
    149         async_answer_0(rid, rc);
     135/** Receive a call setting the program to execute.
     136 *
     137 * @param rid
     138 * @param request
     139 */
     140static void ldr_set_program(ipc_callid_t rid, ipc_call_t *request)
     141{
     142        ipc_callid_t writeid;
     143        size_t namesize;
     144        if (!async_data_write_receive(&writeid, &namesize)) {
     145                async_answer_0(rid, EINVAL);
     146                return;
     147        }
     148
     149        char* name = malloc(namesize);
     150        int rc = async_data_write_finalize(writeid, name, namesize);
     151        if (rc != EOK) {
     152                async_answer_0(rid, EINVAL);
     153                return;
     154        }
     155
     156        int file = vfs_receive_handle(true);
     157        if (file < 0) {
     158                async_answer_0(rid, EINVAL);
     159                return;
     160        }
     161       
     162        progname = name;
     163        program_fd = file;
     164        async_answer_0(rid, EOK);
    150165}
    151166
     
    215230}
    216231
    217 /** Receive a call setting preset files of the program to execute.
    218  *
    219  * @param rid
    220  * @param request
    221  */
    222 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
    223 {
    224         size_t count = IPC_GET_ARG1(*request);
    225 
    226         for (filc = 0; filc < count; filc++) {
    227                 int fd = vfs_receive_handle();
    228                 if (fd < 0) {
    229                         break;
    230                 }
    231                 assert(fd == (int) filc);
    232         }
    233 
     232/** Receive a call setting inbox files of the program to execute.
     233 *
     234 * @param rid
     235 * @param request
     236 */
     237static void ldr_add_inbox(ipc_callid_t rid, ipc_call_t *request)
     238{
     239        if (inbox_entries == INBOX_MAX_ENTRIES) {
     240                async_answer_0(rid, ERANGE);
     241        }
     242
     243        ipc_callid_t writeid;
     244        size_t namesize;
     245        if (!async_data_write_receive(&writeid, &namesize)) {
     246                async_answer_0(rid, EINVAL);
     247                return;
     248        }
     249
     250        char* name = malloc(namesize);
     251        int rc = async_data_write_finalize(writeid, name, namesize);
     252        if (rc != EOK) {
     253                async_answer_0(rid, EINVAL);
     254                return;
     255        }
     256
     257        int file = vfs_receive_handle(true);
     258        if (file < 0) {
     259                async_answer_0(rid, EINVAL);
     260                return;
     261        }
     262
     263        inbox[inbox_entries].name = name;
     264        inbox[inbox_entries].file = file;
     265        inbox_entries++;
    234266        async_answer_0(rid, EOK);
    235267}
     
    243275static int ldr_load(ipc_callid_t rid, ipc_call_t *request)
    244276{
    245         int rc;
    246        
    247         rc = elf_load(pathname, &prog_info);
     277        int rc = elf_load(program_fd, &prog_info);
    248278        if (rc != EE_OK) {
    249                 DPRINTF("Failed to load executable '%s'.\n", pathname);
     279                DPRINTF("Failed to load executable for '%s'.\n", progname);
    250280                async_answer_0(rid, EINVAL);
    251281                return 1;
     
    259289        pcb.argv = argv;
    260290       
    261         pcb.filc = filc;
     291        pcb.inbox = inbox;
     292        pcb.inbox_entries = inbox_entries;
    262293       
    263294        async_answer_0(rid, rc);
     
    273304static void ldr_run(ipc_callid_t rid, ipc_call_t *request)
    274305{
    275         const char *cp;
    276        
    277306        DPRINTF("Set task name\n");
    278307
    279308        /* Set the task name. */
    280         cp = str_rchr(pathname, '/');
    281         cp = (cp == NULL) ? pathname : (cp + 1);
    282         task_set_name(cp);
     309        task_set_name(progname);
    283310       
    284311        /* Run program */
     
    327354                        ldr_set_cwd(callid, &call);
    328355                        continue;
    329                 case LOADER_SET_PATHNAME:
    330                         ldr_set_pathname(callid, &call);
     356                case LOADER_SET_PROGRAM:
     357                        ldr_set_program(callid, &call);
    331358                        continue;
    332359                case LOADER_SET_ARGS:
    333360                        ldr_set_args(callid, &call);
    334361                        continue;
    335                 case LOADER_SET_FILES:
    336                         ldr_set_files(callid, &call);
     362                case LOADER_ADD_INBOX:
     363                        ldr_add_inbox(callid, &call);
    337364                        continue;
    338365                case LOADER_LOAD:
  • uspace/srv/vfs/vfs.h

    re796dc8 rbb9ec2d  
    197197
    198198extern void vfs_op_pass_handle(task_id_t, task_id_t, int);
    199 extern int vfs_wait_handle_internal(void);
     199extern int vfs_wait_handle_internal(bool);
    200200
    201201extern vfs_file_t *vfs_file_get(int);
  • uspace/srv/vfs/vfs_file.c

    re796dc8 rbb9ec2d  
    5959typedef struct {
    6060        link_t link;
    61         int handle;
     61        vfs_node_t *node;
     62        int permissions;
    6263} vfs_boxed_handle_t;
    6364
     
    365366        vfs_client_data_t *acceptor_data = NULL;
    366367        vfs_file_t *donor_file = NULL;
    367         vfs_file_t *acceptor_file = NULL;
    368368        vfs_boxed_handle_t *bh;
    369         int acceptor_fd;
    370369
    371370        acceptor_data = async_get_client_data_by_id(acceptor_id);
     
    377376
    378377        link_initialize(&bh->link);
    379         bh->handle = -1;
     378        bh->node = NULL;
    380379
    381380        donor_data = async_get_client_data_by_id(donor_id);
     
    386385        if (!donor_file)
    387386                goto out;
    388 
    389         acceptor_fd = _vfs_fd_alloc(acceptor_data, &acceptor_file, false);
    390         if (acceptor_fd < 0)
    391                 goto out;
    392 
    393         bh->handle = acceptor_fd;
    394387
    395388        /*
     
    397390         */
    398391        vfs_node_addref(donor_file->node);
    399 
    400         assert(acceptor_file);
    401 
    402         /*
    403          * Inherit attributes from the donor.
    404          */
    405         acceptor_file->node = donor_file->node;
    406         acceptor_file->permissions = donor_file->permissions;
    407        
    408         // TODO: The file should not inherit its open status, but clients depend on this.
    409         acceptor_file->pos = donor_file->pos;
    410         acceptor_file->append = donor_file->append;
    411         acceptor_file->open_read = donor_file->open_read;
    412         acceptor_file->open_write = donor_file->open_write;
    413 
    414         if (acceptor_file->open_read || acceptor_file->open_write) {
    415                 (void) vfs_open_node_remote(acceptor_file->node);
    416         }
     392        bh->node = donor_file->node;
     393        bh->permissions = donor_file->permissions;
    417394
    418395out:
     
    428405        if (donor_file)
    429406                _vfs_file_put(donor_data, donor_file);
    430         if (acceptor_file)
    431                 _vfs_file_put(acceptor_data, acceptor_file);
    432 
    433 }
    434 
    435 int vfs_wait_handle_internal(void)
     407}
     408
     409int vfs_wait_handle_internal(bool high_fd)
    436410{
    437411        vfs_client_data_t *vfs_data = VFS_DATA;
    438         int fd;
    439412       
    440413        fibril_mutex_lock(&vfs_data->lock);
     
    446419
    447420        vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link);
    448         fd = bh->handle;
     421
     422        vfs_file_t *file;
     423        int fd = _vfs_fd_alloc(vfs_data, &file, high_fd);
     424        if (fd < 0) {
     425                vfs_node_delref(bh->node);
     426                free(bh);
     427                return fd;
     428        }
     429       
     430        file->node = bh->node;
     431        file->permissions = bh->permissions;
     432        vfs_file_put(file);
    449433        free(bh);
    450 
    451434        return fd;
    452435}
  • uspace/srv/vfs/vfs_ops.c

    re796dc8 rbb9ec2d  
    12481248void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request)
    12491249{
    1250         int fd = vfs_wait_handle_internal();
     1250        bool high_fd = IPC_GET_ARG1(*request);
     1251        int fd = vfs_wait_handle_internal(high_fd);
    12511252        async_answer_1(rid, EOK, fd);
    12521253}
Note: See TracChangeset for help on using the changeset viewer.