Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4580 → Rev 4581

/branches/network/uspace/lib/libfs/libfs.c
1,5 → 1,5
/*
* Copyright (c) 2008 Jakub Jermar
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
42,6 → 42,7
#include <as.h>
#include <assert.h>
#include <dirent.h>
#include <mem.h>
 
/** Register file system server.
*
122,23 → 123,106
return IPC_GET_RETVAL(answer);
}
 
void fs_node_initialize(fs_node_t *fn)
{
memset(fn, 0, sizeof(fs_node_t));
}
 
void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
ipc_call_t *request)
{
dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request);
int res;
ipcarg_t rc;
 
ipc_call_t call;
ipc_callid_t callid;
 
/* accept the phone */
callid = async_get_call(&call);
int mountee_phone = (int)IPC_GET_ARG1(call);
if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
mountee_phone < 0) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
ipc_answer_0(callid, EOK); /* acknowledge the mountee_phone */
res = ipc_data_write_receive(&callid, NULL);
if (!res) {
ipc_hangup(mountee_phone);
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
fs_node_t *fn = ops->node_get(mp_dev_handle, mp_fs_index);
if (!fn) {
ipc_hangup(mountee_phone);
ipc_answer_0(callid, ENOENT);
ipc_answer_0(rid, ENOENT);
return;
}
 
if (fn->mp_data.mp_active) {
ipc_hangup(mountee_phone);
ops->node_put(fn);
ipc_answer_0(callid, EBUSY);
ipc_answer_0(rid, EBUSY);
return;
}
 
rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
if (rc != 0) {
ipc_hangup(mountee_phone);
ops->node_put(fn);
ipc_answer_0(callid, rc);
ipc_answer_0(rid, rc);
return;
}
ipc_call_t answer;
aid_t msg = async_send_1(mountee_phone, VFS_MOUNTED, mr_dev_handle,
&answer);
ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
async_wait_for(msg, &rc);
if (rc == EOK) {
fn->mp_data.mp_active = true;
fn->mp_data.fs_handle = mr_fs_handle;
fn->mp_data.dev_handle = mr_dev_handle;
fn->mp_data.phone = mountee_phone;
}
/*
* Do not release the FS node so that it stays in memory.
*/
ipc_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
IPC_GET_ARG3(answer));
}
 
/** Lookup VFS triplet by name in the file system name space.
*
* The path passed in the PLB must be in the canonical file system path format
* as returned by the canonify() function.
*
* @param ops libfs operations structure with function pointers to
* file system implementation
* @param fs_handle File system handle of the file system where to perform
* the lookup.
* @param rid Request ID of the VFS_LOOKUP request.
* @param request VFS_LOOKUP request data itself.
* @param ops libfs operations structure with function pointers to
* file system implementation
* @param fs_handle File system handle of the file system where to perform
* the lookup.
* @param rid Request ID of the VFS_LOOKUP request.
* @param request VFS_LOOKUP request data itself.
*
*/
void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
ipc_call_t *request)
{
unsigned next = IPC_GET_ARG1(*request);
unsigned first = IPC_GET_ARG1(*request);
unsigned last = IPC_GET_ARG2(*request);
unsigned next = first;
dev_handle_t dev_handle = IPC_GET_ARG3(*request);
int lflag = IPC_GET_ARG4(*request);
fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
148,10 → 232,18
if (last < next)
last += PLB_SIZE;
 
void *par = NULL;
void *cur = ops->root_get(dev_handle);
void *tmp = NULL;
fs_node_t *par = NULL;
fs_node_t *cur = ops->root_get(dev_handle);
fs_node_t *tmp = NULL;
 
if (cur->mp_data.mp_active) {
ipc_forward_slow(rid, cur->mp_data.phone, VFS_LOOKUP,
next, last, cur->mp_data.dev_handle, lflag, index,
IPC_FF_ROUTE_FROM_ME);
ops->node_put(cur);
return;
}
 
if (ops->plb_get_char(next) == '/')
next++; /* eat slash */
174,6 → 266,21
 
/* match the component */
tmp = ops->match(cur, component);
if (tmp && tmp->mp_data.mp_active) {
if (next > last)
next = last = first;
else
next--;
ipc_forward_slow(rid, tmp->mp_data.phone, VFS_LOOKUP,
next, last, tmp->mp_data.dev_handle, lflag, index,
IPC_FF_ROUTE_FROM_ME);
ops->node_put(cur);
ops->node_put(tmp);
if (par)
ops->node_put(par);
return;
}
 
/* handle miss: match amongst siblings */
if (!tmp) {
189,39 → 296,33
ipc_answer_0(rid, ENOTDIR);
goto out;
}
void *nodep;
fs_node_t *fn;
if (lflag & L_CREATE)
nodep = ops->create(dev_handle, lflag);
fn = ops->create(dev_handle, lflag);
else
nodep = ops->node_get(dev_handle,
fn = ops->node_get(dev_handle,
index);
if (nodep) {
if (fn) {
int rc;
 
rc = ops->link(cur, nodep, component);
rc = ops->link(cur, fn, component);
if (rc != EOK) {
if (lflag & L_CREATE) {
(void)ops->destroy(
nodep);
(void)ops->destroy(fn);
}
ipc_answer_0(rid, rc);
} else {
ipc_answer_5(rid, EOK,
fs_handle, dev_handle,
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
ops->node_put(nodep);
ops->index_get(fn),
ops->size_get(fn),
ops->lnkcnt_get(fn));
ops->node_put(fn);
}
} else {
ipc_answer_0(rid, ENOSPC);
}
goto out;
} else if (lflag & L_PARENT) {
/* return parent */
ipc_answer_5(rid, EOK, fs_handle, dev_handle,
ops->index_get(cur), ops->size_get(cur),
ops->lnkcnt_get(cur));
}
ipc_answer_0(rid, ENOENT);
goto out;
263,26 → 364,26
assert(len);
component[len] = '\0';
void *nodep;
fs_node_t *fn;
if (lflag & L_CREATE)
nodep = ops->create(dev_handle, lflag);
fn = ops->create(dev_handle, lflag);
else
nodep = ops->node_get(dev_handle, index);
if (nodep) {
fn = ops->node_get(dev_handle, index);
if (fn) {
int rc;
 
rc = ops->link(cur, nodep, component);
rc = ops->link(cur, fn, component);
if (rc != EOK) {
if (lflag & L_CREATE)
(void)ops->destroy(nodep);
(void)ops->destroy(fn);
ipc_answer_0(rid, rc);
} else {
ipc_answer_5(rid, EOK,
fs_handle, dev_handle,
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
ops->node_put(nodep);
ops->index_get(fn),
ops->size_get(fn),
ops->lnkcnt_get(fn));
ops->node_put(fn);
}
} else {
ipc_answer_0(rid, ENOSPC);
294,18 → 395,9
}
 
/* handle hit */
if (lflag & L_PARENT) {
ops->node_put(cur);
cur = par;
par = NULL;
if (!cur) {
ipc_answer_0(rid, ENOENT);
goto out;
}
}
if (lflag & L_UNLINK) {
unsigned old_lnkcnt = ops->lnkcnt_get(cur);
int res = ops->unlink(par, cur);
int res = ops->unlink(par, cur, component);
ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
goto out;
336,5 → 428,32
ops->node_put(tmp);
}
 
/** Open VFS triplet.
*
* @param ops libfs operations structure with function pointers to
* file system implementation
* @param rid Request ID of the VFS_OPEN_NODE request.
* @param request VFS_OPEN_NODE request data itself.
*
*/
void libfs_open_node(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
ipc_call_t *request)
{
dev_handle_t dev_handle = IPC_GET_ARG1(*request);
fs_index_t index = IPC_GET_ARG2(*request);
fs_node_t *node = ops->node_get(dev_handle, index);
if (node == NULL) {
ipc_answer_0(rid, ENOENT);
return;
}
ipc_answer_5(rid, EOK, fs_handle, dev_handle, index,
ops->size_get(node), ops->lnkcnt_get(node));
ops->node_put(node);
}
 
/** @}
*/
/branches/network/uspace/lib/libfs/libfs.h
1,5 → 1,5
/*
* Copyright (c) 2007 Jakub Jermar
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,51 → 26,68
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libfs
/** @addtogroup libfs
* @{
*/
*/
/**
* @file
*/
 
#ifndef LIBFS_LIBFS_H_
#define LIBFS_LIBFS_H_
#define LIBFS_LIBFS_H_
 
#include "../../srv/vfs/vfs.h"
#include <ipc/vfs.h>
#include <stdint.h>
#include <ipc/ipc.h>
#include <async.h>
#include <devmap.h>
 
typedef struct {
void * (* match)(void *, const char *);
void * (* node_get)(dev_handle_t, fs_index_t);
void (* node_put)(void *);
void * (* create)(dev_handle_t, int);
int (* destroy)(void *);
int (* link)(void *, void *, const char *);
int (* unlink)(void *, void *);
fs_index_t (* index_get)(void *);
size_t (* size_get)(void *);
unsigned (* lnkcnt_get)(void *);
bool (* has_children)(void *);
void *(* root_get)(dev_handle_t);
char (* plb_get_char)(unsigned pos);
bool (* is_directory)(void *);
bool (* is_file)(void *);
bool mp_active;
int phone;
fs_handle_t fs_handle;
dev_handle_t dev_handle;
} mp_data_t;
 
typedef struct {
mp_data_t mp_data; /**< Mount point info. */
void *data; /**< Data of the file system implementation. */
} fs_node_t;
 
typedef struct {
fs_node_t * (* match)(fs_node_t *, const char *);
fs_node_t * (* node_get)(dev_handle_t, fs_index_t);
void (* node_put)(fs_node_t *);
fs_node_t * (* create)(dev_handle_t, int);
int (* destroy)(fs_node_t *);
int (* link)(fs_node_t *, fs_node_t *, const char *);
int (* unlink)(fs_node_t *, fs_node_t *, const char *);
fs_index_t (* index_get)(fs_node_t *);
size_t (* size_get)(fs_node_t *);
unsigned (* lnkcnt_get)(fs_node_t *);
bool (* has_children)(fs_node_t *);
fs_node_t *(* root_get)(dev_handle_t);
char (* plb_get_char)(unsigned pos);
bool (* is_directory)(fs_node_t *);
bool (* is_file)(fs_node_t *);
} libfs_ops_t;
 
typedef struct {
int fs_handle; /**< File system handle. */
ipcarg_t vfs_phonehash; /**< Initial VFS phonehash. */
uint8_t *plb_ro; /**< Read-only PLB view. */
int fs_handle; /**< File system handle. */
ipcarg_t vfs_phonehash; /**< Initial VFS phonehash. */
uint8_t *plb_ro; /**< Read-only PLB view. */
} fs_reg_t;
 
extern int fs_register(int, fs_reg_t *, vfs_info_t *, async_client_conn_t);
 
extern void fs_node_initialize(fs_node_t *);
 
extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
ipc_call_t *);
 
#endif
 
/** @}
*/
 
/branches/network/uspace/lib/libblock/libblock.c
37,8 → 37,8
 
#include "libblock.h"
#include "../../srv/vfs/vfs.h"
#include "../../srv/rd/rd.h"
#include <ipc/devmap.h>
#include <ipc/bd.h>
#include <ipc/services.h>
#include <errno.h>
#include <sys/mman.h>
46,12 → 46,13
#include <ipc/ipc.h>
#include <as.h>
#include <assert.h>
#include <futex.h>
#include <libadt/list.h>
#include <libadt/hash_table.h>
#include <fibril_sync.h>
#include <adt/list.h>
#include <adt/hash_table.h>
#include <mem.h>
 
/** Lock protecting the device connection list */
static futex_t dcl_lock = FUTEX_INITIALIZER;
static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
/** Device connection list head. */
static LIST_INITIALIZE(dcl_head);
 
59,16 → 60,17
#define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2)
 
typedef struct {
futex_t lock;
fibril_mutex_t lock;
size_t block_size; /**< Block size. */
unsigned block_count; /**< Total number of blocks. */
hash_table_t block_hash;
link_t free_head;
enum cache_mode mode;
} cache_t;
 
typedef struct {
link_t link;
int dev_handle;
dev_handle_t dev_handle;
int dev_phone;
void *com_area;
size_t com_size;
78,19 → 80,22
cache_t *cache;
} devcon_t;
 
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size,
const void *src);
 
static devcon_t *devcon_search(dev_handle_t dev_handle)
{
link_t *cur;
 
futex_down(&dcl_lock);
fibril_mutex_lock(&dcl_lock);
for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
devcon_t *devcon = list_get_instance(cur, devcon_t, link);
if (devcon->dev_handle == dev_handle) {
futex_up(&dcl_lock);
fibril_mutex_unlock(&dcl_lock);
return devcon;
}
}
futex_up(&dcl_lock);
fibril_mutex_unlock(&dcl_lock);
return NULL;
}
 
114,25 → 119,25
devcon->bb_size = 0;
devcon->cache = NULL;
 
futex_down(&dcl_lock);
fibril_mutex_lock(&dcl_lock);
for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
devcon_t *d = list_get_instance(cur, devcon_t, link);
if (d->dev_handle == dev_handle) {
futex_up(&dcl_lock);
fibril_mutex_unlock(&dcl_lock);
free(devcon);
return EEXIST;
}
}
list_append(&devcon->link, &dcl_head);
futex_up(&dcl_lock);
fibril_mutex_unlock(&dcl_lock);
return EOK;
}
 
static void devcon_remove(devcon_t *devcon)
{
futex_down(&dcl_lock);
fibril_mutex_lock(&dcl_lock);
list_remove(&devcon->link);
futex_up(&dcl_lock);
fibril_mutex_unlock(&dcl_lock);
}
 
int block_init(dev_handle_t dev_handle, size_t com_size)
146,9 → 151,8
if (!com_area) {
return ENOMEM;
}
dev_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_CONNECT_TO_DEVICE, dev_handle);
 
dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING);
if (dev_phone < 0) {
munmap(com_area, com_size);
return dev_phone;
250,7 → 254,8
.remove_callback = cache_remove_callback
};
 
int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks)
int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks,
enum cache_mode mode)
{
devcon_t *devcon = devcon_search(dev_handle);
cache_t *cache;
262,10 → 267,11
if (!cache)
return ENOMEM;
futex_initialize(&cache->lock, 1);
fibril_mutex_initialize(&cache->lock);
list_initialize(&cache->free_head);
cache->block_size = size;
cache->block_count = blocks;
cache->mode = mode;
 
if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
&cache_ops)) {
284,10 → 290,10
 
static void block_initialize(block_t *b)
{
futex_initialize(&b->lock, 1);
fibril_mutex_initialize(&b->lock);
b->refcnt = 1;
b->dirty = false;
rwlock_initialize(&b->contents_lock);
fibril_rwlock_initialize(&b->contents_lock);
link_initialize(&b->free_link);
link_initialize(&b->hash_link);
}
316,7 → 322,7
assert(devcon->cache);
cache = devcon->cache;
futex_down(&cache->lock);
fibril_mutex_lock(&cache->lock);
l = hash_table_find(&cache->block_hash, &key);
if (l) {
/*
323,11 → 329,11
* We found the block in the cache.
*/
b = hash_table_get_instance(l, block_t, hash_link);
futex_down(&b->lock);
fibril_mutex_lock(&b->lock);
if (b->refcnt++ == 0)
list_remove(&b->free_link);
futex_up(&b->lock);
futex_up(&cache->lock);
fibril_mutex_unlock(&b->lock);
fibril_mutex_unlock(&cache->lock);
} else {
/*
* The block was not found in the cache.
378,8 → 384,8
* kill concurent operations on the cache while doing I/O on the
* block.
*/
futex_down(&b->lock);
futex_up(&cache->lock);
fibril_mutex_lock(&b->lock);
fibril_mutex_unlock(&cache->lock);
 
if (sync) {
/*
398,7 → 404,7
assert(rc == EOK);
}
 
futex_up(&b->lock);
fibril_mutex_unlock(&b->lock);
}
return b;
}
413,13 → 419,14
{
devcon_t *devcon = devcon_search(block->dev_handle);
cache_t *cache;
int rc;
 
assert(devcon);
assert(devcon->cache);
 
cache = devcon->cache;
futex_down(&cache->lock);
futex_down(&block->lock);
fibril_mutex_lock(&cache->lock);
fibril_mutex_lock(&block->lock);
if (!--block->refcnt) {
/*
* Last reference to the block was dropped, put the block on the
426,9 → 433,16
* free list.
*/
list_append(&block->free_link, &cache->free_head);
if (cache->mode != CACHE_MODE_WB && block->dirty) {
rc = write_block(devcon, block->boff, block->size,
block->data);
assert(rc == EOK);
 
block->dirty = false;
}
}
futex_up(&block->lock);
futex_up(&cache->lock);
fibril_mutex_unlock(&block->lock);
fibril_mutex_unlock(&cache->lock);
}
 
/** Read data from a block device.
446,8 → 460,8
* @return EOK on success or a negative return code on failure.
*/
int
block_read(int dev_handle, off_t *bufpos, size_t *buflen, off_t *pos, void *dst,
size_t size, size_t block_size)
block_read(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen, off_t *pos,
void *dst, size_t size, size_t block_size)
{
off_t offset = 0;
size_t left = size;
474,13 → 488,13
left -= rd;
}
if (*bufpos == *buflen) {
if (*bufpos == (off_t) *buflen) {
/* Refill the communication buffer with a new block. */
ipcarg_t retval;
int rc = async_req_2_1(devcon->dev_phone, RD_READ_BLOCK,
int rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK,
*pos / block_size, block_size, &retval);
if ((rc != EOK) || (retval != EOK))
return (rc != EOK ? rc : retval);
return (rc != EOK ? rc : (int) retval);
*bufpos = 0;
*buflen = block_size;
490,5 → 504,31
return EOK;
}
 
/** Write block to block device.
*
* @param devcon Device connection.
* @param boff Block index.
* @param block_size Block size.
* @param src Buffer containing the data to write.
*
* @return EOK on success or negative error code on failure.
*/
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size,
const void *src)
{
ipcarg_t retval;
int rc;
 
assert(devcon);
memcpy(devcon->com_area, src, block_size);
rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK,
boff, block_size, &retval);
if ((rc != EOK) || (retval != EOK))
return (rc != EOK ? rc : (int) retval);
 
return EOK;
}
 
