Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4718 → Rev 4581

/branches/network/uspace/lib/libc/generic/malloc.c
File deleted
/branches/network/uspace/lib/libc/generic/errno.c
File deleted
/branches/network/uspace/lib/libc/generic/task.c
148,23 → 148,10
return 0;
}
 
int task_wait(task_id_t id, task_exit_t *texit, int *retval)
int task_wait(task_id_t id)
{
ipcarg_t te, rv;
int rc;
 
rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id),
UPPER32(id), &te, &rv);
*texit = te;
*retval = rv;
 
return rc;
return (int) async_req_2_0(PHONE_NS, NS_TASK_WAIT, LOWER32(id), UPPER32(id));
}
 
int task_retval(int val)
{
return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val);
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/as.c
38,23 → 38,23
#include <align.h>
#include <sys/types.h>
#include <bitops.h>
#include <malloc.h>
 
/** Last position allocated by as_get_mappable_page */
static uintptr_t last_allocated = 0;
/**
* Either 4*256M on 32-bit architecures or 16*256M on 64-bit architectures.
*/
#define MAX_HEAP_SIZE (sizeof(uintptr_t)<<28)
 
/** Create address space area.
*
* @param address Virtual address where to place new address space area.
* @param size Size of the area.
* @param flags Flags describing type of the area.
* @param size Size of the area.
* @param flags Flags describing type of the area.
*
* @return address on success, (void *) -1 otherwise.
*
*/
void *as_area_create(void *address, size_t size, int flags)
{
return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t) address,
return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t ) address,
(sysarg_t) size, (sysarg_t) flags);
}
 
61,16 → 61,15
/** Resize address space area.
*
* @param address Virtual address pointing into already existing address space
* area.
* @param size New requested size of the area.
* @param flags Currently unused.
* area.
* @param size New requested size of the area.
* @param flags Currently unused.
*
* @return zero on success or a code from @ref errno.h on failure.
*
* @return Zero on success or a code from @ref errno.h on failure.
*/
int as_area_resize(void *address, size_t size, int flags)
{
return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t) address,
return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t ) address,
(sysarg_t) size, (sysarg_t) flags);
}
 
77,24 → 76,22
/** Destroy address space area.
*
* @param address Virtual address pointing into the address space area being
* destroyed.
* destroyed.
*
* @return zero on success or a code from @ref errno.h on failure.
*
* @return Zero on success or a code from @ref errno.h on failure.
*/
int as_area_destroy(void *address)
{
return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t) address);
return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t ) address);
}
 
/** Change address-space area flags.
*
* @param address Virtual address pointing into the address space area being
* modified.
* @param flags New flags describing type of the area.
* modified.
* @param flags New flags describing type of the area.
*
* @return zero on success or a code from @ref errno.h on failure.
*
* @return Zero on success or a code from @ref errno.h on failure.
*/
int as_area_change_flags(void *address, int flags)
{
102,29 → 99,101
(sysarg_t) flags);
}
 
static size_t heapsize = 0;
static size_t maxheapsize = (size_t) (-1);
 
static void *last_allocated = 0;
 
/* Start of heap linker symbol */
extern char _heap;
 
/** Sbrk emulation
*
* @param incr New area that should be allocated or negative,
if it should be shrinked
* @return Pointer to newly allocated area
*/
void *sbrk(ssize_t incr)
{
int rc;
void *res;
/* Check for invalid values */
if ((incr < 0) && (((size_t) -incr) > heapsize))
return NULL;
/* Check for too large value */
if ((incr > 0) && (incr + heapsize < heapsize))
return NULL;
/* Check for too small values */
if ((incr < 0) && (incr + heapsize > heapsize))
return NULL;
/* Check for user limit */
if ((maxheapsize != (size_t) (-1)) && (heapsize + incr) > maxheapsize)
return NULL;
rc = as_area_resize(&_heap, heapsize + incr, 0);
if (rc != 0)
return NULL;
/* Compute start of new area */
res = (void *) &_heap + heapsize;
 
heapsize += incr;
 
return res;
}
 
/** Set maximum heap size and return pointer just after the heap */
void *set_maxheapsize(size_t mhs)
{
maxheapsize = mhs;
/* Return pointer to area not managed by sbrk */
return ((void *) &_heap + maxheapsize);
}
 
