/branches/sparc/uspace/app/bdsh/cmds/mknewcmd |
---|
120,8 → 120,8 |
EOF |
[ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/entry.h |
/* Entry points for the ${CMDNAME} command */ |
extern int * ${CMDENTRY}(char **); |
extern void * ${HELPENTRY}(unsigned int); |
extern int ${CMDENTRY}(char **); |
extern void ${HELPENTRY}(unsigned int); |
#endif /* ${defname}_ENTRY_H */ |
170,22 → 170,22 |
static char *cmdname = "${CMDNAME}"; |
/* Dispays help for ${CMDNAME} in various levels */ |
void * ${HELPENTRY}(unsigned int level) |
void ${HELPENTRY}(unsigned int level) |
{ |
printf("This is the %s help for '%s'.\n", |
level ? EXT_HELP : SHORT_HELP, cmdname); |
return CMD_VOID; |
return; |
} |
EOF |
[ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c |
/* Main entry point for ${CMDNAME}, accepts an array of arguments */ |
int * ${CMDENTRY}(char **argv) |
int ${CMDENTRY}(char **argv) |
EOF |
[ "${CMDTYPE}" = "builtin" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c |
/* Main entry point for ${CMDNAME}, accepts an array of arguments and a |
* pointer to the cliuser_t structure */ |
int * ${CMDENTRY}(char **argv, cliuser_t *usr) |
int ${CMDENTRY}(char **argv, cliuser_t *usr) |
EOF |
cat << EOF >> ${OUTDIR}/${CMDNAME}.c |
{ |
/branches/sparc/uspace/app/bdsh/cmds/modules/quit/quit.c |
---|
39,15 → 39,15 |
extern volatile unsigned int cli_quit; |
extern const char *progname; |
void * help_cmd_quit(unsigned int level) |
void help_cmd_quit(unsigned int level) |
{ |
printf("Type `%s' to exit %s\n", cmdname, progname); |
return CMD_VOID; |
return; |
} |
/* Quits the program and returns the status of whatever command |
* came before invoking 'quit' */ |
int * cmd_quit(char *argv[]) |
int cmd_quit(char *argv[]) |
{ |
/* Inform that we're outta here */ |
cli_quit = 1; |
/branches/sparc/uspace/app/bdsh/cmds/modules/quit/entry.h |
---|
2,8 → 2,8 |
#define QUIT_ENTRY_H_ |
/* Entry points for the quit command */ |
extern void * help_cmd_quit(unsigned int); |
extern int * cmd_quit(char *[]); |
extern void help_cmd_quit(unsigned int); |
extern int cmd_quit(char *[]); |
#endif |
/branches/sparc/uspace/app/bdsh/cmds/modules/touch/touch.c |
---|
48,7 → 48,7 |
static char *cmdname = "touch"; |
/* Dispays help for touch in various levels */ |
void * help_cmd_touch(unsigned int level) |
void help_cmd_touch(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' updates access times for files\n", cmdname); |
58,11 → 58,11 |
"created\n", cmdname); |
} |
return CMD_VOID; |
return; |
} |
/* Main entry point for touch, accepts an array of arguments */ |
int * cmd_touch(char **argv) |
int cmd_touch(char **argv) |
{ |
unsigned int argc, i = 0, ret = 0; |
int fd; |
/branches/sparc/uspace/app/bdsh/cmds/modules/touch/entry.h |
---|
2,8 → 2,8 |
#define TOUCH_ENTRY_H |
/* Entry points for the touch command */ |
extern int * cmd_touch(char **); |
extern void * help_cmd_touch(unsigned int); |
extern int cmd_touch(char **); |
extern void help_cmd_touch(unsigned int); |
#endif /* TOUCH_ENTRY_H */ |
/branches/sparc/uspace/app/bdsh/cmds/modules/cp/cp.c |
---|
0,0 → 1,73 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* 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. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "cp.h" |
#include "cmds.h" |
static char *cmdname = "cp"; |
/* Dispays help for cp in various levels */ |
void help_cmd_cp(unsigned int level) |
{ |
printf("This is the %s help for '%s'.\n", |
level ? EXT_HELP : SHORT_HELP, cmdname); |
return; |
} |
/* Main entry point for cp, accepts an array of arguments */ |
int cmd_cp(char **argv) |
{ |
unsigned int argc; |
unsigned int i; |
/* Count the arguments */ |
for (argc = 0; argv[argc] != NULL; argc ++); |
printf("%s %s\n", TEST_ANNOUNCE, cmdname); |
printf("%d arguments passed to %s", argc - 1, cmdname); |
if (argc < 2) { |
printf("\n"); |
return CMD_SUCCESS; |
} |
printf(":\n"); |
for (i = 1; i < argc; i++) |
printf("[%d] -> %s\n", i, argv[i]); |
return CMD_SUCCESS; |
} |
/branches/sparc/uspace/app/bdsh/cmds/modules/cp/cp_def.h |
---|
0,0 → 1,8 |
{ |
"cp", |
"Copy files and directories", |
&cmd_cp, |
&help_cmd_cp, |
0 |
}, |
/branches/sparc/uspace/app/bdsh/cmds/modules/cp/entry.h |
---|
0,0 → 1,9 |
#ifndef CP_ENTRY_H |
#define CP_ENTRY_H |
/* Entry points for the cp command */ |
extern int cmd_cp(char **); |
extern void help_cmd_cp(unsigned int); |
#endif /* CP_ENTRY_H */ |
/branches/sparc/uspace/app/bdsh/cmds/modules/cp/cp.h |
---|
0,0 → 1,8 |
#ifndef CP_H |
#define CP_H |
/* Prototypes for the cp command, excluding entry points */ |
#endif /* CP_H */ |
/branches/sparc/uspace/app/bdsh/cmds/modules/mkdir/entry.h |
---|
2,8 → 2,8 |
#define MKDIR_ENTRY_H |
/* Entry points for the mkdir command */ |
extern int * cmd_mkdir(char **); |
extern void * help_cmd_mkdir(unsigned int); |
extern int cmd_mkdir(char **); |
extern void help_cmd_mkdir(unsigned int); |
#endif /* MKDIR_ENTRY_H */ |
/branches/sparc/uspace/app/bdsh/cmds/modules/mkdir/mkdir.c |
---|
60,7 → 60,7 |
}; |
void * help_cmd_mkdir(unsigned int level) |
void help_cmd_mkdir(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' creates a new directory\n", cmdname); |
79,7 → 79,7 |
cmdname, cmdname); |
} |
return CMD_VOID; |
return; |
} |
/* This is kind of clunky, but effective for now */ |
181,7 → 181,7 |
return ret; |
} |
int * cmd_mkdir(char **argv) |
int cmd_mkdir(char **argv) |
{ |
unsigned int argc, create_parents = 0, i, ret = 0, follow = 0; |
unsigned int verbose = 0; |
/branches/sparc/uspace/app/bdsh/cmds/modules/cat/entry.h |
---|
2,8 → 2,8 |
#define CAT_ENTRY_H |
/* Entry points for the cat command */ |
extern int * cmd_cat(char **); |
extern void * help_cmd_cat(unsigned int); |
extern int cmd_cat(char **); |
extern void help_cmd_cat(unsigned int); |
#endif /* CAT_ENTRY_H */ |
/branches/sparc/uspace/app/bdsh/cmds/modules/cat/cat.c |
---|
59,7 → 59,7 |
}; |
/* Dispays help for cat in various levels */ |
void * help_cmd_cat(unsigned int level) |
void help_cmd_cat(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' shows the contents of files\n", cmdname); |
78,7 → 78,7 |
cmdname, cmdname); |
} |
return CMD_VOID; |
return; |
} |
static unsigned int cat_file(const char *fname, size_t blen) |
121,12 → 121,6 |
return 1; |
} |
/* Debug stuff, newline not added purposefully */ |
printf("** %s is a file with the size of %ld bytes\n", |
fname, total); |
printf( "** %d bytes were read in a buffer of %d bytes in %d reads\n", |
count, blen, reads); |
printf("** Read %s\n", count == total ? "Succeeded" : "Failed"); |
free(buff); |
return 0; |
133,7 → 127,7 |
} |
/* Main entry point for cat, accepts an array of arguments */ |
int * cmd_cat(char **argv) |
int cmd_cat(char **argv) |
{ |
unsigned int argc, i, ret = 0, buffer = 0; |
int c, opt_ind; |
/branches/sparc/uspace/app/bdsh/cmds/modules/help/entry.h |
---|
2,7 → 2,7 |
#define HELP_ENTRY_H_ |
/* Entry points for the help command */ |
extern void * help_cmd_help(unsigned int); |
extern int * cmd_help(char *[]); |
extern void help_cmd_help(unsigned int); |
extern int cmd_help(char *[]); |
#endif |
/branches/sparc/uspace/app/bdsh/cmds/modules/help/help.c |
---|
69,7 → 69,7 |
return HELP_IS_RUBBISH; |
} |
void *help_cmd_help(unsigned int level) |
void help_cmd_help(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf( |
86,10 → 86,10 |
cmdname, cmdname, cmdname, cmdname); |
} |
return CMD_VOID; |
return; |
} |
int *cmd_help(char *argv[]) |
int cmd_help(char *argv[]) |
{ |
module_t *mod; |
builtin_t *cmd; |
/branches/sparc/uspace/app/bdsh/cmds/modules/sleep/entry.h |
---|
0,0 → 1,9 |
#ifndef SLEEP_ENTRY_H |
#define SLEEP_ENTRY_H |
/* Entry points for the sleep command */ |
extern int cmd_sleep(char **); |
extern void help_cmd_sleep(unsigned int); |
#endif /* SLEEP_ENTRY_H */ |
/branches/sparc/uspace/app/bdsh/cmds/modules/sleep/sleep.c |
---|
0,0 → 1,73 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* 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. |
* |
* Neither the name of the original program's authors nor the names of its |
* contributors may be used to endorse or promote products derived from this |
* software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "sleep.h" |
#include "cmds.h" |
static char *cmdname = "sleep"; |
/* Dispays help for sleep in various levels */ |
void help_cmd_sleep(unsigned int level) |
{ |
printf("This is the %s help for '%s'.\n", |
level ? EXT_HELP : SHORT_HELP, cmdname); |
return; |
} |
/* Main entry point for sleep, accepts an array of arguments */ |
int cmd_sleep(char **argv) |
{ |
unsigned int argc; |
unsigned int i; |
/* Count the arguments */ |
for (argc = 0; argv[argc] != NULL; argc ++); |
printf("%s %s\n", TEST_ANNOUNCE, cmdname); |
printf("%d arguments passed to %s", argc - 1, cmdname); |
if (argc < 2) { |
printf("\n"); |
return CMD_SUCCESS; |
} |
printf(":\n"); |
for (i = 1; i < argc; i++) |
printf("[%d] -> %s\n", i, argv[i]); |
return CMD_SUCCESS; |
} |
/branches/sparc/uspace/app/bdsh/cmds/modules/sleep/sleep_def.h |
---|
0,0 → 1,8 |
{ |
"sleep", |
"Pause for given time interval (in seconds)", |
&cmd_sleep, |
&help_cmd_sleep, |
0 |
}, |
/branches/sparc/uspace/app/bdsh/cmds/modules/sleep/sleep.h |
---|
0,0 → 1,8 |
#ifndef SLEEP_H |
#define SLEEP_H |
/* Prototypes for the sleep command, excluding entry points */ |
#endif /* SLEEP_H */ |
/branches/sparc/uspace/app/bdsh/cmds/modules/pwd/entry.h |
---|
4,8 → 4,8 |
#include "scli.h" |
/* Entry points for the pwd command */ |
extern void * help_cmd_pwd(unsigned int); |
extern int * cmd_pwd(char **); |
extern void help_cmd_pwd(unsigned int); |
extern int cmd_pwd(char **); |
#endif |
/branches/sparc/uspace/app/bdsh/cmds/modules/pwd/pwd.c |
---|
39,13 → 39,13 |
static char * cmdname = "pwd"; |
void * help_cmd_pwd(unsigned int level) |
void help_cmd_pwd(unsigned int level) |
{ |
printf("`%s' prints your current working directory.\n", cmdname); |
return CMD_VOID; |
return; |
} |
int * cmd_pwd(char *argv[]) |
int cmd_pwd(char *argv[]) |
{ |
char *buff; |
/branches/sparc/uspace/app/bdsh/cmds/modules/ls/ls.c |
---|
132,7 → 132,7 |
return; |
} |
void * help_cmd_ls(unsigned int level) |
void help_cmd_ls(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' lists files and directories.\n", cmdname); |
142,10 → 142,10 |
"working directory is used.\n", cmdname); |
} |
return CMD_VOID; |
return; |
} |
int * cmd_ls(char **argv) |
int cmd_ls(char **argv) |
{ |
unsigned int argc; |
unsigned int scope; |
/branches/sparc/uspace/app/bdsh/cmds/modules/ls/entry.h |
---|
2,8 → 2,8 |
#define LS_ENTRY_H |
/* Entry points for the ls command */ |
extern int * cmd_ls(char **); |
extern void * help_cmd_ls(unsigned int); |
extern int cmd_ls(char **); |
extern void help_cmd_ls(unsigned int); |
#endif /* LS_ENTRY_H */ |
/branches/sparc/uspace/app/bdsh/cmds/modules/modules.h |
---|
25,6 → 25,8 |
#include "touch/entry.h" |
#include "ls/entry.h" |
#include "pwd/entry.h" |
#include "sleep/entry.h" |
#include "cp/entry.h" |
/* Each .def function fills the module_t struct with the individual name, entry |
* point, help entry point, etc. You can use config.h to control what modules |
39,6 → 41,8 |
#include "touch/touch_def.h" |
#include "ls/ls_def.h" |
#include "pwd/pwd_def.h" |
#include "sleep/sleep_def.h" |
#include "cp/cp_def.h" |
{NULL, NULL, NULL, NULL} |
}; |
/branches/sparc/uspace/app/bdsh/cmds/modules/rm/rm.c |
---|
144,7 → 144,7 |
} |
/* Dispays help for rm in various levels */ |
void * help_cmd_rm(unsigned int level) |
void help_cmd_rm(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' removes files and directories.\n", cmdname); |
161,11 → 161,11 |
"Currently, %s is under development, some options don't work.\n", |
cmdname, cmdname); |
} |
return CMD_VOID; |
return; |
} |
/* Main entry point for rm, accepts an array of arguments */ |
int * cmd_rm(char **argv) |
int cmd_rm(char **argv) |
{ |
unsigned int argc; |
unsigned int i, scope, ret = 0; |
/branches/sparc/uspace/app/bdsh/cmds/modules/rm/entry.h |
---|
2,8 → 2,8 |
#define RM_ENTRY_H |
/* Entry points for the rm command */ |
extern int * cmd_rm(char **); |
extern void * help_cmd_rm(unsigned int); |
extern int cmd_rm(char **); |
extern void help_cmd_rm(unsigned int); |
#endif /* RM_ENTRY_H */ |
/branches/sparc/uspace/app/bdsh/cmds/builtins/cd/cd.c |
---|
42,7 → 42,7 |
static char * cmdname = "cd"; |
void * help_cmd_cd(unsigned int level) |
void help_cmd_cd(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' changes the current working directory.\n", cmdname); |
53,12 → 53,12 |
cmdname, cmdname); |
} |
return CMD_VOID; |
return; |
} |
/* This is a very rudamentary 'cd' command. It is not 'link smart' (yet) */ |
int * cmd_cd(char **argv, cliuser_t *usr) |
int cmd_cd(char **argv, cliuser_t *usr) |
{ |
int argc, rc = 0; |
/branches/sparc/uspace/app/bdsh/cmds/builtins/cd/entry.h |
---|
4,8 → 4,8 |
#include "scli.h" |
/* Entry points for the cd command */ |
extern void * help_cmd_cd(unsigned int); |
extern int * cmd_cd(char **, cliuser_t *); |
extern void help_cmd_cd(unsigned int); |
extern int cmd_cd(char **, cliuser_t *); |
#endif |
/branches/sparc/uspace/app/bdsh/cmds/cmds.h |
---|
19,17 → 19,16 |
#define BUFF_SMALL 255 |
/* Return macros for int type entry points */ |
#define CMD_FAILURE (int*)1 |
#define CMD_FAILURE 1 |
#define CMD_SUCCESS 0 |
#define CMD_VOID (void *)NULL |
/* Types for module command entry and help */ |
typedef int * (* mod_entry_t)(char **); |
typedef void * (* mod_help_t)(unsigned int); |
typedef int (* mod_entry_t)(char **); |
typedef void (* mod_help_t)(unsigned int); |
/* Built-in commands need to be able to modify cliuser_t */ |
typedef int * (* builtin_entry_t)(char **, cliuser_t *); |
typedef void * (* builtin_help_t)(unsigned int); |
typedef int (* builtin_entry_t)(char **, cliuser_t *); |
typedef void (* builtin_help_t)(unsigned int); |
/* Module structure */ |
typedef struct { |
/branches/sparc/uspace/app/bdsh/config.h |
---|
1,15 → 1,18 |
/* Various things that are used in many files |
* Various temporary port work-arounds are addressed in __HELENOS__ , this |
* serves as a convenience and later as a guide to make "phony.h" for future |
* ports */ |
/* Various things that are used in many places including a few |
* tidbits left over from autoconf prior to the HelenOS port */ |
/* Specific port work-arounds : */ |
#ifndef PATH_MAX |
#define PATH_MAX 255 |
#endif |
#ifndef EXIT_SUCCESS |
#define EXIT_SUCCESS 0 |
#define EXIT_FAILURE 0 |
#define EXIT_FAILURE 1 |
#endif |
/* Work around for getenv() */ |
#define PATH "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" |
#define PATH "/srv:/app" |
#define PATH_DELIM ":" |
/* Used in many places */ |
26,7 → 29,7 |
#define PACKAGE_BUGREPORT "echo@echoreply.us" |
#define PACKAGE_NAME "bdsh" |
#define PACKAGE_STRING "The brain dead shell" |
#define PACKAGE_TARNAME "scli" |
#define PACKAGE_TARNAME "bdsh" |
#define PACKAGE_VERSION "0.0.1" |
/branches/sparc/uspace/app/bdsh/README |
---|
57,12 → 57,12 |
They are typed as such (from cmds.h): |
/* Types for module command entry and help */ |
typedef int * (* mod_entry_t)(char **); |
typedef void * (* mod_help_t)(unsigned int); |
typedef int (* mod_entry_t)(char **); |
typedef void (* mod_help_t)(unsigned int); |
/* Built-in commands need to be able to modify cliuser_t */ |
typedef int * (* builtin_entry_t)(char **, cliuser_t *); |
typedef void * (* builtin_help_t)(unsigned int); |
typedef int (* builtin_entry_t)(char **, cliuser_t *); |
typedef void (* builtin_help_t)(unsigned int); |
As you can see, both modular and builtin commands expect an array of |
arguments, however bulitins also expect to be pointed to cliuser_t. |
153,9 → 153,7 |
2: Change your "usage()" command as shown: |
-- void usage(...) |
++ void * help_cmd_foo(unsigned int level) |
-- return; |
++ retrn CMD_VOID; |
++ void help_cmd_foo(unsigned int level) |
'level' is either 0 or 1, indicating the level of help requested. |
If the help / usage function currently exits based on how it is |
163,33 → 161,19 |
3: Change the programs "main()" as shown: |
-- int main(int argc, char **argv) |
++ int * cmd_foo(char **argv) |
++ int cmd_foo(char **argv) |
-- return 1; |
++ return CMD_FAILURE; |
-- return 0; |
++ return CMD_SUCCESS; |
If main() returns an int that is not 1 or 0 (e.g. 127), cast it as |
such: |
-- return 127; |
++ return (int *) 127; |
NOTE: _ONLY_ the main and help entry points need to return int * or |
void *, respectively. Also take note that argc has changed. The type |
for entry points may soon change. |
NOTE: If main is void, you'll need to change it and ensure that its |
expecting an array of arguments, even if they'll never be read or |
used. I.e.: |
-- void main(void) |
++ int * cmd_foo(char **argv) |
++ int cmd_foo(char **argv) |
Similararly, do not try to return CMD_VOID within the modules main |
entry point. If somehow you escape the compiler yelling at you, you |
will surely see pretty blue and yellow fireworks once its reached. |
4: Don't expose more than the entry and help points: |
-- void my_function(int n) |
++ static void my_function(int n) |
/branches/sparc/uspace/app/bdsh/util.c |
---|
70,125 → 70,6 |
return (char *) memcpy(ret, s1, len); |
} |
/* |
* Take a previously allocated string (s1), re-size it to accept s2 and copy |
* the contents of s2 into s1. |
* Return -1 on failure, or the length of the copied string on success. |
*/ |
int cli_redup(char **s1, const char *s2) |
{ |
size_t len = strlen(s2) + 1; |
if (! len) |
return -1; |
*s1 = realloc(*s1, len); |
if (*s1 == NULL) { |
cli_errno = CL_ENOMEM; |
return -1; |
} |
memset(*s1, 0, sizeof(*s1)); |
memcpy(*s1, s2, len); |
cli_errno = CL_EOK; |
return (int) len; |
} |
/* An asprintf() for formatting paths, similar to asprintf() but ensures |
* the returned allocated string is <= PATH_MAX. On failure, an attempt |
* is made to return the original string (if not null) unmodified. |
* |
* Returns: Length of the new string on success, 0 if the string was handed |
* back unmodified, -1 on failure. On failure, cli_errno is set. |
* |
* We do not use POSIX_PATH_MAX, as it is typically much smaller than the |
* PATH_MAX defined by the kernel. |
* |
* Use this like: |
* if (1 > cli_psprintf(&char, "%s/%s", foo, bar)) { |
* cli_error(cli_errno, "Failed to format path"); |
* stop_what_your_doing_as_your_out_of_memory(); |
* } |
*/ |
int cli_psprintf(char **s1, const char *fmt, ...) |
{ |
va_list ap; |
size_t needed, base = PATH_MAX + 1; |
int skipped = 0; |
char *orig = NULL; |
char *tmp = (char *) malloc(base); |
/* Don't even touch s1, not enough memory */ |
if (NULL == tmp) { |
cli_errno = CL_ENOMEM; |
return -1; |
} |
/* If re-allocating s1, save a copy in case we fail */ |
if (NULL != *s1) |
orig = cli_strdup(*s1); |
/* Print the string to tmp so we can determine the size that |
* we actually need */ |
memset(tmp, 0, sizeof(tmp)); |
va_start(ap, fmt); |
/* vsnprintf will return the # of bytes not written */ |
skipped = vsnprintf(tmp, base, fmt, ap); |
va_end(ap); |
/* realloc/alloc s1 to be just the size that we need */ |
needed = strlen(tmp) + 1; |
*s1 = realloc(*s1, needed); |
if (NULL == *s1) { |
/* No string lived here previously, or we failed to |
* make a copy of it, either way there's nothing we |
* can do. */ |
if (NULL == *orig) { |
cli_errno = CL_ENOMEM; |
return -1; |
} |
/* We can't even allocate enough size to restore the |
* saved copy, just give up */ |
*s1 = realloc(*s1, strlen(orig) + 1); |
if (NULL == *s1) { |
free(tmp); |
free(orig); |
cli_errno = CL_ENOMEM; |
return -1; |
} |
/* Give the string back as we found it */ |
memset(*s1, 0, sizeof(*s1)); |
memcpy(*s1, orig, strlen(orig) + 1); |
free(tmp); |
free(orig); |
cli_errno = CL_ENOMEM; |
return 0; |
} |
/* Ok, great, we have enough room */ |
memset(*s1, 0, sizeof(*s1)); |
memcpy(*s1, tmp, needed); |
free(tmp); |
/* Free tmp only if s1 was reallocated instead of allocated */ |
if (NULL != orig) |
free(orig); |
if (skipped) { |
/* s1 was bigger than PATH_MAX when expanded, however part |
* of the string was printed. Tell the caller not to use it */ |
cli_errno = CL_ETOOBIG; |
return -1; |
} |
/* Success! */ |
cli_errno = CL_EOK; |
return (int) needed; |
} |
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */ |
char * cli_strtok_r(char *s, const char *delim, char **last) |
{ |
273,10 → 154,7 |
if (NULL == usr->cwd) |
snprintf(usr->cwd, PATH_MAX, "(unknown)"); |
if (1 < cli_psprintf(&usr->prompt, "%s # ", usr->cwd)) { |
cli_error(cli_errno, "Failed to set prompt"); |
return 1; |
} |
asprintf(&usr->prompt, "%s # ", usr->cwd); |
return 0; |
} |
/branches/sparc/uspace/app/bdsh/util.h |
---|
5,8 → 5,6 |
/* Internal string handlers */ |
extern char * cli_strdup(const char *); |
extern int cli_redup(char **, const char *); |
extern int cli_psprintf(char **, const char *, ...); |
extern char * cli_strtok_r(char *, const char *, char **); |
extern char * cli_strtok(char *, const char *); |
/branches/sparc/uspace/app/bdsh/exec.c |
---|
46,13 → 46,13 |
#include "errors.h" |
/* FIXME: Just have find_command() return an allocated string */ |
char *found; |
static char *found; |
static char *find_command(char *); |
static unsigned int try_access(const char *); |
static int try_access(const char *); |
/* work-around for access() */ |
static unsigned int try_access(const char *f) |
static int try_access(const char *f) |
{ |
int fd; |
117,7 → 117,7 |
tmp = cli_strdup(find_command(cmd)); |
free(found); |
tid = task_spawn((const char *)tmp, (const char **)argv); |
tid = task_spawn((const char *)tmp, argv); |
free(tmp); |
if (tid == 0) { |
/branches/sparc/uspace/app/bdsh/scli.c |
---|
53,8 → 53,8 |
const char *progname = PACKAGE_NAME; |
/* These are not exposed, even to builtins */ |
static int cli_init(cliuser_t *usr); |
static void cli_finit(cliuser_t *usr); |
static int cli_init(cliuser_t *); |
static void cli_finit(cliuser_t *); |
/* Constructor */ |
static int cli_init(cliuser_t *usr) |
/branches/sparc/uspace/app/bdsh/Makefile |
---|
64,6 → 64,8 |
cmds/modules/touch/ \ |
cmds/modules/ls/ \ |
cmds/modules/pwd/ \ |
cmds/modules/sleep/ \ |
cmds/modules/cp/ \ |
cmds/builtins/ \ |
cmds/builtins/cd/ |
76,6 → 78,8 |
cmds/modules/touch/touch.c \ |
cmds/modules/ls/ls.c \ |
cmds/modules/pwd/pwd.c \ |
cmds/modules/sleep/sleep.c \ |
cmds/modules/cp/cp.c \ |
cmds/builtins/cd/cd.c \ |
cmds/mod_cmds.c \ |
cmds/builtin_cmds.c \ |
/branches/sparc/uspace/app/init/init.c |
---|
104,15 → 104,15 |
return -1; |
} |
// FIXME: spawn("/sbin/pci"); |
//spawn("/sbin/fb"); |
spawn("/sbin/kbd"); |
spawn("/sbin/console"); |
// FIXME: spawn("/srv/pci"); |
//spawn("/srv/fb"); |
spawn("/srv/kbd"); |
spawn("/srv/console"); |
console_wait(); |
version_print(); |
spawn("/sbin/bdsh"); |
spawn("/app/bdsh"); |
return 0; |
} |
/branches/sparc/uspace/app/tester/tester.c |
---|
133,7 → 133,7 |
if (c == 'a') |
break; |
if (c > 'a') |
if (test->name == NULL) |
printf("Unknown test\n\n"); |
else |
run_test(test); |
147,6 → 147,8 |
} |
} |
return 0; |
} |
/** @} |
/branches/sparc/uspace/app/tester/ipc/send_sync.c |
---|
35,7 → 35,6 |
{ |
int phoneid; |
int res; |
static int msgid = 1; |
char c; |
printf("Select phoneid to send msg: 2-9 (q to skip)\n"); |
/branches/sparc/uspace/app/trace/trace.c |
---|
0,0 → 1,806 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <ipc/ipc.h> |
#include <fibril.h> |
#include <errno.h> |
#include <udebug.h> |
#include <async.h> |
#include <task.h> |
#include <loader/loader.h> |
#include <libc.h> |
// Temporary: service and method names |
#include "proto.h" |
#include <ipc/services.h> |
#include "../../srv/vfs/vfs.h" |
#include "../../srv/console/console.h" |
#include "syscalls.h" |
#include "ipcp.h" |
#include "errors.h" |
#include "trace.h" |
#define THBUF_SIZE 64 |
uintptr_t thread_hash_buf[THBUF_SIZE]; |
int n_threads; |
int next_thread_id; |
int phoneid; |
int abort_trace; |
uintptr_t thash; |
volatile int paused; |
void thread_trace_start(uintptr_t thread_hash); |
static proto_t *proto_console; |
static task_id_t task_id; |
static loader_t *task_ldr; |
/** Combination of events/data to print. */ |
display_mask_t display_mask; |
static int program_run_fibril(void *arg); |
static void program_run(void) |
{ |
fid_t fid; |
fid = fibril_create(program_run_fibril, NULL); |
if (fid == 0) { |
printf("Error creating fibril\n"); |
exit(1); |
} |
fibril_add_ready(fid); |
} |
static int program_run_fibril(void *arg) |
{ |
int rc; |
/* |
* This must be done in background as it will block until |
* we let the task reply to this call. |
*/ |
rc = loader_run(task_ldr); |
if (rc != 0) { |
printf("Error running program\n"); |
exit(1); |
} |
free(task_ldr); |
task_ldr = NULL; |
printf("program_run_fibril exiting\n"); |
return 0; |
} |
static int connect_task(task_id_t task_id) |
{ |
int rc; |
rc = ipc_connect_kbox(task_id); |
if (rc == ENOTSUP) { |
printf("You do not have userspace debugging support " |
"compiled in the kernel.\n"); |
printf("Compile kernel with 'Support for userspace debuggers' " |
"(CONFIG_UDEBUG) enabled.\n"); |
return rc; |
} |
if (rc < 0) { |
printf("Error connecting\n"); |
printf("ipc_connect_task(%lld) -> %d ", task_id, rc); |
return rc; |
} |
phoneid = rc; |
rc = udebug_begin(phoneid); |
if (rc < 0) { |
printf("udebug_begin() -> %d\n", rc); |
return rc; |
} |
rc = udebug_set_evmask(phoneid, UDEBUG_EM_ALL); |
if (rc < 0) { |
printf("udebug_set_evmask(0x%x) -> %d\n ", UDEBUG_EM_ALL, rc); |
return rc; |
} |
return 0; |
} |
static int get_thread_list(void) |
{ |
int rc; |
size_t tb_copied; |
size_t tb_needed; |
int i; |
rc = udebug_thread_read(phoneid, thread_hash_buf, |
THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed); |
if (rc < 0) { |
printf("udebug_thread_read() -> %d\n", rc); |
return rc; |
} |
n_threads = tb_copied / sizeof(uintptr_t); |
printf("Threads:"); |
for (i = 0; i < n_threads; i++) { |
printf(" [%d] (hash 0x%lx)", 1+i, thread_hash_buf[i]); |
} |
printf("\ntotal of %u threads\n", tb_needed / sizeof(uintptr_t)); |
return 0; |
} |
void val_print(sysarg_t val, val_type_t v_type) |
{ |
switch (v_type) { |
case V_VOID: |
printf("<void>"); |
break; |
case V_INTEGER: |
printf("%ld", val); |
break; |
case V_HASH: |
case V_PTR: |
printf("0x%08lx", val); |
break; |
case V_ERRNO: |
if (val >= -15 && val <= 0) { |
printf("%ld %s (%s)", val, |
err_desc[-val].name, |
err_desc[-val].desc); |
} else { |
printf("%ld", val); |
} |
break; |
case V_INT_ERRNO: |
if (val >= -15 && val < 0) { |
printf("%ld %s (%s)", val, |
err_desc[-val].name, |
err_desc[-val].desc); |
} else { |
printf("%ld", val); |
} |
break; |
case V_CHAR: |
if (val >= 0x20 && val < 0x7f) { |
printf("'%c'", val); |
} else { |
switch (val) { |
case '\a': printf("'\\a'"); break; |
case '\b': printf("'\\b'"); break; |
case '\n': printf("'\\n'"); break; |
case '\r': printf("'\\r'"); break; |
case '\t': printf("'\\t'"); break; |
case '\\': printf("'\\\\'"); break; |
default: printf("'\\x%02lX'", val); break; |
} |
} |
break; |
} |
} |
static void print_sc_retval(sysarg_t retval, val_type_t val_type) |
{ |
printf(" -> "); |
val_print(retval, val_type); |
putchar('\n'); |
} |
static void print_sc_args(sysarg_t *sc_args, int n) |
{ |
int i; |
putchar('('); |
if (n > 0) printf("%ld", sc_args[0]); |
for (i = 1; i < n; i++) { |
printf(", %ld", sc_args[i]); |
} |
putchar(')'); |
} |
static void sc_ipc_call_async_fast(sysarg_t *sc_args, sysarg_t sc_rc) |
{ |
ipc_call_t call; |
ipcarg_t phoneid; |
if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY) |
return; |
phoneid = sc_args[0]; |
IPC_SET_METHOD(call, sc_args[1]); |
IPC_SET_ARG1(call, sc_args[2]); |
IPC_SET_ARG2(call, sc_args[3]); |
IPC_SET_ARG3(call, sc_args[4]); |
IPC_SET_ARG4(call, sc_args[5]); |
IPC_SET_ARG5(call, 0); |
ipcp_call_out(phoneid, &call, sc_rc); |
} |
static void sc_ipc_call_async_slow(sysarg_t *sc_args, sysarg_t sc_rc) |
{ |
ipc_call_t call; |
int rc; |
if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY) |
return; |
memset(&call, 0, sizeof(call)); |
rc = udebug_mem_read(phoneid, &call.args, sc_args[1], sizeof(call.args)); |
if (rc >= 0) { |
ipcp_call_out(sc_args[0], &call, sc_rc); |
} |
} |
static void sc_ipc_call_sync_fast(sysarg_t *sc_args) |
{ |
ipc_call_t question, reply; |
int rc; |
int phoneidx; |
// printf("sc_ipc_call_sync_fast()\n"); |
phoneidx = sc_args[0]; |
IPC_SET_METHOD(question, sc_args[1]); |
IPC_SET_ARG1(question, sc_args[2]); |
IPC_SET_ARG2(question, sc_args[3]); |
IPC_SET_ARG3(question, sc_args[4]); |
IPC_SET_ARG4(question, 0); |
IPC_SET_ARG5(question, 0); |
// printf("memset\n"); |
memset(&reply, 0, sizeof(reply)); |
// printf("udebug_mem_read(phone=%d, buffer_ptr=%u, src_addr=%d, n=%d\n", |
// phoneid, &reply.args, sc_args[5], sizeof(reply.args)); |
rc = udebug_mem_read(phoneid, &reply.args, sc_args[5], sizeof(reply.args)); |
// printf("dmr->%d\n", rc); |
if (rc < 0) return; |
// printf("call ipc_call_sync\n"); |
ipcp_call_sync(phoneidx, &question, &reply); |
} |
static void sc_ipc_call_sync_slow(sysarg_t *sc_args) |
{ |
ipc_call_t question, reply; |
int rc; |
memset(&question, 0, sizeof(question)); |
rc = udebug_mem_read(phoneid, &question.args, sc_args[1], sizeof(question.args)); |
printf("dmr->%d\n", rc); |
if (rc < 0) return; |
memset(&reply, 0, sizeof(reply)); |
rc = udebug_mem_read(phoneid, &reply.args, sc_args[2], sizeof(reply.args)); |
printf("dmr->%d\n", rc); |
if (rc < 0) return; |
ipcp_call_sync(sc_args[0], &question, &reply); |
} |
static void sc_ipc_wait(sysarg_t *sc_args, int sc_rc) |
{ |
ipc_call_t call; |
int rc; |
if (sc_rc == 0) return; |
memset(&call, 0, sizeof(call)); |
rc = udebug_mem_read(phoneid, &call, sc_args[0], sizeof(call)); |
// printf("udebug_mem_read(phone %d, dest %d, app-mem src %d, size %d -> %d\n", |
// phoneid, (int)&call, sc_args[0], sizeof(call), rc); |
if (rc >= 0) { |
ipcp_call_in(&call, sc_rc); |
} |
} |
static void event_syscall_b(unsigned thread_id, uintptr_t thread_hash, |
unsigned sc_id, sysarg_t sc_rc) |
{ |
sysarg_t sc_args[6]; |
int rc; |
/* Read syscall arguments */ |
rc = udebug_args_read(phoneid, thread_hash, sc_args); |
async_serialize_start(); |
// printf("[%d] ", thread_id); |
if (rc < 0) { |
printf("error\n"); |
async_serialize_end(); |
return; |
} |
if ((display_mask & DM_SYSCALL) != 0) { |
/* Print syscall name and arguments */ |
printf("%s", syscall_desc[sc_id].name); |
print_sc_args(sc_args, syscall_desc[sc_id].n_args); |
} |
async_serialize_end(); |
} |
static void event_syscall_e(unsigned thread_id, uintptr_t thread_hash, |
unsigned sc_id, sysarg_t sc_rc) |
{ |
sysarg_t sc_args[6]; |
int rv_type; |
int rc; |
/* Read syscall arguments */ |
rc = udebug_args_read(phoneid, thread_hash, sc_args); |
async_serialize_start(); |
// printf("[%d] ", thread_id); |
if (rc < 0) { |
printf("error\n"); |
async_serialize_end(); |
return; |
} |
if ((display_mask & DM_SYSCALL) != 0) { |
/* Print syscall return value */ |
rv_type = syscall_desc[sc_id].rv_type; |
print_sc_retval(sc_rc, rv_type); |
} |
switch (sc_id) { |
case SYS_IPC_CALL_ASYNC_FAST: |
sc_ipc_call_async_fast(sc_args, sc_rc); |
break; |
case SYS_IPC_CALL_ASYNC_SLOW: |
sc_ipc_call_async_slow(sc_args, sc_rc); |
break; |
case SYS_IPC_CALL_SYNC_FAST: |
sc_ipc_call_sync_fast(sc_args); |
break; |
case SYS_IPC_CALL_SYNC_SLOW: |
sc_ipc_call_sync_slow(sc_args); |
break; |
case SYS_IPC_WAIT: |
sc_ipc_wait(sc_args, sc_rc); |
break; |
default: |
break; |
} |
async_serialize_end(); |
} |
static void event_thread_b(uintptr_t hash) |
{ |
async_serialize_start(); |
printf("New thread, hash 0x%lx\n", hash); |
async_serialize_end(); |
thread_trace_start(hash); |
} |
static int trace_loop(void *thread_hash_arg) |
{ |
int rc; |
unsigned ev_type; |
uintptr_t thread_hash; |
unsigned thread_id; |
sysarg_t val0, val1; |
thread_hash = (uintptr_t)thread_hash_arg; |
thread_id = next_thread_id++; |
printf("Start tracing thread [%d] (hash 0x%lx)\n", thread_id, thread_hash); |
while (!abort_trace) { |
/* Run thread until an event occurs */ |
rc = udebug_go(phoneid, thread_hash, |
&ev_type, &val0, &val1); |
// printf("rc = %d, ev_type=%d\n", rc, ev_type); |
if (ev_type == UDEBUG_EVENT_FINISHED) { |
/* Done tracing this thread */ |
break; |
} |
if (rc >= 0) { |
switch (ev_type) { |
case UDEBUG_EVENT_SYSCALL_B: |
event_syscall_b(thread_id, thread_hash, val0, (int)val1); |
break; |
case UDEBUG_EVENT_SYSCALL_E: |
event_syscall_e(thread_id, thread_hash, val0, (int)val1); |
break; |
case UDEBUG_EVENT_STOP: |
printf("Stop event\n"); |
printf("Waiting for resume\n"); |
while (paused) { |
usleep(1000000); |
fibril_yield(); |
printf("."); |
} |
printf("Resumed\n"); |
break; |
case UDEBUG_EVENT_THREAD_B: |
event_thread_b(val0); |
break; |
case UDEBUG_EVENT_THREAD_E: |
printf("Thread 0x%lx exited\n", val0); |
abort_trace = 1; |
break; |
default: |
printf("Unknown event type %d\n", ev_type); |
break; |
} |
} |
} |
printf("Finished tracing thread [%d]\n", thread_id); |
return 0; |
} |
void thread_trace_start(uintptr_t thread_hash) |
{ |
fid_t fid; |
thash = thread_hash; |
fid = fibril_create(trace_loop, (void *)thread_hash); |
if (fid == 0) { |
printf("Warning: Failed creating fibril\n"); |
} |
fibril_add_ready(fid); |
} |
static loader_t *preload_task(const char *path, char *const argv[], |
task_id_t *task_id) |
{ |
loader_t *ldr; |
int rc; |
/* Spawn a program loader */ |
ldr = loader_spawn(); |
if (ldr == NULL) |
return 0; |
/* Get task ID. */ |
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); |
if (rc != EOK) |
goto error; |
/* Load the program. */ |
rc = loader_load_program(ldr); |
if (rc != EOK) |
goto error; |
/* Success */ |
return ldr; |
/* Error exit */ |
error: |
loader_abort(ldr); |
free(ldr); |
return NULL; |
} |
static void trace_task(task_id_t task_id) |
{ |
int i; |
int rc; |
int c; |
ipcp_init(); |
/* |
* User apps now typically have console on phone 3. |
* (Phones 1 and 2 are used by the loader). |
*/ |
ipcp_connection_set(3, 0, proto_console); |
rc = get_thread_list(); |
if (rc < 0) { |
printf("Failed to get thread list (error %d)\n", rc); |
return; |
} |
abort_trace = 0; |
for (i = 0; i < n_threads; i++) { |
thread_trace_start(thread_hash_buf[i]); |
} |
while(1) { |
c = getchar(); |
if (c == 'q') break; |
if (c == 'p') { |
paused = 1; |
rc = udebug_stop(phoneid, thash); |
printf("stop -> %d\n", rc); |
} |
if (c == 'r') { |
paused = 0; |
} |
} |
printf("\nTerminate debugging session...\n"); |
abort_trace = 1; |
udebug_end(phoneid); |
ipc_hangup(phoneid); |
ipcp_cleanup(); |
printf("Done\n"); |
return; |
} |
static void main_init(void) |
{ |
proto_t *p; |
oper_t *o; |
val_type_t arg_def[OPER_MAX_ARGS] = { |
V_INTEGER, |
V_INTEGER, |
V_INTEGER, |
V_INTEGER, |
V_INTEGER |
}; |
val_type_t resp_def[OPER_MAX_ARGS] = { |
V_INTEGER, |
V_INTEGER, |
V_INTEGER, |
V_INTEGER, |
V_INTEGER |
}; |
next_thread_id = 1; |
paused = 0; |
proto_init(); |
p = proto_new("vfs"); |
o = oper_new("read", 1, arg_def, V_ERRNO, 1, resp_def); |
proto_add_oper(p, VFS_READ, o); |
o = oper_new("write", 1, arg_def, V_ERRNO, 1, resp_def); |
proto_add_oper(p, VFS_WRITE, o); |
o = oper_new("truncate", 5, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_TRUNCATE, o); |
o = oper_new("mount", 2, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_MOUNT, o); |
/* o = oper_new("unmount", 0, arg_def); |
proto_add_oper(p, VFS_UNMOUNT, o);*/ |
proto_register(SERVICE_VFS, p); |
p = proto_new("console"); |
resp_def[0] = V_CHAR; |
o = oper_new("getchar", 0, arg_def, V_INTEGER, 2, resp_def); |
proto_add_oper(p, CONSOLE_GETCHAR, o); |
arg_def[0] = V_CHAR; |
o = oper_new("putchar", 1, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_PUTCHAR, o); |
o = oper_new("clear", 0, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_CLEAR, o); |
arg_def[0] = V_INTEGER; arg_def[1] = V_INTEGER; |
o = oper_new("goto", 2, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_GOTO, o); |
resp_def[0] = V_INTEGER; resp_def[1] = V_INTEGER; |
o = oper_new("getsize", 0, arg_def, V_INTEGER, 2, resp_def); |
proto_add_oper(p, CONSOLE_GETSIZE, o); |
o = oper_new("flush", 0, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_FLUSH, o); |
arg_def[0] = V_INTEGER; arg_def[1] = V_INTEGER; |
o = oper_new("set_style", 2, arg_def, V_INTEGER, 0, resp_def); |
proto_add_oper(p, CONSOLE_SET_STYLE, o); |
o = oper_new("cursor_visibility", 1, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_CURSOR_VISIBILITY, o); |
proto_console = p; |
proto_register(SERVICE_CONSOLE, p); |
} |
static void print_syntax() |
{ |
printf("Syntax:\n"); |
printf("\ttrace [+<events>] <executable> [<arg1> [...]]\n"); |
printf("or\ttrace [+<events>] -t <task_id>\n"); |
printf("Events: (default is +tp)\n"); |
printf("\n"); |
printf("\tt ... Thread creation and termination\n"); |
printf("\ts ... System calls\n"); |
printf("\ti ... Low-level IPC\n"); |
printf("\tp ... Protocol level\n"); |
printf("\n"); |
printf("Examples:\n"); |
printf("\ttrace +s /app/tetris\n"); |
printf("\ttrace +tsip -t 12\n"); |
} |
static display_mask_t parse_display_mask(char *text) |
{ |
display_mask_t dm; |
char *c; |
c = text; |
while (*c) { |
switch (*c) { |
case 't': dm = dm | DM_THREAD; break; |
case 's': dm = dm | DM_SYSCALL; break; |
case 'i': dm = dm | DM_IPC; break; |
case 'p': dm = dm | DM_SYSTEM | DM_USER; break; |
default: |
printf("Unexpected event type '%c'\n", *c); |
exit(1); |
} |
++c; |
} |
return dm; |
} |
static int parse_args(int argc, char *argv[]) |
{ |
char *arg; |
char *err_p; |
task_id = 0; |
--argc; ++argv; |
while (argc > 0) { |
arg = *argv; |
if (arg[0] == '+') { |
display_mask = parse_display_mask(&arg[1]); |
} else if (arg[0] == '-') { |
if (arg[1] == 't') { |
/* Trace an already running task */ |
--argc; ++argv; |
task_id = strtol(*argv, &err_p, 10); |
task_ldr = NULL; |
if (*err_p) { |
printf("Task ID syntax error\n"); |
print_syntax(); |
return -1; |
} |
} else { |
printf("Uknown option '%s'\n", arg[0]); |
print_syntax(); |
return -1; |
} |
} else { |
break; |
} |
--argc; ++argv; |
} |
if (task_id != 0) { |
if (argc == 0) return 0; |
printf("Extra arguments\n"); |
print_syntax(); |
return -1; |
} |
if (argc < 1) { |
printf("Missing argument\n"); |
print_syntax(); |
return -1; |
} |
/* Preload the specified program file. */ |
printf("Spawning '%s' with arguments:\n", *argv); |
{ |
char **cp = argv; |
while (*cp) printf("'%s'\n", *cp++); |
} |
task_ldr = preload_task(*argv, argv, &task_id); |
return 0; |
} |
int main(int argc, char *argv[]) |
{ |
int rc; |
printf("System Call / IPC Tracer\n"); |
display_mask = DM_THREAD | DM_SYSTEM | DM_USER; |
if (parse_args(argc, argv) < 0) |
return 1; |
main_init(); |
rc = connect_task(task_id); |
if (rc < 0) { |
printf("Failed connecting to task %lld\n", task_id); |
return 1; |
} |
printf("Connected to task %lld\n", task_id); |
if (task_ldr != NULL) { |
program_run(); |
} |
trace_task(task_id); |
return 0; |
} |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/ipcp.c |
---|
0,0 → 1,375 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <libadt/hash_table.h> |
#include "ipc_desc.h" |
#include "proto.h" |
#include "trace.h" |
#include "ipcp.h" |
#define IPCP_CALLID_SYNC 0 |
typedef struct { |
ipcarg_t phone_hash; |
ipc_call_t question; |
oper_t *oper; |
ipc_callid_t call_hash; |
link_t link; |
} pending_call_t; |
typedef struct { |
int server; |
proto_t *proto; |
} connection_t; |
#define MAX_PHONE 64 |
connection_t connections[MAX_PHONE]; |
int have_conn[MAX_PHONE]; |
#define PCALL_TABLE_CHAINS 32 |
hash_table_t pending_calls; |
/* |
* Pseudo-protocols |
*/ |
proto_t *proto_system; /**< Protocol describing system IPC methods. */ |
proto_t *proto_unknown; /**< Protocol with no known methods. */ |
static hash_index_t pending_call_hash(unsigned long key[]); |
static int pending_call_compare(unsigned long key[], hash_count_t keys, |
link_t *item); |
static void pending_call_remove_callback(link_t *item); |
hash_table_operations_t pending_call_ops = { |
.hash = pending_call_hash, |
.compare = pending_call_compare, |
.remove_callback = pending_call_remove_callback |
}; |
static hash_index_t pending_call_hash(unsigned long key[]) |
{ |
// printf("pending_call_hash\n"); |
return key[0] % PCALL_TABLE_CHAINS; |
} |
static int pending_call_compare(unsigned long key[], hash_count_t keys, |
link_t *item) |
{ |
pending_call_t *hs; |
// printf("pending_call_compare\n"); |
hs = hash_table_get_instance(item, pending_call_t, link); |
// FIXME: this will fail if sizeof(long) < sizeof(void *). |
return key[0] == hs->call_hash; |
} |
static void pending_call_remove_callback(link_t *item) |
{ |
// printf("pending_call_remove_callback\n"); |
} |
void ipcp_connection_set(int phone, int server, proto_t *proto) |
{ |
if (phone <0 || phone >= MAX_PHONE) return; |
connections[phone].server = server; |
connections[phone].proto = proto; |
have_conn[phone] = 1; |
} |
void ipcp_connection_clear(int phone) |
{ |
have_conn[phone] = 0; |
connections[phone].server = 0; |
connections[phone].proto = NULL; |
} |
static void ipc_m_print(proto_t *proto, ipcarg_t method) |
{ |
oper_t *oper; |
/* Try system methods first */ |
oper = proto_get_oper(proto_system, method); |
if (oper == NULL && proto != NULL) { |
/* Not a system method, try the user protocol. */ |
oper = proto_get_oper(proto, method); |
} |
if (oper != NULL) { |
printf("%s (%ld)", oper->name, method); |
return; |
} |
printf("%ld", method); |
} |
void ipcp_init(void) |
{ |
ipc_m_desc_t *desc; |
oper_t *oper; |
val_type_t arg_def[OPER_MAX_ARGS] = { |
V_INTEGER, |
V_INTEGER, |
V_INTEGER, |
V_INTEGER, |
V_INTEGER |
}; |
/* |
* Create a pseudo-protocol 'unknown' that has no known methods. |
*/ |
proto_unknown = proto_new("unknown"); |
/* |
* Create a pseudo-protocol 'system' defining names of system IPC |
* methods. |
*/ |
proto_system = proto_new("system"); |
desc = ipc_methods; |
while (desc->number != 0) { |
oper = oper_new(desc->name, OPER_MAX_ARGS, arg_def, V_INTEGER, |
OPER_MAX_ARGS, arg_def); |
proto_add_oper(proto_system, desc->number, oper); |
++desc; |
} |
hash_table_create(&pending_calls, PCALL_TABLE_CHAINS, 1, &pending_call_ops); |
} |
void ipcp_cleanup(void) |
{ |
proto_delete(proto_system); |
hash_table_destroy(&pending_calls); |
} |
void ipcp_call_out(int phone, ipc_call_t *call, ipc_callid_t hash) |
{ |
pending_call_t *pcall; |
proto_t *proto; |
unsigned long key[1]; |
oper_t *oper; |
ipcarg_t *args; |
int i; |
if (have_conn[phone]) proto = connections[phone].proto; |
else proto = NULL; |
args = call->args; |
if ((display_mask & DM_IPC) != 0) { |
printf("Call ID: 0x%lx, phone: %d, proto: %s, method: ", hash, |
phone, (proto ? proto->name : "n/a")); |
ipc_m_print(proto, IPC_GET_METHOD(*call)); |
printf(" args: (%lu, %lu, %lu, %lu, %lu)\n", args[1], args[2], |
args[3], args[4], args[5]); |
} |
if ((display_mask & DM_USER) != 0) { |
if (proto != NULL) { |
oper = proto_get_oper(proto, IPC_GET_METHOD(*call)); |
} else { |
oper = NULL; |
} |
if (oper != NULL) { |
printf("%s(%d).%s", (proto ? proto->name : "n/a"), |
phone, (oper ? oper->name : "unknown")); |
putchar('('); |
for (i = 1; i <= oper->argc; ++i) { |
if (i > 1) printf(", "); |
val_print(args[i], oper->arg_type[i - 1]); |
} |
putchar(')'); |
if (oper->rv_type == V_VOID && oper->respc == 0) { |
/* |
* No response data (typically the task will |
* not be interested in the response). |
* We will not display response. |
*/ |
putchar('.'); |
} |
putchar('\n'); |
} |
} else { |
oper = NULL; |
} |
/* Store call in hash table for response matching */ |
pcall = malloc(sizeof(pending_call_t)); |
pcall->phone_hash = phone; |
pcall->question = *call; |
pcall->call_hash = hash; |
pcall->oper = oper; |
key[0] = hash; |
hash_table_insert(&pending_calls, key, &pcall->link); |
} |
static void parse_answer(ipc_callid_t hash, pending_call_t *pcall, |
ipc_call_t *answer) |
{ |
ipcarg_t phone; |
ipcarg_t method; |
ipcarg_t service; |
ipcarg_t retval; |
proto_t *proto; |
int cphone; |
ipcarg_t *resp; |
oper_t *oper; |
int i; |
// printf("parse_answer\n"); |
phone = pcall->phone_hash; |
method = IPC_GET_METHOD(pcall->question); |
retval = IPC_GET_RETVAL(*answer); |
resp = answer->args; |
if ((display_mask & DM_IPC) != 0) { |
printf("Response to 0x%lx: retval=%ld, args = (%lu, %lu, %lu, %lu, %lu)\n", |
hash, retval, IPC_GET_ARG1(*answer), |
IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), |
IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer)); |
} |
if ((display_mask & DM_USER) != 0) { |
oper = pcall->oper; |
if (oper != NULL && (oper->rv_type != V_VOID || oper->respc > 0)) { |
printf("->"); |
if (oper->rv_type != V_VOID) { |
putchar(' '); |
val_print(retval, oper->rv_type); |
} |
if (oper->respc > 0) { |
putchar(' '); |
putchar('('); |
for (i = 1; i <= oper->respc; ++i) { |
if (i > 1) printf(", "); |
val_print(resp[i], oper->resp_type[i - 1]); |
} |
putchar(')'); |
} |
putchar('\n'); |
} |
} |
if (phone == 0 && method == IPC_M_CONNECT_ME_TO && retval == 0) { |
/* Connected to a service (through NS) */ |
service = IPC_GET_ARG1(pcall->question); |
proto = proto_get_by_srv(service); |
if (proto == NULL) proto = proto_unknown; |
cphone = IPC_GET_ARG5(*answer); |
if ((display_mask & DM_SYSTEM) != 0) { |
printf("Registering connection (phone %d, protocol: %s)\n", cphone, |
proto->name); |
} |
ipcp_connection_set(cphone, 0, proto); |
} |
} |
void ipcp_call_in(ipc_call_t *call, ipc_callid_t hash) |
{ |
link_t *item; |
pending_call_t *pcall; |
unsigned long key[1]; |
// printf("ipcp_call_in()\n"); |
if ((hash & IPC_CALLID_ANSWERED) == 0 && hash != IPCP_CALLID_SYNC) { |
/* Not a response */ |
if ((display_mask & DM_IPC) != 0) { |
printf("Not a response (hash 0x%lx)\n", hash); |
} |
return; |
} |
hash = hash & ~IPC_CALLID_ANSWERED; |
key[0] = hash; |
item = hash_table_find(&pending_calls, key); |
if (item == NULL) return; // No matching question found |
/* |
* Response matched to question. |
*/ |
pcall = hash_table_get_instance(item, pending_call_t, link); |
hash_table_remove(&pending_calls, key, 1); |
parse_answer(hash, pcall, call); |
free(pcall); |
} |
void ipcp_call_sync(int phone, ipc_call_t *call, ipc_call_t *answer) |
{ |
ipcp_call_out(phone, call, IPCP_CALLID_SYNC); |
ipcp_call_in(answer, IPCP_CALLID_SYNC); |
} |
void ipcp_hangup(int phone, int rc) |
{ |
if ((display_mask & DM_SYSTEM) != 0) { |
printf("Hang phone %d up -> %d\n", phone, rc); |
ipcp_connection_clear(phone); |
} |
} |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/trace.h |
---|
0,0 → 1,71 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#ifndef TRACE_H_ |
#define TRACE_H_ |
#include <sys/types.h> |
/** |
* Classes of events that can be displayed. Can be or-ed together. |
*/ |
typedef enum { |
DM_THREAD = 1, /**< Thread creation and termination events */ |
DM_SYSCALL = 2, /**< System calls */ |
DM_IPC = 4, /**< Low-level IPC */ |
DM_SYSTEM = 8, /**< Sysipc protocol */ |
DM_USER = 16 /**< User IPC protocols */ |
} display_mask_t; |
typedef enum { |
V_VOID, |
V_INTEGER, |
V_PTR, |
V_HASH, |
V_ERRNO, |
V_INT_ERRNO, |
V_CHAR |
} val_type_t; |
/** Combination of events to print. */ |
extern display_mask_t display_mask; |
void val_print(sysarg_t val, val_type_t v_type); |
#endif |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/syscalls.h |
---|
0,0 → 1,51 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#ifndef SYSCALLS_H_ |
#define SYSCALLS_H_ |
#include "trace.h" |
typedef struct { |
char *name; |
int n_args; |
val_type_t rv_type; |
} sc_desc_t; |
extern const sc_desc_t syscall_desc[]; |
#endif |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/syscalls.c |
---|
0,0 → 1,80 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#include <kernel/syscall/syscall.h> |
#include "syscalls.h" |
#include "trace.h" |
const sc_desc_t syscall_desc[] = { |
[SYS_KLOG] ={ "klog", 3, V_INT_ERRNO }, |
[SYS_TLS_SET] = { "tls_set", 1, V_ERRNO }, |
[SYS_THREAD_CREATE] = { "thread_create", 3, V_ERRNO }, |
[SYS_THREAD_EXIT] = { "thread_exit", 1, V_ERRNO }, |
[SYS_THREAD_GET_ID] = { "thread_get_id", 1, V_ERRNO }, |
[SYS_TASK_GET_ID] = { "task_get_id", 1, V_ERRNO }, |
[SYS_FUTEX_SLEEP] = { "futex_sleep_timeout", 3, V_ERRNO }, |
[SYS_FUTEX_WAKEUP] = { "futex_wakeup", 1, V_ERRNO }, |
[SYS_AS_AREA_CREATE] = { "as_area_create", 3, V_ERRNO }, |
[SYS_AS_AREA_RESIZE] = { "as_area_resize", 3, V_ERRNO }, |
[SYS_AS_AREA_DESTROY] = { "as_area_destroy", 1, V_ERRNO }, |
[SYS_IPC_CALL_SYNC_FAST] = { "ipc_call_sync_fast", 6, V_ERRNO }, |
[SYS_IPC_CALL_SYNC_SLOW] = { "ipc_call_sync_slow", 3, V_ERRNO }, |
[SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6, V_HASH }, |
[SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2, V_HASH }, |
[SYS_IPC_ANSWER_FAST] = { "ipc_answer_fast", 6, V_ERRNO }, |
[SYS_IPC_ANSWER_SLOW] = { "ipc_answer_slow", 2, V_ERRNO }, |
[SYS_IPC_FORWARD_FAST] = { "ipc_forward_fast", 6, V_ERRNO }, |
[SYS_IPC_WAIT] = { "ipc_wait_for_call", 3, V_HASH }, |
[SYS_IPC_HANGUP] = { "ipc_hangup", 1, V_ERRNO }, |
[SYS_IPC_REGISTER_IRQ] = { "ipc_register_irq", 4, V_ERRNO }, |
[SYS_IPC_UNREGISTER_IRQ] = { "ipc_unregister_irq", 2, V_ERRNO }, |
[SYS_CAP_GRANT] = { "cap_grant", 2, V_ERRNO }, |
[SYS_CAP_REVOKE] = { "cap_revoke", 2, V_ERRNO }, |
[SYS_PHYSMEM_MAP] = { "physmem_map", 4, V_ERRNO }, |
[SYS_IOSPACE_ENABLE] = { "iospace_enable", 1, V_ERRNO }, |
[SYS_PREEMPT_CONTROL] = { "preempt_control", 1, V_ERRNO }, |
[SYS_SYSINFO_VALID] = { "sysinfo_valid", 2, V_HASH }, |
[SYS_SYSINFO_VALUE] = { "sysinfo_value", 2, V_HASH }, |
[SYS_DEBUG_ENABLE_CONSOLE] = { "debug_enable_console", 0, V_ERRNO }, |
[SYS_IPC_CONNECT_KBOX] = { "ipc_connect_kbox", 1, V_ERRNO } |
}; |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/proto.c |
---|
0,0 → 1,236 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <ipc/ipc.h> |
#include <libadt/hash_table.h> |
#include "trace.h" |
#include "proto.h" |
#define SRV_PROTO_TABLE_CHAINS 32 |
#define METHOD_OPER_TABLE_CHAINS 32 |
hash_table_t srv_proto; |
typedef struct { |
int srv; |
proto_t *proto; |
link_t link; |
} srv_proto_t; |
typedef struct { |
ipcarg_t method; |
oper_t *oper; |
link_t link; |
} method_oper_t; |
static hash_index_t srv_proto_hash(unsigned long key[]); |
static int srv_proto_compare(unsigned long key[], hash_count_t keys, |
link_t *item); |
static void srv_proto_remove_callback(link_t *item); |
hash_table_operations_t srv_proto_ops = { |
.hash = srv_proto_hash, |
.compare = srv_proto_compare, |
.remove_callback = srv_proto_remove_callback |
}; |
static hash_index_t method_oper_hash(unsigned long key[]); |
static int method_oper_compare(unsigned long key[], hash_count_t keys, |
link_t *item); |
static void method_oper_remove_callback(link_t *item); |
hash_table_operations_t method_oper_ops = { |
.hash = method_oper_hash, |
.compare = method_oper_compare, |
.remove_callback = method_oper_remove_callback |
}; |
static hash_index_t srv_proto_hash(unsigned long key[]) |
{ |
return key[0] % SRV_PROTO_TABLE_CHAINS; |
} |
static int srv_proto_compare(unsigned long key[], hash_count_t keys, |
link_t *item) |
{ |
srv_proto_t *sp; |
sp = hash_table_get_instance(item, srv_proto_t, link); |
return key[0] == sp->srv; |
} |
static void srv_proto_remove_callback(link_t *item) |
{ |
} |
static hash_index_t method_oper_hash(unsigned long key[]) |
{ |
return key[0] % METHOD_OPER_TABLE_CHAINS; |
} |
static int method_oper_compare(unsigned long key[], hash_count_t keys, |
link_t *item) |
{ |
method_oper_t *mo; |
mo = hash_table_get_instance(item, method_oper_t, link); |
return key[0] == mo->method; |
} |
static void method_oper_remove_callback(link_t *item) |
{ |
} |
void proto_init(void) |
{ |
hash_table_create(&srv_proto, SRV_PROTO_TABLE_CHAINS, 1, |
&srv_proto_ops); |
} |
void proto_cleanup(void) |
{ |
hash_table_destroy(&srv_proto); |
} |
void proto_register(int srv, proto_t *proto) |
{ |
srv_proto_t *sp; |
unsigned long key; |
sp = malloc(sizeof(srv_proto_t)); |
sp->srv = srv; |
sp->proto = proto; |
key = srv; |
hash_table_insert(&srv_proto, &key, &sp->link); |
} |
proto_t *proto_get_by_srv(int srv) |
{ |
unsigned long key; |
link_t *item; |
srv_proto_t *sp; |
key = srv; |
item = hash_table_find(&srv_proto, &key); |
if (item == NULL) return NULL; |
sp = hash_table_get_instance(item, srv_proto_t, link); |
return sp->proto; |
} |
static void proto_struct_init(proto_t *proto, char *name) |
{ |
proto->name = name; |
hash_table_create(&proto->method_oper, SRV_PROTO_TABLE_CHAINS, 1, |
&method_oper_ops); |
} |
proto_t *proto_new(char *name) |
{ |
proto_t *p; |
p = malloc(sizeof(proto_t)); |
proto_struct_init(p, name); |
return p; |
} |
void proto_delete(proto_t *proto) |
{ |
free(proto); |
} |
void proto_add_oper(proto_t *proto, int method, oper_t *oper) |
{ |
method_oper_t *mo; |
unsigned long key; |
mo = malloc(sizeof(method_oper_t)); |
mo->method = method; |
mo->oper = oper; |
key = method; |
hash_table_insert(&proto->method_oper, &key, &mo->link); |
} |
oper_t *proto_get_oper(proto_t *proto, int method) |
{ |
unsigned long key; |
link_t *item; |
method_oper_t *mo; |
key = method; |
item = hash_table_find(&proto->method_oper, &key); |
if (item == NULL) return NULL; |
mo = hash_table_get_instance(item, method_oper_t, link); |
return mo->oper; |
} |
static void oper_struct_init(oper_t *oper, char *name) |
{ |
oper->name = name; |
} |
oper_t *oper_new(char *name, int argc, val_type_t *arg_types, |
val_type_t rv_type, int respc, val_type_t *resp_types) |
{ |
oper_t *o; |
int i; |
o = malloc(sizeof(oper_t)); |
oper_struct_init(o, name); |
o->argc = argc; |
for (i = 0; i < argc; i++) |
o->arg_type[i] = arg_types[i]; |
o->rv_type = rv_type; |
o->respc = respc; |
for (i = 0; i < respc; i++) |
o->resp_type[i] = resp_types[i]; |
return o; |
} |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/proto.h |
---|
0,0 → 1,85 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#ifndef PROTO_H_ |
#define PROTO_H_ |
#include <libadt/hash_table.h> |
#include <ipc/ipc.h> |
#include "trace.h" |
#define OPER_MAX_ARGS (IPC_CALL_LEN - 1) |
typedef struct { |
char *name; |
int argc; |
val_type_t arg_type[OPER_MAX_ARGS]; |
val_type_t rv_type; |
int respc; |
val_type_t resp_type[OPER_MAX_ARGS]; |
} oper_t; |
typedef struct { |
/** Protocol name */ |
char *name; |
/** Maps method number to operation */ |
hash_table_t method_oper; |
} proto_t; |
/* Maps service number to protocol */ |
extern hash_table_t srv_proto; |
void proto_init(void); |
void proto_cleanup(void); |
void proto_register(int srv, proto_t *proto); |
proto_t *proto_get_by_srv(int srv); |
proto_t *proto_new(char *name); |
void proto_delete(proto_t *proto); |
void proto_add_oper(proto_t *proto, int method, oper_t *oper); |
oper_t *proto_get_oper(proto_t *proto, int method); |
oper_t *oper_new(char *name, int argc, val_type_t *arg_types, |
val_type_t rv_type, int respc, val_type_t *resp_types); |
#endif |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/ipc_desc.h |
---|
0,0 → 1,48 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#ifndef IPC_DESC_H_ |
#define IPC_DESC_H_ |
typedef struct { |
int number; |
char *name; |
} ipc_m_desc_t; |
extern ipc_m_desc_t ipc_methods[]; |
#endif |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/ipcp.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 trace |
* @{ |
*/ |
/** @file |
*/ |
#ifndef IPCP_H_ |
#define IPCP_H_ |
#include <ipc/ipc.h> |
#include "proto.h" |
void ipcp_init(void); |
void ipcp_cleanup(void); |
void ipcp_call_out(int phone, ipc_call_t *call, ipc_callid_t hash); |
void ipcp_call_sync(int phone, ipc_call_t *call, ipc_call_t *answer); |
void ipcp_call_in(ipc_call_t *call, ipc_callid_t hash); |
void ipcp_hangup(int phone, int rc); |
void ipcp_connection_set(int phone, int server, proto_t *proto); |
void ipcp_connection_clear(int phone); |
#endif |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/errors.h |
---|
0,0 → 1,48 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#ifndef ERRORS_H_ |
#define ERRORS_H_ |
typedef struct { |
char *name; /**< Error value name (Exx) */ |
char *desc; /**< Error description */ |
} err_desc_t; |
extern const err_desc_t err_desc[]; |
#endif |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/ipc_desc.c |
---|
0,0 → 1,58 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#include <stdlib.h> |
#include <ipc/ipc.h> |
#include "ipc_desc.h" |
ipc_m_desc_t ipc_methods[] = { |
/* System methods */ |
{ IPC_M_CONNECT_TO_ME, "CONNECT_TO_ME" }, |
{ IPC_M_CONNECT_ME_TO, "CONNECT_ME_TO" }, |
{ IPC_M_PHONE_HUNGUP, "PHONE_HUNGUP" }, |
{ IPC_M_SHARE_OUT, "SHARE_OUT" }, |
{ IPC_M_SHARE_IN, "SHARE_IN" }, |
{ IPC_M_DATA_WRITE, "DATA_WRITE" }, |
{ IPC_M_DATA_READ, "DATA_READ" }, |
{ IPC_M_DEBUG_ALL, "DEBUG_ALL" }, |
/* Well-known methods */ |
{ IPC_M_PING, "PING" }, |
/* Terminating entry */ |
{ 0, NULL } |
}; |
/** @} |
*/ |
/branches/sparc/uspace/app/trace/Makefile |
---|
0,0 → 1,78 |
# |
# Copyright (c) 2005 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. |
# |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
LIBS = $(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = trace |
SOURCES = trace.c \ |
syscalls.c \ |
ipcp.c \ |
ipc_desc.c \ |
proto.c \ |
errors.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/branches/sparc/uspace/app/trace/errors.c |
---|
0,0 → 1,61 |
/* |
* 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 trace |
* @{ |
*/ |
/** @file |
*/ |
#include <errno.h> |
#include "errors.h" |
const err_desc_t err_desc[] = { |
[-EOK] = { "EOK", "No error" }, |
[-ENOENT] = { "ENOENT", "No such entry" }, |
[-ENOMEM] = { "ENOMEM", "Not enough memory" }, |
[-ELIMIT] = { "ELIMIT", "Limit exceeded" }, |
[-EREFUSED] = { "EREFUSED", "Connection refused" }, |
[-EFORWARD] = { "EFORWARD", "Forward error" }, |
[-EPERM] = { "EPERM", "Permission denied" }, |
[-EHANGUP] = { "EHANGUP", "Answerbox closed connection" }, |
[-EEXISTS] = { "EEXISTS", "Entry already exists" }, |
[-EBADMEM] = { "EBADMEM", "Bad memory pointer" }, |
[-ENOTSUP] = { "ENOTSUP", "Not supported" }, |
[-EADDRNOTAVAIL] = { "EADDRNOTAVAIL", "Address not available." }, |
[-ETIMEOUT] = { "ETIMEOUT", "Timeout expired" }, |
[-EINVAL] = { "EINVAL", "Invalid value" }, |
[-EBUSY] = { "EBUSY", "Resource is busy" }, |
[-EOVERFLOW] = { "EOVERFLOW", "The result does not fit its size." } |
}; |
/** @} |
*/ |