/** @}
*/
/branches/network/uspace/lib/libblock/libblock.h
39,10 → 39,9
 
#include <stdint.h>
#include "../../srv/vfs/vfs.h"
#include <futex.h>
#include <rwlock.h>
#include <libadt/hash_table.h>
#include <libadt/list.h>
#include <fibril_sync.h>
#include <adt/hash_table.h>
#include <adt/list.h>
 
/*
* Flags that can be used with block_get().
63,14 → 62,14
typedef unsigned bn_t; /**< Block number type. */
 
typedef struct block {
/** Futex protecting the reference count. */
futex_t lock;
/** Mutex protecting the reference count. */
fibril_mutex_t lock;
/** Number of references to the block_t structure. */
unsigned refcnt;
/** If true, the block needs to be written back to the block device. */
bool dirty;
/** Readers / Writer lock protecting the contents of the block. */
rwlock_t contents_lock;
fibril_rwlock_t contents_lock;
/** Handle of the device where the block resides. */
dev_handle_t dev_handle;
/** Block offset on the block device. Counted in 'size'-byte blocks. */
85,6 → 84,14
void *data;
} block_t;
 
/** Caching mode */
enum cache_mode {
/** Write-Through */
CACHE_MODE_WT,
/** Write-Back */
CACHE_MODE_WB
};
 
extern int block_init(dev_handle_t, size_t);
extern void block_fini(dev_handle_t);
 
91,12 → 98,13
extern int block_bb_read(dev_handle_t, off_t, size_t);
extern void *block_bb_get(dev_handle_t);
 
extern int block_cache_init(dev_handle_t, size_t, unsigned);
extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode);
 
extern block_t *block_get(dev_handle_t, bn_t, int flags);
extern void block_put(block_t *);
 
extern int block_read(int, off_t *, size_t *, off_t *, void *, size_t, size_t);
extern int block_read(dev_handle_t, off_t *, size_t *, off_t *, void *, size_t,
size_t);
 
#endif
 
/branches/network/uspace/lib/softfloat/include/sftypes.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup softfloat
/** @addtogroup softfloat
* @{
*/
/** @file
41,40 → 41,40
typedef union {
float f;
uint32_t binary;
 
struct {
#if defined(ARCH_IS_BIG_ENDIAN)
uint32_t sign:1;
uint32_t exp:8;
uint32_t fraction:23;
#elif defined(ARCH_IS_LITTLE_ENDIAN)
uint32_t fraction:23;
uint32_t exp:8;
uint32_t sign:1;
#else
#error "Unknown endians."
struct {
#if defined(__BE__)
uint32_t sign : 1;
uint32_t exp : 8;
uint32_t fraction : 23;
#elif defined(__LE__)
uint32_t fraction : 23;
uint32_t exp : 8;
uint32_t sign : 1;
#else
#error Unknown endianess
#endif
} parts __attribute__ ((packed));
} float32;
} float32;
 
typedef union {
double d;
uint64_t binary;
struct {
#if defined(ARCH_IS_BIG_ENDIAN)
uint64_t sign:1;
uint64_t exp:11;
uint64_t fraction:52;
#elif defined(ARCH_IS_LITTLE_ENDIAN)
uint64_t fraction:52;
uint64_t exp:11;
uint64_t sign:1;
#else
#error "Unknown endians."
struct {
#if defined(__BE__)
uint64_t sign : 1;
uint64_t exp : 11;
uint64_t fraction : 52;
#elif defined(__LE__)
uint64_t fraction : 52;
uint64_t exp : 11;
uint64_t sign : 1;
#else
#error Unknown endianess
#endif
} parts __attribute__ ((packed));
} float64;
} parts __attribute__ ((packed));
} float64;
 
#define FLOAT32_MAX 0x7f800000
#define FLOAT32_MIN 0xff800000
109,7 → 109,5
 
#endif
 
 
/** @}
/** @}
*/
 
/branches/network/uspace/lib/softfloat/Makefile
36,7 → 36,7
 
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS +=-Iinclude -Iarch/$(UARCH)/include/
CFLAGS += -Iinclude -Iarch/$(UARCH)/include/
 
## Sources
#
/branches/network/uspace/lib/libc/include/console.h
File deleted
/branches/network/uspace/lib/libc/include/console/color.h
File deleted
/branches/network/uspace/lib/libc/include/console/style.h
File deleted
/branches/network/uspace/lib/libc/include/kbd/kbd.h
File deleted
/branches/network/uspace/lib/libc/include/kbd/keycode.h
File deleted
/branches/network/uspace/lib/libc/include/libadt/fifo.h
File deleted
/branches/network/uspace/lib/libc/include/libadt/hash_table.h
File deleted
/branches/network/uspace/lib/libc/include/libadt/list.h
File deleted
/branches/network/uspace/lib/libc/include/byteorder.h
35,48 → 35,47
#ifndef LIBC_BYTEORDER_H_
#define LIBC_BYTEORDER_H_
 
#include <libarch/byteorder.h>
#include <stdint.h>
 
#if !(defined(ARCH_IS_BIG_ENDIAN) ^ defined(ARCH_IS_LITTLE_ENDIAN))
#error The architecture must be either big-endian or little-endian.
#if !(defined(__BE__) ^ defined(__LE__))
#error The architecture must be either big-endian or little-endian.
#endif
 
#ifdef ARCH_IS_BIG_ENDIAN
#ifdef __BE__
 
#define uint16_t_le2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
#define uint16_t_le2host(n) (uint16_t_byteorder_swap(n))
#define uint32_t_le2host(n) (uint32_t_byteorder_swap(n))
#define uint64_t_le2host(n) (uint64_t_byteorder_swap(n))
 
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#define host2uint16_t_le(n) uint16_t_byteorder_swap(n)
#define host2uint32_t_le(n) uint32_t_byteorder_swap(n)
#define host2uint64_t_le(n) uint64_t_byteorder_swap(n)
#define host2uint16_t_le(n) (uint16_t_byteorder_swap(n))
#define host2uint32_t_le(n) (uint32_t_byteorder_swap(n))
#define host2uint64_t_le(n) (uint64_t_byteorder_swap(n))
 
#define host2uint16_t_be(n) (n)
#define host2uint32_t_be(n) (n)
#define host2uint64_t_be(n) (n)
#define host2uint16_t_be(n) (n)
#define host2uint32_t_be(n) (n)
#define host2uint64_t_be(n) (n)
 
#else
 
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint16_t_be2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
#define uint16_t_be2host(n) (uint16_t_byteorder_swap(n))
#define uint32_t_be2host(n) (uint32_t_byteorder_swap(n))
#define uint64_t_be2host(n) (uint64_t_byteorder_swap(n))
 
#define host2uint16_t_le(n) (n)
#define host2uint32_t_le(n) (n)
#define host2uint64_t_le(n) (n)
#define host2uint16_t_le(n) (n)
#define host2uint32_t_le(n) (n)
#define host2uint64_t_le(n) (n)
 
#define host2uint16_t_be(n) uint16_t_byteorder_swap(n)
#define host2uint32_t_be(n) uint32_t_byteorder_swap(n)
#define host2uint64_t_be(n) uint64_t_byteorder_swap(n)
#define host2uint16_t_be(n) (uint16_t_byteorder_swap(n))
#define host2uint32_t_be(n) (uint32_t_byteorder_swap(n))
#define host2uint64_t_be(n) (uint64_t_byteorder_swap(n))
 
#endif
 
/branches/network/uspace/lib/libc/include/fcntl.h
35,13 → 35,13
#ifndef LIBC_FCNTL_H_
#define LIBC_FCNTL_H_
 
#define O_CREAT 1
#define O_EXCL 2
#define O_TRUNC 4
#define O_APPEND 8
#define O_RDONLY 16
#define O_RDWR 32
#define O_WRONLY 64
#define O_CREAT 1
#define O_EXCL 2
#define O_TRUNC 4
#define O_APPEND 8
#define O_RDONLY 16
#define O_RDWR 32
#define O_WRONLY 64
 
extern int open(const char *, int, ...);
 
/branches/network/uspace/lib/libc/include/string.h
39,13 → 39,12
#include <sys/types.h>
#include <bool.h>
 
#define U_SPECIAL '?'
#define U_BOM 0xfeff
#define U_SPECIAL '?'
 
/**< No size limit constant */
/** No size limit constant */
#define STR_NO_LIMIT ((size_t) -1)
 
/**< Maximum size of a string containing @c length characters */
/** Maximum size of a string containing @c length characters */
#define STR_BOUNDS(length) ((length) << 2)
 
extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
54,20 → 53,20
extern size_t str_size(const char *str);
extern size_t wstr_size(const wchar_t *str);
 
extern size_t str_lsize(const char *str, count_t max_len);
extern size_t wstr_lsize(const wchar_t *str, count_t max_len);
extern size_t str_lsize(const char *str, size_t max_len);
extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
 
extern count_t str_length(const char *str);
extern count_t wstr_length(const wchar_t *wstr);
extern size_t str_length(const char *str);
extern size_t wstr_length(const wchar_t *wstr);
 
extern count_t str_nlength(const char *str, size_t size);
extern count_t wstr_nlength(const wchar_t *str, size_t size);
extern size_t str_nlength(const char *str, size_t size);
extern size_t wstr_nlength(const wchar_t *str, size_t size);
 
extern bool ascii_check(wchar_t ch);
extern bool chr_check(wchar_t ch);
 
extern int str_cmp(const char *s1, const char *s2);
extern int str_lcmp(const char *s1, const char *s2, count_t max_len);
extern int str_lcmp(const char *s1, const char *s2, size_t max_len);
 
extern void str_cpy(char *dest, size_t size, const char *src);
extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
78,8 → 77,8
extern const char *str_chr(const char *str, wchar_t ch);
extern const char *str_rchr(const char *str, wchar_t ch);
 
extern bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos);
extern bool wstr_remove(wchar_t *str, count_t pos);
extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
extern bool wstr_remove(wchar_t *str, size_t pos);
 
extern char *str_dup(const char *);
 
/branches/network/uspace/lib/libc/include/vfs/vfs.h
36,12 → 36,36
#define LIBC_VFS_H_
 
#include <sys/types.h>
#include <ipc/vfs.h>
#include <ipc/devmap.h>
#include <stdio.h>
 
/**
* This type is a libc version of the VFS triplet.
* It uniquelly identifies a file system node within a file system instance.
*/
typedef struct {
fs_handle_t fs_handle;
dev_handle_t dev_handle;
fs_index_t index;
} fdi_node_t;
 
extern char *absolutize(const char *, size_t *);
 
extern int mount(const char *, const char *, const char *, const char *,
const unsigned int flags);
unsigned int);
 
extern void stdio_init(int filc, fdi_node_t *filv[]);
extern void stdio_done(void);
 
extern int open_node(fdi_node_t *, int);
extern int fd_phone(int);
extern int fd_node(int, fdi_node_t *);
 
extern FILE *fopen_node(fdi_node_t *, const char *);
extern int fphone(FILE *);
extern int fnode(FILE *, fdi_node_t *);
 
#endif
 
/** @}
/branches/network/uspace/lib/libc/include/async.h
44,12 → 44,15
typedef ipc_callid_t aid_t;
typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
 
extern atomic_t async_futex;
 
static inline void async_manager(void)
{
fibril_switch(FIBRIL_TO_MANAGER);
}
 
ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
 
static inline ipc_callid_t async_get_call(ipc_call_t *data)
{
return async_get_call_timeout(data, 0);
63,19 → 66,19
*/
 
#define async_send_0(phoneid, method, dataptr) \
async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
#define async_send_1(phoneid, method, arg1, dataptr) \
async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
#define async_send_2(phoneid, method, arg1, arg2, dataptr) \
async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
#define async_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
#define async_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(dataptr))
async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(dataptr))
#define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (dataptr))
async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (dataptr))
 
extern aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr);
86,12 → 89,12
extern int async_wait_timeout(aid_t amsgid, ipcarg_t *retval,
suseconds_t timeout);
 
fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
extern fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *));
void async_usleep(suseconds_t timeout);
void async_create_manager(void);
void async_destroy_manager(void);
int _async_init(void);
extern void async_usleep(suseconds_t timeout);
extern void async_create_manager(void);
extern void async_destroy_manager(void);
extern int _async_init(void);
 
extern void async_set_client_connection(async_client_conn_t conn);
extern void async_set_interrupt_received(async_client_conn_t conn);
98,22 → 101,22
 
/* Wrappers for simple communication */
#define async_msg_0(phone, method) \
ipc_call_async_0((phone), (method), NULL, NULL, true)
ipc_call_async_0((phone), (method), NULL, NULL, true)
#define async_msg_1(phone, method, arg1) \
ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
true)
ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
true)
#define async_msg_2(phone, method, arg1, arg2) \
ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
true)
ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
true)
#define async_msg_3(phone, method, arg1, arg2, arg3) \
ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
true)
ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
true)
#define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \
ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, true)
ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, true)
#define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \
ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, true)
ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, true)
 
/*
* User-friendly wrappers for async_req_fast() and async_req_slow(). The macros
122,90 → 125,90
* and slow verion based on m.
*/
#define async_req_0_0(phoneid, method) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
NULL)
#define async_req_0_1(phoneid, method, r1) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
NULL)
#define async_req_0_2(phoneid, method, r1, r2) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
NULL)
#define async_req_0_3(phoneid, method, r1, r2, r3) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
NULL)
#define async_req_0_4(phoneid, method, r1, r2, r3, r4) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
NULL)
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
NULL)
#define async_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
(r5))
async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
(r5))
#define async_req_1_0(phoneid, method, arg1) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
NULL, NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
NULL, NULL)
#define async_req_1_1(phoneid, method, arg1, rc1) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
NULL, NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
NULL, NULL)
#define async_req_1_2(phoneid, method, arg1, rc1, rc2) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
NULL, NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
NULL, NULL)
#define async_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
NULL, NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
NULL, NULL)
#define async_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
(rc4), NULL)
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
(rc4), NULL)
#define async_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
(rc4), (rc5))
async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
(rc4), (rc5))
#define async_req_2_0(phoneid, method, arg1, arg2) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
NULL, NULL, NULL)
#define async_req_2_1(phoneid, method, arg1, arg2, rc1) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
NULL, NULL, NULL)
#define async_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
NULL, NULL, NULL)
#define async_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), NULL, NULL)
#define async_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), (rc4), NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), (rc4), NULL)
#define async_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), (rc4), (rc5))
async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
(rc3), (rc4), (rc5))
#define async_req_3_0(phoneid, method, arg1, arg2, arg3) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
NULL, NULL, NULL)
#define async_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
NULL, NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
NULL, NULL, NULL, NULL)
#define async_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), NULL, NULL, NULL)
#define async_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), NULL, NULL)
#define async_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), (rc4), NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), (rc4), NULL)
#define async_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
rc5) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
(rc2), (rc3), (rc4), (rc5))
#define async_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
NULL, NULL, NULL, NULL)
#define async_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
NULL, NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
NULL, NULL, NULL, NULL)
#define async_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
(rc2), NULL, NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
(rc2), NULL, NULL, NULL)
#define async_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
(rc2), (rc3), NULL, NULL)
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
(rc2), (rc3), NULL, NULL)
#define async_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
rc4) \
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
215,14 → 218,14
async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(rc1), (rc2), (rc3), (rc4), (rc5))
#define async_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, NULL, NULL, NULL)
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), NULL, NULL, NULL, NULL, NULL)
#define async_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (rc1), NULL, NULL, NULL, NULL)
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (rc1), NULL, NULL, NULL, NULL)
#define async_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (rc1), (rc2), NULL, NULL, NULL)
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (rc1), (rc2), NULL, NULL, NULL)
#define async_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
rc3) \
async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
253,8 → 256,6
fibril_dec_sercount();
}
 
extern atomic_t async_futex;
 
#endif
 
/** @}
/branches/network/uspace/lib/libc/include/stdio.h
37,78 → 37,117
 
#include <sys/types.h>
#include <stdarg.h>
#include <adt/list.h>
 
#define EOF (-1)
#define EOF (-1)
 
#include <string.h>
#include <io/stream.h>
/** Default size for stream I/O buffers */
#define BUFSIZ 4096
 
#define DEBUG(fmt, ...) \
{ \
char buf[256]; \
int n; \
n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \
int n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \
if (n > 0) \
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, str_size(buf)); \
}
 
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
 
enum _buffer_type {
/** No buffering */
_IONBF,
/** Line buffering */
_IOLBF,
/** Full buffering */
_IOFBF
};
 
typedef struct {
/** Linked list pointer. */
link_t link;
/** Underlying file descriptor. */
int fd;
 
/** Error indicator. */
int error;
 
/** End-of-file indicator. */
int eof;
/** Klog indicator */
int klog;
/** Phone to the file provider */
int phone;
 
/** Buffering type */
enum _buffer_type btype;
/** Buffer */
uint8_t *buf;
/** Buffer size */
size_t buf_size;
/** Buffer I/O pointer */
uint8_t *buf_head;
} FILE;
 
extern FILE *stdin, *stdout, *stderr;
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
 
/* Character and string input functions */
extern int fgetc(FILE *);
extern char *fgets(char *, size_t, FILE *);
 
extern int getchar(void);
extern char *gets(char *, size_t);
 
/* Character and string output functions */
extern int fputc(wchar_t, FILE *);
extern int fputs(const char *, FILE *);
 
extern int putchar(wchar_t);
extern int puts(const char *);
extern int putchar(int);
extern int fflush(FILE *);
 
/* Formatted string output functions */
extern int fprintf(FILE *, const char*, ...);
extern int vfprintf(FILE *, const char *, va_list);
 
extern int printf(const char *, ...);
extern int vprintf(const char *, va_list);
 
extern int snprintf(char *, size_t , const char *, ...);
extern int asprintf(char **, const char *, ...);
extern int sprintf(char *, const char *, ...);
extern int snprintf(char *, size_t , const char *, ...);
 
extern int vprintf(const char *, va_list);
extern int vsprintf(char *, const char *, va_list);
extern int vsnprintf(char *, size_t, const char *, va_list);
 
extern int rename(const char *, const char *);
 