/** Return pointer to some unmapped area, where fits new as_area
*
* @param size Requested size of the allocation.
* @param sz Requested size of the allocation.
*
* @return pointer to the beginning
* @return Pointer to the beginning
*
* TODO: make some first_fit/... algorithm, we are now just incrementing
* the pointer to last area
*/
void *as_get_mappable_page(size_t size)
void *as_get_mappable_page(size_t sz)
{
if (size == 0)
return NULL;
void *res;
uint64_t asz;
int i;
size_t sz = 1 << (fnzb(size - 1) + 1);
if (last_allocated == 0)
last_allocated = get_max_heap_addr();
if (!sz)
return NULL;
 
asz = 1 << (fnzb64(sz - 1) + 1);
 
/* Set heapsize to some meaningful value */
if (maxheapsize == (size_t) -1)
set_maxheapsize(MAX_HEAP_SIZE);
/*
* Make sure we allocate from naturally aligned address.
*/
uintptr_t res = ALIGN_UP(last_allocated, sz);
last_allocated = res + ALIGN_UP(size, PAGE_SIZE);
return ((void *) res);
i = 0;
if (!last_allocated) {
last_allocated = (void *) ALIGN_UP((void *) &_heap +
maxheapsize, asz);
} else {
last_allocated = (void *) ALIGN_UP(((uintptr_t)
last_allocated) + (int) (i > 0), asz);
}
 
res = last_allocated;
last_allocated += ALIGN_UP(sz, PAGE_SIZE);
 
return res;
}
 
/** @}
/branches/network/uspace/lib/libc/generic/string.c
589,7 → 589,7
*
* @return Pointer to character in @a str or NULL if not found.
*/
char *str_chr(const char *str, wchar_t ch)
const char *str_chr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
597,7 → 597,7
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
return (char *) (str + last);
return (str + last);
last = off;
}
611,7 → 611,7
*
* @return Pointer to character in @a str or NULL if not found.
*/
char *str_rchr(const char *str, wchar_t ch)
const char *str_rchr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
624,7 → 624,7
last = off;
}
return (char *) res;
return res;
}
 
/** Insert a wide character into a wide string.
/branches/network/uspace/lib/libc/generic/libc.c
52,8 → 52,11
#include <as.h>
#include <loader/pcb.h>
 
extern char _heap;
extern int main(int argc, char *argv[]);
 
int _errno;
 
void _exit(int status)
{
thread_exit(status);
61,10 → 64,9
 
void __main(void *pcb_ptr)
{
int retval;
 
__heap_init();
__async_init();
(void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ);
_async_init();
fibril_t *fibril = fibril_setup();
__tcb_set(fibril->tcb);
77,17 → 79,15
if (__pcb == NULL) {
argc = 0;
argv = NULL;
__stdio_init(0, NULL);
stdio_init(0, NULL);
} else {
argc = __pcb->argc;
argv = __pcb->argv;
__stdio_init(__pcb->filc, __pcb->filv);
stdio_init(__pcb->filc, __pcb->filv);
}
retval = main(argc, argv);
 
__stdio_done();
(void) task_retval(retval);
main(argc, argv);
stdio_done();
}
 
void __exit(void)
/branches/network/uspace/lib/libc/generic/devmap.c
218,31 → 218,6
return phone;
}
 
int devmap_null_create(void)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return -1;
ipcarg_t null_id;
int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
if (retval != EOK)
return -1;
return (int) null_id;
}
 
void devmap_null_destroy(int null_id)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
if (phone < 0)
return;
async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
}
 
ipcarg_t devmap_device_get_count(void)
{
int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
/branches/network/uspace/lib/libc/generic/async.c
738,7 → 738,7
*
* @return Zero on success or an error code.
*/
int __async_init(void)
int _async_init(void)
{
if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
&conn_hash_table_ops)) {
/branches/network/uspace/lib/libc/generic/vfs/vfs.c
38,8 → 38,8
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
137,7 → 137,7
async_serialize_start();
vfs_connect();
req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
req = async_send_2(vfs_phone, VFS_MOUNT, dev_handle, flags, NULL);
rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
198,7 → 198,7
async_serialize_start();
vfs_connect();
req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
230,7 → 230,7
vfs_connect();
ipc_call_t answer;
aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
aid_t req = async_send_4(vfs_phone, VFS_OPEN_NODE, node->fs_handle,
node->dev_handle, node->index, oflag, &answer);
ipcarg_t rc;
252,7 → 252,7
async_serialize_start();
vfs_connect();
rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
rc = async_req_1_0(vfs_phone, VFS_CLOSE, fildes);
async_serialize_end();
futex_up(&vfs_phone_futex);
270,7 → 270,7
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
req = async_send_1(vfs_phone, VFS_READ, fildes, &answer);
rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);
if (rc != EOK) {
async_wait_for(req, NULL);
297,7 → 297,7
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
req = async_send_1(vfs_phone, VFS_WRITE, fildes, &answer);
rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte);
if (rc != EOK) {
async_wait_for(req, NULL);
314,115 → 314,95
return -1;
}
 
