Changeset 3b3e776 in mainline for uspace/lib


Ignore:
Timestamp:
2010-02-05T10:57:50Z (16 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0358da0
Parents:
3f085132 (diff), b4cbef1 (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:

merged with head

Location:
uspace/lib
Files:
52 added
5 deleted
78 edited
7 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/Makefile.common

    r3f085132 r3b3e776  
    2828#
    2929
    30 ## Setup toolchain
     30## Common rules for building apps.
    3131#
    3232
    33 include Makefile.common
     33# Individual makefiles set:
     34#
     35#       USPACE_PREFIX   relative path to uspace/ directory
     36#       LIBS            libraries to link with (with relative path)
     37#       EXTRA_CFLAGS    additional flags to pass to C compiler
     38#       JOB             job file name (like appname.job)
     39#       OUTPUT          output binary name (like appname)
     40#       SOURCES         list of source files
     41#
     42
     43DEPEND = Makefile.depend
     44DEPEND_PREV = $(DEPEND).prev
     45
     46LIBC_PREFIX = $(USPACE_PREFIX)/lib/libc
     47
     48JOB = $(OUTPUT).job
     49
     50OBJECTS = $(addsuffix .o,$(basename $(SOURCES)))
     51
     52-include $(USPACE_PREFIX)/../Makefile.config
    3453include $(LIBC_PREFIX)/Makefile.toolchain
    3554
    36 CFLAGS += -Iinclude
     55CFLAGS += $(EXTRA_CFLAGS)
    3756
    38 ## Sources
    39 #
     57.PHONY: all build clean
    4058
    41 SOURCES = \
    42         generic/division.c\
    43         generic/multiplication.c
     59all: \
     60    $(LIBC_PREFIX)/../../../version \
     61    $(LIBC_PREFIX)/../../../Makefile.config \
     62    $(LIBC_PREFIX)/../../../config.h \
     63    $(LIBC_PREFIX)/../../../config.defs \
     64    $(LIBS) \
     65    \
     66    $(OUTPUT) \
     67    $(EXTRA_OUTPUT)
     68        -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
    4469
    45 OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
     70clean:
     71        rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(OUTPUT) $(EXTRA_OUTPUT) $(EXTRA_CLEAN)
     72        find . -name '*.o' -follow -exec rm \{\} \;
    4673
    47 .PHONY: all
    48 
    49 all: $(LIBSOFTINT)
     74build:
    5075
    5176-include $(DEPEND)
    5277
    53 $(LIBSOFTINT): $(OBJECTS)
     78$(OUTPUT): $(OBJECTS)
    5479        $(AR) rc $@ $(OBJECTS)
     80
     81%.o: %.S $(DEPEND)
     82        $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
     83ifeq ($(PRECHECK),y)
     84        $(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__
     85endif
     86
     87%.o: %.s $(DEPEND)
     88        $(AS) $(AFLAGS) $< -o $@
     89ifeq ($(PRECHECK),y)
     90        $(JOBFILE) $(JOB) $< $@ as asm $(AFLAGS)
     91endif
    5592
    5693%.o: %.c $(DEPEND)
    5794        $(CC) $(DEFS) $(CFLAGS) -c $< -o $@
     95ifeq ($(PRECHECK),y)
     96        $(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS)
     97endif
    5898
    59 $(DEPEND):
     99$(DEPEND): $(PRE_DEPEND)
    60100        makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
    61101        -[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
  • uspace/lib/libblock/Makefile

    r3f085132 r3b3e776  
    2828#
    2929
    30 include Makefile.common
     30USPACE_PREFIX = ../..
     31LIBS = $(LIBC_PREFIX)/libc.a
    3132
    32 .PHONY: all clean
     33OUTPUT = libblock.a
    3334
    34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
    35         -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
    36         $(MAKE) -f Makefile.build
     35SOURCES = \
     36        libblock.c
    3737
    38 clean:
    39         rm -f $(DEPEND) $(DEPEND_PREV) $(LIBBLOCK)
    40         find . -name '*.o' -follow -exec rm \{\} \;
     38include ../Makefile.common
  • uspace/lib/libblock/libblock.c

    r3f085132 r3b3e776  
    4747#include <as.h>
    4848#include <assert.h>
    49 #include <fibril_sync.h>
     49#include <fibril_synch.h>
    5050#include <adt/list.h>
    5151#include <adt/hash_table.h>
     
    8787static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
    8888static int get_block_size(int dev_phone, size_t *bsize);
     89static int get_num_blocks(int dev_phone, bn_t *nblocks);
    8990
    9091static devcon_t *devcon_search(dev_handle_t dev_handle)
     
    197198        assert(devcon);
    198199       
     200        if (devcon->cache)
     201                (void) block_cache_fini(dev_handle);
     202
    199203        devcon_remove(devcon);
    200204
    201205        if (devcon->bb_buf)
    202206                free(devcon->bb_buf);
    203 
    204         if (devcon->cache) {
    205                 hash_table_destroy(&devcon->cache->block_hash);
    206                 free(devcon->cache);
    207         }
    208207
    209208        munmap(devcon->comm_area, devcon->comm_size);
     
    301300
    302301        devcon->cache = cache;
     302        return EOK;
     303}
     304
     305int block_cache_fini(dev_handle_t dev_handle)
     306{
     307        devcon_t *devcon = devcon_search(dev_handle);
     308        cache_t *cache;
     309        int rc;
     310
     311        if (!devcon)
     312                return ENOENT;
     313        if (!devcon->cache)
     314                return EOK;
     315        cache = devcon->cache;
     316       
     317        /*
     318         * We are expecting to find all blocks for this device handle on the
     319         * free list, i.e. the block reference count should be zero. Do not
     320         * bother with the cache and block locks because we are single-threaded.
     321         */
     322        while (!list_empty(&cache->free_head)) {
     323                block_t *b = list_get_instance(cache->free_head.next,
     324                    block_t, free_link);
     325
     326                list_remove(&b->free_link);
     327                if (b->dirty) {
     328                        memcpy(devcon->comm_area, b->data, b->size);
     329                        rc = write_blocks(devcon, b->boff, 1);
     330                        if (rc != EOK)
     331                                return rc;
     332                }
     333
     334                long key = b->boff;
     335                hash_table_remove(&cache->block_hash, &key, 1);
     336               
     337                free(b->data);
     338                free(b);
     339        }
     340
     341        hash_table_destroy(&cache->block_hash);
     342        devcon->cache = NULL;
     343        free(cache);
     344
    303345        return EOK;
    304346}
     
    714756
    715757        memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    716         rc = read_blocks(devcon, ba, cnt);
     758        rc = write_blocks(devcon, ba, cnt);
    717759
    718760        fibril_mutex_unlock(&devcon->comm_area_lock);
     
    736778       
    737779        return get_block_size(devcon->dev_phone, bsize);
     780}
     781
     782/** Get number of blocks on device.
     783 *
     784 * @param dev_handle    Device handle of the block device.
     785 * @param nblocks       Output number of blocks.
     786 *
     787 * @return              EOK on success or negative error code on failure.
     788 */
     789int block_get_nblocks(dev_handle_t dev_handle, bn_t *nblocks)
     790{
     791        devcon_t *devcon;
     792
     793        devcon = devcon_search(dev_handle);
     794        assert(devcon);
     795       
     796        return get_num_blocks(devcon->dev_phone, nblocks);
    738797}
    739798
     
    789848}
    790849
     850/** Get total number of blocks on block device. */
     851static int get_num_blocks(int dev_phone, bn_t *nblocks)
     852{
     853        ipcarg_t nb_l, nb_h;
     854        int rc;
     855
     856        rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
     857        if (rc == EOK) {
     858                *nblocks = (bn_t) MERGE_LOUP32(nb_l, nb_h);
     859        }
     860
     861        return rc;
     862}
     863
    791864/** @}
    792865 */
  • uspace/lib/libblock/libblock.h

    r3f085132 r3b3e776  
    3636
    3737#ifndef LIBBLOCK_LIBBLOCK_H_
    38 #define LIBBLOCK_LIBBLOCK_H_
     38#define LIBBLOCK_LIBBLOCK_H_
    3939
    4040#include <stdint.h>
    4141#include "../../srv/vfs/vfs.h"
    42 #include <fibril_sync.h>
     42#include <fibril_synch.h>
    4343#include <adt/hash_table.h>
    4444#include <adt/list.h>
     
    5959 */
    6060#define BLOCK_FLAGS_NOREAD      1
    61 
    62 typedef uint64_t bn_t;  /**< Block number type. */
    6361
    6462typedef struct block {
     
    102100
    103101extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode);
     102extern int block_cache_fini(dev_handle_t);
    104103
    105104extern int block_get(block_t **, dev_handle_t, bn_t, int);
     
    110109
    111110extern int block_get_bsize(dev_handle_t, size_t *);
     111extern int block_get_nblocks(dev_handle_t, bn_t *);
    112112extern int block_read_direct(dev_handle_t, bn_t, size_t, void *);
    113113extern int block_write_direct(dev_handle_t, bn_t, size_t, const void *);
  • uspace/lib/libc/Makefile

    r3f085132 r3b3e776  
    11#
    22# Copyright (c) 2005 Martin Decky
     3# Copyright (c) 2007 Jakub Jermar
    34# All rights reserved.
    45#
     
    2728#
    2829
    29 include Makefile.common
     30-include ../../../Makefile.config
    3031
    31 .PHONY: all clean
     32USPACE_PREFIX = $(shell pwd)/../..
     33#LIBS = $(LIBC_PREFIX)/libc.a
     34LIBS =
    3235
    33 all: ../../../Makefile.config ../../../config.h ../../../config.defs
    34         -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
    35         $(MAKE) -f Makefile.build
     36LINK = arch/$(UARCH)/_link.ld
    3637
    37 clean:
    38         rm -f $(DEPEND) $(DEPEND_PREV) $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) $(LIBC) arch/*/_link.ld
    39         find generic/ arch/*/ -name '*.o' -follow -exec rm \{\} \;
     38PRE_DEPEND = $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH)
     39EXTRA_CLEAN = $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH)
     40EXTRA_OUTPUT = $(LINK)
     41
     42INCLUDE_KERNEL = include/kernel
     43INCLUDE_ARCH = include/arch
     44INCLUDE_LIBARCH = include/libarch
     45
     46OUTPUT = libc.a
     47
     48GENERIC_SOURCES = \
     49        generic/libc.c \
     50        generic/ddi.c \
     51        generic/as.c \
     52        generic/cap.c \
     53        generic/clipboard.c \
     54        generic/devmap.c \
     55        generic/event.c \
     56        generic/errno.c \
     57        generic/mem.c \
     58        generic/string.c \
     59        generic/fibril.c \
     60        generic/fibril_synch.c \
     61        generic/pcb.c \
     62        generic/smc.c \
     63        generic/thread.c \
     64        generic/tls.c \
     65        generic/task.c \
     66        generic/futex.c \
     67        generic/io/asprintf.c \
     68        generic/io/io.c \
     69        generic/io/printf.c \
     70        generic/io/klog.c \
     71        generic/io/snprintf.c \
     72        generic/io/vprintf.c \
     73        generic/io/vsnprintf.c \
     74        generic/io/printf_core.c \
     75        generic/io/console.c \
     76        generic/malloc.c \
     77        generic/sysinfo.c \
     78        generic/ipc.c \
     79        generic/async.c \
     80        generic/loader.c \
     81        generic/getopt.c \
     82        generic/adt/list.o \
     83        generic/adt/hash_table.o \
     84        generic/time.c \
     85        generic/err.c \
     86        generic/stdlib.c \
     87        generic/mman.c \
     88        generic/udebug.c \
     89        generic/vfs/vfs.c \
     90        generic/vfs/canonify.c \
     91        generic/stacktrace.c
     92
     93ARCH_SOURCES = \
     94        arch/$(UARCH)/src/entry.s \
     95        arch/$(UARCH)/src/thread_entry.s
     96
     97SOURCES = \
     98        $(GENERIC_SOURCES) \
     99        $(ARCH_SOURCES)
     100
     101include ../Makefile.common
     102
     103$(INCLUDE_ARCH): $(INCLUDE_KERNEL) $(INCLUDE_KERNEL)/arch
     104        ln -sfn kernel/arch $@
     105
     106$(INCLUDE_LIBARCH): arch/$(UARCH)/include
     107        ln -sfn ../$< $@
     108
     109$(INCLUDE_KERNEL)/arch: ../../../kernel/generic/include/arch $(INCLUDE_KERNEL)
     110
     111$(INCLUDE_KERNEL): ../../../kernel/generic/include/
     112        ln -sfn ../$< $@
     113
     114$(LINK): $(LINK).in
     115        $(GCC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
  • uspace/lib/libc/Makefile.toolchain

    r3f085132 r3b3e776  
    5959#
    6060
    61 include $(LIBC_PREFIX)/../../../Makefile.config
    62 include $(LIBC_PREFIX)/../../../config.defs
    63 include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc
     61-include $(LIBC_PREFIX)/../../../Makefile.config
     62-include $(LIBC_PREFIX)/../../../config.defs
     63-include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc
    6464
    6565## Simple detection of the host system
     
    7777## Toolchain configuration
    7878#
     79
     80JOBFILE = $(LIBC_PREFIX)/../../../tools/jobfile.py
    7981
    8082ifeq ($(COMPILER),gcc_cross)
  • uspace/lib/libc/arch/amd64/Makefile.inc

    r3f085132 r3b3e776  
    3636ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \
    3737        arch/$(UARCH)/src/fibril.S \
    38         arch/$(UARCH)/src/tls.c
     38        arch/$(UARCH)/src/tls.c \
     39        arch/$(UARCH)/src/stacktrace.c \
     40        arch/$(UARCH)/src/stacktrace_asm.S
    3941
     42GCC_CFLAGS += -fno-omit-frame-pointer
    4043LFLAGS += -N
    4144
  • uspace/lib/libc/arch/amd64/include/atomic.h

    r3f085132 r3b3e776  
    3737#ifndef LIBC_amd64_ATOMIC_H_
    3838#define LIBC_amd64_ATOMIC_H_
     39
     40#define LIBC_ARCH_ATOMIC_H_
     41
     42#include <atomicdflt.h>
    3943
    4044static inline void atomic_inc(atomic_t *val) {
  • uspace/lib/libc/arch/amd64/include/fibril.h

    r3f085132 r3b3e776  
    4444#define SP_DELTA     16
    4545
     46#define context_set(c, _pc, stack, size, ptls) \
     47        do { \
     48                (c)->pc = (sysarg_t) (_pc); \
     49                (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
     50                (c)->tls = (sysarg_t) (ptls); \
     51                (c)->rbp = 0; \
     52        } while (0)
     53
    4654/* We include only registers that must be preserved
    4755 * during function call
  • uspace/lib/libc/arch/amd64/include/types.h

    r3f085132 r3b3e776  
    3636#define LIBC_amd64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long long sysarg_t;
    3941
  • uspace/lib/libc/arch/amd64/src/entry.s

    r3f085132 r3b3e776  
    3838#
    3939__entry:
     40        #
     41        # Create the first stack frame.
     42        #
     43        pushq $0
     44        mov %rsp, %rbp
     45       
    4046        # %rdi was deliberately chosen as the first argument is also in %rdi
    4147        # Pass PCB pointer to __main (no operation)
  • uspace/lib/libc/arch/amd64/src/thread_entry.s

    r3f085132 r3b3e776  
    3636__thread_entry:
    3737        #
     38        # Create the first stack frame.
     39        #
     40        pushq $0
     41        movq %rsp, %rbp
     42
     43        #
    3844        # RAX contains address of uarg
    3945        #
  • uspace/lib/libc/arch/arm32/Makefile.inc

    r3f085132 r3b3e776  
    3737        arch/$(UARCH)/src/fibril.S \
    3838        arch/$(UARCH)/src/tls.c \
    39         arch/$(UARCH)/src/eabi.S
     39        arch/$(UARCH)/src/eabi.S \
     40        arch/$(UARCH)/src/stacktrace.c \
     41        arch/$(UARCH)/src/stacktrace_asm.S
    4042
    41 GCC_CFLAGS += -ffixed-r9 -mtp=soft
     43GCC_CFLAGS += -ffixed-r9 -mtp=soft -mapcs-frame -fno-omit-frame-pointer
    4244LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
    4345
  • uspace/lib/libc/arch/arm32/include/atomic.h

    r3f085132 r3b3e776  
    3737#define LIBC_arm32_ATOMIC_H_
    3838
     39#define LIBC_ARCH_ATOMIC_H_
     40#define CAS
     41
     42#include <atomicdflt.h>
     43#include <bool.h>
     44#include <sys/types.h>
     45
     46extern uintptr_t *ras_page;
     47
     48static inline bool cas(atomic_t *val, long ov, long nv)
     49{
     50        long ret = 0;
     51
     52        /*
     53         * The following instructions between labels 1 and 2 constitute a
     54         * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
     55         * the kernel will restart it.
     56         */
     57        asm volatile (
     58                "1:\n"
     59                "       adr %[ret], 1b\n"
     60                "       str %[ret], %[rp0]\n"
     61                "       adr %[ret], 2f\n"
     62                "       str %[ret], %[rp1]\n"
     63                "       ldr %[ret], %[addr]\n"
     64                "       cmp %[ret], %[ov]\n"
     65                "       streq %[nv], %[addr]\n"
     66                "2:\n"
     67                "       moveq %[ret], #1\n"
     68                "       movne %[ret], #0\n"
     69                : [ret] "+&r" (ret),
     70                  [rp0] "=m" (ras_page[0]),
     71                  [rp1] "=m" (ras_page[1]),
     72                  [addr] "+m" (val->count)
     73                : [ov] "r" (ov),
     74                  [nv] "r" (nv)
     75                : "memory"
     76        );
     77
     78        ras_page[0] = 0;
     79        asm volatile ("" ::: "memory");
     80        ras_page[1] = 0xffffffff;
     81
     82        return (bool) ret;
     83}
     84
    3985/** Atomic addition.
    4086 *
     
    4692static inline long atomic_add(atomic_t *val, int i)
    4793{
    48         int ret;
    49         volatile long * mem = &(val->count);
     94        long ret = 0;
    5095
     96        /*
     97         * The following instructions between labels 1 and 2 constitute a
     98         * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
     99         * the kernel will restart it.
     100         */
    51101        asm volatile (
    52         "1:\n"
    53                 "ldr r2, [%1]\n"
    54                 "add r3, r2, %2\n"
    55                 "str r3, %0\n"
    56                 "swp r3, r3, [%1]\n"
    57                 "cmp r3, r2\n"
    58                 "bne 1b\n"
     102                "1:\n"
     103                "       adr %[ret], 1b\n"
     104                "       str %[ret], %[rp0]\n"
     105                "       adr %[ret], 2f\n"
     106                "       str %[ret], %[rp1]\n"
     107                "       ldr %[ret], %[addr]\n"
     108                "       add %[ret], %[ret], %[imm]\n"
     109                "       str %[ret], %[addr]\n"
     110                "2:\n"
     111                : [ret] "+&r" (ret),
     112                  [rp0] "=m" (ras_page[0]),
     113                  [rp1] "=m" (ras_page[1]),
     114                  [addr] "+m" (val->count)
     115                : [imm] "r" (i)
     116        );
    59117
    60                 : "=m" (ret)
    61                 : "r" (mem), "r" (i)
    62                 : "r3", "r2"
    63         );
     118        ras_page[0] = 0;
     119        asm volatile ("" ::: "memory");
     120        ras_page[1] = 0xffffffff;
    64121
    65122        return ret;
  • uspace/lib/libc/arch/arm32/include/fibril.h

    r3f085132 r3b3e776  
    5858 *  @param ptls  Pointer to the TCB.
    5959 */
    60 #define context_set(c, _pc, stack, size, ptls)                  \
    61         (c)->pc = (sysarg_t) (_pc);                             \
    62         (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA;     \
    63         (c)->tls = ((sysarg_t)(ptls)) + sizeof(tcb_t) + ARM_TP_OFFSET;
    64 
     60#define context_set(c, _pc, stack, size, ptls) \
     61        do { \
     62                (c)->pc = (sysarg_t) (_pc); \
     63                (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
     64                (c)->tls = ((sysarg_t)(ptls)) + sizeof(tcb_t) + ARM_TP_OFFSET; \
     65                (c)->fp = 0; \
     66        } while (0)
    6567
    6668/** Fibril context.
     
    7981        uint32_t r7;
    8082        uint32_t r8;
    81         uint32_t tls;
     83        uint32_t tls;   /* r9 */
    8284        uint32_t r10;
    83         uint32_t r11;
     85        uint32_t fp;    /* r11 */
    8486} context_t;
    8587
  • uspace/lib/libc/arch/arm32/include/types.h

    r3f085132 r3b3e776  
    3737#define LIBC_arm32_TYPES_H_
    3838
     39#define __32_BITS__
     40
    3941typedef unsigned int sysarg_t;
    4042
  • uspace/lib/libc/arch/arm32/src/entry.s

    r3f085132 r3b3e776  
    3636#
    3737# r1 contains the PCB pointer
     38# r2 contains the RAS page address
    3839#
    3940__entry:
     41        # Store the RAS page address into the ras_page variable
     42        ldr r0, =ras_page
     43        str r2, [r0]
     44
     45        #
     46        # Create the first stack frame.
     47        #
     48        mov fp, #0
     49        mov ip, sp
     50        push {fp, ip, lr, pc}
     51        sub fp, ip, #4
     52
    4053        # Pass pcb_ptr to __main as the first argument (in r0)
    4154        mov r0, r1
     
    4356
    4457        bl __exit
     58
     59.data
     60
     61.global ras_page
     62ras_page:
     63        .long 0
     64
  • uspace/lib/libc/arch/arm32/src/syscall.c

    r3f085132 r3b3e776  
    6060        register sysarg_t __arm_reg_r5 asm("r5") = p6;
    6161        register sysarg_t __arm_reg_r6 asm("r6") = id;
    62 
    63         asm volatile ( "swi"
     62       
     63        asm volatile (
     64                "swi 0"
    6465                : "=r" (__arm_reg_r0)
    6566                : "r" (__arm_reg_r0),
     
    7172                  "r" (__arm_reg_r6)
    7273        );
    73 
     74       
    7475        return __arm_reg_r0;
    7576}
  • uspace/lib/libc/arch/arm32/src/thread_entry.s

    r3f085132 r3b3e776  
    3535#
    3636__thread_entry:
     37        #
     38        # Create the first stack frame.
     39        #
     40        mov fp, #0
     41        mov ip, sp
     42        push {fp, ip, lr, pc}
     43        sub fp, ip, #4
     44
    3745        b __thread_main
  • uspace/lib/libc/arch/ia32/Makefile.inc

    r3f085132 r3b3e776  
    3737        arch/$(UARCH)/src/fibril.S \
    3838        arch/$(UARCH)/src/tls.c \
    39         arch/$(UARCH)/src/setjmp.S
     39        arch/$(UARCH)/src/setjmp.S \
     40        arch/$(UARCH)/src/stacktrace.c \
     41        arch/$(UARCH)/src/stacktrace_asm.S
    4042
     43GCC_CFLAGS += -march=pentium
    4144LFLAGS += -N
    4245
  • uspace/lib/libc/arch/ia32/include/atomic.h

    r3f085132 r3b3e776  
    3535#ifndef LIBC_ia32_ATOMIC_H_
    3636#define LIBC_ia32_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val) {
  • uspace/lib/libc/arch/ia32/include/fibril.h

    r3f085132 r3b3e776  
    4444#define SP_DELTA     (12)
    4545
     46#define context_set(c, _pc, stack, size, ptls) \
     47        do { \
     48                (c)->pc = (sysarg_t) (_pc); \
     49                (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
     50                (c)->tls = (sysarg_t) (ptls); \
     51                (c)->ebp = 0; \
     52        } while (0)
     53       
    4654/* We include only registers that must be preserved
    4755 * during function call
  • uspace/lib/libc/arch/ia32/include/types.h

    r3f085132 r3b3e776  
    3636#define LIBC_ia32_TYPES_H_
    3737
     38#define __32_BITS__
     39
    3840typedef unsigned int sysarg_t;
    3941
  • uspace/lib/libc/arch/ia32/src/entry.s

    r3f085132 r3b3e776  
    5555        movl $__syscall_fast, (%eax)
    56560:
     57        #
     58        # Create the first stack frame.
     59        #
     60        pushl $0
     61        movl %esp, %ebp
    5762
    5863        # Pass the PCB pointer to __main as the first argument
  • uspace/lib/libc/arch/ia32/src/thread_entry.s

    r3f085132 r3b3e776  
    4242
    4343        #
     44        # Create the first stack frame.
     45        #
     46        pushl $0
     47        mov %esp, %ebp
     48
     49        #
    4450        # EAX contains address of uarg.
    4551        #
  • uspace/lib/libc/arch/ia64/Makefile.inc

    r3f085132 r3b3e776  
    3636        arch/$(UARCH)/src/fibril.S \
    3737        arch/$(UARCH)/src/tls.c \
    38         arch/$(UARCH)/src/ddi.c
     38        arch/$(UARCH)/src/ddi.c \
     39        arch/$(UARCH)/src/stacktrace.c \
     40        arch/$(UARCH)/src/stacktrace_asm.S
    3941
    4042GCC_CFLAGS += -fno-unwind-tables
  • uspace/lib/libc/arch/ia64/include/atomic.h

    r3f085132 r3b3e776  
    3535#ifndef LIBC_ia64_ATOMIC_H_
    3636#define LIBC_ia64_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val)
  • uspace/lib/libc/arch/ia64/include/types.h

    r3f085132 r3b3e776  
    3636#define LIBC_ia64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long long sysarg_t;
    3941
  • uspace/lib/libc/arch/mips32/Makefile.inc

    r3f085132 r3b3e776  
    3535ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
    3636        arch/$(UARCH)/src/fibril.S \
    37         arch/$(UARCH)/src/tls.c
     37        arch/$(UARCH)/src/tls.c \
     38        arch/$(UARCH)/src/stacktrace.c \
     39        arch/$(UARCH)/src/stacktrace_asm.S
    3840
    3941GCC_CFLAGS += -mips3
  • uspace/lib/libc/arch/mips32/include/atomic.h

    r3f085132 r3b3e776  
    3636#ifndef LIBC_mips32_ATOMIC_H_
    3737#define LIBC_mips32_ATOMIC_H_
     38
     39#define LIBC_ARCH_ATOMIC_H_
     40
     41#include <atomicdflt.h>
    3842
    3943#define atomic_inc(x)   ((void) atomic_add(x, 1))
  • uspace/lib/libc/arch/mips32/include/types.h

    r3f085132 r3b3e776  
    3737#define LIBC_mips32_TYPES_H_
    3838
     39#define __32_BITS__
     40
    3941typedef unsigned int sysarg_t;
    4042
  • uspace/lib/libc/arch/mips32eb/Makefile.inc

    r3f085132 r3b3e776  
    3535ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
    3636        arch/$(UARCH)/src/fibril.S \
    37         arch/$(UARCH)/src/tls.c
     37        arch/$(UARCH)/src/tls.c \
     38        arch/$(UARCH)/src/stacktrace.c \
     39        arch/$(UARCH)/src/stacktrace_asm.S
    3840
    3941GCC_CFLAGS += -mips3
  • uspace/lib/libc/arch/ppc32/Makefile.inc

    r3f085132 r3b3e776  
    3535ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
    3636        arch/$(UARCH)/src/fibril.S \
    37         arch/$(UARCH)/src/tls.c
     37        arch/$(UARCH)/src/tls.c \
     38        arch/$(UARCH)/src/stacktrace.c \
     39        arch/$(UARCH)/src/stacktrace_asm.S
    3840
    3941GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
  • uspace/lib/libc/arch/ppc32/include/atomic.h

    r3f085132 r3b3e776  
    3535#ifndef LIBC_ppc32_ATOMIC_H_
    3636#define LIBC_ppc32_ATOMIC_H_
     37
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3741
    3842static inline void atomic_inc(atomic_t *val)
  • uspace/lib/libc/arch/ppc32/include/types.h

    r3f085132 r3b3e776  
    3636#define LIBC_ppc32_TYPES_H_
    3737
     38#define __32_BITS__
     39
    3840typedef unsigned int sysarg_t;
    3941
  • uspace/lib/libc/arch/ppc32/src/entry.s

    r3f085132 r3b3e776  
    3838#
    3939__entry:
     40        #
     41        # Create the first stack frame.
     42        #
     43        li %r3, 0
     44        stw %r3, 0(%r1)
     45        stwu %r1, -16(%r1)
     46
    4047        # Pass the PCB pointer to __main() as the first argument.
    4148        # The first argument is passed in r3.
  • uspace/lib/libc/arch/ppc32/src/thread_entry.s

    r3f085132 r3b3e776  
    3535#
    3636__thread_entry:
     37        #
     38        # Create the first stack frame.
     39        #
     40        li %r4, 0
     41        stw %r4, 0(%r1)
     42        stwu %r1, -16(%r1)
     43
    3744        b __thread_main
    3845
  • uspace/lib/libc/arch/sparc64/Makefile.inc

    r3f085132 r3b3e776  
    3434
    3535ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \
    36         arch/$(UARCH)/src/tls.c
     36        arch/$(UARCH)/src/tls.c \
     37        arch/$(UARCH)/src/stacktrace.c \
     38        arch/$(UARCH)/src/stacktrace_asm.S
    3739
    3840GCC_CFLAGS += -mcpu=ultrasparc -m64
  • uspace/lib/libc/arch/sparc64/include/atomic.h

    r3f085132 r3b3e776  
    3636#define LIBC_sparc64_ATOMIC_H_
    3737
     38#define LIBC_ARCH_ATOMIC_H_
     39
     40#include <atomicdflt.h>
    3841#include <sys/types.h>
    3942
  • uspace/lib/libc/arch/sparc64/include/fibril.h

    r3f085132 r3b3e776  
    4646#endif
    4747
    48 #define context_set(c, _pc, stack, size, ptls)                  \
    49         (c)->pc = ((uintptr_t) _pc) - 8;                        \
    50         (c)->sp = ((uintptr_t) stack) + ALIGN_UP((size),        \
    51                 STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA);     \
    52         (c)->fp = -STACK_BIAS;                                  \
    53         (c)->tp = ptls
     48#define context_set(c, _pc, stack, size, ptls) \
     49        do { \
     50                (c)->pc = ((uintptr_t) _pc) - 8; \
     51                (c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), \
     52                    STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA); \
     53                (c)->fp = -STACK_BIAS; \
     54                (c)->tp = ptls; \
     55        } while (0)
    5456       
    5557/*
  • uspace/lib/libc/arch/sparc64/include/types.h

    r3f085132 r3b3e776  
    3636#define LIBC_sparc64_TYPES_H_
    3737
     38#define __64_BITS__
     39
    3840typedef unsigned long sysarg_t;
    3941
  • uspace/lib/libc/arch/sparc64/src/entry.s

    r3f085132 r3b3e776  
    3939#
    4040__entry:
     41        #
     42        # Create the first stack frame.
     43        #
     44        save %sp, -176, %sp
     45        flushw
     46        add %g0, -0x7ff, %fp
     47
    4148        # Pass pcb_ptr as the first argument to __main()
    42         mov %o1, %o0
     49        mov %i1, %o0
    4350        sethi %hi(_gp), %l7
    4451        call __main
  • uspace/lib/libc/arch/sparc64/src/fibril.S

    r3f085132 r3b3e776  
    3535
    3636context_save:
     37        #
     38        # We rely on the kernel to flush our active register windows to memory
     39        # should a thread switch occur.
     40        #
    3741        CONTEXT_SAVE_ARCH_CORE %o0
    3842        retl
     
    4246        #
    4347        # Flush all active windows.
    44         # This is essential, because CONTEXT_LOAD overwrites
    45         # %sp of CWP - 1 with the value written to %fp of CWP.
    46         # Flushing all active windows mitigates this problem
    47         # as CWP - 1 becomes the overlap window.
    48         #               
     48        # This is essential, because CONTEXT_RESTORE_ARCH_CORE overwrites %sp of
     49        # CWP - 1 with the value written to %fp of CWP.  Flushing all active
     50        # windows mitigates this problem as CWP - 1 becomes the overlap window.
     51        #
    4952        flushw
    5053       
  • uspace/lib/libc/arch/sparc64/src/stacktrace_asm.S

    r3f085132 r3b3e776  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2009 Jakub Jermar
    43# All rights reserved.
    54#
     
    2827#
    2928
    30 include Makefile.common
     29#include <libarch/stack.h>
    3130
    32 .PHONY: all clean
     31.text
    3332
    34 all: $(LIBC_PREFIX)/../../../version $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
    35         -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
    36         $(MAKE) -f Makefile.build
     33.global stacktrace_prepare
     34.global stacktrace_fp_get
     35.global stacktrace_pc_get
    3736
    38 clean:
    39         rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
    40         find . -name '*.o' -follow -exec rm \{\} \;
     37stacktrace_prepare:
     38        save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE+STACK_ARG_SAVE_AREA_SIZE), %sp
     39        # Flush all other windows to memory so that we can read their contents.
     40        flushw
     41        ret
     42        restore
     43
     44stacktrace_fp_get:
     45        # Add the stack bias to %sp to get the actual address.
     46        retl
     47        add %sp, STACK_BIAS, %o0
     48
     49stacktrace_pc_get:
     50        retl
     51        mov %o7, %o0
  • uspace/lib/libc/arch/sparc64/src/thread_entry.s

    r3f085132 r3b3e776  
    3535#
    3636__thread_entry:
     37        #
     38        # Create the first stack frame.
     39        #
     40        save %sp, -176, %sp
     41        flushw
     42        add %g0, -0x7ff, %fp
     43
    3744        sethi %hi(_gp), %l7
    3845        call __thread_main              ! %o0 contains address of uarg
  • uspace/lib/libc/generic/adt/hash_table.c

    r3f085132 r3b3e776  
    193193}
    194194
     195/** Apply fucntion to all items in hash table.
     196 *
     197 * @param h             Hash table.
     198 * @param f             Function to be applied.
     199 * @param arg           Argument to be passed to the function.
     200 */
     201void
     202hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)
     203{
     204        hash_index_t bucket;
     205        link_t *cur;
     206
     207        for (bucket = 0; bucket < h->entries; bucket++) {
     208                for (cur = h->entry[bucket].next; cur != &h->entry[bucket];
     209                    cur = cur->next) {
     210                        f(cur, arg);
     211                }
     212        }
     213}
     214
    195215/** @}
    196216 */
  • uspace/lib/libc/generic/async.c

    r3f085132 r3b3e776  
    392392        /* If nothing in queue, wait until something arrives */
    393393        while (list_empty(&conn->msg_queue)) {
     394                if (conn->close_callid) {
     395                        /*
     396                         * Handle the case when the connection was already
     397                         * closed by the client but the server did not notice
     398                         * the first IPC_M_PHONE_HUNGUP call and continues to
     399                         * call async_get_call_timeout(). Repeat
     400                         * IPC_M_PHONE_HUNGUP until the caller notices.
     401                         */
     402                        memset(call, 0, sizeof(ipc_call_t));
     403                        IPC_SET_METHOD(*call, IPC_M_PHONE_HUNGUP);
     404                        futex_up(&async_futex);
     405                        return conn->close_callid;
     406                }
     407
    394408                if (usecs)
    395409                        async_insert_timeout(&conn->wdata);
     
    528542        list_initialize(&conn->msg_queue);
    529543        conn->callid = callid;
    530         conn->close_callid = false;
     544        conn->close_callid = 0;
    531545       
    532546        if (call)
     
    12731287}
    12741288
     1289/** Wrapper for forwarding any read request
     1290 *
     1291 *
     1292 */
     1293int async_data_read_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
     1294    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
     1295{
     1296        ipc_callid_t callid;
     1297        if (!async_data_read_receive(&callid, NULL)) {
     1298                ipc_answer_0(callid, EINVAL);
     1299                return EINVAL;
     1300        }
     1301       
     1302        aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     1303            dataptr);
     1304        if (msg == 0) {
     1305                ipc_answer_0(callid, EINVAL);
     1306                return EINVAL;
     1307        }
     1308       
     1309        int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     1310            IPC_FF_ROUTE_FROM_ME);
     1311        if (retval != EOK) {
     1312                ipc_answer_0(callid, retval);
     1313                return retval;
     1314        }
     1315       
     1316        ipcarg_t rc;
     1317        async_wait_for(msg, &rc);
     1318       
     1319        return (int) rc;
     1320}
     1321
    12751322/** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.
    12761323 *
    1277  * @param phoneid       Phone that will be used to contact the receiving side.
    1278  * @param src           Address of the beginning of the source buffer.
    1279  * @param size          Size of the source buffer.
    1280  *
    1281  * @return              Zero on success or a negative error code from errno.h.
     1324 * @param phoneid Phone that will be used to contact the receiving side.
     1325 * @param src     Address of the beginning of the source buffer.
     1326 * @param size    Size of the source buffer.
     1327 *
     1328 * @return Zero on success or a negative error code from errno.h.
     1329 *
    12821330 */
    12831331int async_data_write_start(int phoneid, const void *src, size_t size)
     
    12941342 * So far, this wrapper is to be used from within a connection fibril.
    12951343 *
    1296  * @param callid        Storage where the hash of the IPC_M_DATA_WRITE call will
    1297  *                      be stored.
    1298  * @param size          Storage where the suggested size will be stored. May be
    1299  *                      NULL
    1300  *
    1301  * @return              Non-zero on success, zero on failure.
     1344 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will
     1345 *               be stored.
     1346 * @param size   Storage where the suggested size will be stored. May be
     1347 *               NULL
     1348 *
     1349 * @return Non-zero on success, zero on failure.
     1350 *
    13021351 */
    13031352int async_data_write_receive(ipc_callid_t *callid, size_t *size)
     
    13061355       
    13071356        assert(callid);
    1308 
     1357       
    13091358        *callid = async_get_call(&data);
    13101359        if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)
    13111360                return 0;
     1361       
    13121362        if (size)
    13131363                *size = (size_t) IPC_GET_ARG2(data);
     1364       
    13141365        return 1;
    13151366}
     
    13201371 * so that the user doesn't have to remember the meaning of each IPC argument.
    13211372 *
    1322  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    1323  * @param dst           Final destination address for the IPC_M_DATA_WRITE call.
    1324  * @param size          Final size for the IPC_M_DATA_WRITE call.
    1325  *
    1326  * @return              Zero on success or a value from @ref errno.h on failure.
     1373 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     1374 * @param dst    Final destination address for the IPC_M_DATA_WRITE call.
     1375 * @param size   Final size for the IPC_M_DATA_WRITE call.
     1376 *
     1377 * @return Zero on success or a value from @ref errno.h on failure.
     1378 *
    13271379 */
    13281380int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
     
    13311383}
    13321384
     1385/** Wrapper for receiving binary data
     1386 *
     1387 * This wrapper only makes it more comfortable to use async_data_write_*
     1388 * functions to receive binary data.
     1389 *
     1390 * @param data       Pointer to data pointer (which should be later disposed
     1391 *                   by free()). If the operation fails, the pointer is not
     1392 *                   touched.
     1393 * @param min_size   Minimum size (in bytes) of the data to receive.
     1394 * @param max_size   Maximum size (in bytes) of the data to receive. 0 means
     1395 *                   no limit.
     1396 * @param granulariy If non-zero, then the size of the received data has to
     1397 *                   be divisible by this value.
     1398 * @param received   If not NULL, the size of the received data is stored here.
     1399 *
     1400 * @return Zero on success or a value from @ref errno.h on failure.
     1401 *
     1402 */
     1403int async_data_receive(void **data, const size_t min_size,
     1404    const size_t max_size, const size_t granularity, size_t *received)
     1405{
     1406        ipc_callid_t callid;
     1407        size_t size;
     1408        if (!async_data_write_receive(&callid, &size)) {
     1409                ipc_answer_0(callid, EINVAL);
     1410                return EINVAL;
     1411        }
     1412       
     1413        if (size < min_size) {
     1414                ipc_answer_0(callid, EINVAL);
     1415                return EINVAL;
     1416        }
     1417       
     1418        if ((max_size > 0) && (size > max_size)) {
     1419                ipc_answer_0(callid, EINVAL);
     1420                return EINVAL;
     1421        }
     1422       
     1423        if ((granularity > 0) && ((size % granularity) != 0)) {
     1424                ipc_answer_0(callid, EINVAL);
     1425                return EINVAL;
     1426        }
     1427       
     1428        void *_data = malloc(size);
     1429        if (_data == NULL) {
     1430                ipc_answer_0(callid, ENOMEM);
     1431                return ENOMEM;
     1432        }
     1433       
     1434        int rc = async_data_write_finalize(callid, _data, size);
     1435        if (rc != EOK) {
     1436                free(_data);
     1437                return rc;
     1438        }
     1439       
     1440        *data = _data;
     1441        if (received != NULL)
     1442                *received = size;
     1443       
     1444        return EOK;
     1445}
     1446
     1447/** Wrapper for receiving strings
     1448 *
     1449 * This wrapper only makes it more comfortable to use async_data_write_*
     1450 * functions to receive strings.
     1451 *
     1452 * @param str      Pointer to string pointer (which should be later disposed
     1453 *                 by free()). If the operation fails, the pointer is not
     1454 *                 touched.
     1455 * @param max_size Maximum size (in bytes) of the string to receive. 0 means
     1456 *                 no limit.
     1457 * @param received If not NULL, the size of the received data is stored here.
     1458 *
     1459 * @return Zero on success or a value from @ref errno.h on failure.
     1460 *
     1461 */
     1462int async_string_receive(char **str, const size_t max_size, size_t *received)
     1463{
     1464        ipc_callid_t callid;
     1465        size_t size;
     1466        if (!async_data_write_receive(&callid, &size)) {
     1467                ipc_answer_0(callid, EINVAL);
     1468                return EINVAL;
     1469        }
     1470       
     1471        if ((max_size > 0) && (size > max_size)) {
     1472                ipc_answer_0(callid, EINVAL);
     1473                return EINVAL;
     1474        }
     1475       
     1476        char *data = (char *) malloc(size + 1);
     1477        if (data == NULL) {
     1478                ipc_answer_0(callid, ENOMEM);
     1479                return ENOMEM;
     1480        }
     1481       
     1482        int rc = async_data_write_finalize(callid, data, size);
     1483        if (rc != EOK) {
     1484                free(data);
     1485                return rc;
     1486        }
     1487       
     1488        data[size] = 0;
     1489        *str = data;
     1490        if (received != NULL)
     1491                *received = size;
     1492       
     1493        return EOK;
     1494}
     1495
     1496/** Wrapper for voiding any data that is about to be received
     1497 *
     1498 * This wrapper can be used to void any pending data
     1499 *
     1500 * @param retval Error value from @ref errno.h to be returned to the caller.
     1501 *
     1502 */
     1503void async_data_void(const int retval)
     1504{
     1505        ipc_callid_t callid;
     1506        async_data_write_receive(&callid, NULL);
     1507        ipc_answer_0(callid, retval);
     1508}
     1509
     1510/** Wrapper for forwarding any data that is about to be received
     1511 *
     1512 *
     1513 */
     1514int async_data_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
     1515    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
     1516{
     1517        ipc_callid_t callid;
     1518        if (!async_data_write_receive(&callid, NULL)) {
     1519                ipc_answer_0(callid, EINVAL);
     1520                return EINVAL;
     1521        }
     1522       
     1523        aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     1524            dataptr);
     1525        if (msg == 0) {
     1526                ipc_answer_0(callid, EINVAL);
     1527                return EINVAL;
     1528        }
     1529       
     1530        int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     1531            IPC_FF_ROUTE_FROM_ME);
     1532        if (retval != EOK) {
     1533                ipc_answer_0(callid, retval);
     1534                return retval;
     1535        }
     1536       
     1537        ipcarg_t rc;
     1538        async_wait_for(msg, &rc);
     1539       
     1540        return (int) rc;
     1541}
     1542
    13331543/** @}
    13341544 */
  • uspace/lib/libc/generic/devmap.c

    r3f085132 r3b3e776  
    3535#include <async.h>
    3636#include <errno.h>
     37#include <malloc.h>
     38#include <bool.h>
    3739
    3840static int devmap_phone_driver = -1;
     
    105107        aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
    106108       
    107         ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
    108        
     109        ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
    109110        if (retval != EOK) {
    110111                async_wait_for(req, NULL);
     
    126127/** Register new device.
    127128 *
    128  * @param name   Device name.
    129  * @param handle Output: Handle to the created instance of device.
     129 * @param namespace Namespace name.
     130 * @param fqdn      Fully qualified device name.
     131 * @param handle    Output: Handle to the created instance of device.
    130132 *
    131133 */
    132 int devmap_device_register(const char *name, dev_handle_t *handle)
     134int devmap_device_register(const char *fqdn, dev_handle_t *handle)
    133135{
    134136        int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
     
    143145            &answer);
    144146       
    145         ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
    146        
     147        ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
    147148        if (retval != EOK) {
    148149                async_wait_for(req, NULL);
     
    167168}
    168169
    169 int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
     170int devmap_device_get_handle(const char *fqdn, dev_handle_t *handle, unsigned int flags)
    170171{
    171172        int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
     
    180181            &answer);
    181182       
    182         ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1);
    183        
     183        ipcarg_t retval = async_data_write_start(phone, fqdn, str_size(fqdn));
    184184        if (retval != EOK) {
    185185                async_wait_for(req, NULL);
     
    202202       
    203203        return retval;
     204}
     205
     206int devmap_namespace_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
     207{
     208        int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
     209       
     210        if (phone < 0)
     211                return phone;
     212       
     213        async_serialize_start();
     214       
     215        ipc_call_t answer;
     216        aid_t req = async_send_2(phone, DEVMAP_NAMESPACE_GET_HANDLE, flags, 0,
     217            &answer);
     218       
     219        ipcarg_t retval = async_data_write_start(phone, name, str_size(name));
     220        if (retval != EOK) {
     221                async_wait_for(req, NULL);
     222                async_serialize_end();
     223                return retval;
     224        }
     225       
     226        async_wait_for(req, &retval);
     227       
     228        async_serialize_end();
     229       
     230        if (retval != EOK) {
     231                if (handle != NULL)
     232                        *handle = (dev_handle_t) -1;
     233                return retval;
     234        }
     235       
     236        if (handle != NULL)
     237                *handle = (dev_handle_t) IPC_GET_ARG1(answer);
     238       
     239        return retval;
     240}
     241
     242devmap_handle_type_t devmap_handle_probe(dev_handle_t handle)
     243{
     244        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     245       
     246        if (phone < 0)
     247                return phone;
     248       
     249        ipcarg_t type;
     250        int retval = async_req_1_1(phone, DEVMAP_HANDLE_PROBE, handle, &type);
     251        if (retval != EOK)
     252                return DEV_HANDLE_NONE;
     253       
     254        return (devmap_handle_type_t) type;
    204255}
    205256
     
    227278       
    228279        ipcarg_t null_id;
    229         int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
     280        int retval = async_req_0_1(phone, DEVMAP_NULL_CREATE, &null_id);
    230281        if (retval != EOK)
    231282                return -1;
     
    241292                return;
    242293       
    243         async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
    244 }
    245 
    246 ipcarg_t devmap_device_get_count(void)
    247 {
    248         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    249        
    250         if (phone < 0)
    251                 return 0;
    252        
     294        async_req_1_0(phone, DEVMAP_NULL_DESTROY, (ipcarg_t) null_id);
     295}
     296
     297static size_t devmap_count_namespaces_internal(int phone)
     298{
    253299        ipcarg_t count;
    254         int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
     300        int retval = async_req_0_1(phone, DEVMAP_GET_NAMESPACE_COUNT, &count);
    255301        if (retval != EOK)
    256302                return 0;
     
    259305}
    260306
    261 ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
    262 {
    263         int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
    264        
    265         if (phone < 0)
    266                 return 0;
    267        
    268         async_serialize_start();
    269        
    270         ipc_call_t answer;
    271         aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
    272        
    273         ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t));
    274        
    275         if (retval != EOK) {
    276                 async_wait_for(req, NULL);
    277                 async_serialize_end();
    278                 return 0;
    279         }
    280        
    281         async_wait_for(req, &retval);
    282        
    283         async_serialize_end();
    284        
     307static size_t devmap_count_devices_internal(int phone, dev_handle_t ns_handle)
     308{
     309        ipcarg_t count;
     310        int retval = async_req_1_1(phone, DEVMAP_GET_DEVICE_COUNT, ns_handle, &count);
    285311        if (retval != EOK)
    286312                return 0;
    287313       
    288         return IPC_GET_ARG1(answer);
    289 }
     314        return count;
     315}
     316
     317size_t devmap_count_namespaces(void)
     318{
     319        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     320       
     321        if (phone < 0)
     322                return 0;
     323       
     324        return devmap_count_namespaces_internal(phone);
     325}
     326
     327size_t devmap_count_devices(dev_handle_t ns_handle)
     328{
     329        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     330       
     331        if (phone < 0)
     332                return 0;
     333       
     334        return devmap_count_devices_internal(phone, ns_handle);
     335}
     336
     337size_t devmap_get_namespaces(dev_desc_t **data)
     338{
     339        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     340       
     341        if (phone < 0)
     342                return 0;
     343       
     344        /* Loop until namespaces read succesful */
     345        while (true) {
     346                size_t count = devmap_count_namespaces_internal(phone);
     347                if (count == 0)
     348                        return 0;
     349               
     350                dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
     351                if (devs == NULL)
     352                        return 0;
     353               
     354                async_serialize_start();
     355               
     356                ipc_call_t answer;
     357                aid_t req = async_send_0(phone, DEVMAP_GET_NAMESPACES, &answer);
     358               
     359                int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
     360                if (rc == EOVERFLOW) {
     361                        /*
     362                         * Number of namespaces has changed since
     363                         * the last call of DEVMAP_DEVICE_GET_NAMESPACE_COUNT
     364                         */
     365                        async_serialize_end();
     366                        free(devs);
     367                        continue;
     368                }
     369               
     370                if (rc != EOK) {
     371                        async_wait_for(req, NULL);
     372                        async_serialize_end();
     373                        free(devs);
     374                        return 0;
     375                }
     376               
     377                ipcarg_t retval;
     378                async_wait_for(req, &retval);
     379                async_serialize_end();
     380               
     381                if (retval != EOK)
     382                        return 0;
     383               
     384                *data = devs;
     385                return count;
     386        }
     387}
     388
     389size_t devmap_get_devices(dev_handle_t ns_handle, dev_desc_t **data)
     390{
     391        int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
     392       
     393        if (phone < 0)
     394                return 0;
     395       
     396        /* Loop until namespaces read succesful */
     397        while (true) {
     398                size_t count = devmap_count_devices_internal(phone, ns_handle);
     399                if (count == 0)
     400                        return 0;
     401               
     402                dev_desc_t *devs = (dev_desc_t *) calloc(count, sizeof(dev_desc_t));
     403                if (devs == NULL)
     404                        return 0;
     405               
     406                async_serialize_start();
     407               
     408                ipc_call_t answer;
     409                aid_t req = async_send_1(phone, DEVMAP_GET_DEVICES, ns_handle, &answer);
     410               
     411                int rc = async_data_read_start(phone, devs, count * sizeof(dev_desc_t));
     412                if (rc == EOVERFLOW) {
     413                        /*
     414                         * Number of devices has changed since
     415                         * the last call of DEVMAP_DEVICE_GET_DEVICE_COUNT
     416                         */
     417                        async_serialize_end();
     418                        free(devs);
     419                        continue;
     420                }
     421               
     422                if (rc != EOK) {
     423                        async_wait_for(req, NULL);
     424                        async_serialize_end();
     425                        free(devs);
     426                        return 0;
     427                }
     428               
     429                ipcarg_t retval;
     430                async_wait_for(req, &retval);
     431                async_serialize_end();
     432               
     433                if (retval != EOK)
     434                        return 0;
     435               
     436                *data = devs;
     437                return count;
     438        }
     439}
  • uspace/lib/libc/generic/fibril_synch.c

    r3f085132 r3b3e776  
    3333 */
    3434
    35 #include <fibril_sync.h>
     35#include <fibril_synch.h>
    3636#include <fibril.h>
    3737#include <async.h>
  • uspace/lib/libc/generic/futex.c

    r3f085132 r3b3e776  
    3636#include <atomic.h>
    3737#include <libc.h>
    38 #include <stdio.h>
    3938#include <sys/types.h>
    40 #include <kernel/synch/synch.h>
    41 
    42 /*
    43  * Note about race conditions.
    44  * Because of non-atomic nature of operations performed sequentially on the
    45  * futex counter and the futex wait queue, there is a race condition:
    46  *
    47  * (wq->missed_wakeups == 1) && (futex->count = 1)
    48  *
    49  * Scenario 1 (wait queue timeout vs. futex_up()):
    50  * 1. assume wq->missed_wakeups == 0 && futex->count == -1
    51  *    (ie. thread A sleeping, thread B in the critical section)
    52  * 2. A receives timeout and gets removed from the wait queue
    53  * 3. B wants to leave the critical section and calls futex_up()
    54  * 4. B thus changes futex->count from -1 to 0
    55  * 5. B has to call SYS_FUTEX_WAKEUP syscall to wake up the sleeping thread
    56  * 6. B finds the wait queue empty and changes wq->missed_wakeups from 0 to 1
    57  * 7. A fixes futex->count (i.e. the number of waiting threads) by changing it
    58  *    from 0 to 1
    59  *
    60  * Scenario 2 (conditional down operation vs. futex_up)
    61  * 1. assume wq->missed_wakeups == 0 && futex->count == 0
    62  *    (i.e. thread A is in the critical section)
    63  * 2. thread B performs futex_trydown() operation and changes futex->count from
    64  *    0 to -1
    65  *    B is now obliged to call SYS_FUTEX_SLEEP syscall
    66  * 3. A wants to leave the critical section and does futex_up()
    67  * 4. A thus changes futex->count from -1 to 0 and must call SYS_FUTEX_WAKEUP
    68  *    syscall
    69  * 5. B finds the wait queue empty and immediatelly aborts the conditional sleep
    70  * 6. No thread is queueing in the wait queue so wq->missed_wakeups changes from
    71  *    0 to 1
    72  * 6. B fixes futex->count (i.e. the number of waiting threads) by changing it
    73  *    from 0 to 1
    74  *
    75  * Both scenarios allow two threads to be in the critical section
    76  * simultaneously. One without kernel intervention and the other through
    77  * wq->missed_wakeups being 1.
    78  *
    79  * To mitigate this problem, futex_down_timeout() detects that the syscall
    80  * didn't sleep in the wait queue, fixes the futex counter and RETRIES the
    81  * whole operation again.
    82  */
    8339
    8440/** Initialize futex counter.
     
    9248}
    9349
    94 int futex_down(futex_t *futex)
    95 {
    96         return futex_down_timeout(futex, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
    97 }
    98 
    99 int futex_trydown(futex_t *futex)
    100 {
    101         return futex_down_timeout(futex, SYNCH_NO_TIMEOUT,
    102             SYNCH_FLAGS_NON_BLOCKING);
    103 }
    104 
    10550/** Try to down the futex.
    10651 *
    10752 * @param futex         Futex.
    108  * @param usec          Microseconds to wait. Zero value means sleep without
    109  *                      timeout.
    110  * @param flags         Select mode of operation. See comment for
    111  *                      waitq_sleep_timeout().
     53 * @return              Non-zero if the futex was acquired.
     54 * @return              Zero if the futex was not acquired.
     55 */
     56int futex_trydown(futex_t *futex)
     57{
     58        return cas(futex, 1, 0);
     59}
     60
     61/** Down the futex.
    11262 *
    113  * @return              ENOENT if there is no such virtual address. One of
    114  *                      ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED on success or
    115  *                      ESYNCH_TIMEOUT if the lock was not acquired because of
    116  *                      a timeout or ESYNCH_WOULD_BLOCK if the operation could
    117  *                      not be carried out atomically (if requested so).
     63 * @param futex         Futex.
     64 * @return              ENOENT if there is no such virtual address.
     65 * @return              Zero in the uncontended case.
     66 * @return              Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
    11867 */
    119 int futex_down_timeout(futex_t *futex, uint32_t usec, int flags)
     68int futex_down(futex_t *futex)
    12069{
    121         int rc;
    122        
    123         while (atomic_predec(futex) < 0) {
    124                 rc = __SYSCALL3(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count,
    125                     (sysarg_t) usec, (sysarg_t) flags);
    126                
    127                 switch (rc) {
    128                 case ESYNCH_OK_ATOMIC:
    129                         /*
    130                          * Because of a race condition between timeout and
    131                          * futex_up() and between conditional
    132                          * futex_down_timeout() and futex_up(), we have to give
    133                          * up and try again in this special case.
    134                          */
    135                         atomic_inc(futex);
    136                         break;
     70        if (atomic_predec(futex) < 0)
     71                return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
    13772
    138                 case ESYNCH_TIMEOUT:
    139                         atomic_inc(futex);
    140                         return ESYNCH_TIMEOUT;
    141                         break;
    142 
    143                 case ESYNCH_WOULD_BLOCK:
    144                         /*
    145                          * The conditional down operation should be implemented
    146                          * this way. The userspace-only variant tends to
    147                          * accumulate missed wakeups in the kernel futex wait
    148                          * queue.
    149                          */
    150                         atomic_inc(futex);
    151                         return ESYNCH_WOULD_BLOCK;
    152                         break;
    153 
    154                 case ESYNCH_OK_BLOCKED:
    155                         /*
    156                          * Enter the critical section.
    157                          * The futex counter has already been incremented for
    158                          * us.
    159                          */
    160                         return ESYNCH_OK_BLOCKED;
    161                         break;
    162                 default:
    163                         return rc;
    164                 }
    165         }
    166 
    167         /*
    168          * Enter the critical section.
    169          */
    170         return ESYNCH_OK_ATOMIC;
     73        return 0;
    17174}
    17275
     
    17477 *
    17578 * @param futex         Futex.
    176  *
    177  * @return              ENOENT if there is no such virtual address. Otherwise
    178  *                      zero.
     79 * @return              ENOENT if there is no such virtual address.
     80 * @return              Zero in the uncontended case.
    17981 */
    18082int futex_up(futex_t *futex)
    18183{
    182         long val;
    183        
    184         val = atomic_postinc(futex);
    185         if (val < 0)
     84        if (atomic_postinc(futex) < 0)
    18685                return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
    18786               
  • uspace/lib/libc/generic/io/console.c

    r3f085132 r3b3e776  
    9494}
    9595
     96int console_get_pos(int phone, int *col, int *row)
     97{
     98        ipcarg_t col_v;
     99        ipcarg_t row_v;
     100        int rc;
     101
     102        rc = async_req_0_2(phone, CONSOLE_GET_POS, &col_v, &row_v);
     103
     104        *col = (int) col_v;
     105        *row = (int) row_v;
     106        return rc;
     107}
     108
    96109void console_goto(int phone, int col, int row)
    97110{
  • uspace/lib/libc/generic/io/io.c

    r3f085132 r3b3e776  
    341341size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
    342342{
    343         size_t left = size * nmemb;
    344         size_t done = 0;
    345        
     343        size_t left, done;
     344
     345        if (size == 0 || nmemb == 0)
     346                return 0;
     347
    346348        /* Make sure no data is pending write. */
    347349        _fflushbuf(stream);
     350
     351        left = size * nmemb;
     352        done = 0;
    348353       
    349354        while ((left > 0) && (!stream->error) && (!stream->eof)) {
     
    365370static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
    366371{
    367         size_t left = size * nmemb;
    368         size_t done = 0;
    369        
     372        size_t left;
     373        size_t done;
     374
     375        if (size == 0 || nmemb == 0)
     376                return 0;
     377
     378        left = size * nmemb;
     379        done = 0;
     380
    370381        while ((left > 0) && (!stream->error)) {
    371382                ssize_t wr;
     
    421432        uint8_t b;
    422433        bool need_flush;
    423        
     434
     435        if (size == 0 || nmemb == 0)
     436                return 0;
     437
    424438        /* If not buffered stream, write out directly. */
    425439        if (stream->btype == _IONBF) {
     
    480494       
    481495        if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) {
    482                 size_t wr = fwrite(buf, sz, 1, stream);
     496                size_t wr = fwrite(buf, 1, sz, stream);
    483497               
    484498                if (wr < sz)
     
    540554}
    541555
     556int ftell(FILE *stream)
     557{
     558        off_t rc = lseek(stream->fd, 0, SEEK_CUR);
     559        if (rc == (off_t) (-1)) {
     560                /* errno has been set by lseek. */
     561                return -1;
     562        }
     563
     564        return rc;
     565}
     566
    542567void rewind(FILE *stream)
    543568{
     
    570595}
    571596
     597void clearerr(FILE *stream)
     598{
     599        stream->eof = false;
     600        stream->error = false;
     601}
     602
    572603int fphone(FILE *stream)
    573604{
  • uspace/lib/libc/generic/string.c

    r3f085132 r3b3e776  
    471471 * null-terminated and containing only complete characters.
    472472 *
    473  * @param dst   Destination buffer.
     473 * @param dest   Destination buffer.
    474474 * @param count Size of the destination buffer (must be > 0).
    475475 * @param src   Source string.
     
    505505 * have to be null-terminated.
    506506 *
    507  * @param dst   Destination buffer.
     507 * @param dest   Destination buffer.
    508508 * @param count Size of the destination buffer (must be > 0).
    509509 * @param src   Source string.
     
    537537 * null-terminated and containing only complete characters.
    538538 *
    539  * @param dst   Destination buffer.
     539 * @param dest   Destination buffer.
    540540 * @param count Size of the destination buffer.
    541541 * @param src   Source string.
     
    549549}
    550550
    551 /** Copy NULL-terminated wide string to string
    552  *
    553  * Copy source wide string @a src to destination buffer @a dst.
    554  * No more than @a size bytes are written. NULL-terminator is always
    555  * written after the last succesfully copied character (i.e. if the
    556  * destination buffer is has at least 1 byte, it will be always
    557  * NULL-terminated).
    558  *
    559  * @param src   Source wide string.
    560  * @param dst   Destination buffer.
    561  * @param count Size of the destination buffer.
    562  *
    563  */
    564 void wstr_nstr(char *dst, const wchar_t *src, size_t size)
    565 {
    566         /* No space for the NULL-terminator in the buffer */
    567         if (size == 0)
    568                 return;
    569        
     551/** Convert wide string to string.
     552 *
     553 * Convert wide string @a src to string. The output is written to the buffer
     554 * specified by @a dest and @a size. @a size must be non-zero and the string
     555 * written will always be well-formed.
     556 *
     557 * @param dest  Destination buffer.
     558 * @param size  Size of the destination buffer.
     559 * @param src   Source wide string.
     560 */
     561void wstr_to_str(char *dest, size_t size, const wchar_t *src)
     562{
    570563        wchar_t ch;
    571         size_t src_idx = 0;
    572         size_t dst_off = 0;
    573        
     564        size_t src_idx;
     565        size_t dest_off;
     566
     567        /* There must be space for a null terminator in the buffer. */
     568        assert(size > 0);
     569       
     570        src_idx = 0;
     571        dest_off = 0;
     572
    574573        while ((ch = src[src_idx++]) != 0) {
    575                 if (chr_encode(ch, dst, &dst_off, size) != EOK)
     574                if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
    576575                        break;
    577576        }
    578        
    579         if (dst_off >= size)
    580                 dst[size - 1] = 0;
    581         else
    582                 dst[dst_off] = 0;
     577
     578        dest[dest_off] = '\0';
     579}
     580
     581/** Convert wide string to new string.
     582 *
     583 * Convert wide string @a src to string. Space for the new string is allocated
     584 * on the heap.
     585 *
     586 * @param src   Source wide string.
     587 * @return      New string.
     588 */
     589char *wstr_to_astr(const wchar_t *src)
     590{
     591        char dbuf[STR_BOUNDS(1)];
     592        char *str;
     593        wchar_t ch;
     594
     595        size_t src_idx;
     596        size_t dest_off;
     597        size_t dest_size;
     598
     599        /* Compute size of encoded string. */
     600
     601        src_idx = 0;
     602        dest_size = 0;
     603
     604        while ((ch = src[src_idx++]) != 0) {
     605                dest_off = 0;
     606                if (chr_encode(ch, dbuf, &dest_off, STR_BOUNDS(1)) != EOK)
     607                        break;
     608                dest_size += dest_off;
     609        }
     610
     611        str = malloc(dest_size + 1);
     612        if (str == NULL)
     613                return NULL;
     614
     615        /* Encode string. */
     616
     617        src_idx = 0;
     618        dest_off = 0;
     619
     620        while ((ch = src[src_idx++]) != 0) {
     621                if (chr_encode(ch, str, &dest_off, dest_size) != EOK)
     622                        break;
     623        }
     624
     625        str[dest_size] = '\0';
     626        return str;
     627}
     628
     629
     630/** Convert string to wide string.
     631 *
     632 * Convert string @a src to wide string. The output is written to the
     633 * buffer specified by @a dest and @a dlen. @a dlen must be non-zero
     634 * and the wide string written will always be null-terminated.
     635 *
     636 * @param dest  Destination buffer.
     637 * @param dlen  Length of destination buffer (number of wchars).
     638 * @param src   Source string.
     639 */
     640void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
     641{
     642        size_t offset;
     643        size_t di;
     644        wchar_t c;
     645
     646        assert(dlen > 0);
     647
     648        offset = 0;
     649        di = 0;
     650
     651        do {
     652                if (di >= dlen - 1)
     653                        break;
     654
     655                c = str_decode(src, &offset, STR_NO_LIMIT);
     656                dest[di++] = c;
     657        } while (c != '\0');
     658
     659        dest[dlen - 1] = '\0';
    583660}
    584661
     
    819896}
    820897
     898char *str_dup(const char *src)
     899{
     900        size_t size = str_size(src);
     901        void *dest = malloc(size + 1);
     902       
     903        if (dest == NULL)
     904                return (char *) NULL;
     905       
     906        return (char *) memcpy(dest, src, size + 1);
     907}
     908
     909char *str_ndup(const char *src, size_t max_size)
     910{
     911        size_t size = str_size(src);
     912        if (size > max_size)
     913                size = max_size;
     914       
     915        char *dest = (char *) malloc(size + 1);
     916       
     917        if (dest == NULL)
     918                return (char *) NULL;
     919       
     920        memcpy(dest, src, size);
     921        dest[size] = 0;
     922        return dest;
     923}
     924
    821925
    822926/** Convert initial part of string to unsigned long according to given base.
     
    843947}
    844948
    845 char *str_dup(const char *src)
    846 {
    847         size_t size = str_size(src);
    848         void *dest = malloc(size + 1);
    849 
    850         if (dest == NULL)
    851                 return (char *) NULL;
    852 
    853         return (char *) memcpy(dest, src, size + 1);
    854 }
    855 
    856949char *strtok(char *s, const char *delim)
    857950{
  • uspace/lib/libc/generic/time.c

    r3f085132 r3b3e776  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#include <sys/time.h>
     
    4040#include <unistd.h>
    4141#include <atomic.h>
    42 #include <futex.h>
    4342#include <sysinfo.h>
    4443#include <ipc/services.h>
     44#include <libc.h>
    4545
    4646#include <sysinfo.h>
     
    189189
    190190/** Wait unconditionally for specified number of microseconds */
    191 int usleep(unsigned long usec)
    192 {
    193         atomic_t futex = FUTEX_INITIALIZER;
    194 
    195         futex_initialize(&futex, 0);
    196         futex_down_timeout(&futex, usec, 0);
     191int usleep(useconds_t usec)
     192{
     193        (void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
    197194        return 0;
    198195}
    199196
    200197/** Wait unconditionally for specified number of seconds */
    201 unsigned int sleep(unsigned int seconds)
    202 {
    203         atomic_t futex = FUTEX_INITIALIZER;
    204 
    205         futex_initialize(&futex, 0);
    206        
     198unsigned int sleep(unsigned int sec)
     199{
    207200        /* Sleep in 1000 second steps to support
    208201           full argument range */
    209         while (seconds > 0) {
    210                 unsigned int period = (seconds > 1000) ? 1000 : seconds;
     202        while (sec > 0) {
     203                unsigned int period = (sec > 1000) ? 1000 : sec;
    211204       
    212                 futex_down_timeout(&futex, period * 1000000, 0);
    213                 seconds -= period;
     205                usleep(period * 1000000);
     206                sec -= period;
    214207        }
    215208        return 0;
  • uspace/lib/libc/generic/udebug.c

    r3f085132 r3b3e776  
    6969}
    7070
     71int udebug_name_read(int phoneid, void *buffer, size_t n,
     72        size_t *copied, size_t *needed)
     73{
     74        ipcarg_t a_copied, a_needed;
     75        int rc;
     76
     77        rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,
     78                (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
     79
     80        *copied = (size_t)a_copied;
     81        *needed = (size_t)a_needed;
     82
     83        return rc;
     84}
     85
     86int udebug_areas_read(int phoneid, void *buffer, size_t n,
     87        size_t *copied, size_t *needed)
     88{
     89        ipcarg_t a_copied, a_needed;
     90        int rc;
     91
     92        rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ,
     93                (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
     94
     95        *copied = (size_t)a_copied;
     96        *needed = (size_t)a_needed;
     97
     98        return rc;
     99}
     100
    71101int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
    72102{
     
    78108{
    79109        return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ,
     110            tid, (sysarg_t)buffer);
     111}
     112
     113int udebug_regs_read(int phoneid, thash_t tid, void *buffer)
     114{
     115        return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ,
    80116            tid, (sysarg_t)buffer);
    81117}
  • uspace/lib/libc/generic/vfs/canonify.c

    r3f085132 r3b3e776  
    142142        t->start[-1] = '\0';
    143143}
    144 /** Eat the extra '/'..
     144/** Eat the extra '/'.
    145145 *
    146146 * @param t             The current TK_SLASH token.
     
    288288 *
    289289 * A file system path is canonical, if the following holds:
    290  * 1) the path is absolute (i.e. a/b/c is not canonical)
    291  * 2) there is no trailing slash in the path (i.e. /a/b/c is not canonical)
    292  * 3) there is no extra slash in the path (i.e. /a//b/c is not canonical)
    293  * 4) there is no '.' component in the path (i.e. /a/./b/c is not canonical)
    294  * 5) there is no '..' component in the path (i.e. /a/b/../c is not canonical)
     290 *
     291 * 1) the path is absolute
     292 *    (i.e. a/b/c is not canonical)
     293 * 2) there is no trailing slash in the path if it has components
     294 *    (i.e. /a/b/c/ is not canonical)
     295 * 3) there is no extra slash in the path
     296 *    (i.e. /a//b/c is not canonical)
     297 * 4) there is no '.' component in the path
     298 *    (i.e. /a/./b/c is not canonical)
     299 * 5) there is no '..' component in the path
     300 *    (i.e. /a/b/../c is not canonical)
    295301 *
    296302 * This function makes a potentially non-canonical file system path canonical.
  • uspace/lib/libc/generic/vfs/vfs.c

    r3f085132 r3b3e776  
    117117}
    118118
    119 int mount(const char *fs_name, const char *mp, const char *dev,
     119int mount(const char *fs_name, const char *mp, const char *fqdn,
    120120    const char *opts, unsigned int flags)
    121121{
    122         int res;
     122        int null_id = -1;
     123        char null[DEVMAP_NAME_MAXLEN];
     124       
     125        if (str_cmp(fqdn, "") == 0) {
     126                /* No device specified, create a fresh
     127                   null/%d device instead */
     128                null_id = devmap_null_create();
     129               
     130                if (null_id == -1)
     131                        return ENOMEM;
     132               
     133                snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);
     134                fqdn = null;
     135        }
     136       
     137        dev_handle_t dev_handle;
     138        int res = devmap_device_get_handle(fqdn, &dev_handle, flags);
     139        if (res != EOK) {
     140                if (null_id != -1)
     141                        devmap_null_destroy(null_id);
     142               
     143                return res;
     144        }
     145       
     146        size_t mpa_size;
     147        char *mpa = absolutize(mp, &mpa_size);
     148        if (!mpa) {
     149                if (null_id != -1)
     150                        devmap_null_destroy(null_id);
     151               
     152                return ENOMEM;
     153        }
     154       
     155        futex_down(&vfs_phone_futex);
     156        async_serialize_start();
     157        vfs_connect();
     158       
     159        ipcarg_t rc_orig;
     160        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
     161        ipcarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
     162        if (rc != EOK) {
     163                async_wait_for(req, &rc_orig);
     164                async_serialize_end();
     165                futex_up(&vfs_phone_futex);
     166                free(mpa);
     167               
     168                if (null_id != -1)
     169                        devmap_null_destroy(null_id);
     170               
     171                if (rc_orig == EOK)
     172                        return (int) rc;
     173                else
     174                        return (int) rc_orig;
     175        }
     176       
     177        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
     178        if (rc != EOK) {
     179                async_wait_for(req, &rc_orig);
     180                async_serialize_end();
     181                futex_up(&vfs_phone_futex);
     182                free(mpa);
     183               
     184                if (null_id != -1)
     185                        devmap_null_destroy(null_id);
     186               
     187                if (rc_orig == EOK)
     188                        return (int) rc;
     189                else
     190                        return (int) rc_orig;
     191        }
     192       
     193        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
     194        if (rc != EOK) {
     195                async_wait_for(req, &rc_orig);
     196                async_serialize_end();
     197                futex_up(&vfs_phone_futex);
     198                free(mpa);
     199               
     200                if (null_id != -1)
     201                        devmap_null_destroy(null_id);
     202               
     203                if (rc_orig == EOK)
     204                        return (int) rc;
     205                else
     206                        return (int) rc_orig;
     207        }
     208       
     209        /* Ask VFS whether it likes fs_name. */
     210        rc = async_req_0_0(vfs_phone, IPC_M_PING);
     211        if (rc != EOK) {
     212                async_wait_for(req, &rc_orig);
     213                async_serialize_end();
     214                futex_up(&vfs_phone_futex);
     215                free(mpa);
     216               
     217                if (null_id != -1)
     218                        devmap_null_destroy(null_id);
     219               
     220                if (rc_orig == EOK)
     221                        return (int) rc;
     222                else
     223                        return (int) rc_orig;
     224        }
     225       
     226        async_wait_for(req, &rc);
     227        async_serialize_end();
     228        futex_up(&vfs_phone_futex);
     229        free(mpa);
     230       
     231        if ((rc != EOK) && (null_id != -1))
     232                devmap_null_destroy(null_id);
     233       
     234        return (int) rc;
     235}
     236
     237int unmount(const char *mp)
     238{
    123239        ipcarg_t rc;
    124240        ipcarg_t rc_orig;
    125241        aid_t req;
    126         dev_handle_t dev_handle;
    127        
    128         res = devmap_device_get_handle(dev, &dev_handle, flags);
    129         if (res != EOK)
    130                 return res;
    131        
    132242        size_t mpa_size;
    133         char *mpa = absolutize(mp, &mpa_size);
     243        char *mpa;
     244       
     245        mpa = absolutize(mp, &mpa_size);
    134246        if (!mpa)
    135247                return ENOMEM;
     
    139251        vfs_connect();
    140252       
    141         req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
     253        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    142254        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    143255        if (rc != EOK) {
     
    152264        }
    153265       
    154         rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    155         if (rc != EOK) {
    156                 async_wait_for(req, &rc_orig);
    157                 async_serialize_end();
    158                 futex_up(&vfs_phone_futex);
    159                 free(mpa);
    160                 if (rc_orig == EOK)
    161                         return (int) rc;
    162                 else
    163                         return (int) rc_orig;
    164         }
    165 
    166         rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    167         if (rc != EOK) {
    168                 async_wait_for(req, &rc_orig);
    169                 async_serialize_end();
    170                 futex_up(&vfs_phone_futex);
    171                 free(mpa);
    172                 if (rc_orig == EOK)
    173                         return (int) rc;
    174                 else
    175                         return (int) rc_orig;
    176         }
    177 
    178         /* Ask VFS whether it likes fs_name. */
    179         rc = async_req_0_0(vfs_phone, IPC_M_PING);
    180         if (rc != EOK) {
    181                 async_wait_for(req, &rc_orig);
    182                 async_serialize_end();
    183                 futex_up(&vfs_phone_futex);
    184                 free(mpa);
    185                 if (rc_orig == EOK)
    186                         return (int) rc;
    187                 else
    188                         return (int) rc_orig;
    189         }
    190        
     266
    191267        async_wait_for(req, &rc);
    192268        async_serialize_end();
     
    703779        rc = fstat(fildes, &stat);
    704780
    705         if (!stat.devfs_stat.device)
     781        if (!stat.device)
    706782                return -1;
    707783       
    708         return devmap_device_connect(stat.devfs_stat.device, 0);
     784        return devmap_device_connect(stat.device, 0);
    709785}
    710786
  • uspace/lib/libc/include/adt/hash_table.h

    r3f085132 r3b3e776  
    8888extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t);
    8989extern void hash_table_destroy(hash_table_t *);
     90extern void hash_table_apply(hash_table_t *, void (*)(link_t *, void *),
     91    void *);
    9092
    9193#endif
  • uspace/lib/libc/include/assert.h

    r3f085132 r3b3e776  
    5151
    5252#ifndef NDEBUG
    53 #       define assert(expr) if (!(expr)) { printf("Assertion failed (%s) at file '%s', line %d.\n", #expr, __FILE__, __LINE__); abort();}
     53#       define assert(expr) \
     54                do { \
     55                        if (!(expr)) { \
     56                                printf("Assertion failed (%s) at file '%s', " \
     57                                    "line %d.\n", #expr, __FILE__, __LINE__); \
     58                                abort(); \
     59                        } \
     60                } while (0)
    5461#else
    5562#       define assert(expr)
  • uspace/lib/libc/include/async.h

    r3f085132 r3b3e776  
    277277extern int async_share_out_receive(ipc_callid_t *, size_t *, int *);
    278278extern int async_share_out_finalize(ipc_callid_t, void *);
     279
     280/*
     281 * User-friendly wrappers for async_data_read_forward_fast().
     282 */
     283#define async_data_read_forward_0_0(phoneid, method, answer) \
     284        async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
     285#define async_data_read_forward_0_1(phoneid, method, answer) \
     286        async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
     287#define async_data_read_forward_1_0(phoneid, method, arg1, answer) \
     288        async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
     289#define async_data_read_forward_1_1(phoneid, method, arg1, answer) \
     290        async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer))
     291#define async_data_read_forward_2_0(phoneid, method, arg1, arg2, answer) \
     292        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL)
     293#define async_data_read_forward_2_1(phoneid, method, arg1, arg2, answer) \
     294        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
     295            (answer))
     296#define async_data_read_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
     297        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
     298            NULL)
     299#define async_data_read_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
     300        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
     301            (answer))
     302#define async_data_read_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
     303        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     304            (arg4), NULL)
     305#define async_data_read_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
     306        async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     307            (arg4), (answer))
     308
    279309extern int async_data_read_start(int, void *, size_t);
    280310extern int async_data_read_receive(ipc_callid_t *, size_t *);
    281311extern int async_data_read_finalize(ipc_callid_t, const void *, size_t);
     312extern int async_data_read_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t,
     313    ipcarg_t, ipcarg_t, ipc_call_t *);
     314
     315/*
     316 * User-friendly wrappers for async_data_forward_fast().
     317 */
     318#define async_data_forward_0_0(phoneid, method, answer) \
     319        async_data_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
     320#define async_data_forward_0_1(phoneid, method, answer) \
     321        async_data_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer))
     322#define async_data_forward_1_0(phoneid, method, arg1, answer) \
     323        async_data_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL)
     324#define async_data_forward_1_1(phoneid, method, arg1, answer) \
     325        async_data_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer))
     326#define async_data_forward_2_0(phoneid, method, arg1, arg2, answer) \
     327        async_data_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL)
     328#define async_data_forward_2_1(phoneid, method, arg1, arg2, answer) \
     329        async_data_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \
     330            (answer))
     331#define async_data_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \
     332        async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
     333            NULL)
     334#define async_data_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \
     335        async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \
     336            (answer))
     337#define async_data_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \
     338        async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     339            (arg4), NULL)
     340#define async_data_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \
     341        async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \
     342            (arg4), (answer))
     343
    282344extern int async_data_write_start(int, const void *, size_t);
    283345extern int async_data_write_receive(ipc_callid_t *, size_t *);
    284346extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
     347extern int async_data_receive(void **, const size_t, const size_t,
     348    const size_t, size_t *);
     349extern int async_string_receive(char **, const size_t, size_t *);
     350extern void async_data_void(const int);
     351extern int async_data_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t,
     352    ipcarg_t, ipc_call_t *);
    285353
    286354#endif
  • uspace/lib/libc/include/atomic.h

    r3f085132 r3b3e776  
    11/*
    2  * Copyright (c) 2006 Jakub Jermar
     2 * Copyright (c) 2009 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    3636#define LIBC_ATOMIC_H_
    3737
    38 typedef struct atomic {
    39         volatile long count;
    40 } atomic_t;
    41 
    4238#include <libarch/atomic.h>
    43 
    44 static inline void atomic_set(atomic_t *val, long i)
    45 {
    46         val->count = i;
    47 }
    48 
    49 static inline long atomic_get(atomic_t *val)
    50 {
    51         return val->count;
    52 }
    5339
    5440#endif
  • uspace/lib/libc/include/devmap.h

    r3f085132 r3b3e776  
    3838#include <ipc/devmap.h>
    3939#include <async.h>
     40#include <bool.h>
    4041
    4142extern int devmap_get_phone(devmap_interface_t, unsigned int);
     
    4647
    4748extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int);
     49extern int devmap_namespace_get_handle(const char *, dev_handle_t *, unsigned int);
     50extern devmap_handle_type_t devmap_handle_probe(dev_handle_t);
     51
    4852extern int devmap_device_connect(dev_handle_t, unsigned int);
    4953
     
    5155extern void devmap_null_destroy(int);
    5256
    53 extern ipcarg_t devmap_device_get_count(void);
    54 extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *);
     57extern size_t devmap_count_namespaces(void);
     58extern size_t devmap_count_devices(dev_handle_t);
     59
     60extern size_t devmap_get_namespaces(dev_desc_t **);
     61extern size_t devmap_get_devices(dev_handle_t, dev_desc_t **);
    5562
    5663#endif
  • uspace/lib/libc/include/fibril_synch.h

    r3f085132 r3b3e776  
    3333 */
    3434
    35 #ifndef LIBC_FIBRIL_SYNC_H_
    36 #define LIBC_FIBRIL_SYNC_H_
     35#ifndef LIBC_FIBRIL_SYNCH_H_
     36#define LIBC_FIBRIL_SYNCH_H_
    3737
    3838#include <async.h>
  • uspace/lib/libc/include/futex.h

    r3f085132 r3b3e776  
    4646extern int futex_down(futex_t *futex);
    4747extern int futex_trydown(futex_t *futex);
    48 extern int futex_down_timeout(futex_t *futex, uint32_t usec, int flags);
    4948extern int futex_up(futex_t *futex);
    5049
  • uspace/lib/libc/include/io/console.h

    r3f085132 r3b3e776  
    6969
    7070extern int console_get_size(int phone, int *cols, int *rows);
     71extern int console_get_pos(int phone, int *col, int *row);
    7172extern void console_goto(int phone, int col, int row);
    7273
  • uspace/lib/libc/include/ipc/bd.h

    r3f085132 r3b3e776  
    4040typedef enum {
    4141        BD_GET_BLOCK_SIZE = IPC_FIRST_USER_METHOD,
     42        BD_GET_NUM_BLOCKS,
    4243        BD_READ_BLOCKS,
    4344        BD_WRITE_BLOCKS
  • uspace/lib/libc/include/ipc/console.h

    r3f085132 r3b3e776  
    4343        CONSOLE_GET_COLOR_CAP,
    4444        CONSOLE_GET_EVENT,
     45        CONSOLE_GET_POS,
    4546        CONSOLE_GOTO,
    4647        CONSOLE_CLEAR,
  • uspace/lib/libc/include/ipc/devmap.h

    r3f085132 r3b3e776  
    4343
    4444typedef enum {
     45        DEV_HANDLE_NONE,
     46        DEV_HANDLE_NAMESPACE,
     47        DEV_HANDLE_DEVICE
     48} devmap_handle_type_t;
     49
     50typedef enum {
    4551        DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
    4652        DEVMAP_DRIVER_UNREGISTER,
    4753        DEVMAP_DEVICE_REGISTER,
    4854        DEVMAP_DEVICE_UNREGISTER,
    49         DEVMAP_DEVICE_GET_NAME,
    5055        DEVMAP_DEVICE_GET_HANDLE,
    51         DEVMAP_DEVICE_NULL_CREATE,
    52         DEVMAP_DEVICE_NULL_DESTROY,
    53         DEVMAP_DEVICE_GET_COUNT,
    54         DEVMAP_DEVICE_GET_DEVICES
     56        DEVMAP_NAMESPACE_GET_HANDLE,
     57        DEVMAP_HANDLE_PROBE,
     58        DEVMAP_NULL_CREATE,
     59        DEVMAP_NULL_DESTROY,
     60        DEVMAP_GET_NAMESPACE_COUNT,
     61        DEVMAP_GET_DEVICE_COUNT,
     62        DEVMAP_GET_NAMESPACES,
     63        DEVMAP_GET_DEVICES
    5564} devmap_request_t;
    5665
  • uspace/lib/libc/include/ipc/services.h

    r3f085132 r3b3e776  
    4141        SERVICE_LOAD = 1,
    4242        SERVICE_PCI,
    43         SERVICE_KEYBOARD,
    4443        SERVICE_VIDEO,
    4544        SERVICE_CONSOLE,
     
    4746        SERVICE_DEVMAP,
    4847        SERVICE_FHC,
    49         SERVICE_OBIO
     48        SERVICE_OBIO,
     49        SERVICE_CLIPBOARD
    5050} services_t;
    5151
  • uspace/lib/libc/include/ipc/vfs.h

    r3f085132 r3b3e776  
    8686        VFS_OUT_MOUNTED,
    8787        VFS_OUT_UNMOUNT,
     88        VFS_OUT_UNMOUNTED,
    8889        VFS_OUT_SYNC,
    8990        VFS_OUT_STAT,
     
    100101 * No lookup flags used.
    101102 */
    102 #define L_NONE  0
     103#define L_NONE                  0
    103104
    104105/**
     
    107108 * with L_DIRECTORY.
    108109 */
    109 #define L_FILE  1
     110#define L_FILE                  1
    110111
    111112/**
    112  * Lookup wil succeed only if the object is a directory. If L_CREATE is
     113 * Lookup will succeed only if the object is a directory. If L_CREATE is
    113114 * specified, an empty directory will be created. This flag is mutually
    114115 * exclusive with L_FILE.
    115116 */
    116 #define L_DIRECTORY  2
     117#define L_DIRECTORY             2
     118
     119/**
     120 * Lookup will succeed only if the object is a root directory. The flag is
     121 * mutually exclusive with L_FILE and L_MP.
     122 */
     123#define L_ROOT                  4
     124
     125/**
     126 * Lookup will succeed only if the object is a mount point. The flag is mutually
     127 * exclusive with L_FILE and L_ROOT.
     128 */
     129#define L_MP                    8
     130
    117131
    118132/**
     
    120134 * object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used.
    121135 */
    122 #define L_EXCLUSIVE  4
     136#define L_EXCLUSIVE             16
    123137
    124138/**
    125139 * L_CREATE is used for creating both regular files and directories.
    126140 */
    127 #define L_CREATE  8
     141#define L_CREATE                32
    128142
    129143/**
    130144 * L_LINK is used for linking to an already existing nodes.
    131145 */
    132 #define L_LINK  16
     146#define L_LINK                  64
    133147
    134148/**
     
    137151 * VFS_UNLINK.
    138152 */
    139 #define L_UNLINK  32
     153#define L_UNLINK                128
    140154
    141155/**
    142  * L_OPEN is used to indicate that the lookup operation is a part of VFS_OPEN
     156 * L_OPEN is used to indicate that the lookup operation is a part of VFS_IN_OPEN
    143157 * call from the client. This means that the server might allocate some
    144158 * resources for the opened file. This flag cannot be passed directly by the
    145159 * client.
    146160 */
    147 #define L_OPEN  64
     161#define L_OPEN                  256
    148162
    149163#endif
  • uspace/lib/libc/include/stdlib.h

    r3f085132 r3b3e776  
    3838#include <unistd.h>
    3939#include <malloc.h>
     40#include <stacktrace.h>
    4041
    41 #define abort()       _exit(1)
     42#define abort() \
     43        do { \
     44                stacktrace_print(); \
     45                _exit(1); \
     46        } while (0)
     47
    4248#define exit(status)  _exit((status))
    4349
  • uspace/lib/libc/include/string.h

    r3f085132 r3b3e776  
    7373extern void str_append(char *dest, size_t size, const char *src);
    7474
    75 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
     75extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
     76extern char *wstr_to_astr(const wchar_t *src);
     77extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
    7678
    7779extern char *str_chr(const char *str, wchar_t ch);
     
    8284
    8385extern char *str_dup(const char *);
     86extern char *str_ndup(const char *, size_t max_size);
    8487
    8588/*
  • uspace/lib/libc/include/sys/stat.h

    r3f085132 r3b3e776  
    4242
    4343struct stat {
    44         fs_handle_t     fs_handle;
    45         dev_handle_t    dev_handle;
    46         fs_index_t      index;
    47         unsigned        lnkcnt;
    48         bool            is_file;
    49         off_t           size;
    50         union {
    51                 struct {
    52                         dev_handle_t    device;
    53                 } devfs_stat;
    54         };
     44        fs_handle_t fs_handle;
     45        dev_handle_t dev_handle;
     46        fs_index_t index;
     47        unsigned int lnkcnt;
     48        bool is_file;
     49        bool is_directory;
     50        off_t size;
     51        dev_handle_t device;
    5552};
    5653
  • uspace/lib/libc/include/sys/types.h

    r3f085132 r3b3e776  
    4040typedef long off_t;
    4141typedef int mode_t;
     42typedef uint64_t bn_t;  /**< Block number type. */
    4243
    4344typedef int32_t wchar_t;
  • uspace/lib/libc/include/udebug.h

    r3f085132 r3b3e776  
    4747int udebug_thread_read(int phoneid, void *buffer, size_t n,
    4848        size_t *copied, size_t *needed);
     49int udebug_name_read(int phoneid, void *buffer, size_t n,
     50        size_t *copied, size_t *needed);
     51int udebug_areas_read(int phoneid, void *buffer, size_t n,
     52        size_t *copied, size_t *needed);
    4953int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n);
    5054int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer);
     55int udebug_regs_read(int phoneid, thash_t tid, void *buffer);
    5156int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type,
    5257        sysarg_t *val0, sysarg_t *val1);
  • uspace/lib/libc/include/unistd.h

    r3f085132 r3b3e776  
    5151#endif
    5252
     53typedef uint32_t useconds_t;
     54
    5355extern int dup2(int oldfd, int newfd);
    5456
     
    6870
    6971extern void _exit(int status) __attribute__ ((noreturn));
    70 extern int usleep(unsigned long usec);
    71 extern unsigned int sleep(unsigned int seconds);
     72extern int usleep(useconds_t uses);
     73extern unsigned int sleep(unsigned int se);
    7274
    7375#endif
  • uspace/lib/libc/include/vfs/vfs.h

    r3f085132 r3b3e776  
    5555extern int mount(const char *, const char *, const char *, const char *,
    5656    unsigned int);
     57extern int unmount(const char *);
    5758
    5859extern void __stdio_init(int filc, fdi_node_t *filv[]);
  • uspace/lib/libfs/Makefile

    r3f085132 r3b3e776  
    2828#
    2929
    30 include Makefile.common
     30USPACE_PREFIX = ../..
     31LIBS = $(LIBC_PREFIX)/libc.a
    3132
    32 .PHONY: all clean
     33OUTPUT = libfs.a
    3334
    34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
    35         -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
    36         $(MAKE) -f Makefile.build
     35SOURCES = \
     36        libfs.c
    3737
    38 clean:
    39         rm -f $(DEPEND) $(DEPEND_PREV) $(LIBFS)
    40         find . -name '*.o' -follow -exec rm \{\} \;
     38include ../Makefile.common
  • uspace/lib/libfs/libfs.c

    r3f085132 r3b3e776  
    11/*
    2  * Copyright (c) 2009 Jakub Jermar 
     2 * Copyright (c) 2009 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libfs 
     29/** @addtogroup libfs
    3030 * @{
    31  */ 
     31 */
    3232/**
    3333 * @file
    34  * Glue code which is commonod to all FS implementations.
     34 * Glue code which is common to all FS implementations.
    3535 */
    3636
    37 #include "libfs.h" 
     37#include "libfs.h"
    3838#include "../../srv/vfs/vfs.h"
    3939#include <errno.h>
     
    6767 * code.
    6868 *
    69  * @param vfs_phone     Open phone for communication with VFS.
    70  * @param reg           File system registration structure. It will be
    71  *                      initialized by this function.
    72  * @param info          VFS info structure supplied by the file system
    73  *                      implementation.
    74  * @param conn          Connection fibril for handling all calls originating in
    75  *                      VFS.
    76  *
    77  * @return              EOK on success or a non-zero error code on errror.
     69 * @param vfs_phone Open phone for communication with VFS.
     70 * @param reg       File system registration structure. It will be
     71 *                  initialized by this function.
     72 * @param info      VFS info structure supplied by the file system
     73 *                  implementation.
     74 * @param conn      Connection fibril for handling all calls originating in
     75 *                  VFS.
     76 *
     77 * @return EOK on success or a non-zero error code on errror.
     78 *
    7879 */
    7980int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
     
    8788        ipc_call_t answer;
    8889        aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
    89 
     90       
    9091        /*
    9192         * Send our VFS info structure to VFS.
     
    9697                return rc;
    9798        }
    98 
     99       
    99100        /*
    100101         * Ask VFS for callback connection.
    101102         */
    102103        ipc_connect_to_me(vfs_phone, 0, 0, 0, &reg->vfs_phonehash);
    103 
     104       
    104105        /*
    105106         * Allocate piece of address space for PLB.
     
    110111                return ENOMEM;
    111112        }
    112 
     113       
    113114        /*
    114115         * Request sharing the Path Lookup Buffer with VFS.
     
    136137         */
    137138        async_set_client_connection(conn);
    138 
     139       
    139140        return IPC_GET_RETVAL(answer);
    140141}
     
    154155        int res;
    155156        ipcarg_t rc;
    156 
     157       
    157158        ipc_call_t call;
    158159        ipc_callid_t callid;
    159 
    160         /* accept the phone */
     160       
     161        /* Accept the phone */
    161162        callid = async_get_call(&call);
    162         int mountee_phone = (int)IPC_GET_ARG1(call);
     163        int mountee_phone = (int) IPC_GET_ARG1(call);
    163164        if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
    164             mountee_phone < 0) {
     165            (mountee_phone < 0)) {
    165166                ipc_answer_0(callid, EINVAL);
    166167                ipc_answer_0(rid, EINVAL);
    167168                return;
    168169        }
    169         ipc_answer_0(callid, EOK);      /* acknowledge the mountee_phone */
    170        
    171         res = async_data_write_receive(&callid, NULL);
    172         if (!res) {
    173                 ipc_hangup(mountee_phone);
    174                 ipc_answer_0(callid, EINVAL);
    175                 ipc_answer_0(rid, EINVAL);
    176                 return;
    177         }
    178 
     170       
     171        /* Acknowledge the mountee_phone */
     172        ipc_answer_0(callid, EOK);
     173       
    179174        fs_node_t *fn;
    180175        res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
    181         if (res != EOK || !fn) {
     176        if ((res != EOK) || (!fn)) {
    182177                ipc_hangup(mountee_phone);
    183                 ipc_answer_0(callid, combine_rc(res, ENOENT));
     178                async_data_void(combine_rc(res, ENOENT));
    184179                ipc_answer_0(rid, combine_rc(res, ENOENT));
    185180                return;
    186181        }
    187 
     182       
    188183        if (fn->mp_data.mp_active) {
    189184                ipc_hangup(mountee_phone);
    190185                (void) ops->node_put(fn);
    191                 ipc_answer_0(callid, EBUSY);
     186                async_data_void(EBUSY);
    192187                ipc_answer_0(rid, EBUSY);
    193188                return;
    194189        }
    195 
     190       
    196191        rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
    197192        if (rc != EOK) {
    198193                ipc_hangup(mountee_phone);
    199194                (void) ops->node_put(fn);
    200                 ipc_answer_0(callid, rc);
     195                async_data_void(rc);
    201196                ipc_answer_0(rid, rc);
    202197                return;
     
    204199       
    205200        ipc_call_t answer;
    206         aid_t msg = async_send_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle,
     201        rc = async_data_forward_1_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle,
    207202            &answer);
    208         ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    209         async_wait_for(msg, &rc);
    210203       
    211204        if (rc == EOK) {
     
    215208                fn->mp_data.phone = mountee_phone;
    216209        }
     210       
    217211        /*
    218212         * Do not release the FS node so that it stays in memory.
     
    220214        ipc_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    221215            IPC_GET_ARG3(answer));
     216}
     217
     218void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
     219{
     220        dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     221        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
     222        fs_node_t *fn;
     223        int res;
     224
     225        res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
     226        if ((res != EOK) || (!fn)) {
     227                ipc_answer_0(rid, combine_rc(res, ENOENT));
     228                return;
     229        }
     230
     231        /*
     232         * We are clearly expecting to find the mount point active.
     233         */
     234        if (!fn->mp_data.mp_active) {
     235                (void) ops->node_put(fn);
     236                ipc_answer_0(rid, EINVAL);
     237                return;
     238        }
     239
     240        /*
     241         * Tell the mounted file system to unmount.
     242         */
     243        res = async_req_1_0(fn->mp_data.phone, VFS_OUT_UNMOUNTED,
     244            fn->mp_data.dev_handle);
     245
     246        /*
     247         * If everything went well, perform the clean-up on our side.
     248         */
     249        if (res == EOK) {
     250                ipc_hangup(fn->mp_data.phone);
     251                fn->mp_data.mp_active = false;
     252                fn->mp_data.fs_handle = 0;
     253                fn->mp_data.dev_handle = 0;
     254                fn->mp_data.phone = 0;
     255                /* Drop the reference created in libfs_mount(). */
     256                (void) ops->node_put(fn);
     257        }
     258
     259        (void) ops->node_put(fn);
     260        ipc_answer_0(rid, res);
    222261}
    223262
     
    238277    ipc_call_t *request)
    239278{
    240         unsigned first = IPC_GET_ARG1(*request);
    241         unsigned last = IPC_GET_ARG2(*request);
    242         unsigned next = first;
     279        unsigned int first = IPC_GET_ARG1(*request);
     280        unsigned int last = IPC_GET_ARG2(*request);
     281        unsigned int next = first;
    243282        dev_handle_t dev_handle = IPC_GET_ARG3(*request);
    244283        int lflag = IPC_GET_ARG4(*request);
    245         fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
     284        fs_index_t index = IPC_GET_ARG5(*request);
    246285        char component[NAME_MAX + 1];
    247286        int len;
    248287        int rc;
    249 
     288       
    250289        if (last < next)
    251290                last += PLB_SIZE;
    252 
     291       
    253292        fs_node_t *par = NULL;
    254293        fs_node_t *cur = NULL;
    255294        fs_node_t *tmp = NULL;
    256 
     295       
    257296        rc = ops->root_get(&cur, dev_handle);
    258297        on_error(rc, goto out_with_answer);
    259 
     298       
    260299        if (cur->mp_data.mp_active) {
    261300                ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
     
    265304                return;
    266305        }
    267 
     306       
     307        /* Eat slash */
    268308        if (ops->plb_get_char(next) == '/')
    269                 next++;         /* eat slash */
     309                next++;
    270310       
    271311        while (next <= last) {
    272312                bool has_children;
    273 
     313               
    274314                rc = ops->has_children(&has_children, cur);
    275315                on_error(rc, goto out_with_answer);
    276316                if (!has_children)
    277317                        break;
    278 
    279                 /* collect the component */
     318               
     319                /* Collect the component */
    280320                len = 0;
    281                 while ((next <= last) &&  (ops->plb_get_char(next) != '/')) {
     321                while ((next <= last) && (ops->plb_get_char(next) != '/')) {
    282322                        if (len + 1 == NAME_MAX) {
    283                                 /* component length overflow */
     323                                /* Component length overflow */
    284324                                ipc_answer_0(rid, ENAMETOOLONG);
    285325                                goto out;
    286326                        }
    287327                        component[len++] = ops->plb_get_char(next);
    288                         next++; /* process next character */
     328                        /* Process next character */
     329                        next++;
    289330                }
    290 
     331               
    291332                assert(len);
    292333                component[len] = '\0';
    293                 next++;         /* eat slash */
    294 
    295                 /* match the component */
     334                /* Eat slash */
     335                next++;
     336               
     337                /* Match the component */
    296338                rc = ops->match(&tmp, cur, component);
    297339                on_error(rc, goto out_with_answer);
    298 
    299                 if (tmp && tmp->mp_data.mp_active) {
     340               
     341                /*
     342                 * If the matching component is a mount point, there are two
     343                 * legitimate semantics of the lookup operation. The first is
     344                 * the commonly used one in which the lookup crosses each mount
     345                 * point into the mounted file system. The second semantics is
     346                 * used mostly during unmount() and differs from the first one
     347                 * only in that the last mount point in the looked up path,
     348                 * which is also its last component, is not crossed.
     349                 */
     350
     351                if ((tmp) && (tmp->mp_data.mp_active) &&
     352                    (!(lflag & L_MP) || (next <= last))) {
    300353                        if (next > last)
    301354                                next = last = first;
    302355                        else
    303356                                next--;
    304                                
     357                       
    305358                        ipc_forward_slow(rid, tmp->mp_data.phone,
    306359                            VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
     
    312365                        return;
    313366                }
    314 
    315                 /* handle miss: match amongst siblings */
     367               
     368                /* Handle miss: match amongst siblings */
    316369                if (!tmp) {
    317370                        if (next <= last) {
    318                                 /* there are unprocessed components */
     371                                /* There are unprocessed components */
    319372                                ipc_answer_0(rid, ENOENT);
    320373                                goto out;
    321374                        }
    322                         /* miss in the last component */
    323                         if (lflag & (L_CREATE | L_LINK)) {
    324                                 /* request to create a new link */
     375                       
     376                        /* Miss in the last component */
     377                        if (lflag & (L_CREATE | L_LINK)) {
     378                                /* Request to create a new link */
    325379                                if (!ops->is_directory(cur)) {
    326380                                        ipc_answer_0(rid, ENOTDIR);
    327381                                        goto out;
    328382                                }
     383                               
    329384                                fs_node_t *fn;
    330385                                if (lflag & L_CREATE)
     
    335390                                            index);
    336391                                on_error(rc, goto out_with_answer);
     392                               
    337393                                if (fn) {
    338394                                        rc = ops->link(cur, fn, component);
     
    349405                                                (void) ops->node_put(fn);
    350406                                        }
    351                                 } else {
     407                                } else
    352408                                        ipc_answer_0(rid, ENOSPC);
    353                                 }
     409                               
    354410                                goto out;
    355                         }
     411                        }
     412                       
    356413                        ipc_answer_0(rid, ENOENT);
    357414                        goto out;
    358415                }
    359 
     416               
    360417                if (par) {
    361418                        rc = ops->node_put(par);
    362419                        on_error(rc, goto out_with_answer);
    363420                }
    364 
    365                 /* descend one level */
     421               
     422                /* Descend one level */
    366423                par = cur;
    367424                cur = tmp;
    368425                tmp = NULL;
    369426        }
    370 
    371         /* handle miss: excessive components */
     427       
     428        /* Handle miss: excessive components */
    372429        if (next <= last) {
    373430                bool has_children;
    374 
    375431                rc = ops->has_children(&has_children, cur);
    376432                on_error(rc, goto out_with_answer);
     433               
    377434                if (has_children)
    378435                        goto skip_miss;
    379 
     436               
    380437                if (lflag & (L_CREATE | L_LINK)) {
    381438                        if (!ops->is_directory(cur)) {
     
    383440                                goto out;
    384441                        }
    385 
    386                         /* collect next component */
     442                       
     443                        /* Collect next component */
    387444                        len = 0;
    388445                        while (next <= last) {
    389446                                if (ops->plb_get_char(next) == '/') {
    390                                         /* more than one component */
     447                                        /* More than one component */
    391448                                        ipc_answer_0(rid, ENOENT);
    392449                                        goto out;
    393450                                }
     451                               
    394452                                if (len + 1 == NAME_MAX) {
    395                                         /* component length overflow */
     453                                        /* Component length overflow */
    396454                                        ipc_answer_0(rid, ENAMETOOLONG);
    397455                                        goto out;
    398456                                }
     457                               
    399458                                component[len++] = ops->plb_get_char(next);
    400                                 next++; /* process next character */
     459                                /* Process next character */
     460                                next++;
    401461                        }
     462                       
    402463                        assert(len);
    403464                        component[len] = '\0';
    404                                
     465                       
    405466                        fs_node_t *fn;
    406467                        if (lflag & L_CREATE)
     
    409470                                rc = ops->node_get(&fn, dev_handle, index);
    410471                        on_error(rc, goto out_with_answer);
     472                       
    411473                        if (fn) {
    412474                                rc = ops->link(cur, fn, component);
     
    423485                                        (void) ops->node_put(fn);
    424486                                }
    425                         } else {
     487                        } else
    426488                                ipc_answer_0(rid, ENOSPC);
    427                         }
     489                       
    428490                        goto out;
    429491                }
     492               
    430493                ipc_answer_0(rid, ENOENT);
    431494                goto out;
    432495        }
     496       
    433497skip_miss:
    434 
    435         /* handle hit */
     498       
     499        /* Handle hit */
    436500        if (lflag & L_UNLINK) {
    437                 unsigned old_lnkcnt = ops->lnkcnt_get(cur);
     501                unsigned int old_lnkcnt = ops->lnkcnt_get(cur);
    438502                rc = ops->unlink(par, cur, component);
    439                 ipc_answer_5(rid, (ipcarg_t)rc, fs_handle, dev_handle,
     503                ipc_answer_5(rid, (ipcarg_t) rc, fs_handle, dev_handle,
    440504                    ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
    441505                goto out;
    442506        }
     507       
    443508        if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
    444509            (lflag & L_LINK)) {
     
    446511                goto out;
    447512        }
     513       
    448514        if ((lflag & L_FILE) && (ops->is_directory(cur))) {
    449515                ipc_answer_0(rid, EISDIR);
    450516                goto out;
    451517        }
     518       
    452519        if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
    453520                ipc_answer_0(rid, ENOTDIR);
     
    455522        }
    456523
     524        if ((lflag & L_ROOT) && par) {
     525                ipc_answer_0(rid, EINVAL);
     526                goto out;
     527        }
     528       
    457529out_with_answer:
     530       
    458531        if (rc == EOK) {
    459                 ipc_answer_5(rid, EOK, fs_handle, dev_handle,
     532                if (lflag & L_OPEN)
     533                        rc = ops->node_open(cur);
     534               
     535                ipc_answer_5(rid, rc, fs_handle, dev_handle,
    460536                    ops->index_get(cur), ops->size_get(cur),
    461537                    ops->lnkcnt_get(cur));
    462         } else {
     538        } else
    463539                ipc_answer_0(rid, rc);
    464         }
    465 
     540       
    466541out:
     542       
    467543        if (par)
    468544                (void) ops->node_put(par);
     545       
    469546        if (cur)
    470547                (void) ops->node_put(cur);
     548       
    471549        if (tmp)
    472550                (void) ops->node_put(tmp);
     
    478556        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    479557        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     558       
    480559        fs_node_t *fn;
    481         int rc;
    482 
    483         rc = ops->node_get(&fn, dev_handle, index);
     560        int rc = ops->node_get(&fn, dev_handle, index);
    484561        on_error(rc, answer_and_return(rid, rc));
    485 
     562       
    486563        ipc_callid_t callid;
    487564        size_t size;
    488         if (!async_data_read_receive(&callid, &size) ||
    489             size != sizeof(struct stat)) {
     565        if ((!async_data_read_receive(&callid, &size)) ||
     566            (size != sizeof(struct stat))) {
     567                ops->node_put(fn);
    490568                ipc_answer_0(callid, EINVAL);
    491569                ipc_answer_0(rid, EINVAL);
    492570                return;
    493571        }
    494 
     572       
    495573        struct stat stat;
    496574        memset(&stat, 0, sizeof(struct stat));
     
    499577        stat.dev_handle = dev_handle;
    500578        stat.index = index;
    501         stat.lnkcnt = ops->lnkcnt_get(fn); 
     579        stat.lnkcnt = ops->lnkcnt_get(fn);
    502580        stat.is_file = ops->is_file(fn);
     581        stat.is_directory = ops->is_directory(fn);
    503582        stat.size = ops->size_get(fn);
    504 
     583        stat.device = ops->device_get(fn);
     584       
     585        ops->node_put(fn);
     586       
    505587        async_data_read_finalize(callid, &stat, sizeof(struct stat));
    506588        ipc_answer_0(rid, EOK);
     
    509591/** Open VFS triplet.
    510592 *
    511  * @param ops       libfs operations structure with function pointers to
    512  *                  file system implementation
    513  * @param rid       Request ID of the VFS_OUT_OPEN_NODE request.
    514  * @param request   VFS_OUT_OPEN_NODE request data itself.
     593 * @param ops     libfs operations structure with function pointers to
     594 *                file system implementation
     595 * @param rid     Request ID of the VFS_OUT_OPEN_NODE request.
     596 * @param request VFS_OUT_OPEN_NODE request data itself.
    515597 *
    516598 */
     
    531613        }
    532614       
    533         ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn),
     615        rc = ops->node_open(fn);
     616        ipc_answer_3(rid, rc, ops->size_get(fn), ops->lnkcnt_get(fn),
    534617            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    535618       
  • uspace/lib/libfs/libfs.h

    r3f085132 r3b3e776  
    6464        int (* match)(fs_node_t **, fs_node_t *, const char *);
    6565        int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t);
     66        int (* node_open)(fs_node_t *);
    6667        int (* node_put)(fs_node_t *);
    6768        int (* create)(fs_node_t **, dev_handle_t, int);
     
    7677        fs_index_t (* index_get)(fs_node_t *);
    7778        size_t (* size_get)(fs_node_t *);
    78         unsigned (* lnkcnt_get)(fs_node_t *);
     79        unsigned int (* lnkcnt_get)(fs_node_t *);
    7980        char (* plb_get_char)(unsigned pos);
    8081        bool (* is_directory)(fs_node_t *);
    8182        bool (* is_file)(fs_node_t *);
     83        dev_handle_t (* device_get)(fs_node_t *);
    8284} libfs_ops_t;
    8385
     
    9395
    9496extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     97extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    9598extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    9699extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
  • uspace/lib/libpci/Makefile

    r3f085132 r3b3e776  
    11#
    22# Copyright (c) 2005 Martin Decky
     3# Copyright (c) 2007 Jakub Jermar
    34# All rights reserved.
    45#
     
    2728#
    2829
    29 
    30 ## Common names
    31 #
    32 
    33 LIBC_PREFIX = ../../lib/libc
    34 SOFTINT_PREFIX = ../../lib/softint
     30USPACE_PREFIX = ../..
    3531LIBS = $(LIBC_PREFIX)/libc.a
    3632
    37 DEPEND = Makefile.depend
    38 DEPEND_PREV = $(DEPEND).prev
    39 OUTPUT = edit
     33OUTPUT = libpci.a
     34
     35SOURCES = \
     36        access.c \
     37        generic.c \
     38        names.c \
     39        i386-ports.c
     40
     41include ../Makefile.common
  • uspace/lib/softfloat/Makefile

    r3f085132 r3b3e776  
    2828#
    2929
    30 include Makefile.common
     30USPACE_PREFIX = ../..
     31LIBS = $(LIBC_PREFIX)/libc.a
     32EXTRA_CFLAGS += -Iinclude -Iarch/$(UARCH)/include/
    3133
    32 .PHONY: all clean
     34OUTPUT = libsoftfloat.a
    3335
    34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
    35         -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
    36         $(MAKE) -f Makefile.build
     36SOURCES = \
     37        generic/add.c \
     38        generic/common.c \
     39        generic/comparison.c \
     40        generic/conversion.c \
     41        generic/div.c \
     42        generic/mul.c \
     43        generic/other.c \
     44        generic/softfloat.c \
     45        generic/sub.c
    3746
    38 clean:
    39         rm -f $(DEPEND) $(DEPEND_PREV) $(LIBSOFTFLOAT)
    40         find . -name '*.o' -follow -exec rm \{\} \;
     47include ../Makefile.common
  • uspace/lib/softint/Makefile

    r3f085132 r3b3e776  
    2828#
    2929
    30 include Makefile.common
     30USPACE_PREFIX = ../..
     31LIBS = $(LIBC_PREFIX)/libc.a
     32EXTRA_CFLAGS = -Iinclude
    3133
    32 .PHONY: all clean
     34OUTPUT = libsoftint.a
    3335
    34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a
    35         -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
    36         $(MAKE) -f Makefile.build
     36SOURCES = \
     37        generic/division.c\
     38        generic/multiplication.c
    3739
    38 clean:
    39         rm -f $(DEPEND) $(DEPEND_PREV) $(LIBSOFTINT)
    40         find . -name '*.o' -follow -exec rm \{\} \;
     40include ../Makefile.common
Note: See TracChangeset for help on using the changeset viewer.