/branches/tracing/uspace/lib/libfs/libfs.c |
---|
36,6 → 36,7 |
#include "libfs.h" |
#include "../../srv/vfs/vfs.h" |
#include "../../srv/rd/rd.h" |
#include <errno.h> |
#include <async.h> |
#include <ipc/ipc.h> |
330,5 → 331,62 |
ops->node_put(tmp); |
} |
/** Read data from a block device. |
* |
* @param phone Phone to be used to communicate with the device. |
* @param buffer Communication buffer shared with the device. |
* @param bufpos Pointer to the first unread valid offset within the |
* communication buffer. |
* @param buflen Pointer to the number of unread bytes that are ready in |
* the communication buffer. |
* @param pos Device position to be read. |
* @param dst Destination buffer. |
* @param size Size of the destination buffer. |
* @param block_size Block size to be used for the transfer. |
* |
* @return True on success, false on failure. |
*/ |
bool libfs_blockread(int phone, void *buffer, 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; |
while (left > 0) { |
size_t rd; |
if (*bufpos + left < *buflen) |
rd = left; |
else |
rd = *buflen - *bufpos; |
if (rd > 0) { |
/* |
* Copy the contents of the communication buffer to the |
* destination buffer. |
*/ |
memcpy(dst + offset, buffer + *bufpos, rd); |
offset += rd; |
*bufpos += rd; |
*pos += rd; |
left -= rd; |
} |
if (*bufpos == *buflen) { |
/* Refill the communication buffer with a new block. */ |
ipcarg_t retval; |
int rc = async_req_2_1(phone, RD_READ_BLOCK, |
*pos / block_size, block_size, &retval); |
if ((rc != EOK) || (retval != EOK)) |
return false; |
*bufpos = 0; |
*buflen = block_size; |
} |
} |
return true; |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libfs/libfs.h |
---|
69,6 → 69,9 |
extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); |
extern bool libfs_blockread(int, void *, off_t *, size_t *, off_t *, void *, |
size_t, size_t); |
#endif |
/** @} |
/branches/tracing/uspace/lib/libc/include/getopt.h |
---|
0,0 → 1,71 |
/* $NetBSD: getopt.h,v 1.10.6.1 2008/05/18 12:30:09 yamt Exp $ */ |
/*- |
* Copyright (c) 2000 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Dieter Baron and Thomas Klausner. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. 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. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``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 FOUNDATION OR CONTRIBUTORS |
* 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. |
*/ |
/* Ported to HelenOS August 2008 by Tim Post <echo@echoreply.us> */ |
#ifndef _GETOPT_H_ |
#define _GETOPT_H_ |
#include <unistd.h> |
/* |
* Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions |
*/ |
#define no_argument 0 |
#define required_argument 1 |
#define optional_argument 2 |
struct option { |
/* name of long option */ |
const char *name; |
/* |
* one of no_argument, required_argument, and optional_argument: |
* whether option takes an argument |
*/ |
int has_arg; |
/* if not NULL, set *flag to val when option found */ |
int *flag; |
/* if flag not NULL, value to set *flag to; else return value */ |
int val; |
}; |
/* HelenOS Port - These need to be exposed for legacy getopt() */ |
extern char *optarg; |
extern int optind, opterr, optopt; |
extern int optreset; |
int getopt_long(int, char * const *, const char *, |
const struct option *, int *); |
/* HelenOS Port : Expose legacy getopt() */ |
int getopt(int, char * const [], const char *); |
#endif /* !_GETOPT_H_ */ |
/branches/tracing/uspace/lib/libc/include/as.h |
---|
42,6 → 42,7 |
extern void *as_area_create(void *address, size_t size, int flags); |
extern int as_area_resize(void *address, size_t size, int flags); |
extern int as_area_change_flags(void *address, int flags); |
extern int as_area_destroy(void *address); |
extern void *set_maxheapsize(size_t mhs); |
extern void * as_get_mappable_page(size_t sz); |
/branches/tracing/uspace/lib/libc/include/string.h |
---|
47,6 → 47,7 |
extern int strcmp(const char *, const char *); |
extern int strncmp(const char *, const char *, size_t); |
extern int stricmp(const char *, const char *); |
extern char *strcpy(char *, const char *); |
extern char *strncpy(char *, const char *, size_t); |
55,6 → 56,8 |
extern size_t strlen(const char *); |
extern char *strdup(const char *); |
extern char *strchr(const char *, int); |
extern char *strrchr(const char *, int); |
/branches/tracing/uspace/lib/libc/include/vfs/vfs.h |
---|
35,6 → 35,10 |
#ifndef LIBC_VFS_H_ |
#define LIBC_VFS_H_ |
#include <sys/types.h> |
extern char *absolutize(const char *, size_t *); |
extern int mount(const char *, const char *, const char *); |
#endif |
/branches/tracing/uspace/lib/libc/include/stdio.h |
---|
54,16 → 54,17 |
extern int getchar(void); |
extern int puts(const char * str); |
extern int putchar(int c); |
extern int puts(const char *); |
extern int putchar(int); |
extern int printf(const char *fmt, ...); |
extern int sprintf(char *str, const char *fmt, ...); |
extern int snprintf(char *str, size_t size, const char *fmt, ...); |
extern int printf(const char *, ...); |
extern int asprintf(char **, const char *, ...); |
extern int sprintf(char *, const char *fmt, ...); |
extern int snprintf(char *, size_t , const char *, ...); |
extern int vprintf(const char *fmt, va_list ap); |
extern int vsprintf(char *str, const char *fmt, va_list ap); |
extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap); |
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); |
#define fprintf(f, fmt, ...) printf(fmt, ##__VA_ARGS__) |
/branches/tracing/uspace/lib/libc/include/task.h |
---|
40,7 → 40,7 |
typedef uint64_t task_id_t; |
extern task_id_t task_get_id(void); |
extern int task_spawn(void *image, size_t size); |
extern task_id_t task_spawn(const char *path, const char *argv[]); |
#endif |
/branches/tracing/uspace/lib/libc/include/libc.h |
---|
48,7 → 48,7 |
#define __SYSCALL6(id, p1, p2, p3, p4, p5, p6) \ |
__syscall(p1, p2, p3, p4, p5, p6,id) |
extern void __main(void); |
extern void __main(void *pcb_ptr); |
extern void __exit(void); |
#endif |
/branches/tracing/uspace/lib/libc/include/loader/pcb.h |
---|
0,0 → 1,74 |
/* |
* 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 fs |
* @{ |
*/ |
/** @file |
* @brief Program Control Block interface. |
*/ |
#ifndef LIBC_PCB_H_ |
#define LIBC_PCB_H_ |
#include <sys/types.h> |
typedef void (*entry_point_t)(void); |
/** |
* 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; |
/* |
* ELF-specific data |
*/ |
/** Pointer to ELF dynamic section of the program */ |
void *dynamic; |
/** Pointer to dynamic section of the runtime linker */ |
void *rtld_dynamic; |
/** Runtime-linker load bias */ |
uintptr_t rtld_bias; |
} pcb_t; |
extern pcb_t *__pcb; |
#endif |
/** |
* @} |
*/ |
/branches/tracing/uspace/lib/libc/include/io/stream.h |
---|
40,6 → 40,7 |
#define EMFILE -17 |
extern void open_console(void); |
extern void close_console(void); |
extern void klog_update(void); |
extern ssize_t read_stdin(void *, size_t); |
/branches/tracing/uspace/lib/libc/include/smc.h |
---|
0,0 → 1,45 |
/* |
* 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_SMC_H_ |
#define LIBC_SMC_H_ |
#include <sys/types.h> |
extern int smc_coherence(void *address, size_t size); |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/include/ctype.h |
---|
76,6 → 76,14 |
} |
} |
static inline int tolower(int c) |
{ |
if (isupper(c)) |
return (c + ('a' - 'A' > 0 ? 'a' - 'A' : 'A' - 'a')); |
else |
return c; |
} |
#endif |
/** @} |
/branches/tracing/uspace/lib/libc/include/ipc/loader.h |
---|
0,0 → 1,50 |
/* |
* 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 libcipc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_LOADER_H_ |
#define LIBC_LOADER_H_ |
#include <ipc/ipc.h> |
typedef enum { |
LOADER_HELLO = IPC_FIRST_USER_METHOD, |
LOADER_SET_PATHNAME, |
LOADER_SET_ARGS, |
LOADER_RUN |
} fb_request_t; |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/task.c |
---|
1,5 → 1,6 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
33,7 → 34,14 |
*/ |
#include <task.h> |
#include <ipc/ipc.h> |
#include <ipc/loader.h> |
#include <libc.h> |
#include <string.h> |
#include <stdlib.h> |
#include <async.h> |
#include <errno.h> |
#include <vfs/vfs.h> |
task_id_t task_get_id(void) |
{ |
44,10 → 52,136 |
return task_id; |
} |
int task_spawn(void *image, size_t size) |
static int task_spawn_loader(void) |
{ |
return __SYSCALL2(SYS_TASK_SPAWN, (sysarg_t) image, (sysarg_t) size); |
int phone_id, rc; |
rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id); |
if (rc != 0) |
return rc; |
return phone_id; |
} |
static int loader_set_args(int phone_id, const char *argv[]) |
{ |
aid_t req; |
ipc_call_t answer; |
ipcarg_t rc; |
const char **ap; |
char *dp; |
char *arg_buf; |
size_t buffer_size; |
size_t len; |
/* |
* Serialize the arguments into a single array. First |
* compute size of the buffer needed. |
*/ |
ap = argv; |
buffer_size = 0; |
while (*ap != NULL) { |
buffer_size += strlen(*ap) + 1; |
++ap; |
} |
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; |
while (*ap != NULL) { |
strcpy(dp, *ap); |
dp += strlen(*ap) + 1; |
++ap; |
} |
/* Send serialized arguments to the loader */ |
req = async_send_0(phone_id, LOADER_SET_ARGS, &answer); |
rc = ipc_data_write_start(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; |
/* Free temporary buffer */ |
free(arg_buf); |
return EOK; |
} |
/** Create a new task by running an executable from VFS. |
* |
* @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, const char *argv[]) |
{ |
int phone_id; |
ipc_call_t answer; |
aid_t req; |
int rc; |
ipcarg_t retval; |
char *pa; |
size_t pa_len; |
pa = absolutize(path, &pa_len); |
if (!pa) |
return 0; |
/* Spawn a program loader */ |
phone_id = task_spawn_loader(); |
if (phone_id < 0) |
return 0; |
/* |
* Say hello so that the loader knows the incoming connection's |
* phone hash. |
*/ |
rc = async_req_0_0(phone_id, LOADER_HELLO); |
if (rc != EOK) |
return 0; |
/* Send program pathname */ |
req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer); |
rc = ipc_data_write_start(phone_id, (void *)pa, pa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return 1; |
} |
async_wait_for(req, &retval); |
if (retval != EOK) |
goto error; |
/* Send arguments */ |
rc = loader_set_args(phone_id, argv); |
if (rc != EOK) |
goto error; |
/* Request loader to start the program */ |
rc = async_req_0_0(phone_id, LOADER_RUN); |
if (rc != EOK) |
goto error; |
/* Success */ |
ipc_hangup(phone_id); |
return 1; |
/* Error exit */ |
error: |
ipc_hangup(phone_id); |
return 0; |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/getopt.c |
---|
0,0 → 1,478 |
/* $NetBSD: getopt_long.c,v 1.21.4.1 2008/01/09 01:34:14 matt Exp $ */ |
/*- |
* Copyright (c) 2000 The NetBSD Foundation, Inc. |
* All rights reserved. |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* by Dieter Baron and Thomas Klausner. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. 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. |
* |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
* ``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 FOUNDATION OR CONTRIBUTORS |
* 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. |
*/ |
/* Ported to HelenOS August 2008 by Tim Post <echo@echoreply.us> */ |
#include <assert.h> |
#include <stdarg.h> |
#include <err.h> |
#include <errno.h> |
#include <getopt.h> |
#include <stdlib.h> |
#include <string.h> |
/* HelenOS Port : We're incorporating only the modern getopt_long with wrappers |
* to keep legacy getopt() usage from breaking. All references to REPLACE_GETOPT |
* are dropped, we just include the code */ |
int opterr = 1; /* if error message should be printed */ |
int optind = 1; /* index into parent argv vector */ |
int optopt = '?'; /* character checked for validity */ |
int optreset; /* reset getopt */ |
char *optarg; /* argument associated with option */ |
#define IGNORE_FIRST (*options == '-' || *options == '+') |
#define PRINT_ERROR ((opterr) && ((*options != ':') \ |
|| (IGNORE_FIRST && options[1] != ':'))) |
/*HelenOS Port - POSIXLY_CORRECT is always false */ |
#define IS_POSIXLY_CORRECT 0 |
#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) |
/* XXX: GNU ignores PC if *options == '-' */ |
#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') |
/* return values */ |
#define BADCH (int)'?' |
#define BADARG ((IGNORE_FIRST && options[1] == ':') \ |
|| (*options == ':') ? (int)':' : (int)'?') |
#define INORDER (int)1 |
#define EMSG "" |
static int getopt_internal(int, char **, const char *); |
static int gcd(int, int); |
static void permute_args(int, int, int, char **); |
static const char *place = EMSG; /* option letter processing */ |
/* XXX: set optreset to 1 rather than these two */ |
static int nonopt_start = -1; /* first non option argument (for permute) */ |
static int nonopt_end = -1; /* first option after non options (for permute) */ |
/* Error messages */ |
/* HelenOS Port: Calls to warnx() were eliminated (as we have no stderr that |
* may be redirected) and replaced with printf. As such, error messages now |
* end in a newline */ |
static const char recargchar[] = "option requires an argument -- %c\n"; |
static const char recargstring[] = "option requires an argument -- %s\n"; |
static const char ambig[] = "ambiguous option -- %.*s\n"; |
static const char noarg[] = "option doesn't take an argument -- %.*s\n"; |
static const char illoptchar[] = "unknown option -- %c\n"; |
static const char illoptstring[] = "unknown option -- %s\n"; |
/* |
* Compute the greatest common divisor of a and b. |
*/ |
static int |
gcd(a, b) |
int a; |
int b; |
{ |
int c; |
c = a % b; |
while (c != 0) { |
a = b; |
b = c; |
c = a % b; |
} |
return b; |
} |
/* |
* Exchange the block from nonopt_start to nonopt_end with the block |
* from nonopt_end to opt_end (keeping the same order of arguments |
* in each block). |
*/ |
static void |
permute_args(panonopt_start, panonopt_end, opt_end, nargv) |
int panonopt_start; |
int panonopt_end; |
int opt_end; |
char **nargv; |
{ |
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; |
char *swap; |
assert(nargv != NULL); |
/* |
* compute lengths of blocks and number and size of cycles |
*/ |
nnonopts = panonopt_end - panonopt_start; |
nopts = opt_end - panonopt_end; |
ncycle = gcd(nnonopts, nopts); |
cyclelen = (opt_end - panonopt_start) / ncycle; |
for (i = 0; i < ncycle; i++) { |
cstart = panonopt_end+i; |
pos = cstart; |
for (j = 0; j < cyclelen; j++) { |
if (pos >= panonopt_end) |
pos -= nnonopts; |
else |
pos += nopts; |
swap = nargv[pos]; |
nargv[pos] = nargv[cstart]; |
nargv[cstart] = swap; |
} |
} |
} |
/* |
* getopt_internal -- |
* Parse argc/argv argument vector. Called by user level routines. |
* Returns -2 if -- is found (can be long option or end of options marker). |
*/ |
static int |
getopt_internal(nargc, nargv, options) |
int nargc; |
char **nargv; |
const char *options; |
{ |
char *oli; /* option letter list index */ |
int optchar; |
assert(nargv != NULL); |
assert(options != NULL); |
optarg = NULL; |
/* |
* XXX Some programs (like rsyncd) expect to be able to |
* XXX re-initialize optind to 0 and have getopt_long(3) |
* XXX properly function again. Work around this braindamage. |
*/ |
if (optind == 0) |
optind = 1; |
if (optreset) |
nonopt_start = nonopt_end = -1; |
start: |
if (optreset || !*place) { /* update scanning pointer */ |
optreset = 0; |
if (optind >= nargc) { /* end of argument vector */ |
place = EMSG; |
if (nonopt_end != -1) { |
/* do permutation, if we have to */ |
permute_args(nonopt_start, nonopt_end, |
optind, nargv); |
optind -= nonopt_end - nonopt_start; |
} |
else if (nonopt_start != -1) { |
/* |
* If we skipped non-options, set optind |
* to the first of them. |
*/ |
optind = nonopt_start; |
} |
nonopt_start = nonopt_end = -1; |
return -1; |
} |
if ((*(place = nargv[optind]) != '-') |
|| (place[1] == '\0')) { /* found non-option */ |
place = EMSG; |
if (IN_ORDER) { |
/* |
* GNU extension: |
* return non-option as argument to option 1 |
*/ |
optarg = nargv[optind++]; |
return INORDER; |
} |
if (!PERMUTE) { |
/* |
* if no permutation wanted, stop parsing |
* at first non-option |
*/ |
return -1; |
} |
/* do permutation */ |
if (nonopt_start == -1) |
nonopt_start = optind; |
else if (nonopt_end != -1) { |
permute_args(nonopt_start, nonopt_end, |
optind, nargv); |
nonopt_start = optind - |
(nonopt_end - nonopt_start); |
nonopt_end = -1; |
} |
optind++; |
/* process next argument */ |
goto start; |
} |
if (nonopt_start != -1 && nonopt_end == -1) |
nonopt_end = optind; |
if (place[1] && *++place == '-') { /* found "--" */ |
place++; |
return -2; |
} |
} |
if ((optchar = (int)*place++) == (int)':' || |
(oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { |
/* option letter unknown or ':' */ |
if (!*place) |
++optind; |
if (PRINT_ERROR) |
printf(illoptchar, optchar); |
optopt = optchar; |
return BADCH; |
} |
if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ |
/* XXX: what if no long options provided (called by getopt)? */ |
if (*place) |
return -2; |
if (++optind >= nargc) { /* no arg */ |
place = EMSG; |
if (PRINT_ERROR) |
printf(recargchar, optchar); |
optopt = optchar; |
return BADARG; |
} else /* white space */ |
place = nargv[optind]; |
/* |
* Handle -W arg the same as --arg (which causes getopt to |
* stop parsing). |
*/ |
return -2; |
} |
if (*++oli != ':') { /* doesn't take argument */ |
if (!*place) |
++optind; |
} else { /* takes (optional) argument */ |
optarg = NULL; |
if (*place) /* no white space */ |
optarg = *place; |
/* XXX: disable test for :: if PC? (GNU doesn't) */ |
else if (oli[1] != ':') { /* arg not optional */ |
if (++optind >= nargc) { /* no arg */ |
place = EMSG; |
if (PRINT_ERROR) |
printf(recargchar, optchar); |
optopt = optchar; |
return BADARG; |
} else |
optarg = nargv[optind]; |
} |
place = EMSG; |
++optind; |
} |
/* dump back option letter */ |
return optchar; |
} |
/* |
* getopt -- |
* Parse argc/argv argument vector. |
*/ |
int |
getopt(nargc, nargv, options) |
int nargc; |
char * const *nargv; |
const char *options; |
{ |
int retval; |
assert(nargv != NULL); |
assert(options != NULL); |
retval = getopt_internal(nargc, (char **)nargv, options); |
if (retval == -2) { |
++optind; |
/* |
* We found an option (--), so if we skipped non-options, |
* we have to permute. |
*/ |
if (nonopt_end != -1) { |
permute_args(nonopt_start, nonopt_end, optind, |
(char **)nargv); |
optind -= nonopt_end - nonopt_start; |
} |
nonopt_start = nonopt_end = -1; |
retval = -1; |
} |
return retval; |
} |
/* |
* getopt_long -- |
* Parse argc/argv argument vector. |
*/ |
int |
getopt_long(nargc, nargv, options, long_options, idx) |
int nargc; |
char * const *nargv; |
const char *options; |
const struct option *long_options; |
int *idx; |
{ |
int retval; |
#define IDENTICAL_INTERPRETATION(_x, _y) \ |
(long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ |
long_options[(_x)].flag == long_options[(_y)].flag && \ |
long_options[(_x)].val == long_options[(_y)].val) |
assert(nargv != NULL); |
assert(options != NULL); |
assert(long_options != NULL); |
/* idx may be NULL */ |
retval = getopt_internal(nargc, (char **)nargv, options); |
if (retval == -2) { |
char *current_argv, *has_equal; |
size_t current_argv_len; |
int i, ambiguous, match; |
current_argv = (char *)place; |
match = -1; |
ambiguous = 0; |
optind++; |
place = EMSG; |
if (*current_argv == '\0') { /* found "--" */ |
/* |
* We found an option (--), so if we skipped |
* non-options, we have to permute. |
*/ |
if (nonopt_end != -1) { |
permute_args(nonopt_start, nonopt_end, |
optind, (char **)nargv); |
optind -= nonopt_end - nonopt_start; |
} |
nonopt_start = nonopt_end = -1; |
return -1; |
} |
if ((has_equal = strchr(current_argv, '=')) != NULL) { |
/* argument found (--option=arg) */ |
current_argv_len = has_equal - current_argv; |
has_equal++; |
} else |
current_argv_len = strlen(current_argv); |
for (i = 0; long_options[i].name; i++) { |
/* find matching long option */ |
if (strncmp(current_argv, long_options[i].name, |
current_argv_len)) |
continue; |
if (strlen(long_options[i].name) == |
(unsigned)current_argv_len) { |
/* exact match */ |
match = i; |
ambiguous = 0; |
break; |
} |
if (match == -1) /* partial match */ |
match = i; |
else if (!IDENTICAL_INTERPRETATION(i, match)) |
ambiguous = 1; |
} |
if (ambiguous) { |
/* ambiguous abbreviation */ |
if (PRINT_ERROR) |
printf(ambig, (int)current_argv_len, |
current_argv); |
optopt = 0; |
return BADCH; |
} |
if (match != -1) { /* option found */ |
if (long_options[match].has_arg == no_argument |
&& has_equal) { |
if (PRINT_ERROR) |
printf(noarg, (int)current_argv_len, |
current_argv); |
/* |
* XXX: GNU sets optopt to val regardless of |
* flag |
*/ |
if (long_options[match].flag == NULL) |
optopt = long_options[match].val; |
else |
optopt = 0; |
return BADARG; |
} |
if (long_options[match].has_arg == required_argument || |
long_options[match].has_arg == optional_argument) { |
if (has_equal) |
optarg = has_equal; |
else if (long_options[match].has_arg == |
required_argument) { |
/* |
* optional argument doesn't use |
* next nargv |
*/ |
optarg = nargv[optind++]; |
} |
} |
if ((long_options[match].has_arg == required_argument) |
&& (optarg == NULL)) { |
/* |
* Missing argument; leading ':' |
* indicates no error should be generated |
*/ |
if (PRINT_ERROR) |
printf(recargstring, current_argv); |
/* |
* XXX: GNU sets optopt to val regardless |
* of flag |
*/ |
if (long_options[match].flag == NULL) |
optopt = long_options[match].val; |
else |
optopt = 0; |
--optind; |
return BADARG; |
} |
} else { /* unknown option */ |
if (PRINT_ERROR) |
printf(illoptstring, current_argv); |
optopt = 0; |
return BADCH; |
} |
if (long_options[match].flag) { |
*long_options[match].flag = long_options[match].val; |
retval = 0; |
} else |
retval = long_options[match].val; |
if (idx) |
*idx = match; |
} |
return retval; |
#undef IDENTICAL_INTERPRETATION |
} |
/branches/tracing/uspace/lib/libc/generic/as.c |
---|
85,6 → 85,20 |
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. |
* |
* @return Zero on success or a code from @ref errno.h on failure. |
*/ |
int as_area_change_flags(void *address, int flags) |
{ |
return __SYSCALL2(SYS_AS_AREA_CHANGE_FLAGS, (sysarg_t) address, |
(sysarg_t) flags); |
} |
static size_t heapsize = 0; |
static size_t maxheapsize = (size_t) (-1); |
/branches/tracing/uspace/lib/libc/generic/pcb.c |
---|
0,0 → 1,40 |
/* |
* 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 <loader/pcb.h> |
pcb_t *__pcb; |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/string.c |
---|
38,8 → 38,8 |
#include <limits.h> |
#include <align.h> |
#include <sys/types.h> |
#include <malloc.h> |
/* Dummy implementation of mem/ functions */ |
void *memset(void *s, int c, size_t n) |
66,9 → 66,10 |
adst[i].n = asrc[i].n; |
for (j = 0; j < n % sizeof(unsigned long); j++) |
((unsigned char *) (((unsigned long *) dst) + i))[j] = ((unsigned char *) (((unsigned long *) src) + i))[j]; |
((unsigned char *) (((unsigned long *) dst) + i))[j] = |
((unsigned char *) (((unsigned long *) src) + i))[j]; |
return (char *) src; |
return (char *) dst; |
} |
void *memcpy(void *dst, const void *src, size_t n) |
75,7 → 76,8 |
{ |
int i, j; |
if (((long) dst & (sizeof(long) - 1)) || ((long) src & (sizeof(long) - 1))) |
if (((long) dst & (sizeof(long) - 1)) || |
((long) src & (sizeof(long) - 1))) |
return unaligned_memcpy(dst, src, n); |
for (i = 0; i < n / sizeof(unsigned long); i++) |
82,9 → 84,10 |
((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
for (j = 0; j < n % sizeof(unsigned long); j++) |
((unsigned char *) (((unsigned long *) dst) + i))[j] = ((unsigned char *) (((unsigned long *) src) + i))[j]; |
((unsigned char *) (((unsigned long *) dst) + i))[j] = |
((unsigned char *) (((unsigned long *) src) + i))[j]; |
return (char *) src; |
return (char *) dst; |
} |
void *memmove(void *dst, const void *src, size_t n) |
95,22 → 98,23 |
return memcpy(dst, src, n); |
for (j = (n % sizeof(unsigned long)) - 1; j >= 0; j--) |
((unsigned char *) ((unsigned long *) dst))[j] = ((unsigned char *) ((unsigned long *) src))[j]; |
((unsigned char *) ((unsigned long *) dst))[j] = |
((unsigned char *) ((unsigned long *) src))[j]; |
for (i = n / sizeof(unsigned long) - 1; i >=0 ; i--) |
((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
return (char *) src; |
return (char *) dst; |
} |
/** Compare two memory areas. |
* |
* @param s1 Pointer to the first area to compare. |
* @param s2 Pointer to the second area to compare. |
* @param len Size of the first area in bytes. Both areas must have the same |
* length. |
* @return If len is 0, return zero. If the areas match, return zero. |
* Otherwise return non-zero. |
* @param s1 Pointer to the first area to compare. |
* @param s2 Pointer to the second area to compare. |
* @param len Size of the first area in bytes. Both areas must have |
* the same length. |
* @return If len is 0, return zero. If the areas match, return |
* zero. Otherwise return non-zero. |
*/ |
int bcmp(const char *s1, const char *s2, size_t len) |
{ |
120,8 → 124,9 |
} |
/** Count the number of characters in the string, not including terminating 0. |
* @param str string |
* @return number of characters in string. |
* |
* @param str String. |
* @return Number of characters in string. |
*/ |
size_t strlen(const char *str) |
{ |
141,7 → 146,6 |
c++; |
return (a[c] - b[c]); |
} |
int strncmp(const char *a, const char *b, size_t n) |
155,10 → 159,22 |
} |
/** Return pointer to the first occurence of character c in string |
* @param str scanned string |
* @param c searched character (taken as one byte) |
* @return pointer to the matched character or NULL if it is not found in given string. |
int stricmp(const char *a, const char *b) |
{ |
int c = 0; |
while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c])))) |
c++; |
return (tolower(a[c]) - tolower(b[c])); |
} |
/** Return pointer to the first occurence of character c in string. |
* |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
*/ |
char *strchr(const char *str, int c) |
{ |
171,10 → 187,12 |
return NULL; |
} |
/** Return pointer to the last occurence of character c in string |
* @param str scanned string |
* @param c searched character (taken as one byte) |
* @return pointer to the matched character or NULL if it is not found in given string. |
/** Return pointer to the last occurence of character c in string. |
* |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
*/ |
char *strrchr(const char *str, int c) |
{ |
191,13 → 209,16 |
/** Convert string to a number. |
* Core of strtol and strtoul functions. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @param sgn its set to 1 if minus found |
* @return result of conversion. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character. |
* @param base Zero or number between 2 and 36 inclusive. |
* @param sgn It's set to 1 if minus found. |
* @return Result of conversion. |
*/ |
static unsigned long _strtoul(const char *nptr, char **endptr, int base, char *sgn) |
static unsigned long |
_strtoul(const char *nptr, char **endptr, int base, char *sgn) |
{ |
unsigned char c; |
unsigned long result = 0; |
219,7 → 240,8 |
/* FIXME: set errno to EINVAL */ |
return 0; |
} |
if ((base == 16) && (*str == '0') && ((str[1] == 'x') || (str[1] == 'X'))) { |
if ((base == 16) && (*str == '0') && ((str[1] == 'x') || |
(str[1] == 'X'))) { |
str += 2; |
} |
} else { |
238,7 → 260,8 |
while (*str) { |
c = *str; |
c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 : (c <= '9' ? c - '0' : 0xff))); |
c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 : |
(c <= '9' ? c - '0' : 0xff))); |
if (c > base) { |
break; |
} |
257,7 → 280,10 |
} |
if (str == tmpptr) { |
/* no number was found => first invalid character is the first character of the string */ |
/* |
* No number was found => first invalid character is the first |
* character of the string. |
*/ |
/* FIXME: set errno to EINVAL */ |
str = nptr; |
result = 0; |
275,14 → 301,17 |
} |
/** Convert initial part of string to long int according to given base. |
* The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-'). |
* If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one. |
* If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8). |
* Otherwise the base 0 is taken as decimal. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @return result of conversion. |
* The number may begin with an arbitrary number of whitespaces followed by |
* optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be |
* inserted and the number will be taken as hexadecimal one. If the base is 0 |
* and the number begin with a zero, number will be taken as octal one (as with |
* base 8). Otherwise the base 0 is taken as decimal. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character. |
* @param base Zero or number between 2 and 36 inclusive. |
* @return Result of conversion. |
*/ |
long int strtol(const char *nptr, char **endptr, int base) |
{ |
305,14 → 334,17 |
/** Convert initial part of string to unsigned long according to given base. |
* The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-'). |
* If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one. |
* If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8). |
* Otherwise the base 0 is taken as decimal. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @return result of conversion. |
* The number may begin with an arbitrary number of whitespaces followed by |
* optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be |
* inserted and the number will be taken as hexadecimal one. If the base is 0 |
* and the number begin with a zero, number will be taken as octal one (as with |
* base 8). Otherwise the base 0 is taken as decimal. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character |
* @param base Zero or number between 2 and 36 inclusive. |
* @return Result of conversion. |
*/ |
unsigned long strtoul(const char *nptr, char **endptr, int base) |
{ |
353,5 → 385,16 |
return orig; |
} |
char * strdup(const char *s1) |
{ |
size_t len = strlen(s1) + 1; |
void *ret = malloc(len); |
if (ret == NULL) |
return (char *) NULL; |
return (char *) memcpy(ret, s1, len); |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/libc.c |
---|
48,8 → 48,10 |
#include <ipc/ipc.h> |
#include <async.h> |
#include <as.h> |
#include <loader/pcb.h> |
extern char _heap; |
extern int main(int argc, char *argv[]); |
void _exit(int status) |
{ |
56,9 → 58,11 |
thread_exit(status); |
} |
void __main(void) |
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(); |
66,6 → 70,19 |
__tcb_set(f->tcb); |
open_console(); |
/* Save the PCB pointer */ |
__pcb = (pcb_t *)pcb_ptr; |
if (__pcb == NULL) { |
argc = 0; |
argv = NULL; |
} else { |
argc = __pcb->argc; |
argv = __pcb->argv; |
} |
main(argc, argv); |
} |
void __exit(void) |
/branches/tracing/uspace/lib/libc/generic/ipc.c |
---|
682,7 → 682,7 |
{ |
int res; |
sysarg_t tmp_flags; |
res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, |
res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, |
(ipcarg_t) size, arg, NULL, &tmp_flags); |
if (flags) |
*flags = tmp_flags; |
742,7 → 742,7 |
*/ |
int ipc_share_out_start(int phoneid, void *src, int flags) |
{ |
return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, |
return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, |
(ipcarg_t) flags); |
} |
803,7 → 803,7 |
*/ |
int ipc_data_read_start(int phoneid, void *dst, size_t size) |
{ |
return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, |
return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, |
(ipcarg_t) size); |
} |
862,7 → 862,7 |
*/ |
int ipc_data_write_start(int phoneid, void *src, size_t size) |
{ |
return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, |
return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, |
(ipcarg_t) size); |
} |
/branches/tracing/uspace/lib/libc/generic/vfs/vfs.c |
---|
59,9 → 59,10 |
char *cwd_path = NULL; |
size_t cwd_len = 0; |
static char *absolutize(const char *path, size_t *retlen) |
char *absolutize(const char *path, size_t *retlen) |
{ |
char *ncwd_path; |
char *ncwd_path_nc; |
futex_down(&cwd_futex); |
size_t len = strlen(path); |
70,28 → 71,40 |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path = malloc(len + cwd_len + 1); |
if (!ncwd_path) { |
ncwd_path_nc = malloc(cwd_len + 1 + len + 1); |
if (!ncwd_path_nc) { |
futex_up(&cwd_futex); |
return NULL; |
} |
strcpy(ncwd_path, cwd_path); |
ncwd_path[cwd_len] = '/'; |
ncwd_path[cwd_len + 1] = '\0'; |
strcpy(ncwd_path_nc, cwd_path); |
ncwd_path_nc[cwd_len] = '/'; |
ncwd_path_nc[cwd_len + 1] = '\0'; |
} else { |
ncwd_path = malloc(len + 1); |
if (!ncwd_path) { |
ncwd_path_nc = malloc(len + 1); |
if (!ncwd_path_nc) { |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path[0] = '\0'; |
ncwd_path_nc[0] = '\0'; |
} |
strcat(ncwd_path, path); |
if (!canonify(ncwd_path, retlen)) { |
strcat(ncwd_path_nc, path); |
ncwd_path = canonify(ncwd_path_nc, retlen); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
free(ncwd_path); |
free(ncwd_path_nc); |
return NULL; |
} |
/* |
* We need to clone ncwd_path because canonify() works in-place and thus |
* the address in ncwd_path need not be the same as ncwd_path_nc, even |
* though they both point into the same dynamically allocated buffer. |
*/ |
ncwd_path = strdup(ncwd_path); |
free(ncwd_path_nc); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
futex_up(&cwd_futex); |
return ncwd_path; |
} |
105,7 → 118,8 |
static int device_get_handle(char *name, dev_handle_t *handle) |
{ |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, 0); |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, |
0); |
if (phone < 0) |
return phone; |
171,6 → 185,15 |
free(mpa); |
return (int) rc; |
} |
/* Ask VFS whether it likes fs_name. */ |
rc = async_req_0_0(vfs_phone, IPC_M_PING); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return (int) rc; |
} |
rc = ipc_data_write_start(vfs_phone, (void *)mpa, mpa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
222,6 → 245,9 |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
if (rc != EOK) |
return (int) rc; |
return (int) IPC_GET_ARG1(answer); |
} |
285,7 → 311,7 |
if (rc == EOK) |
return (ssize_t) IPC_GET_ARG1(answer); |
else |
return -1; |
return rc; |
} |
ssize_t write(int fildes, const void *buf, size_t nbyte) |
/branches/tracing/uspace/lib/libc/generic/vfs/canonify.c |
---|
125,6 → 125,7 |
static void set_first_slash(token_t *t, token_t *tfsl, token_t *tlcomp) |
{ |
*tfsl = *t; |
*tlcomp = *t; |
} |
static void save_component(token_t *t, token_t *tfsl, token_t *tlcomp) |
{ |
/branches/tracing/uspace/lib/libc/generic/smc.c |
---|
0,0 → 1,45 |
/* |
* 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 <sys/types.h> |
int smc_coherence(void *address, size_t size) |
{ |
return __SYSCALL2(SYS_SMC_COHERENCE, (sysarg_t) address, |
(sysarg_t) size); |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/io/sprintf.c |
---|
48,7 → 48,6 |
va_start(args, fmt); |
ret = vsprintf(str, fmt, args); |
va_end(args); |
return ret; |
/branches/tracing/uspace/lib/libc/generic/io/asprintf.c |
---|
0,0 → 1,79 |
/* |
* Copyright (c) 2006 Josef Cejka |
* 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 |
*/ |
#include <stdarg.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <io/printf_core.h> |
static int asprintf_prewrite(const char *str, size_t count, void *unused) |
{ |
return 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. |
* |
* @return Number of characters printed or a negative error code. |
*/ |
int asprintf(char **strp, const char *fmt, ...) |
{ |
struct printf_spec ps = { |
asprintf_prewrite, |
NULL |
}; |
int ret; |
va_list args; |
va_start(args, fmt); |
ret = printf_core(fmt, &ps, args); |
va_end(args); |
if (ret > 0) { |
*strp = malloc(ret + 20); |
if (!*strp) |
return -1; |
va_start(args, fmt); |
vsprintf(*strp, fmt, args); |
va_end(args); |
} |
return ret; |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/io/vsnprintf.c |
---|
38,22 → 38,27 |
#include <io/printf_core.h> |
struct vsnprintf_data { |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
}; |
/** Write string to given buffer. |
* Write at most data->size characters including trailing zero. According to C99 has snprintf to return number |
* of characters that would have been written if enough space had been available. Hence the return value is not |
* number of really printed characters but size of input string. Number of really used characters |
* is stored in data->len. |
* @param str source string to print |
* @param count size of source string |
* @param data structure with destination string, counter of used space and total string size. |
* @return number of characters to print (not characters really printed!) |
* Write at most data->size characters including trailing zero. According to C99 |
* has snprintf to return number of characters that would have been written if |
* enough space had been available. Hence the return value is not number of |
* really printed characters but size of input string. Number of really used |
* characters is stored in data->len. |
* |
* @param str Source string to print. |
* @param count Size of the source string. |
* @param data Structure with destination string, counter of used space |
* and total string size. |
* @return Number of characters to print (not characters really |
* printed!) |
*/ |
static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
static int |
vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
{ |
size_t i; |
i = data->size - data->len; |
63,7 → 68,10 |
} |
if (i == 1) { |
/* We have only one free byte left in buffer => write there trailing zero */ |
/* |
* We have only one free byte left in buffer => write there |
* trailing zero. |
*/ |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
70,17 → 78,23 |
} |
if (i <= count) { |
/* We have not enought space for whole string with the trailing zero => print only a part of string */ |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
/* |
* We have not enought space for whole string with the trailing |
* zero => print only a part of string. |
*/ |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
} |
/* Buffer is big enought to print whole string */ |
memcpy((void *)(data->string + data->len), (void *)str, count); |
data->len += count; |
/* Put trailing zero at end, but not count it into data->len so it could be rewritten next time */ |
/* |
* Put trailing zero at end, but not count it into data->len so it could |
* be rewritten next time. |
*/ |
data->string[data->len] = 0; |
return count; |
87,17 → 101,22 |
} |
/** 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 Bffer size. |
* @param fmt Format string. |
* \see For more details about format string see printf_core. |
*/ |
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) |
{ |
struct vsnprintf_data data = {size, 0, str}; |
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vsnprintf_write, &data}; |
struct printf_spec ps = { |
(int(*)(void *, size_t, void *)) vsnprintf_write, |
&data |
}; |
/* Print 0 at end of string - fix the case that nothing will be printed */ |
/* |
* Print 0 at end of string - fix the case that nothing will be printed. |
*/ |
if (size > 0) |
str[0] = 0; |
/branches/tracing/uspace/lib/libc/generic/io/printf_core.c |
---|
94,12 → 94,9 |
if (str == NULL) |
return printf_putnchars("(NULL)", 6, ps); |
for (count = 0; str[count] != 0; count++); |
count = strlen(str); |
if (ps->write((void *) str, count, ps->data) == count) |
return 0; |
return EOF; |
return ps->write((void *) str, count, ps->data); |
} |
/** Print one character to output |
/branches/tracing/uspace/lib/libc/generic/io/stream.c |
---|
96,6 → 96,15 |
} |
} |
void close_console(void) |
{ |
if (console_phone >= 0) { |
if (ipc_hangup(console_phone) == 0) { |
console_phone = -1; |
} |
} |
} |
void klog_update(void) |
{ |
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0); |
/branches/tracing/uspace/lib/libc/Makefile |
---|
51,10 → 51,13 |
generic/cap.c \ |
generic/string.c \ |
generic/fibril.c \ |
generic/pcb.c \ |
generic/smc.c \ |
generic/thread.c \ |
generic/tls.c \ |
generic/task.c \ |
generic/futex.c \ |
generic/io/asprintf.c \ |
generic/io/io.c \ |
generic/io/printf.c \ |
generic/io/stream.c \ |
68,6 → 71,7 |
generic/sysinfo.c \ |
generic/ipc.c \ |
generic/async.c \ |
generic/getopt.c \ |
generic/libadt/list.o \ |
generic/libadt/hash_table.o \ |
generic/time.c \ |
/branches/tracing/uspace/lib/libc/arch/sparc64/include/config.h |
---|
37,7 → 37,6 |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /**< Only one page color. */ |
#endif |
/branches/tracing/uspace/lib/libc/arch/sparc64/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/sparc64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin |
ARCH_SOURCES += arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
/branches/tracing/uspace/lib/libc/arch/sparc64/src/entry.s |
---|
34,12 → 34,15 |
## User-space task entry point |
# |
# %o0 contains uarg |
# %o1 contains pcb_ptr |
# |
__entry: |
# Pass pcb_ptr as the first argument to __main() |
mov %o1, %o0 |
sethi %hi(_gp), %l7 |
call __main |
or %l7, %lo(_gp), %l7 |
call main |
nop |
call __exit |
nop |
/branches/tracing/uspace/lib/libc/arch/ia64/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_ia64_CONFIG_H_ |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/tracing/uspace/lib/libc/arch/ia64/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ia64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin |
CFLAGS += -fno-unwind-tables -DMALLOC_ALIGNMENT_16 |
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS += |
/branches/tracing/uspace/lib/libc/arch/ia64/src/entry.s |
---|
34,12 → 34,14 |
## User-space task entry point |
# |
# r2 contains the PCB pointer |
# |
__entry: |
alloc loc0 = ar.pfs, 0, 1, 2, 0 |
mov r1 = _gp |
mov r1 = _gp |
# Pass PCB pointer as the first argument to __main |
mov out0 = r2 |
br.call.sptk.many b0 = __main |
0: |
br.call.sptk.many b0 = main |
1: |
br.call.sptk.many b0 = __exit |
/branches/tracing/uspace/lib/libc/arch/arm32/include/byteorder.h |
---|
36,7 → 36,7 |
#ifndef LIBC_arm32_BYTEORDER_H_ |
#define LIBC_arm32_BYTEORDER_H_ |
#define ARCH_IS_BIG_ENDIAN |
#define ARCH_IS_LITTLE_ENDIAN |
#endif |
/branches/tracing/uspace/lib/libc/arch/arm32/include/config.h |
---|
38,7 → 38,6 |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/tracing/uspace/lib/libc/arch/arm32/Makefile.inc |
---|
30,8 → 30,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = /usr/local/arm/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin |
CFLAGS += -ffixed-r9 -mtp=soft |
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS += |
/branches/tracing/uspace/lib/libc/arch/arm32/src/entry.s |
---|
34,8 → 34,11 |
## User-space task entry point |
# |
# r1 contains the PCB pointer |
# |
__entry: |
# Pass pcb_ptr to __main as the first argument (in r0) |
mov r0, r1 |
bl __main |
bl main |
bl __exit |
/branches/tracing/uspace/lib/libc/arch/mips32eb/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin |
CFLAGS += -mips3 |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
/branches/tracing/uspace/lib/libc/arch/ppc32/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_ppc32_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/tracing/uspace/lib/libc/arch/ppc32/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
/branches/tracing/uspace/lib/libc/arch/ppc32/src/entry.s |
---|
34,8 → 34,11 |
## User-space task entry point |
# |
# r3 contains the PCB pointer |
# |
__entry: |
# Pass the PCB pointer to __main() as the first argument. |
# Since the first argument is passed in r3, no operation is needed. |
bl __main |
bl main |
bl __exit |
/branches/tracing/uspace/lib/libc/arch/amd64/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_amd64_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/tracing/uspace/lib/libc/arch/amd64/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = amd64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/amd64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
/branches/tracing/uspace/lib/libc/arch/amd64/src/entry.s |
---|
34,8 → 34,11 |
## User-space task entry point |
# |
# %rdi contains the PCB pointer |
# |
__entry: |
# %rdi was deliberately chosen as the first argument is also in %rdi |
# Pass PCB pointer to __main (no operation) |
call __main |
call main |
call __exit |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_ppc64_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/tracing/uspace/lib/libc/arch/ppc64/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc64/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
/branches/tracing/uspace/lib/libc/arch/ppc64/src/entry.s |
---|
31,7 → 31,6 |
.org 0 |
.globl __entry |
.globl __entry_driver |
## User-space task entry point |
# |
38,11 → 37,4 |
# |
__entry: |
bl __main |
bl __io_init |
bl main |
bl __exit |
__entry_driver: |
bl __main |
bl main |
bl __exit |
/branches/tracing/uspace/lib/libc/arch/mips32/include/config.h |
---|
36,8 → 36,7 |
#define LIBC_mips32_CONFIG_H_ |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/branches/tracing/uspace/lib/libc/arch/mips32/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = /usr/local/mipsel/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin |
CFLAGS += -mips3 |
-include ../../Makefile.config |
/branches/tracing/uspace/lib/libc/arch/mips32/src/entry.s |
---|
35,13 → 35,13 |
## User-space task entry point |
# |
# $a0 ($4) contains the PCB pointer |
# |
.ent __entry |
__entry: |
.frame $sp, 32, $31 |
.cpload $25 |
# Mips o32 may store its arguments on stack, make space (16 bytes), |
# so that it could work with -O0 |
# Make space additional 16 bytes for the stack frame |
48,13 → 48,14 |
addiu $sp, -32 |
.cprestore 16 # Allow PIC code |
# Pass pcb_ptr to __main() as the first argument. pcb_ptr is already |
# in $a0. As the first argument is passed in $a0, no operation |
# is needed. |
jal __main |
nop |
jal main |
nop |
jal __exit |
nop |
.end |
/branches/tracing/uspace/lib/libc/arch/ia32/include/config.h |
---|
37,7 → 37,6 |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/tracing/uspace/lib/libc/arch/ia32/Makefile.inc |
---|
29,8 → 29,12 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
/branches/tracing/uspace/lib/libc/arch/ia32/src/entry.s |
---|
34,6 → 34,7 |
## User-space task entry point |
# |
# %ebx contains the PCB pointer |
# |
__entry: |
mov %ss, %ax |
41,7 → 42,9 |
mov %ax, %es |
mov %ax, %fs |
# Do not set %gs, it contains descriptor that can see TLS |
# Pass the PCB pointer to __main as the first argument |
pushl %ebx |
call __main |
call main |
call __exit |