int fsync(int fildes)
int fd_phone(int fildes)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
ipcarg_t device;
ipcarg_t rc = async_req_1_1(vfs_phone, VFS_DEVICE, fildes, &device);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (int) rc;
if (rc != EOK)
return -1;
return devmap_device_connect((dev_handle_t) device, 0);
}
 
off_t lseek(int fildes, off_t offset, int whence)
int fd_node(int fildes, fdi_node_t *node)
{
ipcarg_t rc;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t newoffs;
rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
&newoffs);
 
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)
return (off_t) -1;
return (off_t) newoffs;
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 ftruncate(int fildes, off_t length)
int fsync(int fildes)
{
ipcarg_t rc;
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
ipcarg_t rc = async_req_1_0(vfs_phone, VFS_SYNC, fildes);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (int) rc;
}
 
int fstat(int fildes, struct stat *stat)
off_t lseek(int fildes, off_t offset, int whence)
{
ipcarg_t rc;
aid_t req;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (ssize_t) rc;
}
async_wait_for(req, &rc);
ipcarg_t newoffs;
rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence,
&newoffs);
 
async_serialize_end();
futex_up(&vfs_phone_futex);
 
return rc;
if (rc != EOK)
return (off_t) -1;
return (off_t) newoffs;
}
 
int stat(const char *path, struct stat *stat)
int ftruncate(int fildes, off_t length)
{
ipcarg_t rc;
aid_t req;
size_t pa_size;
char *pa = absolutize(path, &pa_size);
if (!pa)
return ENOMEM;
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return (int) rc;
}
rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return (int) rc;
}
async_wait_for(req, &rc);
rc = async_req_2_0(vfs_phone, VFS_TRUNCATE, fildes, length);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(pa);
return rc;
return (int) rc;
}
 
DIR *opendir(const char *dirname)
472,7 → 452,7
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
502,7 → 482,7
async_serialize_start();
vfs_connect();
req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
req = async_send_0(vfs_phone, VFS_UNLINK, NULL);
rc = ipc_data_write_start(vfs_phone, pa, pa_size);
if (rc != EOK) {
async_wait_for(req, NULL);
549,7 → 529,7
async_serialize_start();
vfs_connect();
req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
req = async_send_0(vfs_phone, VFS_RENAME, NULL);
rc = ipc_data_write_start(vfs_phone, olda, olda_size);
if (rc != EOK) {
async_wait_for(req, NULL);
618,34 → 598,5
return buf;
}
 
int fd_phone(int fildes)
{
struct stat stat;
int rc;
 
rc = fstat(fildes, &stat);
 
if (!stat.devfs_stat.device)
return -1;
return devmap_device_connect(stat.devfs_stat.device, 0);
}
 
int fd_node(int fildes, fdi_node_t *node)
{
struct stat stat;
int rc;
 
rc = fstat(fildes, &stat);
if (rc == EOK) {
node->fs_handle = stat.fs_handle;
node->dev_handle = stat.dev_handle;
node->index = stat.index;
}
return rc;
}
 
/** @}
*/
/branches/network/uspace/lib/libc/generic/io/console.c
69,17 → 69,6
async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
}
 
int console_get_color_cap(int phone, int *ccap)
{
ipcarg_t ccap_tmp;
int rc;
 
rc = async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, &ccap_tmp);
*ccap = ccap_tmp;
 
return rc;
}
 
