Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3447 → Rev 3448

/branches/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/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/dynload/uspace/app/bdsh/util.c
273,7 → 273,7
if (NULL == usr->cwd)
snprintf(usr->cwd, PATH_MAX, "(unknown)");
 
if (1 < cli_psprintf(&usr->prompt, "%s # ", usr->cwd)) {
if (1 < cli_psprintf(&usr->prompt, "%s ", usr->cwd)) {
cli_error(cli_errno, "Failed to set prompt");
return 1;
}
/branches/dynload/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/dynload/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/dynload/uspace/app/init/init.c
108,17 → 108,15
return -1;
}
buf = malloc(BUF_SIZE);
// FIXME: spawn("/srv/pci");
spawn("/srv/fb");
spawn("/srv/kbd");
spawn("/srv/console");
// FIXME: spawn("/sbin/pci");
spawn("/sbin/fb");
spawn("/sbin/kbd");
spawn("/sbin/console");
console_wait();
version_print();
spawn("/sbin/bdsh");
spawn("/app/bdsh");
free(buf);
return 0;
/branches/dynload/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);
/branches/dynload/uspace/app/trace/trace.c
0,0 → 1,658
/*
* 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 <syscall.h>
#include <ipc/ipc.h>
#include <fibril.h>
#include <errno.h>
#include <udebug.h>
#include <async.h>
#include <task.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
unsigned thread_hash_buf[THBUF_SIZE];
unsigned n_threads;
 
int next_thread_id;
 
int phoneid;
int abort_trace;
 
unsigned thash;
volatile int paused;
 
void thread_trace_start(unsigned thread_hash);
 
static proto_t *proto_console;
static task_id_t task_id;
 
/** Combination of events/data to print. */
display_mask_t display_mask;
 
static int task_connect(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(unsigned);
 
printf("Threads:");
for (i = 0; i < n_threads; i++) {
printf(" [%d] (hash 0x%x)", 1+i, thread_hash_buf[i]);
}
printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
 
return 0;
}
 
static void print_sc_retval(int retval, rv_type_t rv_type)
{
printf (" -> ");
if (rv_type == RV_INTEGER) {
printf("%d", retval);
} else if (rv_type == RV_HASH) {
printf("0x%08x", retval);
} else if (rv_type == RV_ERRNO) {
if (retval >= -15 && retval <= 0) {
printf("%d %s (%s)", retval,
err_desc[retval].name,
err_desc[retval].desc);
} else {
printf("%d", retval);
}
} else if (rv_type == RV_INT_ERRNO) {
if (retval >= -15 && retval < 0) {
printf("%d %s (%s)", retval,
err_desc[retval].name,
err_desc[retval].desc);
} else {
printf("%d", retval);
}
}
putchar('\n');
}
 
static void print_sc_args(unsigned *sc_args, int n)
{
int i;
 
putchar('(');
if (n > 0) printf("%d", sc_args[0]);
for (i=1; i<n; i++) {
printf(", %d", sc_args[i]);
}
putchar(')');
}
 
