/branches/dd/uspace/app/ash/lex.yy.c |
---|
File deleted |
/branches/dd/uspace/app/ash/arith_lex.l |
---|
File deleted |
/branches/dd/uspace/app/ash/sh.1 |
---|
File deleted |
/branches/dd/uspace/app/ash/Makefile |
---|
File deleted |
/branches/dd/uspace/app/ash/funcs/cmv |
---|
File deleted |
/branches/dd/uspace/app/ash/funcs/login |
---|
File deleted |
/branches/dd/uspace/app/ash/funcs/kill |
---|
File deleted |
/branches/dd/uspace/app/ash/funcs/suspend |
---|
File deleted |
/branches/dd/uspace/app/ash/funcs/dirs |
---|
File deleted |
/branches/dd/uspace/app/ash/funcs/popd |
---|
File deleted |
/branches/dd/uspace/app/ash/funcs/newgrp |
---|
File deleted |
/branches/dd/uspace/app/ash/funcs/pushd |
---|
File deleted |
/branches/dd/uspace/app/ash/input.c |
---|
File deleted |
/branches/dd/uspace/app/ash/input.h |
---|
File deleted |
/branches/dd/uspace/app/ash/redir.c |
---|
File deleted |
/branches/dd/uspace/app/ash/arith.c |
---|
File deleted |
/branches/dd/uspace/app/ash/TOUR |
---|
File deleted |
/branches/dd/uspace/app/ash/redir.h |
---|
File deleted |
/branches/dd/uspace/app/ash/mktokens |
---|
File deleted |
/branches/dd/uspace/app/ash/arith.h |
---|
File deleted |
/branches/dd/uspace/app/ash/miscbltin.c |
---|
File deleted |
/branches/dd/uspace/app/ash/exec.c |
---|
File deleted |
/branches/dd/uspace/app/ash/cd.c |
---|
File deleted |
/branches/dd/uspace/app/ash/var.c |
---|
File deleted |
/branches/dd/uspace/app/ash/miscbltin.h |
---|
File deleted |
/branches/dd/uspace/app/ash/memalloc.c |
---|
File deleted |
/branches/dd/uspace/app/ash/exec.h |
---|
File deleted |
/branches/dd/uspace/app/ash/cd.h |
---|
File deleted |
/branches/dd/uspace/app/ash/options.c |
---|
File deleted |
/branches/dd/uspace/app/ash/parser.c |
---|
File deleted |
/branches/dd/uspace/app/ash/var.h |
---|
File deleted |
/branches/dd/uspace/app/ash/arith.y |
---|
File deleted |
/branches/dd/uspace/app/ash/jobs.c |
---|
File deleted |
/branches/dd/uspace/app/ash/memalloc.h |
---|
File deleted |
/branches/dd/uspace/app/ash/setmode.c |
---|
File deleted |
/branches/dd/uspace/app/ash/options.h |
---|
File deleted |
/branches/dd/uspace/app/ash/output.c |
---|
File deleted |
/branches/dd/uspace/app/ash/parser.h |
---|
File deleted |
/branches/dd/uspace/app/ash/jobs.h |
---|
File deleted |
/branches/dd/uspace/app/ash/output.h |
---|
File deleted |
/branches/dd/uspace/app/ash/builtins.def |
---|
File deleted |
/branches/dd/uspace/app/ash/mystring.c |
---|
File deleted |
/branches/dd/uspace/app/ash/histedit.c |
---|
File deleted |
/branches/dd/uspace/app/ash/tags |
---|
File deleted |
/branches/dd/uspace/app/ash/tools/Makefile |
---|
File deleted |
/branches/dd/uspace/app/ash/tools/mksyntax.c |
---|
File deleted |
/branches/dd/uspace/app/ash/tools/mksignames.c |
---|
File deleted |
/branches/dd/uspace/app/ash/tools/mknodes.c |
---|
File deleted |
/branches/dd/uspace/app/ash/tools/mkinit.c |
---|
File deleted |
/branches/dd/uspace/app/ash/show.c |
---|
File deleted |
/branches/dd/uspace/app/ash/mystring.h |
---|
File deleted |
/branches/dd/uspace/app/ash/show.h |
---|
File deleted |
/branches/dd/uspace/app/ash/myhistedit.h |
---|
File deleted |
/branches/dd/uspace/app/ash/nodetypes |
---|
File deleted |
/branches/dd/uspace/app/ash/error.c |
---|
File deleted |
/branches/dd/uspace/app/ash/error.h |
---|
File deleted |
/branches/dd/uspace/app/ash/trap.c |
---|
File deleted |
/branches/dd/uspace/app/ash/machdep.h |
---|
File deleted |
/branches/dd/uspace/app/ash/hetio.c |
---|
File deleted |
/branches/dd/uspace/app/ash/trap.h |
---|
File deleted |
/branches/dd/uspace/app/ash/shell.h |
---|
File deleted |
/branches/dd/uspace/app/ash/hetio.h |
---|
File deleted |
/branches/dd/uspace/app/ash/expand.c |
---|
File deleted |
/branches/dd/uspace/app/ash/mail.c |
---|
File deleted |
/branches/dd/uspace/app/ash/expand.h |
---|
File deleted |
/branches/dd/uspace/app/ash/main.c |
---|
File deleted |
/branches/dd/uspace/app/ash/mail.h |
---|
File deleted |
/branches/dd/uspace/app/ash/eval.c |
---|
File deleted |
/branches/dd/uspace/app/ash/bltin/echo.1 |
---|
File deleted |
/branches/dd/uspace/app/ash/bltin/bltin.h |
---|
File deleted |
/branches/dd/uspace/app/ash/bltin/echo.c |
---|
File deleted |
/branches/dd/uspace/app/ash/bltin/test.c |
---|
File deleted |
/branches/dd/uspace/app/ash/bltin/times.c |
---|
File deleted |
/branches/dd/uspace/app/ash/alias.c |
---|
File deleted |
/branches/dd/uspace/app/ash/main.h |
---|
File deleted |
/branches/dd/uspace/app/ash/nodes.c.pat |
---|
File deleted |
/branches/dd/uspace/app/ash/eval.h |
---|
File deleted |
/branches/dd/uspace/app/ash/alias.h |
---|
File deleted |
/branches/dd/uspace/app/ash/mkbuiltins |
---|
File deleted |
/branches/dd/uspace/app/ash/fake.c |
---|
File deleted |
/branches/dd/uspace/app/ash/init.h |
---|
File deleted |
/branches/dd/uspace/app/ash/fake.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/input.c |
---|
0,0 → 1,146 |
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com> |
* All rights reserved. |
* 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. |
* |
* 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 <string.h> |
#include <io/stream.h> |
#include <console.h> |
#include "config.h" |
#include "util.h" |
#include "scli.h" |
#include "input.h" |
#include "errors.h" |
#include "exec.h" |
static void read_line(char *, int); |
/* Tokenizes input from console, sees if the first word is a built-in, if so |
* invokes the built-in entry point (a[0]) passing all arguments in a[] to |
* the handler */ |
int tok_input(cliuser_t *usr) |
{ |
char *cmd[WORD_MAX]; |
int n = 0, i = 0; |
int rc = 0; |
char *tmp; |
if (NULL == usr->line) |
return CL_EFAIL; |
tmp = strdup(usr->line); |
cmd[n] = strtok(tmp, " "); |
while (cmd[n] && n < WORD_MAX) { |
cmd[++n] = strtok(NULL, " "); |
} |
/* We have rubbish */ |
if (NULL == cmd[0]) { |
rc = CL_ENOENT; |
goto finit; |
} |
/* Its a builtin command ? */ |
if ((i = (is_builtin(cmd[0]))) > -1) { |
rc = run_builtin(i, cmd, usr); |
goto finit; |
/* Its a module ? */ |
} else if ((i = (is_module(cmd[0]))) > -1) { |
rc = run_module(i, cmd); |
goto finit; |
} |
/* See what try_exec thinks of it */ |
rc = try_exec(cmd[0], cmd); |
finit: |
if (NULL != usr->line) { |
free(usr->line); |
usr->line = (char *) NULL; |
} |
if (NULL != tmp) |
free(tmp); |
return rc; |
} |
static void read_line(char *buffer, int n) |
{ |
char c; |
int chars; |
chars = 0; |
while (chars < n - 1) { |
c = getchar(); |
if (c < 0) |
return; |
if (c == '\n') |
break; |
if (c == '\b') { |
if (chars > 0) { |
putchar('\b'); |
--chars; |
} |
continue; |
} |
if (c >= ' ') { |
putchar(c); |
buffer[chars++] = c; |
} |
} |
putchar('\n'); |
buffer[chars] = '\0'; |
} |
/* TODO: |
* Implement something like editline() / readline(), if even |
* just for command history and making arrows work. */ |
void get_input(cliuser_t *usr) |
{ |
char line[INPUT_MAX]; |
size_t len = 0; |
console_set_style(STYLE_EMPHASIS); |
printf("%s", usr->prompt); |
console_set_style(STYLE_NORMAL); |
read_line(line, INPUT_MAX); |
len = strlen(line); |
/* Make sure we don't have rubbish or a C/R happy user */ |
if (len == 0 || line[0] == '\n') |
return; |
usr->line = strdup(line); |
return; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/ls/ls.c |
---|
0,0 → 1,214 |
/* 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. |
*/ |
/* NOTE: |
* This is a bit of an ugly hack, working around the absence of fstat / etc. |
* As more stuff is completed and exposed in libc, this will improve */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <dirent.h> |
#include <fcntl.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <string.h> |
#include "errors.h" |
#include "config.h" |
#include "util.h" |
#include "entry.h" |
#include "ls.h" |
#include "cmds.h" |
static char *cmdname = "ls"; |
static inline off_t flen(const char *f) |
{ |
int fd; |
off_t size; |
fd = open(f, O_RDONLY); |
if (fd == -1) |
return 0; |
size = lseek(fd, 0, SEEK_END); |
close(fd); |
if (size < 0) |
size = 0; |
return size; |
} |
static unsigned int ls_scope(const char *path) |
{ |
int fd; |
DIR *dirp; |
dirp = opendir(path); |
if (dirp) { |
closedir(dirp); |
return LS_DIR; |
} |
fd = open(path, O_RDONLY); |
if (fd > 0) { |
close(fd); |
return LS_FILE; |
} |
return LS_BOGUS; |
} |
static void ls_scan_dir(const char *d, DIR *dirp) |
{ |
struct dirent *dp; |
unsigned int scope; |
char *buff; |
if (! dirp) |
return; |
buff = (char *)malloc(PATH_MAX); |
if (NULL == buff) { |
cli_error(CL_ENOMEM, "ls: failed to scan %s", d); |
return; |
} |
while ((dp = readdir(dirp))) { |
memset(buff, 0, sizeof(buff)); |
/* Don't worry if inserting a double slash, this will be fixed by |
* absolutize() later with subsequent calls to open() or readdir() */ |
snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name); |
scope = ls_scope(buff); |
switch (scope) { |
case LS_DIR: |
ls_print_dir(dp->d_name); |
break; |
case LS_FILE: |
ls_print_file(dp->d_name, buff); |
break; |
case LS_BOGUS: |
/* Odd chance it was deleted from the time readdir() found |
* it and the time that it was scoped */ |
printf("ls: skipping bogus node %s\n", dp->d_name); |
break; |
} |
} |
free(buff); |
return; |
} |
/* ls_print_* currently does nothing more than print the entry. |
* in the future, we will likely pass the absolute path, and |
* some sort of ls_options structure that controls how each |
* entry is printed and what is printed about it. |
* |
* Now we just print basic DOS style lists */ |
static void ls_print_dir(const char *d) |
{ |
printf("%-40s\t<dir>\n", d); |
return; |
} |
static void ls_print_file(const char *name, const char *pathname) |
{ |
printf("%-40s\t%llu\n", name, (long long) flen(pathname)); |
return; |
} |
void help_cmd_ls(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' lists files and directories.\n", cmdname); |
} else { |
help_cmd_ls(HELP_SHORT); |
printf(" `%s' [path], if no path is given the current " |
"working directory is used.\n", cmdname); |
} |
return; |
} |
int cmd_ls(char **argv) |
{ |
unsigned int argc; |
unsigned int scope; |
char *buff; |
DIR *dirp; |
argc = cli_count_args(argv); |
buff = (char *) malloc(PATH_MAX); |
if (NULL == buff) { |
cli_error(CL_ENOMEM, "%s: ", cmdname); |
return CMD_FAILURE; |
} |
memset(buff, 0, sizeof(buff)); |
if (argc == 1) |
getcwd(buff, PATH_MAX); |
else |
strncpy(buff, argv[1], PATH_MAX); |
scope = ls_scope(buff); |
switch (scope) { |
case LS_BOGUS: |
cli_error(CL_ENOENT, buff); |
free(buff); |
return CMD_FAILURE; |
case LS_FILE: |
ls_print_file(buff, buff); |
break; |
case LS_DIR: |
dirp = opendir(buff); |
if (! dirp) { |
/* May have been deleted between scoping it and opening it */ |
cli_error(CL_EFAIL, "Could not stat %s", buff); |
free(buff); |
return CMD_FAILURE; |
} |
ls_scan_dir(buff, dirp); |
closedir(dirp); |
break; |
} |
free(buff); |
return CMD_SUCCESS; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/ls/ls.h |
---|
0,0 → 1,16 |
#ifndef LS_H |
#define LS_H |
/* Various values that can be returned by ls_scope() */ |
#define LS_BOGUS 0 |
#define LS_FILE 1 |
#define LS_DIR 2 |
static unsigned int ls_scope(const char *); |
static void ls_scan_dir(const char *, DIR *); |
static void ls_print_dir(const char *); |
static void ls_print_file(const char *, const char *); |
#endif /* LS_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/ls/ls_def.h |
---|
0,0 → 1,6 |
{ |
"ls", |
"List files and directories", |
&cmd_ls, |
&help_cmd_ls, |
}, |
/branches/dd/uspace/app/bdsh/cmds/modules/ls/entry.h |
---|
0,0 → 1,9 |
#ifndef LS_ENTRY_H |
#define LS_ENTRY_H |
/* Entry points for the ls command */ |
extern int cmd_ls(char **); |
extern void help_cmd_ls(unsigned int); |
#endif /* LS_ENTRY_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/cp/cp.c |
---|
0,0 → 1,231 |
/* 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 <unistd.h> |
#include <getopt.h> |
#include <string.h> |
#include <fcntl.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "cp.h" |
#include "cmds.h" |
#define CP_VERSION "0.0.1" |
#define CP_DEFAULT_BUFLEN 1024 |
static const char *cmdname = "cp"; |
static struct option const long_options[] = { |
{ "buffer", required_argument, 0, 'b' }, |
{ "force", no_argument, 0, 'f' }, |
{ "recursive", no_argument, 0, 'r' }, |
{ "help", no_argument, 0, 'h' }, |
{ "version", no_argument, 0, 'v' }, |
{ "verbose", no_argument, 0, 'V' }, |
{ 0, 0, 0, 0 } |
}; |
static int strtoint(const char *s1) |
{ |
long t1; |
if (-1 == (t1 = strtol(s1, (char **) NULL, 10))) |
return -1; |
if (t1 <= 0) |
return -1; |
return (int) t1; |
} |
static int64_t copy_file(const char *src, const char *dest, |
size_t blen, int vb) |
{ |
int fd1, fd2, bytes = 0; |
off_t total = 0; |
int64_t copied = 0; |
char *buff = NULL; |
if (vb) |
printf("Copying %s to %s\n", src, dest); |
if (-1 == (fd1 = open(src, O_RDONLY))) { |
printf("Unable to open source file %s\n", src); |
return -1; |
} |
if (-1 == (fd2 = open(dest, O_CREAT))) { |
printf("Unable to open destination file %s\n", dest); |
close(fd1); |
return -1; |
} |
total = lseek(fd1, 0, SEEK_END); |
if (vb) |
printf("%d bytes to copy\n", total); |
lseek(fd1, 0, SEEK_SET); |
if (NULL == (buff = (char *) malloc(blen))) { |
printf("Unable to allocate enough memory to read %s\n", |
src); |
copied = -1; |
goto out; |
} |
for (;;) { |
ssize_t res; |
bytes = read(fd1, buff, blen); |
if (bytes <= 0) |
break; |
copied += bytes; |
res = bytes; |
do { |
/* |
* Theoretically, it may not be enough to call write() |
* only once. Also the previous read() may have |
* returned less data than requested. |
*/ |
bytes = write(fd2, buff, res); |
if (bytes < 0) |
goto err; |
res -= bytes; |
} while (res > 0); |
/* TODO: re-insert assert() once this is stand alone, |
* removed as abort() exits the entire shell |
*/ |
if (res != 0) { |
printf("\n%d more bytes than actually exist were copied\n", res); |
goto err; |
} |
} |
if (bytes < 0) { |
err: |
printf("\nError copying %s, (%d)\n", src, bytes); |
copied = bytes; |
} |
out: |
close(fd1); |
close(fd2); |
if (buff) |
free(buff); |
return copied; |
} |
void help_cmd_cp(unsigned int level) |
{ |
static char helpfmt[] = |
"Usage: %s [options] <source> <dest>\n" |
"Options: (* indicates not yet implemented)\n" |
" -h, --help A short option summary\n" |
" -v, --version Print version information and exit\n" |
"* -V, --verbose Be annoyingly noisy about what's being done\n" |
"* -f, --force Do not complain when <dest> exists\n" |
"* -r, --recursive Copy entire directories\n" |
" -b, --buffer ## Set the read buffer size to ##\n" |
"Currently, %s is under development, some options may not work.\n"; |
if (level == HELP_SHORT) { |
printf("`%s' copies files and directories\n", cmdname); |
} else { |
help_cmd_cp(HELP_SHORT); |
printf(helpfmt, cmdname, cmdname); |
} |
return; |
} |
int cmd_cp(char **argv) |
{ |
unsigned int argc, buffer = 0, verbose = 0; |
int c, opt_ind; |
int64_t ret; |
argc = cli_count_args(argv); |
for (c = 0, optind = 0, opt_ind = 0; c != -1;) { |
c = getopt_long(argc, argv, "hvVfrb:", long_options, &opt_ind); |
switch (c) { |
case 'h': |
help_cmd_cp(1); |
return CMD_SUCCESS; |
case 'v': |
printf("%d\n", CP_VERSION); |
return CMD_SUCCESS; |
case 'V': |
verbose = 1; |
break; |
case 'f': |
break; |
case 'r': |
break; |
case 'b': |
if (-1 == (buffer = strtoint(optarg))) { |
printf("%s: Invalid buffer specification, " |
"(should be a number greater than zero)\n", |
cmdname); |
return CMD_FAILURE; |
} |
if (verbose) |
printf("Buffer = %d\n", buffer); |
break; |
} |
} |
if (buffer == 0) |
buffer = CP_DEFAULT_BUFLEN; |
argc -= optind; |
if (argc != 2) { |
printf("%s: invalid number of arguments. Try %s --help\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
ret = copy_file(argv[optind], argv[optind + 1], buffer, verbose); |
if (verbose) |
printf("%d bytes copied\n", ret); |
if (ret >= 0) |
return CMD_SUCCESS; |
else |
return CMD_FAILURE; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/cp/cp_def.h |
---|
0,0 → 1,7 |
{ |
"cp", |
"Copy files and directories", |
&cmd_cp, |
&help_cmd_cp, |
}, |
/branches/dd/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/dd/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/dd/uspace/app/bdsh/cmds/modules/rm/rm.c |
---|
0,0 → 1,257 |
/* 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 <unistd.h> |
#include <fcntl.h> |
#include <dirent.h> |
#include <getopt.h> |
#include "config.h" |
#include "errors.h" |
#include "util.h" |
#include "entry.h" |
#include "rm.h" |
#include "cmds.h" |
static char *cmdname = "rm"; |
#define RM_VERSION "0.0.1" |
static rm_job_t rm; |
static struct option const long_options[] = { |
{ "help", no_argument, 0, 'h' }, |
{ "version", no_argument, 0, 'v' }, |
{ "recursive", no_argument, 0, 'r' }, |
{ "force", no_argument, 0, 'f' }, |
{ "safe", no_argument, 0, 's' }, |
{ 0, 0, 0, 0 } |
}; |
static unsigned int rm_start(rm_job_t *rm) |
{ |
rm->recursive = 0; |
rm->force = 0; |
rm->safe = 0; |
/* Make sure we can allocate enough memory to store |
* what is needed in the job structure */ |
if (NULL == (rm->nwd = (char *) malloc(PATH_MAX))) |
return 0; |
memset(rm->nwd, 0, sizeof(rm->nwd)); |
if (NULL == (rm->owd = (char *) malloc(PATH_MAX))) |
return 0; |
memset(rm->owd, 0, sizeof(rm->owd)); |
if (NULL == (rm->cwd = (char *) malloc(PATH_MAX))) |
return 0; |
memset(rm->cwd, 0, sizeof(rm->cwd)); |
chdir("."); |
if (NULL == (getcwd(rm->owd, PATH_MAX))) |
return 0; |
return 1; |
} |
static void rm_end(rm_job_t *rm) |
{ |
if (NULL != rm->nwd) |
free(rm->nwd); |
if (NULL != rm->owd) |
free(rm->owd); |
if (NULL != rm->cwd) |
free(rm->cwd); |
return; |
} |
static unsigned int rm_recursive(const char *path) |
{ |
int rc; |
/* First see if it will just go away */ |
rc = rmdir(path); |
if (rc == 0) |
return 0; |
/* Its not empty, recursively scan it */ |
cli_error(CL_ENOTSUP, |
"Can not remove %s, directory not empty", path); |
return 1; |
} |
static unsigned int rm_single(const char *path) |
{ |
if (unlink(path)) { |
cli_error(CL_EFAIL, "rm: could not remove file %s", path); |
return 1; |
} |
return 0; |
} |
static unsigned int rm_scope(const char *path) |
{ |
int fd; |
DIR *dirp; |
dirp = opendir(path); |
if (dirp) { |
closedir(dirp); |
return RM_DIR; |
} |
fd = open(path, O_RDONLY); |
if (fd > 0) { |
close(fd); |
return RM_FILE; |
} |
return RM_BOGUS; |
} |
/* Dispays help for rm in various levels */ |
void help_cmd_rm(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' removes files and directories.\n", cmdname); |
} else { |
help_cmd_rm(HELP_SHORT); |
printf( |
"Usage: %s [options] <path>\n" |
"Options:\n" |
" -h, --help A short option summary\n" |
" -v, --version Print version information and exit\n" |
" -r, --recursive Recursively remove sub directories\n" |
" -f, --force Do not prompt prior to removing files\n" |
" -s, --safe Stop if directories change during removal\n\n" |
"Currently, %s is under development, some options don't work.\n", |
cmdname, cmdname); |
} |
return; |
} |
/* Main entry point for rm, accepts an array of arguments */ |
int cmd_rm(char **argv) |
{ |
unsigned int argc; |
unsigned int i, scope, ret = 0; |
int c, opt_ind; |
size_t len; |
char *buff = NULL; |
argc = cli_count_args(argv); |
if (argc < 2) { |
cli_error(CL_EFAIL, |
"%s: insufficient arguments. Try %s --help", cmdname, cmdname); |
return CMD_FAILURE; |
} |
if (!rm_start(&rm)) { |
cli_error(CL_ENOMEM, "%s: could not initialize", cmdname); |
rm_end(&rm); |
return CMD_FAILURE; |
} |
for (c = 0, optind = 0, opt_ind = 0; c != -1;) { |
c = getopt_long(argc, argv, "hvrfs", long_options, &opt_ind); |
switch (c) { |
case 'h': |
help_cmd_rm(HELP_LONG); |
return CMD_SUCCESS; |
case 'v': |
printf("%s\n", RM_VERSION); |
return CMD_SUCCESS; |
case 'r': |
rm.recursive = 1; |
break; |
case 'f': |
rm.force = 1; |
break; |
case 's': |
rm.safe = 1; |
break; |
} |
} |
if (optind == argc) { |
cli_error(CL_EFAIL, |
"%s: insufficient arguments. Try %s --help", cmdname, cmdname); |
rm_end(&rm); |
return CMD_FAILURE; |
} |
i = optind; |
while (NULL != argv[i]) { |
len = strlen(argv[i]) + 2; |
buff = (char *) realloc(buff, len); |
if (buff == NULL) { |
printf("rm: out of memory\n"); |
ret = 1; |
break; |
} |
memset(buff, 0, sizeof(buff)); |
snprintf(buff, len, argv[i]); |
scope = rm_scope(buff); |
switch (scope) { |
case RM_BOGUS: /* FIXME */ |
case RM_FILE: |
ret += rm_single(buff); |
break; |
case RM_DIR: |
if (! rm.recursive) { |
printf("%s is a directory, use -r to remove it.\n", buff); |
ret ++; |
} else { |
ret += rm_recursive(buff); |
} |
break; |
} |
i++; |
} |
if (NULL != buff) |
free(buff); |
rm_end(&rm); |
if (ret) |
return CMD_FAILURE; |
else |
return CMD_SUCCESS; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/rm/rm_def.h |
---|
0,0 → 1,7 |
{ |
"rm", |
"Remove files and directories", |
&cmd_rm, |
&help_cmd_rm, |
}, |
/branches/dd/uspace/app/bdsh/cmds/modules/rm/entry.h |
---|
0,0 → 1,9 |
#ifndef RM_ENTRY_H |
#define RM_ENTRY_H |
/* Entry points for the rm command */ |
extern int cmd_rm(char **); |
extern void help_cmd_rm(unsigned int); |
#endif /* RM_ENTRY_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/rm/rm.h |
---|
0,0 → 1,43 |
#ifndef RM_H |
#define RM_H |
/* Return values for rm_scope() */ |
#define RM_BOGUS 0 |
#define RM_FILE 1 |
#define RM_DIR 2 |
/* Flags for rm_update() */ |
#define _RM_ENTRY 0 |
#define _RM_ADVANCE 1 |
#define _RM_REWIND 2 |
#define _RM_EXIT 3 |
/* A simple job structure */ |
typedef struct { |
/* Options set at run time */ |
unsigned int force; /* -f option */ |
unsigned int recursive; /* -r option */ |
unsigned int safe; /* -s option */ |
/* Keeps track of the job in progress */ |
int advance; /* How far deep we've gone since entering */ |
DIR *entry; /* Entry point to the tree being removed */ |
char *owd; /* Where we were when we invoked rm */ |
char *cwd; /* Current directory being transversed */ |
char *nwd; /* Next directory to be transversed */ |
/* Counters */ |
int f_removed; /* Number of files unlinked */ |
int d_removed; /* Number of directories unlinked */ |
} rm_job_t; |
/* Prototypes for the rm command, excluding entry points */ |
static unsigned int rm_start(rm_job_t *); |
static void rm_end(rm_job_t *rm); |
static unsigned int rm_recursive(const char *); |
static unsigned int rm_single(const char *); |
static unsigned int rm_scope(const char *); |
#endif /* RM_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/touch/touch.c |
---|
0,0 → 1,108 |
/* 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. |
*/ |
/* TODO: Options that people would expect, such as not creating the file if |
* it doesn't exist, specifying the access time, etc */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include <dirent.h> |
#include <sys/types.h> |
#include <string.h> |
#include "config.h" |
#include "errors.h" |
#include "util.h" |
#include "entry.h" |
#include "touch.h" |
#include "cmds.h" |
static char *cmdname = "touch"; |
/* Dispays help for touch in various levels */ |
void help_cmd_touch(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' updates access times for files\n", cmdname); |
} else { |
help_cmd_touch(HELP_SHORT); |
printf(" `%s' <file>, if the file does not exist it will be " |
"created\n", cmdname); |
} |
return; |
} |
/* Main entry point for touch, accepts an array of arguments */ |
int cmd_touch(char **argv) |
{ |
unsigned int argc, i = 0, ret = 0; |
int fd; |
char *buff = NULL; |
DIR *dirp; |
argc = cli_count_args(argv); |
if (argc == 1) { |
printf("%s - incorrect number of arguments. Try `help %s extended'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
for (i = 1; i < argc; i ++) { |
buff = strdup(argv[i]); |
dirp = opendir(buff); |
if (dirp) { |
cli_error(CL_ENOTSUP, "%s is a directory", buff); |
closedir(dirp); |
ret ++; |
continue; |
} |
fd = open(buff, O_RDWR | O_CREAT); |
if (fd < 0) { |
cli_error(CL_EFAIL, "Could not update / create %s ", buff); |
ret ++; |
continue; |
} else |
close(fd); |
free(buff); |
} |
if (ret) |
return CMD_FAILURE; |
else |
return CMD_SUCCESS; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/touch/touch_def.h |
---|
0,0 → 1,7 |
{ |
"touch", |
"Create files or update access times", |
&cmd_touch, |
&help_cmd_touch, |
}, |
/branches/dd/uspace/app/bdsh/cmds/modules/touch/entry.h |
---|
0,0 → 1,9 |
#ifndef TOUCH_ENTRY_H |
#define TOUCH_ENTRY_H |
/* Entry points for the touch command */ |
extern int cmd_touch(char **); |
extern void help_cmd_touch(unsigned int); |
#endif /* TOUCH_ENTRY_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/touch/touch.h |
---|
0,0 → 1,8 |
#ifndef TOUCH_H |
#define TOUCH_H |
/* Prototypes for the touch command, excluding entry points */ |
#endif /* TOUCH_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/mkdir/mkdir.c |
---|
0,0 → 1,251 |
/* 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 <dirent.h> |
#include <fcntl.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <getopt.h> |
#include <stdarg.h> |
#include "config.h" |
#include "errors.h" |
#include "util.h" |
#include "entry.h" |
#include "mkdir.h" |
#include "cmds.h" |
#define MKDIR_VERSION "0.0.1" |
static char *cmdname = "mkdir"; |
static struct option const long_options[] = { |
{"parents", no_argument, 0, 'p'}, |
{"verbose", no_argument, 0, 'v'}, |
{"mode", required_argument, 0, 'm'}, |
{"help", no_argument, 0, 'h'}, |
{"version", no_argument, 0, 'V'}, |
{"follow", no_argument, 0, 'f'}, |
{0, 0, 0, 0} |
}; |
void help_cmd_mkdir(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' creates a new directory\n", cmdname); |
} else { |
help_cmd_mkdir(HELP_SHORT); |
printf( |
"Usage: %s [options] <path>\n" |
"Options:\n" |
" -h, --help A short option summary\n" |
" -V, --version Print version information and exit\n" |
" -p, --parents Create needed parents for <path>\n" |
" -m, --mode Set permissions to [mode] (UNUSED)\n" |
" -v, --verbose Be extremely noisy about what is happening\n" |
" -f, --follow Go to the new directory once created\n" |
"Currently, %s is under development, some options don't work.\n", |
cmdname, cmdname); |
} |
return; |
} |
/* This is kind of clunky, but effective for now */ |
static unsigned int |
create_directory(const char *path, unsigned int p) |
{ |
DIR *dirp; |
char *tmp = NULL, *buff = NULL, *wdp = NULL; |
char *dirs[255]; |
unsigned int absolute = 0, i = 0, ret = 0; |
/* Its a good idea to allocate path, plus we (may) need a copy of |
* path to tokenize if parents are specified */ |
if (NULL == (tmp = strdup(path))) { |
cli_error(CL_ENOMEM, "%s: path too big?", cmdname); |
return 1; |
} |
if (NULL == (wdp = (char *) malloc(PATH_MAX))) { |
cli_error(CL_ENOMEM, "%s: could not alloc cwd", cmdname); |
free(tmp); |
return 1; |
} |
/* The only reason for wdp is to be (optionally) verbose */ |
getcwd(wdp, PATH_MAX); |
/* Typical use without specifying the creation of parents */ |
if (p == 0) { |
dirp = opendir(tmp); |
if (dirp) { |
cli_error(CL_EEXISTS, "%s: can not create %s, try -p", cmdname, path); |
closedir(dirp); |
goto finit; |
} |
if (-1 == (mkdir(tmp, 0))) { |
cli_error(CL_EFAIL, "%s: could not create %s", cmdname, path); |
goto finit; |
} |
} |
/* Parents need to be created, path has to be broken up */ |
/* See if path[0] is a slash, if so we have to remember to append it */ |
if (tmp[0] == '/') |
absolute = 1; |
/* TODO: Canonify the path prior to tokenizing it, see below */ |
dirs[i] = strtok(tmp, "/"); |
while (dirs[i] && i < 255) |
dirs[++i] = strtok(NULL, "/"); |
if (NULL == dirs[0]) |
return 1; |
if (absolute == 1) { |
asprintf(&buff, "/%s", dirs[0]); |
mkdir(buff, 0); |
chdir(buff); |
free(buff); |
getcwd(wdp, PATH_MAX); |
i = 1; |
} else { |
i = 0; |
} |
while (dirs[i] != NULL) { |
/* Sometimes make or scripts conjoin odd paths. Account for something |
* like this: ../../foo/bar/../foo/foofoo/./bar */ |
if (!strcmp(dirs[i], "..") || !strcmp(dirs[i], ".")) { |
if (0 != (chdir(dirs[i]))) { |
cli_error(CL_EFAIL, "%s: impossible path: %s", |
cmdname, path); |
ret ++; |
goto finit; |
} |
getcwd(wdp, PATH_MAX); |
} else { |
if (-1 == (mkdir(dirs[i], 0))) { |
cli_error(CL_EFAIL, |
"%s: failed at %s/%s", wdp, dirs[i]); |
ret ++; |
goto finit; |
} |
if (0 != (chdir(dirs[i]))) { |
cli_error(CL_EFAIL, "%s: failed creating %s\n", |
cmdname, dirs[i]); |
ret ++; |
break; |
} |
} |
i++; |
} |
goto finit; |
finit: |
free(wdp); |
free(tmp); |
return ret; |
} |
int cmd_mkdir(char **argv) |
{ |
unsigned int argc, create_parents = 0, i, ret = 0, follow = 0; |
unsigned int verbose = 0; |
int c, opt_ind; |
char *cwd; |
argc = cli_count_args(argv); |
for (c = 0, optind = 0, opt_ind = 0; c != -1;) { |
c = getopt_long(argc, argv, "pvhVfm:", long_options, &opt_ind); |
switch (c) { |
case 'p': |
create_parents = 1; |
break; |
case 'v': |
verbose = 1; |
break; |
case 'h': |
help_cmd_mkdir(HELP_LONG); |
return CMD_SUCCESS; |
case 'V': |
printf("%s\n", MKDIR_VERSION); |
return CMD_SUCCESS; |
case 'f': |
follow = 1; |
break; |
case 'm': |
printf("%s: [W] Ignoring mode %s\n", cmdname, optarg); |
break; |
} |
} |
argc -= optind; |
if (argc < 1) { |
printf("%s - incorrect number of arguments. Try `%s --help'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
if (NULL == (cwd = (char *) malloc(PATH_MAX))) { |
cli_error(CL_ENOMEM, "%s: could not allocate cwd", cmdname); |
return CMD_FAILURE; |
} |
memset(cwd, 0, sizeof(cwd)); |
getcwd(cwd, PATH_MAX); |
for (i = optind; argv[i] != NULL; i++) { |
if (verbose == 1) |
printf("%s: creating %s%s\n", |
cmdname, argv[i], |
create_parents ? " (and all parents)" : ""); |
ret += create_directory(argv[i], create_parents); |
} |
if (follow == 0) |
chdir(cwd); |
free(cwd); |
if (ret) |
return CMD_FAILURE; |
else |
return CMD_SUCCESS; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/mkdir/mkdir_def.h |
---|
0,0 → 1,8 |
{ |
"mkdir", |
"Create new directories", |
&cmd_mkdir, |
&help_cmd_mkdir, |
}, |
/branches/dd/uspace/app/bdsh/cmds/modules/mkdir/entry.h |
---|
0,0 → 1,9 |
#ifndef MKDIR_ENTRY_H |
#define MKDIR_ENTRY_H |
/* Entry points for the mkdir command */ |
extern int cmd_mkdir(char **); |
extern void help_cmd_mkdir(unsigned int); |
#endif /* MKDIR_ENTRY_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/mkdir/mkdir.h |
---|
0,0 → 1,8 |
#ifndef MKDIR_H |
#define MKDIR_H |
/* Prototypes for the mkdir command, excluding entry points */ |
static unsigned int create_directory(const char *, unsigned int); |
#endif /* MKDIR_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/modules.h |
---|
0,0 → 1,47 |
#ifndef MODULES_H |
#define MODULES_H |
/* Each built in function has two files, one being an entry.h file which |
* prototypes the run/help entry functions, the other being a .def file |
* which fills the modules[] array according to the cmd_t structure |
* defined in cmds.h. |
* |
* To add or remove a module, just make a new directory in cmds/modules |
* for it and copy the 'show' example for basics, then include it here. |
* (or reverse the process to remove one) |
* |
* NOTE: See module_ aliases.h as well, this is where aliases (commands that |
* share an entry point with others) are indexed */ |
#include "config.h" |
/* Prototypes for each module's entry (help/exec) points */ |
#include "help/entry.h" |
#include "mkdir/entry.h" |
#include "rm/entry.h" |
#include "cat/entry.h" |
#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 |
* are loaded based on what libraries exist on the system. */ |
module_t modules[] = { |
#include "help/help_def.h" |
#include "mkdir/mkdir_def.h" |
#include "rm/rm_def.h" |
#include "cat/cat_def.h" |
#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} |
}; |
#endif |
/branches/dd/uspace/app/bdsh/cmds/modules/cat/cat_def.h |
---|
0,0 → 1,7 |
{ |
"cat", |
"Show the contents of a file", |
&cmd_cat, |
&help_cmd_cat, |
}, |
/branches/dd/uspace/app/bdsh/cmds/modules/cat/cat.c |
---|
0,0 → 1,178 |
/* 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 <unistd.h> |
#include <getopt.h> |
#include <string.h> |
#include <fcntl.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "cat.h" |
#include "cmds.h" |
static char *cmdname = "cat"; |
#define CAT_VERSION "0.0.1" |
#define CAT_DEFAULT_BUFLEN 1024 |
static char *cat_oops = "That option is not yet supported\n"; |
static struct option const long_options[] = { |
{ "help", no_argument, 0, 'h' }, |
{ "version", no_argument, 0, 'v' }, |
{ "head", required_argument, 0, 'H' }, |
{ "tail", required_argument, 0, 't' }, |
{ "buffer", required_argument, 0, 'b' }, |
{ "more", no_argument, 0, 'm' }, |
{ 0, 0, 0, 0 } |
}; |
/* Dispays help for cat in various levels */ |
void help_cmd_cat(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' shows the contents of files\n", cmdname); |
} else { |
help_cmd_cat(HELP_SHORT); |
printf( |
"Usage: %s [options] <file1> [file2] [...]\n" |
"Options:\n" |
" -h, --help A short option summary\n" |
" -v, --version Print version information and exit\n" |
" -H, --head ## Print only the first ## bytes\n" |
" -t, --tail ## Print only the last ## bytes\n" |
" -b, --buffer ## Set the read buffer size to ##\n" |
" -m, --more Pause after each screen full\n" |
"Currently, %s is under development, some options don't work.\n", |
cmdname, cmdname); |
} |
return; |
} |
static unsigned int cat_file(const char *fname, size_t blen) |
{ |
int fd, bytes = 0, count = 0, reads = 0; |
off_t total = 0; |
char *buff = NULL; |
if (-1 == (fd = open(fname, O_RDONLY))) { |
printf("Unable to open %s\n", fname); |
return 1; |
} |
total = lseek(fd, 0, SEEK_END); |
lseek(fd, 0, SEEK_SET); |
if (NULL == (buff = (char *) malloc(blen + 1))) { |
close(fd); |
printf("Unable to allocate enough memory to read %s\n", |
fname); |
return 1; |
} |
do { |
bytes = read(fd, buff, blen); |
if (bytes > 0) { |
count += bytes; |
buff[bytes] = '\0'; |
printf("%s", buff); |
reads++; |
} |
} while (bytes > 0); |
close(fd); |
if (bytes == -1) { |
printf("Error reading %s\n", fname); |
free(buff); |
return 1; |
} |
free(buff); |
return 0; |
} |
/* Main entry point for cat, accepts an array of arguments */ |
int cmd_cat(char **argv) |
{ |
unsigned int argc, i, ret = 0, buffer = 0; |
int c, opt_ind; |
argc = cli_count_args(argv); |
for (c = 0, optind = 0, opt_ind = 0; c != -1;) { |
c = getopt_long(argc, argv, "hvmH:t:b:", long_options, &opt_ind); |
switch (c) { |
case 'h': |
help_cmd_cat(HELP_LONG); |
return CMD_SUCCESS; |
case 'v': |
printf("%s\n", CAT_VERSION); |
return CMD_SUCCESS; |
case 'H': |
printf(cat_oops); |
return CMD_FAILURE; |
case 't': |
printf(cat_oops); |
return CMD_FAILURE; |
case 'b': |
printf(cat_oops); |
break; |
case 'm': |
printf(cat_oops); |
return CMD_FAILURE; |
} |
} |
argc -= optind; |
if (argc < 1) { |
printf("%s - incorrect number of arguments. Try `%s --help'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
if (buffer <= 0) |
buffer = CAT_DEFAULT_BUFLEN; |
for (i = optind; argv[i] != NULL; i++) |
ret += cat_file(argv[i], buffer); |
if (ret) |
return CMD_FAILURE; |
else |
return CMD_SUCCESS; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/cat/entry.h |
---|
0,0 → 1,9 |
#ifndef CAT_ENTRY_H |
#define CAT_ENTRY_H |
/* Entry points for the cat command */ |
extern int cmd_cat(char **); |
extern void help_cmd_cat(unsigned int); |
#endif /* CAT_ENTRY_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/cat/cat.h |
---|
0,0 → 1,9 |
#ifndef CAT_H |
#define CAT_H |
/* Prototypes for the cat command, excluding entry points */ |
static unsigned int cat_file(const char *, size_t); |
#endif /* CAT_H */ |
/branches/dd/uspace/app/bdsh/cmds/modules/help/help.c |
---|
0,0 → 1,158 |
/* 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 <string.h> |
#include "config.h" |
#include "entry.h" |
#include "help.h" |
#include "cmds.h" |
#include "modules.h" |
#include "builtins.h" |
#include "errors.h" |
#include "util.h" |
static char *cmdname = "help"; |
extern const char *progname; |
#define HELP_IS_MODULE 1 |
#define HELP_IS_BUILTIN 0 |
#define HELP_IS_RUBBISH -1 |
volatile int mod_switch = -1; |
/* Just use a pointer here, no need for mod_switch */ |
static int is_mod_or_builtin(char *cmd) |
{ |
int rc = HELP_IS_RUBBISH; |
rc = is_builtin(cmd); |
if (rc > -1) { |
mod_switch = rc; |
return HELP_IS_BUILTIN; |
} |
rc = is_module(cmd); |
if (rc > -1) { |
mod_switch = rc; |
return HELP_IS_MODULE; |
} |
return HELP_IS_RUBBISH; |
} |
void help_cmd_help(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf( |
"\n %s [command] <extended>\n" |
" Use help [command] extended for detailed help on [command] " |
", even `help'\n\n", cmdname); |
} else { |
printf( |
"\n `%s' - shows help for commands\n" |
" Examples:\n" |
" %s [command] Show help for [command]\n" |
" %s [command] extended Show extended help for [command]\n" |
"\n If no argument is given to %s, a list of commands are shown\n\n", |
cmdname, cmdname, cmdname, cmdname); |
} |
return; |
} |
int cmd_help(char *argv[]) |
{ |
module_t *mod; |
builtin_t *cmd; |
unsigned int i = 0; |
int rc = 0; |
int argc; |
int level = HELP_SHORT; |
argc = cli_count_args(argv); |
if (argc > 3) { |
printf("\nToo many arguments to `%s', try:\n", cmdname); |
help_cmd_help(HELP_SHORT); |
return CMD_FAILURE; |
} |
if (argc == 3) { |
if (!strcmp("extended", argv[2])) |
level = HELP_LONG; |
else |
level = HELP_SHORT; |
} |
if (argc > 1) { |
rc = is_mod_or_builtin(argv[1]); |
switch (rc) { |
case HELP_IS_RUBBISH: |
printf("Invalid command %s\n", argv[1]); |
return CMD_FAILURE; |
case HELP_IS_MODULE: |
help_module(mod_switch, level); |
return CMD_SUCCESS; |
case HELP_IS_BUILTIN: |
help_builtin(mod_switch, level); |
return CMD_SUCCESS; |
} |
} |
printf("\n Available commands are:\n"); |
printf(" ------------------------------------------------------------\n"); |
/* First, show a list of built in commands that are available in this mode */ |
for (cmd = builtins; cmd->name != NULL; cmd++, i++) { |
if (is_builtin_alias(cmd->name)) |
printf(" %-16s\tAlias for `%s'\n", cmd->name, |
alias_for_builtin(cmd->name)); |
else |
printf(" %-16s\t%s\n", cmd->name, cmd->desc); |
} |
i = 0; |
/* Now, show a list of module commands that are available in this mode */ |
for (mod = modules; mod->name != NULL; mod++, i++) { |
if (is_module_alias(mod->name)) |
printf(" %-16s\tAlias for `%s'\n", mod->name, |
alias_for_module(mod->name)); |
else |
printf(" %-16s\t%s\n", mod->name, mod->desc); |
} |
printf("\n Try %s %s for more information on how `%s' works.\n\n", |
cmdname, cmdname, cmdname); |
return CMD_SUCCESS; |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/help/help_def.h |
---|
0,0 → 1,6 |
{ |
"help", |
"Show help for commands", |
&cmd_help, |
&help_cmd_help, |
}, |
/branches/dd/uspace/app/bdsh/cmds/modules/help/entry.h |
---|
0,0 → 1,8 |
#ifndef HELP_ENTRY_H_ |
#define HELP_ENTRY_H_ |
/* Entry points for the help command */ |
extern void help_cmd_help(unsigned int); |
extern int cmd_help(char *[]); |
#endif |
/branches/dd/uspace/app/bdsh/cmds/modules/help/help.h |
---|
0,0 → 1,7 |
#ifndef HELP_H |
#define HELP_H |
/* Prototypes for the help command (excluding entry points) */ |
static int is_mod_or_builtin(char *); |
#endif |
/branches/dd/uspace/app/bdsh/cmds/modules/sleep/sleep_def.h |
---|
0,0 → 1,7 |
{ |
"sleep", |
"Pause for given time interval (in seconds)", |
&cmd_sleep, |
&help_cmd_sleep, |
}, |
/branches/dd/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/dd/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/dd/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/dd/uspace/app/bdsh/cmds/modules/pwd/pwd_def.h |
---|
0,0 → 1,6 |
{ |
"pwd", |
"Prints the current working directory", |
&cmd_pwd, |
&help_cmd_pwd, |
}, |
/branches/dd/uspace/app/bdsh/cmds/modules/pwd/entry.h |
---|
0,0 → 1,12 |
#ifndef PWD_ENTRY_H |
#define PWD_ENTRY_H |
#include "scli.h" |
/* Entry points for the pwd command */ |
extern void help_cmd_pwd(unsigned int); |
extern int cmd_pwd(char **); |
#endif |
/branches/dd/uspace/app/bdsh/cmds/modules/pwd/pwd.c |
---|
0,0 → 1,71 |
/* 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 "errors.h" |
#include "entry.h" |
#include "cmds.h" |
#include "pwd.h" |
static char * cmdname = "pwd"; |
void help_cmd_pwd(unsigned int level) |
{ |
printf("`%s' prints your current working directory.\n", cmdname); |
return; |
} |
int cmd_pwd(char *argv[]) |
{ |
char *buff; |
buff = (char *) malloc(PATH_MAX); |
if (NULL == buff) { |
cli_error(CL_ENOMEM, "%s:", cmdname); |
return CMD_FAILURE; |
} |
memset(buff, 0, sizeof(buff)); |
getcwd(buff, PATH_MAX); |
if (! buff) { |
cli_error(CL_EFAIL, |
"Unable to determine the current working directory"); |
free(buff); |
return CMD_FAILURE; |
} else { |
printf("%s\n", buff); |
free(buff); |
return CMD_SUCCESS; |
} |
} |
/branches/dd/uspace/app/bdsh/cmds/modules/pwd/pwd.h |
---|
0,0 → 1,6 |
#ifndef PWD_H_ |
#define PWD_H_ |
/* Prototypes for the pwd command (excluding entry points) */ |
#endif |
/branches/dd/uspace/app/bdsh/cmds/modules/module_aliases.h |
---|
0,0 → 1,18 |
#ifndef MODULE_ALIASES_H |
#define MODULE_ALIASES_H |
/* Modules that declare multiple names for themselves but use the |
* same entry functions are aliases. This array helps to determine if |
* a module is an alias, as such it can be invoked differently. |
* format is alias , real_name */ |
/* So far, this is only used in the help display but could be used to |
* handle a module differently even prior to reaching its entry code. |
* For instance, 'exit' could behave differently than 'quit', prior to |
* the entry point being reached. */ |
char *mod_aliases[] = { |
NULL, NULL |
}; |
#endif |
/branches/dd/uspace/app/bdsh/cmds/modules/README |
---|
0,0 → 1,15 |
Modules are commands or full programs (anything can be made into a module |
that can return int type) should go here. Note, modules do not (can not) |
update or read cliuser_t. |
Stuff that needs to write to the user structures contained in scli.h should |
be made as built-in commands, not modules, but there are very few times when |
you would want to do that. |
See the README file in the bdsh root directory for a quick overview of how to |
write a new command, or convert an existig stand-alone program into a module |
for BDSH. |
/branches/dd/uspace/app/bdsh/cmds/builtins/builtins.h |
---|
0,0 → 1,15 |
#ifndef BUILTINS_H |
#define BUILTINS_H |
#include "config.h" |
#include "cd/entry.h" |
#include "exit/entry.h" |
builtin_t builtins[] = { |
#include "cd/cd_def.h" |
#include "exit/exit_def.h" |
{NULL, NULL, NULL, NULL} |
}; |
#endif |
/branches/dd/uspace/app/bdsh/cmds/builtins/exit/exit.h |
---|
0,0 → 1,6 |
#ifndef EXIT_H |
#define EXIT_H |
/* Prototypes for the quit command (excluding entry points) */ |
#endif |
/branches/dd/uspace/app/bdsh/cmds/builtins/exit/entry.h |
---|
0,0 → 1,12 |
#ifndef EXIT_ENTRY_H_ |
#define EXIT_ENTRY_H_ |
#include "scli.h" |
/* Entry points for the quit command */ |
extern void help_cmd_exit(unsigned int); |
extern int cmd_exit(char *[], cliuser_t *); |
#endif |
/branches/dd/uspace/app/bdsh/cmds/builtins/exit/exit.c |
---|
0,0 → 1,55 |
/* 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 "entry.h" |
#include "exit.h" |
#include "cmds.h" |
static const char *cmdname = "exit"; |
extern volatile unsigned int cli_quit; |
extern const char *progname; |
void help_cmd_exit(unsigned int level) |
{ |
printf("Type `%s' to exit %s\n", cmdname, progname); |
return; |
} |
/* Quits the program and returns the status of whatever command |
* came before invoking 'quit' */ |
int cmd_exit(char *argv[], cliuser_t *usr) |
{ |
/* Inform that we're outta here */ |
cli_quit = 1; |
return CMD_SUCCESS; |
} |
/branches/dd/uspace/app/bdsh/cmds/builtins/exit/exit_def.h |
---|
0,0 → 1,6 |
{ |
"exit", |
"Exit the shell", |
&cmd_exit, |
&help_cmd_exit, |
}, |
/branches/dd/uspace/app/bdsh/cmds/builtins/cd/cd_def.h |
---|
0,0 → 1,6 |
{ |
"cd", |
"Change the current working directory", |
&cmd_cd, |
&help_cmd_cd, |
}, |
/branches/dd/uspace/app/bdsh/cmds/builtins/cd/cd.c |
---|
0,0 → 1,106 |
/* 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 <unistd.h> |
#include <string.h> |
#include <errno.h> |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "cmds.h" |
#include "cd.h" |
static char * cmdname = "cd"; |
void help_cmd_cd(unsigned int level) |
{ |
if (level == HELP_SHORT) { |
printf("`%s' changes the current working directory.\n", cmdname); |
} else { |
printf( |
" %s <directory>\n" |
" Change directory to <directory>, e.g `%s /sbin'\n", |
cmdname, cmdname); |
} |
return; |
} |
/* This is a very rudamentary 'cd' command. It is not 'link smart' (yet) */ |
int cmd_cd(char **argv, cliuser_t *usr) |
{ |
int argc, rc = 0; |
argc = cli_count_args(argv); |
/* We don't yet play nice with whitespace, a getopt implementation should |
* protect "quoted\ destination" as a single argument. Its not our job to |
* look for && || or redirection as the tokenizer should have done that |
* (currently, it does not) */ |
if (argc > 2) { |
cli_error(CL_EFAIL, "Too many arguments to `%s'", cmdname); |
return CMD_FAILURE; |
} |
if (argc < 2) { |
printf("%s - no directory specified. Try `help %s extended'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
/* We have the correct # of arguments |
* TODO: handle tidle (~) expansion? */ |
rc = chdir(argv[1]); |
if (rc == 0) { |
cli_set_prompt(usr); |
return CMD_SUCCESS; |
} else { |
switch (rc) { |
case ENOMEM: |
cli_error(CL_EFAIL, "Destination path too long"); |
break; |
case ENOENT: |
cli_error(CL_ENOENT, "Invalid directory `%s'", argv[1]); |
break; |
default: |
cli_error(CL_EFAIL, "Unable to change to `%s'", argv[1]); |
break; |
} |
} |
return CMD_FAILURE; |
} |
/branches/dd/uspace/app/bdsh/cmds/builtins/cd/entry.h |
---|
0,0 → 1,12 |
#ifndef CD_ENTRY_H_ |
#define CD_ENTRY_H_ |
#include "scli.h" |
/* Entry points for the cd command */ |
extern void help_cmd_cd(unsigned int); |
extern int cmd_cd(char **, cliuser_t *); |
#endif |
/branches/dd/uspace/app/bdsh/cmds/builtins/cd/cd.h |
---|
0,0 → 1,7 |
#ifndef CD_H |
#define CD_H |
/* Prototypes for the cd command (excluding entry points) */ |
#endif |
/branches/dd/uspace/app/bdsh/cmds/builtins/builtin_aliases.h |
---|
0,0 → 1,10 |
#ifndef BUILTIN_ALIASES_H |
#define BUILTIN_ALIASES_H |
/* See modules/module_aliases.h for an explanation of this file */ |
char *builtin_aliases[] = { |
NULL, NULL |
}; |
#endif |
/branches/dd/uspace/app/bdsh/cmds/builtins/README |
---|
0,0 → 1,21 |
Commands that need to modify the running user structure defined in scli.h |
should reside here. They (will) have a slightly different prototype that |
allows passing the user structure to them for ease of modifications. |
Examples of what should be a built-in and not a module would be: |
cd (cliuser_t->cwd needs to be updated) |
In the future, more user preferences will be set via built-in commands, |
such as the formatting of the prompt string (HelenOS doesn't yet have |
an environment, much less PS*, even if it did we'd likely do it a little |
differently). |
.... etc. |
Anything that does _not_ need to use this structure should be included |
as a module, not a built in. If you want to include a new command, there |
is a 99% chance that you want it to be a module. |
/branches/dd/uspace/app/bdsh/cmds/mknewcmd |
---|
0,0 → 1,314 |
#!/bin/sh |
# Copyright (C) 2008 Tim Post - 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. |
# Script to generate skeletal files for a new command |
# Uses `getopt', not quite a bash-ism but might be |
# lacking on some legacy systems. |
# If your shell does not support eval, shift (x) or |
# here-now documents, sorry :) |
usage() |
{ |
def="$DEFAULT_COMMAND" |
cat << EOF |
\`$PROGNAME' generates skeletal command files to simplify adding commands |
Usage: $PROGNAME [options] <location> |
Options: |
-n, --name Name of the command (default: ${def}) |
-d, --desc Short (20 30 chars) description of the command |
(def: "The $def command") |
-e, --entry Entry function of the command (def: cmd_${def}) |
-h, --help-entry Entry function for command help (def: help_cmd_${def}) |
-a, --alias Alias (nickname) for this command (def: none) |
-t, --type Type of command (module or builtin) (def: module) |
-H, --help This help summary |
-V, --version Print $PROGNAME version and exit normally |
Notes: |
You must supply at least the name of the command. |
If you do not specify a location (i.e. modules/foo), the command will be |
created in modules/command_name or builtins/command_name depending on your |
selection. |
This script will only create skeletal files and inform you what headers |
need to be modified to incorporate the command. You will also have to |
manually update the main Makefile. |
This script is intended only to be a convenience for developers. Example use: |
$PROGNAME -n foo -d "Foo power" -a bar -r both -t module modules/foo |
The example would generate a modular command named 'foo', which is also |
reached by typing 'bar'. |
Skeletal files do *not* depend on the autoconf generated "config.h" unless you |
include it. This may or may not be desirable depending on your use. |
Report bugs to $PROGMAINT |
EOF |
} |
# Convert a string to all uppercase |
toupper() |
{ |
local str="$1" |
echo "${str}" | tr 'a-z' 'A-Z' |
} |
# Template stored `here-now' style, this generates all files needed |
# for a new command according to arguments passed. |
generate_code() |
{ |
echo "Creating ${OUTDIR}/${CMDNAME}_def.h ..." |
cat << EOF > ${OUTDIR}/${CMDNAME}_def.h |
{ |
"${CMDNAME}", |
"${CMDDESC}", |
&${CMDENTRY}, |
&${HELPENTRY}, |
}, |
EOF |
[ -n "${CMDALIAS}" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}_def.h |
{ |
"${CMDALIAS}", |
NULL, |
&${CMDENTRY}, |
&${HELPENTRY}, |
}, |
EOF |
local defname=$(toupper "${CMDNAME}") |
echo "Creating ${OUTDIR}/entry.h ..." |
cat << EOF > ${OUTDIR}/entry.h |
#ifndef ${defname}_ENTRY_H |
#define ${defname}_ENTRY_H |
EOF |
[ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/entry.h |
/* Entry points for the ${CMDNAME} command */ |
extern int ${CMDENTRY}(char **); |
extern void ${HELPENTRY}(unsigned int); |
#endif /* ${defname}_ENTRY_H */ |
EOF |
[ "${CMDTYPE}" = "builtin" ] && cat << EOF >> ${OUTDIR}/entry.h |
/* Pick up cliuser_t */ |
#include "scli.h" |
/* Entry points for the ${CMDNAME} command */ |
extern int * ${CMDENTRY}(char **, cliuser_t *); |
extern void * ${HELPENTRY}(unsigned int); |
#endif /* ${defname}_ENTRY_H */ |
EOF |
echo "Creating ${OUTDIR}/${CMDNAME}.h ..." |
cat << EOF > ${OUTDIR}/${CMDNAME}.h |
#ifndef ${defname}_H |
#define ${defname}_H |
/* Prototypes for the ${CMDNAME} command, excluding entry points */ |
#endif /* ${defname}_H */ |
EOF |
echo "Creating ${OUTDIR}/${CMDNAME}.c ..." |
cat << EOF > ${OUTDIR}/${CMDNAME}.c |
/* Automatically generated by ${PROGNAME} on ${TIMESTAMP} |
* This is machine generated output. The author of ${PROGNAME} claims no |
* copyright over the contents of this file. Where legally permitted, the |
* contents herein are donated to the public domain. |
* |
* You should apply any license and copyright that you wish to this file, |
* replacing this header in its entirety. */ |
#include <stdio.h> |
#include <stdlib.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "${CMDNAME}.h" |
#include "cmds.h" |
static const char *cmdname = "${CMDNAME}"; |
/* Dispays help for ${CMDNAME} in various levels */ |
void ${HELPENTRY}(unsigned int level) |
{ |
printf("This is the %s help for '%s'.\n", |
level ? EXT_HELP : SHORT_HELP, cmdname); |
return; |
} |
EOF |
[ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c |
/* Main entry point for ${CMDNAME}, accepts an array of arguments */ |
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) |
EOF |
cat << EOF >> ${OUTDIR}/${CMDNAME}.c |
{ |
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; |
} |
EOF |
printf "Done.\n\nYou should now modify %ss/%ss.h and ../Makefile" \ |
"${CMDTYPE}" "${CMDTYPE}" |
printf " to include your new command.\n" |
[ -n "$CMDALIAS" ] && { |
printf "\nYou should also modify %ss/%s_aliases.h and " \ |
"${CMDTYPE}" "${CMDTYPE}" |
printf "add %s as an alias for %s\n" \ |
"${CMDALIAS}" "${CMDNAME}" |
} |
printf "\nOnce completed, re-run make\n\n" |
} |
# Main program |
TIMESTAMP="$(date)" |
PROGNAME=$(basename $0) |
PROGVER="0.0.1" |
PROGMAINT="Tim Post <echo@echoreply.us>" |
DEFAULT_COMMAND="cmdname" |
# We need at least one |
[ $# = 0 ] && usage && exit 1; |
TEMP=$(getopt -o n:d:e:h:a:t:HV \ |
--long name:,desc:,entry:,help-entry:,alias:,type:,help,version \ |
-- "$@") || { |
echo "Try $PROGNAME --help for help" |
} |
eval set -- "$TEMP" |
while true; do |
case "$1" in |
-n | --name) |
CMDNAME="$2" |
shift 2 |
continue |
;; |
-d | --desc) |
CMDDESC="$2" |
shift 2 |
continue |
;; |
-e | --entry) |
CMDENTRY="$2" |
shift 2 |
continue |
;; |
-h | --help-entry) |
HELPENTRY="$2" |
shift 2 |
continue |
;; |
-a | --alias) |
CMDALIAS="$2" |
shift 2 |
continue |
;; |
-t | --type) |
CMDTYPE="$2" |
shift 2 |
continue |
;; |
-H | --help) |
usage |
exit 0 |
;; |
-V | --version) |
echo "$PROGVER" |
exit 0 |
;; |
--) |
break |
;; |
esac |
done |
# Pick up a location if one was specified |
eval set -- "$*" |
[ -n "$2" ] && OUTDIR="$2" |
# Fill in defaults for whatever was not specified |
[ -n "$CMDNAME" ] || CMDNAME="$DEFAULT_COMMAND" |
[ -n "$CMDDESC" ] || CMDDESC="The $CMDNAME command" |
[ -n "$CMDENTRY" ] || CMDENTRY="cmd_${CMDNAME}" |
[ -n "$HELPENTRY" ] || HELPENTRY="help_cmd_${CMDNAME}" |
[ -n "$CMDTYPE" ] || CMDTYPE="module" |
[ -n "$OUTDIR" ] || OUTDIR="${CMDTYPE}s/${CMDNAME}" |
# Do a little sanity |
[ -d $OUTDIR ] && { |
echo "$OUTDIR already exists, remove it to proceed." |
exit 1 |
} |
mkdir -p ${OUTDIR} >/dev/null 2>&1 || { |
echo "Could not create ${OUTDIR}, aborting!" |
exit 1 |
} |
# Generate the files and inform on how to include them based on options |
generate_code |
exit 0 |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dd/uspace/app/bdsh/cmds/mod_cmds.c |
---|
0,0 → 1,136 |
/* 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. |
*/ |
/* NOTES: |
* module_* functions are pretty much identical to builtin_* functions at this |
* point. On the surface, it would appear that making each function dual purpose |
* would be economical. |
* |
* These are kept separate because the structures (module_t and builtin_t) may |
* grow apart and become rather different, even though they're identical at this |
* point. |
* |
* To keep things easy to hack, everything is separated. In reality this only adds |
* 6 - 8 extra functions, but keeps each function very easy to read and modify. */ |
/* TODO: |
* Many of these could be unsigned, provided the modules and builtins themselves |
* can follow suit. Long term goal. */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "errors.h" |
#include "cmds.h" |
#include "module_aliases.h" |
extern volatile unsigned int cli_interactive; |
/* Checks if an entry function matching command exists in modules[], if so |
* its position in the array is returned */ |
int is_module(const char *command) |
{ |
module_t *mod; |
unsigned int i = 0; |
if (NULL == command) |
return -2; |
for (mod = modules; mod->name != NULL; mod++, i++) { |
if (!strcmp(mod->name, command)) |
return i; |
} |
return -1; |
} |
/* Checks if a module is an alias (sharing an entry point with another |
* module). Returns 1 if so */ |
int is_module_alias(const char *command) |
{ |
unsigned int i = 0; |
if (NULL == command) |
return -1; |
for(i=0; mod_aliases[i] != NULL; i+=2) { |
if (!strcmp(mod_aliases[i], command)) |
return 1; |
} |
return 0; |
} |
/* Returns the name of the module that an alias points to */ |
char *alias_for_module(const char *command) |
{ |
unsigned int i = 0; |
if (NULL == command) |
return (char *)NULL; |
for(i=0; mod_aliases[i] != NULL; i++) { |
if (!strcmp(mod_aliases[i], command)) |
return (char *)mod_aliases[++i]; |
i++; |
} |
return (char *)NULL; |
} |
/* Invokes the 'help' entry function for the module at position (int) module, |
* which wants an unsigned int to determine brief or extended display. */ |
int help_module(int module, unsigned int extended) |
{ |
module_t *mod = modules; |
mod += module; |
if (NULL != mod->help) { |
mod->help(extended); |
return CL_EOK; |
} else |
return CL_ENOENT; |
} |
/* Invokes the module entry point modules[module], passing argv[] as an argument |
* stack. */ |
int run_module(int module, char *argv[]) |
{ |
module_t *mod = modules; |
mod += module; |
if (NULL != mod->entry) |
return ((int)mod->entry(argv)); |
return CL_ENOENT; |
} |
/branches/dd/uspace/app/bdsh/cmds/cmds.h |
---|
0,0 → 1,71 |
#ifndef CMDS_H |
#define CMDS_H |
#include "config.h" |
#include "scli.h" |
/* Temporary to store strings */ |
#define EXT_HELP "extended" |
#define SHORT_HELP "short" |
#define TEST_ANNOUNCE "Hello, this is :" |
/* Simple levels of help displays */ |
#define HELP_SHORT 0 |
#define HELP_LONG 1 |
/* Acceptable buffer sizes (for strn functions) */ |
/* TODO: Move me, other files duplicate these needlessly */ |
#define BUFF_LARGE 1024 |
#define BUFF_SMALL 255 |
/* Return macros for int type entry points */ |
#define CMD_FAILURE 1 |
#define CMD_SUCCESS 0 |
/* Types for module command entry and help */ |
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); |
/* Module structure */ |
typedef struct { |
char *name; /* Name of the command */ |
char *desc; /* Description of the command */ |
mod_entry_t entry; /* Command (exec) entry function */ |
mod_help_t help; /* Command (help) entry function */ |
} module_t; |
/* Builtin structure, same as modules except different types of entry points */ |
typedef struct { |
char *name; |
char *desc; |
builtin_entry_t entry; |
builtin_help_t help; |
int restricted; |
} builtin_t; |
/* Declared in cmds/modules/modules.h and cmds/builtins/builtins.h |
* respectively */ |
extern module_t modules[]; |
extern builtin_t builtins[]; |
/* Prototypes for module launchers */ |
extern int module_is_restricted(int); |
extern int is_module(const char *); |
extern int is_module_alias(const char *); |
extern char * alias_for_module(const char *); |
extern int help_module(int, unsigned int); |
extern int run_module(int, char *[]); |
/* Prototypes for builtin launchers */ |
extern int builtin_is_restricted(int); |
extern int is_builtin(const char *); |
extern int is_builtin_alias(const char *); |
extern char * alias_for_builtin(const char *); |
extern int help_builtin(int, unsigned int); |
extern int run_builtin(int, char *[], cliuser_t *); |
#endif |
/branches/dd/uspace/app/bdsh/cmds/builtin_cmds.c |
---|
0,0 → 1,113 |
/* 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. |
*/ |
/* Almost identical (for now) to mod_cmds.c , however this will not be the case |
* soon as builtin_t is going to grow way beyond module_t */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "errors.h" |
#include "cmds.h" |
#include "builtin_aliases.h" |
extern volatile unsigned int cli_interactive; |
int is_builtin(const char *command) |
{ |
builtin_t *cmd; |
unsigned int i = 0; |
if (NULL == command) |
return -2; |
for (cmd = builtins; cmd->name != NULL; cmd++, i++) { |
if (!strcmp(cmd->name, command)) |
return i; |
} |
return -1; |
} |
int is_builtin_alias(const char *command) |
{ |
unsigned int i = 0; |
if (NULL == command) |
return -1; |
for(i=0; builtin_aliases[i] != NULL; i+=2) { |
if (!strcmp(builtin_aliases[i], command)) |
return 1; |
} |
return 0; |
} |
char *alias_for_builtin(const char *command) |
{ |
unsigned int i = 0; |
if (NULL == command) |
return (char *)NULL; |
for(i=0; builtin_aliases[i] != NULL; i++) { |
if (!strcmp(builtin_aliases[i], command)) |
return (char *)builtin_aliases[++i]; |
i++; |
} |
return (char *)NULL; |
} |
int help_builtin(int builtin, unsigned int extended) |
{ |
builtin_t *cmd = builtins; |
cmd += builtin; |
if (NULL != cmd->help) { |
cmd->help(extended); |
return CL_EOK; |
} else |
return CL_ENOENT; |
} |
int run_builtin(int builtin, char *argv[], cliuser_t *usr) |
{ |
builtin_t *cmd = builtins; |
cmd += builtin; |
if (NULL != cmd->entry) |
return((int)cmd->entry(argv, usr)); |
return CL_ENOENT; |
} |
/branches/dd/uspace/app/bdsh/Makefile |
---|
0,0 → 1,130 |
# Copyright (c) 2005, Martin Decky |
# All rights reserved. |
# 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 ../../../version |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
LIBS = $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=$(RELEASE) |
PROGRAM = bdsh |
# Any directory that cleaning targets should know about |
SUBDIRS = \ |
./ \ |
cmds/ \ |
cmds/modules/ \ |
cmds/modules/help/ \ |
cmds/modules/mkdir/ \ |
cmds/modules/rm/ \ |
cmds/modules/cat/ \ |
cmds/modules/touch/ \ |
cmds/modules/ls/ \ |
cmds/modules/pwd/ \ |
cmds/modules/sleep/ \ |
cmds/modules/cp/ \ |
cmds/builtins/ \ |
cmds/builtins/exit/\ |
cmds/builtins/cd/ |
SOURCES = \ |
cmds/modules/help/help.c \ |
cmds/modules/mkdir/mkdir.c \ |
cmds/modules/rm/rm.c \ |
cmds/modules/cat/cat.c \ |
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/exit/exit.c \ |
cmds/builtins/cd/cd.c \ |
cmds/mod_cmds.c \ |
cmds/builtin_cmds.c \ |
errors.c \ |
input.c \ |
util.c \ |
exec.c \ |
scli.c |
CFLAGS += -I. -Icmds/ -Icmds/builtins -Icmds/modules |
OBJECTS = $(SOURCES:.c=.o) |
# For easy cleaning, *.o is already handled |
CLEANDIRS := $(addsuffix *~,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.bak,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.tmp,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.out,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.d,$(SUBDIRS)) |
CLEANDIRS += $(addsuffix *.gch,$(SUBDIRS) ) |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(CFLAGS) $(INC) -c $< -o $@ |
@$(CC) -M $(CFLAGS) $(INC) $*.c > $*.d |
$(PROGRAM): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(PROGRAM).map |
# Everything else is a phony target |
.PHONY: all clean distclean depend disasm |
all: $(PROGRAM) disasm |
clean: |
@-rm -f $(OBJECTS) |
@-rm -f $(PROGRAM) |
@-rm -f $(PROGRAM).map |
@-rm -f $(PROGRAM).disasm |
@-rm -f $(CLEANDIRS) |
depend: |
@echo '' |
disasm: |
$(OBJDUMP) -d $(PROGRAM) >$(PROGRAM).disasm |
distclean: clean |
# Do not delete - dependencies |
-include $(OBJECTS:.o=.d) |
/branches/dd/uspace/app/bdsh/AUTHORS |
---|
0,0 → 1,14 |
Written by Tim Post <echo@echoreply.us> to serve as a primitive shell |
for HelenOS, or as a template to make a command line interface that |
offers shell like creature comforts. |
This program was mostly written from scratch, some existing code was |
used from other various free software projects: |
* Based on the HelenOS testing sub-system written by Martin Decky |
* read_line() (input.c) was written by Jiri Svoboda |
Individual author copyrights are listed in the headers of each file. |
/branches/dd/uspace/app/bdsh/util.c |
---|
0,0 → 1,82 |
/* 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 <string.h> |
#include <stdarg.h> |
#include <stdlib.h> |
#include <stdarg.h> |
#include "config.h" |
#include "errors.h" |
#include "util.h" |
extern volatile int cli_errno; |
/* Count and return the # of elements in an array */ |
unsigned int cli_count_args(char **args) |
{ |
unsigned int i; |
for (i=0; args[i] != NULL; i++); |
return i; |
} |
/* (re)allocates memory to store the current working directory, gets |
* and updates the current working directory, formats the prompt |
* string */ |
unsigned int cli_set_prompt(cliuser_t *usr) |
{ |
usr->prompt = (char *) realloc(usr->prompt, PATH_MAX); |
if (NULL == usr->prompt) { |
cli_error(CL_ENOMEM, "Can not allocate prompt"); |
cli_errno = CL_ENOMEM; |
return 1; |
} |
memset(usr->prompt, 0, sizeof(usr->prompt)); |
usr->cwd = (char *) realloc(usr->cwd, PATH_MAX); |
if (NULL == usr->cwd) { |
cli_error(CL_ENOMEM, "Can not allocate cwd"); |
cli_errno = CL_ENOMEM; |
return 1; |
} |
memset(usr->cwd, 0, sizeof(usr->cwd)); |
usr->cwd = getcwd(usr->cwd, PATH_MAX - 1); |
if (NULL == usr->cwd) |
snprintf(usr->cwd, PATH_MAX, "(unknown)"); |
asprintf(&usr->prompt, "%s # ", usr->cwd); |
return 0; |
} |
/branches/dd/uspace/app/bdsh/util.h |
---|
0,0 → 1,10 |
#ifndef UTIL_H |
#define UTIL_H |
#include "scli.h" |
/* Utility functions */ |
extern unsigned int cli_count_args(char **); |
extern unsigned int cli_set_prompt(cliuser_t *usr); |
#endif |
/branches/dd/uspace/app/bdsh/exec.c |
---|
0,0 → 1,129 |
/* 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. |
*/ |
/* The VERY basics of execute in place support. These are buggy, leaky |
* and not nearly done. Only here for beta testing!! You were warned!! |
* TODO: |
* Hash command lookups to save time |
* Create a running pointer to **path and advance/rewind it as we go */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <string.h> |
#include <fcntl.h> |
#include "config.h" |
#include "util.h" |
#include "exec.h" |
#include "errors.h" |
/* FIXME: Just have find_command() return an allocated string */ |
static char *found; |
static char *find_command(char *); |
static int try_access(const char *); |
/* work-around for access() */ |
static int try_access(const char *f) |
{ |
int fd; |
fd = open(f, O_RDONLY); |
if (fd > -1) { |
close(fd); |
return 0; |
} else |
return -1; |
} |
/* Returns the full path of "cmd" if cmd is found, else just hand back |
* cmd as it was presented */ |
static char *find_command(char *cmd) |
{ |
char *path_tok; |
char *path[PATH_MAX]; |
int n = 0, i = 0; |
size_t x = strlen(cmd) + 2; |
found = (char *)malloc(PATH_MAX); |
/* The user has specified a full or relative path, just give it back. */ |
if (-1 != try_access(cmd)) { |
return (char *) cmd; |
} |
path_tok = strdup(PATH); |
/* Extract the PATH env to a path[] array */ |
path[n] = strtok(path_tok, PATH_DELIM); |
while (NULL != path[n]) { |
if ((strlen(path[n]) + x ) > PATH_MAX) { |
cli_error(CL_ENOTSUP, |
"Segment %d of path is too large, search ends at segment %d", |
n, n-1); |
break; |
} |
path[++n] = strtok(NULL, PATH_DELIM); |
} |
/* We now have n places to look for the command */ |
for (i=0; path[i]; i++) { |
memset(found, 0, sizeof(found)); |
snprintf(found, PATH_MAX, "%s/%s", path[i], cmd); |
if (-1 != try_access(found)) { |
free(path_tok); |
return (char *) found; |
} |
} |
/* We didn't find it, just give it back as-is. */ |
free(path_tok); |
return (char *) cmd; |
} |
unsigned int try_exec(char *cmd, char **argv) |
{ |
task_id_t tid; |
char *tmp; |
tmp = strdup(find_command(cmd)); |
free(found); |
tid = task_spawn((const char *)tmp, argv); |
free(tmp); |
if (tid == 0) { |
cli_error(CL_EEXEC, "Can not spawn %s", cmd); |
return 1; |
} else { |
return 0; |
} |
} |
/branches/dd/uspace/app/bdsh/scli.c |
---|
0,0 → 1,105 |
/* 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 <string.h> |
#include <unistd.h> |
#include "config.h" |
#include "scli.h" |
#include "input.h" |
#include "util.h" |
#include "errors.h" |
#include "cmds/cmds.h" |
/* See scli.h */ |
static cliuser_t usr; |
/* Globals that are modified during start-up that modules/builtins |
* should be aware of. */ |
volatile unsigned int cli_quit = 0; |
volatile unsigned int cli_verbocity = 1; |
/* The official name of this program |
* (change to your liking in configure.ac and re-run autoconf) */ |
const char *progname = PACKAGE_NAME; |
/* These are not exposed, even to builtins */ |
static int cli_init(cliuser_t *); |
static void cli_finit(cliuser_t *); |
/* Constructor */ |
static int cli_init(cliuser_t *usr) |
{ |
usr->line = (char *) NULL; |
usr->name = "root"; |
usr->home = "/"; |
usr->cwd = (char *) NULL; |
usr->prompt = (char *) NULL; |
chdir(usr->home); |
usr->lasterr = 0; |
return (int) cli_set_prompt(usr); |
} |
/* Destructor */ |
static void cli_finit(cliuser_t *usr) |
{ |
if (NULL != usr->line) |
free(usr->line); |
if (NULL != usr->prompt) |
free(usr->prompt); |
if (NULL != usr->cwd) |
free(usr->cwd); |
} |
int main(int argc, char *argv[]) |
{ |
int ret = 0; |
if (cli_init(&usr)) |
exit(EXIT_FAILURE); |
printf("Welcome to %s - %s\nType `help' at any time for usage information.\n", |
progname, PACKAGE_STRING); |
while (!cli_quit) { |
get_input(&usr); |
if (NULL != usr.line) { |
ret = tok_input(&usr); |
cli_set_prompt(&usr); |
usr.lasterr = ret; |
} |
} |
goto finit; |
finit: |
cli_finit(&usr); |
return ret; |
} |
/branches/dd/uspace/app/bdsh/config.h |
---|
0,0 → 1,36 |
/* 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 1 |
#endif |
/* Work around for getenv() */ |
#define PATH "/srv:/app" |
#define PATH_DELIM ":" |
/* Used in many places */ |
#define SMALL_BUFLEN 256 |
#define LARGE_BUFLEN 1024 |
/* How many words (arguments) are permitted, how big can a whole |
* sentence be? Similar to ARG_MAX */ |
#define WORD_MAX 255 |
#define INPUT_MAX 1024 |
/* Leftovers from Autoconf */ |
#define PACKAGE_MAINTAINER "Tim Post" |
#define PACKAGE_BUGREPORT "echo@echoreply.us" |
#define PACKAGE_NAME "bdsh" |
#define PACKAGE_STRING "The brain dead shell" |
#define PACKAGE_TARNAME "bdsh" |
#define PACKAGE_VERSION "0.0.1" |
/branches/dd/uspace/app/bdsh/README |
---|
0,0 → 1,252 |
BDSH - The Brain Dead Shell | Design Documentation |
-------------------------------------------------- |
Overview: |
========= |
BDSH was written as a drop in command line interface for HelenOS to permit |
interactive access to persistent file systems in development. BDSH was |
written from scratch with a very limited userspace standard C library in |
mind. Much like the popular Busybox program, BDSH provides a very limited |
shell with limited common UNIX creature comforts built in. |
Porting Busybox (and by extension ASH) would have taken much longer to |
complete, much less make stable due to stark differences between Linux and |
Spartan with regards to IPC, term I/O and process creation. BDSH was written |
and made stable within the space of less than 30 days. |
BDSH will eventually evolve and be refined into the HelenOS equivalent |
of Busybox. While BDSH is now very intrinsic to HelenOS, its structure and |
use of strictly lower level functions makes it extremely easy to port. |
Design: |
======= |
BDSH is made up of three basic components: |
1. Main i/o, error handling and task management |
2. The builtin sub system |
3. The module sub system |
The main part handles user input, reports errors, spawns external tasks and |
provides a convenient entry point for built-in and modular commands. A simple |
structure, cliuser_t keeps track of the user's vitals, such as their current |
working directory (and eventually uid, home directory, etc if they apply). |
This part defines and exposes all functions that are not intrinsic to a |
certain built in or modular command. For instance: string handlers, |
module/builtin search and launch functions, error handlers and other things |
can be found here. |
Builtin commands are commands that must have access to cliuser_t, which is |
not exposed to modular commands. For instance, the 'cd' command must update |
the current working directory, which is stored in cliuser_t. As such, the |
entry types for builtin commands are slightly different. |
Modular commands do not need anything more than the basic functions that are |
exposed by default. They do not need to modify cliuser_t, they are just self |
contained. A modular command could very easily be made into a stand alone |
program, likewise any stand alone program could easily become a modular |
command. |
Both modular and builtin commands share two things in common. Both must have |
two entry points, one to invoke the command and one to invoke a help display |
for the command. Exec (main()) entry points are int * and are expected to |
return a value. Help entry points are void *, no return value is expected. |
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); |
/* 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); |
As you can see, both modular and builtin commands expect an array of |
arguments, however bulitins also expect to be pointed to cliuser_t. |
Both are defined with the same simple structure: |
/* Module structure */ |
typedef struct { |
char *name; /* Name of the command */ |
char *desc; /* Description of the command */ |
mod_entry_t entry; /* Command (exec) entry function */ |
mod_help_t help; /* Command (help) entry function */ |
int restricted; /* Restricts to interactive/non-interactive only */ |
} module_t; |
NOTE: Builtin commands may grow in this respect, that is why they are |
defined separately. |
Builtins, of course, would use the builtin_entry_t type. The name of the |
command is used to associate user input to a possible entry point. The |
description is a short (40 - 60 chars) summary of what the command does. Both |
entry points are then defined, and the restrict value is used to determine a |
commands availability. |
Restriction levels are easy, a command is either available exclusively within |
interactive mode, exclusively within non-interactive mode or both. If you are |
looking at a prompt, you are in interactive mode. If you issue a command like |
this: |
/sbin/bdsh command [arg1] [arg2] |
... you are in non interactive mode. This is done when you need to force the |
parent shell to be the one who actually handles the command, or ensure that |
/sbin/ls was used in lieu of the built in 'ls' when in non-interactive mode. |
The values are: |
0 : Unrestricted |
-1 : Interactive only |
1 : Non-interactive only |
A script to generate skeletal files for a new command is included, it can be |
found in cmds/mknewcmd. To generate a new modular command named 'foo', which |
should also be reachable by typing 'f00', you would issue this command: |
./mknewcmd -n foo -a f00 -t module |
This generates all needed files and instructs you on how to include your new |
command in the build and make it accessible. By default, the command will be |
unrestricted. Builtin commands can be created by changing 'module' to |
'builtin' |
There are more options to mknewcmd, which allow you to specify the |
description, entry point, help entry point, or restriction. By default, names |
just follow the command such as cmd_foo(), help_cmd_foo(), 'The foo command', |
etc. If you want to see the options and explanations in detail, use |
./mknewcmd --help. |
When working with commands, keep in mind that only the main and help entry |
points need to be exposed. If commands share the same functions, put them |
where they are exposed to all commands, without the potential oops of those |
functions going away if the command is eliminated in favor of a stand alone |
external program. |
The util.c file is a great place to put those types of functions. |
Also, be careful with globals, option structures, etc. The compiler will |
generally tell you if you've made a mistake, however declaring: |
volatile int foo |
... in a command will allow for anything else to pick it up. Sometimes |
this could be desirable .. other times not. When communicating between |
builtins and the main system, try to use cliuser_t. The one exception |
for this is the cli_quit global, since everything may at some point |
need to check it. Modules should only communicate their return value. |
Symbolic constants that everything needs should go in the config.h file, |
however this is not the place to define shared macros. |
Making a program into a module |
============================== |
If you have some neat program that would be useful as a modular command, |
converting it is not very hard. The following steps should get you through |
the process easily (assuming your program is named 'foo'): |
1: Use mknewcmd to generate the skeletal files. |
2: Change your "usage()" command as shown: |
-- void usage(...) |
++ 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 |
called, you'll need to change it. |
3: Change the programs "main()" as shown: |
-- int main(int argc, char **argv) |
++ int cmd_foo(char **argv) |
-- return 1; |
++ return CMD_FAILURE; |
-- return 0; |
++ return CMD_SUCCESS; |
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) |
4: Don't expose more than the entry and help points: |
-- void my_function(int n) |
++ static void my_function(int n) |
5: Copy/paste to the stub generated by mknewcmd then add your files to the |
Makefile. Be sure to add any directories that you made to the SUBDIRS so |
that a 'make clean' will clean them. |
Provided that all functions that your calling are available in the |
userspace C library, your program should compile just fine and appear |
as a modular command. |
Overcoming userspace libc obstacles |
=================================== |
A quick glance through the util.c file will reveal functions like |
cli_strdup(), cli_strtok(), cli_strtok_r() and more. Those are functions |
that were missing from userspace libc when BDSH was born. Later, after |
porting what was needed from FBSD/NBSD, the real functions appeared in |
the userspace libc after being tested in their cli_* implementations. |
Those functions remain because they guarantee that bdsh will work even |
on systems that lack them. Additionally, more BDSH specific stuff can |
go into them, such as error handling and reporting when malloc() fails. |
You will also notice that FILE, fopen() (and all friends), ato*() and |
other common things might be missing. The HelenOS userspace C library is |
still very young, you are sure to run into something that you want/need |
which is missing. |
When that happens, you have three options: |
1 - Implement it internally in util.c , when its tested and stable send a |
patch to HelenOS asking for your function to be included in libc. This is |
the best option, as you not only improve BDSH .. but HelenOS as a whole. |
2 - Work around it. Not everyone can implement / port fopen() and all of |
its friends. Make open(), read(), write() (etc) work if at all possible. |
3 - Send an e-mail to the HelenOS development mailing list. Explain why you |
need the function and what its absence is holding up. |
If what you need is part of a library that is typically a shared object, try |
to implement a 'mini' version of it. Currently, all userspace applications |
are statically linked. Giving up creature comforts for size while avoiding |
temporary 'band aids' is never frowned upon. |
Most of all, don't get discouraged .. ask for some help prior to giving up |
if you just can't accomplish something with the limited means provided. |
Contributing |
============ |
I will take any well written patch that sanely improves or expands BDSH. Send |
me a patch against the trunk revision, or, if you like a Mercurial repository |
is also maintained at http://echoreply.us/hg/bdsh.hg and kept in sync with |
the trunk. |
Please be sure to follow the simple coding standards outlined at |
http://www.helenos.eu/cstyle (mostly just regarding formatting), test your |
changes and make sure your patch applies cleanly against the latest revision. |
All patches submitted must be your original code, or a derivative work of |
something licensed under the same 3 clause BSD license as BDSH. See LICENSE |
for more information. |
When sending patches, you agree that your work will be published under the |
same 3 clause BSD license as BDSH itself. Failure to ensure that anything |
you used is not under the same or less restrictive license could cause major |
issues for BDSH in the future .. please be sure. Also, please don't forget |
to add yourself in the AUTHORS file, as I am horrible about keeping such |
things up to date. |
/branches/dd/uspace/app/bdsh/scli.h |
---|
0,0 → 1,16 |
#ifndef SCLI_H |
#define SCLI_H |
#include "config.h" |
#include <stdint.h> |
typedef struct { |
char *name; |
char *home; |
char *line; |
char *cwd; |
char *prompt; |
int lasterr; |
} cliuser_t; |
#endif |
/branches/dd/uspace/app/bdsh/input.h |
---|
0,0 → 1,11 |
#ifndef INPUT_H |
#define INPUT_H |
#include "cmds/cmds.h" |
/* prototypes */ |
extern void get_input(cliuser_t *); |
extern int tok_input(cliuser_t *); |
#endif |
/branches/dd/uspace/app/bdsh/exec.h |
---|
0,0 → 1,7 |
#ifndef EXEC_H |
#define EXEC_H |
#include <task.h> |
extern unsigned int try_exec(char *, char **); |
#endif |
/branches/dd/uspace/app/bdsh/errors.c |
---|
0,0 → 1,87 |
/* 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 <string.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <stdarg.h> |
#include "config.h" |
#include "errors.h" |
#include "errstr.h" |
volatile int cli_errno = CL_EOK; |
extern volatile unsigned int cli_quit; |
/* Error printing, translation and handling functions */ |
/* Look up errno in cl_errors and return the corresponding string. |
* Return NULL if not found */ |
static char *err2str(int err) |
{ |
if (NULL != cl_errors[err]) |
return cl_errors[err]; |
return (char *)NULL; |
} |
/* Print an error report signifying errno, which is translated to |
* its corresponding human readable string. If errno > 0, raise the |
* cli_quit int that tells the main program loop to exit immediately */ |
void cli_error(int err, const char *fmt, ...) |
{ |
va_list vargs; |
va_start(vargs, fmt); |
vprintf(fmt, vargs); |
va_end(vargs); |
if (NULL != err2str(err)) |
printf(" (%s)\n", err2str(err)); |
else |
printf(" (Unknown Error %d)\n", err); |
/* If fatal, raise cli_quit so that we try to exit |
* gracefully. This will break the main loop and |
* invoke the destructor */ |
if (err == CL_EFATAL) |
cli_quit = 1; |
return; |
} |
/branches/dd/uspace/app/bdsh/errors.h |
---|
0,0 → 1,22 |
#ifndef ERRORS_H |
#define ERRORS_H |
/* Various error levels */ |
#define CL_EFATAL -1 |
#define CL_EOK 0 |
#define CL_EFAIL 1 |
#define CL_EBUSY 2 |
#define CL_ENOENT 3 |
#define CL_ENOMEM 4 |
#define CL_EPERM 5 |
#define CL_ENOTSUP 6 |
#define CL_EEXEC 7 |
#define CL_EEXISTS 8 |
#define CL_ETOOBIG 9 |
/* Just like 'errno' */ |
extern volatile int cli_errno; |
extern void cli_error(int, const char *, ...); |
#endif |
/branches/dd/uspace/app/bdsh/errstr.h |
---|
0,0 → 1,23 |
#ifndef ERRSTR_H |
#define ERRSTR_H |
/* Simple array to translate error codes to meaningful strings */ |
static char *cl_errors[] = { |
"Success", |
"Failure", |
"Busy", |
"No Such Entry", |
"Not Enough Memory", |
"Permission Denied", |
"Method Not Supported", |
"Bad command or file name", |
"Entry already exists", |
"Object too large", |
NULL |
}; |
static char *err2str(int); |
#endif |
/branches/dd/uspace/app/bdsh/TODO |
---|
0,0 → 1,57 |
This is a very brain dead shell. It needs some love, coffee or perhaps beer. |
Currently, you can't even really call it a shell, its more of a CLI that |
offers some shell like creature comforts. |
This was written in a hurry to provide some means of testing persistent file |
systems in HelenOS. It does its job, its nowhere near complete but it is |
actively developed. If your reading this, its likely that you're looking for |
some functionality that is not yet present. Prior to filing a bug report, |
please make sure that what you want is not on the list below. |
A list of things to do: |
----------------------- |
* rm: add support for recursively removing directories and files therein |
* Port an editor (vim?) |
* Finish cat / cp |
* Support basic redirection (i.e ls > foo.txt) |
* Expand wildcards (i.e. *.txt), don't worry about variables for now |
* Basic scripting |
* Hash previously found commands |
* Improve input, add history / etc (port libedit?) |
* Add wrappers for signal, sigaction to make ports to modules easier |
* Add 'echo' and 'printf' modules. |
Regarding POSIX: |
---------------- |
POSIX is a standard for Unix-like operating systems. HelenOS is (mostly) just |
a kernel at this point with a few userspace programs that facilitate testing |
of the kernel and file systems. |
HelenOS is not a Unix-like operating system. HelenOS is its own thing, a modern |
microkernel OS and many directions are not yet set. |
Please do not e-mail me to point out that modular implementations that resemble |
typical core utilities do not conform to some POSIX standard, these are temporary |
and serve the useful purpose of testing persistent file systems. |
Contributing: |
------------- |
If you feel like doing any of the above to-do items, I am echo@echoreply.us. Please |
e-mail me and let me know your working on something so that I do not unwittingly |
duplicate your efforts. You can also e-mail the HelenOS list directly: |
HelenOS development mailing list <helenos-devel@lists.modry.cz> |
Subscribe here if you like: http://lists.modry.cz/cgi-bin/listinfo/helenos-devel |
Cheers and happy hacking! |
--Tim |
/branches/dd/uspace/app/bdsh/LICENSE |
---|
0,0 → 1,28 |
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. |
/branches/dd/uspace/app/init/init.c |
---|
27,37 → 27,93 |
*/ |
/** @addtogroup init Init |
* @brief Init process for testing purposes. |
* @brief Init process for user space environment configuration. |
* @{ |
*/ |
*/ |
/** |
* @file |
*/ |
#include <stdio.h> |
#include <unistd.h> |
#include <ipc/ipc.h> |
#include <vfs/vfs.h> |
#include <bool.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <task.h> |
#include <malloc.h> |
#include <macros.h> |
#include "init.h" |
#include "version.h" |
#include <stdio.h> |
static void test_console(void) |
static bool mount_fs(const char *fstype) |
{ |
int c; |
int rc = -1; |
while (rc < 0) { |
rc = mount(fstype, "/", "initrd", IPC_FLAG_BLOCKING); |
switch (rc) { |
case EOK: |
printf(NAME ": Root filesystem mounted\n"); |
break; |
case EBUSY: |
printf(NAME ": Root filesystem already mounted\n"); |
break; |
case ELIMIT: |
printf(NAME ": Unable to mount root filesystem\n"); |
return false; |
case ENOENT: |
printf(NAME ": Unknown filesystem type (%s)\n", fstype); |
return false; |
} |
} |
return true; |
} |
while ((c = getchar()) != EOF) |
putchar(c); |
static void spawn(char *fname) |
{ |
char *argv[2]; |
printf(NAME ": Spawning %s\n", fname); |
argv[0] = fname; |
argv[1] = NULL; |
if (task_spawn(fname, argv)) |
/* Add reasonable delay to avoid |
intermixed klog output */ |
usleep(10000); |
else |
printf(NAME ": Error spawning %s\n", fname); |
} |
int main(int argc, char *argv[]) |
{ |
info_print(); |
if (!mount_fs(STRING(RDFMT))) { |
printf(NAME ": Exiting\n"); |
return -1; |
} |
// FIXME: spawn("/srv/pci"); |
spawn("/srv/fb"); |
spawn("/srv/kbd"); |
spawn("/srv/console"); |
spawn("/srv/fhc"); |
spawn("/srv/obio"); |
console_wait(); |
version_print(); |
printf("This is init\n"); |
test_console(); |
printf("\nBye.\n"); |
spawn("/app/klog"); |
spawn("/app/bdsh"); |
return 0; |
} |
/** @} |
*/ |
/branches/dd/uspace/app/init/version.c |
---|
35,22 → 35,29 |
#include <unistd.h> |
#include <stdio.h> |
#include <macros.h> |
#include "init.h" |
#include "version.h" |
char *release = RELEASE; |
char *release = STRING(RELEASE); |
#ifdef REVISION |
char *revision = ", revision " REVISION; |
char *revision = ", revision " STRING(REVISION); |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = "\nBuilt on " TIMESTAMP; |
char *timestamp = "\nBuilt on " STRING(TIMESTAMP); |
#else |
char *timestamp = ""; |
#endif |
void info_print(void) |
{ |
printf(NAME ": HelenOS init\n"); |
} |
/** Print version information. */ |
void version_print(void) |
{ |
/branches/dd/uspace/app/init/init.h |
---|
36,7 → 36,7 |
#ifndef __INIT_H__ |
#define __INIT_H__ |
#include "version.h" |
#define NAME "init" |
#endif |
/branches/dd/uspace/app/init/version.h |
---|
36,6 → 36,7 |
#ifndef __VERSION_H__ |
#define __VERSION_H__ |
extern void info_print(void); |
extern void version_print(void); |
#endif |
/branches/dd/uspace/app/init/Makefile |
---|
27,7 → 27,6 |
# |
include ../../../version |
include ../../Makefile.config |
## Setup toolchain |
# |
34,21 → 33,14 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
LIBS = $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=\"$(RELEASE)\" |
DEFS += -DRELEASE=$(RELEASE) |
ifdef REVISION |
DEFS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
## Sources |
# |
61,22 → 53,24 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
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 |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/app/tester/console/console1.c |
---|
0,0 → 1,109 |
/* |
* 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. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <io/stream.h> |
#include <async.h> |
#include "../tester.h" |
#include <console.h> |
const char *color_name[] = { |
[COLOR_BLACK] = "black", |
[COLOR_BLUE] = "blue", |
[COLOR_GREEN] = "green", |
[COLOR_CYAN] = "cyan", |
[COLOR_RED] = "red", |
[COLOR_MAGENTA] = "magenta", |
[COLOR_YELLOW] = "yellow", |
[COLOR_WHITE] = "white" |
}; |
char * test_console1(bool quiet) |
{ |
int i, j; |
printf("Style test: "); |
console_set_style(STYLE_NORMAL); |
printf("normal "); |
console_set_style(STYLE_EMPHASIS); |
printf("emphasized"); |
console_set_style(STYLE_NORMAL); |
printf(".\n"); |
printf("Foreground color test:\n"); |
for (j = 0; j < 2; j++) { |
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) { |
console_set_color(i, COLOR_WHITE, |
j ? CATTR_BRIGHT : 0); |
printf(" %s ", color_name[i]); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
} |
printf("Background color test:\n"); |
for (j = 0; j < 2; j++) { |
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) { |
console_set_color(COLOR_WHITE, i, |
j ? CATTR_BRIGHT : 0); |
printf(" %s ", color_name[i]); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
} |
printf("Now let's test RGB colors:\n"); |
for (i = 0; i < 255; i += 16) { |
console_set_rgb_color(0xffffff, i << 16); |
putchar('X'); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
for (i = 0; i < 255; i += 16) { |
console_set_rgb_color(0xffffff, i << 8); |
putchar('X'); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
for (i = 0; i < 255; i += 16) { |
console_set_rgb_color(0xffffff, i); |
putchar('X'); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
printf("[press a key]\n"); |
getchar(); |
return NULL; |
} |
/branches/dd/uspace/app/tester/console/console1.def |
---|
0,0 → 1,6 |
{ |
"console1", |
"Console color test", |
&test_console1, |
true |
}, |
/branches/dd/uspace/app/tester/stdio/stdio1.def |
---|
0,0 → 1,6 |
{ |
"stdio1", |
"ANSI C streams reading test", |
&test_stdio1, |
true |
}, |
/branches/dd/uspace/app/tester/stdio/stdio2.def |
---|
0,0 → 1,6 |
{ |
"stdio2", |
"ANSI C streams writing test", |
&test_stdio2, |
true |
}, |
/branches/dd/uspace/app/tester/stdio/stdio2.c |
---|
0,0 → 1,69 |
/* |
* 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. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <errno.h> |
#include "../tester.h" |
char * test_stdio2(bool quiet) |
{ |
FILE *f; |
char *file_name = "/test"; |
size_t n; |
int c; |
printf("Open file '%s' for writing\n", file_name); |
errno = 0; |
f = fopen(file_name, "wt"); |
if (f == NULL) |
return "Failed opening file."; |
fprintf(f, "Integer: %d, string: '%s'\n", 42, "Hello!"); |
if (fclose(f) != 0) |
return "Failed closing file."; |
printf("Open file '%s' for reading\n", file_name); |
f = fopen(file_name, "rt"); |
if (f == NULL) |
return "Failed opening file."; |
printf("File contains:\n"); |
while (true) { |
c = fgetc(f); |
if (c == EOF) break; |
putchar(c); |
} |
if (fclose(f) != 0) |
return "Failed closing file."; |
return NULL; |
} |
/branches/dd/uspace/app/tester/stdio/stdio1.c |
---|
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. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <errno.h> |
#include "../tester.h" |
#define BUF_SIZE 32 |
static char buf[BUF_SIZE + 1]; |
char * test_stdio1(bool quiet) |
{ |
FILE *f; |
char *file_name = "/readme"; |
size_t n; |
int c; |
printf("Open file '%s'\n", file_name); |
errno = 0; |
f = fopen(file_name, "rt"); |
if (f == NULL) printf("errno = %d\n", errno); |
if (f == NULL) |
return "Failed opening file."; |
n = fread(buf, 1, BUF_SIZE, f); |
if (ferror(f)) { |
fclose(f); |
return "Failed reading file."; |
} |
printf("Read %d bytes.\n", n); |
buf[n] = '\0'; |
printf("Read string '%s'.\n", buf); |
printf("Seek to beginning.\n"); |
if (fseek(f, 0, SEEK_SET) != 0) { |
fclose(f); |
return "Failed seeking."; |
} |
printf("Read using fgetc().\n"); |
while (true) { |
c = fgetc(f); |
if (c == EOF) break; |
printf("'%c'", c); |
} |
printf("[EOF]\n"); |
printf("Closing.\n"); |
if (fclose(f) != 0) |
return "Failed closing."; |
return NULL; |
} |
/branches/dd/uspace/app/tester/tester.c |
---|
56,7 → 56,11 |
#include "ipc/answer.def" |
#include "ipc/hangup.def" |
#include "devmap/devmap1.def" |
#include "loop/loop1.def" |
#include "vfs/vfs1.def" |
#include "console/console1.def" |
#include "stdio/stdio1.def" |
#include "stdio/stdio2.def" |
{NULL, NULL, NULL} |
}; |
107,8 → 111,17 |
printf("*\t\t\tRun all safe tests\n"); |
} |
int main(void) |
int main(int argc, char **argv) |
{ |
printf("Number of arguments: %d\n", argc); |
if (argv) { |
printf("Arguments:"); |
while (*argv) { |
printf(" '%s'", *argv++); |
} |
printf("\n"); |
} |
while (1) { |
char c; |
test_t *test; |
124,15 → 137,22 |
if (c == 'a') |
break; |
if (c > 'a') |
if (test->name == NULL) |
printf("Unknown test\n\n"); |
else |
run_test(test); |
} else if (c == '*') |
} else if (c == '*') { |
run_safe_tests(); |
else |
} else if (c < 0) { |
/* got EOF */ |
break; |
} else { |
printf("Invalid test\n\n"); |
} |
} |
return 0; |
} |
/** @} |
/branches/dd/uspace/app/tester/loop/loop1.def |
---|
0,0 → 1,6 |
{ |
"loop1", |
"Endless loop", |
&test_loop1, |
false |
}, |
/branches/dd/uspace/app/tester/loop/loop1.c |
---|
0,0 → 1,41 |
/* |
* 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. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include "../tester.h" |
char *test_loop1(bool quiet) |
{ |
printf("Looping...\n"); |
while (1); |
printf("Survived endless loop?!!\n"); |
return NULL; |
} |
/branches/dd/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/dd/uspace/app/tester/devmap/devmap1.c |
---|
32,7 → 32,7 |
#include <ipc/services.h> |
#include <async.h> |
#include <errno.h> |
#include <../../../srv/devmap/devmap.h> |
#include <ipc/devmap.h> |
#include "../tester.h" |
#include <time.h> |
132,12 → 132,10 |
int phone; |
ipcarg_t callback_phonehash; |
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0); |
while (phone < 0) { |
usleep(100000); |
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
DEVMAP_DRIVER, 0); |
phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0); |
if (phone < 0) { |
printf("Failed to connect to device mapper\n"); |
return -1; |
} |
req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); |
/branches/dd/uspace/app/tester/tester.h |
---|
69,7 → 69,11 |
extern char * test_answer(bool quiet); |
extern char * test_hangup(bool quiet); |
extern char * test_devmap1(bool quiet); |
extern char * test_loop1(bool quiet); |
extern char * test_vfs1(bool quiet); |
extern char * test_console1(bool quiet); |
extern char * test_stdio1(bool quiet); |
extern char * test_stdio2(bool quiet); |
extern test_t tests[]; |
/branches/dd/uspace/app/tester/Makefile |
---|
31,6 → 31,7 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
52,7 → 53,11 |
ipc/send_sync.c \ |
ipc/answer.c \ |
ipc/hangup.c \ |
loop/loop1.c \ |
devmap/devmap1.c \ |
console/console1.c \ |
stdio/stdio1.c \ |
stdio/stdio2.c \ |
vfs/vfs1.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
59,22 → 64,24 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
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 |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/app/tester/vfs/vfs1.c |
---|
45,7 → 45,7 |
{ |
int rc; |
rc = mount("tmpfs", "/", "nulldev0"); |
rc = mount("tmpfs", "/", "nulldev0", 0); |
switch (rc) { |
case EOK: |
if (!quiet) |
/branches/dd/uspace/app/tetris/scores.c |
---|
52,7 → 52,7 |
/* #include <err.h> */ |
/* #include <fcntl.h> */ |
/* #include <pwd.h> */ |
#include <stdio.h> |
#include <stdio.h> |
/* #include <stdlib.h> */ |
#include <string.h> |
/* #include <time.h> */ |
/branches/dd/uspace/app/tetris/input.c |
---|
57,7 → 57,8 |
#include "tetris.h" |
#include <async.h> |
#include "../../srv/console/console.h" |
#include <ipc/console.h> |
#include <kbd/kbd.h> |
/* return true iff the given timeval is positive */ |
#define TV_POS(tv) \ |
96,6 → 97,7 |
struct timeval starttv, endtv, *s; |
static ipc_call_t charcall; |
ipcarg_t rc; |
int cons_phone; |
/* |
* Someday, select() will do this for us. |
110,8 → 112,12 |
s = NULL; |
if (!lastchar) { |
if (!getchar_inprog) |
getchar_inprog = async_send_2(1,CONSOLE_GETCHAR,0,0,&charcall); |
again: |
if (!getchar_inprog) { |
cons_phone = get_console_phone(); |
getchar_inprog = async_send_2(cons_phone, |
CONSOLE_GETKEY, 0, 0, &charcall); |
} |
if (!s) |
async_wait_for(getchar_inprog, &rc); |
else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) { |
123,7 → 129,10 |
if (rc) { |
stop("end of file, help"); |
} |
lastchar = IPC_GET_ARG1(charcall); |
if (IPC_GET_ARG1(charcall) == KE_RELEASE) |
goto again; |
lastchar = IPC_GET_ARG4(charcall); |
} |
if (tvp) { |
/* since there is input, we may not have timed out */ |
/branches/dd/uspace/app/tetris/screen.c |
---|
50,13 → 50,12 |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <io/stream.h> |
#include <console.h> |
#include <async.h> |
#include "screen.h" |
#include "tetris.h" |
#include "../../srv/console/console.h" |
#include <ipc/console.h> |
static cell curscreen[B_SIZE]; /* 1 => standout (or otherwise marked) */ |
static int curscore; |
73,29 → 72,19 |
putchar(*(s++)); |
} |
static int con_phone; |
static void set_style(int fgcolor, int bgcolor) |
{ |
async_msg_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor); |
} |
static void start_standout(void) |
{ |
set_style(0xf0f0f0, 0); |
console_set_rgb_color(0xf0f0f0, 0); |
} |
static void resume_normal(void) |
{ |
set_style(0, 0xf0f0f0); |
console_set_rgb_color(0, 0xf0f0f0); |
} |
void clear_screen(void) |
{ |
async_msg_0(con_phone, CONSOLE_CLEAR); |
console_clear(); |
moveto(0, 0); |
} |
107,7 → 96,7 |
{ |
resume_normal(); |
async_msg_0(con_phone, CONSOLE_CLEAR); |
console_clear(); |
curscore = -1; |
memset((char *)curscreen, 0, sizeof(curscreen)); |
} |
118,8 → 107,7 |
void |
scr_init(void) |
{ |
con_phone = get_cons_phone(); |
async_msg_1(con_phone, CONSOLE_CURSOR_VISIBILITY, 0); |
console_cursor_visibility(0); |
resume_normal(); |
scr_clear(); |
} |
126,12 → 114,12 |
void moveto(int r, int c) |
{ |
async_msg_2(con_phone, CONSOLE_GOTO, r, c); |
console_goto(r, c); |
} |
static void fflush(void) |
{ |
async_msg_0(con_phone, CONSOLE_FLUSH); |
console_flush(); |
} |
winsize_t winsize; |
138,8 → 126,7 |
static int get_display_size(winsize_t *ws) |
{ |
return async_req_0_2(con_phone, CONSOLE_GETSIZE, &ws->ws_row, |
&ws->ws_col); |
return console_get_size(&ws->ws_row, &ws->ws_col); |
} |
/* |
/branches/dd/uspace/app/tetris/screen.h |
---|
49,8 → 49,8 |
#include <async.h> |
typedef struct { |
ipcarg_t ws_row; |
ipcarg_t ws_col; |
int ws_row; |
int ws_col; |
} winsize_t; |
extern winsize_t winsize; |
/branches/dd/uspace/app/tetris/Makefile |
---|
1,5 → 1,6 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
10,7 → 11,7 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
18,13 → 19,16 |
$(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 |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend *.o |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/app/klog/Makefile |
---|
31,6 → 31,7 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
47,22 → 48,24 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
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 |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/app/klog/klog.c |
---|
27,9 → 27,9 |
*/ |
/** @addtogroup klog KLog |
* @brief HelenOS KLog |
* @brief HelenOS KLog |
* @{ |
*/ |
*/ |
/** |
* @file |
*/ |
40,46 → 40,56 |
#include <ipc/services.h> |
#include <as.h> |
#include <sysinfo.h> |
#include <io/stream.h> |
#include <errno.h> |
#define NAME "klog" |
#define KLOG_SIZE PAGE_SIZE |
/* Pointer to klog area */ |
static char *klog; |
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
int i; |
async_serialize_start(); |
async_serialize_start(); |
for (i=0; klog[i + IPC_GET_ARG1(*call)] && i < IPC_GET_ARG2(*call); i++) |
putchar(klog[i + IPC_GET_ARG1(*call)]); |
putchar('\n'); |
size_t klog_start = (size_t) IPC_GET_ARG1(*call); |
size_t klog_len = (size_t) IPC_GET_ARG2(*call); |
size_t klog_stored = (size_t) IPC_GET_ARG3(*call); |
size_t i; |
for (i = klog_len - klog_stored; i < klog_len; i++) |
putchar(klog[(klog_start + i) % KLOG_SIZE]); |
async_serialize_end(); |
} |
int main(int argc, char *argv[]) |
{ |
int res; |
void *mapping; |
printf("Kernel console output.\n"); |
console_wait(); |
mapping = as_get_mappable_page(PAGE_SIZE); |
res = ipc_share_in_start_1_0(PHONE_NS, mapping, PAGE_SIZE, |
klog = (char *) as_get_mappable_page(KLOG_SIZE); |
if (klog == NULL) { |
printf(NAME ": Error allocating memory area\n"); |
return -1; |
} |
int res = ipc_share_in_start_1_0(PHONE_NS, (void *) klog, KLOG_SIZE, |
SERVICE_MEM_KLOG); |
if (res) { |
printf("Failed to initialize klog memarea\n"); |
_exit(1); |
if (res != EOK) { |
printf(NAME ": Error initializing memory area\n"); |
return -1; |
} |
klog = mapping; |
int devno = sysinfo_value("klog.devno"); |
int inr = sysinfo_value("klog.inr"); |
int devno = sysinfo_value("klog.devno"); |
if (ipc_register_irq(inr, devno, 0, NULL)) { |
printf("Error registering for klog service.\n"); |
return 0; |
if (ipc_register_irq(inr, devno, 0, NULL) != EOK) { |
printf(NAME ": Error registering klog notifications\n"); |
return -1; |
} |
async_set_interrupt_received(interrupt_received); |
klog_update(); |
async_manager(); |
return 0; |
/branches/dd/uspace/app/trace/trace.c |
---|
0,0 → 1,831 |
/* |
* 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 <ipc/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) { |
if (paused) { |
printf("Press R to resume (and be patient).\n"); |
while (paused) { |
usleep(1000000); |
fibril_yield(); |
printf("."); |
} |
printf("Resumed\n"); |
} |
/* 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"); |
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_connect(); |
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') { |
printf("Pause...\n"); |
paused = 1; |
rc = udebug_stop(phoneid, thash); |
printf("stop -> %d\n", rc); |
} |
if (c == 'r') { |
paused = 0; |
printf("Resume...\n"); |
} |
} |
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);*/ |
o = oper_new("open", 2, arg_def, V_INT_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_OPEN, o); |
o = oper_new("close", 1, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_CLOSE, o); |
o = oper_new("seek", 3, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_SEEK, o); |
o = oper_new("mkdir", 1, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_MKDIR, o); |
o = oper_new("unlink", 0, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_UNLINK, o); |
o = oper_new("rename", 0, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_RENAME, o); |
proto_register(SERVICE_VFS, p); |
p = proto_new("console"); |
resp_def[0] = V_INTEGER; resp_def[1] = V_INTEGER; |
resp_def[2] = V_INTEGER; resp_def[3] = V_CHAR; |
o = oper_new("getkey", 0, arg_def, V_ERRNO, 4, resp_def); |
proto_add_oper(p, CONSOLE_GETKEY, 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; |
o = oper_new("set_style", 1, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_SET_STYLE, o); |
arg_def[0] = V_INTEGER; arg_def[1] = V_INTEGER; arg_def[2] = V_INTEGER; |
o = oper_new("set_color", 3, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_SET_COLOR, o); |
arg_def[0] = V_INTEGER; arg_def[1] = V_INTEGER; |
o = oper_new("set_rgb_color", 2, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_SET_RGB_COLOR, 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"); |
printf("Controls: Q - Quit, P - Pause, R - Resume\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/dd/uspace/app/trace/Makefile |
---|
0,0 → 1,79 |
# |
# 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/$(UARCH)/_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/dd/uspace/app/trace/syscalls.c |
---|
0,0 → 1,81 |
/* |
* 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_FORWARD_SLOW] = { "ipc_forward_slow", 3, 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/dd/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/dd/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/dd/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/dd/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/dd/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/dd/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/dd/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/dd/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/dd/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/dd/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." } |
}; |
/** @} |
*/ |