/* File stream functions */
extern FILE *fopen(const char *, const char *);
extern FILE *fdopen(int, const char *);
extern int fclose(FILE *);
 
extern size_t fread(void *, size_t, size_t, FILE *);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
 
extern int fseek(FILE *, long, int);
extern void rewind(FILE *);
extern int ftell(FILE *);
extern int feof(FILE *);
 
extern int fflush(FILE *);
extern int ferror(FILE *);
extern void clearerr(FILE *);
 
extern int fgetc(FILE *);
extern int fputc(int, FILE *);
extern int fputs(const char *, FILE *);
extern void setvbuf(FILE *, void *, int, size_t);
 
extern int fprintf(FILE *, const char *, ...);
extern int vfprintf(FILE *, const char *, va_list);
/* Misc file functions */
extern int rename(const char *, const char *);
 
#define getc fgetc
#define putc fputc
 
extern int fseek(FILE *, long, int);
 
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/dirent.h
35,7 → 35,7
#ifndef LIBC_DIRENT_H_
#define LIBC_DIRENT_H_
 
#define NAME_MAX 256
#define NAME_MAX 256
 
struct dirent {
char d_name[NAME_MAX + 1];
46,7 → 46,6
struct dirent res;
} DIR;
 
 
extern DIR *opendir(const char *);
extern struct dirent *readdir(DIR *);
extern void rewinddir(DIR *);
/branches/network/uspace/lib/libc/include/task.h
42,6 → 42,7
extern task_id_t task_get_id(void);
extern int task_set_name(const char *name);
extern task_id_t task_spawn(const char *path, char *const argv[]);
extern int task_wait(task_id_t id);
 
#endif
 
/branches/network/uspace/lib/libc/include/fibril_sync.h
0,0 → 1,104
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_FIBRIL_SYNC_H_
#define LIBC_FIBRIL_SYNC_H_
 
#include <async.h>
#include <fibril.h>
#include <adt/list.h>
#include <libarch/tls.h>
 
typedef struct {
int counter;
link_t waiters;
} fibril_mutex_t;
 
#define FIBRIL_MUTEX_INITIALIZE(name) \
fibril_mutex_t name = { \
.counter = 1, \
.waiters = { \
.prev = &name.waiters, \
.next = &name.waiters, \
} \
}
 
typedef struct {
unsigned writers;
unsigned readers;
link_t waiters;
} fibril_rwlock_t;
 
#define FIBRIL_RWLOCK_INITIALIZE(name) \
fibril_rwlock_t name = { \
.readers = 0, \
.writers = 0, \
.waiters = { \
.prev = &name.waiters, \
.next = &name.waiters, \
} \
}
 
typedef struct {
link_t waiters;
} fibril_condvar_t;
 
#define FIBRIL_CONDVAR_INITIALIZE(name) \
fibril_condvar_t name = { \
.waiters = { \
.next = &name.waiters, \
.prev = &name.waiters, \
} \
}
 
extern void fibril_mutex_initialize(fibril_mutex_t *);
extern void fibril_mutex_lock(fibril_mutex_t *);
extern bool fibril_mutex_trylock(fibril_mutex_t *);
extern void fibril_mutex_unlock(fibril_mutex_t *);
 
extern void fibril_rwlock_initialize(fibril_rwlock_t *);
extern void fibril_rwlock_read_lock(fibril_rwlock_t *);
extern void fibril_rwlock_write_lock(fibril_rwlock_t *);
extern void fibril_rwlock_read_unlock(fibril_rwlock_t *);
extern void fibril_rwlock_write_unlock(fibril_rwlock_t *);
 
extern void fibril_condvar_initialize(fibril_condvar_t *);
extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *);
extern void fibril_condvar_signal(fibril_condvar_t *);
extern void fibril_condvar_broadcast(fibril_condvar_t *);
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/unistd.h
39,26 → 39,30
#include <libarch/config.h>
 
#ifndef NULL
#define NULL 0
#define NULL 0
#endif
 
#define getpagesize() (PAGE_SIZE)
#define getpagesize() (PAGE_SIZE)
 
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
 
extern ssize_t write(int, const void *, size_t);
extern ssize_t read(int, void *, size_t);
 
extern off_t lseek(int, off_t, int);
extern int ftruncate(int, off_t);
 
extern int close(int);
extern int fsync(int);
extern int unlink(const char *);
 
extern char *getcwd(char *buf, size_t);
extern int rmdir(const char *);
extern int chdir(const char *);
extern char *getcwd(char *buf, size_t);
 
extern void _exit(int status) __attribute__ ((noreturn));
extern void *sbrk(ssize_t incr);
/branches/network/uspace/lib/libc/include/fibril.h
36,17 → 36,18
#define LIBC_FIBRIL_H_
 
#include <libarch/fibril.h>
#include <libadt/list.h>
#include <adt/list.h>
#include <libarch/tls.h>
 
#ifndef context_set
#define context_set(c, _pc, stack, size, ptls) \
(c)->pc = (sysarg_t) (_pc); \
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
(c)->tls = (sysarg_t) (ptls);
#define context_set(c, _pc, stack, size, ptls) \
(c)->pc = (sysarg_t) (_pc); \
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
(c)->tls = (sysarg_t) (ptls);
#endif /* context_set */
 
#define FIBRIL_SERIALIZED 1
#define FIBRIL_SERIALIZED 1
#define FIBRIL_WRITER 2
 
typedef enum {
FIBRIL_PREEMPT,
71,6 → 72,9
};
typedef struct fibril fibril_t;
 
/** Fibril-local variable specifier */
#define fibril_local __thread
 
extern int context_save(context_t *c);
extern void context_restore(context_t *c) __attribute__ ((noreturn));
 
/branches/network/uspace/lib/libc/include/devmap.h
0,0 → 1,56
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_DEVMAP_H_
#define LIBC_DEVMAP_H_
 
#include <ipc/devmap.h>
#include <async.h>
 
extern int devmap_get_phone(devmap_interface_t, unsigned int);
extern void devmap_hangup_phone(devmap_interface_t iface);
 
extern int devmap_driver_register(const char *, async_client_conn_t);
extern int devmap_device_register(const char *, dev_handle_t *);
 
extern int devmap_device_get_handle(const char *, dev_handle_t *, unsigned int);
extern int devmap_device_connect(dev_handle_t, unsigned int);
 
extern ipcarg_t devmap_device_get_count(void);
extern ipcarg_t devmap_device_get_devices(ipcarg_t, dev_desc_t *);
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/loader/pcb.h
37,6 → 37,7
#define LIBC_PCB_H_
 
#include <sys/types.h>
#include <vfs/vfs.h>
 
typedef void (*entry_point_t)(void);
 
45,19 → 46,26
* Holds pointers to data passed from the program loader to the program
* and/or to the dynamic linker. This includes the program entry point,
* arguments, environment variables etc.
*
*/
typedef struct {
/** Program entry point. */
entry_point_t entry;
 
/** Number of command-line arguments. */
int argc;
/** Command-line arguments. */
char **argv;
 
/** Number of preset files. */
int filc;
/** Preset files. */
fdi_node_t **filv;
/*
* ELF-specific data.
*/
/** Pointer to ELF dynamic section of the program. */
void *dynamic;
} pcb_t;
/branches/network/uspace/lib/libc/include/loader/loader.h
37,6 → 37,7
#define LIBC_LOADER_H_
 
#include <task.h>
#include <vfs/vfs.h>
 
/** Abstraction of a loader connection */
typedef struct {
48,7 → 49,8
extern loader_t *loader_connect(void);
extern int loader_get_task_id(loader_t *, task_id_t *);
extern int loader_set_pathname(loader_t *, const char *);
extern int loader_set_args(loader_t *, char *const []);
extern int loader_set_args(loader_t *, char *const[]);
extern int loader_set_files(loader_t *, fdi_node_t *const[]);
extern int loader_load_program(loader_t *);
extern int loader_run(loader_t *);
extern void loader_abort(loader_t *);
/branches/network/uspace/lib/libc/include/io/io.h
File deleted
/branches/network/uspace/lib/libc/include/io/stream.h
File deleted
/branches/network/uspace/lib/libc/include/io/printf_core.h
56,5 → 56,3
 
/** @}
*/
/branches/network/uspace/lib/libc/include/io/klog.h
0,0 → 1,46
/*
* Copyright (c) 2006 Jakub Vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_STREAM_H_
#define LIBC_STREAM_H_
 
#include <sys/types.h>
 
extern size_t klog_write(const void *buf, size_t size);
extern void klog_update(void);
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/io/color.h
0,0 → 1,55
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IO_COLOR_H_
#define LIBC_IO_COLOR_H_
 
enum console_color {
COLOR_BLACK = 0,
COLOR_BLUE = 1,
COLOR_GREEN = 2,
COLOR_CYAN = 3,
COLOR_RED = 4,
COLOR_MAGENTA = 5,
COLOR_YELLOW = 6,
COLOR_WHITE = 7,
CATTR_BRIGHT = 8,
CATTR_BLINK = 8
};
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/io/style.h
0,0 → 1,46
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IO_STYLE_H_
#define LIBC_IO_STYLE_H_
 
enum console_style {
STYLE_NORMAL = 0,
STYLE_EMPHASIS = 1
};
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/io/console.h
0,0 → 1,78
/*
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IO_CONSOLE_H_
#define LIBC_IO_CONSOLE_H_
 
#include <ipc/ipc.h>
#include <bool.h>
 
typedef enum {
KEY_PRESS,
KEY_RELEASE
} console_ev_type_t;
 
/** Console event structure. */
typedef struct {
/** Press or release event. */
console_ev_type_t type;
/** Keycode of the key that was pressed or released. */
unsigned int key;
/** Bitmask of modifiers held. */
unsigned int mods;
/** The character that was generated or '\0' for none. */
wchar_t c;
} console_event_t;
 
extern void console_clear(int phone);
 
extern int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols);
extern void console_goto(int phone, ipcarg_t row, ipcarg_t col);
 
extern void console_set_style(int phone, int style);
extern void console_set_color(int phone, int fg_color, int bg_color, int flags);
extern void console_set_rgb_color(int phone, int fg_color, int bg_color);
 
extern void console_cursor_visibility(int phone, bool show);
extern void console_kcon_enable(int phone);
 
extern bool console_get_event(int phone, console_event_t *event);
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/io/keycode.h
0,0 → 1,220
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IO_KEYCODE_H_
#define LIBC_IO_KEYCODE_H_
 
/** Keycode definitions.
*
* A keycode identifies a key by its position on the keyboard, rather
* than by its label. For human readability, key positions are noted
* with the key label on a keyboard with US layout. This label has
* nothing to do with the character, that the key produces
* -- this is determined by the keymap.
*
* The keyboard model reflects a standard PC keyboard layout.
* Non-standard keyboards need to be mapped to this model in some
* logical way. Scancodes are mapped to keycodes with a scanmap.
*
* For easier mapping to the model and to emphasize the nature of keycodes,
* they really are organized here by position, rather than by label.
*/
enum keycode {
 
/* Main block row 1 */
 
KC_BACKTICK = 1,
 
KC_1,
KC_2,
KC_3,
KC_4,
KC_5,
KC_6,
KC_7,
KC_8,
KC_9,
KC_0,
 
KC_MINUS,
KC_EQUALS,
KC_BACKSPACE,
 
/* Main block row 2 */
 
KC_TAB,
 
KC_Q,
KC_W,
KC_E,
KC_R,
KC_T,
KC_Y,
KC_U,
KC_I,
KC_O,
KC_P,
 
KC_LBRACKET,
KC_RBRACKET,
 
/* Main block row 3 */
 
KC_CAPS_LOCK,
KC_A,
KC_S,
KC_D,
KC_F,
KC_G,
KC_H,
KC_J,
KC_K,
KC_L,
 
KC_SEMICOLON,
KC_QUOTE,
KC_BACKSLASH,
 
KC_ENTER,
 
/* Main block row 4 */
 
KC_LSHIFT,
 
KC_Z,
KC_X,
KC_C,
KC_V,
KC_B,
KC_N,
KC_M,
 
KC_COMMA,
KC_PERIOD,
KC_SLASH,
 
KC_RSHIFT,
 
/* Main block row 5 */
 
KC_LCTRL,
KC_LALT,
KC_SPACE,
KC_RALT,
KC_RCTRL,
 
/* Function keys block */
 
KC_ESCAPE,
 
KC_F1,
KC_F2,
KC_F3,
KC_F4,
KC_F5,
KC_F6,
KC_F7,
KC_F8,
KC_F9,
KC_F10,
KC_F11,
KC_F12,
 
KC_PRTSCR,
KC_SCROLL_LOCK,
KC_PAUSE,
 
/* Cursor keys block */
 
KC_INSERT,
KC_HOME,
KC_PAGE_UP,
 
KC_DELETE,
KC_END,
KC_PAGE_DOWN,
 
KC_UP,
KC_LEFT,
KC_DOWN,
KC_RIGHT,
 
/* Numeric block */
 
KC_NUM_LOCK,
KC_NSLASH,
KC_NTIMES,
KC_NMINUS,
 
KC_NPLUS,
KC_NENTER,
 
KC_N7,
KC_N8,
KC_N9,
 
KC_N4,
KC_N5,
KC_N6,
 
KC_N1,
KC_N2,
KC_N3,
 
KC_N0,
KC_NPERIOD
} keycode_t;
 
enum keymod {
KM_LSHIFT = 0x001,
KM_RSHIFT = 0x002,
KM_LCTRL = 0x004,
KM_RCTRL = 0x008,
KM_LALT = 0x010,
KM_RALT = 0x020,
KM_CAPS_LOCK = 0x040,
KM_NUM_LOCK = 0x080,
KM_SCROLL_LOCK = 0x100,
KM_SHIFT = KM_LSHIFT | KM_RSHIFT,
KM_CTRL = KM_LCTRL | KM_RCTRL,
KM_ALT = KM_LALT | KM_RALT
} keymod_t;
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/adt/hash_table.h
0,0 → 1,94
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_HASH_TABLE_H_
#define LIBC_HASH_TABLE_H_
 
#include <adt/list.h>
#include <unistd.h>
 
typedef unsigned long hash_count_t;
typedef unsigned long hash_index_t;
typedef struct hash_table hash_table_t;
typedef struct hash_table_operations hash_table_operations_t;
 
/** Hash table structure. */
struct hash_table {
link_t *entry;
hash_count_t entries;
hash_count_t max_keys;
hash_table_operations_t *op;
};
 
/** Set of operations for hash table. */
struct hash_table_operations {
/** Hash function.
*
* @param key Array of keys needed to compute hash index. All keys
* must be passed.
*
* @return Index into hash table.
*/
hash_index_t (* hash)(unsigned long key[]);
/** Hash table item comparison function.
*
* @param key Array of keys that will be compared with item. It is
* not necessary to pass all keys.
*
* @return true if the keys match, false otherwise.
*/
int (*compare)(unsigned long key[], hash_count_t keys, link_t *item);
 
/** Hash table item removal callback.
*
* @param item Item that was removed from the hash table.
*/
void (*remove_callback)(link_t *item);
};
 
#define hash_table_get_instance(item, type, member) \
list_get_instance((item), type, member)
 
extern int hash_table_create(hash_table_t *, hash_count_t, hash_count_t,
hash_table_operations_t *);
extern void hash_table_insert(hash_table_t *, unsigned long [], link_t *);
extern link_t *hash_table_find(hash_table_t *, unsigned long []);
extern void hash_table_remove(hash_table_t *, unsigned long [], hash_count_t);
extern void hash_table_destroy(hash_table_t *);
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/adt/list.h
0,0 → 1,201
/*
* Copyright (c) 2001-2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_LIST_H_
#define LIBC_LIST_H_
 
#include <unistd.h>
 
/** Doubly linked list head and link type. */
typedef struct link {
struct link *prev; /**< Pointer to the previous item in the list. */
struct link *next; /**< Pointer to the next item in the list. */
} link_t;
 
/** Declare and initialize statically allocated list.
*
* @param name Name of the new statically allocated list.
*/
#define LIST_INITIALIZE(name) link_t name = { \
.prev = &name, \
.next = &name \
}
 
/** Initialize doubly-linked circular list link
*
* Initialize doubly-linked list link.
*
* @param link Pointer to link_t structure to be initialized.
*/
static inline void link_initialize(link_t *link)
{
link->prev = NULL;
link->next = NULL;
}
 
/** Initialize doubly-linked circular list
*
* Initialize doubly-linked circular list.
*
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_initialize(link_t *head)
{
head->prev = head;
head->next = head;
}
 
/** Add item to the beginning of doubly-linked circular list
*
* Add item to the beginning of doubly-linked circular list.
*
* @param link Pointer to link_t structure to be added.
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_prepend(link_t *link, link_t *head)
{
link->next = head->next;
link->prev = head;
head->next->prev = link;
head->next = link;
}
 
/** Add item to the end of doubly-linked circular list
*
* Add item to the end of doubly-linked circular list.
*
* @param link Pointer to link_t structure to be added.
* @param head Pointer to link_t structure representing head of the list.
*/
static inline void list_append(link_t *link, link_t *head)
{
link->prev = head->prev;
link->next = head;
head->prev->next = link;
head->prev = link;
}
 
/** Insert item before another item in doubly-linked circular list. */
static inline void list_insert_before(link_t *l, link_t *r)
{
list_append(l, r);
}
 
/** Insert item after another item in doubly-linked circular list. */
static inline void list_insert_after(link_t *r, link_t *l)
{
list_prepend(l, r);
}
 
/** Remove item from doubly-linked circular list
*
* Remove item from doubly-linked circular list.
*
* @param link Pointer to link_t structure to be removed from the list it is contained in.
*/
static inline void list_remove(link_t *link)
{
link->next->prev = link->prev;
link->prev->next = link->next;
link_initialize(link);
}
 