static void sc_ipc_call_async_fast(unsigned *sc_args, int sc_rc)
{
ipc_call_t call;
int 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(unsigned *sc_args, int 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(unsigned *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(unsigned *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(unsigned *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, unsigned thread_hash, unsigned sc_id, int sc_rc)
{
unsigned 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, unsigned thread_hash, unsigned sc_id, int sc_rc)
{
unsigned 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(unsigned hash)
{
async_serialize_start();
printf("New thread, hash 0x%x\n", hash);
async_serialize_end();
 
thread_trace_start(hash);
}
 
static int trace_loop(void *thread_hash_arg)
{
int rc;
unsigned ev_type;
unsigned thread_hash;
unsigned thread_id;
unsigned val0, val1;
 
thread_hash = (unsigned)thread_hash_arg;
thread_id = next_thread_id++;
 
printf("Start tracing thread [%d] (hash 0x%x)\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%x 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(unsigned 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 void trace_active_task(task_id_t task_id)
{
int i;
int rc;
int c;
 
rc = task_connect(task_id);
if (rc < 0) {
printf("Failed to connect to task %lld\n", task_id);
return;
}
 
printf("Connected to task %lld\n", task_id);
 
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;
 
next_thread_id = 1;
paused = 0;
 
proto_init();
 
p = proto_new("vfs");
o = oper_new("read");
proto_add_oper(p, VFS_READ, o);
o = oper_new("write");
proto_add_oper(p, VFS_WRITE, o);
o = oper_new("truncate");
proto_add_oper(p, VFS_TRUNCATE, o);
o = oper_new("mount");
proto_add_oper(p, VFS_MOUNT, o);
o = oper_new("unmount");
proto_add_oper(p, VFS_UNMOUNT, o);
 
proto_register(SERVICE_VFS, p);
 
p = proto_new("console");
o = oper_new("getchar");
proto_add_oper(p, CONSOLE_GETCHAR, o);
o = oper_new("putchar");
proto_add_oper(p, CONSOLE_PUTCHAR, o);
o = oper_new("clear");
proto_add_oper(p, CONSOLE_CLEAR, o);
o = oper_new("goto");
proto_add_oper(p, CONSOLE_GOTO, o);
o = oper_new("getsize");
proto_add_oper(p, CONSOLE_GETSIZE, o);
o = oper_new("flush");
proto_add_oper(p, CONSOLE_FLUSH, o);
o = oper_new("set_style");
proto_add_oper(p, CONSOLE_SET_STYLE, o);
o = oper_new("cursor_visibility");
proto_add_oper(p, CONSOLE_CURSOR_VISIBILITY, o);
o = oper_new("flush");
proto_add_oper(p, CONSOLE_FLUSH, 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);
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;
printf("Extra arguments\n");
print_syntax();
return -1;
}
 
if (argc < 1) {
printf("Missing argument\n");
print_syntax();
return -1;
}
 
/* Execute the specified command and trace the new task. */
printf("Spawning '%s' with arguments:\n", *argv);
{
char **cp = argv;
while (*cp) printf("'%s'\n", *cp++);
}
task_id = task_spawn(*argv, argv);
 
return 0;
}
 
int main(int argc, char *argv[])
{
printf("System Call / IPC Tracer\n");
 
display_mask = DM_THREAD | DM_SYSTEM | DM_USER;
 
if (parse_args(argc, argv) < 0)
return 1;
 
main_init();
trace_active_task(task_id);
 
return 0;
}
 
/** @}
*/
/branches/dynload/uspace/app/trace/trace.h
0,0 → 1,57
/*
* 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_
 
/**
* 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;
 
/** Combination of events to print. */
extern display_mask_t display_mask;
 
#endif
 
/** @}
*/
/branches/dynload/uspace/app/trace/ipcp.c
0,0 → 1,334
/*
* 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 {
int phone_hash;
ipc_call_t question;
 
int 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);
 
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 (%d)", oper->name, method);
return;
}
 
printf("%d", method);
}
 
void ipcp_init(void)
{
ipc_m_desc_t *desc;
oper_t *oper;
 
/*
* 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);
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;
 
if (have_conn[phone]) proto = connections[phone].proto;
else proto = NULL;
 
if ((display_mask & DM_IPC) != 0) {
printf("Call ID: 0x%x, phone: %d, proto: %s, method: ", hash,
phone, (proto ? proto->name : "n/a"));
ipc_m_print(proto, IPC_GET_METHOD(*call));
printf(" args: (%u, %u, %u, %u, %u)\n",
IPC_GET_ARG1(*call),
IPC_GET_ARG2(*call),
IPC_GET_ARG3(*call),
IPC_GET_ARG4(*call),
IPC_GET_ARG5(*call)
);
}
 
 
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"));
 
printf("(%u, %u, %u, %u, %u)\n",
IPC_GET_ARG1(*call),
IPC_GET_ARG2(*call),
IPC_GET_ARG3(*call),
IPC_GET_ARG4(*call),
IPC_GET_ARG5(*call)
);
}
}
 
/* 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;
 
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)
{
int phone;
ipcarg_t method;
ipcarg_t service;
int retval;
proto_t *proto;
int cphone;
 
// printf("parse_answer\n");
 
phone = pcall->phone_hash;
method = IPC_GET_METHOD(pcall->question);
retval = IPC_GET_RETVAL(*answer);
 
if ((display_mask & DM_IPC) != 0) {
printf("Response to 0x%x: retval=%d, args = (%u, %u, %u, %u, %u)\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) {
printf("-> %d\n", retval);
}
 
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");
/* printf("phone: %d, method: ", call->in_phone_hash);
ipc_m_print(IPC_GET_METHOD(*call));
printf(" args: (%u, %u, %u, %u, %u)\n",
IPC_GET_ARG1(*call),
IPC_GET_ARG2(*call),
IPC_GET_ARG3(*call),
IPC_GET_ARG4(*call),
IPC_GET_ARG5(*call)
);*/
 
if ((hash & IPC_CALLID_ANSWERED) == 0 && hash != IPCP_CALLID_SYNC) {
/* Not a response */
if ((display_mask & DM_IPC) != 0) {
printf("Not a response (hash %d)\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/dynload/uspace/app/trace/proto.c
0,0 → 1,223
/*
* 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 "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)
{
oper_t *o;
 
o = malloc(sizeof(oper_t));
oper_struct_init(o, name);
 
return o;
}
 
/** @}
*/
/branches/dynload/uspace/app/trace/proto.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 PROTO_H_
#define PROTO_H_
 
#include <libadt/hash_table.h>
 
typedef struct {
char *name;
} 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);
 
 
#endif
 
/** @}
*/
/branches/dynload/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/dynload/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/dynload/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/dynload/uspace/app/trace/syscalls.h
0,0 → 1,56
/*
* 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_
 
typedef enum {
RV_INTEGER,
RV_HASH,
RV_ERRNO,
RV_INT_ERRNO
} rv_type_t;
 
typedef struct {
char *name;
int n_args;
rv_type_t rv_type;
} sc_desc_t;
 
extern const sc_desc_t syscall_desc[];
 
#endif
 
/** @}
*/
/branches/dynload/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/dynload/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/dynload/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." }
};
 
/** @}
*/
/branches/dynload/uspace/app/trace/syscalls.c
0,0 → 1,79
/*
* 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"
 
const sc_desc_t syscall_desc[] = {
[SYS_KLOG] ={ "klog", 3, RV_INT_ERRNO },
[SYS_TLS_SET] = { "tls_set", 1, RV_ERRNO },
[SYS_THREAD_CREATE] = { "thread_create", 3, RV_ERRNO },
[SYS_THREAD_EXIT] = { "thread_exit", 1, RV_ERRNO },
[SYS_THREAD_GET_ID] = { "thread_get_id", 1, RV_ERRNO },
 
[SYS_TASK_GET_ID] = { "task_get_id", 1, RV_ERRNO },
[SYS_FUTEX_SLEEP] = { "futex_sleep_timeout", 3, RV_ERRNO },
[SYS_FUTEX_WAKEUP] = { "futex_wakeup", 1, RV_ERRNO },
 
[SYS_AS_AREA_CREATE] = { "as_area_create", 3, RV_ERRNO },
[SYS_AS_AREA_RESIZE] = { "as_area_resize", 3, RV_ERRNO },
[SYS_AS_AREA_DESTROY] = { "as_area_destroy", 1, RV_ERRNO },
 
[SYS_IPC_CALL_SYNC_FAST] = { "ipc_call_sync_fast", 6, RV_ERRNO },
[SYS_IPC_CALL_SYNC_SLOW] = { "ipc_call_sync_slow", 3, RV_ERRNO },
[SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6, RV_HASH },
[SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2, RV_HASH },
 
[SYS_IPC_ANSWER_FAST] = { "ipc_answer_fast", 6, RV_ERRNO },
[SYS_IPC_ANSWER_SLOW] = { "ipc_answer_slow", 2, RV_ERRNO },
[SYS_IPC_FORWARD_FAST] = { "ipc_forward_fast", 6, RV_ERRNO },
[SYS_IPC_WAIT] = { "ipc_wait_for_call", 3, RV_HASH },
[SYS_IPC_HANGUP] = { "ipc_hangup", 1, RV_ERRNO },
[SYS_IPC_REGISTER_IRQ] = { "ipc_register_irq", 4, RV_ERRNO },
[SYS_IPC_UNREGISTER_IRQ] = { "ipc_unregister_irq", 2, RV_ERRNO },
 
[SYS_CAP_GRANT] = { "cap_grant", 2, RV_ERRNO },
[SYS_CAP_REVOKE] = { "cap_revoke", 2, RV_ERRNO },
[SYS_PHYSMEM_MAP] = { "physmem_map", 4, RV_ERRNO },
[SYS_IOSPACE_ENABLE] = { "iospace_enable", 1, RV_ERRNO },
[SYS_PREEMPT_CONTROL] = { "preempt_control", 1, RV_ERRNO },
 
[SYS_SYSINFO_VALID] = { "sysinfo_valid", 2, RV_HASH },
[SYS_SYSINFO_VALUE] = { "sysinfo_value", 2, RV_HASH },
[SYS_DEBUG_ENABLE_CONSOLE] = { "debug_enable_console", 0, RV_ERRNO },
[SYS_IPC_CONNECT_KBOX] = { "ipc_connect_kbox", 1, RV_ERRNO }
};
 
/** @}
*/