Changeset bb9ec2d in mainline for uspace/lib/c


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/lib/c
Files:
2 added
17 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.