/** Query emptiness of doubly-linked circular list
*
* Query emptiness of doubly-linked circular list.
*
* @param head Pointer to link_t structure representing head of the list.
*/
static inline int list_empty(link_t *head)
{
return ((head->next == head) ? 1 : 0);
}
 
 
/** Split or concatenate headless doubly-linked circular list
*
* Split or concatenate headless doubly-linked circular list.
*
* Note that the algorithm works both directions:
* concatenates splitted lists and splits concatenated lists.
*
* @param part1 Pointer to link_t structure leading the first (half of the headless) list.
* @param part2 Pointer to link_t structure leading the second (half of the headless) list.
*/
static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
{
part1->prev->next = part2;
part2->prev->next = part1;
link_t *hlp = part1->prev;
part1->prev = part2->prev;
part2->prev = hlp;
}
 
 
/** Split headless doubly-linked circular list
*
* Split headless doubly-linked circular list.
*
* @param part1 Pointer to link_t structure leading the first half of the headless list.
* @param part2 Pointer to link_t structure leading the second half of the headless list.
*/
static inline void headless_list_split(link_t *part1, link_t *part2)
{
headless_list_split_or_concat(part1, part2);
}
 
/** Concatenate two headless doubly-linked circular lists
*
* Concatenate two headless doubly-linked circular lists.
*
* @param part1 Pointer to link_t structure leading the first headless list.
* @param part2 Pointer to link_t structure leading the second headless list.
*/
static inline void headless_list_concat(link_t *part1, link_t *part2)
{
headless_list_split_or_concat(part1, part2);
}
 
#define list_get_instance(link, type, member) ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
 
extern int list_member(const link_t *link, const link_t *head);
extern void list_concat(link_t *head1, link_t *head2);
extern unsigned int list_count(const link_t *link);
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/adt/fifo.h
0,0 → 1,127
/*
* Copyright (c) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
/*
* This implementation of FIFO stores values in an array
* (static or dynamic). As such, these FIFOs have upper bound
* on number of values they can store. Push and pop operations
* are done via accessing the array through head and tail indices.
* Because of better operation ordering in fifo_pop(), the access
* policy for these two indices is to 'increment (mod size of FIFO)
* and use'.
*/
 
#ifndef LIBC_FIFO_H_
#define LIBC_FIFO_H_
 
#include <malloc.h>
 
typedef unsigned long fifo_count_t;
typedef unsigned long fifo_index_t;
 
#define FIFO_CREATE_STATIC(name, t, itms) \
struct { \
t fifo[(itms)]; \
fifo_count_t items; \
fifo_index_t head; \
fifo_index_t tail; \
} name
 
/** Create and initialize static FIFO.
*
* FIFO is allocated statically.
* This macro is suitable for creating smaller FIFOs.
*
* @param name Name of FIFO.
* @param t Type of values stored in FIFO.
* @param itms Number of items that can be stored in FIFO.
*/
#define FIFO_INITIALIZE_STATIC(name, t, itms) \
FIFO_CREATE_STATIC(name, t, itms) = { \
.items = (itms), \
.head = 0, \
.tail = 0 \
}
 
/** Create and prepare dynamic FIFO.
*
* FIFO is allocated dynamically.
* This macro is suitable for creating larger FIFOs.
*
* @param name Name of FIFO.
* @param t Type of values stored in FIFO.
* @param itms Number of items that can be stored in FIFO.
*/
#define FIFO_INITIALIZE_DYNAMIC(name, t, itms) \
struct { \
t *fifo; \
fifo_count_t items; \
fifo_index_t head; \
fifo_index_t tail; \
} name = { \
.fifo = NULL, \
.items = (itms), \
.head = 0, \
.tail = 0 \
}
 
/** Pop value from head of FIFO.
*
* @param name FIFO name.
*
* @return Leading value in FIFO.
*/
#define fifo_pop(name) \
name.fifo[name.head = (name.head + 1) < name.items ? (name.head + 1) : 0]
 
/** Push value to tail of FIFO.
*
* @param name FIFO name.
* @param value Value to be appended to FIFO.
*
*/
#define fifo_push(name, value) \
name.fifo[name.tail = (name.tail + 1) < name.items ? (name.tail + 1) : 0] = (value)
 
/** Allocate memory for dynamic FIFO.
*
* @param name FIFO name.
*/
#define fifo_create(name) \
name.fifo = malloc(sizeof(*name.fifo) * name.items)
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/macros.h
35,15 → 35,22
#ifndef LIBC_MACROS_H_
#define LIBC_MACROS_H_
 
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
 
#define KB2SIZE(kb) ((kb) << 10)
#define MB2SIZE(mb) ((mb) << 20)
#define KB2SIZE(kb) ((kb) << 10)
#define MB2SIZE(mb) ((mb) << 20)
 
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
 
#define LOWER32(arg) ((arg) & 0xffffffff)
#define UPPER32(arg) (((arg) >> 32) & 0xffffffff)
 
#define MERGE_LOUP32(lo, up) \
((((uint64_t) (lo)) & 0xffffffff) \
| ((((uint64_t) (up)) & 0xffffffff) << 32))
 
#endif
 
/** @}
/branches/network/uspace/lib/libc/include/ipc/ipc.h
30,21 → 30,26
* @{
*/
/** @file
*/
*/
 
#ifndef LIBIPC_IPC_H_
#define LIBIPC_IPC_H_
 
#include <task.h>
#include <kernel/ipc/ipc.h>
#include <kernel/ddi/irq.h>
#include <sys/types.h>
#include <kernel/synch/synch.h>
 
#define IPC_FLAG_BLOCKING 0x01
 
typedef sysarg_t ipcarg_t;
 
typedef struct {
ipcarg_t args[IPC_CALL_LEN];
ipcarg_t in_phone_hash;
} ipc_call_t;
 
typedef sysarg_t ipc_callid_t;
 
typedef void (* ipc_async_callback_t)(void *, int, ipc_call_t *);
56,49 → 61,51
* possible, the fast version is used.
*/
#define ipc_call_sync_0_0(phoneid, method) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)
#define ipc_call_sync_0_1(phoneid, method, res1) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), 0, 0, 0, 0)
#define ipc_call_sync_0_2(phoneid, method, res1, res2) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), 0, 0, 0)
#define ipc_call_sync_0_3(phoneid, method, res1, res2, res3) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
0, 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
0, 0)
#define ipc_call_sync_0_4(phoneid, method, res1, res2, res3, res4) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
(res4), 0)
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
(res4), 0)
#define ipc_call_sync_0_5(phoneid, method, res1, res2, res3, res4, res5) \
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
(res4), (res5))
ipc_call_sync_fast((phoneid), (method), 0, 0, 0, (res1), (res2), (res3), \
(res4), (res5))
 
#define ipc_call_sync_1_0(phoneid, method, arg1) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, 0, 0, 0, 0, 0)
#define ipc_call_sync_1_1(phoneid, method, arg1, res1) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), 0, 0, 0, 0)
#define ipc_call_sync_1_2(phoneid, method, arg1, res1, res2) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \
0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), 0, \
0, 0)
#define ipc_call_sync_1_3(phoneid, method, arg1, res1, res2, res3) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), 0, 0)
#define ipc_call_sync_1_4(phoneid, method, arg1, res1, res2, res3, res4) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), (res4), 0)
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), (res4), 0)
#define ipc_call_sync_1_5(phoneid, method, arg1, res1, res2, res3, res4, \
res5) \
ipc_call_sync_fast((phoneid), (method), (arg1), 0, 0, (res1), (res2), \
(res3), (res4), (res5))
 
#define ipc_call_sync_2_0(phoneid, method, arg1, arg2) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \
0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, 0, 0, 0, \
0, 0)
#define ipc_call_sync_2_1(phoneid, method, arg1, arg2, res1) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \
0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), 0, 0, \
0, 0)
#define ipc_call_sync_2_2(phoneid, method, arg1, arg2, res1, res2) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), 0, 0, 0)
#define ipc_call_sync_2_3(phoneid, method, arg1, arg2, res1, res2, res3) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), (res3), 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), (res3), 0, 0)
#define ipc_call_sync_2_4(phoneid, method, arg1, arg2, res1, res2, res3, \
res4) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
107,15 → 114,16
res4, res5)\
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), 0, (res1), \
(res2), (res3), (res4), (res5))
 
#define ipc_call_sync_3_0(phoneid, method, arg1, arg2, arg3) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \
0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, 0, 0, \
0, 0)
#define ipc_call_sync_3_1(phoneid, method, arg1, arg2, arg3, res1) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
0, 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
0, 0, 0, 0)
#define ipc_call_sync_3_2(phoneid, method, arg1, arg2, arg3, res1, res2) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
(res2), 0, 0, 0)
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), (res1), \
(res2), 0, 0, 0)
#define ipc_call_sync_3_3(phoneid, method, arg1, arg2, arg3, res1, res2, \
res3) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
128,15 → 136,16
res3, res4, res5) \
ipc_call_sync_fast((phoneid), (method), (arg1), (arg2), (arg3), \
(res1), (res2), (res3), (res4), (res5))
 
#define ipc_call_sync_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
0, 0, 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
0, 0, 0, 0, 0)
#define ipc_call_sync_4_1(phoneid, method, arg1, arg2, arg3, arg4, res1) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
(res1), 0, 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
(res1), 0, 0, 0, 0)
#define ipc_call_sync_4_2(phoneid, method, arg1, arg2, arg3, arg4, res1, res2) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
(res1), (res2), 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), 0, \
(res1), (res2), 0, 0, 0)
#define ipc_call_sync_4_3(phoneid, method, arg1, arg2, arg3, arg4, res1, res2, \
res3) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
149,12 → 158,13
res3, res4, res5) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
(arg4), 0, (res1), (res2), (res3), (res4), (res5))
 
#define ipc_call_sync_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), 0, 0, 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), 0, 0, 0, 0, 0)
#define ipc_call_sync_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (res1), 0, 0, 0, 0)
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
(arg5), (res1), 0, 0, 0, 0)
#define ipc_call_sync_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, res1, \
res2) \
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \
181,10 → 191,12
 
extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int);
extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t);
 
static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data)
{
return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT);
}
 
extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *);
 
/*
194,17 → 206,17
* to m.
*/
#define ipc_answer_0(callid, retval) \
ipc_answer_fast((callid), (retval), 0, 0, 0, 0)
ipc_answer_fast((callid), (retval), 0, 0, 0, 0)
#define ipc_answer_1(callid, retval, arg1) \
ipc_answer_fast((callid), (retval), (arg1), 0, 0, 0)
ipc_answer_fast((callid), (retval), (arg1), 0, 0, 0)
#define ipc_answer_2(callid, retval, arg1, arg2) \
ipc_answer_fast((callid), (retval), (arg1), (arg2), 0, 0)
ipc_answer_fast((callid), (retval), (arg1), (arg2), 0, 0)
#define ipc_answer_3(callid, retval, arg1, arg2, arg3) \
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), 0)
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), 0)
#define ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4) \
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), (arg4))
ipc_answer_fast((callid), (retval), (arg1), (arg2), (arg3), (arg4))
#define ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5) \
ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5))
ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5))
 
extern ipcarg_t ipc_answer_fast(ipc_callid_t, ipcarg_t, ipcarg_t, ipcarg_t,
ipcarg_t, ipcarg_t);
246,8 → 258,6
extern void ipc_call_async_slow(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t,
ipcarg_t, ipcarg_t, void *, ipc_async_callback_t, int);
 
#define IPC_FLAG_BLOCKING 0x01
 
extern int ipc_connect_to_me(int, int, int, int, ipcarg_t *);
extern int ipc_connect_me_to(int, int, int, int);
extern int ipc_connect_me_to_blocking(int, int, int, int);
256,20 → 266,19
extern int ipc_unregister_irq(int, int);
extern int ipc_forward_fast(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, int);
extern int ipc_forward_slow(ipc_callid_t, int, int, ipcarg_t, ipcarg_t,
ipcarg_t, ipcarg_t, ipcarg_t, int);
ipcarg_t, ipcarg_t, ipcarg_t, int);
 
 
/*
* User-friendly wrappers for ipc_share_in_start().
*/
#define ipc_share_in_start_0_0(phoneid, dst, size) \
ipc_share_in_start((phoneid), (dst), (size), 0, NULL)
ipc_share_in_start((phoneid), (dst), (size), 0, NULL)
#define ipc_share_in_start_0_1(phoneid, dst, size, flags) \
ipc_share_in_start((phoneid), (dst), (size), 0, (flags))
ipc_share_in_start((phoneid), (dst), (size), 0, (flags))
#define ipc_share_in_start_1_0(phoneid, dst, size, arg) \
ipc_share_in_start((phoneid), (dst), (size), (arg), NULL)
ipc_share_in_start((phoneid), (dst), (size), (arg), NULL)
#define ipc_share_in_start_1_1(phoneid, dst, size, arg, flags) \
ipc_share_in_start((phoneid), (dst), (size), (arg), (flags))
ipc_share_in_start((phoneid), (dst), (size), (arg), (flags))
 
extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *);
extern int ipc_share_in_receive(ipc_callid_t *, size_t *);
284,8 → 293,6
extern int ipc_data_write_receive(ipc_callid_t *, size_t *);
extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t);
 
#include <task.h>
 
extern int ipc_connect_kbox(task_id_t);
 
#endif
/branches/network/uspace/lib/libc/include/ipc/devmap.h
33,11 → 33,14
#ifndef DEVMAP_DEVMAP_H_
#define DEVMAP_DEVMAP_H_
 
#include <atomic.h>
#include <ipc/ipc.h>
#include <libadt/list.h>
#include <adt/list.h>
 
#define DEVMAP_NAME_MAXLEN 512
#define DEVMAP_NAME_MAXLEN 255
 
typedef ipcarg_t dev_handle_t;
 
typedef enum {
DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
DEVMAP_DRIVER_UNREGISTER,
44,56 → 47,30
DEVMAP_DEVICE_REGISTER,
DEVMAP_DEVICE_UNREGISTER,
DEVMAP_DEVICE_GET_NAME,
DEVMAP_DEVICE_GET_HANDLE
DEVMAP_DEVICE_GET_HANDLE,
DEVMAP_DEVICE_GET_COUNT,
DEVMAP_DEVICE_GET_DEVICES
} devmap_request_t;
 
/** Representation of device driver.
* Each driver is responsible for a set of devices.
*/
typedef struct {
/** Pointers to previous and next drivers in linked list */
link_t drivers;
/** Pointer to the linked list of devices controlled by
* this driver */
link_t devices;
/** Phone asociated with this driver */
ipcarg_t phone;
/** Device driver name */
char *name;
/** Futex for list of devices owned by this driver */
atomic_t devices_futex;
} devmap_driver_t;
 
/** Info about registered device
/** Interface provided by devmap.
*
*/
typedef struct {
/** Pointer to the previous and next device in the list of all devices */
link_t devices;
/** Pointer to the previous and next device in the list of devices
owned by one driver */
link_t driver_devices;
/** Unique device identifier */
int handle;
/** Device name */
char *name;
/** Device driver handling this device */
devmap_driver_t *driver;
} devmap_device_t;
 
/** Interface provided by devmap.
* Every process that connects to devmap must ask one of following
* interfaces otherwise connection will be refused.
*
*/
typedef enum {
/** Connect as device driver */
DEVMAP_DRIVER = 1,
/** Connect as client */
/** Connect as device driver */
DEVMAP_DRIVER = 1,
/** Connect as client */
DEVMAP_CLIENT,
/** Create new connection to instance of device that
* is specified by second argument of call. */
/** Create new connection to instance of device that
is specified by second argument of call. */
DEVMAP_CONNECT_TO_DEVICE
} devmap_interface_t;
 
typedef struct {
dev_handle_t handle;
char name[DEVMAP_NAME_MAXLEN + 1];
} dev_desc_t;
 
#endif
 
/branches/network/uspace/lib/libc/include/ipc/vfs.h
0,0 → 1,147
/*
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libcipc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IPC_VFS_H_
#define LIBC_IPC_VFS_H_
 
#include <sys/types.h>
#include <ipc/ipc.h>
 
#define FS_NAME_MAXLEN 20
#define MAX_PATH_LEN (64 * 1024)
#define PLB_SIZE (2 * MAX_PATH_LEN)
 
/* Basic types. */
typedef int16_t fs_handle_t;
typedef uint32_t fs_index_t;
 
/**
* A structure like this is passed to VFS by each individual FS upon its
* registration. It assosiates a human-readable identifier with each
* registered FS.
*/
typedef struct {
/** Unique identifier of the fs. */
char name[FS_NAME_MAXLEN + 1];
} vfs_info_t;
 
typedef enum {
VFS_OPEN_NODE = IPC_FIRST_USER_METHOD,
VFS_READ,
VFS_WRITE,
VFS_TRUNCATE,
VFS_MOUNT,
VFS_UNMOUNT,
VFS_DEVICE,
VFS_SYNC,
VFS_CLOSE,
VFS_LAST_CMN /* keep this the last member of this enum */
} vfs_request_cmn_t;
 
typedef enum {
VFS_LOOKUP = VFS_LAST_CMN,
VFS_MOUNTED,
VFS_DESTROY,
VFS_LAST_CLNT /* keep this the last member of this enum */
} vfs_request_clnt_t;
 
typedef enum {
VFS_REGISTER = VFS_LAST_CMN,
VFS_OPEN,
VFS_SEEK,
VFS_MKDIR,
VFS_UNLINK,
VFS_RENAME,
VFS_NODE,
VFS_LAST_SRV /* keep this the last member of this enum */
} vfs_request_srv_t;
 
/*
* Lookup flags.
*/
 
/**
* No lookup flags used.
*/
#define L_NONE 0
 
/**
* Lookup will succeed only if the object is a regular file. If L_CREATE is
* specified, an empty file will be created. This flag is mutually exclusive
* with L_DIRECTORY.
*/
#define L_FILE 1
 
/**
* Lookup wil succeed only if the object is a directory. If L_CREATE is
* specified, an empty directory will be created. This flag is mutually
* exclusive with L_FILE.
*/
#define L_DIRECTORY 2
 
/**
* When used with L_CREATE, L_EXCLUSIVE will cause the lookup to fail if the
* object already exists. L_EXCLUSIVE is implied when L_DIRECTORY is used.
*/
#define L_EXCLUSIVE 4
 
/**
* L_CREATE is used for creating both regular files and directories.
*/
#define L_CREATE 8
 
/**
* L_LINK is used for linking to an already existing nodes.
*/
#define L_LINK 16
 
