/tags/0.4.1/uspace/app/bdsh/cmds/modules/cp/cp.c |
---|
0,0 → 1,232 |
/* 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, verbose = 0; |
int buffer = 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; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/cp/cp_def.h |
---|
0,0 → 1,7 |
{ |
"cp", |
"Copy files and directories", |
&cmd_cp, |
&help_cmd_cp, |
}, |
/tags/0.4.1/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 */ |
/tags/0.4.1/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 */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/ls/ls.c |
---|
0,0 → 1,166 |
/* 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 void ls_scan_dir(const char *d, DIR *dirp) |
{ |
struct dirent *dp; |
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); |
ls_print(dp->d_name, buff); |
} |
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(const char *name, const char *pathname) |
{ |
struct stat s; |
int rc; |
rc = stat(pathname, &s); |
if (rc != 0) { |
/* Odd chance it was deleted from the time readdir() found it */ |
printf("ls: skipping bogus node %s\n", pathname); |
printf("rc=%d\n", rc); |
return; |
} |
if (s.is_file) |
printf("%-40s\t%llu\n", name, (long long) s.size); |
else |
printf("%-40s\n", name); |
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; |
struct stat s; |
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 |
str_cpy(buff, PATH_MAX, argv[1]); |
if (stat(buff, &s)) { |
cli_error(CL_ENOENT, buff); |
free(buff); |
return CMD_FAILURE; |
} |
if (s.is_file) { |
ls_print(buff, buff); |
} else { |
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); |
} |
free(buff); |
return CMD_SUCCESS; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/ls/ls.h |
---|
0,0 → 1,13 |
#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 void ls_scan_dir(const char *, DIR *); |
static void ls_print(const char *, const char *); |
#endif /* LS_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/ls/ls_def.h |
---|
0,0 → 1,6 |
{ |
"ls", |
"List files and directories", |
&cmd_ls, |
&help_cmd_ls, |
}, |
/tags/0.4.1/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 */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/rm/rm.c |
---|
0,0 → 1,259 |
/* 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 <mem.h> |
#include <string.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 ((unsigned) 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 = str_size(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; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/rm/rm_def.h |
---|
0,0 → 1,7 |
{ |
"rm", |
"Remove files and directories", |
&cmd_rm, |
&help_cmd_rm, |
}, |
/tags/0.4.1/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 */ |
/tags/0.4.1/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 */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/bdd/bdd.c |
---|
0,0 → 1,154 |
/* |
* Copyright (c) 2009 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 <string.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "bdd.h" |
#include "cmds.h" |
#include <libblock.h> |
#include <devmap.h> |
#include <errno.h> |
#define BLOCK_SIZE 512 |
#define BPR 16 |
static const char *cmdname = "bdd"; |
/* Dispays help for bdd in various levels */ |
void help_cmd_bdd(unsigned int level) |
{ |
static char helpfmt[] = |
"Usage: %s <device> [<block_number> [<bytes>]]\n"; |
if (level == HELP_SHORT) { |
printf("'%s' dump block device contents.\n", cmdname); |
} else { |
help_cmd_bdd(HELP_SHORT); |
printf(helpfmt, cmdname); |
} |
return; |
} |
/* Main entry point for bdd, accepts an array of arguments */ |
int cmd_bdd(char **argv) |
{ |
unsigned int argc; |
unsigned int i, j; |
dev_handle_t handle; |
block_t *block; |
uint8_t *blk; |
size_t size, bytes, rows; |
int rc; |
bn_t boff; |
uint8_t b; |
/* Count the arguments */ |
for (argc = 0; argv[argc] != NULL; argc ++); |
if (argc < 2 || argc > 4) { |
printf("%s - incorrect number of arguments.\n", cmdname); |
return CMD_FAILURE; |
} |
if (argc >= 3) |
boff = strtol(argv[2], NULL, 0); |
else |
boff = 0; |
if (argc >= 4) |
size = strtol(argv[3], NULL, 0); |
else |
size = 256; |
rc = devmap_device_get_handle(argv[1], &handle, 0); |
if (rc != EOK) { |
printf("Error: could not resolve device `%s'.\n", argv[1]); |
return CMD_FAILURE; |
} |
rc = block_init(handle, BLOCK_SIZE); |
if (rc != EOK) { |
printf("Error: could not init libblock.\n"); |
return CMD_FAILURE; |
} |
rc = block_cache_init(handle, BLOCK_SIZE, 2, CACHE_MODE_WB); |
if (rc != EOK) { |
printf("Error: could not init block cache.\n"); |
return CMD_FAILURE; |
} |
while (size > 0) { |
block = block_get(handle, boff, 0); |
blk = (uint8_t *) block->data; |
bytes = (size < BLOCK_SIZE) ? size : BLOCK_SIZE; |
rows = (bytes + BPR - 1) / BPR; |
for (j = 0; j < rows; j++) { |
for (i = 0; i < BPR; i++) { |
if (j * BPR + i < bytes) |
printf("%02x ", blk[j * BPR + i]); |
else |
printf(" "); |
} |
putchar('\t'); |
for (i = 0; i < BPR; i++) { |
if (j * BPR + i < bytes) { |
b = blk[j * BPR + i]; |
if (b >= 32 && b < 127) |
putchar(b); |
else |
putchar(' '); |
} else { |
putchar(' '); |
} |
} |
putchar('\n'); |
} |
block_put(block); |
if (size > rows * BPR) |
size -= rows * BPR; |
else |
size = 0; |
boff += rows * BPR; |
} |
block_fini(handle); |
return CMD_SUCCESS; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/bdd/bdd.h |
---|
0,0 → 1,8 |
#ifndef BDD_H |
#define BDD_H |
/* Prototypes for the bdd command, excluding entry points */ |
#endif /* BDD_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/bdd/entry.h |
---|
0,0 → 1,9 |
#ifndef BDD_ENTRY_H |
#define BDD_ENTRY_H |
/* Entry points for the bdd command */ |
extern int cmd_bdd(char **); |
extern void help_cmd_bdd(unsigned int); |
#endif /* BDD_ENTRY_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/bdd/bdd_def.h |
---|
0,0 → 1,7 |
{ |
"bdd", |
"Dump block device contents", |
&cmd_bdd, |
&help_cmd_bdd, |
}, |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/kcon/kcon.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 <io/console.h> |
#include <vfs/vfs.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "kcon.h" |
#include "cmds.h" |
static char *cmdname = "kcon"; |
/* Dispays help for kcon in various levels */ |
void help_cmd_kcon(unsigned int level) |
{ |
printf("`kcon' switches to the kernel debug console.\n"); |
if (level != HELP_SHORT) { |
printf("Usage: %s\n", cmdname); |
} |
return; |
} |
/* Main entry point for kcon, accepts an array of arguments */ |
int cmd_kcon(char **argv) |
{ |
unsigned int argc; |
argc = cli_count_args(argv); |
if (argc != 1) { |
printf("%s - incorrect number of arguments. Try `%s --help'\n", |
cmdname, cmdname); |
return CMD_FAILURE; |
} |
console_kcon_enable(fphone(stdout)); |
return CMD_SUCCESS; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/kcon/kcon.h |
---|
0,0 → 1,8 |
#ifndef KCON_H |
#define KCON_H |
/* Prototypes for the kcon command, excluding entry points */ |
#endif /* KCON_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/kcon/entry.h |
---|
0,0 → 1,9 |
#ifndef KCON_ENTRY_H |
#define KCON_ENTRY_H |
/* Entry points for the kcon command */ |
extern int cmd_kcon(char **); |
extern void help_cmd_kcon(unsigned int); |
#endif /* KCON_ENTRY_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/kcon/kcon_def.h |
---|
0,0 → 1,7 |
{ |
"kcon", |
"Switch to kernel console", |
&cmd_kcon, |
&help_cmd_kcon, |
}, |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/pwd/pwd.c |
---|
0,0 → 1,72 |
/* 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 <mem.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; |
} |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/pwd/pwd_def.h |
---|
0,0 → 1,6 |
{ |
"pwd", |
"Prints the current working directory", |
&cmd_pwd, |
&help_cmd_pwd, |
}, |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mkdir/mkdir.c |
---|
0,0 → 1,252 |
/* 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 <string.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 = str_dup(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 (!str_cmp(dirs[i], "..") || !str_cmp(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; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mkdir/mkdir_def.h |
---|
0,0 → 1,8 |
{ |
"mkdir", |
"Create new directories", |
&cmd_mkdir, |
&help_cmd_mkdir, |
}, |
/tags/0.4.1/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 */ |
/tags/0.4.1/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 */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/modules.h |
---|
0,0 → 1,56 |
#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 "bdd/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" |
#include "mv/entry.h" |
#include "mount/entry.h" |
#include "kcon/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 "bdd/bdd_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" |
#include "mv/mv_def.h" |
#include "mount/mount_def.h" |
#include "kcon/kcon_def.h" |
{NULL, NULL, NULL, NULL} |
}; |
#endif |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mount/mount.c |
---|
0,0 → 1,82 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <vfs/vfs.h> |
#include <errno.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "mount.h" |
#include "cmds.h" |
static const char *cmdname = "mount"; |
/* Dispays help for mount in various levels */ |
void help_cmd_mount(unsigned int level) |
{ |
static char helpfmt[] = |
"Usage: %s <fstype> <mp> <dev> [<moptions>]\n"; |
if (level == HELP_SHORT) { |
printf("'%s' mounts a file system.\n", cmdname); |
} else { |
help_cmd_mount(HELP_SHORT); |
printf(helpfmt, cmdname); |
} |
return; |
} |
/* Main entry point for mount, accepts an array of arguments */ |
int cmd_mount(char **argv) |
{ |
unsigned int argc; |
char *mopts = ""; |
int rc; |
argc = cli_count_args(argv); |
if ((argc < 4) || (argc > 5)) { |
printf("%s: invalid number of arguments.\n", |
cmdname); |
return CMD_FAILURE; |
} |
if (argc == 5) |
mopts = argv[4]; |
rc = mount(argv[1], argv[2], argv[3], mopts, 0); |
if (rc != EOK) { |
printf("Unable to mount %s filesystem to %s on %s (rc=%d)\n", |
argv[1], argv[2], argv[3], rc); |
return CMD_FAILURE; |
} |
return CMD_SUCCESS; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mount/mount_def.h |
---|
0,0 → 1,7 |
{ |
"mount", |
"The mount command", |
&cmd_mount, |
&help_cmd_mount, |
}, |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mount/entry.h |
---|
0,0 → 1,9 |
#ifndef MOUNT_ENTRY_H |
#define MOUNT_ENTRY_H |
/* Entry points for the mount command */ |
extern int cmd_mount(char **); |
extern void help_cmd_mount(unsigned int); |
#endif /* MOUNT_ENTRY_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mount/mount.h |
---|
0,0 → 1,8 |
#ifndef MOUNT_H |
#define MOUNT_H |
/* Prototypes for the mount command, excluding entry points */ |
#endif /* MOUNT_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mv/mv.c |
---|
0,0 → 1,70 |
/* |
* Copyright (c) 2009 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <errno.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
#include "entry.h" |
#include "mv.h" |
#include "cmds.h" |
static const char *cmdname = "mv"; |
/* Dispays help for mv in various levels */ |
void help_cmd_mv(unsigned int level) |
{ |
printf("'%s' renames files\n", cmdname); |
return; |
} |
/* Main entry point for mv, accepts an array of arguments */ |
int cmd_mv(char **argv) |
{ |
unsigned int argc; |
int rc; |
argc = cli_count_args(argv); |
if (argc != 3) { |
printf("%s: invalid number of arguments.\n", |
cmdname); |
return CMD_FAILURE; |
} |
rc = rename(argv[1], argv[2]); |
if (rc != EOK) { |
printf("Unable to rename %s to %s (rc=%d)\n", |
argv[1], argv[2], rc); |
return CMD_FAILURE; |
} |
return CMD_SUCCESS; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mv/mv_def.h |
---|
0,0 → 1,14 |
{ |
"mv", |
"The mv command", |
&cmd_mv, |
&help_cmd_mv, |
}, |
{ |
"ren", |
NULL, |
&cmd_mv, |
&help_cmd_mv, |
}, |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mv/entry.h |
---|
0,0 → 1,9 |
#ifndef MV_ENTRY_H |
#define MV_ENTRY_H |
/* Entry points for the mv command */ |
extern int cmd_mv(char **); |
extern void help_cmd_mv(unsigned int); |
#endif /* MV_ENTRY_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/mv/mv.h |
---|
0,0 → 1,8 |
#ifndef MV_H |
#define MV_H |
/* Prototypes for the mv command, excluding entry points */ |
#endif /* MV_H */ |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/module_aliases.h |
---|
0,0 → 1,19 |
#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[] = { |
"ren", "mv", |
NULL, NULL |
}; |
#endif |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/cat/cat.c |
---|
0,0 → 1,179 |
/* 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; |
fd = open(fname, O_RDONLY); |
if (fd < 0) { |
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; |
} |
/tags/0.4.1/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, |
}, |
/tags/0.4.1/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 */ |
/tags/0.4.1/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 */ |
/tags/0.4.1/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 = str_dup(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; |
} |
/tags/0.4.1/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, |
}, |
/tags/0.4.1/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 */ |
/tags/0.4.1/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 */ |
/tags/0.4.1/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 (!str_cmp("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; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/modules/help/help_def.h |
---|
0,0 → 1,6 |
{ |
"help", |
"Show help for commands", |
&cmd_help, |
&help_cmd_help, |
}, |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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, |
}, |
/tags/0.4.1/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 */ |
/tags/0.4.1/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; |
} |
/tags/0.4.1/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 */ |
/tags/0.4.1/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. |
/tags/0.4.1/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 (!str_cmp(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 (!str_cmp(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 (!str_cmp(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; |
} |
/tags/0.4.1/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 (!str_cmp(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 (!str_cmp(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 (!str_cmp(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; |
} |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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; |
} |
/tags/0.4.1/uspace/app/bdsh/cmds/builtins/exit/exit_def.h |
---|
0,0 → 1,6 |
{ |
"exit", |
"Exit the shell", |
&cmd_exit, |
&help_cmd_exit, |
}, |
/tags/0.4.1/uspace/app/bdsh/cmds/builtins/cd/cd_def.h |
---|
0,0 → 1,6 |
{ |
"cd", |
"Change the current working directory", |
&cmd_cd, |
&help_cmd_cd, |
}, |
/tags/0.4.1/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; |
} |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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. |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/uspace/app/bdsh/util.c |
---|
0,0 → 1,72 |
/* 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->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; |
} |
if (!getcwd(usr->cwd, PATH_MAX)) |
snprintf(usr->cwd, PATH_MAX, "(unknown)"); |
if (usr->prompt) |
free(usr->prompt); |
asprintf(&usr->prompt, "%s # ", usr->cwd); |
return 0; |
} |
/tags/0.4.1/uspace/app/bdsh/exec.c |
---|
0,0 → 1,138 |
/* 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 = str_size(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 = str_dup(PATH); |
/* Extract the PATH env to a path[] array */ |
path[n] = strtok(path_tok, PATH_DELIM); |
while (NULL != path[n]) { |
if ((str_size(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; |
task_exit_t texit; |
char *tmp; |
int retval; |
tmp = str_dup(find_command(cmd)); |
free(found); |
tid = task_spawn((const char *)tmp, argv); |
free(tmp); |
if (tid == 0) { |
cli_error(CL_EEXEC, "Cannot spawn `%s'.", cmd); |
return 1; |
} |
task_wait(tid, &texit, &retval); |
if (texit != TASK_EXIT_NORMAL) { |
printf("Command failed (unexpectedly terminated).\n"); |
} else if (retval != 0) { |
printf("Command failed (return value %d).\n", retval); |
} |
return 0; |
} |
/tags/0.4.1/uspace/app/bdsh/input.c |
---|
0,0 → 1,164 |
/* 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/console.h> |
#include <io/keycode.h> |
#include <io/style.h> |
#include <vfs/vfs.h> |
#include <errno.h> |
#include <bool.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 = str_dup(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) |
{ |
console_event_t ev; |
size_t offs, otmp; |
wchar_t dec; |
offs = 0; |
while (true) { |
fflush(stdout); |
if (!console_get_event(fphone(stdin), &ev)) |
return; |
if (ev.type != KEY_PRESS) |
continue; |
if (ev.key == KC_ENTER || ev.key == KC_NENTER) |
break; |
if (ev.key == KC_BACKSPACE) { |
if (offs > 0) { |
/* |
* Back up until we reach valid start of |
* character. |
*/ |
while (offs > 0) { |
--offs; otmp = offs; |
dec = str_decode(buffer, &otmp, n); |
if (dec != U_SPECIAL) |
break; |
} |
putchar('\b'); |
} |
continue; |
} |
if (ev.c >= ' ') { |
if (chr_encode(ev.c, buffer, &offs, n - 1) == EOK) |
putchar(ev.c); |
} |
} |
putchar('\n'); |
buffer[offs] = '\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]; |
fflush(stdout); |
console_set_style(fphone(stdout), STYLE_EMPHASIS); |
printf("%s", usr->prompt); |
fflush(stdout); |
console_set_style(fphone(stdout), STYLE_NORMAL); |
read_line(line, INPUT_MAX); |
/* Make sure we don't have rubbish or a C/R happy user */ |
if (str_cmp(line, "") == 0 || str_cmp(line, "\n") == 0) |
return; |
usr->line = str_dup(line); |
return; |
} |
/tags/0.4.1/uspace/app/bdsh/Makefile |
---|
0,0 → 1,139 |
# 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 |
LIBBLOCK_PREFIX = ../../lib/libblock |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include -I$(LIBBLOCK_PREFIX) |
LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(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/bdd/ \ |
cmds/modules/cat/ \ |
cmds/modules/touch/ \ |
cmds/modules/ls/ \ |
cmds/modules/pwd/ \ |
cmds/modules/sleep/ \ |
cmds/modules/cp/ \ |
cmds/modules/mv/ \ |
cmds/modules/mount/ \ |
cmds/modules/kcon/ \ |
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/bdd/bdd.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/modules/mv/mv.c \ |
cmds/modules/mount/mount.c \ |
cmds/modules/kcon/kcon.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) |
/tags/0.4.1/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. |
/tags/0.4.1/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 |
/tags/0.4.1/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; |
} |
/tags/0.4.1/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" |
/tags/0.4.1/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. |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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; |
} |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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 |
/tags/0.4.1/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. |
/tags/0.4.1/uspace/app/init/init.c |
---|
0,0 → 1,270 |
/* |
* 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. |
*/ |
/** @addtogroup init Init |
* @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 <sys/stat.h> |
#include <task.h> |
#include <malloc.h> |
#include <macros.h> |
#include <string.h> |
#include <devmap.h> |
#include <config.h> |
#include "init.h" |
static void info_print(void) |
{ |
printf(NAME ": HelenOS init\n"); |
} |
static bool mount_root(const char *fstype) |
{ |
char *opts = ""; |
const char *root_dev = "initrd"; |
if (str_cmp(fstype, "tmpfs") == 0) |
opts = "restore"; |
int rc = mount(fstype, "/", root_dev, opts, IPC_FLAG_BLOCKING); |
switch (rc) { |
case EOK: |
printf(NAME ": Root filesystem mounted, %s at %s\n", |
fstype, root_dev); |
break; |
case EBUSY: |
printf(NAME ": Root filesystem already mounted\n"); |
return false; |
case ELIMIT: |
printf(NAME ": Unable to mount root filesystem\n"); |
return false; |
case ENOENT: |
printf(NAME ": Unknown filesystem type (%s)\n", fstype); |
return false; |
default: |
printf(NAME ": Error mounting root filesystem (%d)\n", rc); |
return false; |
} |
return true; |
} |
static bool mount_devfs(void) |
{ |
char null[MAX_DEVICE_NAME]; |
int null_id = devmap_null_create(); |
if (null_id == -1) { |
printf(NAME ": Unable to create null device\n"); |
return false; |
} |
snprintf(null, MAX_DEVICE_NAME, "null%d", null_id); |
int rc = mount("devfs", "/dev", null, "", IPC_FLAG_BLOCKING); |
switch (rc) { |
case EOK: |
printf(NAME ": Device filesystem mounted\n"); |
break; |
case EBUSY: |
printf(NAME ": Device filesystem already mounted\n"); |
devmap_null_destroy(null_id); |
return false; |
case ELIMIT: |
printf(NAME ": Unable to mount device filesystem\n"); |
devmap_null_destroy(null_id); |
return false; |
case ENOENT: |
printf(NAME ": Unknown filesystem type (devfs)\n"); |
devmap_null_destroy(null_id); |
return false; |
default: |
printf(NAME ": Error mounting device filesystem (%d)\n", rc); |
devmap_null_destroy(null_id); |
return false; |
} |
return true; |
} |
static void spawn(char *fname) |
{ |
char *argv[2]; |
struct stat s; |
if (stat(fname, &s) == ENOENT) |
return; |
printf(NAME ": Spawning %s\n", fname); |
argv[0] = fname; |
argv[1] = NULL; |
if (!task_spawn(fname, argv)) |
printf(NAME ": Error spawning %s\n", fname); |
} |
static void srv_start(char *fname) |
{ |
char *argv[2]; |
task_id_t id; |
task_exit_t texit; |
int rc, retval; |
struct stat s; |
if (stat(fname, &s) == ENOENT) |
return; |
printf(NAME ": Starting %s\n", fname); |
argv[0] = fname; |
argv[1] = NULL; |
id = task_spawn(fname, argv); |
if (!id) { |
printf(NAME ": Error spawning %s\n", fname); |
return; |
} |
rc = task_wait(id, &texit, &retval); |
if (rc != EOK) { |
printf(NAME ": Error waiting for %s\n", fname); |
return; |
} |
if (texit != TASK_EXIT_NORMAL || retval != 0) { |
printf(NAME ": Server %s failed to start (returned %d)\n", |
fname, retval); |
} |
} |
static void getvc(char *dev, char *app) |
{ |
char *argv[4]; |
char vc[MAX_DEVICE_NAME]; |
int rc; |
snprintf(vc, MAX_DEVICE_NAME, "/dev/%s", dev); |
printf(NAME ": Spawning getvc on %s\n", vc); |
dev_handle_t handle; |
rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING); |
if (rc == EOK) { |
argv[0] = "/app/getvc"; |
argv[1] = vc; |
argv[2] = app; |
argv[3] = NULL; |
if (!task_spawn("/app/getvc", argv)) |
printf(NAME ": Error spawning getvc on %s\n", vc); |
} else { |
printf(NAME ": Error waiting on %s\n", vc); |
} |
} |
static void mount_data(void) |
{ |
int rc; |
printf("Trying to mount disk0 on /data... "); |
fflush(stdout); |
rc = mount("fat", "/data", "disk0", "wtcache", 0); |
if (rc == EOK) |
printf("OK\n"); |
else |
printf("Failed\n"); |
} |
int main(int argc, char *argv[]) |
{ |
info_print(); |
if (!mount_root(STRING(RDFMT))) { |
printf(NAME ": Exiting\n"); |
return -1; |
} |
spawn("/srv/devfs"); |
if (!mount_devfs()) { |
printf(NAME ": Exiting\n"); |
return -2; |
} |
spawn("/srv/fb"); |
spawn("/srv/kbd"); |
spawn("/srv/console"); |
spawn("/srv/fhc"); |
spawn("/srv/obio"); |
/* |
* Start these synchronously so that mount_data() can be |
* non-blocking. |
*/ |
#ifdef CONFIG_START_BD |
srv_start("/srv/ata_bd"); |
srv_start("/srv/gxe_bd"); |
#else |
(void) srv_start; |
#endif |
#ifdef CONFIG_MOUNT_DATA |
mount_data(); |
#else |
(void) mount_data; |
#endif |
getvc("vc0", "/app/bdsh"); |
getvc("vc1", "/app/bdsh"); |
getvc("vc2", "/app/bdsh"); |
getvc("vc3", "/app/bdsh"); |
getvc("vc4", "/app/bdsh"); |
getvc("vc5", "/app/bdsh"); |
getvc("vc6", "/app/klog"); |
return 0; |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/init/Makefile |
---|
0,0 → 1,76 |
# |
# 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../../.. |
LIBS = $(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = init |
SOURCES = \ |
init.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-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/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/tags/0.4.1/uspace/app/init/init.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 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. |
*/ |
/** @addtogroup init |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef __INIT_H__ |
#define __INIT_H__ |
#define NAME "init" |
#define MAX_DEVICE_NAME 32 |
#endif |
/** @} |
*/ |
/tags/0.4.1/uspace/app/trace/trace.c |
---|
0,0 → 1,1007 |
/* |
* 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 <mem.h> |
#include <string.h> |
#include <bool.h> |
#include <loader/loader.h> |
#include <io/console.h> |
#include <io/keycode.h> |
#include <fibril_sync.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; |
ipc_call_t thread_ipc_req[THBUF_SIZE]; |
int phoneid; |
bool abort_trace; |
uintptr_t thash; |
static bool paused; |
static fibril_condvar_t state_cv; |
static fibril_mutex_t state_lock; |
static bool cev_valid; |
static console_event_t cev; |
void thread_trace_start(uintptr_t thread_hash); |
static proto_t *proto_console; |
static task_id_t task_id; |
static loader_t *task_ldr; |
static bool task_wait_for; |
/** Combination of events/data to print. */ |
display_mask_t display_mask; |
static int program_run_fibril(void *arg); |
static int cev_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 void cev_fibril_start(void) |
{ |
fid_t fid; |
fid = fibril_create(cev_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) |
{ |
long sval; |
sval = (long) val; |
switch (v_type) { |
case V_VOID: |
printf("<void>"); |
break; |
case V_INTEGER: |
printf("%ld", sval); |
break; |
case V_HASH: |
case V_PTR: |
printf("0x%08lx", val); |
break; |
case V_ERRNO: |
if (sval >= -15 && sval <= 0) { |
printf("%ld %s (%s)", sval, |
err_desc[-sval].name, |
err_desc[-sval].desc); |
} else { |
printf("%ld", sval); |
} |
break; |
case V_INT_ERRNO: |
if (sval >= -15 && sval < 0) { |
printf("%ld %s (%s)", sval, |
err_desc[-sval].name, |
err_desc[-sval].desc); |
} else { |
printf("%ld", sval); |
} |
break; |
case V_CHAR: |
if (sval >= 0x20 && sval < 0x7f) { |
printf("'%c'", sval); |
} else { |
switch (sval) { |
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 == (sysarg_t) IPC_CALLRET_FATAL || |
sc_rc == (sysarg_t) 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 == (sysarg_t) IPC_CALLRET_FATAL || |
sc_rc == (sysarg_t) 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_b(unsigned thread_id, sysarg_t *sc_args) |
{ |
ipc_call_t question; |
int rc; |
memset(&question, 0, sizeof(question)); |
rc = udebug_mem_read(phoneid, &question.args, sc_args[1], |
sizeof(question.args)); |
if (rc < 0) { |
printf("Error: mem_read->%d\n", rc); |
return; |
} |
thread_ipc_req[thread_id] = question; |
} |
static void sc_ipc_call_sync_slow_e(unsigned thread_id, sysarg_t *sc_args) |
{ |
ipc_call_t reply; |
int rc; |
memset(&reply, 0, sizeof(reply)); |
rc = udebug_mem_read(phoneid, &reply.args, sc_args[2], |
sizeof(reply.args)); |
if (rc < 0) { |
printf("Error: mem_read->%d\n", rc); |
return; |
} |
ipcp_call_sync(sc_args[0], &thread_ipc_req[thread_id], &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); |
} |
switch (sc_id) { |
case SYS_IPC_CALL_SYNC_SLOW: |
sc_ipc_call_sync_slow_b(thread_id, sc_args); |
break; |
default: |
break; |
} |
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_e(thread_id, 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++; |
if (thread_id >= THBUF_SIZE) { |
printf("Too many threads.\n"); |
return ELIMIT; |
} |
printf("Start tracing thread [%d] (hash 0x%lx).\n", thread_id, thread_hash); |
while (!abort_trace) { |
fibril_mutex_lock(&state_lock); |
if (paused) { |
printf("Thread [%d] paused. Press R to resume.\n", |
thread_id); |
while (paused) |
fibril_condvar_wait(&state_cv, &state_lock); |
printf("Thread [%d] resumed.\n", thread_id); |
} |
fibril_mutex_unlock(&state_lock); |
/* 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"); |
fibril_mutex_lock(&state_lock); |
paused = true; |
fibril_mutex_unlock(&state_lock); |
break; |
case UDEBUG_EVENT_THREAD_B: |
event_thread_b(val0); |
break; |
case UDEBUG_EVENT_THREAD_E: |
printf("Thread 0x%lx exited.\n", val0); |
fibril_mutex_lock(&state_lock); |
abort_trace = true; |
fibril_condvar_broadcast(&state_cv); |
fibril_mutex_unlock(&state_lock); |
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; |
/* Send default files */ |
fdi_node_t *files[4]; |
fdi_node_t stdin_node; |
fdi_node_t stdout_node; |
fdi_node_t stderr_node; |
if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK)) |
files[0] = &stdin_node; |
else |
files[0] = NULL; |
if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK)) |
files[1] = &stdout_node; |
else |
files[1] = NULL; |
if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK)) |
files[2] = &stderr_node; |
else |
files[2] = NULL; |
files[3] = NULL; |
rc = loader_set_files(ldr, files); |
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 int cev_fibril(void *arg) |
{ |
(void) arg; |
while (true) { |
fibril_mutex_lock(&state_lock); |
while (cev_valid) |
fibril_condvar_wait(&state_cv, &state_lock); |
fibril_mutex_unlock(&state_lock); |
if (!console_get_event(fphone(stdin), &cev)) |
return -1; |
fibril_mutex_lock(&state_lock); |
cev_valid = true; |
fibril_condvar_broadcast(&state_cv); |
fibril_mutex_unlock(&state_lock); |
} |
} |
static void trace_task(task_id_t task_id) |
{ |
console_event_t ev; |
bool done; |
int i; |
int rc; |
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 = false; |
for (i = 0; i < n_threads; i++) { |
thread_trace_start(thread_hash_buf[i]); |
} |
done = false; |
while (!done) { |
fibril_mutex_lock(&state_lock); |
while (!cev_valid && !abort_trace) |
fibril_condvar_wait(&state_cv, &state_lock); |
fibril_mutex_unlock(&state_lock); |
ev = cev; |
fibril_mutex_lock(&state_lock); |
cev_valid = false; |
fibril_condvar_broadcast(&state_cv); |
fibril_mutex_unlock(&state_lock); |
if (abort_trace) |
break; |
if (ev.type != KEY_PRESS) |
continue; |
switch (ev.key) { |
case KC_Q: |
done = true; |
break; |
case KC_P: |
printf("Pause...\n"); |
rc = udebug_stop(phoneid, thash); |
if (rc != EOK) |
printf("Error: stop -> %d\n", rc); |
break; |
case KC_R: |
fibril_mutex_lock(&state_lock); |
paused = false; |
fibril_condvar_broadcast(&state_cv); |
fibril_mutex_unlock(&state_lock); |
printf("Resume...\n"); |
break; |
} |
} |
printf("\nTerminate debugging session...\n"); |
abort_trace = true; |
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 = false; |
cev_valid = false; |
fibril_mutex_initialize(&state_lock); |
fibril_condvar_initialize(&state_cv); |
proto_init(); |
p = proto_new("vfs"); |
o = oper_new("open", 2, arg_def, V_INT_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_OPEN, o); |
o = oper_new("open_node", 4, arg_def, V_INT_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_OPEN_NODE, o); |
o = oper_new("read", 1, arg_def, V_ERRNO, 1, resp_def); |
proto_add_oper(p, VFS_IN_READ, o); |
o = oper_new("write", 1, arg_def, V_ERRNO, 1, resp_def); |
proto_add_oper(p, VFS_IN_WRITE, o); |
o = oper_new("seek", 3, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_SEEK, o); |
o = oper_new("truncate", 5, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_TRUNCATE, o); |
o = oper_new("fstat", 1, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_FSTAT, o); |
o = oper_new("close", 1, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_CLOSE, o); |
o = oper_new("mount", 2, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_MOUNT, o); |
/* o = oper_new("unmount", 0, arg_def); |
proto_add_oper(p, VFS_IN_UNMOUNT, o);*/ |
o = oper_new("sync", 1, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_SYNC, o); |
o = oper_new("mkdir", 1, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_MKDIR, o); |
o = oper_new("unlink", 0, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_UNLINK, o); |
o = oper_new("rename", 0, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_RENAME, o); |
o = oper_new("stat", 0, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_IN_STAT, o); |
proto_register(SERVICE_VFS, p); |
p = proto_new("console"); |
o = oper_new("write", 1, arg_def, V_ERRNO, 1, resp_def); |
proto_add_oper(p, VFS_IN_WRITE, o); |
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); |
arg_def[0] = V_CHAR; |
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_GET_SIZE, 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; |
task_wait_for = false; |
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); |
task_wait_for = true; |
return 0; |
} |
int main(int argc, char *argv[]) |
{ |
int rc; |
task_exit_t texit; |
int retval; |
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(); |
cev_fibril_start(); |
trace_task(task_id); |
if (task_wait_for) { |
printf("Waiting for task to exit.\n"); |
rc = task_wait(task_id, &texit, &retval); |
if (rc != EOK) { |
printf("Failed waiting for task.\n"); |
return -1; |
} |
if (texit == TASK_EXIT_NORMAL) { |
printf("Task exited normally, return value %d.\n", |
retval); |
} else { |
printf("Task exited unexpectedly.\n"); |
} |
} |
return 0; |
} |
/** @} |
*/ |
/tags/0.4.1/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 <adt/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 { |
unsigned 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; |
} |
/** @} |
*/ |
/tags/0.4.1/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 <adt/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 |
/** @} |
*/ |
/tags/0.4.1/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 <adt/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); |
} |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/trace/syscalls.c |
---|
0,0 → 1,83 |
/* |
* 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_EVENT_SUBSCRIBE] = { "event_subscribe", 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 } |
}; |
/** @} |
*/ |
/tags/0.4.1/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 $@ |
/tags/0.4.1/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 |
/** @} |
*/ |
/tags/0.4.1/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 |
/** @} |
*/ |
/tags/0.4.1/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 |
/** @} |
*/ |
/tags/0.4.1/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 |
/** @} |
*/ |
/tags/0.4.1/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 |
/** @} |
*/ |
/tags/0.4.1/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 } |
}; |
/** @} |
*/ |
/tags/0.4.1/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." } |
}; |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tester/thread/thread1.c |
---|
0,0 → 1,81 |
/* |
* Copyright (c) 2005 Jakub Vana |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#define THREADS 20 |
#define DELAY 10 |
#include <atomic.h> |
#include <thread.h> |
#include <stdio.h> |
#include <unistd.h> |
#include "../tester.h" |
static atomic_t finish; |
static atomic_t threads_finished; |
static void threadtest(void *data) |
{ |
thread_detach(thread_get_id()); |
while (atomic_get(&finish)) |
usleep(100000); |
atomic_inc(&threads_finished); |
} |
char *test_thread1(void) |
{ |
unsigned int i; |
int total = 0; |
atomic_set(&finish, 1); |
atomic_set(&threads_finished, 0); |
TPRINTF("Creating threads"); |
for (i = 0; i < THREADS; i++) { |
if (thread_create(threadtest, NULL, "threadtest", NULL) < 0) { |
TPRINTF("\nCould not create thread %u\n", i); |
break; |
} |
TPRINTF("."); |
total++; |
} |
TPRINTF("\nRunning threads for %u seconds...", DELAY); |
sleep(DELAY); |
TPRINTF("\n"); |
atomic_set(&finish, 0); |
while (atomic_get(&threads_finished) < total) { |
TPRINTF("Threads left: %u\n", total - atomic_get(&threads_finished)); |
sleep(1); |
} |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/thread/thread1.def |
---|
0,0 → 1,6 |
{ |
"thread1", |
"Thread test", |
&test_thread1, |
true |
}, |
/tags/0.4.1/uspace/app/tester/console/console1.c |
---|
0,0 → 1,123 |
/* |
* 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/console.h> |
#include <io/color.h> |
#include <io/style.h> |
#include <vfs/vfs.h> |
#include <async.h> |
#include "../tester.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(void) |
{ |
if (!test_quiet) { |
printf("Style test: "); |
fflush(stdout); |
console_set_style(fphone(stdout), STYLE_NORMAL); |
printf("normal "); |
fflush(stdout); |
console_set_style(fphone(stdout), STYLE_EMPHASIS); |
printf("emphasized"); |
fflush(stdout); |
console_set_style(fphone(stdout), STYLE_NORMAL); |
printf(".\n"); |
unsigned int i; |
unsigned int j; |
printf("\nForeground color test:\n"); |
for (j = 0; j < 2; j++) { |
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) { |
fflush(stdout); |
console_set_color(fphone(stdout), i, COLOR_WHITE, |
j ? CATTR_BRIGHT : 0); |
printf(" %s ", color_name[i]); |
} |
fflush(stdout); |
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
} |
printf("\nBackground color test:\n"); |
for (j = 0; j < 2; j++) { |
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) { |
fflush(stdout); |
console_set_color(fphone(stdout), COLOR_WHITE, i, |
j ? CATTR_BRIGHT : 0); |
printf(" %s ", color_name[i]); |
} |
fflush(stdout); |
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
} |
printf("\nRGB colors test:\n"); |
for (i = 0; i < 255; i += 16) { |
fflush(stdout); |
console_set_rgb_color(fphone(stdout), 0xffffff, i << 16); |
putchar('X'); |
} |
fflush(stdout); |
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
for (i = 0; i < 255; i += 16) { |
fflush(stdout); |
console_set_rgb_color(fphone(stdout), 0xffffff, i << 8); |
putchar('X'); |
} |
fflush(stdout); |
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
for (i = 0; i < 255; i += 16) { |
fflush(stdout); |
console_set_rgb_color(fphone(stdout), 0xffffff, i); |
putchar('X'); |
} |
fflush(stdout); |
console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
} |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/console/console1.def |
---|
0,0 → 1,6 |
{ |
"console1", |
"Console color test", |
&test_console1, |
true |
}, |
/tags/0.4.1/uspace/app/tester/stdio/stdio1.c |
---|
0,0 → 1,90 |
/* |
* 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(void) |
{ |
FILE *file; |
char *file_name = "/readme"; |
TPRINTF("Open file \"%s\"...", file_name); |
errno = 0; |
file = fopen(file_name, "rt"); |
if (file == NULL) { |
TPRINTF("errno = %d\n", errno); |
return "Failed opening file"; |
} else |
TPRINTF("OK\n"); |
TPRINTF("Read file..."); |
size_t cnt = fread(buf, 1, BUF_SIZE, file); |
if (ferror(file)) { |
TPRINTF("errno = %d\n", errno); |
fclose(file); |
return "Failed reading file"; |
} else |
TPRINTF("OK\n"); |
buf[cnt] = '\0'; |
TPRINTF("Read %u bytes, string \"%s\"\n", cnt, buf); |
TPRINTF("Seek to beginning..."); |
if (fseek(file, 0, SEEK_SET) != 0) { |
TPRINTF("errno = %d\n", errno); |
fclose(file); |
return "Failed seeking in file"; |
} else |
TPRINTF("OK\n"); |
TPRINTF("Read using fgetc()..."); |
while (true) { |
int c = fgetc(file); |
if (c == EOF) |
break; |
TPRINTF("."); |
} |
TPRINTF("[EOF]\n"); |
TPRINTF("Close..."); |
if (fclose(file) != 0) { |
TPRINTF("errno = %d\n", errno); |
return "Failed closing file"; |
} else |
TPRINTF("OK\n"); |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/stdio/stdio2.c |
---|
0,0 → 1,83 |
/* |
* 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(void) |
{ |
FILE *file; |
char *file_name = "/test"; |
TPRINTF("Open file \"%s\" for writing...", file_name); |
errno = 0; |
file = fopen(file_name, "wt"); |
if (file == NULL) { |
TPRINTF("errno = %d\n", errno); |
return "Failed opening file"; |
} else |
TPRINTF("OK\n"); |
TPRINTF("Write to file..."); |
fprintf(file, "integer: %u, string: \"%s\"", 42, "Hello!"); |
TPRINTF("OK\n"); |
TPRINTF("Close..."); |
if (fclose(file) != 0) { |
TPRINTF("errno = %d\n", errno); |
return "Failed closing file"; |
} else |
TPRINTF("OK\n"); |
TPRINTF("Open file \"%s\" for reading...", file_name); |
file = fopen(file_name, "rt"); |
if (file == NULL) { |
TPRINTF("errno = %d\n", errno); |
return "Failed opening file"; |
} else |
TPRINTF("OK\n"); |
TPRINTF("File contains:\n"); |
while (true) { |
int c = fgetc(file); |
if (c == EOF) |
break; |
TPRINTF("%c", c); |
} |
TPRINTF("\nClose..."); |
if (fclose(file) != 0) { |
TPRINTF("errno = %d\n", errno); |
return "Failed closing file"; |
} else |
TPRINTF("OK\n"); |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/stdio/stdio1.def |
---|
0,0 → 1,6 |
{ |
"stdio1", |
"ANSI C streams reading test", |
&test_stdio1, |
true |
}, |
/tags/0.4.1/uspace/app/tester/stdio/stdio2.def |
---|
0,0 → 1,6 |
{ |
"stdio2", |
"ANSI C streams writing test", |
&test_stdio2, |
true |
}, |
/tags/0.4.1/uspace/app/tester/tester.c |
---|
0,0 → 1,147 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* Copyright (c) 2007 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. |
*/ |
/** @addtogroup tester User space tester |
* @brief User space testing infrastructure. |
* @{ |
*/ |
/** |
* @file |
*/ |
#include <unistd.h> |
#include <stdio.h> |
#include <string.h> |
#include "tester.h" |
bool test_quiet; |
int test_argc; |
char **test_argv; |
test_t tests[] = { |
#include "thread/thread1.def" |
#include "print/print1.def" |
#include "print/print2.def" |
#include "print/print3.def" |
#include "print/print4.def" |
#include "console/console1.def" |
#include "stdio/stdio1.def" |
#include "stdio/stdio2.def" |
#include "fault/fault1.def" |
#include "fault/fault2.def" |
#include "vfs/vfs1.def" |
#include "ipc/ping_pong.def" |
#include "ipc/register.def" |
#include "ipc/connect.def" |
#include "loop/loop1.def" |
#include "mm/malloc1.def" |
{NULL, NULL, NULL, false} |
}; |
static bool run_test(test_t *test) |
{ |
/* Execute the test */ |
char *ret = test->entry(); |
if (ret == NULL) { |
printf("\nTest passed\n"); |
return true; |
} |
printf("\n%s\n", ret); |
return false; |
} |
static void run_safe_tests(void) |
{ |
test_t *test; |
unsigned int i = 0; |
unsigned int n = 0; |
printf("\n*** Running all safe tests ***\n\n"); |
for (test = tests; test->name != NULL; test++) { |
if (test->safe) { |
printf("%s (%s)\n", test->name, test->desc); |
if (run_test(test)) |
i++; |
else |
n++; |
} |
} |
printf("\nCompleted, %u tests run, %u passed.\n", i + n, i); |
} |
static void list_tests(void) |
{ |
size_t len = 0; |
test_t *test; |
for (test = tests; test->name != NULL; test++) { |
if (str_length(test->name) > len) |
len = str_length(test->name); |
} |
for (test = tests; test->name != NULL; test++) |
printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)")); |
printf("%-*s Run all safe tests\n", len, "*"); |
} |
int main(int argc, char *argv[]) |
{ |
if (argc < 2) { |
printf("Usage:\n\n"); |
printf("%s <test> [args ...]\n\n", argv[0]); |
list_tests(); |
return 0; |
} |
test_quiet = false; |
test_argc = argc - 2; |
test_argv = argv + 2; |
if (str_cmp(argv[1], "*") == 0) { |
run_safe_tests(); |
return 0; |
} |
test_t *test; |
for (test = tests; test->name != NULL; test++) { |
if (str_cmp(argv[1], test->name) == 0) { |
return (run_test(test) ? 0 : -1); |
} |
} |
printf("Unknown test \"%s\"\n", argv[1]); |
return -2; |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tester/loop/loop1.c |
---|
0,0 → 1,40 |
/* |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include "../tester.h" |
char *test_loop1(void) |
{ |
TPRINTF("Looping..."); |
while (true); |
TPRINTF("\n"); |
return "Survived endless loop"; |
} |
/tags/0.4.1/uspace/app/tester/loop/loop1.def |
---|
0,0 → 1,6 |
{ |
"loop1", |
"Endless loop", |
&test_loop1, |
false |
}, |
/tags/0.4.1/uspace/app/tester/fault/fault1.c |
---|
0,0 → 1,37 |
/* |
* Copyright (c) 2005 Jakub Vana |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "../tester.h" |
char *test_fault1(void) |
{ |
((int *)(0))[1] = 0; |
return "Survived write to NULL"; |
} |
/tags/0.4.1/uspace/app/tester/fault/fault2.c |
---|
0,0 → 1,40 |
/* |
* Copyright (c) 2005 Jakub Vana |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "../tester.h" |
char *test_fault2(void) |
{ |
volatile long long var; |
volatile int var1; |
var1 = *((int *) (((char *) (&var)) + 1)); |
return "Survived unaligned read"; |
} |
/tags/0.4.1/uspace/app/tester/fault/fault1.def |
---|
0,0 → 1,6 |
{ |
"fault1", |
"Write to NULL", |
&test_fault1, |
false |
}, |
/tags/0.4.1/uspace/app/tester/fault/fault2.def |
---|
0,0 → 1,6 |
{ |
"fault2", |
"Unaligned read", |
&test_fault2, |
false |
}, |
/tags/0.4.1/uspace/app/tester/ipc/ping_pong.c |
---|
0,0 → 1,78 |
/* |
* Copyright (c) 2009 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 <sys/time.h> |
#include <ipc/ns.h> |
#include <async.h> |
#include <errno.h> |
#include "../tester.h" |
#define DURATION_SECS 10 |
#define COUNT_GRANULARITY 100 |
char *test_ping_pong(void) |
{ |
TPRINTF("Pinging ns server for %d seconds...", DURATION_SECS); |
struct timeval start; |
if (gettimeofday(&start, NULL) != 0) { |
TPRINTF("\n"); |
return "Failed getting the time"; |
} |
uint64_t count = 0; |
while (true) { |
struct timeval now; |
if (gettimeofday(&now, NULL) != 0) { |
TPRINTF("\n"); |
return "Failed getting the time"; |
} |
if (tv_sub(&now, &start) >= DURATION_SECS * 1000000L) |
break; |
size_t i; |
for (i = 0; i < COUNT_GRANULARITY; i++) { |
int retval = async_req_0_0(PHONE_NS, NS_PING); |
if (retval != EOK) { |
TPRINTF("\n"); |
return "Failed to send ping message"; |
} |
} |
count += COUNT_GRANULARITY; |
} |
TPRINTF("OK\nCompleted %llu round trips in %u seconds, %llu rt/s.\n", |
count, DURATION_SECS, count / DURATION_SECS); |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/ipc/register.c |
---|
0,0 → 1,89 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* 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 <unistd.h> |
#include <async.h> |
#include <errno.h> |
#include "../tester.h" |
#define MAX_CONNECTIONS 50 |
static int connections[MAX_CONNECTIONS]; |
static void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
unsigned int i; |
TPRINTF("Connected phone %#x accepting\n", icall->in_phone_hash); |
ipc_answer_0(iid, EOK); |
for (i = 0; i < MAX_CONNECTIONS; i++) { |
if (!connections[i]) { |
connections[i] = icall->in_phone_hash; |
break; |
} |
} |
while (true) { |
ipc_call_t call; |
ipc_callid_t callid = async_get_call(&call); |
int retval; |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
TPRINTF("Phone %#x hung up\n", icall->in_phone_hash); |
retval = 0; |
break; |
case IPC_TEST_METHOD: |
TPRINTF("Received well known message from %#x: %#x\n", |
icall->in_phone_hash, callid); |
ipc_answer_0(callid, EOK); |
break; |
default: |
TPRINTF("Received unknown message from %#x: %#x\n", |
icall->in_phone_hash, callid); |
ipc_answer_0(callid, ENOENT); |
break; |
} |
} |
} |
char *test_register(void) |
{ |
async_set_client_connection(client_connection); |
ipcarg_t phonead; |
int res = ipc_connect_to_me(PHONE_NS, IPC_TEST_SERVICE, 0, 0, &phonead); |
if (res != 0) |
return "Failed registering IPC service"; |
TPRINTF("Registered as service %u, accepting connections\n", IPC_TEST_SERVICE); |
async_manager(); |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/ipc/connect.c |
---|
0,0 → 1,73 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* 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 <unistd.h> |
#include <atomic.h> |
#include "../tester.h" |
static atomic_t finish; |
static void callback(void *priv, int retval, ipc_call_t *data) |
{ |
atomic_set(&finish, 1); |
} |
char *test_connect(void) |
{ |
TPRINTF("Connecting to %u...", IPC_TEST_SERVICE); |
int phone = ipc_connect_me_to(PHONE_NS, IPC_TEST_SERVICE, 0, 0); |
if (phone > 0) { |
TPRINTF("phoneid %d\n", phone); |
} else { |
TPRINTF("\n"); |
return "ipc_connect_me_to() failed"; |
} |
printf("Sending synchronous message...\n"); |
int retval = ipc_call_sync_0_0(phone, IPC_TEST_METHOD); |
TPRINTF("Received response to synchronous message\n"); |
TPRINTF("Sending asynchronous message...\n"); |
atomic_set(&finish, 0); |
ipc_call_async_0(phone, IPC_TEST_METHOD, NULL, callback, 1); |
while (atomic_get(&finish) != 1) |
TPRINTF("."); |
TPRINTF("Received response to asynchronous message\n"); |
TPRINTF("Hanging up..."); |
retval = ipc_hangup(phone); |
if (retval == 0) { |
TPRINTF("OK\n"); |
} else { |
TPRINTF("\n"); |
return "ipc_hangup() failed"; |
} |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/ipc/ping_pong.def |
---|
0,0 → 1,6 |
{ |
"ping_pong", |
"IPC ping-pong benchmark", |
&test_ping_pong, |
true |
}, |
/tags/0.4.1/uspace/app/tester/ipc/register.def |
---|
0,0 → 1,6 |
{ |
"register", |
"IPC registration test", |
&test_register, |
true |
}, |
/tags/0.4.1/uspace/app/tester/ipc/connect.def |
---|
0,0 → 1,6 |
{ |
"connect", |
"IPC connection test (connect to other service)", |
&test_connect, |
true |
}, |
/tags/0.4.1/uspace/app/tester/print/print2.c |
---|
0,0 → 1,52 |
/* |
* Copyright (c) 2005 Josef Cejka |
* 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 <unistd.h> |
#include "../tester.h" |
char *test_print2(void) |
{ |
TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n"); |
TPRINTF("Expected output: [a] [ b] [c ] [ d] [e ]\n"); |
TPRINTF("Real output: [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e'); |
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", 1, 2, 3, 4, 5):\n"); |
TPRINTF("Expected output: [1] [ 02] [03 ] [004] [005]\n"); |
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", 1, 2, 3, 4, 5); |
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", -1, -2, -3, -4, -5):\n"); |
TPRINTF("Expected output: [-1] [-02] [-03] [-004] [-005]\n"); |
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", -1, -2, -3, -4, -5); |
TPRINTF("Testing printf(\"%%#x %%5.3#x %%-5.3#x %%3.5#x %%-3.5#x\", 17, 18, 19, 20, 21):\n"); |
TPRINTF("Expected output: [0x11] [0x012] [0x013] [0x00014] [0x00015]\n"); |
TPRINTF("Real output: [%#x] [%#5.3x] [%#-5.3x] [%#3.5x] [%#-3.5x]\n\n", 17, 18, 19, 20, 21); |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/print/print3.c |
---|
0,0 → 1,62 |
/* |
* Copyright (c) 2005 Josef Cejka |
* 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 <unistd.h> |
#include <macros.h> |
#include "../tester.h" |
#define BUFFER_SIZE 32 |
char *test_print3(void) |
{ |
char buffer[BUFFER_SIZE]; |
int retval; |
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short text without parameters.\"):\n"); |
TPRINTF("Expected result: retval=30 buffer=\"Short text without parameters.\"\n"); |
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters."); |
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer); |
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very very very long text without parameters.\"):\n"); |
TPRINTF("Expected result: retval=44 buffer=\"Very very very long text withou\"\n"); |
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters."); |
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer); |
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short %%s.\", \"text\"):\n"); |
TPRINTF("Expected result: retval=11 buffer=\"Short text.\"\n"); |
retval = snprintf(buffer, BUFFER_SIZE, "Short %s.", "text"); |
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer); |
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very long %%s. This text's length is more than %%d. We are interested in the result.\", \"text\", " STRING(BUFFER_SIZE) "):\n"); |
TPRINTF("Expected result: retval=84 buffer=\"Very long text. This text's len\"\n"); |
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text's length is more than %d. We are interested in the result.", "text", BUFFER_SIZE); |
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer); |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/print/print4.c |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2009 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. |
*/ |
#include <stdio.h> |
#include <unistd.h> |
#include "../tester.h" |
char *test_print4(void) |
{ |
TPRINTF("ASCII printable characters (32 - 127) using printf(\"%%c\") and printf(\"%%lc\"):\n"); |
uint8_t group; |
for (group = 1; group < 4; group++) { |
TPRINTF("%#x: ", group << 5); |
uint8_t index; |
for (index = 0; index < 32; index++) |
TPRINTF("%c", (char) ((group << 5) + index)); |
TPRINTF(" "); |
for (index = 0; index < 32; index++) |
TPRINTF("%lc", (wchar_t) ((group << 5) + index)); |
TPRINTF("\n"); |
} |
TPRINTF("\nExtended ASCII characters (128 - 255) using printf(\"%%lc\"):\n"); |
for (group = 4; group < 8; group++) { |
TPRINTF("%#x: ", group << 5); |
uint8_t index; |
for (index = 0; index < 32; index++) |
TPRINTF("%lc", (wchar_t) ((group << 5) + index)); |
TPRINTF("\n"); |
} |
TPRINTF("\nUTF-8 strings using printf(\"%%s\"):\n"); |
TPRINTF("English: %s\n", "Quick brown fox jumps over the lazy dog"); |
TPRINTF("Czech: %s\n", "Příliš žluťoučký kůň úpěl ďábelské ódy"); |
TPRINTF("Greek: %s\n", "á½® ξεῖν’, ἀγγÎλλειν Λακεδαιμονίοις ὅτι τῇδε"); |
TPRINTF("Hebrew: %s\n", "משוואת ברנולי היא משוואה בהידרודינמיקה"); |
TPRINTF("Arabic: %s\n", "التوزيع الجغرافي للحمل العنقودي"); |
TPRINTF("Russian: %s\n", "Леннон познакомился с художницей-авангардисткой"); |
TPRINTF("Armenian: %s\n", "ÕÕ¯Õ½Õ¥Ö Õ°Ö€Õ¡Õ¿Õ¡Ö€Õ¡Õ¯Õ¾Õ¥Õ¬ ÔµÖ€Õ¸Ö‚Õ½Õ¡Õ²Õ¥Õ´Õ« Õ°Õ¡ÕµÕ¯Õ¡Õ¯Õ¡Õ¶"); |
TPRINTF("\nUTF-32 strings using printf(\"%%ls\"):\n"); |
TPRINTF("English: %ls\n", L"Quick brown fox jumps over the lazy dog"); |
TPRINTF("Czech: %ls\n", L"Příliš žluťoučký kůň úpěl ďábelské ódy"); |
TPRINTF("Greek: %ls\n", L"á½® ξεῖν’, ἀγγÎλλειν Λακεδαιμονίοις ὅτι τῇδε"); |
TPRINTF("Hebrew: %ls\n", L"משוואת ברנולי היא משוואה בהידרודינמיקה"); |
TPRINTF("Arabic: %ls\n", L"التوزيع الجغرافي للحمل العنقودي"); |
TPRINTF("Russian: %ls\n", L"Леннон познакомился с художницей-авангардисткой"); |
TPRINTF("Armenian: %ls\n", L"ÕÕ¯Õ½Õ¥Ö Õ°Ö€Õ¡Õ¿Õ¡Ö€Õ¡Õ¯Õ¾Õ¥Õ¬ ÔµÖ€Õ¸Ö‚Õ½Õ¡Õ²Õ¥Õ´Õ« Õ°Õ¡ÕµÕ¯Õ¡Õ¯Õ¡Õ¶"); |
return NULL; |
} |
Property changes: |
Added: svn:mergeinfo |
/tags/0.4.1/uspace/app/tester/print/print1.def |
---|
0,0 → 1,6 |
{ |
"print1", |
"String printf test", |
&test_print1, |
true |
}, |
/tags/0.4.1/uspace/app/tester/print/print2.def |
---|
0,0 → 1,6 |
{ |
"print2", |
"Numeric printf test", |
&test_print2, |
true |
}, |
/tags/0.4.1/uspace/app/tester/print/print3.def |
---|
0,0 → 1,6 |
{ |
"print3", |
"Buffered printf test", |
&test_print3, |
true |
}, |
/tags/0.4.1/uspace/app/tester/print/print1.c |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2005 Josef Cejka |
* 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 <unistd.h> |
#include "../tester.h" |
char *test_print1(void) |
{ |
TPRINTF("Testing printf(\"%%*.*s\", 5, 3, \"text\"):\n"); |
TPRINTF("Expected output: \" tex\"\n"); |
TPRINTF("Real output: \"%*.*s\"\n\n", 5, 3, "text"); |
TPRINTF("Testing printf(\"%%10.8s\", \"very long text\"):\n"); |
TPRINTF("Expected output: \" very lon\"\n"); |
TPRINTF("Real output: \"%10.8s\"\n\n", "very long text"); |
TPRINTF("Testing printf(\"%%8.10s\", \"text\"):\n"); |
TPRINTF("Expected output: \"text\"\n"); |
TPRINTF("Real output: \"%8.10s\"\n\n", "text"); |
TPRINTF("Testing printf(\"%%8.10s\", \"very long text\"):\n"); |
TPRINTF("Expected output: \"very long \"\n"); |
TPRINTF("Real output: \"%8.10s\"\n\n", "very long text"); |
TPRINTF("Testing printf(\"%%s\", NULL):\n"); |
TPRINTF("Expected output: \"(NULL)\"\n"); |
TPRINTF("Real output: \"%s\"\n\n", NULL); |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/print/print4.def |
---|
0,0 → 1,6 |
{ |
"print4", |
"Unicode test", |
&test_print4, |
true |
}, |
Property changes: |
Added: svn:mergeinfo |
/tags/0.4.1/uspace/app/tester/tester.h |
---|
0,0 → 1,87 |
/* |
* Copyright (c) 2007 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. |
*/ |
/** @addtogroup tester |
* @{ |
*/ |
/** @file |
*/ |
#ifndef TESTER_H_ |
#define TESTER_H_ |
#include <sys/types.h> |
#include <bool.h> |
#include <ipc/ipc.h> |
#define IPC_TEST_SERVICE 10240 |
#define IPC_TEST_METHOD 2000 |
extern bool test_quiet; |
extern int test_argc; |
extern char **test_argv; |
#define TPRINTF(format, ...) \ |
{ \ |
if (!test_quiet) { \ |
fprintf(stderr, format, ##__VA_ARGS__); \ |
} \ |
} |
typedef char *(*test_entry_t)(void); |
typedef struct { |
char *name; |
char *desc; |
test_entry_t entry; |
bool safe; |
} test_t; |
extern char *test_thread1(void); |
extern char *test_print1(void); |
extern char *test_print2(void); |
extern char *test_print3(void); |
extern char *test_print4(void); |
extern char *test_console1(void); |
extern char *test_stdio1(void); |
extern char *test_stdio2(void); |
extern char *test_fault1(void); |
extern char *test_fault2(void); |
extern char *test_vfs1(void); |
extern char *test_ping_pong(void); |
extern char *test_register(void); |
extern char *test_connect(void); |
extern char *test_loop1(void); |
extern char *test_malloc1(void); |
extern test_t tests[]; |
#endif |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tester/Makefile |
---|
0,0 → 1,92 |
# |
# 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 = tester |
SOURCES = tester.c \ |
thread/thread1.c \ |
print/print1.c \ |
print/print2.c \ |
print/print3.c \ |
print/print4.c \ |
console/console1.c \ |
stdio/stdio1.c \ |
stdio/stdio2.c \ |
fault/fault1.c \ |
fault/fault2.c \ |
vfs/vfs1.c \ |
ipc/ping_pong.c \ |
ipc/register.c \ |
ipc/connect.c \ |
loop/loop1.c \ |
mm/malloc1.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-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/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/tags/0.4.1/uspace/app/tester/vfs/vfs1.c |
---|
0,0 → 1,151 |
/* |
* Copyright (c) 2008 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <errno.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <vfs/vfs.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include <dirent.h> |
#include <devmap.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include "../tester.h" |
#define FS_TYPE "tmpfs" |
#define MOUNT_POINT "/tmp" |
#define OPTIONS "" |
#define FLAGS 0 |
#define TEST_DIRECTORY MOUNT_POINT "/testdir" |
#define TEST_FILE TEST_DIRECTORY "/testfile" |
#define TEST_FILE2 TEST_DIRECTORY "/nextfile" |
#define MAX_DEVICE_NAME 32 |
#define BUF_SIZE 16 |
static char text[] = "Lorem ipsum dolor sit amet, consectetur adipisicing elit"; |
static char *read_root(void) |
{ |
TPRINTF("Opening the root directory..."); |
DIR *dirp = opendir("/"); |
if (!dirp) { |
TPRINTF("\n"); |
return "opendir() failed"; |
} else |
TPRINTF("OK\n"); |
struct dirent *dp; |
while ((dp = readdir(dirp))) |
TPRINTF(" node \"%s\"\n", dp->d_name); |
closedir(dirp); |
return NULL; |
} |
char *test_vfs1(void) |
{ |
if (mkdir(MOUNT_POINT, 0) != 0) |
return "mkdir() failed"; |
TPRINTF("Created directory %s\n", MOUNT_POINT); |
char null[MAX_DEVICE_NAME]; |
int null_id = devmap_null_create(); |
if (null_id == -1) |
return "Unable to create null device"; |
snprintf(null, MAX_DEVICE_NAME, "null%d", null_id); |
int rc = mount(FS_TYPE, MOUNT_POINT, null, OPTIONS, FLAGS); |
switch (rc) { |
case EOK: |
TPRINTF("Mounted /dev/%s as %s on %s\n", null, FS_TYPE, MOUNT_POINT); |
break; |
case EBUSY: |
TPRINTF("(INFO) Filesystem already mounted on %s\n", MOUNT_POINT); |
break; |
default: |
TPRINTF("(ERR) IPC returned errno %d (is tmpfs loaded?)\n", rc); |
return "mount() failed"; |
} |
if (mkdir(TEST_DIRECTORY, 0) != 0) |
return "mkdir() failed"; |
TPRINTF("Created directory %s\n", TEST_DIRECTORY); |
int fd0 = open(TEST_FILE, O_CREAT); |
if (fd0 < 0) |
return "open() failed"; |
TPRINTF("Created file %s (fd=%d)\n", TEST_FILE, fd0); |
size_t size = sizeof(text); |
ssize_t cnt = write(fd0, text, size); |
if (cnt < 0) |
return "write() failed"; |
TPRINTF("Written %d bytes\n", cnt); |
if (lseek(fd0, 0, SEEK_SET) != 0) |
return "lseek() failed"; |
TPRINTF("Sought to position 0\n"); |
char buf[BUF_SIZE]; |
while ((cnt = read(fd0, buf, BUF_SIZE))) { |
if (cnt < 0) |
return "read() failed"; |
TPRINTF("Read %d bytes: \".*s\"\n", cnt, cnt, buf); |
} |
close(fd0); |
char *rv = read_root(); |
if (rv != NULL) |
return rv; |
if (rename(TEST_FILE, TEST_FILE2)) |
return "rename() failed"; |
TPRINTF("Renamed %s to %s\n", TEST_FILE, TEST_FILE2); |
if (unlink(TEST_FILE2)) |
return "unlink() failed"; |
TPRINTF("Unlinked %s\n", TEST_FILE2); |
if (rmdir(TEST_DIRECTORY)) |
return "rmdir() failed"; |
TPRINTF("Removed directory %s\n", TEST_DIRECTORY); |
rv = read_root(); |
if (rv != NULL) |
return rv; |
return NULL; |
} |
/tags/0.4.1/uspace/app/tester/vfs/vfs1.def |
---|
0,0 → 1,6 |
{ |
"vfs1", |
"VFS test", |
&test_vfs1, |
true |
}, |
/tags/0.4.1/uspace/app/tester/mm/malloc1.def |
---|
0,0 → 1,6 |
{ |
"malloc1", |
"Memory allocator test", |
&test_malloc1, |
true |
}, |
/tags/0.4.1/uspace/app/tester/mm/malloc1.c |
---|
0,0 → 1,651 |
/* |
* Copyright (c) 2009 Martin Decky |
* Copyright (c) 2009 Tomas Bures |
* Copyright (c) 2009 Lubomir Bulej |
* 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 <unistd.h> |
#include <stdlib.h> |
#include <malloc.h> |
#include "../tester.h" |
/* |
* The test consists of several phases which differ in the size of blocks |
* they allocate. The size of blocks is given as a range of minimum and |
* maximum allowed size. Each of the phases is divided into 3 subphases which |
* differ in the probability of free and alloc actions. Second subphase is |
* started when malloc returns 'out of memory' or when MAX_ALLOC is reached. |
* Third subphase is started after a given number of cycles. The third subphase |
* as well as the whole phase ends when all memory blocks are released. |
*/ |
/** |
* sizeof_array |
* @array array to determine the size of |
* |
* Returns the size of @array in array elements. |
*/ |
#define sizeof_array(array) \ |
(sizeof(array) / sizeof((array)[0])) |
#define MAX_ALLOC (16 * 1024 * 1024) |
/* |
* Subphase control structures: subphase termination conditions, |
* probabilities of individual actions, subphase control structure. |
*/ |
typedef struct { |
unsigned int max_cycles; |
unsigned int no_memory; |
unsigned int no_allocated; |
} sp_term_cond_s; |
typedef struct { |
unsigned int alloc; |
unsigned int free; |
} sp_action_prob_s; |
typedef struct { |
char *name; |
sp_term_cond_s cond; |
sp_action_prob_s prob; |
} subphase_s; |
/* |
* Phase control structures: The minimum and maximum block size that |
* can be allocated during the phase execution, phase control structure. |
*/ |
typedef struct { |
size_t min_block_size; |
size_t max_block_size; |
} ph_alloc_size_s; |
typedef struct { |
char *name; |
ph_alloc_size_s alloc; |
subphase_s *subphases; |
} phase_s; |
/* |
* Subphases are defined separately here. This is for two reasons: |
* 1) data are not duplicated, 2) we don't have to state beforehand |
* how many subphases a phase contains. |
*/ |
static subphase_s subphases_32B[] = { |
{ |
.name = "Allocation", |
.cond = { |
.max_cycles = 200, |
.no_memory = 1, |
.no_allocated = 0, |
}, |
.prob = { |
.alloc = 90, |
.free = 100 |
} |
}, |
{ |
.name = "Alloc/Dealloc", |
.cond = { |
.max_cycles = 200, |
.no_memory = 0, |
.no_allocated = 0, |
}, |
.prob = { |
.alloc = 50, |
.free = 100 |
} |
}, |
{ |
.name = "Deallocation", |
.cond = { |
.max_cycles = 0, |
.no_memory = 0, |
.no_allocated = 1, |
}, |
.prob = { |
.alloc = 10, |
.free = 100 |
} |
} |
}; |
static subphase_s subphases_128K[] = { |
{ |
.name = "Allocation", |
.cond = { |
.max_cycles = 0, |
.no_memory = 1, |
.no_allocated = 0, |
}, |
.prob = { |
.alloc = 70, |
.free = 100 |
} |
}, |
{ |
.name = "Alloc/Dealloc", |
.cond = { |
.max_cycles = 30, |
.no_memory = 0, |
.no_allocated = 0, |
}, |
.prob = { |
.alloc = 50, |
.free = 100 |
} |
}, |
{ |
.name = "Deallocation", |
.cond = { |
.max_cycles = 0, |
.no_memory = 0, |
.no_allocated = 1, |
}, |
.prob = { |
.alloc = 30, |
.free = 100 |
} |
} |
}; |
static subphase_s subphases_default[] = { |
{ |
.name = "Allocation", |
.cond = { |
.max_cycles = 0, |
.no_memory = 1, |
.no_allocated = 0, |
}, |
.prob = { |
.alloc = 90, |
.free = 100 |
} |
}, |
{ |
.name = "Alloc/Dealloc", |
.cond = { |
.max_cycles = 200, |
.no_memory = 0, |
.no_allocated = 0, |
}, |
.prob = { |
.alloc = 50, |
.free = 100 |
} |
}, |
{ |
.name = "Deallocation", |
.cond = { |
.max_cycles = 0, |
.no_memory = 0, |
.no_allocated = 1, |
}, |
.prob = { |
.alloc = 10, |
.free = 100 |
} |
} |
}; |
/* |
* Phase definitions. |
*/ |
static phase_s phases[] = { |
{ |
.name = "32 B memory blocks", |
.alloc = { |
.min_block_size = 32, |
.max_block_size = 32 |
}, |
.subphases = subphases_32B |
}, |
{ |
.name = "128 KB memory blocks", |
.alloc = { |
.min_block_size = 128 * 1024, |
.max_block_size = 128 * 1024 |
}, |
.subphases = subphases_128K |
}, |
{ |
.name = "2500 B memory blocks", |
.alloc = { |
.min_block_size = 2500, |
.max_block_size = 2500 |
}, |
.subphases = subphases_default |
}, |
{ |
.name = "1 B .. 250000 B memory blocks", |
.alloc = { |
.min_block_size = 1, |
.max_block_size = 250000 |
}, |
.subphases = subphases_default |
} |
}; |
/* |
* Global error flag. The flag is set if an error |
* is encountered (overlapping blocks, inconsistent |
* block data, etc.) |
*/ |
static bool error_flag = false; |
/* |
* Memory accounting: the amount of allocated memory and the |
* number and list of allocated blocks. |
*/ |
static size_t mem_allocated; |
static size_t mem_blocks_count; |
static LIST_INITIALIZE(mem_blocks); |
typedef struct { |
/* Address of the start of the block */ |
void *addr; |
/* Size of the memory block */ |
size_t size; |
/* link to other blocks */ |
link_t link; |
} mem_block_s; |
typedef mem_block_s *mem_block_t; |
/** init_mem |
* |
* Initializes the memory accounting structures. |
* |
*/ |
static void init_mem(void) |
{ |
mem_allocated = 0; |
mem_blocks_count = 0; |
} |
static bool overlap_match(link_t *entry, void *addr, size_t size) |
{ |
mem_block_t mblk = list_get_instance(entry, mem_block_s, link); |
/* Entry block control structure <mbeg, mend) */ |
uint8_t *mbeg = (uint8_t *) mblk; |
uint8_t *mend = (uint8_t *) mblk + sizeof(mem_block_s); |
/* Entry block memory <bbeg, bend) */ |
uint8_t *bbeg = (uint8_t *) mblk->addr; |
uint8_t *bend = (uint8_t *) mblk->addr + mblk->size; |
/* Data block <dbeg, dend) */ |
uint8_t *dbeg = (uint8_t *) addr; |
uint8_t *dend = (uint8_t *) addr + size; |
/* Check for overlaps */ |
if (((mbeg >= dbeg) && (mbeg < dend)) || |
((mend > dbeg) && (mend <= dend)) || |
((bbeg >= dbeg) && (bbeg < dend)) || |
((bend > dbeg) && (bend <= dend))) |
return true; |
return false; |
} |
/** test_overlap |
* |
* Test whether a block starting at @addr overlaps with another, previously |
* allocated memory block or its control structure. |
* |
* @param addr Initial address of the block |
* @param size Size of the block |
* |
* @return false if the block does not overlap. |
* |
*/ |
static int test_overlap(void *addr, size_t size) |
{ |
link_t *entry; |
bool fnd = false; |
for (entry = mem_blocks.next; entry != &mem_blocks; entry = entry->next) { |
if (overlap_match(entry, addr, size)) { |
fnd = true; |
break; |
} |
} |
return fnd; |
} |
/** checked_malloc |
* |
* Allocate @size bytes of memory and check whether the chunk comes |
* from the non-mapped memory region and whether the chunk overlaps |
* with other, previously allocated, chunks. |
* |
* @param size Amount of memory to allocate |
* |
* @return NULL if the allocation failed. Sets the global error_flag to |
* true if the allocation succeeded but is illegal. |
* |
*/ |
static void *checked_malloc(size_t size) |
{ |
void *data; |
/* Allocate the chunk of memory */ |
data = malloc(size); |
if (data == NULL) |
return NULL; |
/* Check for overlaps with other chunks */ |
if (test_overlap(data, size)) { |
TPRINTF("\nError: Allocated block overlaps with another " |
"previously allocated block.\n"); |
error_flag = true; |
} |
return data; |
} |
/** alloc_block |
* |
* Allocate a block of memory of @size bytes and add record about it into |
* the mem_blocks list. Return a pointer to the block holder structure or |
* NULL if the allocation failed. |
* |
* If the allocation is illegal (e.g. the memory does not come from the |
* right region or some of the allocated blocks overlap with others), |
* set the global error_flag. |
* |
* @param size Size of the memory block |
* |
*/ |
static mem_block_t alloc_block(size_t size) |
{ |
/* Check for allocation limit */ |
if (mem_allocated >= MAX_ALLOC) |
return NULL; |
/* Allocate the block holder */ |
mem_block_t block = (mem_block_t) checked_malloc(sizeof(mem_block_s)); |
if (block == NULL) |
return NULL; |
link_initialize(&block->link); |
/* Allocate the block memory */ |
block->addr = checked_malloc(size); |
if (block->addr == NULL) { |
free(block); |
return NULL; |
} |
block->size = size; |
/* Register the allocated block */ |
list_append(&block->link, &mem_blocks); |
mem_allocated += size + sizeof(mem_block_s); |
mem_blocks_count++; |
return block; |
} |
/** free_block |
* |
* Free the block of memory and the block control structure allocated by |
* alloc_block. Set the global error_flag if an error occurs. |
* |
* @param block Block control structure |
* |
*/ |
static void free_block(mem_block_t block) |
{ |
/* Unregister the block */ |
list_remove(&block->link); |
mem_allocated -= block->size + sizeof(mem_block_s); |
mem_blocks_count--; |
/* Free the memory */ |
free(block->addr); |
free(block); |
} |
/** expected_value |
* |
* Compute the expected value of a byte located at @pos in memory |
* block described by @blk. |
* |
* @param blk Memory block control structure |
* @param pos Position in the memory block data area |
* |
*/ |
static inline uint8_t expected_value(mem_block_t blk, uint8_t *pos) |
{ |
return ((unsigned long) blk ^ (unsigned long) pos) & 0xff; |
} |
/** fill_block |
* |
* Fill the memory block controlled by @blk with data. |
* |
* @param blk Memory block control structure |
* |
*/ |
static void fill_block(mem_block_t blk) |
{ |
uint8_t *pos; |
uint8_t *end; |
for (pos = blk->addr, end = pos + blk->size; pos < end; pos++) |
*pos = expected_value(blk, pos); |
} |
/** check_block |
* |
* Check whether the block @blk contains the data it was filled with. |
* Set global error_flag if an error occurs. |
* |
* @param blk Memory block control structure |
* |
*/ |
static void check_block(mem_block_t blk) |
{ |
uint8_t *pos; |
uint8_t *end; |
for (pos = blk->addr, end = pos + blk->size; pos < end; pos++) { |
if (*pos != expected_value (blk, pos)) { |
TPRINTF("\nError: Corrupted content of a data block.\n"); |
error_flag = true; |
return; |
} |
} |
} |
static link_t *list_get_nth(link_t *list, unsigned int i) |
{ |
unsigned int cnt = 0; |
link_t *entry; |
for (entry = list->next; entry != list; entry = entry->next) { |
if (cnt == i) |
return entry; |
cnt++; |
} |
return NULL; |
} |
/** get_random_block |
* |
* Select a random memory block from the list of allocated blocks. |
* |
* @return Block control structure or NULL if the list is empty. |
* |
*/ |
static mem_block_t get_random_block(void) |
{ |
if (mem_blocks_count == 0) |
return NULL; |
unsigned int blkidx = rand() % mem_blocks_count; |
link_t *entry = list_get_nth(&mem_blocks, blkidx); |
if (entry == NULL) { |
TPRINTF("\nError: Corrupted list of allocated memory blocks.\n"); |
error_flag = true; |
} |
return list_get_instance(entry, mem_block_s, link); |
} |
#define RETURN_IF_ERROR \ |
{ \ |
if (error_flag) \ |
return; \ |
} |
static void do_subphase(phase_s *phase, subphase_s *subphase) |
{ |
unsigned int cycles; |
for (cycles = 0; /* always */; cycles++) { |
if (subphase->cond.max_cycles && |
cycles >= subphase->cond.max_cycles) { |
/* |
* We have performed the required number of |
* cycles. End the current subphase. |
*/ |
break; |
} |
/* |
* Decide whether we alloc or free memory in this step. |
*/ |
unsigned int rnd = rand() % 100; |
if (rnd < subphase->prob.alloc) { |
/* Compute a random number lying in interval <min_block_size, max_block_size> */ |
int alloc = phase->alloc.min_block_size + |
(rand() % (phase->alloc.max_block_size - phase->alloc.min_block_size + 1)); |
mem_block_t blk = alloc_block(alloc); |
RETURN_IF_ERROR; |
if (blk == NULL) { |
TPRINTF("F(A)"); |
if (subphase->cond.no_memory) { |
/* We filled the memory. Proceed to next subphase */ |
break; |
} |
} else { |
TPRINTF("A"); |
fill_block(blk); |
} |
} else if (rnd < subphase->prob.free) { |
mem_block_t blk = get_random_block(); |
if (blk == NULL) { |
TPRINTF("F(R)"); |
if (subphase->cond.no_allocated) { |
/* We free all the memory. Proceed to next subphase. */ |
break; |
} |
} else { |
TPRINTF("R"); |
check_block(blk); |
RETURN_IF_ERROR; |
free_block(blk); |
RETURN_IF_ERROR; |
} |
} |
} |
TPRINTF("\n.. finished.\n"); |
} |
static void do_phase(phase_s *phase) |
{ |
unsigned int subno; |
for (subno = 0; subno < 3; subno++) { |
subphase_s *subphase = & phase->subphases [subno]; |
TPRINTF(".. Sub-phase %u (%s)\n", subno + 1, subphase->name); |
do_subphase(phase, subphase); |
RETURN_IF_ERROR; |
} |
} |
char *test_malloc1(void) |
{ |
init_mem(); |
unsigned int phaseno; |
for (phaseno = 0; phaseno < sizeof_array(phases); phaseno++) { |
phase_s *phase = &phases[phaseno]; |
TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name); |
do_phase(phase); |
if (error_flag) |
break; |
TPRINTF("Phase finished.\n"); |
} |
if (error_flag) |
return "Test failed"; |
return NULL; |
} |
/tags/0.4.1/uspace/app/tetris/shapes.c |
---|
0,0 → 1,114 |
/* $OpenBSD: shapes.c,v 1.8 2004/07/10 07:26:24 deraadt Exp $ */ |
/* $NetBSD: shapes.c,v 1.2 1995/04/22 07:42:44 cgd Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)shapes.c 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
*/ |
/** @file |
*/ |
/* |
* Tetris shapes and related routines. |
* |
* Note that the first 7 are `well known'. |
*/ |
#include <unistd.h> |
#include "tetris.h" |
#define TL (-B_COLS - 1) /* top left */ |
#define TC (-B_COLS) /* top center */ |
#define TR (-B_COLS + 1) /* top right */ |
#define ML -1 /* middle left */ |
#define MR 1 /* middle right */ |
#define BL (B_COLS - 1) /* bottom left */ |
#define BC B_COLS /* bottom center */ |
#define BR (B_COLS + 1) /* bottom right */ |
const struct shape shapes[] = { |
/* 0 */ { 7, 7, { TL, TC, MR }, 0xff042d}, |
/* 1 */ { 8, 8, { TC, TR, ML }, 0xff9304}, |
/* 2 */ { 9, 11, { ML, MR, BC }, 0xbeff04}, |
/* 3 */ { 3, 3, { TL, TC, ML }, 0x63ff04}, |
/* 4 */ { 12, 14, { ML, BL, MR }, 0xce04ff}, |
/* 5 */ { 15, 17, { ML, BR, MR }, 0xff04cf}, |
/* 6 */ { 18, 18, { ML, MR, 2 }, 0x7604ff}, /* sticks out */ |
/* 7 */ { 0, 0, { TC, ML, BL }, 0xff042d}, |
/* 8 */ { 1, 1, { TC, MR, BR }, 0xff9304}, |
/* 9 */ { 10, 2, { TC, MR, BC }, 0xbeff04}, |
/* 10 */ { 11, 9, { TC, ML, MR }, 0xbeff04}, |
/* 11 */ { 2, 10, { TC, ML, BC }, 0xbeff04}, |
/* 12 */ { 13, 4, { TC, BC, BR }, 0xce04ff}, |
/* 13 */ { 14, 12, { TR, ML, MR }, 0xce04ff}, |
/* 14 */ { 4, 13, { TL, TC, BC }, 0xce04ff}, |
/* 15 */ { 16, 5, { TR, TC, BC }, 0xff04cf}, |
/* 16 */ { 17, 15, { TL, MR, ML }, 0xff04cf}, |
/* 17 */ { 5, 16, { TC, BC, BL }, 0xff04cf}, |
/* 18 */ { 6, 6, { TC, BC, 2 * B_COLS }, 0x7604ff} /* sticks out */ |
}; |
/* |
* Return true iff the given shape fits in the given position, |
* taking the current board into account. |
*/ |
int fits_in(const struct shape *shape, int pos) |
{ |
const int *o = shape->off; |
if ((board[pos]) || (board[pos + *o++]) || (board[pos + *o++]) || |
(board[pos + *o])) |
return 0; |
return 1; |
} |
/* |
* Write the given shape into the current board, turning it on |
* if `onoff' is 1, and off if `onoff' is 0. |
*/ |
void place(const struct shape *shape, int pos, int onoff) |
{ |
const int *o = shape->off; |
board[pos] = onoff ? shape->color : 0x000000; |
board[pos + *o++] = onoff ? shape->color : 0x000000; |
board[pos + *o++] = onoff ? shape->color : 0x000000; |
board[pos + *o] = onoff ? shape->color : 0x000000; |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/tetris.c |
---|
0,0 → 1,442 |
/* $OpenBSD: tetris.c,v 1.21 2006/04/20 03:24:12 ray Exp $ */ |
/* $NetBSD: tetris.c,v 1.2 1995/04/22 07:42:47 cgd Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)tetris.c 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris Tetris |
* @brief Tetris ported from OpenBSD |
* @{ |
*/ |
/** @file |
*/ |
static const char copyright[] = |
"@(#) Copyright (c) 1992, 1993\n" |
"\tThe Regents of the University of California. All rights reserved.\n"; |
#include <sys/time.h> |
#include <sys/types.h> |
#include <err.h> |
#include <errno.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <getopt.h> |
#include "input.h" |
#include "scores.h" |
#include "screen.h" |
#include "tetris.h" |
cell board[B_SIZE]; |
int Rows; |
int Cols; |
const struct shape *curshape; |
const struct shape *nextshape; |
long fallrate; |
int score; |
char key_msg[100]; |
int showpreview; |
int classic; |
static void elide(void); |
static void setup_board(void); |
static const struct shape *randshape(void); |
static void usage(void); |
static int firstgame = 1; |
/* |
* Set up the initial board. The bottom display row is completely set, |
* along with another (hidden) row underneath that. Also, the left and |
* right edges are set. |
*/ |
static void setup_board(void) |
{ |
int i; |
cell *p = board; |
for (i = B_SIZE; i; i--) |
*p++ = (i <= (2 * B_COLS) || (i % B_COLS) < 2) ? 0x0000ff : 0x000000; |
} |
/* |
* Elide any full active rows. |
*/ |
static void elide(void) |
{ |
int rows = 0; |
int i; |
int j; |
int base; |
cell *p; |
for (i = A_FIRST; i < A_LAST; i++) { |
base = i * B_COLS + 1; |
p = &board[base]; |
for (j = B_COLS - 2; *p++ != 0;) { |
if (--j <= 0) { |
/* This row is to be elided */ |
rows++; |
memset(&board[base], 0, sizeof(cell) * (B_COLS - 2)); |
scr_update(); |
tsleep(); |
while (--base != 0) |
board[base + B_COLS] = board[base]; |
scr_update(); |
tsleep(); |
break; |
} |
} |
} |
switch (rows) { |
case 1: |
score += 10; |
break; |
case 2: |
score += 30; |
break; |
case 3: |
score += 70; |
break; |
case 4: |
score += 150; |
break; |
default: |
break; |
} |
} |
const struct shape *randshape(void) |
{ |
const struct shape *tmp = &shapes[random() % 7]; |
int i; |
int j = random() % 4; |
for (i = 0; i < j; i++) |
tmp = &shapes[classic ? tmp->rotc : tmp->rot]; |
return (tmp); |
} |
static void srandomdev(void) |
{ |
struct timeval tv; |
gettimeofday(&tv, NULL); |
srandom(tv.tv_sec + tv.tv_usec / 100000); |
} |
static void tetris_menu_draw(int level) |
{ |
clear_screen(); |
moveto(5, 10); |
puts("Tetris\n\n"); |
moveto(8, 10); |
printf("Level = %d (press keys 1 - 9 to change)", level); |
moveto(9, 10); |
printf("Preview is %s (press 'p' to change)", (showpreview ? "on ": "off")); |
moveto(12, 10); |
printf("Press 'h' to show hiscore table."); |
moveto(13, 10); |
printf("Press 's' to start game."); |
moveto(14, 10); |
printf("Press 'q' to quit game."); |
moveto(20, 10); |
printf("In game controls:"); |
moveto(21, 0); |
puts(key_msg); |
} |
static int tetris_menu(int *level) |
{ |
tetris_menu_draw(*level); |
while (1) { |
int i = getchar(); |
switch(i) { |
case 'p': |
showpreview = !showpreview; |
moveto(9, 21); |
if (showpreview) |
printf("on "); |
else |
printf("off"); |
break; |
case 'h': |
loadscores(); |
showscores(firstgame); |
tetris_menu_draw(*level); |
break; |
case 's': |
firstgame = 0; |
return 1; |
case 'q': |
return 0; |
case '1': |
case '2': |
case '3': |
case '4': |
case '5': |
case '6': |
case '7': |
case '8': |
case '9': |
*level = i - '0'; |
moveto(8, 18); |
printf("%d", *level); |
break; |
} |
} |
} |
int main(int argc, char *argv[]) |
{ |
int pos; |
int c; |
const char *keys; |
int level = 2; |
char key_write[6][10]; |
int i; |
int j; |
int ch; |
keys = "jkl pq"; |
classic = 0; |
showpreview = 1; |
while ((ch = getopt(argc, argv, "ck:ps")) != -1) |
switch(ch) { |
case 'c': |
/* |
* this means: |
* - rotate the other way |
* - no reverse video |
*/ |
classic = 1; |
break; |
case 'k': |
if (str_size(keys = optarg) != 6) |
usage(); |
break; |
case 'p': |
showpreview = 1; |
break; |
case 's': |
showscores(0); |
exit(0); |
default: |
usage(); |
} |
argc -= optind; |
argv += optind; |
if (argc) |
usage(); |
for (i = 0; i <= 5; i++) { |
for (j = i + 1; j <= 5; j++) { |
if (keys[i] == keys[j]) |
errx(1, "duplicate command keys specified."); |
} |
if (keys[i] == ' ') |
str_cpy(key_write[i], sizeof(key_write[i]), "<space>"); |
else { |
key_write[i][0] = keys[i]; |
key_write[i][1] = '\0'; |
} |
} |
snprintf(key_msg, sizeof(key_msg), |
"%s - left %s - rotate %s - right %s - drop %s - pause %s - quit", |
key_write[0], key_write[1], key_write[2], key_write[3], |
key_write[4], key_write[5]); |
scr_init(); |
if (loadscores() != EOK) |
initscores(); |
while (tetris_menu(&level)) { |
fallrate = 1000000 / level; |
scr_clear(); |
setup_board(); |
srandomdev(); |
scr_set(); |
pos = A_FIRST * B_COLS + (B_COLS / 2) - 1; |
nextshape = randshape(); |
curshape = randshape(); |
scr_msg(key_msg, 1); |
while (1) { |
place(curshape, pos, 1); |
scr_update(); |
place(curshape, pos, 0); |
c = tgetchar(); |
if (c < 0) { |
/* |
* Timeout. Move down if possible. |
*/ |
if (fits_in(curshape, pos + B_COLS)) { |
pos += B_COLS; |
continue; |
} |
/* |
* Put up the current shape `permanently', |
* bump score, and elide any full rows. |
*/ |
place(curshape, pos, 1); |
score++; |
elide(); |
/* |
* Choose a new shape. If it does not fit, |
* the game is over. |
*/ |
curshape = nextshape; |
nextshape = randshape(); |
pos = A_FIRST * B_COLS + (B_COLS / 2) - 1; |
if (!fits_in(curshape, pos)) |
break; |
continue; |
} |
/* |
* Handle command keys. |
*/ |
if (c == keys[5]) { |
/* quit */ |
break; |
} |
if (c == keys[4]) { |
static char msg[] = |
"paused - press RETURN to continue"; |
place(curshape, pos, 1); |
do { |
scr_update(); |
scr_msg(key_msg, 0); |
scr_msg(msg, 1); |
(void) fflush(stdout); |
} while (rwait((struct timeval *) NULL) == -1); |
scr_msg(msg, 0); |
scr_msg(key_msg, 1); |
place(curshape, pos, 0); |
continue; |
} |
if (c == keys[0]) { |
/* move left */ |
if (fits_in(curshape, pos - 1)) |
pos--; |
continue; |
} |
if (c == keys[1]) { |
/* turn */ |
const struct shape *new = |
&shapes[classic ? curshape->rotc : curshape->rot]; |
if (fits_in(new, pos)) |
curshape = new; |
continue; |
} |
if (c == keys[2]) { |
/* move right */ |
if (fits_in(curshape, pos + 1)) |
pos++; |
continue; |
} |
if (c == keys[3]) { |
/* move to bottom */ |
while (fits_in(curshape, pos + B_COLS)) { |
pos += B_COLS; |
score++; |
} |
continue; |
} |
if (c == '\f') { |
scr_clear(); |
scr_msg(key_msg, 1); |
} |
} |
scr_clear(); |
loadscores(); |
insertscore(score, level); |
savescores(); |
score = 0; |
} |
scr_clear(); |
printf("\nGame over.\n"); |
scr_end(); |
return 0; |
} |
void usage(void) |
{ |
fprintf(stderr, "usage: tetris [-ps] [-k keys]\n"); |
exit(1); |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/screen.c |
---|
0,0 → 1,324 |
/* $OpenBSD: screen.c,v 1.13 2006/04/20 03:25:36 ray Exp $ */ |
/* $NetBSD: screen.c,v 1.4 1995/04/29 01:11:36 mycroft Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)screen.c 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
*/ |
/** @file |
*/ |
/* |
* Tetris screen control. |
*/ |
#include <err.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <vfs/vfs.h> |
#include <async.h> |
#include "screen.h" |
#include "tetris.h" |
#include <io/console.h> |
#define STOP (B_COLS - 3) |
static cell curscreen[B_SIZE]; /* non-zero => standout (or otherwise marked) */ |
static int curscore; |
static int isset; /* true => terminal is in game mode */ |
static int use_color; /* true => use colors */ |
static const struct shape *lastshape; |
/* |
* putstr() is for unpadded strings (either as in termcap(5) or |
* simply literal strings); |
*/ |
static inline void putstr(char *s) |
{ |
while (*s) |
putchar(*(s++)); |
} |
static void start_standout(uint32_t color) |
{ |
fflush(stdout); |
console_set_rgb_color(fphone(stdout), 0xf0f0f0, |
use_color ? color : 0x000000); |
} |
static void resume_normal(void) |
{ |
fflush(stdout); |
console_set_rgb_color(fphone(stdout), 0, 0xf0f0f0); |
} |
void clear_screen(void) |
{ |
console_clear(fphone(stdout)); |
moveto(0, 0); |
} |
/* |
* Clear the screen, forgetting the current contents in the process. |
*/ |
void scr_clear(void) |
{ |
resume_normal(); |
console_clear(fphone(stdout)); |
curscore = -1; |
memset(curscreen, 0, sizeof(curscreen)); |
} |
/* |
* Set up screen |
*/ |
void scr_init(void) |
{ |
console_cursor_visibility(fphone(stdout), 0); |
resume_normal(); |
scr_clear(); |
} |
void moveto(int r, int c) |
{ |
fflush(stdout); |
console_goto(fphone(stdout), c, r); |
} |
winsize_t winsize; |
static int get_display_size(winsize_t *ws) |
{ |
return console_get_size(fphone(stdout), &ws->ws_col, &ws->ws_row); |
} |
static int get_display_color_sup(void) |
{ |
int rc; |
int ccap; |
rc = console_get_color_cap(fphone(stdout), &ccap); |
if (rc != 0) |
return 0; |
return (ccap >= CONSOLE_CCAP_RGB); |
} |
/* |
* Set up screen mode. |
*/ |
void scr_set(void) |
{ |
winsize_t ws; |
Rows = 0; |
Cols = 0; |
if (get_display_size(&ws) == 0) { |
Rows = ws.ws_row; |
Cols = ws.ws_col; |
} |
use_color = get_display_color_sup(); |
if ((Rows < MINROWS) || (Cols < MINCOLS)) { |
char smallscr[55]; |
snprintf(smallscr, sizeof(smallscr), |
"the screen is too small (must be at least %dx%d)", |
MINROWS, MINCOLS); |
stop(smallscr); |
} |
isset = 1; |
scr_clear(); |
} |
/* |
* End screen mode. |
*/ |
void scr_end(void) |
{ |
console_cursor_visibility(fphone(stdout), 1); |
} |
void stop(char *why) |
{ |
if (isset) |
scr_end(); |
errx(1, "aborting: %s", why); |
} |
/* |
* Update the screen. |
*/ |
void scr_update(void) |
{ |
cell *bp; |
cell *sp; |
cell so; |
cell cur_so = 0; |
int i; |
int j; |
int ccol; |
/* Always leave cursor after last displayed point */ |
curscreen[D_LAST * B_COLS - 1] = -1; |
if (score != curscore) { |
moveto(0, 0); |
printf("Score: %d", score); |
curscore = score; |
} |
/* Draw preview of next pattern */ |
if ((showpreview) && (nextshape != lastshape)) { |
int i; |
static int r = 5, c = 2; |
int tr, tc, t; |
lastshape = nextshape; |
/* Clean */ |
resume_normal(); |
moveto(r - 1, c - 1); |
putstr(" "); |
moveto(r, c - 1); |
putstr(" "); |
moveto(r + 1, c - 1); |
putstr(" "); |
moveto(r + 2, c - 1); |
putstr(" "); |
moveto(r - 3, c - 2); |
putstr("Next shape:"); |
/* Draw */ |
start_standout(nextshape->color); |
moveto(r, 2 * c); |
putstr(" "); |
for (i = 0; i < 3; i++) { |
t = c + r * B_COLS; |
t += nextshape->off[i]; |
tr = t / B_COLS; |
tc = t % B_COLS; |
moveto(tr, 2*tc); |
putstr(" "); |
} |
resume_normal(); |
} |
bp = &board[D_FIRST * B_COLS]; |
sp = &curscreen[D_FIRST * B_COLS]; |
for (j = D_FIRST; j < D_LAST; j++) { |
ccol = -1; |
for (i = 0; i < B_COLS; bp++, sp++, i++) { |
if (*sp == (so = *bp)) |
continue; |
*sp = so; |
if (i != ccol) { |
if (cur_so) { |
resume_normal(); |
cur_so = 0; |
} |
moveto(RTOD(j), CTOD(i)); |
} |
if (so != cur_so) { |
if (so) |
start_standout(so); |
else |
resume_normal(); |
cur_so = so; |
} |
putstr(" "); |
ccol = i + 1; |
/* |
* Look ahead a bit, to avoid extra motion if |
* we will be redrawing the cell after the next. |
* Motion probably takes four or more characters, |
* so we save even if we rewrite two cells |
* `unnecessarily'. Skip it all, though, if |
* the next cell is a different color. |
*/ |
if ((i > STOP) || (sp[1] != bp[1]) || (so != bp[1])) |
continue; |
if (sp[2] != bp[2]) |
sp[1] = -1; |
else if ((i < STOP) && (so == bp[2]) && (sp[3] != bp[3])) { |
sp[2] = -1; |
sp[1] = -1; |
} |
} |
} |
if (cur_so) |
resume_normal(); |
fflush(stdout); |
} |
/* |
* Write a message (set != 0), or clear the same message (set == 0). |
* (We need its length in case we have to overwrite with blanks.) |
*/ |
void scr_msg(char *s, int set) |
{ |
int l = str_size(s); |
moveto(Rows - 2, ((Cols - l) >> 1) - 1); |
if (set) |
putstr(s); |
else |
while (--l >= 0) |
(void) putchar(' '); |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/scores.c |
---|
0,0 → 1,233 |
/* $OpenBSD: scores.c,v 1.11 2006/04/20 03:25:36 ray Exp $ */ |
/* $NetBSD: scores.c,v 1.2 1995/04/22 07:42:38 cgd Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)scores.c 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
*/ |
/** @file |
*/ |
/* |
* Score code for Tetris, by Darren Provine (kilroy@gboro.glassboro.edu) |
* modified 22 January 1992, to limit the number of entries any one |
* person has. |
* |
* Major whacks since then. |
*/ |
#include <errno.h> |
#include <stdio.h> |
#include <string.h> |
#include <io/console.h> |
#include <io/keycode.h> |
#include <vfs/vfs.h> |
#include <stdlib.h> |
#include <fcntl.h> |
#include <err.h> |
#include <time.h> |
#include "screen.h" |
#include "tetris.h" |
#include "scores.h" |
/* |
* Within this code, we can hang onto one extra "high score", leaving |
* room for our current score (whether or not it is high). |
* |
* We also sometimes keep tabs on the "highest" score on each level. |
* As long as the scores are kept sorted, this is simply the first one at |
* that level. |
*/ |
#define NUMSPOTS (MAXHISCORES + 1) |
#define NLEVELS (MAXLEVEL + 1) |
static struct highscore scores[NUMSPOTS]; |
/** Copy from hiscore table score with index src to dest |
* |
*/ |
static void copyhiscore(int dest, int src) |
{ |
str_cpy(scores[dest].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, |
scores[src].hs_name); |
scores[dest].hs_score = scores[src].hs_score; |
scores[dest].hs_level = scores[src].hs_level; |
} |
void showscores(int firstgame) |
{ |
int i; |
clear_screen(); |
moveto(10, 0); |
printf("\tRank \tLevel \tName\t points\n"); |
printf("\t========================================================\n"); |
for (i = 0; i < NUMSPOTS - 1; i++) |
printf("\t%6d %6d %-16s %20d\n", |
i + 1, scores[i].hs_level, scores[i].hs_name, scores[i].hs_score); |
if (!firstgame) { |
printf("\t========================================================\n"); |
printf("\t Last %6d %-16s %20d\n", |
scores[NUMSPOTS - 1].hs_level, scores[NUMSPOTS - 1].hs_name, scores[NUMSPOTS - 1].hs_score); |
} |
printf("\n\n\n\n\tPress any key to return to main menu."); |
getchar(); |
} |
void insertscore(int score, int level) |
{ |
int i; |
int j; |
size_t off; |
console_event_t ev; |
clear_screen(); |
moveto(10, 10); |
puts("Insert your name: "); |
str_cpy(scores[NUMSPOTS - 1].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, |
"Player"); |
i = 6; |
off = 6; |
moveto(10 , 28); |
printf("%s%.*s", scores[NUMSPOTS - 1].hs_name, MAXLOGNAME-i, |
"........................................"); |
while (1) { |
fflush(stdout); |
if (!console_get_event(fphone(stdin), &ev)) |
exit(1); |
if (ev.type == KEY_RELEASE) |
continue; |
if (ev.key == KC_ENTER || ev.key == KC_NENTER) |
break; |
if (ev.key == KC_BACKSPACE) { |
if (i > 0) { |
wchar_t uc; |
--i; |
while (off > 0) { |
--off; |
size_t otmp = off; |
uc = str_decode(scores[NUMSPOTS - 1].hs_name, |
&otmp, STR_BOUNDS(MAXLOGNAME) + 1); |
if (uc != U_SPECIAL) |
break; |
} |
scores[NUMSPOTS - 1].hs_name[off] = '\0'; |
} |
} else if (ev.c != '\0') { |
if (i < (MAXLOGNAME - 1)) { |
if (chr_encode(ev.c, scores[NUMSPOTS - 1].hs_name, |
&off, STR_BOUNDS(MAXLOGNAME) + 1) == EOK) { |
++i; |
} |
scores[NUMSPOTS - 1].hs_name[off] = '\0'; |
} |
} |
moveto(10, 28); |
printf("%s%.*s", scores[NUMSPOTS - 1].hs_name, MAXLOGNAME - i, |
"........................................"); |
} |
scores[NUMSPOTS - 1].hs_score = score; |
scores[NUMSPOTS - 1].hs_level = level; |
i = NUMSPOTS - 1; |
while ((i > 0) && (scores[i - 1].hs_score < score)) |
i--; |
for (j = NUMSPOTS - 2; j > i; j--) |
copyhiscore(j, j-1); |
copyhiscore(i, NUMSPOTS - 1); |
} |
void initscores(void) |
{ |
int i; |
for (i = 0; i < NUMSPOTS; i++) { |
str_cpy(scores[i].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, "HelenOS Team"); |
scores[i].hs_score = (NUMSPOTS - i) * 200; |
scores[i].hs_level = (i + 1 > MAXLEVEL ? MAXLEVEL : i + 1); |
} |
} |
int loadscores(void) |
{ |
FILE *f; |
size_t cnt; |
int rc; |
f = fopen("/data/tetris.sco", "rb"); |
if (f == NULL) |
return ENOENT; |
cnt = fread(scores, sizeof(struct highscore), NUMSPOTS, f); |
rc = fclose(f); |
if (cnt != NUMSPOTS || rc != 0) |
return EIO; |
return EOK; |
} |
void savescores(void) |
{ |
FILE *f; |
size_t cnt; |
int rc; |
f = fopen("/data/tetris.sco", "wb"); |
cnt = fwrite(scores, sizeof(struct highscore), NUMSPOTS, f); |
rc = fclose(f); |
if (cnt != NUMSPOTS || rc != 0) |
printf("Error saving score table\n"); |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/scores.h |
---|
0,0 → 1,71 |
/* $OpenBSD: scores.h,v 1.5 2003/06/03 03:01:41 millert Exp $ */ |
/* $NetBSD: scores.h,v 1.2 1995/04/22 07:42:40 cgd Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)scores.h 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
*/ |
/** @file |
*/ |
/* |
* Tetris scores. |
*/ |
#include <sys/time.h> |
#include <string.h> |
#define MAXLOGNAME 16 |
#define MAXHISCORES 10 |
#define MAXSCORES 9 /* maximum high score entries per person */ |
#define EXPIRATION (5L * 365 * 24 * 60 * 60) |
struct highscore { |
char hs_name[STR_BOUNDS(MAXLOGNAME) + 1]; /* login name */ |
int hs_score; /* raw score */ |
int hs_level; /* play level */ |
time_t hs_time; /* time at game end */ |
}; |
extern void showscores(int); |
extern void initscores(void); |
extern void insertscore(int score, int level); |
extern int loadscores(void); |
extern void savescores(void); |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/input.c |
---|
0,0 → 1,197 |
/* $OpenBSD: input.c,v 1.12 2005/04/13 02:33:08 deraadt Exp $ */ |
/* $NetBSD: input.c,v 1.3 1996/02/06 22:47:33 jtc Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)input.c 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
*/ |
/** @file |
*/ |
/* |
* Tetris input. |
*/ |
#include <sys/types.h> |
#include <sys/time.h> |
#include <stdio.h> |
#include <errno.h> |
#include <unistd.h> |
#include <string.h> |
#include "input.h" |
#include "tetris.h" |
#include <async.h> |
#include <vfs/vfs.h> |
#include <io/console.h> |
#include <ipc/console.h> |
/* return true iff the given timeval is positive */ |
#define TV_POS(tv) \ |
((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0)) |
/* subtract timeval `sub' from `res' */ |
#define TV_SUB(res, sub) \ |
(res)->tv_sec -= (sub)->tv_sec; \ |
(res)->tv_usec -= (sub)->tv_usec; \ |
if ((res)->tv_usec < 0) { \ |
(res)->tv_usec += 1000000; \ |
(res)->tv_sec--; \ |
} |
/* We will use a hack here - if lastchar is non-zero, it is |
* the last character read. We will somehow simulate the select |
* semantics. |
*/ |
static aid_t getchar_inprog = 0; |
static char lastchar = '\0'; |
/* |
* Do a `read wait': select for reading from stdin, with timeout *tvp. |
* On return, modify *tvp to reflect the amount of time spent waiting. |
* It will be positive only if input appeared before the time ran out; |
* otherwise it will be zero or perhaps negative. |
* |
* If tvp is nil, wait forever, but return if select is interrupted. |
* |
* Return 0 => no input, 1 => can read() from stdin |
* |
*/ |
int rwait(struct timeval *tvp) |
{ |
struct timeval starttv, endtv, *s; |
static ipc_call_t charcall; |
ipcarg_t rc; |
/* |
* Someday, select() will do this for us. |
* Just in case that day is now, and no one has |
* changed this, we use a temporary. |
*/ |
if (tvp) { |
(void) gettimeofday(&starttv, NULL); |
endtv = *tvp; |
s = &endtv; |
} else |
s = NULL; |
if (!lastchar) { |
again: |
if (!getchar_inprog) { |
getchar_inprog = async_send_0(fphone(stdin), |
CONSOLE_GET_EVENT, &charcall); |
} |
if (!s) |
async_wait_for(getchar_inprog, &rc); |
else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) { |
tvp->tv_sec = 0; |
tvp->tv_usec = 0; |
return (0); |
} |
getchar_inprog = 0; |
if (rc) |
stop("end of file, help"); |
if (IPC_GET_ARG1(charcall) == KEY_RELEASE) |
goto again; |
lastchar = IPC_GET_ARG4(charcall); |
} |
if (tvp) { |
/* since there is input, we may not have timed out */ |
(void) gettimeofday(&endtv, NULL); |
TV_SUB(&endtv, &starttv); |
TV_SUB(tvp, &endtv); /* adjust *tvp by elapsed time */ |
} |
return 1; |
} |
/* |
* `sleep' for the current turn time (using select). |
* Eat any input that might be available. |
*/ |
void tsleep(void) |
{ |
struct timeval tv; |
tv.tv_sec = 0; |
tv.tv_usec = fallrate; |
while (TV_POS(&tv)) |
if (rwait(&tv)) { |
lastchar = '\0'; |
} else |
break; |
} |
/* |
* getchar with timeout. |
*/ |
int tgetchar(void) |
{ |
static struct timeval timeleft; |
char c; |
/* |
* Reset timeleft to fallrate whenever it is not positive. |
* In any case, wait to see if there is any input. If so, |
* take it, and update timeleft so that the next call to |
* tgetchar() will not wait as long. If there is no input, |
* make timeleft zero or negative, and return -1. |
* |
* Most of the hard work is done by rwait(). |
*/ |
if (!TV_POS(&timeleft)) { |
faster(); /* go faster */ |
timeleft.tv_sec = 0; |
timeleft.tv_usec = fallrate; |
} |
if (!rwait(&timeleft)) |
return -1; |
c = lastchar; |
lastchar = '\0'; |
return ((int) (unsigned char) c); |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/tetris.h |
---|
0,0 → 1,191 |
/* $OpenBSD: tetris.h,v 1.9 2003/06/03 03:01:41 millert Exp $ */ |
/* $NetBSD: tetris.h,v 1.2 1995/04/22 07:42:48 cgd Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)tetris.h 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
*/ |
/** @file |
*/ |
/* |
* Definitions for Tetris. |
*/ |
/* |
* The display (`board') is composed of 23 rows of 12 columns of characters |
* (numbered 0..22 and 0..11), stored in a single array for convenience. |
* Columns 1 to 10 of rows 1 to 20 are the actual playing area, where |
* shapes appear. Columns 0 and 11 are always occupied, as are all |
* columns of rows 21 and 22. Rows 0 and 22 exist as boundary areas |
* so that regions `outside' the visible area can be examined without |
* worrying about addressing problems. |
*/ |
/* The board */ |
#define B_COLS 12 |
#define B_ROWS 23 |
#define B_SIZE (B_ROWS * B_COLS) |
typedef uint32_t cell; |
extern cell board[B_SIZE]; /* 1 => occupied, 0 => empty */ |
/* The displayed area (rows) */ |
#define D_FIRST 1 |
#define D_LAST 22 |
/* The active area (rows) */ |
#define A_FIRST 1 |
#define A_LAST 21 |
/* |
* Minimum display size. |
*/ |
#define MINROWS 23 |
#define MINCOLS 40 |
/* Current screen size */ |
extern int Rows; |
extern int Cols; |
/* |
* Translations from board coordinates to display coordinates. |
* As with board coordinates, display coordiates are zero origin. |
*/ |
#define RTOD(x) ((x) - 1) |
#define CTOD(x) ((x) * 2 + (((Cols - 2 * B_COLS) >> 1) - 1)) |
/* |
* A `shape' is the fundamental thing that makes up the game. There |
* are 7 basic shapes, each consisting of four `blots': |
* |
* X.X X.X X.X |
* X.X X.X X.X.X X.X X.X.X X.X.X X.X.X.X |
* X X X |
* |
* 0 1 2 3 4 5 6 |
* |
* Except for 3 and 6, the center of each shape is one of the blots. |
* This blot is designated (0, 0). The other three blots can then be |
* described as offsets from the center. Shape 3 is the same under |
* rotation, so its center is effectively irrelevant; it has been chosen |
* so that it `sticks out' upward and leftward. Except for shape 6, |
* all the blots are contained in a box going from (-1, -1) to (+1, +1); |
* shape 6's center `wobbles' as it rotates, so that while it `sticks out' |
* rightward, its rotation---a vertical line---`sticks out' downward. |
* The containment box has to include the offset (2, 0), making the overall |
* containment box range from offset (-1, -1) to (+2, +1). (This is why |
* there is only one row above, but two rows below, the display area.) |
* |
* The game works by choosing one of these shapes at random and putting |
* its center at the middle of the first display row (row 1, column 5). |
* The shape is moved steadily downward until it collides with something: |
* either another shape, or the bottom of the board. When the shape can |
* no longer be moved downwards, it is merged into the current board. |
* At this time, any completely filled rows are elided, and blots above |
* these rows move down to make more room. A new random shape is again |
* introduced at the top of the board, and the whole process repeats. |
* The game ends when the new shape will not fit at (1, 5). |
* |
* While the shapes are falling, the user can rotate them counterclockwise |
* 90 degrees (in addition to moving them left or right), provided that the |
* rotation puts the blots in empty spaces. The table of shapes is set up |
* so that each shape contains the index of the new shape obtained by |
* rotating the current shape. Due to symmetry, each shape has exactly |
* 1, 2, or 4 rotations total; the first 7 entries in the table represent |
* the primary shapes, and the remaining 12 represent their various |
* rotated forms. |
*/ |
struct shape { |
int rot; /* index of rotated version of this shape */ |
int rotc; /* -- " -- in classic version */ |
int off[3]; /* offsets to other blots if center is at (0,0) */ |
uint32_t color; |
}; |
extern const struct shape shapes[]; |
extern const struct shape *curshape; |
extern const struct shape *nextshape; |
/* |
* Shapes fall at a rate faster than once per second. |
* |
* The initial rate is determined by dividing 1 million microseconds |
* by the game `level'. (This is at most 1 million, or one second.) |
* Each time the fall-rate is used, it is decreased a little bit, |
* depending on its current value, via the `faster' macro below. |
* The value eventually reaches a limit, and things stop going faster, |
* but by then the game is utterly impossible. |
*/ |
extern long fallrate; /* less than 1 million; smaller => faster */ |
#define faster() (fallrate -= fallrate / 3000) |
/* |
* Game level must be between 1 and 9. This controls the initial fall rate |
* and affects scoring. |
*/ |
#define MINLEVEL 1 |
#define MAXLEVEL 9 |
/* |
* Scoring is as follows: |
* |
* When the shape comes to rest, and is integrated into the board, |
* we score one point. If the shape is high up (at a low-numbered row), |
* and the user hits the space bar, the shape plummets all the way down, |
* and we score a point for each row it falls (plus one more as soon as |
* we find that it is at rest and integrate it---until then, it can |
* still be moved or rotated). |
* |
* If previewing has been turned on, the score is multiplied by PRE_PENALTY. |
*/ |
#define PRE_PENALTY 0.75 |
extern int score; /* The obvious thing */ |
extern char key_msg[100]; |
extern int showpreview; |
extern int classic; |
extern int fits_in(const struct shape *, int); |
extern void place(const struct shape *, int, int); |
extern void stop(char *); |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/input.h |
---|
0,0 → 1,49 |
/* $OpenBSD: input.h,v 1.5 2003/06/03 03:01:41 millert Exp $ */ |
/* $NetBSD: input.h,v 1.2 1995/04/22 07:42:36 cgd Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)input.h 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
*/ |
/** @file |
*/ |
extern int rwait(struct timeval *); |
extern int tgetchar(void); |
extern void tsleep(void); |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/screen.h |
---|
0,0 → 1,72 |
/* $OpenBSD: screen.h,v 1.5 2003/06/03 03:01:41 millert Exp $ */ |
/* $NetBSD: screen.h,v 1.2 1995/04/22 07:42:42 cgd Exp $ */ |
/*- |
* Copyright (c) 1992, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek and Darren F. Provine. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. |
* |
* @(#)screen.h 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
*/ |
/** @file |
*/ |
/* |
* putpad() is for padded strings with count = 1. |
*/ |
#define putpad(s) tputs(s, 1, put) |
#include <sys/types.h> |
#include <async.h> |
typedef struct { |
ipcarg_t ws_row; |
ipcarg_t ws_col; |
} winsize_t; |
extern winsize_t winsize; |
extern void moveto(int r, int c); |
extern void clear_screen(void); |
/* just calls putchar; for tputs */ |
extern int put(int); |
extern void scr_clear(void); |
extern void scr_end(void); |
extern void scr_init(void); |
extern void scr_msg(char *, int); |
extern void scr_set(void); |
extern void scr_update(void); |
/** @} |
*/ |
/tags/0.4.1/uspace/app/tetris/Makefile |
---|
0,0 → 1,39 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
OUTPUT = tetris |
SOURCES = shapes.c scores.c input.c tetris.c screen.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include 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 |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend *.o |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/tags/0.4.1/uspace/app/getvc/getvc.c |
---|
0,0 → 1,109 |
/* |
* Copyright (c) 2009 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. |
*/ |
/** @addtogroup getvc GetVC |
* @brief Console initialization task. |
* @{ |
*/ |
/** |
* @file |
*/ |
#include <sys/types.h> |
#include <unistd.h> |
#include <stdio.h> |
#include <task.h> |
#include "version.h" |
static void usage(void) |
{ |
printf("Usage: getvc <device> <path>\n"); |
} |
static void closeall(void) |
{ |
fclose(stdin); |
fclose(stdout); |
fclose(stderr); |
close(0); |
close(1); |
close(2); |
} |
static task_id_t spawn(char *fname) |
{ |
char *argv[2]; |
argv[0] = fname; |
argv[1] = NULL; |
task_id_t id = task_spawn(fname, argv); |
if (id == 0) |
printf("Error spawning %s\n", fname); |
return id; |
} |
int main(int argc, char *argv[]) |
{ |
task_exit_t texit; |
int retval; |
if (argc < 3) { |
usage(); |
return -1; |
} |
closeall(); |
stdin = fopen(argv[1], "r"); |
stdout = fopen(argv[1], "w"); |
stderr = fopen(argv[1], "w"); |
/* |
* FIXME: fopen() should actually detect that we are opening a console |
* and it should set line-buffering mode automatically. |
*/ |
setvbuf(stdout, NULL, _IOLBF, BUFSIZ); |
if ((stdin == NULL) |
|| (stdout == NULL) |
|| (stderr == NULL)) |
return -2; |
version_print(argv[1]); |
task_id_t id = spawn(argv[2]); |
task_wait(id, &texit, &retval); |
return 0; |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/getvc/version.c |
---|
0,0 → 1,67 |
/* |
* Copyright (c) 2009 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. |
*/ |
/** @addtogroup getvc |
* @{ |
*/ |
/** |
* @file |
*/ |
#include <unistd.h> |
#include <stdio.h> |
#include <macros.h> |
#include "getvc.h" |
#include "version.h" |
static char *release = STRING(RELEASE); |
static char *name = STRING(NAME); |
static char *arch = STRING(UARCH); |
#ifdef REVISION |
static char *revision = ", revision " STRING(REVISION); |
#else |
static char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
static char *timestamp = "\nBuilt on " STRING(TIMESTAMP); |
#else |
static char *timestamp = ""; |
#endif |
/** Print version information. */ |
void version_print(const char *vc) |
{ |
printf("HelenOS release %s (%s)%s%s\n", release, name, revision, timestamp); |
printf("Running on %s (%s)\n", arch, vc); |
printf("Copyright (c) 2001-2009 HelenOS project\n\n"); |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/getvc/version.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2009 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. |
*/ |
/** @addtogroup getvc |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef VERSION_H__ |
#define VERSION_H__ |
extern void version_print(const char *vc); |
#endif |
/** @} |
*/ |
/tags/0.4.1/uspace/app/getvc/Makefile |
---|
0,0 → 1,79 |
# |
# Copyright (c) 2009 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. |
# |
include ../../../version |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=$(RELEASE) "-DNAME=$(NAME)" |
## Sources |
# |
OUTPUT = getvc |
SOURCES = \ |
getvc.c \ |
version.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-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/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/tags/0.4.1/uspace/app/getvc/getvc.h |
---|
0,0 → 1,42 |
/* |
* Copyright (c) 2009 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. |
*/ |
/** @addtogroup getvc |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef GETVC_H__ |
#define GETVC_H__ |
#endif |
/** @} |
*/ |
/tags/0.4.1/uspace/app/klog/klog.c |
---|
0,0 → 1,96 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* 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 klog KLog |
* @brief HelenOS KLog |
* @{ |
*/ |
/** |
* @file |
*/ |
#include <stdio.h> |
#include <ipc/ipc.h> |
#include <async.h> |
#include <ipc/services.h> |
#include <as.h> |
#include <sysinfo.h> |
#include <event.h> |
#include <errno.h> |
#include <io/klog.h> |
#define NAME "klog" |
/* Pointer to klog area */ |
static wchar_t *klog; |
static size_t klog_length; |
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
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_length]); |
} |
int main(int argc, char *argv[]) |
{ |
size_t klog_pages = sysinfo_value("klog.pages"); |
size_t klog_size = klog_pages * PAGE_SIZE; |
klog_length = klog_size / sizeof(wchar_t); |
klog = (wchar_t *) 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 != EOK) { |
printf(NAME ": Error initializing memory area\n"); |
return -1; |
} |
if (event_subscribe(EVENT_KLOG, 0) != EOK) { |
printf(NAME ": Error registering klog notifications\n"); |
return -1; |
} |
async_set_interrupt_received(interrupt_received); |
klog_update(); |
async_manager(); |
return 0; |
} |
/** @} |
*/ |
/tags/0.4.1/uspace/app/klog/Makefile |
---|
0,0 → 1,76 |
# |
# 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 |
LIBS = $(LIBC_PREFIX)/libc.a |
## Sources |
# |
OUTPUT = klog |
SOURCES = \ |
klog.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
-include Makefile.depend |
clean: |
-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/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |