Changeset 00c2de63 in mainline for uspace/lib


Ignore:
Timestamp:
2011-07-29T14:50:22Z (15 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b6759f4
Parents:
6c69d19 (diff), 7ae249d (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 libposix.

Location:
uspace/lib
Files:
13 added
1 deleted
29 edited
2 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/block/libblock.c

    r6c69d19 r00c2de63  
    258258static hash_index_t cache_hash(unsigned long *key)
    259259{
    260         return *key & (CACHE_BUCKETS - 1);
     260        return MERGE_LOUP32(key[0], key[1]) & (CACHE_BUCKETS - 1);
    261261}
    262262
     
    264264{
    265265        block_t *b = hash_table_get_instance(item, block_t, hash_link);
    266         return b->lba == *key;
     266        return b->lba == MERGE_LOUP32(key[0], key[1]);
    267267}
    268268
     
    305305        cache->blocks_cluster = cache->lblock_size / devcon->pblock_size;
    306306
    307         if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
     307        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 2,
    308308            &cache_ops)) {
    309309                free(cache);
     
    344344                }
    345345
    346                 unsigned long key = b->lba;
    347                 hash_table_remove(&cache->block_hash, &key, 1);
     346                unsigned long key[2] = {
     347                        LOWER32(b->lba),
     348                        UPPER32(b->lba)
     349                };
     350                hash_table_remove(&cache->block_hash, key, 2);
    348351               
    349352                free(b->data);
     
    398401        block_t *b;
    399402        link_t *l;
    400         unsigned long key = ba;
     403        unsigned long key[2] = {
     404                LOWER32(ba),
     405                UPPER32(ba)
     406        };
     407
    401408        int rc;
    402409       
     
    413420
    414421        fibril_mutex_lock(&cache->lock);
    415         l = hash_table_find(&cache->block_hash, &key);
     422        l = hash_table_find(&cache->block_hash, key);
    416423        if (l) {
    417424found:
     
    451458                         * Try to recycle a block from the free list.
    452459                         */
    453                         unsigned long temp_key;
    454460recycle:
    455461                        if (list_empty(&cache->free_list)) {
     
    499505                                        goto retry;
    500506                                }
    501                                 l = hash_table_find(&cache->block_hash, &key);
     507                                l = hash_table_find(&cache->block_hash, key);
    502508                                if (l) {
    503509                                        /*
     
    522528                         */
    523529                        list_remove(&b->free_link);
    524                         temp_key = b->lba;
    525                         hash_table_remove(&cache->block_hash, &temp_key, 1);
     530                        unsigned long temp_key[2] = {
     531                                LOWER32(b->lba),
     532                                UPPER32(b->lba)
     533                        };
     534                        hash_table_remove(&cache->block_hash, temp_key, 2);
    526535                }
    527536
     
    531540                b->lba = ba;
    532541                b->pba = ba_ltop(devcon, b->lba);
    533                 hash_table_insert(&cache->block_hash, &key, &b->hash_link);
     542                hash_table_insert(&cache->block_hash, key, &b->hash_link);
    534543
    535544                /*
     
    643652                         * Take the block out of the cache and free it.
    644653                         */
    645                         unsigned long key = block->lba;
    646                         hash_table_remove(&cache->block_hash, &key, 1);
     654                        unsigned long key[2] = {
     655                                LOWER32(block->lba),
     656                                UPPER32(block->lba)
     657                        };
     658                        hash_table_remove(&cache->block_hash, key, 2);
    647659                        fibril_mutex_unlock(&block->lock);
    648660                        free(block->data);
  • uspace/lib/c/Makefile

    r6c69d19 r00c2de63  
    5959-include arch/$(UARCH)/Makefile.inc
    6060
    61 EXTRA_CFLAGS += -I../../srv/loader/include
    62 
    6361GENERIC_SOURCES = \
    6462        generic/libc.c \
     
    7169        generic/device/hw_res.c \
    7270        generic/device/char_dev.c \
     71        generic/elf/elf_load.c \
    7372        generic/event.c \
    7473        generic/errno.c \
     
    134133                generic/dlfcn.c \
    135134                generic/rtld/rtld.c \
    136                 generic/rtld/elf_load.c \
    137135                generic/rtld/dynamic.c \
    138136                generic/rtld/module.c \
  • uspace/lib/c/generic/elf/elf_load.c

    r6c69d19 r00c2de63  
    2929 */
    3030
    31 /** @addtogroup generic 
     31/** @addtogroup generic
    3232 * @{
    3333 */
     
    4949#include <assert.h>
    5050#include <as.h>
     51#include <elf/elf.h>
    5152#include <unistd.h>
    5253#include <fcntl.h>
     
    5556#include <entry_point.h>
    5657
    57 #include "elf.h"
    58 #include "elf_load.h"
     58#include <elf/elf_load.h>
    5959
    6060#define DPRINTF(...)
     
    7474static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
    7575
    76 /** Read until the buffer is read in its entirety. */
    77 static int my_read(int fd, void *buf, size_t len)
    78 {
    79         int cnt = 0;
    80         do {
    81                 buf += cnt;
    82                 len -= cnt;
    83                 cnt = read(fd, buf, len);
    84         } while ((cnt > 0) && ((len - cnt) > 0));
    85 
    86         return cnt;
    87 }
    88 
    8976/** Load ELF binary from a file.
    9077 *
     
    160147        int i, rc;
    161148
    162         rc = my_read(elf->fd, header, sizeof(elf_header_t));
    163         if (rc < 0) {
     149        rc = read_all(elf->fd, header, sizeof(elf_header_t));
     150        if (rc != sizeof(elf_header_t)) {
    164151                DPRINTF("Read error.\n");
    165152                return EE_INVALID;
     
    222209                        + i * sizeof(elf_segment_header_t), SEEK_SET);
    223210
    224                 rc = my_read(elf->fd, &segment_hdr,
     211                rc = read_all(elf->fd, &segment_hdr,
    225212                    sizeof(elf_segment_header_t));
    226                 if (rc < 0) {
     213                if (rc != sizeof(elf_segment_header_t)) {
    227214                        DPRINTF("Read error.\n");
    228215                        return EE_INVALID;
     
    244231                    + i * sizeof(elf_section_header_t), SEEK_SET);
    245232
    246                 rc = my_read(elf->fd, &section_hdr,
     233                rc = read_all(elf->fd, &section_hdr,
    247234                    sizeof(elf_section_header_t));
    248                 if (rc < 0) {
     235                if (rc != sizeof(elf_section_header_t)) {
    249236                        DPRINTF("Read error.\n");
    250237                        return EE_INVALID;
     
    334321        uintptr_t seg_addr;
    335322        size_t mem_sz;
    336         int rc;
     323        ssize_t rc;
    337324
    338325        bias = elf->bias;
     
    412399                if (now > left) now = left;
    413400
    414                 rc = my_read(elf->fd, dp, now);
    415 
    416                 if (rc < 0) {
     401                rc = read_all(elf->fd, dp, now);
     402
     403                if (rc != (ssize_t) now) {
    417404                        DPRINTF("Read error.\n");
    418405                        return EE_INVALID;
  • uspace/lib/c/generic/io/io.c

    r6c69d19 r00c2de63  
    594594                }
    595595               
    596                 buf += now;
     596                data += now;
    597597                stream->buf_head += now;
    598598                buf_free -= now;
    599599                bytes_left -= now;
    600600                total_written += now;
     601                stream->buf_state = _bs_write;
    601602               
    602603                if (buf_free == 0) {
     
    606607                }
    607608        }
    608        
    609         if (total_written > 0)
    610                 stream->buf_state = _bs_write;
    611609
    612610        if (need_flush)
  • uspace/lib/c/generic/rtld/module.c

    r6c69d19 r00c2de63  
    3535 */
    3636
     37#include <adt/list.h>
     38#include <elf/elf_load.h>
     39#include <fcntl.h>
     40#include <loader/pcb.h>
    3741#include <stdio.h>
    3842#include <stdlib.h>
    3943#include <unistd.h>
    40 #include <fcntl.h>
    41 #include <adt/list.h>
    42 #include <loader/pcb.h>
    4344
    4445#include <rtld/rtld.h>
     
    4748#include <rtld/rtld_arch.h>
    4849#include <rtld/module.h>
    49 #include <elf_load.h>
    5050
    5151/** (Eagerly) process all relocation tables in a module.
     
    9393module_t *module_find(const char *name)
    9494{
    95         link_t *head = &runtime_env->modules_head;
    96 
    97         link_t *cur;
    9895        module_t *m;
    9996        const char *p, *soname;
     
    110107
    111108        /* Traverse list of all modules. Not extremely fast, but simple */
    112         DPRINTF("head = %p\n", head);
    113         for (cur = head->next; cur != head; cur = cur->next) {
     109        list_foreach(runtime_env->modules, cur) {
    114110                DPRINTF("cur = %p\n", cur);
    115111                m = list_get_instance(cur, module_t, modules_link);
     
    177173
    178174        /* Insert into the list of loaded modules */
    179         list_append(&m->modules_link, &runtime_env->modules_head);
     175        list_append(&m->modules_link, &runtime_env->modules);
    180176
    181177        return m;
     
    249245void modules_process_relocs(module_t *start)
    250246{
    251         link_t *head = &runtime_env->modules_head;
    252 
    253         link_t *cur;
    254         module_t *m;
    255 
    256         for (cur = head->next; cur != head; cur = cur->next) {
     247        module_t *m;
     248
     249        list_foreach(runtime_env->modules, cur) {
    257250                m = list_get_instance(cur, module_t, modules_link);
    258251
     
    268261void modules_untag(void)
    269262{
    270         link_t *head = &runtime_env->modules_head;
    271 
    272         link_t *cur;
    273         module_t *m;
    274 
    275         for (cur = head->next; cur != head; cur = cur->next) {
     263        module_t *m;
     264
     265        list_foreach(runtime_env->modules, cur) {
    276266                m = list_get_instance(cur, module_t, modules_link);
    277267                m->bfs_tag = false;
  • uspace/lib/c/generic/rtld/rtld.c

    r6c69d19 r00c2de63  
    4444{
    4545        runtime_env = &rt_env_static;
    46         list_initialize(&runtime_env->modules_head);
     46        list_initialize(&runtime_env->modules);
    4747        runtime_env->next_bias = 0x2000000;
    4848        runtime_env->program = NULL;
  • uspace/lib/c/generic/rtld/symbol.c

    r6c69d19 r00c2de63  
    3838#include <stdlib.h>
    3939
     40#include <elf/elf.h>
    4041#include <rtld/rtld.h>
    4142#include <rtld/rtld_debug.h>
    4243#include <rtld/symbol.h>
    43 #include <elf.h>
    4444
    4545/*
     
    118118        module_t *m, *dm;
    119119        elf_symbol_t *sym, *s;
    120         link_t queue_head;
     120        list_t queue;
    121121        size_t i;
    122122
     
    132132
    133133        /* Insert root (the program) into the queue and tag it */
    134         list_initialize(&queue_head);
     134        list_initialize(&queue);
    135135        start->bfs_tag = true;
    136         list_append(&start->queue_link, &queue_head);
     136        list_append(&start->queue_link, &queue);
    137137
    138138        /* If the symbol is found, it will be stored in 'sym' */
     
    140140
    141141        /* While queue is not empty */
    142         while (!list_empty(&queue_head)) {
     142        while (!list_empty(&queue)) {
    143143                /* Pop first element from the queue */
    144                 m = list_get_instance(queue_head.next, module_t, queue_link);
     144                m = list_get_instance(list_first(&queue), module_t, queue_link);
    145145                list_remove(&m->queue_link);
    146146
     
    162162                        if (dm->bfs_tag == false) {
    163163                                dm->bfs_tag = true;
    164                                 list_append(&dm->queue_link, &queue_head);
     164                                list_append(&dm->queue_link, &queue);
    165165                        }
    166166                }
     
    168168
    169169        /* Empty the queue so that we leave it in a clean state */
    170         while (!list_empty(&queue_head))
    171                 list_remove(queue_head.next);
     170        while (!list_empty(&queue))
     171                list_remove(list_first(&queue));
    172172
    173173        if (!sym) {
  • uspace/lib/c/generic/vfs/vfs.c

    r6c69d19 r00c2de63  
    417417}
    418418
     419/** Read entire buffer.
     420 *
     421 * In face of short reads this function continues reading until either
     422 * the entire buffer is read or no more data is available (at end of file).
     423 *
     424 * @param fildes        File descriptor
     425 * @param buf           Buffer, @a nbytes bytes long
     426 * @param nbytes        Number of bytes to read
     427 *
     428 * @return              On success, positive number of bytes read.
     429 *                      On failure, negative error code from read().
     430 */
     431ssize_t read_all(int fildes, void *buf, size_t nbyte)
     432{
     433        ssize_t cnt = 0;
     434        size_t nread = 0;
     435        uint8_t *bp = (uint8_t *) buf;
     436
     437        do {
     438                bp += cnt;
     439                nread += cnt;
     440                cnt = read(fildes, bp, nbyte - nread);
     441        } while (cnt > 0 && (nbyte - nread - cnt) > 0);
     442
     443        if (cnt < 0)
     444                return cnt;
     445
     446        return nread + cnt;
     447}
     448
     449/** Write entire buffer.
     450 *
     451 * This function fails if it cannot write exactly @a len bytes to the file.
     452 *
     453 * @param fildes        File descriptor
     454 * @param buf           Data, @a nbytes bytes long
     455 * @param nbytes        Number of bytes to write
     456 *
     457 * @return              EOK on error, return value from write() if writing
     458 *                      failed.
     459 */
     460ssize_t write_all(int fildes, const void *buf, size_t nbyte)
     461{
     462        ssize_t cnt = 0;
     463        ssize_t nwritten = 0;
     464        const uint8_t *bp = (uint8_t *) buf;
     465
     466        do {
     467                bp += cnt;
     468                nwritten += cnt;
     469                cnt = write(fildes, bp, nbyte - nwritten);
     470        } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0);
     471
     472        if (cnt < 0)
     473                return cnt;
     474
     475        if ((ssize_t)nbyte - nwritten - cnt > 0)
     476                return EIO;
     477
     478        return nbyte;
     479}
     480
    419481int fsync(int fildes)
    420482{
  • uspace/lib/c/include/elf/elf_load.h

    r6c69d19 r00c2de63  
    11/*
     2 * Copyright (c) 2006 Sergey Bondari
    23 * Copyright (c) 2008 Jiri Svoboda
    34 * All rights reserved.
     
    3839
    3940#include <arch/elf.h>
     41#include <elf/elf.h>
    4042#include <sys/types.h>
    4143#include <loader/pcb.h>
    4244
    43 #include "elf.h"
     45/**
     46 * ELF error return codes
     47 */
     48#define EE_OK                   0       /* No error */
     49#define EE_INVALID              1       /* Invalid ELF image */
     50#define EE_MEMORY               2       /* Cannot allocate address space */
     51#define EE_INCOMPATIBLE         3       /* ELF image is not compatible with current architecture */
     52#define EE_UNSUPPORTED          4       /* Non-supported ELF (e.g. dynamic ELFs) */
     53#define EE_LOADER               5       /* The image is actually a program loader. */
     54#define EE_IRRECOVERABLE        6
    4455
    4556typedef enum {
     
    8293} elf_ld_t;
    8394
    84 int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags,
    85     elf_info_t *info);
    86 void elf_create_pcb(elf_info_t *info, pcb_t *pcb);
     95extern const char *elf_error(unsigned int);
     96extern int elf_load_file(const char *, size_t, eld_flags_t, elf_info_t *);
     97extern void elf_create_pcb(elf_info_t *, pcb_t *);
    8798
    8899#endif
  • uspace/lib/c/include/rtld/elf_dyn.h

    r6c69d19 r00c2de63  
    3939#include <sys/types.h>
    4040
    41 #include <elf.h>
     41#include <elf/elf.h>
    4242#include <libarch/rtld/elf_dyn.h>
    4343
  • uspace/lib/c/include/rtld/rtld.h

    r6c69d19 r00c2de63  
    4949
    5050        /** List of all loaded modules including rtld and the program */
    51         link_t modules_head;
     51        list_t modules;
    5252
    5353        /** Temporary hack to place each module at different address. */
  • uspace/lib/c/include/rtld/symbol.h

    r6c69d19 r00c2de63  
    3636#define LIBC_RTLD_SYMBOL_H_
    3737
     38#include <elf/elf.h>
    3839#include <rtld/rtld.h>
    39 #include <elf.h>
    4040
    4141elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod);
  • uspace/lib/c/include/unistd.h

    r6c69d19 r00c2de63  
    6363extern ssize_t read(int, void *, size_t);
    6464
     65extern ssize_t read_all(int, void *, size_t);
     66extern ssize_t write_all(int, const void *, size_t);
     67
    6568extern off64_t lseek(int, off64_t, int);
    6669extern int ftruncate(int, aoff64_t);
  • uspace/lib/fs/libfs.c

    r6c69d19 r00c2de63  
    4545#include <mem.h>
    4646#include <sys/stat.h>
     47#include <stdlib.h>
    4748
    4849#define on_error(rc, action) \
     
    6162        } while (0)
    6263
     64static fs_reg_t reg;
     65
     66static vfs_out_ops_t *vfs_out_ops = NULL;
     67static libfs_ops_t *libfs_ops = NULL;
     68
     69static void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     70static void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
     71static void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t,
     72    ipc_call_t *);
     73static void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     74static void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
     75    ipc_call_t *);
     76
     77static void vfs_out_mounted(ipc_callid_t rid, ipc_call_t *req)
     78{
     79        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     80        char *opts;
     81        int rc;
     82       
     83        /* Accept the mount options. */
     84        rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     85        if (rc != EOK) {
     86                async_answer_0(rid, rc);
     87                return;
     88        }
     89
     90        fs_index_t index;
     91        aoff64_t size;
     92        unsigned lnkcnt;
     93        rc = vfs_out_ops->mounted(devmap_handle, opts, &index, &size, &lnkcnt);
     94
     95        if (rc == EOK)
     96                async_answer_4(rid, EOK, index, LOWER32(size), UPPER32(size),
     97                    lnkcnt);
     98        else
     99                async_answer_0(rid, rc);
     100
     101        free(opts);
     102}
     103
     104static void vfs_out_mount(ipc_callid_t rid, ipc_call_t *req)
     105{
     106        libfs_mount(libfs_ops, reg.fs_handle, rid, req);
     107}
     108
     109static void vfs_out_unmounted(ipc_callid_t rid, ipc_call_t *req)
     110{
     111        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     112        int rc;
     113
     114        rc = vfs_out_ops->unmounted(devmap_handle);
     115
     116        async_answer_0(rid, rc);
     117}
     118
     119static void vfs_out_unmount(ipc_callid_t rid, ipc_call_t *req)
     120{
     121               
     122        libfs_unmount(libfs_ops, rid, req);
     123}
     124
     125static void vfs_out_lookup(ipc_callid_t rid, ipc_call_t *req)
     126{
     127        libfs_lookup(libfs_ops, reg.fs_handle, rid, req);
     128}
     129
     130static void vfs_out_read(ipc_callid_t rid, ipc_call_t *req)
     131{
     132        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     133        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     134        aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     135            IPC_GET_ARG4(*req));
     136        size_t rbytes;
     137        int rc;
     138
     139        rc = vfs_out_ops->read(devmap_handle, index, pos, &rbytes);
     140
     141        if (rc == EOK)
     142                async_answer_1(rid, EOK, rbytes);
     143        else
     144                async_answer_0(rid, rc);
     145}
     146
     147static void vfs_out_write(ipc_callid_t rid, ipc_call_t *req)
     148{
     149        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     150        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     151        aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     152            IPC_GET_ARG4(*req));
     153        size_t wbytes;
     154        aoff64_t nsize;
     155        int rc;
     156
     157        rc = vfs_out_ops->write(devmap_handle, index, pos, &wbytes, &nsize);
     158
     159        if (rc == EOK)
     160                async_answer_3(rid, EOK, wbytes, LOWER32(nsize), UPPER32(nsize));
     161        else
     162                async_answer_0(rid, rc);
     163}
     164
     165static void vfs_out_truncate(ipc_callid_t rid, ipc_call_t *req)
     166{
     167        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     168        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     169        aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     170            IPC_GET_ARG4(*req));
     171        int rc;
     172
     173        rc = vfs_out_ops->truncate(devmap_handle, index, size);
     174
     175        async_answer_0(rid, rc);
     176}
     177
     178static void vfs_out_close(ipc_callid_t rid, ipc_call_t *req)
     179{
     180        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     181        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     182        int rc;
     183
     184        rc = vfs_out_ops->close(devmap_handle, index);
     185
     186        async_answer_0(rid, rc);
     187}
     188
     189static void vfs_out_destroy(ipc_callid_t rid, ipc_call_t *req)
     190{
     191        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     192        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     193        int rc;
     194
     195        rc = vfs_out_ops->destroy(devmap_handle, index);
     196
     197        async_answer_0(rid, rc);
     198}
     199
     200static void vfs_out_open_node(ipc_callid_t rid, ipc_call_t *req)
     201{
     202        libfs_open_node(libfs_ops, reg.fs_handle, rid, req);
     203}
     204
     205static void vfs_out_stat(ipc_callid_t rid, ipc_call_t *req)
     206{
     207        libfs_stat(libfs_ops, reg.fs_handle, rid, req);
     208}
     209
     210static void vfs_out_sync(ipc_callid_t rid, ipc_call_t *req)
     211{
     212        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     213        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     214        int rc;
     215
     216        rc = vfs_out_ops->sync(devmap_handle, index);
     217
     218        async_answer_0(rid, rc);
     219}
     220
     221static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     222{
     223        if (iid) {
     224                /*
     225                 * This only happens for connections opened by
     226                 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
     227                 * created by IPC_M_CONNECT_TO_ME.
     228                 */
     229                async_answer_0(iid, EOK);
     230        }
     231       
     232        while (true) {
     233                ipc_call_t call;
     234                ipc_callid_t callid = async_get_call(&call);
     235               
     236                if (!IPC_GET_IMETHOD(call))
     237                        return;
     238               
     239                switch (IPC_GET_IMETHOD(call)) {
     240                case VFS_OUT_MOUNTED:
     241                        vfs_out_mounted(callid, &call);
     242                        break;
     243                case VFS_OUT_MOUNT:
     244                        vfs_out_mount(callid, &call);
     245                        break;
     246                case VFS_OUT_UNMOUNTED:
     247                        vfs_out_unmounted(callid, &call);
     248                        break;
     249                case VFS_OUT_UNMOUNT:
     250                        vfs_out_unmount(callid, &call);
     251                        break;
     252                case VFS_OUT_LOOKUP:
     253                        vfs_out_lookup(callid, &call);
     254                        break;
     255                case VFS_OUT_READ:
     256                        vfs_out_read(callid, &call);
     257                        break;
     258                case VFS_OUT_WRITE:
     259                        vfs_out_write(callid, &call);
     260                        break;
     261                case VFS_OUT_TRUNCATE:
     262                        vfs_out_truncate(callid, &call);
     263                        break;
     264                case VFS_OUT_CLOSE:
     265                        vfs_out_close(callid, &call);
     266                        break;
     267                case VFS_OUT_DESTROY:
     268                        vfs_out_destroy(callid, &call);
     269                        break;
     270                case VFS_OUT_OPEN_NODE:
     271                        vfs_out_open_node(callid, &call);
     272                        break;
     273                case VFS_OUT_STAT:
     274                        vfs_out_stat(callid, &call);
     275                        break;
     276                case VFS_OUT_SYNC:
     277                        vfs_out_sync(callid, &call);
     278                        break;
     279                default:
     280                        async_answer_0(callid, ENOTSUP);
     281                        break;
     282                }
     283        }
     284}
     285
    63286/** Register file system server.
    64287 *
     
    68291 *
    69292 * @param sess Session for communication with VFS.
    70  * @param reg  File system registration structure. It will be
    71  *             initialized by this function.
    72293 * @param info VFS info structure supplied by the file system
    73294 *             implementation.
    74  * @param conn Connection fibril for handling all calls originating in
    75  *             VFS.
     295 * @param vops Address of the vfs_out_ops_t structure.
     296 * @param lops Address of the libfs_ops_t structure.
    76297 *
    77298 * @return EOK on success or a non-zero error code on errror.
    78299 *
    79300 */
    80 int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info,
    81     async_client_conn_t conn)
     301int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops,
     302    libfs_ops_t *lops)
    82303{
    83304        /*
     
    104325       
    105326        /*
     327         * Set VFS_OUT and libfs operations.
     328         */
     329        vfs_out_ops = vops;
     330        libfs_ops = lops;
     331
     332        /*
    106333         * Ask VFS for callback connection.
    107334         */
    108         async_connect_to_me(exch, 0, 0, 0, conn, NULL);
     335        async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL);
    109336       
    110337        /*
    111338         * Allocate piece of address space for PLB.
    112339         */
    113         reg->plb_ro = as_get_mappable_page(PLB_SIZE);
    114         if (!reg->plb_ro) {
     340        reg.plb_ro = as_get_mappable_page(PLB_SIZE);
     341        if (!reg.plb_ro) {
    115342                async_exchange_end(exch);
    116343                async_wait_for(req, NULL);
     
    121348         * Request sharing the Path Lookup Buffer with VFS.
    122349         */
    123         rc = async_share_in_start_0_0(exch, reg->plb_ro, PLB_SIZE);
     350        rc = async_share_in_start_0_0(exch, reg.plb_ro, PLB_SIZE);
    124351       
    125352        async_exchange_end(exch);
     
    134361         */
    135362        async_wait_for(req, NULL);
    136         reg->fs_handle = (int) IPC_GET_ARG1(answer);
     363        reg.fs_handle = (int) IPC_GET_ARG1(answer);
    137364       
    138365        /*
     
    140367         * the same connection fibril as well.
    141368         */
    142         async_set_client_connection(conn);
     369        async_set_client_connection(vfs_connection);
    143370       
    144371        return IPC_GET_RETVAL(answer);
     
    151378
    152379void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    153     ipc_call_t *request)
    154 {
    155         devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    156         fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
    157         fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
    158         devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*request);
     380    ipc_call_t *req)
     381{
     382        devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     383        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
     384        fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req);
     385        devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*req);
    159386       
    160387        async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL);
     
    208435         * Do not release the FS node so that it stays in memory.
    209436         */
    210         async_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    211             IPC_GET_ARG3(answer));
    212 }
    213 
    214 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
    215 {
    216         devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    217         fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
     437        async_answer_4(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
     438            IPC_GET_ARG3(answer), IPC_GET_ARG4(answer));
     439}
     440
     441void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req)
     442{
     443        devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     444        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
    218445        fs_node_t *fn;
    219446        int res;
     
    259486}
    260487
     488static char plb_get_char(unsigned pos)
     489{
     490        return reg.plb_ro[pos % PLB_SIZE];
     491}
     492
    261493/** Lookup VFS triplet by name in the file system name space.
    262494 *
     
    273505 */
    274506void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    275     ipc_call_t *request)
    276 {
    277         unsigned int first = IPC_GET_ARG1(*request);
    278         unsigned int last = IPC_GET_ARG2(*request);
     507    ipc_call_t *req)
     508{
     509        unsigned int first = IPC_GET_ARG1(*req);
     510        unsigned int last = IPC_GET_ARG2(*req);
    279511        unsigned int next = first;
    280         devmap_handle_t devmap_handle = IPC_GET_ARG3(*request);
    281         int lflag = IPC_GET_ARG4(*request);
    282         fs_index_t index = IPC_GET_ARG5(*request);
     512        devmap_handle_t devmap_handle = IPC_GET_ARG3(*req);
     513        int lflag = IPC_GET_ARG4(*req);
     514        fs_index_t index = IPC_GET_ARG5(*req);
    283515        char component[NAME_MAX + 1];
    284516        int len;
     
    298530                async_exch_t *exch = async_exchange_begin(cur->mp_data.sess);
    299531                async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
    300                     cur->mp_data.devmap_handle, lflag, index, IPC_FF_ROUTE_FROM_ME);
     532                    cur->mp_data.devmap_handle, lflag, index,
     533                    IPC_FF_ROUTE_FROM_ME);
    301534                async_exchange_end(exch);
    302535               
     
    306539       
    307540        /* Eat slash */
    308         if (ops->plb_get_char(next) == '/')
     541        if (plb_get_char(next) == '/')
    309542                next++;
    310543       
     
    319552                /* Collect the component */
    320553                len = 0;
    321                 while ((next <= last) && (ops->plb_get_char(next) != '/')) {
     554                while ((next <= last) && (plb_get_char(next) != '/')) {
    322555                        if (len + 1 == NAME_MAX) {
    323556                                /* Component length overflow */
     
    325558                                goto out;
    326559                        }
    327                         component[len++] = ops->plb_get_char(next);
     560                        component[len++] = plb_get_char(next);
    328561                        /* Process next character */
    329562                        next++;
     
    357590                       
    358591                        async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess);
    359                         async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
    360                             tmp->mp_data.devmap_handle, lflag, index,
     592                        async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next,
     593                            last, tmp->mp_data.devmap_handle, lflag, index,
    361594                            IPC_FF_ROUTE_FROM_ME);
    362595                        async_exchange_end(exch);
     
    451684                        len = 0;
    452685                        while (next <= last) {
    453                                 if (ops->plb_get_char(next) == '/') {
     686                                if (plb_get_char(next) == '/') {
    454687                                        /* More than one component */
    455688                                        async_answer_0(rid, ENOENT);
     
    463696                                }
    464697                               
    465                                 component[len++] = ops->plb_get_char(next);
     698                                component[len++] = plb_get_char(next);
    466699                                /* Process next character */
    467700                                next++;
     
    637870        rc = ops->node_open(fn);
    638871        aoff64_t size = ops->size_get(fn);
    639         async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn),
     872        async_answer_4(rid, rc, LOWER32(size), UPPER32(size),
     873            ops->lnkcnt_get(fn),
    640874            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    641875       
  • uspace/lib/fs/libfs.h

    r6c69d19 r00c2de63  
    4343
    4444typedef struct {
     45        int (* mounted)(devmap_handle_t, const char *, fs_index_t *, aoff64_t *,
     46            unsigned *);
     47        int (* unmounted)(devmap_handle_t);
     48        int (* read)(devmap_handle_t, fs_index_t, aoff64_t, size_t *);
     49        int (* write)(devmap_handle_t, fs_index_t, aoff64_t, size_t *,
     50            aoff64_t *);
     51        int (* truncate)(devmap_handle_t, fs_index_t, aoff64_t);
     52        int (* close)(devmap_handle_t, fs_index_t);
     53        int (* destroy)(devmap_handle_t, fs_index_t);
     54        int (* sync)(devmap_handle_t, fs_index_t);
     55} vfs_out_ops_t;
     56
     57typedef struct {
    4558        bool mp_active;
    4659        async_sess_t *sess;
     
    7184        int (* has_children)(bool *, fs_node_t *);
    7285        /*
    73          * The second set of methods are usually mere getters that do not return
    74          * an integer error code.
     86         * The second set of methods are usually mere getters that do not
     87         * return an integer error code.
    7588         */
    7689        fs_index_t (* index_get)(fs_node_t *);
    7790        aoff64_t (* size_get)(fs_node_t *);
    7891        unsigned int (* lnkcnt_get)(fs_node_t *);
    79         char (* plb_get_char)(unsigned pos);
    8092        bool (* is_directory)(fs_node_t *);
    8193        bool (* is_file)(fs_node_t *);
     
    88100} fs_reg_t;
    89101
    90 extern int fs_register(async_sess_t *, fs_reg_t *, vfs_info_t *,
    91     async_client_conn_t);
     102extern int fs_register(async_sess_t *, vfs_info_t *, vfs_out_ops_t *,
     103    libfs_ops_t *);
    92104
    93105extern void fs_node_initialize(fs_node_t *);
    94 
    95 extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    96 extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    97 extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    98 extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    99 extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
    100     ipc_call_t *);
    101106
    102107#endif
  • uspace/lib/posix/assert.h

    r6c69d19 r00c2de63  
    4040
    4141#ifndef NDEBUG
    42         #define assert(expr) \
    43                 do { \
    44                         if (!(expr)) { \
    45                                 assert_abort(#expr, __FILE__, __LINE__); \
    46                         } \
    47                 } while (0)
     42        #define assert(expr) ((expr) ? (void) 0 : assert_abort(#expr, __FILE__, __LINE__))
    4843#else
    4944        #define assert(expr) ((void) 0)
  • uspace/lib/posix/ctype.c

    r6c69d19 r00c2de63  
    9494int posix_isprint(int c)
    9595{
    96         return !posix_iscntrl(c);
     96        return posix_isascii(c) && !posix_iscntrl(c);
    9797}
    9898
  • uspace/lib/posix/fnmatch.c

    r6c69d19 r00c2de63  
    525525static char *_casefold(const char *s)
    526526{
     527        assert(s != NULL);
    527528        char *result = strdup(s);
    528529        for (char *i = result; *i != '\0'; ++i) {
     
    542543int posix_fnmatch(const char *pattern, const char *string, int flags)
    543544{
     545        assert(pattern != NULL);
     546        assert(string != NULL);
     547
    544548        // TODO: don't fold everything in advance, but only when needed
    545549
  • uspace/lib/posix/internal/common.h

    r6c69d19 r00c2de63  
    4343    __func__, __FILE__, __LINE__), abort())
    4444
     45/* A little helper macro to avoid typing this over and over. */
     46#define errnify(func, ...) ({ \
     47        int rc = func(__VA_ARGS__); \
     48        if (rc < 0) { \
     49                errno = -rc; \
     50                rc = -1; \
     51        } \
     52        rc; \
     53})
     54
    4555#endif /* LIBPOSIX_COMMON_H_ */
    4656
  • uspace/lib/posix/pwd.c

    r6c69d19 r00c2de63  
    3939#include "errno.h"
    4040
    41 // TODO: documentation
    42 
    4341static bool entry_read = false;
    4442
     
    4644static const struct posix_passwd dummy_pwd = {
    4745        .pw_name = (char *) "user",
    48         .pw_uid = 1,
    49         .pw_gid = 1,
     46        .pw_uid = 0,
     47        .pw_gid = 0,
    5048        .pw_dir = (char *) "/",
    5149        .pw_shell = (char *) "/app/bdsh"
     
    115113{
    116114        assert(name != NULL);
     115        assert(pwd != NULL);
     116        assert(buffer != NULL);
     117        assert(result != NULL);
    117118       
    118119        if (posix_strcmp(name, "user") != 0) {
     
    121122        }
    122123       
    123         return posix_getpwuid_r(1, pwd, buffer, bufsize, result);
     124        return posix_getpwuid_r(0, pwd, buffer, bufsize, result);
    124125}
    125126
     
    132133struct posix_passwd *posix_getpwuid(posix_uid_t uid)
    133134{
    134         if (uid != 1) {
     135        if (uid != 0) {
    135136                return NULL;
    136137        }
     
    159160            '/', '\0', 'b', 'd', 's', 'h', '\0' };
    160161       
    161         if (uid != 1) {
     162        if (uid != 0) {
    162163                *result = NULL;
    163164                return 0;
     
    171172
    172173        pwd->pw_name = (char *) bf;
    173         pwd->pw_uid = 1;
    174         pwd->pw_gid = 1;
     174        pwd->pw_uid = 0;
     175        pwd->pw_gid = 0;
    175176        pwd->pw_dir = (char *) bf + 5;
    176177        pwd->pw_shell = (char *) bf + 7;
  • uspace/lib/posix/pwd.h

    r6c69d19 r00c2de63  
    3535#ifndef POSIX_PWD_H_
    3636#define POSIX_PWD_H_
    37 
    38 // TODO: documentation
    3937
    4038#include "sys/types.h"
  • uspace/lib/posix/signal.c

    r6c69d19 r00c2de63  
    6666
    6767/**
    68  *
    69  * @param signo
     68 * Default signal handler. Executes the default action for each signal,
     69 * as reasonable within HelenOS.
     70 *
     71 * @param signo Signal number.
    7072 */
    7173void __posix_default_signal_handler(int signo)
     
    7577                abort();
    7678        case SIGQUIT:
    77                 fprintf(stderr, "Quit signal raised. Exiting.");
     79                fprintf(stderr, "Quit signal raised. Exiting.\n");
    7880                exit(EXIT_FAILURE);
    7981        case SIGINT:
    80                 fprintf(stderr, "Interrupt signal caught. Exiting.");
     82                fprintf(stderr, "Interrupt signal caught. Exiting.\n");
    8183                exit(EXIT_FAILURE);
    8284        case SIGTERM:
    83                 fprintf(stderr, "Termination signal caught. Exiting.");
     85                fprintf(stderr, "Termination signal caught. Exiting.\n");
    8486                exit(EXIT_FAILURE);
    8587        case SIGSTOP:
    86                 fprintf(stderr, "Stop signal caught, but unsupported. Ignoring.");
     88                fprintf(stderr, "Stop signal caught, but unsupported. Ignoring.\n");
    8789                break;
    8890        case SIGKILL:
  • uspace/lib/posix/stdio.c

    r6c69d19 r00c2de63  
    5050#include "libc/str.h"
    5151#include "libc/malloc.h"
     52#include "libc/adt/list.h"
     53#include "libc/sys/stat.h"
    5254
    5355
     
    252254        assert(mode != NULL);
    253255        assert(stream != NULL);
    254 
     256       
     257        /* Retieve the node. */
     258        struct stat st;
     259        int rc;
     260       
    255261        if (filename == NULL) {
    256                 // TODO
    257                
    258                 /* print error to stderr as well, to avoid hard to find problems
    259                  * with buggy apps that expect this to work
    260                  */
    261                 fprintf(stderr,
    262                     "ERROR: Application wants to use freopen() to change mode of opened stream.\n"
    263                     "       libposix does not support that yet, the application may function improperly.\n");
    264                 errno = ENOTSUP;
     262                rc = fstat(stream->fd, &st);
     263        } else {
     264                rc = stat(filename, &st);
     265        }
     266       
     267        if (rc != EOK) {
     268                fclose(stream);
     269                errno = -rc;
    265270                return NULL;
    266271        }
    267 
    268         FILE* copy = malloc(sizeof(FILE));
    269         if (copy == NULL) {
    270                 errno = ENOMEM;
     272       
     273        fdi_node_t node = {
     274                .fs_handle = st.fs_handle,
     275                .devmap_handle = st.devmap_handle,
     276                .index = st.index
     277        };
     278       
     279        /* Open a new stream. */
     280        FILE* new = fopen_node(&node, mode);
     281        if (new == NULL) {
     282                fclose(stream);
     283                /* fopen_node() sets errno. */
    271284                return NULL;
    272285        }
    273         memcpy(copy, stream, sizeof(FILE));
    274         fclose(copy); /* copy is now freed */
    275        
    276         copy = fopen(filename, mode); /* open new stream */
    277         if (copy == NULL) {
    278                 /* fopen() sets errno */
    279                 return NULL;
    280         }
    281        
    282         /* move the new stream to the original location */
    283         memcpy(stream, copy, sizeof (FILE));
    284         free(copy);
    285        
    286         /* update references in the file list */
     286       
     287        /* Close the original stream without freeing it (ignoring errors). */
     288        if (stream->buf != NULL) {
     289                fflush(stream);
     290        }
     291        if (stream->sess != NULL) {
     292                async_hangup(stream->sess);
     293        }
     294        if (stream->fd >= 0) {
     295                close(stream->fd);
     296        }
     297        list_remove(&stream->link);
     298       
     299        /* Move the new stream to the original location. */
     300        memcpy(stream, new, sizeof (FILE));
     301        free(new);
     302       
     303        /* Update references in the file list. */
    287304        stream->link.next->prev = &stream->link;
    288305        stream->link.prev->next = &stream->link;
     
    676693
    677694/**
    678  * Remove a file.
     695 * Remove a file or directory.
    679696 *
    680697 * @param path Pathname of the file that shall be removed.
    681  * @return Zero on success, -1 otherwise.
     698 * @return Zero on success, -1 (with errno set) otherwise.
    682699 */
    683700int posix_remove(const char *path)
    684701{
    685         // FIXME: unlink() and rmdir() seem to be equivalent at the moment,
    686         //        but that does not have to be true forever
    687         return unlink(path);
     702        struct stat st;
     703        int rc = stat(path, &st);
     704       
     705        if (rc != EOK) {
     706                errno = -rc;
     707                return -1;
     708        }
     709       
     710        if (st.is_directory) {
     711                rc = rmdir(path);
     712        } else {
     713                rc = unlink(path);
     714        }
     715       
     716        if (rc != EOK) {
     717                errno = -rc;
     718                return -1;
     719        }
     720        return 0;
     721}
     722
     723/**
     724 * Rename a file or directory.
     725 *
     726 * @param old
     727 * @param new
     728 * @return Zero on success, -1 (with errno set) otherwise.
     729 */
     730int posix_rename(const char *old, const char *new)
     731{
     732        return errnify(rename, old, new);
    688733}
    689734
  • uspace/lib/posix/stdio.h

    r6c69d19 r00c2de63  
    116116extern int posix_remove(const char *path);
    117117
     118/* Renaming Files */
     119extern int posix_rename(const char *old, const char *new);
     120
    118121/* Temporary Files */
    119122#undef L_tmpnam
     
    170173        #define remove posix_remove
    171174
     175        #define rename posix_rename
     176
    172177        #define tmpnam posix_tmpnam
    173178#endif
  • uspace/lib/posix/sys/wait.c

    r6c69d19 r00c2de63  
    3939#include "wait.h"
    4040
     41#include "../libc/task.h"
     42#include "../assert.h"
     43#include "../errno.h"
     44#include "../limits.h"
     45#include "../signal.h"
     46
     47int __posix_wifexited(int status) {
     48        return status != INT_MIN;
     49}
     50
     51int __posix_wexitstatus(int status) {
     52        assert(__posix_wifexited(status));
     53        return status;
     54}
     55
     56int __posix_wifsignaled(int status) {
     57        return status == INT_MIN;
     58}
     59
     60int __posix_wtermsig(int status) {
     61        assert(__posix_wifsignaled(status));
     62        /* There is no way to distinguish reason
     63         * for unexpected termination at the moment.
     64         */
     65        return SIGABRT;
     66}
     67
    4168/**
    4269 *
     
    4673posix_pid_t posix_wait(int *stat_ptr)
    4774{
    48         // TODO: low priority, just a compile-time dependency of binutils
    49         not_implemented();
     75        /* HelenOS does not support this. */
     76        errno = ENOSYS;
     77        return (posix_pid_t) -1;
    5078}
    5179
     
    5987posix_pid_t posix_waitpid(posix_pid_t pid, int *stat_ptr, int options)
    6088{
    61         // TODO: low priority, just a compile-time dependency of binutils
    62         not_implemented();
     89        assert(stat_ptr != NULL);
     90        assert(options == 0 /* None of the options are supported. */);
     91       
     92        task_exit_t texit;
     93        int retval;
     94       
     95        int rc = task_wait((task_id_t) pid, &texit, &retval);
     96       
     97        if (rc < 0) {
     98                /* Unable to retrieve status. */
     99                errno = -rc;
     100                return (posix_pid_t) -1;
     101        }
     102       
     103        if (texit == TASK_EXIT_NORMAL) {
     104                // FIXME: relies on application not returning this value
     105                assert(retval != INT_MIN);
     106                *stat_ptr = retval;
     107        } else {
     108                /* Reserve the lowest value for unexpected termination. */
     109                *stat_ptr = INT_MIN;
     110        }
     111       
     112        return pid;
    63113}
    64114
  • uspace/lib/posix/sys/wait.h

    r6c69d19 r00c2de63  
    3838#include "types.h"
    3939
     40#undef WIFEXITED
     41#undef WEXITSTATUS
     42#undef WIFSIGNALED
     43#undef WTERMSIG
     44#define WIFEXITED(status) __posix_wifexited(status)
     45#define WEXITSTATUS(status) __posix_wexitstatus(status)
     46#define WIFSIGNALED(status) __posix_wifsignaled(status)
     47#define WTERMSIG(status) __posix_wtermsig(status)
     48
     49extern int __posix_wifexited(int status);
     50extern int __posix_wexitstatus(int status);
     51extern int __posix_wifsignaled(int status);
     52extern int __posix_wtermsig(int status);
     53
    4054extern posix_pid_t posix_wait(int *stat_ptr);
    4155extern posix_pid_t posix_waitpid(posix_pid_t pid, int *stat_ptr, int options);
     
    4357#ifndef LIBPOSIX_INTERNAL
    4458        #define wait posix_wait
    45         #define waitpid posix_waitpid
     59        #define waitpid posix_waitpid
    4660#endif
    4761
  • uspace/lib/posix/unistd.c

    r6c69d19 r00c2de63  
    110110                return NULL;
    111111        }
     112       
     113        /* Save the original value to comply with the "no modification on
     114         * success" semantics.
     115         */
     116        int orig_errno = errno;
     117        errno = EOK;
     118       
    112119        char *ret = getcwd(buf, size);
    113         if (ret == NULL && errno == EOK) {
    114                 errno = ERANGE;
    115         }
     120        if (ret == NULL) {
     121                /* Check errno to avoid shadowing other possible errors. */
     122                if (errno == EOK) {
     123                        errno = ERANGE;
     124                }
     125        } else {
     126                /* Success, restore previous errno value. */
     127                errno = orig_errno;
     128        }
     129       
    116130        return ret;
     131}
     132
     133/**
     134 * Change the current working directory.
     135 *
     136 * @param path New working directory.
     137 */
     138int posix_chdir(const char *path)
     139{
     140        return errnify(chdir, path);
    117141}
    118142
     
    157181        /* There is currently no support for user accounts in HelenOS. */
    158182        return 0;
     183}
     184
     185/**
     186 * Close a file.
     187 *
     188 * @param fildes
     189 * @return 0 on success, -1 on error.
     190 */
     191int posix_close(int fildes)
     192{
     193        return errnify(close, fildes);
    159194}
    160195
     
    169204ssize_t posix_read(int fildes, void *buf, size_t nbyte)
    170205{
    171         int rc = read(fildes, buf, nbyte);
    172         if (rc < 0) {
    173                 errno = -rc;
    174                 return -1;
    175         } else {
    176                 return rc;
    177         }
     206        return errnify(read, fildes, buf, nbyte);
     207}
     208
     209/**
     210 * Write to a file.
     211 *
     212 * @param fildes File descriptor of the opened file.
     213 * @param buf Buffer to write.
     214 * @param nbyte Size of the buffer.
     215 * @return Number of written bytes on success, -1 otherwise.
     216 */
     217ssize_t posix_write(int fildes, const void *buf, size_t nbyte)
     218{
     219        return errnify(write, fildes, buf, nbyte);
     220}
     221
     222/**
     223 * Requests outstanding data to be written to the underlying storage device.
     224 *
     225 * @param fildes
     226 */
     227int posix_fsync(int fildes)
     228{
     229        return errnify(fsync, fildes);
     230}
     231
     232int posix_ftruncate(int fildes, posix_off_t length)
     233{
     234        return errnify(ftruncate, fildes, (aoff64_t) length);
     235}
     236
     237/**
     238 * Remove a directory.
     239 *
     240 * @param path Directory pathname.
     241 * @return Zero on success, -1 otherwise.
     242 */
     243int posix_rmdir(const char *path)
     244{
     245        return errnify(rmdir, path);
    178246}
    179247
     
    186254int posix_unlink(const char *path)
    187255{
    188         int rc = unlink(path);
    189         if (rc < 0) {
    190                 errno = -rc;
    191                 return -1;
    192         } else {
    193                 return rc;
    194         }
     256        return errnify(unlink, path);
     257}
     258
     259int posix_dup(int fildes)
     260{
     261        return posix_fcntl(fildes, F_DUPFD, 0);
     262}
     263
     264int posix_dup2(int fildes, int fildes2)
     265{
     266        return errnify(dup2, fildes, fildes2);
    195267}
    196268
     
    204276int posix_access(const char *path, int amode)
    205277{
    206         if (amode == F_OK) {
    207                 /* Check file existence by attempt to open it. */
     278        if (amode == F_OK || (amode & (X_OK | W_OK | R_OK))) {
     279                /* HelenOS doesn't support permissions, permission checks
     280                 * are equal to existence check.
     281                 *
     282                 * Check file existence by attempting to open it.
     283                 */
    208284                int fd = open(path, O_RDONLY);
    209                 if (fd != -1) {
    210                         close(fd);
     285                if (fd < 0) {
     286                        errno = -fd;
     287                        return -1;
    211288                }
    212                 return fd;
    213         } else if (amode & (X_OK | W_OK | R_OK)) {
    214                 /* HelenOS doesn't support permissions, return success. */
     289                close(fd);
    215290                return 0;
    216291        } else {
  • uspace/lib/posix/unistd.h

    r6c69d19 r00c2de63  
    6060/* Working Directory */
    6161extern char *posix_getcwd(char *buf, size_t size);
     62extern int posix_chdir(const char *path);
    6263
    6364/* Query Memory Parameters */
     
    6970extern posix_gid_t posix_getgid(void);
    7071
    71 /* File Input/Output */
     72/* File Manipulation */
     73extern int posix_close(int fildes);
     74
    7275extern ssize_t posix_read(int fildes, void *buf, size_t nbyte);
     76extern ssize_t posix_write(int fildes, const void *buf, size_t nbyte);
    7377
    74 /* Deleting Files */
     78extern int posix_fsync(int fildes);
     79extern int posix_ftruncate(int fildes, posix_off_t length);
     80
     81extern int posix_rmdir(const char *path);
    7582extern int posix_unlink(const char *path);
     83
     84extern int posix_dup(int fildes);
     85extern int posix_dup2(int fildes, int fildes2);
    7686
    7787/* Standard Streams */
     
    144154
    145155        #define getcwd posix_getcwd
     156        #define chdir posix_chdir
    146157
    147158        #define isatty posix_isatty
     
    154165        #define getgid posix_getgid
    155166
     167        #define close posix_close
    156168        #define read posix_read
    157 
     169        #define write posix_write
     170        #define fsync posix_fsync
     171        #define ftruncate posix_ftruncate
     172        #define rmdir posix_rmdir
    158173        #define unlink posix_unlink
     174        #define dup posix_dup
     175        #define dup2 posix_dup2
    159176
    160177        #define access posix_access
  • uspace/lib/scsi/include/scsi/sbc.h

    r6c69d19 r00c2de63  
    5656};
    5757
     58/** SCSI Read (10) command */
     59typedef struct {
     60        /** Operation code (SCSI_CMD_READ_10) */
     61        uint8_t op_code;
     62        /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */
     63        uint8_t flags;
     64        /** Logical block address */
     65        uint32_t lba;
     66        /** Reserved, Group Number */
     67        uint8_t group_no;
     68        /** Transfer length */
     69        uint16_t xfer_len;
     70        /** Control */
     71        uint8_t control;
     72} __attribute__((packed)) scsi_cdb_read_10_t;
     73
    5874/** SCSI Read (12) command */
    5975typedef struct {
    6076        /** Operation code (SCSI_CMD_READ_12) */
    6177        uint8_t op_code;
    62         /** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
     78        /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */
    6379        uint8_t flags;
    6480        /** Logical block address */
     
    115131} scsi_read_capacity_10_data_t;
    116132
     133/** SCSI Write (10) command */
     134typedef struct {
     135        /** Operation code (SCSI_CMD_WRITE_10) */
     136        uint8_t op_code;
     137        /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */
     138        uint8_t flags;
     139        /** Logical block address */
     140        uint32_t lba;
     141        /** Reserved, Group Number */
     142        uint8_t group_no;
     143        /** Transfer length */
     144        uint16_t xfer_len;
     145        /** Control */
     146        uint8_t control;
     147} __attribute__((packed)) scsi_cdb_write_10_t;
     148
    117149/** SCSI Write (12) command */
    118150typedef struct {
    119151        /** Operation code (SCSI_CMD_WRITE_12) */
    120152        uint8_t op_code;
    121         /** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
     153        /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */
    122154        uint8_t flags;
    123155        /** Logical block address */
  • uspace/lib/scsi/include/scsi/spc.h

    r6c69d19 r00c2de63  
    179179        uint8_t additional_len;
    180180        /** Command-specific Information */
    181         uint8_t cmd_spec;
     181        uint32_t cmd_spec;
    182182        /** Additional Sense Code */
    183183        uint8_t additional_code;
     
    205205        SCSI_SK_ABORTED_COMMAND = 0xb,
    206206        SCSI_SK_VOLUME_OVERFLOW = 0xd,
    207         SCSI_SK_MISCOMPARE      = 0xe
     207        SCSI_SK_MISCOMPARE      = 0xe,
     208
     209        SCSI_SK_LIMIT           = 0x10
    208210};
    209211
    210212extern const char *scsi_dev_type_str[SCSI_DEV_LIMIT];
     213extern const char *scsi_sense_key_str[SCSI_SK_LIMIT];
     214
    211215extern const char *scsi_get_dev_type_str(unsigned);
     216extern const char *scsi_get_sense_key_str(unsigned);
    212217
    213218#endif
  • uspace/lib/scsi/src/spc.c

    r6c69d19 r00c2de63  
    4444};
    4545
     46const char *scsi_sense_key_str[SCSI_SK_LIMIT] = {
     47        [SCSI_SK_NO_SENSE]              = "No Sense",
     48        [SCSI_SK_RECOVERED_ERROR]       = "Recovered Error",
     49        [SCSI_SK_NOT_READY]             = "Not Ready",
     50        [SCSI_SK_MEDIUM_ERROR]          = "Medium Error",
     51        [SCSI_SK_HARDWARE_ERROR]        = "Hardware Error",
     52        [SCSI_SK_ILLEGAL_REQUEST]       = "Illegal Request",
     53        [SCSI_SK_UNIT_ATTENTION]        = "Unit Attention",
     54        [SCSI_SK_DATA_PROTECT]          = "Data Protect",
     55        [SCSI_SK_BLANK_CHECK]           = "Blank Check",
     56        [SCSI_SK_VENDOR_SPECIFIC]       = "Vendor-specific",
     57        [SCSI_SK_COPY_ABORTED]          = "Copy Aborted",
     58        [SCSI_SK_ABORTED_COMMAND]       = "Aborted Command",
     59        [SCSI_SK_VOLUME_OVERFLOW]       = "Volume Overflow",
     60        [SCSI_SK_MISCOMPARE]            = "Miscompare"
     61};
     62
    4663/** Get peripheral device type string.
    4764 *
     
    5370{
    5471        if (dev_type >= SCSI_DEV_LIMIT || scsi_dev_type_str[dev_type] == NULL)
    55                 return "<unknown>";
     72                return "Unknown";
    5673
    5774        return scsi_dev_type_str[dev_type];
    5875}
     76
     77/** Get sense key string.
     78 *
     79 * Return string description of SCSI sense key.
     80 * The returned string is valid indefinitely, the caller should
     81 * not attempt to free it.
     82 */
     83const char *scsi_get_sense_key_str(unsigned sense_key)
     84{
     85        if (sense_key >= SCSI_SK_LIMIT || scsi_sense_key_str[sense_key] == NULL)
     86                return "Unknown";
     87
     88        return scsi_sense_key_str[sense_key];
     89}
     90
Note: See TracChangeset for help on using the changeset viewer.