void console_kcon_enable(int phone)
{
async_msg_0(phone, CONSOLE_KCON_ENABLE);
/branches/network/uspace/lib/libc/generic/io/io.c
89,7 → 89,7
 
static LIST_INITIALIZE(files);
 
void __stdio_init(int filc, fdi_node_t *filv[])
void stdio_init(int filc, fdi_node_t *filv[])
{
if (filc > 0) {
stdin = fopen_node(filv[0], "r");
113,7 → 113,7
}
}
 
void __stdio_done(void)
void stdio_done(void)
{
link_t *link = files.next;
180,34 → 180,17
stream->buf_head = stream->buf;
}
 
static void _setvbuf(FILE *stream)
{
/* FIXME: Use more complex rules for setting buffering options. */
switch (stream->fd) {
case 1:
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
break;
case 0:
case 2:
setvbuf(stream, NULL, _IONBF, 0);
break;
default:
setvbuf(stream, NULL, _IOFBF, BUFSIZ);
}
}
 
/** 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;
}
242,7 → 225,9
stream->eof = false;
stream->klog = false;
stream->phone = -1;
_setvbuf(stream);
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOFBF, BUFSIZ);
list_append(&stream->link, &files);
263,7 → 248,9
stream->eof = false;
stream->klog = false;
stream->phone = -1;
_setvbuf(stream);
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
list_append(&stream->link, &files);
294,7 → 281,9
stream->eof = false;
stream->klog = false;
stream->phone = -1;
_setvbuf(stream);
 
/* FIXME: Should select buffering type based on what was opened. */
setvbuf(stream, NULL, _IOLBF, BUFSIZ);
list_append(&stream->link, &files);
342,10 → 331,10
{
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);
390,14 → 379,14
static void _fflushbuf(FILE *stream)
{
size_t bytes_used;
if ((!stream->buf) || (stream->btype == _IONBF) || (stream->error))
 
if (!stream->buf || stream->btype == _IONBF || stream->error)
return;
 
bytes_used = stream->buf_head - stream->buf;
if (bytes_used == 0)
return;
 
(void) _fwrite(stream->buf, 1, bytes_used, stream);
stream->buf_head = stream->buf;
}
420,46 → 409,44
size_t i;
uint8_t b;
bool need_flush;
 
/* If not buffered stream, write out directly. */
if (stream->btype == _IONBF) {
now = _fwrite(buf, size, nmemb, stream);
fflush(stream);
return now;
}
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)) {
 
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))
 
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);
466,10 → 453,10
need_flush = false;
}
}
 
if (need_flush)
fflush(stream);
 
return (total_written / size);
}
 
508,13 → 495,13
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;
547,7 → 534,7
int fflush(FILE *stream)
{
_fflushbuf(stream);
 
if (stream->klog) {
klog_update();
return EOK;
/branches/network/uspace/lib/libc/generic/getopt.c
47,7 → 47,7
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
int optreset; /* reset getopt */
const char *optarg; /* argument associated with option */
char *optarg; /* argument associated with option */
 
 
#define IGNORE_FIRST (*options == '-' || *options == '+')
162,7 → 162,7
char **nargv;
const char *options;
{
const char *oli; /* option letter list index */
char *oli; /* option letter list index */
int optchar;
 
assert(nargv != NULL);
275,7 → 275,7
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
optarg = *place;
/* XXX: disable test for :: if PC? (GNU doesn't) */
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
353,8 → 353,7
 
retval = getopt_internal(nargc, (char **)nargv, options);
if (retval == -2) {
char *current_argv;
const char *has_equal;
char *current_argv, *has_equal;
size_t current_argv_len;
int i, ambiguous, match;
 
/branches/network/uspace/lib/libc/generic/mman.c
37,18 → 37,17
#include <as.h>
#include <unistd.h>
 
void *mmap(void *start, size_t length, int prot, int flags, int fd,
void *mmap(void *start, size_t length, int prot, int flags, int fd,
off_t offset)
{
if (!start)
start = as_get_mappable_page(length);
// if (!((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE)))
// if (! ((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE)))
// return MAP_FAILED;
if (!(flags & MAP_ANONYMOUS))
if (! (flags & MAP_ANONYMOUS))
return MAP_FAILED;
 
return as_area_create(start, length, prot);
}