/**
* L_UNLINK is used to remove leaves from the file system namespace. This flag
* cannot be passed directly by the client, but will be set by VFS during
* VFS_UNLINK.
*/
#define L_UNLINK 32
 
/**
* L_OPEN is used to indicate that the lookup operation is a part of VFS_OPEN
* call from the client. This means that the server might allocate some
* resources for the opened file. This flag cannot be passed directly by the
* client.
*/
#define L_OPEN 64
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/ipc/ns.h
35,6 → 35,13
#ifndef LIBIPC_NS_H_
#define LIBIPC_NS_H_
 
#include <ipc/ipc.h>
 
typedef enum {
NS_PING = IPC_FIRST_USER_METHOD,
NS_TASK_WAIT
} ns_request_t;
 
#endif
 
/** @}
/branches/network/uspace/lib/libc/include/ipc/console.h
27,7 → 27,7
*/
 
/** @addtogroup libcipc
* @{
* @{
*/
/** @file
*/
36,15 → 36,13
#define LIBC_IPC_CONSOLE_H_
 
#include <ipc/ipc.h>
#include <ipc/vfs.h>
 
typedef enum {
CONSOLE_GETKEY = IPC_FIRST_USER_METHOD,
CONSOLE_PUTCHAR,
CONSOLE_WRITE,
CONSOLE_GET_SIZE = VFS_LAST_SRV,
CONSOLE_GET_EVENT,
CONSOLE_GOTO,
CONSOLE_CLEAR,
CONSOLE_GOTO,
CONSOLE_GETSIZE,
CONSOLE_FLUSH,
CONSOLE_SET_STYLE,
CONSOLE_SET_COLOR,
CONSOLE_SET_RGB_COLOR,
53,6 → 51,6
} console_request_t;
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/ipc/bd.h
0,0 → 1,48
/*
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libcipc
* @{
*/
/** @file
*/
 
#ifndef LIBC_IPC_BD_H_
#define LIBC_IPC_BD_H_
 
#include <ipc/ipc.h>
 
typedef enum {
BD_READ_BLOCK = IPC_FIRST_USER_METHOD,
BD_WRITE_BLOCK
} bd_request_t;
 
#endif
 
/** @}
*/
/branches/network/uspace/lib/libc/include/ipc/loader.h
42,6 → 42,7
LOADER_GET_TASKID,
LOADER_SET_PATHNAME,
LOADER_SET_ARGS,
LOADER_SET_FILES,
LOADER_LOAD,
LOADER_RUN
} loader_request_t;
/branches/network/uspace/lib/libc/include/errno.h
41,17 → 41,18
 
#include <kernel/errno.h>
 
#define ENAMETOOLONG (-256)
#define EISDIR (-257)
#define ENOTDIR (-258)
#define ENOSPC (-259)
#define EEXIST (-260)
#define ENOTEMPTY (-261)
#define EBADF (-262)
#define ERANGE (-263)
#define EXDEV (-264)
#define EIO (-265)
#define EMLINK (-266)
#define EMFILE (-17)
#define ENAMETOOLONG (-256)
#define EISDIR (-257)
#define ENOTDIR (-258)
#define ENOSPC (-259)
#define EEXIST (-260)
#define ENOTEMPTY (-261)
#define EBADF (-262)
#define ERANGE (-263)
#define EXDEV (-264)
#define EIO (-265)
#define EMLINK (-266)
 
#endif
 
/branches/network/uspace/lib/libc/Makefile.toolchain
26,10 → 26,11
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration \
-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32 -finput-charset=UTF-8 \
-Wmissing-prototypes -O3 -nostdlib -nostdinc -imacros \
$(LIBC_PREFIX)/../../../config.h -I$(LIBC_PREFIX)/include -pipe -g
CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-finput-charset=UTF-8 -fno-builtin -Wall -Wextra -Wno-unused-parameter \
-Wmissing-prototypes -Werror-implicit-function-declaration -nostdlib \
-nostdinc -pipe -g -D__$(ENDIANESS)__
LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a
AFLAGS =
 
/branches/network/uspace/lib/libc/generic/kbd.c
File deleted
/branches/network/uspace/lib/libc/generic/libadt/hash_table.c
File deleted
/branches/network/uspace/lib/libc/generic/libadt/list.c
File deleted
/branches/network/uspace/lib/libc/generic/console.c
File deleted
/branches/network/uspace/lib/libc/generic/ddi.c
127,10 → 127,10
}
#endif
 
phys = ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE);
phys = (void *) ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE);
offset = pio_addr - phys;
pages = ALIGN_UP(offset + size, PAGE_SIZE) >> PAGE_WIDTH;
virt = as_get_mappable_page(pages);
virt = as_get_mappable_page(pages << PAGE_WIDTH);
*use_addr = virt + offset;
return physmem_map(phys, virt, pages, AS_AREA_READ | AS_AREA_WRITE);
}
/branches/network/uspace/lib/libc/generic/task.c
31,7 → 31,7
* @{
*/
/** @file
*/
*/
 
#include <task.h>
#include <libc.h>
39,21 → 39,25
#include <errno.h>
#include <loader/loader.h>
#include <string.h>
#include <ipc/ns.h>
#include <macros.h>
#include <async.h>
 
task_id_t task_get_id(void)
{
task_id_t task_id;
 
(void) __SYSCALL1(SYS_TASK_GET_ID, (sysarg_t) &task_id);
 
return task_id;
}
 
/** Set the task name.
*
* @param name The new name, typically the command used to execute the
* program.
* @return Zero on success or negative error code.
* @param name The new name, typically the command used to execute the
* program.
*
* @return Zero on success or negative error code.
*
*/
int task_set_name(const char *name)
{
65,58 → 69,89
* This is really just a convenience wrapper over the more complicated
* loader API.
*
* @param path pathname of the binary to execute
* @param argv command-line arguments
* @return ID of the newly created task or zero on error.
* @param path pathname of the binary to execute
* @param argv command-line arguments
*
* @return ID of the newly created task or zero on error.
*
*/
task_id_t task_spawn(const char *path, char *const argv[])
task_id_t task_spawn(const char *path, char *const args[])
{
loader_t *ldr;
task_id_t task_id;
int rc;
 
/* Connect to a program loader. */
ldr = loader_connect();
loader_t *ldr = loader_connect();
if (ldr == NULL)
return 0;
 
/* Get task ID. */
rc = loader_get_task_id(ldr, &task_id);
task_id_t task_id;
int rc = loader_get_task_id(ldr, &task_id);
if (rc != EOK)
goto error;
 
/* Send program pathname. */
rc = loader_set_pathname(ldr, path);
if (rc != EOK)
goto error;
 
/* Send arguments. */
rc = loader_set_args(ldr, argv);
rc = loader_set_args(ldr, args);
if (rc != EOK)
goto error;
 
/* Send default files */
fdi_node_t *files[4];
fdi_node_t stdin_node;
fdi_node_t stdout_node;
fdi_node_t stderr_node;
if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK))
files[0] = &stdin_node;
else
files[0] = NULL;
if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK))
files[1] = &stdout_node;
else
files[1] = NULL;
if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK))
files[2] = &stderr_node;
else
files[2] = NULL;
files[3] = NULL;
rc = loader_set_files(ldr, files);
if (rc != EOK)
goto error;
/* Load the program. */
rc = loader_load_program(ldr);
if (rc != EOK)
goto error;
 
/* Run it. */
rc = loader_run(ldr);
if (rc != EOK)
goto error;
 
/* Success */
 
free(ldr);
return task_id;
 
error:
/* Error exit */
error:
loader_abort(ldr);
free(ldr);
 
return 0;
}
 
int task_wait(task_id_t id)
{
return (int) async_req_2_0(PHONE_NS, NS_TASK_WAIT, LOWER32(id), UPPER32(id));
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/fibril_sync.c
0,0 → 1,219
/*
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <fibril_sync.h>
#include <fibril.h>
#include <async.h>
#include <adt/list.h>
#include <futex.h>
#include <assert.h>
 
void fibril_mutex_initialize(fibril_mutex_t *fm)
{
fm->counter = 1;
list_initialize(&fm->waiters);
}
 
void fibril_mutex_lock(fibril_mutex_t *fm)
{
futex_down(&async_futex);
if (fm->counter-- <= 0) {
fibril_t *f = (fibril_t *) fibril_get_id();
list_append(&f->link, &fm->waiters);
fibril_switch(FIBRIL_TO_MANAGER);
} else {
futex_up(&async_futex);
}
}
 
bool fibril_mutex_trylock(fibril_mutex_t *fm)
{
bool locked = false;
futex_down(&async_futex);
if (fm->counter > 0) {
fm->counter--;
locked = true;
}
futex_up(&async_futex);
return locked;
}
 
static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm)
{
assert(fm->counter <= 0);
if (fm->counter++ < 0) {
link_t *tmp;
fibril_t *f;
assert(!list_empty(&fm->waiters));
tmp = fm->waiters.next;
f = list_get_instance(tmp, fibril_t, link);
list_remove(&f->link);
fibril_add_ready((fid_t) f);
}
}
 
void fibril_mutex_unlock(fibril_mutex_t *fm)
{
futex_down(&async_futex);
_fibril_mutex_unlock_unsafe(fm);
futex_up(&async_futex);
}
 
void fibril_rwlock_initialize(fibril_rwlock_t *frw)
{
frw->writers = 0;
frw->readers = 0;
list_initialize(&frw->waiters);
}
 
void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
{
futex_down(&async_futex);
if (frw->writers) {
fibril_t *f = (fibril_t *) fibril_get_id();
f->flags &= ~FIBRIL_WRITER;
list_append(&f->link, &frw->waiters);
fibril_switch(FIBRIL_TO_MANAGER);
} else {
frw->readers++;
futex_up(&async_futex);
}
}
 
void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
{
futex_down(&async_futex);
if (frw->writers || frw->readers) {
fibril_t *f = (fibril_t *) fibril_get_id();
f->flags |= FIBRIL_WRITER;
list_append(&f->link, &frw->waiters);
fibril_switch(FIBRIL_TO_MANAGER);
} else {
frw->writers++;
futex_up(&async_futex);
}
}
 
static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw)
{
futex_down(&async_futex);
assert(frw->readers || (frw->writers == 1));
if (frw->readers) {
if (--frw->readers)
goto out;
} else {
frw->writers--;
}
assert(!frw->readers && !frw->writers);
while (!list_empty(&frw->waiters)) {
link_t *tmp = frw->waiters.next;
fibril_t *f = list_get_instance(tmp, fibril_t, link);
if (f->flags & FIBRIL_WRITER) {
if (frw->readers)
break;
list_remove(&f->link);
fibril_add_ready((fid_t) f);
frw->writers++;
break;
} else {
list_remove(&f->link);
fibril_add_ready((fid_t) f);
frw->readers++;
}
}
out:
futex_up(&async_futex);
}
 
void fibril_rwlock_read_unlock(fibril_rwlock_t *frw)
{
_fibril_rwlock_common_unlock(frw);
}
 
void fibril_rwlock_write_unlock(fibril_rwlock_t *frw)
{
_fibril_rwlock_common_unlock(frw);
}
 
void fibril_condvar_initialize(fibril_condvar_t *fcv)
{
list_initialize(&fcv->waiters);
}
 
void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm)
{
fibril_t *f = (fibril_t *) fibril_get_id();
 
futex_down(&async_futex);
list_append(&f->link, &fcv->waiters);
_fibril_mutex_unlock_unsafe(fm);
fibril_switch(FIBRIL_TO_MANAGER);
fibril_mutex_lock(fm);
}
 
static void _fibril_condvar_wakeup_common(fibril_condvar_t *fcv, bool once)
{
link_t *tmp;
fibril_t *f;
 
futex_down(&async_futex);
while (!list_empty(&fcv->waiters)) {
tmp = fcv->waiters.next;
f = list_get_instance(tmp, fibril_t, link);
list_remove(&f->link);
fibril_add_ready((fid_t) f);
if (once)
break;
}
futex_up(&async_futex);
}
 
void fibril_condvar_signal(fibril_condvar_t *fcv)
{
_fibril_condvar_wakeup_common(fcv, true);
}
 
void fibril_condvar_broadcast(fibril_condvar_t *fcv)
{
_fibril_condvar_wakeup_common(fcv, false);
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/as.c
30,7 → 30,7
* @{
*/
/** @file
*/
*/
 
#include <as.h>
#include <libc.h>
102,7 → 102,7
static size_t heapsize = 0;
static size_t maxheapsize = (size_t) (-1);
 
static void * last_allocated = 0;
static void *last_allocated = 0;
 
/* Start of heap linker symbol */
extern char _heap;
119,15 → 119,15
void *res;
/* Check for invalid values */
if (incr < 0 && -incr > heapsize)
if ((incr < 0) && (((size_t) -incr) > heapsize))
return NULL;
/* Check for too large value */
if (incr > 0 && incr+heapsize < heapsize)
if ((incr > 0) && (incr + heapsize < heapsize))
return NULL;
/* Check for too small values */
if (incr < 0 && incr+heapsize > heapsize)
if ((incr < 0) && (incr + heapsize > heapsize))
return NULL;
/* Check for user limit */
175,7 → 175,7
asz = 1 << (fnzb64(sz - 1) + 1);
 
/* Set heapsize to some meaningful value */
if (maxheapsize == -1)
if (maxheapsize == (size_t) -1)
set_maxheapsize(MAX_HEAP_SIZE);
/*
/branches/network/uspace/lib/libc/generic/string.c
138,8 → 138,8
* @param size Size of the output buffer (in bytes).
*
* @return EOK if the character was encoded successfully, EOVERFLOW if there
* was not enough space in the output buffer or EINVAL if the character
* code was invalid.
* was not enough space in the output buffer or EINVAL if the character
* code was invalid.
*/
int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
{
243,9 → 243,9
* @return Number of bytes used by the characters.
*
*/
size_t str_lsize(const char *str, count_t max_len)
size_t str_lsize(const char *str, size_t max_len)
{
count_t len = 0;
size_t len = 0;
size_t offset = 0;
while (len < max_len) {
271,7 → 271,7
* @return Number of bytes used by the wide characters.
*
*/
size_t wstr_lsize(const wchar_t *str, count_t max_len)
size_t wstr_lsize(const wchar_t *str, size_t max_len)
{
return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
}
283,9 → 283,9
* @return Number of characters in string.
*
*/
count_t str_length(const char *str)
size_t str_length(const char *str)
{
count_t len = 0;
size_t len = 0;
size_t offset = 0;
while (str_decode(str, &offset, STR_NO_LIMIT) != 0)
301,9 → 301,9
* @return Number of characters in @a str.
*
*/
count_t wstr_length(const wchar_t *wstr)
size_t wstr_length(const wchar_t *wstr)
{
count_t len = 0;
size_t len = 0;
while (*wstr++ != 0)
len++;
319,9 → 319,9
* @return Number of characters in string.
*
*/
count_t str_nlength(const char *str, size_t size)
size_t str_nlength(const char *str, size_t size)
{
count_t len = 0;
size_t len = 0;
size_t offset = 0;
while (str_decode(str, &offset, size) != 0)
338,11 → 338,11
* @return Number of characters in string.
*
*/
count_t wstr_nlength(const wchar_t *str, size_t size)
size_t wstr_nlength(const wchar_t *str, size_t size)
{
count_t len = 0;
count_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
count_t offset = 0;
size_t len = 0;
size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
size_t offset = 0;
while ((offset < limit) && (*str++ != 0)) {
len++;
430,7 → 430,7
* 1 if second smaller.
*
*/
int str_lcmp(const char *s1, const char *s2, count_t max_len)
int str_lcmp(const char *s1, const char *s2, size_t max_len)
{
wchar_t c1 = 0;
wchar_t c2 = 0;
438,7 → 438,7
size_t off1 = 0;
size_t off2 = 0;
count_t len = 0;
size_t len = 0;
 
while (true) {
if (len >= max_len)
568,7 → 568,7
return;
wchar_t ch;
count_t src_idx = 0;
size_t src_idx = 0;
size_t dst_off = 0;
while ((ch = src[src_idx++]) != 0) {
616,7 → 616,7
wchar_t acc;
size_t off = 0;
size_t last = 0;
char *res = NULL;
const char *res = NULL;
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
641,14 → 641,14
* is out of bounds.
*
*/
bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos)
bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
{
count_t len = wstr_length(str);
size_t len = wstr_length(str);
if ((pos > len) || (pos + 1 > max_pos))
return false;
count_t i;
size_t i;
for (i = len; i + 1 > pos; i--)
str[i + 1] = str[i];
669,14 → 669,14
* is out of bounds.
*
*/
bool wstr_remove(wchar_t *str, count_t pos)
bool wstr_remove(wchar_t *str, size_t pos)
{
count_t len = wstr_length(str);
size_t len = wstr_length(str);
if (pos >= len)
return false;
count_t i;
size_t i;
for (i = pos + 1; i <= len; i++)
str[i - 1] = str[i];
/branches/network/uspace/lib/libc/generic/loader.c
30,7 → 30,7
* @{
*/
/** @file
*/
*/
 
#include <ipc/ipc.h>
#include <ipc/loader.h>
47,9 → 47,12
/** Connect to a new program loader.
*
* Spawns a new program loader task and returns the connection structure.
* @param name Symbolic name to set on the newly created task.
* @return Pointer to the loader connection structure (should be
* de-allocated using free() after use).
*
* @param name Symbolic name to set on the newly created task.
*
* @return Pointer to the loader connection structure (should be
* deallocated using free() after use).
*
*/
int loader_spawn(const char *name)
{
59,19 → 62,16
 
loader_t *loader_connect(void)
{
loader_t *ldr;
int phone_id;
 
phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0);
int phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0);
if (phone_id < 0)
return NULL;
 
ldr = malloc(sizeof(loader_t));
loader_t *ldr = malloc(sizeof(loader_t));
if (ldr == NULL)
return NULL;
 
ldr->phone_id = phone_id;
return ldr;
return ldr;
}
 
/** Get ID of the new task.
78,27 → 78,26
*
* Retrieves the ID of the new task from the loader.
*
* @param ldr Loader connection structure.
* @param task_id Points to a variable where the ID should be stored.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
* @param task_id Points to a variable where the ID should be stored.
*
* @return Zero on success or negative error code.
*
*/
int loader_get_task_id(loader_t *ldr, task_id_t *task_id)
{
/* Get task ID. */
ipc_call_t answer;
aid_t req;
int rc;
ipcarg_t retval;
 
/* Get task ID. */
req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
 
ipcarg_t retval;
async_wait_for(req, &retval);
return (int)retval;
return (int) retval;
}
 
/** Set pathname of the program to load.
107,39 → 106,35
* to the current working directory (it will be absolutized before
* sending to the loader).
*
* @param ldr Loader connection structure.
* @param path Pathname of the program file.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
* @param path Pathname of the program file.
*
* @return Zero on success or negative error code.
*
*/
int loader_set_pathname(loader_t *ldr, const char *path)
{
ipc_call_t answer;
aid_t req;
int rc;
ipcarg_t retval;
 
char *pa;
size_t pa_len;
 
pa = absolutize(path, &pa_len);
char *pa = absolutize(path, &pa_len);
if (!pa)
return 0;
 
/* Send program pathname */
req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
rc = ipc_data_write_start(ldr->phone_id, (void *)pa, pa_len);
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len);
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
 
free(pa);
 
ipcarg_t retval;
async_wait_for(req, &retval);
return (int)retval;
return (int) retval;
}
 
 
/** Set command-line arguments for the program.
*
* Sets the vector of command-line arguments to be passed to the loaded
146,61 → 141,110
* program. By convention, the very first argument is typically the same as
* the command used to execute the program.
*
* @param ldr Loader connection structure.
* @param argv NULL-terminated array of pointers to arguments.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
* @param argv NULL-terminated array of pointers to arguments.
*
* @return Zero on success or negative error code.
*
*/
int loader_set_args(loader_t *ldr, char *const argv[])
{
aid_t req;
ipc_call_t answer;
ipcarg_t rc;
 
char *const *ap;
char *dp;
char *arg_buf;
size_t buffer_size;
 
/*
/*
* Serialize the arguments into a single array. First
* compute size of the buffer needed.
*/
ap = argv;
buffer_size = 0;
char *const *ap = argv;
size_t buffer_size = 0;
while (*ap != NULL) {
buffer_size += str_size(*ap) + 1;
++ap;
ap++;
}
 
arg_buf = malloc(buffer_size);
if (arg_buf == NULL) return ENOMEM;
 
char *arg_buf = malloc(buffer_size);
if (arg_buf == NULL)
return ENOMEM;
/* Now fill the buffer with null-terminated argument strings */
ap = argv;
dp = arg_buf;
 
char *dp = arg_buf;
while (*ap != NULL) {
str_cpy(dp, buffer_size - (dp - arg_buf), *ap);
dp += str_size(*ap) + 1;
 
++ap;
ap++;
}
 
/* Send serialized arguments to the loader */
 
req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
rc = ipc_data_write_start(ldr->phone_id, (void *)arg_buf, buffer_size);
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
 
async_wait_for(req, &rc);
if (rc != EOK) return rc;
 
if (rc != EOK)
return rc;
/* Free temporary buffer */
free(arg_buf);
return EOK;
}
 
/** Set preset files for the program.
*
* Sets the vector of preset files to be passed to the loaded
* program. By convention, the first three files represent stdin,
* stdout and stderr respectively.
*
* @param ldr Loader connection structure.
* @param files NULL-terminated array of pointers to files.
*
* @return Zero on success or negative error code.
*
*/
int loader_set_files(loader_t *ldr, fdi_node_t *const files[])
{
/*
* Serialize the arguments into a single array. First
* compute size of the buffer needed.
*/
fdi_node_t *const *ap = files;
size_t count = 0;
while (*ap != NULL) {
count++;
ap++;
}
fdi_node_t *files_buf;
files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t));
if (files_buf == NULL)
return ENOMEM;
/* Fill the buffer */
size_t i;
for (i = 0; i < count; i++)
files_buf[i] = *files[i];
/* Send serialized files to the loader */
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf,
count * sizeof(fdi_node_t));
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
/* Free temporary buffer */
free(files_buf);
return EOK;
}
 
209,18 → 253,14
* If this function succeeds, the program has been successfully loaded
* and is ready to be executed.
*
* @param ldr Loader connection structure.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
int loader_load_program(loader_t *ldr)
{
int rc;
 
rc = async_req_0_0(ldr->phone_id, LOADER_LOAD);
if (rc != EOK)
return rc;
 
return EOK;
return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
}
 
/** Instruct loader to execute the program.
232,17 → 272,17
* After using this function, no further operations must be performed
* on the loader structure. It should be de-allocated using free().
*
* @param ldr Loader connection structure.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
int loader_run(loader_t *ldr)
{
int rc;
 
rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
if (rc != EOK)
return rc;
 
ipc_hangup(ldr->phone_id);
ldr->phone_id = 0;
return EOK;
254,8 → 294,10
* After using this function, no further operations must be performed
* on the loader structure. It should be de-allocated using free().
*
* @param ldr Loader connection structure.
* @return Zero on success or negative error code.
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
void loader_abort(loader_t *ldr)
{
/branches/network/uspace/lib/libc/generic/fibril.c
33,7 → 33,7
/** @file
*/
 
#include <libadt/list.h>
#include <adt/list.h>
#include <fibril.h>
#include <thread.h>
#include <tls.h>
49,7 → 49,8
#define FIBRIL_INITIAL_STACK_PAGES_NO 1
#endif
 
/** This futex serializes access to ready_list, serialized_list and manage_list.
/**
* This futex serializes access to ready_list, serialized_list and manager_list.
*/
static atomic_t fibril_futex = FUTEX_INITIALIZER;
 
59,12 → 60,12
 
static void fibril_main(void);
 
/** Number of fibrils that are in async_serialized mode */
static int serialized_fibrils; /* Protected by async_futex */
/** Thread-local count of serialization. If >0, we must not preempt */
static __thread int serialization_count;
/** Counter for fibrils residing in async_manager */
static int fibrils_in_manager;
/** Number of threads that are executing a manager fibril. */
static int threads_in_manager;
/** Number of threads that are executing a manager fibril and are serialized. */
static int serialized_threads; /* Protected by async_futex */
/** Fibril-local count of serialization. If > 0, we must not preempt */
static fibril_local int serialization_count;
 
/** Setup fibril information into TCB structure */
fibril_t *fibril_setup(void)
143,11 → 144,11
if (list_empty(&ready_list) && list_empty(&serialized_list))
goto ret_0;
/*
* Do not preempt if there is not sufficient count of fibril
* managers.
* Do not preempt if there is not enough threads to run the
* ready fibrils which are not serialized.
*/
if (list_empty(&serialized_list) &&
fibrils_in_manager <= serialized_fibrils) {
threads_in_manager <= serialized_threads) {
goto ret_0;
}
}
194,7 → 195,7
list_append(&srcf->link, &ready_list);
else if (stype == FIBRIL_FROM_MANAGER) {
list_append(&srcf->link, &manager_list);
fibrils_in_manager--;
threads_in_manager--;
} else {
/*
* If stype == FIBRIL_TO_MANAGER, don't put ourselves to
208,10 → 209,10
if (stype == FIBRIL_TO_MANAGER || stype == FIBRIL_FROM_DEAD) {
dstf = list_get_instance(manager_list.next, fibril_t, link);
if (serialization_count && stype == FIBRIL_TO_MANAGER) {
serialized_fibrils++;
serialized_threads++;
srcf->flags |= FIBRIL_SERIALIZED;
}
fibrils_in_manager++;
threads_in_manager++;
 
if (stype == FIBRIL_FROM_DEAD)
dstf->clean_after_me = srcf;
219,7 → 220,7
if (!list_empty(&serialized_list)) {
dstf = list_get_instance(serialized_list.next, fibril_t,
link);
serialized_fibrils--;
serialized_threads--;
} else {
dstf = list_get_instance(ready_list.next, fibril_t,
link);
269,7 → 270,7
 
/** Add a fibril to the ready list.
*
* @param fid Pinter to the fibril structure of the fibril to be
* @param fid Pointer to the fibril structure of the fibril to be
* added.
*/
void fibril_add_ready(fid_t fid)
287,7 → 288,8
 
/** Add a fibril to the manager list.
*
* @param fid Pinter to the fibril structure of the fibril to be added.
* @param fid Pointer to the fibril structure of the fibril to be
* added.
*/
void fibril_add_manager(fid_t fid)
{
314,7 → 316,8
 
/** Return fibril id of the currently running fibril.
*
* @return Fibril ID of the currently running pseudo thread.
* @return fibril ID of the currently running fibril.
*
*/
fid_t fibril_get_id(void)
{
321,13 → 324,14
return (fid_t) __tcb_get()->fibril_data;
}
 
/** Disable preemption
/** Disable preemption
*
* If the fibril wants to send several message in a row and does not want to be
* preempted, it should start async_serialize_start() in the beginning of
* communication and async_serialize_end() in the end. If it is a true
* multithreaded application, it should protect the communication channel by a
* futex as well. Interrupt messages can still be preempted.
* futex as well.
*
*/
void fibril_inc_sercount(void)
{
/branches/network/uspace/lib/libc/generic/libc.c
27,28 → 27,29
*/
 
/** @addtogroup lc Libc
* @brief HelenOS C library
* @brief HelenOS C library
* @{
* @}
*/
 
/** @addtogroup libc generic
* @ingroup lc
* @{
*/
 
/** @file
*/
*/
 
#include <libc.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <tls.h>
#include <thread.h>
#include <fibril.h>
#include <io/stream.h>
#include <ipc/ipc.h>
#include <async.h>
#include <as.h>
#include <console.h>
#include <loader/pcb.h>
 
extern char _heap;
63,28 → 64,30
 
void __main(void *pcb_ptr)
{
fibril_t *f;
int argc;
char **argv;
 
(void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ);
_async_init();
f = fibril_setup();
__tcb_set(f->tcb);
fibril_t *fibril = fibril_setup();
__tcb_set(fibril->tcb);
/* Save the PCB pointer */
__pcb = (pcb_t *)pcb_ptr;
 
__pcb = (pcb_t *) pcb_ptr;
int argc;
char **argv;
if (__pcb == NULL) {
argc = 0;
argv = NULL;
stdio_init(0, NULL);
} else {
argc = __pcb->argc;
argv = __pcb->argv;
stdio_init(__pcb->filc, __pcb->filv);
}
 
main(argc, argv);
console_flush();
stdio_done();
}
 
void __exit(void)
/branches/network/uspace/lib/libc/generic/ipc.c
43,7 → 43,7
#include <libc.h>
#include <malloc.h>
#include <errno.h>
#include <libadt/list.h>
#include <adt/list.h>
#include <stdio.h>
#include <unistd.h>
#include <futex.h>
232,7 → 232,7
return;
}
 
if (callid == IPC_CALLRET_FATAL) {
if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
futex_up(&ipc_futex);
/* Call asynchronous handler with error code */
if (call->callback)
241,7 → 241,7
return;
}
 
if (callid == IPC_CALLRET_TEMPORARY) {
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
futex_up(&ipc_futex);
 
call->u.msg.phoneid = phoneid;
309,7 → 309,7
callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1,
arg2, arg3, arg4);
 
if (callid == IPC_CALLRET_TEMPORARY) {
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
if (!call) {
call = ipc_prepare_async(private, callback);
if (!call)
442,7 → 442,7
call = list_get_instance(queued_calls.next, async_call_t, list);
callid = _ipc_call_async(call->u.msg.phoneid,
&call->u.msg.data);
if (callid == IPC_CALLRET_TEMPORARY) {
if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
break;
}
list_remove(&call->list);
451,7 → 451,7
if (call->fid)
fibril_add_ready(call->fid);
if (callid == IPC_CALLRET_FATAL) {
if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
if (call->callback)
call->callback(call->private, ENOENT, NULL);
free(call);
704,7 → 704,7
IPC_SET_ARG4(data, arg4);
IPC_SET_ARG5(data, arg5);
 
return __SYSCALL3(SYS_IPC_FORWARD_SLOW, callid, (sysarg_t) &data, mode);
return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, mode);
}
 
/** Wrapper for making IPC_M_SHARE_IN calls.
/branches/network/uspace/lib/libc/generic/devmap.c
0,0 → 1,264
/*
* Copyright (c) 2007 Josef Cejka
* Copyright (c) 2009 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <string.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/devmap.h>
#include <devmap.h>
#include <async.h>
#include <errno.h>
 
static int devmap_phone_driver = -1;
static int devmap_phone_client = -1;
 
/** Get phone to device mapper task. */
int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
{
switch (iface) {
case DEVMAP_DRIVER:
if (devmap_phone_driver >= 0)
return devmap_phone_driver;
if (flags & IPC_FLAG_BLOCKING)
devmap_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
else
devmap_phone_driver = ipc_connect_me_to(PHONE_NS,
SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
return devmap_phone_driver;
case DEVMAP_CLIENT:
if (devmap_phone_client >= 0)
return devmap_phone_client;
if (flags & IPC_FLAG_BLOCKING)
devmap_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
else
devmap_phone_client = ipc_connect_me_to(PHONE_NS,
SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
return devmap_phone_client;
default:
return -1;
}
}
 
void devmap_hangup_phone(devmap_interface_t iface)
{
switch (iface) {
case DEVMAP_DRIVER:
if (devmap_phone_driver >= 0) {
ipc_hangup(devmap_phone_driver);
devmap_phone_driver = -1;
}
break;
case DEVMAP_CLIENT:
if (devmap_phone_client >= 0) {
ipc_hangup(devmap_phone_client);
devmap_phone_client = -1;
}
break;
default:
break;
}
}
 
/** Register new driver with devmap. */
int devmap_driver_register(const char *name, async_client_conn_t conn)
{
int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
if (phone < 0)
return phone;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
if (retval != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return -1;
}
async_set_client_connection(conn);
ipcarg_t callback_phonehash;
ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
async_wait_for(req, &retval);
async_serialize_end();
return retval;
}
 
/** Register new device.
*
* @param name Device name.
* @param handle Output: Handle to the created instance of device.
*
*/
int devmap_device_register(const char *name, dev_handle_t *handle)
{
int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
if (phone < 0)
return phone;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
&answer);
ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
if (retval != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return retval;
}
async_wait_for(req, &retval);
async_serialize_end();
if (retval != EOK) {
if (handle != NULL)
*handle = -1;
return retval;
}
if (handle != NULL)
*handle = (dev_handle_t) IPC_GET_ARG1(answer);
return retval;
}
 
int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
if (phone < 0)
return phone;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
&answer);
ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
if (retval != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return retval;
}
async_wait_for(req, &retval);
async_serialize_end();
if (retval != EOK) {
if (handle != NULL)
*handle = (dev_handle_t) -1;
return retval;
}
if (handle != NULL)
*handle = (dev_handle_t) IPC_GET_ARG1(answer);
return retval;
}
 
int devmap_device_connect(dev_handle_t handle, unsigned int flags)
{
int phone;
if (flags & IPC_FLAG_BLOCKING) {
phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_CONNECT_TO_DEVICE, handle);
} else {
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
DEVMAP_CONNECT_TO_DEVICE, handle);
}
return phone;
}
 
ipcarg_t devmap_device_get_count(void)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return 0;
ipcarg_t count;
int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
if (retval != EOK)
return 0;
return count;
}
 
ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return 0;
async_serialize_start();
ipc_call_t answer;
aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
if (retval != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
return 0;
}
async_wait_for(req, &retval);
async_serialize_end();
if (retval != EOK)
return 0;
return IPC_GET_ARG1(answer);
}
/branches/network/uspace/lib/libc/generic/async.c
95,8 → 95,8
#include <async.h>
#include <fibril.h>
#include <stdio.h>
#include <libadt/hash_table.h>
#include <libadt/list.h>
#include <adt/hash_table.h>
#include <adt/list.h>
#include <ipc/ipc.h>
#include <assert.h>
#include <errno.h>
174,7 → 174,7
} connection_t;
 
/** Identifier of the incoming connection handled by the current fibril. */
__thread connection_t *FIBRIL_connection;
fibril_local connection_t *FIBRIL_connection;
 
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
190,11 → 190,9
*/
static async_client_conn_t interrupt_received = default_interrupt_received;
 
 
static hash_table_t conn_hash_table;
static LIST_INITIALIZE(timeout_list);
 
 
#define CONN_HASH_TABLE_CHAINS 32
 
/** Compute hash into the connection hash table based on the source phone hash.
500,9 → 498,10
/* Answer all remaining messages with EHANGUP */
while (!list_empty(&FIBRIL_connection->msg_queue)) {
msg_t *msg
= list_get_instance(FIBRIL_connection->msg_queue.next, msg_t, link);
msg_t *msg;
msg = list_get_instance(FIBRIL_connection->msg_queue.next,
msg_t, link);
list_remove(&msg->link);
ipc_answer_0(msg->callid, EHANGUP);
free(msg);
563,7 → 562,7
}
/* Add connection to the connection hash table */
ipcarg_t key = conn->in_phone_hash;
unsigned long key = conn->in_phone_hash;
futex_down(&async_futex);
hash_table_insert(&conn_hash_table, &key, &conn->link);
588,23 → 587,28
/* Unrouted call - do some default behaviour */
if ((callid & IPC_CALLID_NOTIFICATION)) {
process_notification(callid, call);
return;
goto out;
}
switch (IPC_GET_METHOD(*call)) {
case IPC_M_CONNECT_ME:
case IPC_M_CONNECT_ME_TO:
/* Open new connection with fibril etc. */
async_new_connection(IPC_GET_ARG5(*call), callid, call,
client_connection);
return;
goto out;
}
/* Try to route the call through the connection hash table */
if (route_call(callid, call))
return;
goto out;
/* Unknown call from unknown phone - hang it up */
ipc_answer_0(callid, EHANGUP);
return;
out:
;
}
 
/** Fire all timeouts that expired. */
662,8 → 666,8
suseconds_t timeout;
if (!list_empty(&timeout_list)) {
awaiter_t *waiter
= list_get_instance(timeout_list.next, awaiter_t, link);
awaiter_t *waiter = list_get_instance(timeout_list.next,
awaiter_t, link);
struct timeval tv;
gettimeofday(&tv, NULL);
680,8 → 684,8
futex_up(&async_futex);
ipc_call_t call;
ipc_callid_t callid
= ipc_wait_cycle(&call, timeout, SYNCH_FLAGS_NONE);
ipc_callid_t callid = ipc_wait_cycle(&call, timeout,
SYNCH_FLAGS_NONE);
if (!callid) {
handle_expired_timeouts();
758,13 → 762,13
*/
static void reply_received(void *arg, int retval, ipc_call_t *data)
{
futex_down(&async_futex);
amsg_t *msg = (amsg_t *) arg;
msg->retval = retval;
futex_down(&async_futex);
/* Copy data after futex_down, just in case the call was detached */
if (msg->dataptr)
if ((msg->dataptr) && (data))
*msg->dataptr = *data;
write_barrier();
810,6 → 814,7
msg->done = false;
msg->dataptr = dataptr;
msg->wdata.inlist = false;
/* We may sleep in the next method, but it will use its own mechanism */
msg->wdata.active = true;
849,6 → 854,7
msg->done = false;
msg->dataptr = dataptr;
msg->wdata.inlist = false;
/* We may sleep in next method, but it will use its own mechanism */
msg->wdata.active = true;
/branches/network/uspace/lib/libc/generic/vfs/vfs.c
48,13 → 48,14
#include <futex.h>
#include <errno.h>
#include <string.h>
#include <devmap.h>
#include <ipc/vfs.h>
#include <ipc/devmap.h>
#include "../../../srv/vfs/vfs.h"
 
int vfs_phone = -1;
futex_t vfs_phone_futex = FUTEX_INITIALIZER;
static int vfs_phone = -1;
static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
static futex_t cwd_futex = FUTEX_INITIALIZER;
 
futex_t cwd_futex = FUTEX_INITIALIZER;
DIR *cwd_dir = NULL;
char *cwd_path = NULL;
size_t cwd_size = 0;
115,47 → 116,8
vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
}
 
static int device_get_handle(const char *name, dev_handle_t *handle,
const unsigned int flags)
{
int phone;
if (flags & IPC_FLAG_BLOCKING)
phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
else
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
if (phone < 0)
return phone;
ipc_call_t answer;
aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
&answer);
ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
if (retval != EOK) {
async_wait_for(req, NULL);
ipc_hangup(phone);
return retval;
}
async_wait_for(req, &retval);
if (handle != NULL)
*handle = -1;
if (retval == EOK) {
if (handle != NULL)
*handle = (dev_handle_t) IPC_GET_ARG1(answer);
}
ipc_hangup(phone);
return retval;
}
 
int mount(const char *fs_name, const char *mp, const char *dev,
const char *opts, const unsigned int flags)
const char *opts, unsigned int flags)
{
int res;
ipcarg_t rc;
162,7 → 124,7
aid_t req;
dev_handle_t dev_handle;
res = device_get_handle(dev, &dev_handle, flags);
res = devmap_device_get_handle(dev, &dev_handle, flags);
if (res != EOK)
return res;
249,9 → 211,10
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
 
if (rc != EOK)
return (int) rc;
return (int) IPC_GET_ARG1(answer);
}
 
260,6 → 223,27
return _open(path, L_FILE, oflag);
}
 
int open_node(fdi_node_t *node, int oflag)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipc_call_t answer;
aid_t req = async_send_4(vfs_phone, VFS_OPEN_NODE, node->fs_handle,
node->dev_handle, node->index, oflag, &answer);
ipcarg_t rc;
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
if (rc != EOK)
return (int) rc;
return (int) IPC_GET_ARG1(answer);
}
 
int close(int fildes)
{
ipcarg_t rc;
330,6 → 314,62
return -1;
}
 
int fd_phone(int fildes)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t device;
ipcarg_t rc = async_req_1_1(vfs_phone, VFS_DEVICE, fildes, &device);
async_serialize_end();
futex_up(&vfs_phone_futex);
if (rc != EOK)
return -1;
return devmap_device_connect((dev_handle_t) device, 0);
}
 
int fd_node(int fildes, fdi_node_t *node)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t fs_handle;
ipcarg_t dev_handle;
ipcarg_t index;
ipcarg_t rc = async_req_1_3(vfs_phone, VFS_NODE, fildes, &fs_handle,
&dev_handle, &index);
async_serialize_end();
futex_up(&vfs_phone_futex);
if (rc == EOK) {
node->fs_handle = (fs_handle_t) fs_handle;
node->dev_handle = (dev_handle_t) dev_handle;
node->index = (fs_index_t) index;
}
return rc;
}
 
int fsync(int fildes)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t rc = async_req_1_0(vfs_phone, VFS_SYNC, fildes);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (int) rc;
}
 
off_t lseek(int fildes, off_t offset, int whence)
{
ipcarg_t rc;
425,7 → 465,7
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return rc;
return rc;
}
 
static int _unlink(const char *path, int lflag)
455,7 → 495,7
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return rc;
return rc;
}
 
int unlink(const char *path)
/branches/network/uspace/lib/libc/generic/mem.c
95,7 → 95,7
 
static void *unaligned_memcpy(void *dst, const void *src, size_t n)
{
int i, j;
size_t i, j;
struct along *adst = dst;
const struct along *asrc = src;
 
/branches/network/uspace/lib/libc/generic/io/sprintf.c
File deleted
/branches/network/uspace/lib/libc/generic/io/vsprintf.c
File deleted
/branches/network/uspace/lib/libc/generic/io/fprintf.c
File deleted
/branches/network/uspace/lib/libc/generic/io/stream.c
File deleted
/branches/network/uspace/lib/libc/generic/io/stdio.c
File deleted
/branches/network/uspace/lib/libc/generic/io/printf.c
34,23 → 34,43
 
#include <io/printf_core.h>
#include <stdio.h>
#include <stdio.h>
 
/** Print formatted text.
* @param fmt format string
*
* @param stream Output stream
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int fprintf(FILE *stream, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = vfprintf(stream, fmt, args);
va_end(args);
return ret;
}
 
/** Print formatted text to stdout.
*
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int printf(const char *fmt, ...)
{
int ret;
va_list args;
 
va_start(args, fmt);
 
ret = vprintf(fmt, args);
int ret = vprintf(fmt, args);
va_end(args);
 
return ret;
}
 
/branches/network/uspace/lib/libc/generic/io/console.c
0,0 → 1,102
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2006 Jakub Vana
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <libc.h>
#include <async.h>
#include <io/console.h>
#include <ipc/console.h>
 
void console_clear(int phone)
{
async_msg_0(phone, CONSOLE_CLEAR);
}
 
int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols)
{
return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols);
}
 
void console_set_style(int phone, int style)
{
async_msg_1(phone, CONSOLE_SET_STYLE, style);
}
 
void console_set_color(int phone, int fg_color, int bg_color, int flags)
{
async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
}
 
void console_set_rgb_color(int phone, int fg_color, int bg_color)
{
async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
}
 
void console_cursor_visibility(int phone, bool show)
{
async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
}
 
void console_kcon_enable(int phone)
{
async_msg_0(phone, CONSOLE_KCON_ENABLE);
}
 
void console_goto(int phone, ipcarg_t row, ipcarg_t col)
{
async_msg_2(phone, CONSOLE_GOTO, row, col);
}
 
bool console_get_event(int phone, console_event_t *event)
{
ipcarg_t type;
ipcarg_t key;
ipcarg_t mods;
ipcarg_t c;
int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
if (rc < 0)
return false;
event->type = type;
event->key = key;
event->mods = mods;
event->c = c;
return true;
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/io/snprintf.c
37,21 → 37,23
#include <io/printf_core.h>
 
/** Print formatted to the given buffer with limited size.
* @param str buffer
* @param size buffer size
* @param fmt format string
*
* @param str Buffer
* @param size Buffer size
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int snprintf(char *str, size_t size, const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt);
va_start(args, fmt);
ret = vsnprintf(str, size, fmt, args);
 
int ret = vsnprintf(str, size, fmt, args);
va_end(args);
 
return ret;
}
 
/branches/network/uspace/lib/libc/generic/io/asprintf.c
36,42 → 36,52
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io/printf_core.h>
 
static int asprintf_prewrite(const char *str, size_t count, void *unused)
static int asprintf_str_write(const char *str, size_t count, void *unused)
{
return count;
return str_nlength(str, count);
}
 
static int asprintf_wstr_write(const wchar_t *str, size_t count, void *unused)
{
return wstr_nlength(str, count);
}
 
/** Allocate and print to string.
*
* @param strp Address of the pointer where to store the address of
* the newly allocated string.
* @fmt Format strin.
* @param strp Address of the pointer where to store the address of
* the newly allocated string.
* @fmt Format string.
*
* @return Number of characters printed or a negative error code.
* @return Number of characters printed or a negative error code.
*
*/
int asprintf(char **strp, const char *fmt, ...)
{
struct printf_spec ps = {
asprintf_prewrite,
NULL
asprintf_str_write,
asprintf_wstr_write,
NULL
};
int ret;
va_list args;
 
va_start(args, fmt);
ret = printf_core(fmt, &ps, args);
int ret = printf_core(fmt, &ps, args);
va_end(args);
if (ret > 0) {
*strp = malloc(ret + 20);
if (!*strp)
*strp = malloc(STR_BOUNDS(ret) + 1);
if (*strp == NULL)
return -1;
va_start(args, fmt);
vsprintf(*strp, fmt, args);
va_end(args);
vsnprintf(*strp, STR_BOUNDS(ret) + 1, fmt, args);
va_end(args);
}
 
return ret;
}
 
/branches/network/uspace/lib/libc/generic/io/io.c
30,98 → 30,551
* @{
*/
/** @file
*/
*/
 
#include <libc.h>
#include <stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <io/io.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <console.h>
#include <bool.h>
#include <malloc.h>
#include <io/klog.h>
#include <vfs/vfs.h>
#include <ipc/devmap.h>
#include <adt/list.h>
 
const static char nl = '\n';
static void _fflushbuf(FILE *stream);
 
int puts(const char *str)
static FILE stdin_null = {
.fd = -1,
.error = true,
.eof = true,
.klog = false,
.phone = -1,
.btype = _IONBF,
.buf = NULL,
.buf_size = 0,
.buf_head = NULL
};
 
static FILE stdout_klog = {
.fd = -1,
.error = false,
.eof = false,
.klog = true,
.phone = -1,
.btype = _IOLBF,
.buf = NULL,
.buf_size = BUFSIZ,
.buf_head = NULL
};
 
static FILE stderr_klog = {
.fd = -1,
.error = false,
.eof = false,
.klog = true,
.phone = -1,
.btype = _IONBF,
.buf = NULL,
.buf_size = 0,
.buf_head = NULL
};
 
FILE *stdin = NULL;
FILE *stdout = NULL;
FILE *stderr = NULL;
 
static LIST_INITIALIZE(files);
 
void stdio_init(int filc, fdi_node_t *filv[])
{
size_t count;
if (filc > 0) {
stdin = fopen_node(filv[0], "r");
} else {
stdin = &stdin_null;
list_append(&stdin->link, &files);
}
if (str == NULL)
return putnchars("(NULL)", 6);
if (filc > 1) {
stdout = fopen_node(filv[1], "w");
} else {
stdout = &stdout_klog;
list_append(&stdout->link, &files);
}
for (count = 0; str[count] != 0; count++);
if (filc > 2) {
stderr = fopen_node(filv[2], "w");
} else {
stderr = &stderr_klog;
list_append(&stderr->link, &files);
}
}
 
void stdio_done(void)
{
link_t *link = files.next;
if (console_write((void *) str, count) == count) {
if (console_write(&nl, 1) == 1)
return 0;
while (link != &files) {
FILE *file = list_get_instance(link, FILE, link);
fclose(file);
link = files.next;
}
}
 
static bool parse_mode(const char *mode, int *flags)
{
/* Parse mode except first character. */
const char *mp = mode;
if (*mp++ == 0) {
errno = EINVAL;
return false;
}
return EOF;
if ((*mp == 'b') || (*mp == 't'))
mp++;
bool plus;
if (*mp == '+') {
mp++;
plus = true;
} else
plus = false;
if (*mp != 0) {
errno = EINVAL;
return false;
}
/* Parse first character of mode and determine flags for open(). */
switch (mode[0]) {
case 'r':
*flags = plus ? O_RDWR : O_RDONLY;
break;
case 'w':
*flags = (O_TRUNC | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
break;
case 'a':
/* TODO: a+ must read from beginning, append to the end. */
if (plus) {
errno = ENOTSUP;
return false;
}
*flags = (O_APPEND | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
default:
errno = EINVAL;
return false;
}
return true;
}
 
/** Put count chars from buffer to stdout without adding newline
* @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
* @param count
* @return 0 on succes, EOF on fail
/** Set stream buffer. */
void setvbuf(FILE *stream, void *buf, int mode, size_t size)
{
stream->btype = mode;
stream->buf = buf;
stream->buf_size = size;
stream->buf_head = stream->buf;
}
 
/** Allocate stream buffer. */
static int _fallocbuf(FILE *stream)
{
assert(stream->buf == NULL);
 
stream->buf = malloc(stream->buf_size);
if (stream->buf == NULL) {
errno = ENOMEM;
return -1;
}
 
stream->buf_head = stream->buf;
return 0;
}
 
/** Open a stream.
*
* @param path Path of the file to open.
* @param mode Mode string, (r|w|a)[b|t][+].
*
*/
int putnchars(const char *buf, size_t count)
FILE *fopen(const char *path, const char *mode)
{
if (console_write((void *) buf, count) == count)
return 0;
int flags;
if (!parse_mode(mode, &flags))
return NULL;
return EOF;
/* Open file. */
FILE *stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
stream->fd = open(path, flags, 0666);
if (stream->fd < 0) {
/* errno was set by open() */
free(stream);
return NULL;
}
stream->error = false;
stream->eof = false;
stream->klog = false;
stream->phone = -1;
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOFBF, BUFSIZ);
list_append(&stream->link, &files);
return stream;
}
 
/** Same as puts, but does not print newline at end
FILE *fdopen(int fd, const char *mode)
{
/* Open file. */
FILE *stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
stream->fd = fd;
stream->error = false;
stream->eof = false;
stream->klog = false;
stream->phone = -1;
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
list_append(&stream->link, &files);
return stream;
}
 
FILE *fopen_node(fdi_node_t *node, const char *mode)
{
int flags;
if (!parse_mode(mode, &flags))
return NULL;
/* Open file. */
FILE *stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
stream->fd = open_node(node, flags);
if (stream->fd < 0) {
/* errno was set by open_node() */
free(stream);
return NULL;
}
stream->error = false;
stream->eof = false;
stream->klog = false;
stream->phone = -1;
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
list_append(&stream->link, &files);
return stream;
}
 
int fclose(FILE *stream)
{
int rc = 0;
fflush(stream);
if (stream->phone >= 0)
ipc_hangup(stream->phone);
if (stream->fd >= 0)
rc = close(stream->fd);
list_remove(&stream->link);
if ((stream != &stdin_null)
&& (stream != &stdout_klog)
&& (stream != &stderr_klog))
free(stream);
stream = NULL;
if (rc != 0) {
/* errno was set by close() */
return EOF;
}
return 0;
}
 
/** Read from a stream.
*
* @param buf Destination buffer.
* @param size Size of each record.
* @param nmemb Number of records to read.
* @param stream Pointer to the stream.
*
*/
int putstr(const char *str)
size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
{
size_t count;
size_t left = size * nmemb;
size_t done = 0;
 
/* Make sure no data is pending write. */
_fflushbuf(stream);
 
while ((left > 0) && (!stream->error) && (!stream->eof)) {
ssize_t rd = read(stream->fd, buf + done, left);
if (rd < 0)
stream->error = true;
else if (rd == 0)
stream->eof = true;
else {
left -= rd;
done += rd;
}
}
if (str == NULL)
return putnchars("(NULL)", 6);
return (done / size);
}
 
for (count = 0; str[count] != 0; count++);
if (console_write((void *) str, count) == count)
return 0;
static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
{
size_t left = size * nmemb;
size_t done = 0;
return EOF;
while ((left > 0) && (!stream->error)) {
ssize_t wr;
if (stream->klog)
wr = klog_write(buf + done, left);
else
wr = write(stream->fd, buf + done, left);
if (wr <= 0)
stream->error = true;
else {
left -= wr;
done += wr;
}
}
return (done / size);
}
 
int putchar(int c)
/** Drain stream buffer, do not sync stream. */
static void _fflushbuf(FILE *stream)
{
char buf[STR_BOUNDS(1)];
size_t offs;
size_t bytes_used;
 
offs = 0;
if (chr_encode(c, buf, &offs, STR_BOUNDS(1)) != EOK)
return EOF;
if (!stream->buf || stream->btype == _IONBF || stream->error)
return;
 
if (console_write((void *) buf, offs) == offs)
return c;
bytes_used = stream->buf_head - stream->buf;
if (bytes_used == 0)
return;
 
return EOF;
(void) _fwrite(stream->buf, 1, bytes_used, stream);
stream->buf_head = stream->buf;
}
 
int getchar(void)
/** Write to a stream.
*
* @param buf Source buffer.
* @param size Size of each record.
* @param nmemb Number of records to write.
* @param stream Pointer to the stream.
*
*/
size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
{
unsigned char c;
uint8_t *data;
size_t bytes_left;
size_t now;
size_t buf_free;
size_t total_written;
size_t i;
uint8_t b;
bool need_flush;
 
/* If not buffered stream, write out directly. */
if (stream->btype == _IONBF)
return _fwrite(buf, size, nmemb, stream);
 
/* Perform lazy allocation of stream buffer. */
if (stream->buf == NULL) {
if (_fallocbuf(stream) != 0)
return 0; /* Errno set by _fallocbuf(). */
}
 
data = (uint8_t *) buf;
bytes_left = size * nmemb;
total_written = 0;
need_flush = false;
 
while (!stream->error && bytes_left > 0) {
 
buf_free = stream->buf_size - (stream->buf_head - stream->buf);
if (bytes_left > buf_free)
now = buf_free;
else
now = bytes_left;
 
for (i = 0; i < now; i++) {
b = data[i];
stream->buf_head[i] = b;
 
if (b == '\n' && stream->btype == _IOLBF)
need_flush = true;
}
 
buf += now;
stream->buf_head += now;
buf_free -= now;
bytes_left -= now;
total_written += now;
 
if (buf_free == 0) {
/* Only need to drain buffer. */
_fflushbuf(stream);
need_flush = false;
}
}
 
if (need_flush)
fflush(stream);
 
return (total_written / size);
}
 
int fputc(wchar_t c, FILE *stream)
{
char buf[STR_BOUNDS(1)];
size_t sz = 0;
console_flush();
if (read_stdin((void *) &c, 1) == 1)
return c;
if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) {
size_t wr = fwrite(buf, sz, 1, stream);
if (wr < sz)
return EOF;
return (int) c;
}
return EOF;
}
 
int fflush(FILE *f)
int putchar(wchar_t c)
{
/* Dummy implementation */
(void) f;
console_flush();
return fputc(c, stdout);
}
 
int fputs(const char *str, FILE *stream)
{
return fwrite(str, str_size(str), 1, stream);
}
 
int puts(const char *str)
{
return fputs(str, stdout);
}
 
int fgetc(FILE *stream)
{
char c;
 
/* This could be made faster by only flushing when needed. */
if (stdout)
fflush(stdout);
if (stderr)
fflush(stderr);
 
if (fread(&c, sizeof(char), 1, stream) < sizeof(char))
return EOF;
return (int) c;
}
 
int getchar(void)
{
return fgetc(stdin);
}
 
int fseek(FILE *stream, long offset, int origin)
{
off_t rc = lseek(stream->fd, offset, origin);
if (rc == (off_t) (-1)) {
/* errno has been set by lseek. */
return -1;
}
stream->eof = false;
return 0;
}
 
void rewind(FILE *stream)
{
(void) fseek(stream, 0, SEEK_SET);
}
 
int fflush(FILE *stream)
{
_fflushbuf(stream);
 
if (stream->klog) {
klog_update();
return EOK;
}
if (stream->fd >= 0)
return fsync(stream->fd);
return ENOENT;
}
 
int feof(FILE *stream)
{
return stream->eof;
}
 
int ferror(FILE *stream)
{
return stream->error;
}
 
int fphone(FILE *stream)
{
if (stream->fd >= 0) {
if (stream->phone < 0)
stream->phone = fd_phone(stream->fd);
return stream->phone;
}
return -1;
}
 
int fnode(FILE *stream, fdi_node_t *node)
{
if (stream->fd >= 0)
return fd_node(stream->fd, node);
return ENOENT;
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/io/vprintf.c
38,37 → 38,25
#include <io/printf_core.h>
#include <futex.h>
#include <async.h>
#include <console.h>
#include <string.h>
 
static atomic_t printf_futex = FUTEX_INITIALIZER;
 
static int vprintf_str_write(const char *str, size_t size, void *data)
static int vprintf_str_write(const char *str, size_t size, void *stream)
{
size_t offset = 0;
size_t prev;
count_t chars = 0;
while (offset < size) {
prev = offset;
str_decode(str, &offset, size);
console_write(str + prev, offset - prev);
chars++;
}
return chars;
size_t wr = fwrite(str, 1, size, (FILE *) stream);
return str_nlength(str, wr);
}
 
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *stream)
{
size_t offset = 0;
size_t boff;
count_t chars = 0;
char buf[4];
size_t chars = 0;
while (offset < size) {
boff = 0;
chr_encode(str[chars], buf, &boff, 4);
console_write(buf, boff);
if (fputc(str[chars], (FILE *) stream) <= 0)
break;
chars++;
offset += sizeof(wchar_t);
}
76,33 → 64,55
return chars;
}
 
 
/** Print formatted text.
* @param fmt format string
* @param ap format parameters
*
* @param stream Output stream
* @param fmt Format string
* @param ap Format parameters
*
* \see For more details about format string see printf_core.
*
*/
int vprintf(const char *fmt, va_list ap)
int vfprintf(FILE *stream, const char *fmt, va_list ap)
{
struct printf_spec ps = {
vprintf_str_write,
vprintf_wstr_write,
NULL
stream
};
/*
* Prevent other threads to execute printf_core()
*/
futex_down(&printf_futex);
/*
* Prevent other pseudo threads of the same thread
* Prevent other fibrils of the same thread
* to execute printf_core()
*/
async_serialize_start();
int ret = printf_core(fmt, &ps, ap);
async_serialize_end();
futex_up(&printf_futex);
return ret;
}
 
/** Print formatted text to stdout.
*
* @param file Output stream
* @param fmt Format string
* @param ap Format parameters
*
* \see For more details about format string see printf_core.
*
*/
int vprintf(const char *fmt, va_list ap)
{
return vfprintf(stdout, fmt, ap);
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/io/vsnprintf.c
82,7 → 82,7
* with the trailing zero => print only a part
* of string
*/
index_t index = 0;
size_t index = 0;
while (index < size) {
wchar_t uc = str_decode(str, &index, size);
130,7 → 130,7
*/
static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
{
index_t index = 0;
size_t index = 0;
while (index < (size / sizeof(wchar_t))) {
size_t left = data->size - data->len;
/branches/network/uspace/lib/libc/generic/io/printf_core.c
173,7 → 173,7
*/
static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps)
{
count_t counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
211,7 → 211,7
*/
static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
{
count_t counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
254,12 → 254,12
return printf_putstr(nullstr, ps);
 
/* Print leading spaces. */
count_t strw = str_length(str);
size_t strw = str_length(str);
if (precision == 0)
precision = strw;
 
/* Left padding */
count_t counter = 0;
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
301,9 → 301,6
if (str == NULL)
return printf_putstr(nullstr, ps);
if (*str == U_BOM)
str++;
/* Print leading spaces. */
size_t strw = wstr_length(str);
if (precision == 0)
310,7 → 307,7
precision = strw;
/* Left padding */
count_t counter = 0;
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
432,7 → 429,7
}
width -= precision + size - number_size;
count_t counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
595,7 → 592,7
size_t nxt = 0; /* Index of the next character from fmt */
size_t j = 0; /* Index to the first not printed nonformating character */
count_t counter = 0; /* Number of characters printed */
size_t counter = 0; /* Number of characters printed */
int retval; /* Return values from nested functions */
while (true) {
/branches/network/uspace/lib/libc/generic/io/klog.c
0,0 → 1,53
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2006 Jakub Vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <libc.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <io/klog.h>
 
size_t klog_write(const void *buf, size_t size)
{
return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
}
 
void klog_update(void)
{
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0);
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/adt/hash_table.c
0,0 → 1,196
/*
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
/*
* This is an implementation of generic chained hash table.
*/
 
#include <adt/hash_table.h>
#include <adt/list.h>
#include <unistd.h>
#include <malloc.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
 
/** Create chained hash table.
*
* @param h Hash table structure. Will be initialized by this call.
* @param m Number of hash table buckets.
* @param max_keys Maximal number of keys needed to identify an item.
* @param op Hash table operations structure.
* @return True on success
*/
int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
hash_table_operations_t *op)
{
hash_count_t i;
 
assert(h);
assert(op && op->hash && op->compare);
assert(max_keys > 0);
h->entry = malloc(m * sizeof(link_t));
if (!h->entry) {
printf("cannot allocate memory for hash table\n");
return false;
}
memset((void *) h->entry, 0, m * sizeof(link_t));
for (i = 0; i < m; i++)
list_initialize(&h->entry[i]);
h->entries = m;
h->max_keys = max_keys;
h->op = op;
return true;
}
 
/** Destroy a hash table instance.
*
* @param h Hash table to be destroyed.
*/
void hash_table_destroy(hash_table_t *h)
{
assert(h);
assert(h->entry);
free(h->entry);
}
 
/** Insert item into a hash table.
*
* @param h Hash table.
* @param key Array of all keys necessary to compute hash index.
* @param item Item to be inserted into the hash table.
*/
void hash_table_insert(hash_table_t *h, unsigned long key[], link_t *item)
{
hash_index_t chain;
 
assert(item);
assert(h && h->op && h->op->hash && h->op->compare);
 
chain = h->op->hash(key);
assert(chain < h->entries);
list_append(item, &h->entry[chain]);
}
 
/** Search hash table for an item matching keys.
*
* @param h Hash table.
* @param key Array of all keys needed to compute hash index.
*
* @return Matching item on success, NULL if there is no such item.
*/
link_t *hash_table_find(hash_table_t *h, unsigned long key[])
{
link_t *cur;
hash_index_t chain;
 
assert(h && h->op && h->op->hash && h->op->compare);
 
chain = h->op->hash(key);
assert(chain < h->entries);
for (cur = h->entry[chain].next; cur != &h->entry[chain];
cur = cur->next) {
if (h->op->compare(key, h->max_keys, cur)) {
/*
* The entry is there.
*/
return cur;
}
}
return NULL;
}
 
/** Remove all matching items from hash table.
*
* For each removed item, h->remove_callback() is called.
*
* @param h Hash table.
* @param key Array of keys that will be compared against items of
* the hash table.
* @param keys Number of keys in the 'key' array.
*/
void hash_table_remove(hash_table_t *h, unsigned long key[], hash_count_t keys)
{
hash_index_t chain;
link_t *cur;
 
assert(h && h->op && h->op->hash && h->op->compare &&
h->op->remove_callback);
assert(keys <= h->max_keys);
if (keys == h->max_keys) {
 
/*
* All keys are known, hash_table_find() can be used to find the
* entry.
*/
cur = hash_table_find(h, key);
if (cur) {
list_remove(cur);
h->op->remove_callback(cur);
}
return;
}
/*
* Fewer keys were passed.
* Any partially matching entries are to be removed.
*/
for (chain = 0; chain < h->entries; chain++) {
for (cur = h->entry[chain].next; cur != &h->entry[chain];
cur = cur->next) {
if (h->op->compare(key, keys, cur)) {
link_t *hlp;
hlp = cur;
cur = cur->prev;
list_remove(hlp);
h->op->remove_callback(hlp);
continue;
}
}
}
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/adt/list.c
0,0 → 1,112
/*
* Copyright (c) 2004 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#include <adt/list.h>
 
 
/** Check for membership
*
* Check whether link is contained in the list head.
* The membership is defined as pointer equivalence.
*
* @param link Item to look for.
* @param head List to look in.
*
* @return true if link is contained in head, false otherwise.
*
*/
int list_member(const link_t *link, const link_t *head)
{
int found = 0;
link_t *hlp = head->next;
while (hlp != head) {
if (hlp == link) {
found = 1;
break;
}
hlp = hlp->next;
}
return found;
}
 
 
/** Concatenate two lists
*
* Concatenate lists head1 and head2, producing a single
* list head1 containing items from both (in head1, head2
* order) and empty list head2.
*
* @param head1 First list and concatenated output
* @param head2 Second list and empty output.
*
*/
void list_concat(link_t *head1, link_t *head2)
{
if (list_empty(head2))
return;
head2->next->prev = head1->prev;
head2->prev->next = head1;
head1->prev->next = head2->next;
head1->prev = head2->prev;
list_initialize(head2);
}
 
 
/** Count list items
*
* Return the number of items in the list.
*
* @param link List to count.
*
* @return Number of items in the list.
*
*/
unsigned int list_count(const link_t *link)
{
unsigned int count = 0;
link_t *hlp = link->next;
while (hlp != link) {
count++;
hlp = hlp->next;
}
return count;
}
 
/** @}
*/
/branches/network/uspace/lib/libc/Makefile
32,6 → 32,7
LIBC_PREFIX = $(shell pwd)
SOFTINT_PREFIX = ../softint
 
 
## Setup toolchain
#
 
46,11 → 47,12
generic/ddi.c \
generic/as.c \
generic/cap.c \
generic/console.c \
generic/devmap.c \
generic/event.c \
generic/mem.c \
generic/string.c \
generic/fibril.c \
generic/fibril_sync.c \
generic/pcb.c \
generic/smc.c \
generic/thread.c \
60,15 → 62,12
generic/io/asprintf.c \
generic/io/io.c \
generic/io/printf.c \
generic/io/fprintf.c \
generic/io/stdio.c \
generic/io/stream.c \
generic/io/sprintf.c \
generic/io/klog.c \
generic/io/snprintf.c \
generic/io/vprintf.c \
generic/io/vsprintf.c \
generic/io/vsnprintf.c \
generic/io/printf_core.c \
generic/io/console.c \
malloc/malloc.c \
generic/sysinfo.c \
generic/ipc.c \
75,12 → 74,11
generic/async.c \
generic/loader.c \
generic/getopt.c \
generic/libadt/list.o \
generic/libadt/hash_table.o \
generic/adt/list.o \
generic/adt/hash_table.o \
generic/time.c \
generic/err.c \
generic/stdlib.c \
generic/kbd.c \
generic/mman.c \
generic/udebug.c \
generic/vfs/vfs.c \
/branches/network/uspace/lib/libc/arch/sparc64/include/byteorder.h
File deleted
/branches/network/uspace/lib/libc/arch/sparc64/include/types.h
49,8 → 49,6
 
typedef int64_t ssize_t;
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
 
/branches/network/uspace/lib/libc/arch/sparc64/Makefile.inc
38,5 → 38,7
CFLAGS += -mcpu=ultrasparc -m64
LFLAGS += -no-check-sections -N
 
ENDIANESS = BE
 
BFD_NAME = elf64-sparc
BFD_ARCH = sparc
/branches/network/uspace/lib/libc/arch/ia64/include/byteorder.h
File deleted
/branches/network/uspace/lib/libc/arch/ia64/include/types.h
49,8 → 49,6
 
typedef int64_t ssize_t;
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
 
/branches/network/uspace/lib/libc/arch/ia64/Makefile.inc
31,9 → 31,6
 
TARGET = ia64-pc-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin
CFLAGS += -fno-unwind-tables -DMALLOC_ALIGNMENT_16
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
AFLAGS +=
 
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \
arch/$(UARCH)/src/fibril.S \
40,5 → 37,10
arch/$(UARCH)/src/tls.c \
arch/$(UARCH)/src/ddi.c
 
CFLAGS += -fno-unwind-tables -DMALLOC_ALIGNMENT_16
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
 
ENDIANESS = LE
 
BFD_NAME = elf64-ia64-little
BFD_ARCH = ia64-elf64
/branches/network/uspace/lib/libc/arch/arm32/include/byteorder.h
File deleted
/branches/network/uspace/lib/libc/arch/arm32/include/tls.h
40,7 → 40,7
 
#define CONFIG_TLS_VARIANT_1
 
/** Offsets for accessing __thread variables are shifted 8 bytes higher. */
/** Offsets for accessing thread-local variables are shifted 8 bytes higher. */
#define ARM_TP_OFFSET (-8)
 
/** TCB (Thread Control Block) struct.
/branches/network/uspace/lib/libc/arch/arm32/include/types.h
50,8 → 50,6
 
typedef int32_t ssize_t;
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
 
/branches/network/uspace/lib/libc/arch/arm32/include/fibril.h
38,7 → 38,7
 
#include <sys/types.h>
#include <align.h>
#include "thread.h"
#include <thread.h>
 
/** Size of a stack item */
#define STACK_ITEM_SIZE 4
/branches/network/uspace/lib/libc/arch/arm32/Makefile.inc
32,9 → 32,6
 
TARGET = arm-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin
CFLAGS += -ffixed-r9 -mtp=soft
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
AFLAGS +=
 
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
arch/$(UARCH)/src/fibril.S \
41,5 → 38,10
arch/$(UARCH)/src/tls.c \
arch/$(UARCH)/src/eabi.S
 
CFLAGS += -ffixed-r9 -mtp=soft
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a
 
ENDIANESS = LE
 
BFD_NAME = elf32-littlearm
BFD_ARCH = arm
/branches/network/uspace/lib/libc/arch/mips32eb/include/byteorder.h
File deleted
/branches/network/uspace/lib/libc/arch/mips32eb/Makefile.inc
31,13 → 31,15
 
TARGET = mips-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin
CFLAGS += -mips3
 
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c
 
CFLAGS += -mips3
LFLAGS += -N
 
ENDIANESS = BE
 
BFD_ARCH = mips
BFD_NAME = elf32-tradbigmips
/branches/network/uspace/lib/libc/arch/ppc32/include/byteorder.h
File deleted
/branches/network/uspace/lib/libc/arch/ppc32/include/types.h
49,8 → 49,6
 
typedef int32_t ssize_t;
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
 
/branches/network/uspace/lib/libc/arch/ppc32/Makefile.inc
40,5 → 40,7
AFLAGS += -a32
LFLAGS += -N
 
ENDIANESS = BE
 
BFD_NAME = elf32-powerpc
BFD_ARCH = powerpc:common
/branches/network/uspace/lib/libc/arch/amd64/include/byteorder.h
File deleted
/branches/network/uspace/lib/libc/arch/amd64/include/types.h
49,8 → 49,6
 
typedef int64_t ssize_t;
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
 
/branches/network/uspace/lib/libc/arch/amd64/Makefile.inc
38,5 → 38,7
 
LFLAGS += -N
 
ENDIANESS = LE
 
BFD_NAME = elf64-x86-64
BFD_ARCH = i386:x86-64
/branches/network/uspace/lib/libc/arch/mips32/include/byteorder.h
File deleted
/branches/network/uspace/lib/libc/arch/mips32/include/types.h
50,8 → 50,6
 
typedef int32_t ssize_t;
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
 
/branches/network/uspace/lib/libc/arch/mips32/Makefile.inc
31,11 → 31,14
 
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin
CFLAGS += -mips3
 
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \
arch/$(UARCH)/src/fibril.S \
arch/$(UARCH)/src/tls.c
 
CFLAGS += -mips3
 
ENDIANESS = LE
 
BFD_ARCH = mips
BFD_NAME = elf32-tradlittlemips
/branches/network/uspace/lib/libc/arch/ia32/include/byteorder.h
File deleted
/branches/network/uspace/lib/libc/arch/ia32/include/types.h
49,8 → 49,6
 
typedef int32_t ssize_t;
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
 
/branches/network/uspace/lib/libc/arch/ia32/Makefile.inc
39,5 → 39,7
 
LFLAGS += -N
 
ENDIANESS = LE
 
BFD_NAME = elf32-i386
BFD_ARCH = i386