/branches/dynload/uspace/app/bdsh/input.c |
---|
32,10 → 32,10 |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <io/stream.h> |
#include <console.h> |
#include <kbd/kbd.h> |
#include <kbd/keycode.h> |
#include <io/console.h> |
#include <io/keycode.h> |
#include <io/style.h> |
#include <vfs/vfs.h> |
#include <errno.h> |
#include <bool.h> |
100,7 → 100,7 |
static void read_line(char *buffer, int n) |
{ |
kbd_event_t ev; |
console_event_t ev; |
size_t offs, otmp; |
wchar_t dec; |
107,11 → 107,12 |
offs = 0; |
while (true) { |
fflush(stdout); |
if (kbd_get_event(&ev) < 0) |
if (!console_get_event(fphone(stdin), &ev)) |
return; |
if (ev.type == KE_RELEASE) |
if (ev.type != KEY_PRESS) |
continue; |
if (ev.key == KC_ENTER || ev.key == KC_NENTER) |
break; |
if (ev.key == KC_BACKSPACE) { |
131,9 → 132,8 |
continue; |
} |
if (ev.c >= ' ') { |
//putchar(ev.c); |
if (chr_encode(ev.c, buffer, &offs, n - 1) == EOK) |
console_putchar(ev.c); |
putchar(ev.c); |
} |
} |
putchar('\n'); |
147,9 → 147,11 |
{ |
char line[INPUT_MAX]; |
console_set_style(STYLE_EMPHASIS); |
fflush(stdout); |
console_set_style(fphone(stdout), STYLE_EMPHASIS); |
printf("%s", usr->prompt); |
console_set_style(STYLE_NORMAL); |
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 */ |
/branches/dynload/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; |
} |
/branches/dynload/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 */ |
/branches/dynload/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 */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/bdd/bdd_def.h |
---|
0,0 → 1,7 |
{ |
"bdd", |
"Dump block device contents", |
&cmd_bdd, |
&help_cmd_bdd, |
}, |
/branches/dynload/uspace/app/bdsh/cmds/modules/kcon/kcon.c |
---|
30,7 → 30,8 |
#include <stdio.h> |
#include <stdlib.h> |
#include <console.h> |
#include <io/console.h> |
#include <vfs/vfs.h> |
#include "config.h" |
#include "util.h" |
#include "errors.h" |
65,7 → 66,7 |
return CMD_FAILURE; |
} |
console_kcon_enable(); |
console_kcon_enable(fphone(stdout)); |
return CMD_SUCCESS; |
} |
/branches/dynload/uspace/app/bdsh/cmds/modules/pwd/pwd.c |
---|
30,6 → 30,7 |
#include <stdio.h> |
#include <stdlib.h> |
#include <mem.h> |
#include "config.h" |
#include "errors.h" |
/branches/dynload/uspace/app/bdsh/cmds/modules/modules.h |
---|
20,6 → 20,7 |
#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" |
38,6 → 39,7 |
#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" |
/branches/dynload/uspace/app/bdsh/cmds/modules/cp/cp.c |
---|
172,7 → 172,8 |
int cmd_cp(char **argv) |
{ |
unsigned int argc, buffer = 0, verbose = 0; |
unsigned int argc, verbose = 0; |
int buffer = 0; |
int c, opt_ind; |
int64_t ret; |
/branches/dynload/uspace/app/bdsh/cmds/modules/mkdir/mkdir.c |
---|
37,6 → 37,7 |
#include <sys/stat.h> |
#include <getopt.h> |
#include <stdarg.h> |
#include <string.h> |
#include "config.h" |
#include "errors.h" |
/branches/dynload/uspace/app/bdsh/cmds/modules/ls/ls.c |
---|
50,48 → 50,9 |
static char *cmdname = "ls"; |
static inline off_t flen(const char *f) |
{ |
int fd; |
off_t size; |
fd = open(f, O_RDONLY); |
if (fd == -1) |
return 0; |
size = lseek(fd, 0, SEEK_END); |
close(fd); |
if (size < 0) |
size = 0; |
return size; |
} |
static unsigned int ls_scope(const char *path) |
{ |
int fd; |
DIR *dirp; |
dirp = opendir(path); |
if (dirp) { |
closedir(dirp); |
return LS_DIR; |
} |
fd = open(path, O_RDONLY); |
if (fd > 0) { |
close(fd); |
return LS_FILE; |
} |
return LS_BOGUS; |
} |
static void ls_scan_dir(const char *d, DIR *dirp) |
{ |
struct dirent *dp; |
unsigned int scope; |
char *buff; |
if (! dirp) |
108,20 → 69,7 |
/* Don't worry if inserting a double slash, this will be fixed by |
* absolutize() later with subsequent calls to open() or readdir() */ |
snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name); |
scope = ls_scope(buff); |
switch (scope) { |
case LS_DIR: |
ls_print_dir(dp->d_name); |
break; |
case LS_FILE: |
ls_print_file(dp->d_name, buff); |
break; |
case LS_BOGUS: |
/* Odd chance it was deleted from the time readdir() found |
* it and the time that it was scoped */ |
printf("ls: skipping bogus node %s\n", dp->d_name); |
break; |
} |
ls_print(dp->d_name, buff); |
} |
free(buff); |
129,7 → 77,7 |
return; |
} |
/* ls_print_* currently does nothing more than print the entry. |
/* 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. |
136,17 → 84,24 |
* |
* Now we just print basic DOS style lists */ |
static void ls_print_dir(const char *d) |
static void ls_print(const char *name, const char *pathname) |
{ |
printf("%-40s\t<dir>\n", d); |
struct stat s; |
int rc; |
return; |
} |
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); |
static void ls_print_file(const char *name, const char *pathname) |
{ |
printf("%-40s\t%llu\n", name, (long long) flen(pathname)); |
return; |
} |
166,7 → 121,7 |
int cmd_ls(char **argv) |
{ |
unsigned int argc; |
unsigned int scope; |
struct stat s; |
char *buff; |
DIR *dirp; |
184,19 → 139,17 |
else |
str_cpy(buff, PATH_MAX, argv[1]); |
scope = ls_scope(buff); |
switch (scope) { |
case LS_BOGUS: |
if (stat(buff, &s)) { |
cli_error(CL_ENOENT, buff); |
free(buff); |
return CMD_FAILURE; |
case LS_FILE: |
ls_print_file(buff, buff); |
break; |
case LS_DIR: |
} |
if (s.is_file) { |
ls_print(buff, buff); |
} else { |
dirp = opendir(buff); |
if (! dirp) { |
if (!dirp) { |
/* May have been deleted between scoping it and opening it */ |
cli_error(CL_EFAIL, "Could not stat %s", buff); |
free(buff); |
204,7 → 157,6 |
} |
ls_scan_dir(buff, dirp); |
closedir(dirp); |
break; |
} |
free(buff); |
/branches/dynload/uspace/app/bdsh/cmds/modules/ls/ls.h |
---|
6,11 → 6,8 |
#define LS_FILE 1 |
#define LS_DIR 2 |
static unsigned int ls_scope(const char *); |
static void ls_scan_dir(const char *, DIR *); |
static void ls_print_dir(const char *); |
static void ls_print_file(const char *, const char *); |
static void ls_print(const char *, const char *); |
#endif /* LS_H */ |
/branches/dynload/uspace/app/bdsh/cmds/modules/rm/rm.c |
---|
34,6 → 34,8 |
#include <fcntl.h> |
#include <dirent.h> |
#include <getopt.h> |
#include <mem.h> |
#include <string.h> |
#include "config.h" |
#include "errors.h" |
207,7 → 209,7 |
} |
} |
if (optind == argc) { |
if ((unsigned) optind == argc) { |
cli_error(CL_EFAIL, |
"%s: insufficient arguments. Try %s --help", cmdname, cmdname); |
rm_end(&rm); |
/branches/dynload/uspace/app/bdsh/util.c |
---|
53,14 → 53,6 |
* string */ |
unsigned int cli_set_prompt(cliuser_t *usr) |
{ |
usr->prompt = (char *) realloc(usr->prompt, PATH_MAX); |
if (NULL == usr->prompt) { |
cli_error(CL_ENOMEM, "Can not allocate prompt"); |
cli_errno = CL_ENOMEM; |
return 1; |
} |
memset(usr->prompt, 0, sizeof(usr->prompt)); |
usr->cwd = (char *) realloc(usr->cwd, PATH_MAX); |
if (NULL == usr->cwd) { |
cli_error(CL_ENOMEM, "Can not allocate cwd"); |
67,13 → 59,11 |
cli_errno = CL_ENOMEM; |
return 1; |
} |
memset(usr->cwd, 0, sizeof(usr->cwd)); |
usr->cwd = getcwd(usr->cwd, PATH_MAX - 1); |
if (NULL == usr->cwd) |
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; |
/branches/dynload/uspace/app/bdsh/exec.c |
---|
112,7 → 112,9 |
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); |
123,7 → 125,14 |
if (tid == 0) { |
cli_error(CL_EEXEC, "Cannot spawn `%s'.", cmd); |
return 1; |
} else { |
return 0; |
} |
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; |
} |
/branches/dynload/uspace/app/bdsh/Makefile |
---|
33,12 → 33,14 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
LIBBLOCK_PREFIX = ../../lib/libblock |
include $(LIBC_PREFIX)/Makefile.toolchain |
include $(LIBC_PREFIX)/Makefile.app |
CFLAGS += -I../../srv/kbd/include |
CFLAGS += -I../../srv/kbd/include -I$(LIBBLOCK_PREFIX) |
LIBS += $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=$(RELEASE) |
PROGRAM = bdsh |
51,6 → 53,7 |
cmds/modules/help/ \ |
cmds/modules/mkdir/ \ |
cmds/modules/rm/ \ |
cmds/modules/bdd/ \ |
cmds/modules/cat/ \ |
cmds/modules/touch/ \ |
cmds/modules/ls/ \ |
68,6 → 71,7 |
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 \ |
/branches/dynload/uspace/app/dload/dload.c |
---|
38,7 → 38,8 |
#include <unistd.h> |
#include <fcntl.h> |
#include <loader/pcb.h> |
#include <console.h> |
#include <ipc/ipc.h> |
#include <vfs/vfs.h> |
/* from librtld */ |
#include <rtld.h> |
107,7 → 108,7 |
DPRINTF("Run program.. (at 0x%lx)\n", (uintptr_t)__pcb->entry); |
#ifndef RTLD_DEBUG |
console_close(); |
ipc_hangup(fphone(stdout)); |
#endif |
program_run(__pcb->entry, __pcb); |
/branches/dynload/uspace/app/init/version.c |
---|
File deleted |
/branches/dynload/uspace/app/init/version.h |
---|
File deleted |
/branches/dynload/uspace/app/init/init.c |
---|
41,41 → 41,87 |
#include <bool.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <sys/stat.h> |
#include <task.h> |
#include <malloc.h> |
#include <macros.h> |
#include <console.h> |
#include <string.h> |
#include <devmap.h> |
#include <config.h> |
#include "init.h" |
#include "version.h" |
static bool mount_fs(const char *fstype) |
static void info_print(void) |
{ |
int rc = -1; |
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; |
} |
while (rc < 0) { |
rc = mount(fstype, "/", "initrd", opts, IPC_FLAG_BLOCKING); |
switch (rc) { |
case EOK: |
printf(NAME ": Root filesystem mounted\n"); |
break; |
case EBUSY: |
printf(NAME ": Root filesystem already mounted\n"); |
break; |
case ELIMIT: |
printf(NAME ": Unable to mount root filesystem\n"); |
return false; |
case ENOENT: |
printf(NAME ": Unknown filesystem type (%s)\n", fstype); |
return false; |
} |
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; |
} |
82,7 → 128,11 |
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; |
92,28 → 142,127 |
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_fs(STRING(RDFMT))) { |
if (!mount_root(STRING(RDFMT))) { |
printf(NAME ": Exiting\n"); |
return -1; |
} |
// FIXME: spawn("/srv/pci"); |
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"); |
console_wait(); |
version_print(); |
spawn("/app/klog"); |
spawn("/app/bdsh"); |
return 0; |
} |
/branches/dynload/uspace/app/init/init.h |
---|
28,7 → 28,7 |
/** @addtogroup init |
* @{ |
*/ |
*/ |
/** |
* @file |
*/ |
36,10 → 36,11 |
#ifndef __INIT_H__ |
#define __INIT_H__ |
#define NAME "init" |
#define NAME "init" |
#define MAX_DEVICE_NAME 32 |
#endif |
/** @} |
*/ |
/branches/dynload/uspace/app/init/Makefile |
---|
26,8 → 26,6 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
include ../../../version |
## Setup toolchain |
# |
36,10 → 34,8 |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
CFLAGS += -I../../.. |
LIBS = $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=$(RELEASE) |
## Sources |
# |
46,8 → 42,7 |
OUTPUT = init |
SOURCES = \ |
init.c \ |
version.c |
init.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
69,7 → 64,7 |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dynload/uspace/app/tester/devmap/devmap1.c |
---|
File deleted |
/branches/dynload/uspace/app/tester/devmap/devmap1.def |
---|
File deleted |
/branches/dynload/uspace/app/tester/console/console1.c |
---|
28,12 → 28,13 |
#include <stdio.h> |
#include <stdlib.h> |
#include <io/stream.h> |
#include <io/console.h> |
#include <io/color.h> |
#include <io/style.h> |
#include <vfs/vfs.h> |
#include <async.h> |
#include "../tester.h" |
#include <console.h> |
const char *color_name[] = { |
[COLOR_BLACK] = "black", |
[COLOR_BLUE] = "blue", |
45,65 → 46,78 |
[COLOR_WHITE] = "white" |
}; |
char * test_console1(bool quiet) |
char *test_console1(void) |
{ |
int i, j; |
printf("Style test: "); |
console_set_style(STYLE_NORMAL); |
printf("normal "); |
console_set_style(STYLE_EMPHASIS); |
printf("emphasized"); |
console_set_style(STYLE_NORMAL); |
printf(".\n"); |
printf("Foreground color test:\n"); |
for (j = 0; j < 2; j++) { |
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) { |
console_set_color(i, COLOR_WHITE, |
j ? CATTR_BRIGHT : 0); |
printf(" %s ", color_name[i]); |
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'); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
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'); |
} |
printf("Background color test:\n"); |
for (j = 0; j < 2; j++) { |
for (i = COLOR_BLACK; i <= COLOR_WHITE; i++) { |
console_set_color(COLOR_WHITE, i, |
j ? CATTR_BRIGHT : 0); |
printf(" %s ", color_name[i]); |
for (i = 0; i < 255; i += 16) { |
fflush(stdout); |
console_set_rgb_color(fphone(stdout), 0xffffff, i << 8); |
putchar('X'); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
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'); |
} |
printf("Now let's test RGB colors:\n"); |
for (i = 0; i < 255; i += 16) { |
console_set_rgb_color(0xffffff, i << 16); |
putchar('X'); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
for (i = 0; i < 255; i += 16) { |
console_set_rgb_color(0xffffff, i << 8); |
putchar('X'); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
for (i = 0; i < 255; i += 16) { |
console_set_rgb_color(0xffffff, i); |
putchar('X'); |
} |
console_set_color(COLOR_BLACK, COLOR_WHITE, 0); |
putchar('\n'); |
printf("[press a key]\n"); |
getchar(); |
return NULL; |
} |
/branches/dynload/uspace/app/tester/stdio/stdio1.c |
---|
31,55 → 31,60 |
#include <errno.h> |
#include "../tester.h" |
#define BUF_SIZE 32 |
#define BUF_SIZE 32 |
static char buf[BUF_SIZE + 1]; |
char * test_stdio1(bool quiet) |
char *test_stdio1(void) |
{ |
FILE *f; |
FILE *file; |
char *file_name = "/readme"; |
size_t n; |
int c; |
printf("Open file '%s'\n", file_name); |
TPRINTF("Open file \"%s\"...", file_name); |
errno = 0; |
f = fopen(file_name, "rt"); |
if (f == NULL) printf("errno = %d\n", errno); |
if (f == NULL) |
return "Failed opening file."; |
n = fread(buf, 1, BUF_SIZE, f); |
if (ferror(f)) { |
fclose(f); |
return "Failed reading file."; |
} |
printf("Read %d bytes.\n", n); |
buf[n] = '\0'; |
printf("Read string '%s'.\n", buf); |
printf("Seek to beginning.\n"); |
if (fseek(f, 0, SEEK_SET) != 0) { |
fclose(f); |
return "Failed seeking."; |
} |
printf("Read using fgetc().\n"); |
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) { |
c = fgetc(f); |
if (c == EOF) break; |
printf("'%c'", c); |
int c = fgetc(file); |
if (c == EOF) |
break; |
TPRINTF("."); |
} |
printf("[EOF]\n"); |
printf("Closing.\n"); |
if (fclose(f) != 0) |
return "Failed closing."; |
TPRINTF("[EOF]\n"); |
TPRINTF("Close..."); |
if (fclose(file) != 0) { |
TPRINTF("errno = %d\n", errno); |
return "Failed closing file"; |
} else |
TPRINTF("OK\n"); |
return NULL; |
} |
/branches/dynload/uspace/app/tester/stdio/stdio2.c |
---|
31,39 → 31,53 |
#include <errno.h> |
#include "../tester.h" |
char * test_stdio2(bool quiet) |
char *test_stdio2(void) |
{ |
FILE *f; |
FILE *file; |
char *file_name = "/test"; |
size_t n; |
int c; |
printf("Open file '%s' for writing\n", file_name); |
TPRINTF("Open file \"%s\" for writing...", file_name); |
errno = 0; |
f = fopen(file_name, "wt"); |
if (f == NULL) |
return "Failed opening file."; |
fprintf(f, "Integer: %d, string: '%s'\n", 42, "Hello!"); |
if (fclose(f) != 0) |
return "Failed closing file."; |
printf("Open file '%s' for reading\n", file_name); |
f = fopen(file_name, "rt"); |
if (f == NULL) |
return "Failed opening file."; |
printf("File contains:\n"); |
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) { |
c = fgetc(f); |
if (c == EOF) break; |
putchar(c); |
int c = fgetc(file); |
if (c == EOF) |
break; |
TPRINTF("%c", c); |
} |
if (fclose(f) != 0) |
return "Failed closing file."; |
TPRINTF("\nClose..."); |
if (fclose(file) != 0) { |
TPRINTF("errno = %d\n", errno); |
return "Failed closing file"; |
} else |
TPRINTF("OK\n"); |
return NULL; |
} |
/branches/dynload/uspace/app/tester/tester.c |
---|
27,10 → 27,10 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup tester User space Tester |
* @brief User space testing infrastructure. |
/** @addtogroup tester User space tester |
* @brief User space testing infrastructure. |
* @{ |
*/ |
*/ |
/** |
* @file |
*/ |
37,48 → 37,44 |
#include <unistd.h> |
#include <stdio.h> |
#include <string.h> |
#include "tester.h" |
int myservice = 0; |
int phones[MAX_PHONES]; |
int connections[MAX_CONNECTIONS]; |
ipc_callid_t callids[MAX_CONNECTIONS]; |
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 "ipc/send_async.def" |
#include "ipc/send_sync.def" |
#include "ipc/answer.def" |
#include "ipc/hangup.def" |
#include "ipc/ping_pong.def" |
#include "devmap/devmap1.def" |
#include "loop/loop1.def" |
#include "vfs/vfs1.def" |
#include "console/console1.def" |
#include "stdio/stdio1.def" |
#include "stdio/stdio2.def" |
{NULL, NULL, NULL} |
#include "mm/malloc1.def" |
{NULL, NULL, NULL, false} |
}; |
static bool run_test(test_t *test) |
{ |
printf("%s\t\t%s\n", test->name, test->desc); |
/* Execute the test */ |
char * ret = test->entry(false); |
char *ret = test->entry(); |
if (ret == NULL) { |
printf("Test passed\n\n"); |
printf("\nTest passed\n"); |
return true; |
} |
printf("%s\n\n", ret); |
printf("\n%s\n", ret); |
return false; |
} |
87,11 → 83,12 |
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 |
98,63 → 95,52 |
n++; |
} |
} |
printf("\nSafe tests completed, %u tests run, %u passed.\n\n", i + n, i); |
printf("\nCompleted, %u tests run, %u passed.\n", i + n, i); |
} |
static void list_tests(void) |
{ |
size_t len = 0; |
test_t *test; |
char c = 'a'; |
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++, c++) |
printf("%c\t%s\t\t%s%s\n", c, test->name, test->desc, (test->safe ? "" : " (unsafe)")); |
for (test = tests; test->name != NULL; test++) |
printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)")); |
printf("*\t\t\tRun all safe tests\n"); |
printf("%-*s Run all safe tests\n", len, "*"); |
} |
int main(int argc, char **argv) |
int main(int argc, char *argv[]) |
{ |
printf("Number of arguments: %d\n", argc); |
if (argv) { |
printf("Arguments:"); |
while (*argv) { |
printf(" '%s'", *argv++); |
} |
printf("\n"); |
if (argc < 2) { |
printf("Usage:\n\n"); |
printf("%s <test> [args ...]\n\n", argv[0]); |
list_tests(); |
return 0; |
} |
while (1) { |
char c; |
test_t *test; |
list_tests(); |
printf("> "); |
c = getchar(); |
printf("%c\n", c); |
if ((c >= 'a') && (c <= 'z')) { |
for (test = tests; test->name != NULL; test++, c--) |
if (c == 'a') |
break; |
if (test->name == NULL) |
printf("Unknown test\n\n"); |
else |
run_test(test); |
} else if (c == '*') { |
run_safe_tests(); |
} else if (c < 0) { |
/* got EOF */ |
break; |
} else { |
printf("Invalid test\n\n"); |
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); |
} |
} |
return 0; |
printf("Unknown test \"%s\"\n", argv[1]); |
return -2; |
} |
/** @} |
/branches/dynload/uspace/app/tester/thread/thread1.c |
---|
27,7 → 27,8 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#define THREADS 5 |
#define THREADS 20 |
#define DELAY 10 |
#include <atomic.h> |
#include <thread.h> |
37,45 → 38,42 |
static atomic_t finish; |
static atomic_t threads_finished; |
static bool sh_quiet; |
static void threadtest(void *data) |
{ |
thread_detach(thread_get_id()); |
while (atomic_get(&finish)) { |
if (!sh_quiet) |
printf("%llu ", thread_get_id()); |
while (atomic_get(&finish)) |
usleep(100000); |
} |
atomic_inc(&threads_finished); |
} |
char * test_thread1(bool quiet) |
char *test_thread1(void) |
{ |
unsigned int i, total = 0; |
sh_quiet = quiet; |
unsigned int i; |
int total = 0; |
atomic_set(&finish, 1); |
atomic_set(&threads_finished, 0); |
for (i = 0; i < THREADS; i++) { |
TPRINTF("Creating threads"); |
for (i = 0; i < THREADS; i++) { |
if (thread_create(threadtest, NULL, "threadtest", NULL) < 0) { |
if (!quiet) |
printf("Could not create thread %d\n", i); |
TPRINTF("\nCould not create thread %u\n", i); |
break; |
} |
TPRINTF("."); |
total++; |
} |
if (!quiet) |
printf("Running threads for 10 seconds...\n"); |
sleep(10); |
TPRINTF("\nRunning threads for %u seconds...", DELAY); |
sleep(DELAY); |
TPRINTF("\n"); |
atomic_set(&finish, 0); |
while (atomic_get(&threads_finished) < total) { |
if (!quiet) |
printf("Threads left: %d\n", total - atomic_get(&threads_finished)); |
TPRINTF("Threads left: %u\n", total - atomic_get(&threads_finished)); |
sleep(1); |
} |
/branches/dynload/uspace/app/tester/loop/loop1.c |
---|
30,12 → 30,11 |
#include <stdlib.h> |
#include "../tester.h" |
char *test_loop1(bool quiet) |
char *test_loop1(void) |
{ |
printf("Looping...\n"); |
while (1); |
printf("Survived endless loop?!!\n"); |
return NULL; |
TPRINTF("Looping..."); |
while (true); |
TPRINTF("\n"); |
return "Survived endless loop"; |
} |
/branches/dynload/uspace/app/tester/mm/malloc1.def |
---|
0,0 → 1,6 |
{ |
"malloc1", |
"Memory allocator test", |
&test_malloc1, |
true |
}, |
/branches/dynload/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; |
} |
/branches/dynload/uspace/app/tester/fault/fault1.c |
---|
29,7 → 29,7 |
#include "../tester.h" |
char * test_fault1(bool quiet) |
char *test_fault1(void) |
{ |
((int *)(0))[1] = 0; |
/branches/dynload/uspace/app/tester/fault/fault2.c |
---|
29,7 → 29,7 |
#include "../tester.h" |
char * test_fault2(bool quiet) |
char *test_fault2(void) |
{ |
volatile long long var; |
volatile int var1; |
/branches/dynload/uspace/app/tester/ipc/send_sync.def |
---|
File deleted |
/branches/dynload/uspace/app/tester/ipc/answer.def |
---|
File deleted |
/branches/dynload/uspace/app/tester/ipc/send_async.def |
---|
File deleted |
/branches/dynload/uspace/app/tester/ipc/answer.c |
---|
File deleted |
/branches/dynload/uspace/app/tester/ipc/hangup.def |
---|
File deleted |
/branches/dynload/uspace/app/tester/ipc/send_async.c |
---|
File deleted |
/branches/dynload/uspace/app/tester/ipc/send_sync.c |
---|
File deleted |
/branches/dynload/uspace/app/tester/ipc/hangup.c |
---|
File deleted |
/branches/dynload/uspace/app/tester/ipc/ping_pong.c |
---|
28,41 → 28,51 |
#include <stdio.h> |
#include <stdlib.h> |
#include <console.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 |
#define DURATION_SECS 10 |
#define COUNT_GRANULARITY 100 |
char * test_ping_pong(bool quiet) |
char *test_ping_pong(void) |
{ |
int i; |
int w, h; |
struct timeval start, now; |
long count; |
printf("Pinging console server for %d seconds...\n", DURATION_SECS); |
if (gettimeofday(&start, NULL) != 0) |
return "Failed getting the time."; |
count = 0; |
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) { |
if (gettimeofday(&now, NULL) != 0) |
return "Failed getting the time."; |
struct timeval now; |
if (gettimeofday(&now, NULL) != 0) { |
TPRINTF("\n"); |
return "Failed getting the time"; |
} |
if (tv_sub(&now, &start) >= DURATION_SECS * 1000000L) |
break; |
for (i = 0; i < COUNT_GRANULARITY; i++) |
console_get_size(&w, &h); |
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; |
} |
printf("Completed %ld round trips in %d seconds, %ld RT/s.\n", count, |
DURATION_SECS, count / DURATION_SECS); |
TPRINTF("OK\nCompleted %llu round trips in %u seconds, %llu rt/s.\n", |
count, DURATION_SECS, count / DURATION_SECS); |
return NULL; |
} |
/branches/dynload/uspace/app/tester/ipc/register.c |
---|
32,58 → 32,58 |
#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) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
ipcarg_t phonehash = icall->in_phone_hash; |
int retval; |
int i; |
printf("Connected phone: %P, accepting\n", icall->in_phone_hash); |
unsigned int i; |
TPRINTF("Connected phone %#x accepting\n", icall->in_phone_hash); |
ipc_answer_0(iid, EOK); |
for (i = 0; i < 1024; i++) |
for (i = 0; i < MAX_CONNECTIONS; i++) { |
if (!connections[i]) { |
connections[i] = phonehash; |
connections[i] = icall->in_phone_hash; |
break; |
} |
} |
while (1) { |
callid = async_get_call(&call); |
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: |
printf("Phone (%P) hung up.\n", phonehash); |
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: |
printf("Received message from %P: %X\n", phonehash, |
callid); |
for (i = 0; i < 1024; i++) |
if (!callids[i]) { |
callids[i] = callid; |
break; |
} |
continue; |
TPRINTF("Received unknown message from %#x: %#x\n", |
icall->in_phone_hash, callid); |
ipc_answer_0(callid, ENOENT); |
break; |
} |
ipc_answer_0(callid, retval); |
} |
} |
char * test_register(bool quiet) |
char *test_register(void) |
{ |
int i; |
async_set_client_connection(client_connection); |
for (i = IPC_TEST_START; i < IPC_TEST_START + 10; i++) { |
ipcarg_t phonead; |
int res = ipc_connect_to_me(PHONE_NS, i, 0, 0, &phonead); |
if (!res) |
break; |
printf("Failed registering as %d..:%d\n", i, res); |
} |
printf("Registered as service: %d\n", i); |
myservice = i; |
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; |
} |
/branches/dynload/uspace/app/tester/ipc/connect.c |
---|
28,32 → 28,46 |
#include <stdio.h> |
#include <unistd.h> |
#include <atomic.h> |
#include "../tester.h" |
char * test_connect(bool quiet) |
static atomic_t finish; |
static void callback(void *priv, int retval, ipc_call_t *data) |
{ |
char c; |
int svc; |
int phid; |
atomic_set(&finish, 1); |
} |
printf("Choose one service: 0:10000....9:10009 (q to skip)\n"); |
do { |
c = getchar(); |
if ((c == 'Q') || (c == 'q')) |
return TEST_SKIPPED; |
} while (c < '0' || c > '9'); |
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"; |
} |
svc = IPC_TEST_START + c - '0'; |
if (svc == myservice) |
return "Currently cannot connect to myself, update test"; |
printf("Sending synchronous message...\n"); |
int retval = ipc_call_sync_0_0(phone, IPC_TEST_METHOD); |
TPRINTF("Received response to synchronous message\n"); |
printf("Connecting to %d..", svc); |
phid = ipc_connect_me_to(PHONE_NS, svc, 0, 0); |
if (phid > 0) { |
printf("phoneid: %d\n", phid); |
phones[phid] = 1; |
} else |
return "Error"; |
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; |
} |
/branches/dynload/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; |
} |
/branches/dynload/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; |
} |
/branches/dynload/uspace/app/tester/print/print4.c |
---|
30,63 → 30,54 |
#include <unistd.h> |
#include "../tester.h" |
#define PRIx8 "x" |
char *test_print4(bool quiet) |
char *test_print4(void) |
{ |
if (!quiet) { |
printf("ASCII printable characters (32 - 127) using printf(\"%%c\") and printf(\"%%lc\"):\n"); |
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 group; |
for (group = 1; group < 4; group++) { |
printf("%#" PRIx8 ": ", group << 5); |
uint8_t index; |
for (index = 0; index < 32; index++) |
printf("%c", (char) ((group << 5) + index)); |
printf(" "); |
for (index = 0; index < 32; index++) |
printf("%lc", (wchar_t) ((group << 5) + index)); |
printf("\n"); |
} |
uint8_t index; |
for (index = 0; index < 32; index++) |
TPRINTF("%c", (char) ((group << 5) + index)); |
printf("\nExtended ASCII characters (128 - 255) using printf(\"%%lc\"):\n"); |
TPRINTF(" "); |
for (index = 0; index < 32; index++) |
TPRINTF("%lc", (wchar_t) ((group << 5) + index)); |
for (group = 4; group < 8; group++) { |
printf("%#" PRIx8 ": ", group << 5); |
uint8_t index; |
for (index = 0; index < 32; index++) |
printf("%lc", (wchar_t) ((group << 5) + index)); |
printf("\n"); |
} |
TPRINTF("\n"); |
} |
TPRINTF("\nExtended ASCII characters (128 - 255) using printf(\"%%lc\"):\n"); |
for (group = 4; group < 8; group++) { |
TPRINTF("%#x: ", group << 5); |
printf("\nUTF-8 strings using printf(\"%%s\"):\n"); |
printf("English: %s\n", "Quick brown fox jumps over the lazy dog"); |
printf("Czech: %s\n", "Příliš žluťoučký kůň úpěl ďábelské ódy"); |
printf("Greek: %s\n", "Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε"); |
printf("Hebrew: %s\n", "משוואת ברנולי היא משוואה בהידרודינמיקה"); |
printf("Arabic: %s\n", "التوزيع الجغرافي للحمل العنقودي"); |
printf("Russian: %s\n", "Леннон познакомился с художницей-авангардисткой"); |
printf("Armenian: %s\n", "Սկսեց հրատարակվել Երուսաղեմի հայկական"); |
uint8_t index; |
for (index = 0; index < 32; index++) |
TPRINTF("%lc", (wchar_t) ((group << 5) + index)); |
printf("\nUTF-32 strings using printf(\"%%ls\"):\n"); |
printf("English: %ls\n", L"Quick brown fox jumps over the lazy dog"); |
printf("Czech: %ls\n", L"Příliš žluťoučký kůň úpěl ďábelské ódy"); |
printf("Greek: %ls\n", L"Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε"); |
printf("Hebrew: %ls\n", L"משוואת ברנולי היא משוואה בהידרודינמיקה"); |
printf("Arabic: %ls\n", L"التوزيع الجغرافي للحمل العنقودي"); |
printf("Russian: %ls\n", L"Леннон познакомился с художницей-авангардисткой"); |
printf("Armenian: %ls\n", L"Սկսեց հրատարակվել Երուսաղեմի հայկական"); |
printf("Test: [%d] '%lc'\n", L'\x0161', L'\x0161'); |
TPRINTF("\n"); |
} |
printf("[Press a key]\n"); |
getchar(); |
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; |
} |
/branches/dynload/uspace/app/tester/print/print1.def |
---|
1,6 → 1,6 |
{ |
"print1", |
"Printf test", |
"String printf test", |
&test_print1, |
true |
}, |
/branches/dynload/uspace/app/tester/print/print2.def |
---|
0,0 → 1,6 |
{ |
"print2", |
"Numeric printf test", |
&test_print2, |
true |
}, |
/branches/dynload/uspace/app/tester/print/print3.def |
---|
0,0 → 1,6 |
{ |
"print3", |
"Buffered printf test", |
&test_print3, |
true |
}, |
/branches/dynload/uspace/app/tester/print/print1.c |
---|
30,44 → 30,27 |
#include <unistd.h> |
#include "../tester.h" |
#define BUFFER_SIZE 32 |
char * test_print1(bool quiet) |
char *test_print1(void) |
{ |
if (!quiet) { |
int retval; |
unsigned int nat = 0x12345678u; |
char buffer[BUFFER_SIZE]; |
printf(" text 10.8s %*.*s \n", 5, 3, "text"); |
printf(" very long text 10.8s %10.8s \n", "very long text"); |
printf(" text 8.10s %8.10s \n", "text"); |
printf(" very long text 8.10s %8.10s \n", "very long text"); |
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n",'a', 'b', 'c', 'd', 'e' ); |
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",1, 1, 1, 1, 1 ); |
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",-1, -1, -1, -1, -1 ); |
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n",17, 17, 17, 17, 17 ); |
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#zx'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" ); |
printf(" Print to NULL '%s'\n", NULL); |
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters."); |
printf("Result is: '%s', retval = %d\n", buffer, retval); |
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters."); |
printf("Result is: '%s', retval = %d\n", buffer, retval); |
printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE); |
retval = snprintf(buffer, BUFFER_SIZE, "Short %s", "text"); |
printf("Result is: '%s', retval = %d\n", buffer, retval); |
printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE); |
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); |
printf("Result is: '%s', retval = %d\n", buffer, retval); |
} |
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; |
} |
/branches/dynload/uspace/app/tester/tester.h |
---|
39,43 → 39,45 |
#include <bool.h> |
#include <ipc/ipc.h> |
#define IPC_TEST_START 10000 |
#define MAX_PHONES 20 |
#define MAX_CONNECTIONS 50 |
#define TEST_SKIPPED "Test Skipped" |
#define IPC_TEST_SERVICE 10240 |
#define IPC_TEST_METHOD 2000 |
extern int myservice; |
extern int phones[MAX_PHONES]; |
extern int connections[MAX_CONNECTIONS]; |
extern ipc_callid_t callids[MAX_CONNECTIONS]; |
extern bool test_quiet; |
extern int test_argc; |
extern char **test_argv; |
typedef char * (* test_entry_t)(bool); |
#define TPRINTF(format, ...) \ |
{ \ |
if (!test_quiet) { \ |
fprintf(stderr, format, ##__VA_ARGS__); \ |
} \ |
} |
typedef char *(*test_entry_t)(void); |
typedef struct { |
char * name; |
char * desc; |
char *name; |
char *desc; |
test_entry_t entry; |
bool safe; |
} test_t; |
extern char * test_thread1(bool quiet); |
extern char * test_print1(bool quiet); |
extern char * test_print4(bool quiet); |
extern char * test_fault1(bool quiet); |
extern char * test_fault2(bool quiet); |
extern char * test_register(bool quiet); |
extern char * test_connect(bool quiet); |
extern char * test_send_async(bool quiet); |
extern char * test_send_sync(bool quiet); |
extern char * test_answer(bool quiet); |
extern char * test_hangup(bool quiet); |
extern char * test_ping_pong(bool quiet); |
extern char * test_devmap1(bool quiet); |
extern char * test_loop1(bool quiet); |
extern char * test_vfs1(bool quiet); |
extern char * test_console1(bool quiet); |
extern char * test_stdio1(bool quiet); |
extern char * test_stdio2(bool quiet); |
extern 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[]; |
/branches/dynload/uspace/app/tester/Makefile |
---|
44,22 → 44,20 |
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 \ |
ipc/send_async.c \ |
ipc/send_sync.c \ |
ipc/answer.c \ |
ipc/hangup.c \ |
ipc/ping_pong.c \ |
loop/loop1.c \ |
devmap/devmap1.c \ |
console/console1.c \ |
stdio/stdio1.c \ |
stdio/stdio2.c \ |
vfs/vfs1.c |
mm/malloc1.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
81,7 → 79,7 |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dynload/uspace/app/tester/vfs/vfs1.c |
---|
34,109 → 34,118 |
#include <unistd.h> |
#include <fcntl.h> |
#include <dirent.h> |
#include <devmap.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include "../tester.h" |
char text[] = "O xein', angellein Lakedaimoniois hoti teide " |
"keimetha tois keinon rhemasi peithomenoi."; |
#define FS_TYPE "tmpfs" |
#define MOUNT_POINT "/tmp" |
#define OPTIONS "" |
#define FLAGS 0 |
char *test_vfs1(bool quiet) |
#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) |
{ |
int rc; |
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; |
} |
rc = mount("tmpfs", "/", "nulldev0", "", 0); |
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: |
if (!quiet) |
printf("mounted tmpfs on /\n"); |
TPRINTF("Mounted /dev/%s as %s on %s\n", null, FS_TYPE, MOUNT_POINT); |
break; |
case EBUSY: |
if (!quiet) |
printf("(INFO) something is already mounted on /\n"); |
TPRINTF("(INFO) Filesystem already mounted on %s\n", MOUNT_POINT); |
break; |
default: |
if (!quiet) |
printf("(INFO) IPC returned errno %d\n", rc); |
return "mount() failed."; |
TPRINTF("(ERR) IPC returned errno %d (is tmpfs loaded?)\n", rc); |
return "mount() failed"; |
} |
if (mkdir("/mydir", 0) != 0) |
return "mkdir() failed.\n"; |
if (!quiet) |
printf("created directory /mydir\n"); |
int fd0 = open("/mydir/myfile", O_CREAT); |
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.\n"; |
if (!quiet) |
printf("created file /mydir/myfile, fd=%d\n", fd0); |
ssize_t cnt; |
return "open() failed"; |
TPRINTF("Created file %s (fd=%d)\n", TEST_FILE, fd0); |
size_t size = sizeof(text); |
cnt = write(fd0, text, size); |
ssize_t cnt = write(fd0, text, size); |
if (cnt < 0) |
return "write() failed.\n"; |
if (!quiet) |
printf("written %d bytes, fd=%d\n", cnt, fd0); |
return "write() failed"; |
TPRINTF("Written %d bytes\n", cnt); |
if (lseek(fd0, 0, SEEK_SET) != 0) |
return "lseek() failed.\n"; |
if (!quiet) |
printf("sought to position 0, fd=%d\n", fd0); |
char buf[10]; |
while ((cnt = read(fd0, buf, sizeof(buf)))) { |
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.\n"; |
if (!quiet) |
printf("read %d bytes: \"%.*s\", fd=%d\n", cnt, cnt, |
buf, fd0); |
return "read() failed"; |
TPRINTF("Read %d bytes: \".*s\"\n", cnt, cnt, buf); |
} |
close(fd0); |
DIR *dirp; |
struct dirent *dp; |
if (!quiet) |
printf("scanning the root directory...\n"); |
dirp = opendir("/"); |
if (!dirp) |
return "opendir() failed\n"; |
while ((dp = readdir(dirp))) |
printf("discovered node %s in /\n", dp->d_name); |
closedir(dirp); |
if (rename("/mydir/myfile", "/mydir/yourfile")) |
return "rename() failed.\n"; |
if (!quiet) |
printf("renamed /mydir/myfile to /mydir/yourfile\n"); |
if (unlink("/mydir/yourfile")) |
return "unlink() failed.\n"; |
if (!quiet) |
printf("unlinked file /mydir/yourfile\n"); |
if (rmdir("/mydir")) |
return "rmdir() failed.\n"; |
if (!quiet) |
printf("removed directory /mydir\n"); |
char *rv = read_root(); |
if (rv != NULL) |
return rv; |
if (!quiet) |
printf("scanning the root directory...\n"); |
dirp = opendir("/"); |
if (!dirp) |
return "opendir() failed\n"; |
while ((dp = readdir(dirp))) |
printf("discovered node %s in /\n", dp->d_name); |
closedir(dirp); |
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; |
} |
/branches/dynload/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; |
} |
/** @} |
*/ |
/branches/dynload/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"); |
} |
/** @} |
*/ |
/branches/dynload/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 |
/** @} |
*/ |
/branches/dynload/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 $@ |
/branches/dynload/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 |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/pathnames.h |
---|
File deleted |
/branches/dynload/uspace/app/tetris/scores.c |
---|
36,7 → 36,7 |
*/ |
/** @addtogroup tetris |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
48,24 → 48,18 |
* |
* Major whacks since then. |
*/ |
#include <errno.h> |
/* #include <err.h> */ |
/* #include <fcntl.h> */ |
/* #include <pwd.h> */ |
#include <stdio.h> |
/* #include <stdlib.h> */ |
#include <string.h> |
#include <kbd/kbd.h> |
#include <kbd/keycode.h> |
#include <io/console.h> |
#include <io/keycode.h> |
#include <vfs/vfs.h> |
#include <stdlib.h> |
/* #include <time.h> */ |
/* #include <term.h> */ |
/* #include <unistd.h> */ |
/* #include <sys/param.h> */ |
/* #include <sys/stat.h> */ |
/* #include <sys/types.h> */ |
#include <fcntl.h> |
#include <err.h> |
#include <time.h> |
#include "pathnames.h" |
#include "screen.h" |
#include "tetris.h" |
#include "scores.h" |
78,20 → 72,22 |
* 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 time_t now; */ |
/* static int nscores; */ |
/* static int gotscores; */ |
/* static struct highscore scores[NUMSPOTS]; */ |
#define NUMSPOTS (MAXHISCORES + 1) |
#define NLEVELS (MAXLEVEL + 1) |
static struct highscore scores[NUMSPOTS]; |
/* static int checkscores(struct highscore *, int); */ |
/* static int cmpscores(const void *, const void *); */ |
/* static void getscores(FILE **); */ |
/* static void printem(int, int, struct highscore *, int, const char *); */ |
/* static char *thisuser(void); */ |
/** 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) |
{ |
101,59 → 97,55 |
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); |
} |
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("\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(); |
} |
/** 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 insertscore(int score, int level) |
{ |
int i,j; |
int i; |
int j; |
size_t off; |
kbd_event_t ev; |
console_event_t ev; |
clear_screen(); |
moveto(10 , 10); |
moveto(10, 10); |
puts("Insert your name: "); |
str_cpy(scores[NUMSPOTS - 1].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, |
"Player"); |
i = 6; off = 6; |
i = 6; |
off = 6; |
moveto(10 , 28); |
printf("%s%.*s",scores[NUMSPOTS - 1].hs_name,MAXLOGNAME-i,"........................................"); |
printf("%s%.*s", scores[NUMSPOTS - 1].hs_name, MAXLOGNAME-i, |
"........................................"); |
while (1) { |
fflush(stdout); |
if (kbd_get_event(&ev) != EOK) |
if (!console_get_event(fphone(stdin), &ev)) |
exit(1); |
if (ev.type == KE_RELEASE) |
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; |
163,7 → 155,7 |
if (uc != U_SPECIAL) |
break; |
} |
scores[NUMSPOTS - 1].hs_name[off] = '\0'; |
} |
} else if (ev.c != '\0') { |
176,398 → 168,66 |
} |
} |
moveto(10 , 28); |
printf("%s%.*s",scores[NUMSPOTS - 1].hs_name,MAXLOGNAME-i,"........................................"); |
moveto(10, 28); |
printf("%s%.*s", scores[NUMSPOTS - 1].hs_name, MAXLOGNAME - i, |
"........................................"); |
} |
scores[NUMSPOTS - 1].hs_score = score; |
scores[NUMSPOTS - 1].hs_score = score; |
scores[NUMSPOTS - 1].hs_level = level; |
i = NUMSPOTS-1; |
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); |
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++) { |
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); |
scores[i].hs_score = (NUMSPOTS - i) * 200; |
scores[i].hs_level = (i + 1 > MAXLEVEL ? MAXLEVEL : i + 1); |
} |
} |
/* |
* Read the score file. Can be called from savescore (before showscores) |
* or showscores (if savescore will not be called). If the given pointer |
* is not NULL, sets *fpp to an open file pointer that corresponds to a |
* read/write score file that is locked with LOCK_EX. Otherwise, the |
* file is locked with LOCK_SH for the read and closed before return. |
* |
* Note, we assume closing the stdio file releases the lock. |
*/ |
/* static void */ |
/* getscores(FILE **fpp) */ |
/* { */ |
/* int sd, mint, lck, mask, i; */ |
/* char *mstr, *human; */ |
/* FILE *sf; */ |
int loadscores(void) |
{ |
FILE *f; |
size_t cnt; |
int rc; |
/* if (fpp != NULL) { */ |
/* mint = O_RDWR | O_CREAT; */ |
/* mstr = "r+"; */ |
/* human = "read/write"; */ |
/* lck = LOCK_EX; */ |
/* } else { */ |
/* mint = O_RDONLY; */ |
/* mstr = "r"; */ |
/* human = "reading"; */ |
/* lck = LOCK_SH; */ |
/* } */ |
/* setegid(egid); */ |
/* mask = umask(S_IWOTH); */ |
/* sd = open(_PATH_SCOREFILE, mint, 0666); */ |
/* (void)umask(mask); */ |
/* setegid(gid); */ |
/* if (sd < 0) { */ |
/* if (fpp == NULL) { */ |
/* nscores = 0; */ |
/* return; */ |
/* } */ |
/* err(1, "cannot open %s for %s", _PATH_SCOREFILE, human); */ |
/* } */ |
/* setegid(egid); */ |
/* if ((sf = fdopen(sd, mstr)) == NULL) */ |
/* err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human); */ |
/* setegid(gid); */ |
f = fopen("/data/tetris.sco", "rb"); |
if (f == NULL) |
return ENOENT; |
/* /\* */ |
/* * Grab a lock. */ |
/* *\/ */ |
/* if (flock(sd, lck)) */ |
/* warn("warning: score file %s cannot be locked", */ |
/* _PATH_SCOREFILE); */ |
cnt = fread(scores, sizeof(struct highscore), NUMSPOTS, f); |
rc = fclose(f); |
/* nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf); */ |
/* if (ferror(sf)) */ |
/* err(1, "error reading %s", _PATH_SCOREFILE); */ |
/* for (i = 0; i < nscores; i++) */ |
/* if (scores[i].hs_level < MINLEVEL || */ |
/* scores[i].hs_level > MAXLEVEL) */ |
/* errx(1, "scorefile %s corrupt", _PATH_SCOREFILE); */ |
if (cnt != NUMSPOTS || rc != 0) |
return EIO; |
/* if (fpp) */ |
/* *fpp = sf; */ |
/* else */ |
/* (void)fclose(sf); */ |
/* } */ |
return EOK; |
} |
void |
savescore(int level) |
void savescores(void) |
{ |
return; |
} |
/* struct highscore *sp; */ |
/* int i; */ |
/* int change; */ |
/* FILE *sf; */ |
/* const char *me; */ |
FILE *f; |
size_t cnt; |
int rc; |
/* getscores(&sf); */ |
/* gotscores = 1; */ |
/* (void)time(&now); */ |
f = fopen("/data/tetris.sco", "wb"); |
cnt = fwrite(scores, sizeof(struct highscore), NUMSPOTS, f); |
rc = fclose(f); |
/* /\* */ |
/* * Allow at most one score per person per level -- see if we */ |
/* * can replace an existing score, or (easiest) do nothing. */ |
/* * Otherwise add new score at end (there is always room). */ |
/* *\/ */ |
/* change = 0; */ |
/* me = thisuser(); */ |
/* for (i = 0, sp = &scores[0]; i < nscores; i++, sp++) { */ |
/* if (sp->hs_level != level || str_cmp(sp->hs_name, me) != 0) */ |
/* continue; */ |
/* if (score > sp->hs_score) { */ |
/* (void)printf("%s bettered %s %d score of %d!\n", */ |
/* "\nYou", "your old level", level, */ |
/* sp->hs_score * sp->hs_level); */ |
/* sp->hs_score = score; /\* new score *\/ */ |
/* sp->hs_time = now; /\* and time *\/ */ |
/* change = 1; */ |
/* } else if (score == sp->hs_score) { */ |
/* (void)printf("%s tied %s %d high score.\n", */ |
/* "\nYou", "your old level", level); */ |
/* sp->hs_time = now; /\* renew it *\/ */ |
/* change = 1; /\* gotta rewrite, sigh *\/ */ |
/* } /\* else new score < old score: do nothing *\/ */ |
/* break; */ |
/* } */ |
/* if (i >= nscores) { */ |
/* strlcpy(sp->hs_name, me, sizeof sp->hs_name); */ |
/* sp->hs_level = level; */ |
/* sp->hs_score = score; */ |
/* sp->hs_time = now; */ |
/* nscores++; */ |
/* change = 1; */ |
/* } */ |
/* if (change) { */ |
/* /\* */ |
/* * Sort & clean the scores, then rewrite. */ |
/* *\/ */ |
/* nscores = checkscores(scores, nscores); */ |
/* rewind(sf); */ |
/* if (fwrite(scores, sizeof(*sp), nscores, sf) != nscores || */ |
/* fflush(sf) == EOF) */ |
/* warnx("error writing %s: %s\n\t-- %s", */ |
/* _PATH_SCOREFILE, strerror(errno), */ |
/* "high scores may be damaged"); */ |
/* } */ |
/* (void)fclose(sf); /\* releases lock *\/ */ |
/* } */ |
/* |
* Get login name, or if that fails, get something suitable. |
* The result is always trimmed to fit in a score. |
*/ |
/* static char * */ |
/* thisuser(void) */ |
/* { */ |
/* const char *p; */ |
/* struct passwd *pw; */ |
/* static char u[sizeof(scores[0].hs_name)]; */ |
/* if (u[0]) */ |
/* return (u); */ |
/* p = getlogin(); */ |
/* if (p == NULL || *p == '\0') { */ |
/* pw = getpwuid(getuid()); */ |
/* if (pw != NULL) */ |
/* p = pw->pw_name; */ |
/* else */ |
/* p = " ???"; */ |
/* } */ |
/* strlcpy(u, p, sizeof(u)); */ |
/* return (u); */ |
/* } */ |
/* |
* Score comparison function for qsort. |
* |
* If two scores are equal, the person who had the score first is |
* listed first in the highscore file. |
*/ |
/* static int */ |
/* cmpscores(const void *x, const void *y) */ |
/* { */ |
/* const struct highscore *a, *b; */ |
/* long l; */ |
/* a = x; */ |
/* b = y; */ |
/* l = (long)b->hs_level * b->hs_score - (long)a->hs_level * a->hs_score; */ |
/* if (l < 0) */ |
/* return (-1); */ |
/* if (l > 0) */ |
/* return (1); */ |
/* if (a->hs_time < b->hs_time) */ |
/* return (-1); */ |
/* if (a->hs_time > b->hs_time) */ |
/* return (1); */ |
/* return (0); */ |
/* } */ |
/* |
* If we've added a score to the file, we need to check the file and ensure |
* that this player has only a few entries. The number of entries is |
* controlled by MAXSCORES, and is to ensure that the highscore file is not |
* monopolised by just a few people. People who no longer have accounts are |
* only allowed the highest score. Scores older than EXPIRATION seconds are |
* removed, unless they are someone's personal best. |
* Caveat: the highest score on each level is always kept. |
*/ |
/* static int */ |
/* checkscores(struct highscore *hs, int num) */ |
/* { */ |
/* struct highscore *sp; */ |
/* int i, j, k, numnames; */ |
/* int levelfound[NLEVELS]; */ |
/* struct peruser { */ |
/* char *name; */ |
/* int times; */ |
/* } count[NUMSPOTS]; */ |
/* struct peruser *pu; */ |
/* /\* */ |
/* * Sort so that highest totals come first. */ |
/* * */ |
/* * levelfound[i] becomes set when the first high score for that */ |
/* * level is encountered. By definition this is the highest score. */ |
/* *\/ */ |
/* qsort((void *)hs, nscores, sizeof(*hs), cmpscores); */ |
/* for (i = MINLEVEL; i < NLEVELS; i++) */ |
/* levelfound[i] = 0; */ |
/* numnames = 0; */ |
/* for (i = 0, sp = hs; i < num;) { */ |
/* /\* */ |
/* * This is O(n^2), but do you think we care? */ |
/* *\/ */ |
/* for (j = 0, pu = count; j < numnames; j++, pu++) */ |
/* if (str_cmp(sp->hs_name, pu->name) == 0) */ |
/* break; */ |
/* if (j == numnames) { */ |
/* /\* */ |
/* * Add new user, set per-user count to 1. */ |
/* *\/ */ |
/* pu->name = sp->hs_name; */ |
/* pu->times = 1; */ |
/* numnames++; */ |
/* } else { */ |
/* /\* */ |
/* * Two ways to keep this score: */ |
/* * - Not too many (per user), still has acct, & */ |
/* * score not dated; or */ |
/* * - High score on this level. */ |
/* *\/ */ |
/* if ((pu->times < MAXSCORES && */ |
/* getpwnam(sp->hs_name) != NULL && */ |
/* sp->hs_time + EXPIRATION >= now) || */ |
/* levelfound[sp->hs_level] == 0) */ |
/* pu->times++; */ |
/* else { */ |
/* /\* */ |
/* * Delete this score, do not count it, */ |
/* * do not pass go, do not collect $200. */ |
/* *\/ */ |
/* num--; */ |
/* for (k = i; k < num; k++) */ |
/* hs[k] = hs[k + 1]; */ |
/* continue; */ |
/* } */ |
/* } */ |
/* levelfound[sp->hs_level] = 1; */ |
/* i++, sp++; */ |
/* } */ |
/* return (num > MAXHISCORES ? MAXHISCORES : num); */ |
/* } */ |
/* |
* Show current scores. This must be called after savescore, if |
* savescore is called at all, for two reasons: |
* - Showscores munches the time field. |
* - Even if that were not the case, a new score must be recorded |
* before it can be shown anyway. |
*/ |
/* |
void |
showscores(int level) |
{ |
return; |
if (cnt != NUMSPOTS || rc != 0) |
printf("Error saving score table\n"); |
} |
*/ |
/* struct highscore *sp; */ |
/* int i, n, c; */ |
/* const char *me; */ |
/* int levelfound[NLEVELS]; */ |
/* if (!gotscores) */ |
/* getscores((FILE **)NULL); */ |
/* (void)printf("\n\t\t Tetris High Scores\n"); */ |
/* /\* */ |
/* * If level == 0, the person has not played a game but just asked for */ |
/* * the high scores; we do not need to check for printing in highlight */ |
/* * mode. If SOstr is null, we can't do highlighting anyway. */ |
/* *\/ */ |
/* me = level && SOstr ? thisuser() : NULL; */ |
/* /\* */ |
/* * Set times to 0 except for high score on each level. */ |
/* *\/ */ |
/* for (i = MINLEVEL; i < NLEVELS; i++) */ |
/* levelfound[i] = 0; */ |
/* for (i = 0, sp = scores; i < nscores; i++, sp++) { */ |
/* if (levelfound[sp->hs_level]) */ |
/* sp->hs_time = 0; */ |
/* else { */ |
/* sp->hs_time = 1; */ |
/* levelfound[sp->hs_level] = 1; */ |
/* } */ |
/* } */ |
/* /\* */ |
/* * Page each screenful of scores. */ |
/* *\/ */ |
/* for (i = 0, sp = scores; i < nscores; sp += n) { */ |
/* n = 20; */ |
/* if (i + n > nscores) */ |
/* n = nscores - i; */ |
/* printem(level, i + 1, sp, n, me); */ |
/* if ((i += n) < nscores) { */ |
/* (void)printf("\nHit RETURN to continue."); */ |
/* (void)fflush(stdout); */ |
/* while ((c = getchar()) != '\n') */ |
/* if (c == EOF) */ |
/* break; */ |
/* (void)printf("\n"); */ |
/* } */ |
/* } */ |
/* if (nscores == 0) */ |
/* printf("\t\t\t - none to date.\n"); */ |
/* } */ |
/* static void */ |
/* printem(int level, int offset, struct highscore *hs, int n, const char *me) */ |
/* { */ |
/* struct highscore *sp; */ |
/* int row, highlight, i; */ |
/* char buf[100]; */ |
/* #define TITLE "Rank Score Name (points/level)" */ |
/* #define TITL2 "==========================================================" */ |
/* printf("%s\n%s\n", TITLE, TITL2); */ |
/* highlight = 0; */ |
/* for (row = 0; row < n; row++) { */ |
/* sp = &hs[row]; */ |
/* (void)snprintf(buf, sizeof(buf), */ |
/* "%3d%c %6d %-31s (%6d on %d)\n", */ |
/* row + offset, sp->hs_time ? '*' : ' ', */ |
/* sp->hs_score * sp->hs_level, */ |
/* sp->hs_name, sp->hs_score, sp->hs_level); */ |
/* /\* Print leaders every three lines *\/ */ |
/* if ((row + 1) % 3 == 0) { */ |
/* for (i = 0; i < sizeof(buf); i++) */ |
/* if (buf[i] == ' ') */ |
/* buf[i] = '_'; */ |
/* } */ |
/* /\* */ |
/* * Highlight if appropriate. This works because */ |
/* * we only get one score per level. */ |
/* *\/ */ |
/* if (me != NULL && */ |
/* sp->hs_level == level && */ |
/* sp->hs_score == score && */ |
/* str_cmp(sp->hs_name, me) == 0) { */ |
/* putpad(SOstr); */ |
/* highlight = 1; */ |
/* } */ |
/* (void)printf("%s", buf); */ |
/* if (highlight) { */ |
/* putpad(SEstr); */ |
/* highlight = 0; */ |
/* } */ |
/* } */ |
/* } */ |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/input.c |
---|
36,7 → 36,7 |
*/ |
/** @addtogroup tetris |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
57,9 → 57,9 |
#include "tetris.h" |
#include <async.h> |
#include <vfs/vfs.h> |
#include <io/console.h> |
#include <ipc/console.h> |
#include <console.h> |
#include <kbd/kbd.h> |
/* return true iff the given timeval is positive */ |
#define TV_POS(tv) \ |
92,14 → 92,12 |
* Return 0 => no input, 1 => can read() from stdin |
* |
*/ |
int |
rwait(struct timeval *tvp) |
int rwait(struct timeval *tvp) |
{ |
struct timeval starttv, endtv, *s; |
static ipc_call_t charcall; |
ipcarg_t rc; |
int cons_phone; |
/* |
* Someday, select() will do this for us. |
* Just in case that day is now, and no one has |
111,15 → 109,15 |
s = &endtv; |
} else |
s = NULL; |
if (!lastchar) { |
again: |
if (!getchar_inprog) { |
cons_phone = console_open(true); |
getchar_inprog = async_send_2(cons_phone, |
CONSOLE_GETKEY, 0, 0, &charcall); |
getchar_inprog = async_send_0(fphone(stdin), |
CONSOLE_GET_EVENT, &charcall); |
} |
if (!s) |
if (!s) |
async_wait_for(getchar_inprog, &rc); |
else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) { |
tvp->tv_sec = 0; |
126,22 → 124,25 |
tvp->tv_usec = 0; |
return (0); |
} |
getchar_inprog = 0; |
if (rc) { |
if (rc) |
stop("end of file, help"); |
} |
if (IPC_GET_ARG1(charcall) == KE_RELEASE) |
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 */ |
TV_SUB(tvp, &endtv); /* adjust *tvp by elapsed time */ |
} |
return (1); |
return 1; |
} |
/* |
148,11 → 149,10 |
* `sleep' for the current turn time (using select). |
* Eat any input that might be available. |
*/ |
void |
tsleep(void) |
void tsleep(void) |
{ |
struct timeval tv; |
tv.tv_sec = 0; |
tv.tv_usec = fallrate; |
while (TV_POS(&tv)) |
165,12 → 165,11 |
/* |
* getchar with timeout. |
*/ |
int |
tgetchar(void) |
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, |
181,17 → 180,18 |
* Most of the hard work is done by rwait(). |
*/ |
if (!TV_POS(&timeleft)) { |
faster(); /* go faster */ |
faster(); /* go faster */ |
timeleft.tv_sec = 0; |
timeleft.tv_usec = fallrate; |
} |
if (!rwait(&timeleft)) |
return (-1); |
return -1; |
c = lastchar; |
lastchar = '\0'; |
return ((int)(unsigned char)c); |
return ((int) (unsigned char) c); |
} |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/screen.c |
---|
36,7 → 36,7 |
*/ |
/** @addtogroup tetris |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
50,21 → 50,26 |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <console.h> |
#include <vfs/vfs.h> |
#include <async.h> |
#include "screen.h" |
#include "tetris.h" |
#include <ipc/console.h> |
#include <io/console.h> |
static cell curscreen[B_SIZE]; /* 1 => standout (or otherwise marked) */ |
#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 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); |
* simply literal strings); |
*/ |
static inline void putstr(char *s) |
{ |
72,19 → 77,22 |
putchar(*(s++)); |
} |
static void start_standout(void) |
static void start_standout(uint32_t color) |
{ |
console_set_rgb_color(0xf0f0f0, 0); |
fflush(stdout); |
console_set_rgb_color(fphone(stdout), 0xf0f0f0, |
use_color ? color : 0x000000); |
} |
static void resume_normal(void) |
{ |
console_set_rgb_color(0, 0xf0f0f0); |
fflush(stdout); |
console_set_rgb_color(fphone(stdout), 0, 0xf0f0f0); |
} |
void clear_screen(void) |
{ |
console_clear(); |
console_clear(fphone(stdout)); |
moveto(0, 0); |
} |
91,23 → 99,20 |
/* |
* Clear the screen, forgetting the current contents in the process. |
*/ |
void |
scr_clear(void) |
void scr_clear(void) |
{ |
resume_normal(); |
console_clear(); |
console_clear(fphone(stdout)); |
curscore = -1; |
memset((char *)curscreen, 0, sizeof(curscreen)); |
memset(curscreen, 0, sizeof(curscreen)); |
} |
/* |
* Set up screen |
*/ |
void |
scr_init(void) |
void scr_init(void) |
{ |
console_cursor_visibility(0); |
console_cursor_visibility(fphone(stdout), 0); |
resume_normal(); |
scr_clear(); |
} |
114,7 → 119,8 |
void moveto(int r, int c) |
{ |
console_goto(r, c); |
fflush(stdout); |
console_goto(fphone(stdout), c, r); |
} |
winsize_t winsize; |
121,25 → 127,41 |
static int get_display_size(winsize_t *ws) |
{ |
return console_get_size(&ws->ws_row, &ws->ws_col); |
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) |
void scr_set(void) |
{ |
winsize_t ws; |
Rows = 0, Cols = 0; |
Rows = 0; |
Cols = 0; |
if (get_display_size(&ws) == 0) { |
Rows = ws.ws_row; |
Cols = ws.ws_col; |
} |
if (Rows < MINROWS || Cols < MINCOLS) { |
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); |
146,7 → 168,7 |
stop(smallscr); |
} |
isset = 1; |
scr_clear(); |
} |
153,76 → 175,80 |
/* |
* End screen mode. |
*/ |
void |
scr_end(void) |
void scr_end(void) |
{ |
console_cursor_visibility(fphone(stdout), 1); |
} |
void |
stop(char *why) |
void stop(char *why) |
{ |
if (isset) |
scr_end(); |
errx(1, "aborting: %s", why); |
} |
/* |
* Update the screen. |
*/ |
void |
scr_update(void) |
void scr_update(void) |
{ |
cell *bp, *sp; |
cell so, cur_so = 0; |
int i, ccol, j; |
static const struct shape *lastshape; |
/* always leave cursor after last displayed point */ |
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)) { |
/* Draw preview of next pattern */ |
if ((showpreview) && (nextshape != lastshape)) { |
int i; |
static int r=5, c=2; |
static int r = 5, c = 2; |
int tr, tc, t; |
lastshape = nextshape; |
/* clean */ |
/* 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); |
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(); |
/* 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++) { |
230,6 → 256,7 |
for (i = 0; i < B_COLS; bp++, sp++, i++) { |
if (*sp == (so = *bp)) |
continue; |
*sp = so; |
if (i != ccol) { |
if (cur_so) { |
238,15 → 265,16 |
} |
moveto(RTOD(j), CTOD(i)); |
} |
if (so != cur_so) { |
if (so) |
start_standout(); |
start_standout(so); |
else |
resume_normal(); |
cur_so = so; |
} |
putstr(" "); |
ccol = i + 1; |
/* |
* Look ahead a bit, to avoid extra motion if |
256,33 → 284,35 |
* `unnecessarily'. Skip it all, though, if |
* the next cell is a different color. |
*/ |
#define STOP (B_COLS - 3) |
if (i > STOP || sp[1] != bp[1] || so != bp[1]) |
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]) { |
else if ((i < STOP) && (so == bp[2]) && (sp[3] != bp[3])) { |
sp[2] = -1; |
sp[1] = -1; |
} |
} |
} |
if (cur_so) |
resume_normal(); |
fflush(stdout); |
fflush(stdout); |
} |
/* |
* Write a message (set!=0), or clear the same message (set==0). |
* 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) |
void scr_msg(char *s, int set) |
{ |
int l = str_size(s); |
moveto(Rows - 2, ((Cols - l) >> 1) - 1); |
if (set) |
putstr(s); |
else |
292,4 → 322,3 |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/tetris.h |
---|
36,7 → 36,7 |
*/ |
/** @addtogroup tetris |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
55,57 → 55,60 |
* worrying about addressing problems. |
*/ |
/* the board */ |
#define B_COLS 12 |
#define B_ROWS 23 |
#define B_SIZE (B_ROWS * B_COLS) |
/* The board */ |
#define B_COLS 12 |
#define B_ROWS 23 |
#define B_SIZE (B_ROWS * B_COLS) |
typedef unsigned char cell; |
extern cell board[B_SIZE]; /* 1 => occupied, 0 => empty */ |
typedef uint32_t cell; |
/* the displayed area (rows) */ |
#define D_FIRST 1 |
#define D_LAST 22 |
extern cell board[B_SIZE]; /* 1 => occupied, 0 => empty */ |
/* the active area (rows) */ |
#define A_FIRST 1 |
#define A_LAST 21 |
/* 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 |
#define MINROWS 23 |
#define MINCOLS 40 |
extern int Rows, Cols; /* current screen size */ |
/* 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)) |
#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 |
* 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 |
* 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 |
* 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); |
* 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 |
* 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 |
116,7 → 119,7 |
* 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). |
* 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 |
128,9 → 131,10 |
* 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) */ |
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[]; |
148,15 → 152,16 |
* 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) |
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 |
#define MINLEVEL 1 |
#define MAXLEVEL 9 |
/* |
* Scoring is as follows: |
170,19 → 175,17 |
* |
* If previewing has been turned on, the score is multiplied by PRE_PENALTY. |
*/ |
#define PRE_PENALTY 0.75 |
#define PRE_PENALTY 0.75 |
extern int score; /* the obvious thing */ |
//extern gid_t gid, egid; |
extern int score; /* The obvious thing */ |
extern char key_msg[100]; |
extern int showpreview; |
extern int classic; |
extern char key_msg[100]; |
extern int showpreview; |
extern int classic; |
int fits_in(const struct shape *, int); |
void place(const struct shape *, int, int); |
void stop(char *); |
extern int fits_in(const struct shape *, int); |
extern void place(const struct shape *, int, int); |
extern void stop(char *); |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/scores.h |
---|
34,8 → 34,9 |
* |
* @(#)scores.h 8.1 (Berkeley) 5/31/93 |
*/ |
/** @addtogroup tetris |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
44,26 → 45,27 |
/* |
* Tetris scores. |
*/ |
#include <sys/time.h> |
#include <string.h> |
#define MAXLOGNAME 16 |
#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 */ |
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 */ |
}; |
#define MAXHISCORES 10 |
//#define MAXSCORES 9 /* maximum high score entries per person */ |
//#define EXPIRATION (5L * 365 * 24 * 60 * 60) |
extern void showscores(int); |
extern void initscores(void); |
extern void insertscore(int score, int level); |
extern int loadscores(void); |
extern void savescores(void); |
void savescore(int); |
void showscores(int); |
void insertscore(int score, int level); |
void initscores(void); |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/shapes.c |
---|
36,7 → 36,7 |
*/ |
/** @addtogroup tetris |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
50,35 → 50,35 |
#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 */ |
#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 } }, |
/* 1*/ { 8, 8, { TC, TR, ML } }, |
/* 2*/ { 9, 11, { ML, MR, BC } }, |
/* 3*/ { 3, 3, { TL, TC, ML } }, |
/* 4*/ { 12, 14, { ML, BL, MR } }, |
/* 5*/ { 15, 17, { ML, BR, MR } }, |
/* 6*/ { 18, 18, { ML, MR, 2 } }, /* sticks out */ |
/* 7*/ { 0, 0, { TC, ML, BL } }, |
/* 8*/ { 1, 1, { TC, MR, BR } }, |
/* 9*/ { 10, 2, { TC, MR, BC } }, |
/*10*/ { 11, 9, { TC, ML, MR } }, |
/*11*/ { 2, 10, { TC, ML, BC } }, |
/*12*/ { 13, 4, { TC, BC, BR } }, |
/*13*/ { 14, 12, { TR, ML, MR } }, |
/*14*/ { 4, 13, { TL, TC, BC } }, |
/*15*/ { 16, 5, { TR, TC, BC } }, |
/*16*/ { 17, 15, { TL, MR, ML } }, |
/*17*/ { 5, 16, { TC, BC, BL } }, |
/*18*/ { 6, 6, { TC, BC, 2*B_COLS } }/* sticks out */ |
/* 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 */ |
}; |
/* |
85,14 → 85,14 |
* 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) |
int fits_in(const struct shape *shape, int pos) |
{ |
int *o = shape->off; |
if (board[pos] || board[pos + *o++] || board[pos + *o++] || |
board[pos + *o]) |
const int *o = shape->off; |
if ((board[pos]) || (board[pos + *o++]) || (board[pos + *o++]) || |
(board[pos + *o])) |
return 0; |
return 1; |
} |
100,17 → 100,15 |
* 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) |
void place(const struct shape *shape, int pos, int onoff) |
{ |
int *o = shape->off; |
board[pos] = onoff; |
board[pos + *o++] = onoff; |
board[pos + *o++] = onoff; |
board[pos + *o] = 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; |
} |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/input.h |
---|
36,15 → 36,14 |
*/ |
/** @addtogroup tetris |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
int rwait(struct timeval *); |
int tgetchar(void); |
void tsleep(void); |
extern int rwait(struct timeval *); |
extern int tgetchar(void); |
extern void tsleep(void); |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/screen.h |
---|
36,36 → 36,37 |
*/ |
/** @addtogroup tetris |
* @{ |
* @{ |
*/ |
/** @file |
*/ |
/* |
* putpad() is for padded strings with count=1. |
* putpad() is for padded strings with count = 1. |
*/ |
#define putpad(s) tputs(s, 1, put) |
#define putpad(s) tputs(s, 1, put) |
#include <sys/types.h> |
#include <async.h> |
typedef struct { |
int ws_row; |
int ws_col; |
ipcarg_t ws_row; |
ipcarg_t ws_col; |
} winsize_t; |
extern winsize_t winsize; |
void moveto(int r, int c); |
void clear_screen(void); |
extern void moveto(int r, int c); |
extern void clear_screen(void); |
int put(int); /* just calls putchar; for tputs */ |
void scr_clear(void); |
void scr_end(void); |
void scr_init(void); |
void scr_msg(char *, int); |
void scr_set(void); |
void scr_update(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); |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/tetris.c |
---|
36,30 → 36,25 |
*/ |
/** @addtogroup tetris Tetris |
* @brief Tetris ported from OpenBSD |
* @{ |
* @brief Tetris ported from OpenBSD |
* @{ |
*/ |
/** @file |
*/ |
#ifndef lint |
static const char copyright[] = |
"@(#) Copyright (c) 1992, 1993\n\ |
The Regents of the University of California. All rights reserved.\n"; |
#endif /* not lint */ |
"@(#) Copyright (c) 1992, 1993\n" |
"\tThe Regents of the University of California. All rights reserved.\n"; |
/* |
* Tetris (or however it is spelled). |
*/ |
#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" |
66,66 → 61,76 |
#include "screen.h" |
#include "tetris.h" |
cell board[B_SIZE]; |
int Rows, Cols; |
cell board[B_SIZE]; |
int Rows; |
int Cols; |
const struct shape *curshape; |
const struct shape *nextshape; |
long fallrate; |
int score; |
//gid_t gid, egid; |
char key_msg[100]; |
int showpreview, classic; |
static void elide(void); |
static void setup_board(void); |
const struct shape *randshape(void); |
void onintr(int); |
void usage(void); |
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 |
* 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) |
static void setup_board(void) |
{ |
int i; |
cell *p; |
p = board; |
cell *p = board; |
for (i = B_SIZE; i; i--) |
*p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2; |
*p++ = (i <= (2 * B_COLS) || (i % B_COLS) < 2) ? 0x0000ff : 0x000000; |
} |
/* |
* Elide any full active rows. |
*/ |
static void |
elide(void) |
static void elide(void) |
{ |
int rows = 0; |
int i, j, base; |
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 */ |
/* This row is to be elided */ |
rows++; |
memset(&board[base], 0, B_COLS - 2); |
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; |
144,16 → 149,15 |
} |
} |
const struct shape * |
randshape(void) |
const struct shape *randshape(void) |
{ |
const struct shape *tmp; |
int i, j; |
tmp = &shapes[random() % 7]; |
j = random() % 4; |
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]; |
tmp = &shapes[classic ? tmp->rotc : tmp->rot]; |
return (tmp); |
} |
160,7 → 164,7 |
static void srandomdev(void) |
{ |
struct timeval tv; |
gettimeofday(&tv, NULL); |
srandom(tv.tv_sec + tv.tv_usec / 100000); |
} |
167,61 → 171,43 |
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); |
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) |
static int tetris_menu(int *level) |
{ |
static int firstgame = 1; |
int i; |
/* if (showpreview == 0) |
(void)printf("Your score: %d point%s x level %d = %d\n", |
score, score == 1 ? "" : "s", level, score * level); |
else { |
(void)printf("Your score: %d point%s x level %d x preview penalty %0.3f = %d\n", |
score, score == 1 ? "" : "s", level, (double)PRE_PENALTY, |
(int)(score * level * PRE_PENALTY)); |
score = score * PRE_PENALTY; |
} |
savescore(level); |
showscores(level); |
printf("\nHit 's' to new game, 'q' to quit.\n"); |
*/ |
tetris_menu_draw(*level); |
while (1) { |
i = getchar(); |
int i = getchar(); |
switch(i) { |
case 'p': |
showpreview = !showpreview; |
moveto(9,21); |
moveto(9, 21); |
if (showpreview) |
printf("on "); |
else |
printf("off"); |
break; |
case 'h': |
loadscores(); |
showscores(firstgame); |
tetris_menu_draw(*level); |
break; |
235,112 → 221,103 |
case '3': |
case '4': |
case '5': |
case '6': |
case '6': |
case '7': |
case '8': |
case '9': |
*level = i - '0'; |
moveto(8,18); |
moveto(8, 18); |
printf("%d", *level); |
break; |
} |
} |
} |
int |
main(int argc, char *argv[]) |
int main(int argc, char *argv[]) |
{ |
int pos, c; |
char *keys; |
int pos; |
int c; |
const char *keys; |
int level = 2; |
char key_write[6][10]; |
int i, j; |
int i; |
int j; |
int ch; |
keys = "jkl pq"; |
// gid = getgid(); |
// egid = getegid(); |
// setegid(gid); |
classic = 0; |
showpreview = 1; |
/* while ((ch = getopt(argc, argv, "ck:l: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 'l': */ |
/* level = (int)strtonum(optarg, MINLEVEL, MAXLEVEL, */ |
/* &errstr); */ |
/* if (errstr) */ |
/* errx(1, "level must be from %d to %d", */ |
/* MINLEVEL, MAXLEVEL); */ |
/* break; */ |
/* case 'p': */ |
/* showpreview = 1; */ |
/* break; */ |
/* case 's': */ |
/* showscores(0); */ |
/* exit(0); */ |
/* default: */ |
/* usage(); */ |
/* } */ |
/* argc -= optind; */ |
/* argv += optind; */ |
/* if (argc) */ |
/* usage(); */ |
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++) { |
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>"); |
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(); |
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(); |
initscores(); |
while (tetris_menu(&level)) { |
fallrate = 1000000 / level; |
scr_clear(); |
setup_board(); |
srandomdev(); |
scr_set(); |
pos = A_FIRST*B_COLS + (B_COLS/2)-1; |
pos = A_FIRST * B_COLS + (B_COLS / 2) - 1; |
nextshape = randshape(); |
curshape = randshape(); |
scr_msg(key_msg, 1); |
for (;;) { |
while (1) { |
place(curshape, pos, 1); |
scr_update(); |
place(curshape, pos, 0); |
353,7 → 330,7 |
pos += B_COLS; |
continue; |
} |
/* |
* Put up the current shape `permanently', |
* bump score, and elide any full rows. |
361,7 → 338,7 |
place(curshape, pos, 1); |
score++; |
elide(); |
/* |
* Choose a new shape. If it does not fit, |
* the game is over. |
368,12 → 345,14 |
*/ |
curshape = nextshape; |
nextshape = randshape(); |
pos = A_FIRST*B_COLS + (B_COLS/2)-1; |
pos = A_FIRST * B_COLS + (B_COLS / 2) - 1; |
if (!fits_in(curshape, pos)) |
break; |
continue; |
} |
/* |
* Handle command keys. |
*/ |
381,10 → 360,11 |
/* quit */ |
break; |
} |
if (c == keys[4]) { |
static char msg[] = |
"paused - press RETURN to continue"; |
place(curshape, pos, 1); |
do { |
scr_update(); |
391,12 → 371,14 |
scr_msg(key_msg, 0); |
scr_msg(msg, 1); |
(void) fflush(stdout); |
} while (rwait((struct timeval *)NULL) == -1); |
} 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)) |
403,15 → 385,17 |
pos--; |
continue; |
} |
if (c == keys[1]) { |
/* turn */ |
const struct shape *new = &shapes[ |
classic? curshape->rotc : curshape->rot]; |
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)) |
418,6 → 402,7 |
pos++; |
continue; |
} |
if (c == keys[3]) { |
/* move to bottom */ |
while (fits_in(curshape, pos + B_COLS)) { |
426,6 → 411,7 |
} |
continue; |
} |
if (c == '\f') { |
scr_clear(); |
scr_msg(key_msg, 1); |
433,37 → 419,24 |
} |
scr_clear(); |
loadscores(); |
insertscore(score, level); |
score=0; |
savescores(); |
score = 0; |
} |
scr_clear(); |
printf("\n\n\n\t\tGame over.\n"); |
/* |
while ((i = getchar()) != '\n') |
if (i == EOF) |
break |
*/ |
printf("\nGame over.\n"); |
scr_end(); |
return 0; |
} |
/* void */ |
/* onintr(int signo) */ |
/* { */ |
/* scr_clear(); /\* XXX signal race *\/ */ |
/* scr_end(); /\* XXX signal race *\/ */ |
/* _exit(0); */ |
/* } */ |
void |
usage(void) |
void usage(void) |
{ |
(void)fprintf(stderr, "usage: tetris [-ps] [-k keys] [-l level]\n"); |
fprintf(stderr, "usage: tetris [-ps] [-k keys]\n"); |
exit(1); |
} |
/** @} |
*/ |
/branches/dynload/uspace/app/tetris/Makefile |
---|
26,7 → 26,7 |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dynload/uspace/app/klog/Makefile |
---|
63,7 → 63,7 |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
$(OBJDUMP) -d $< > $@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dynload/uspace/app/klog/klog.c |
---|
40,41 → 40,34 |
#include <ipc/services.h> |
#include <as.h> |
#include <sysinfo.h> |
#include <io/stream.h> |
#include <console.h> |
#include <event.h> |
#include <errno.h> |
#include <io/klog.h> |
#define NAME "klog" |
#define NAME "klog" |
/* Pointer to klog area */ |
static wchar_t *klog; |
static count_t klog_length; |
static size_t klog_length; |
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
async_serialize_start(); |
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; |
count_t klog_start = (count_t) IPC_GET_ARG1(*call); |
count_t klog_len = (count_t) IPC_GET_ARG2(*call); |
count_t klog_stored = (count_t) IPC_GET_ARG3(*call); |
count_t i; |
for (i = klog_len - klog_stored; i < klog_len; i++) |
putchar(klog[(klog_start + i) % klog_length]); |
async_serialize_end(); |
} |
int main(int argc, char *argv[]) |
{ |
console_wait(); |
count_t klog_pages = sysinfo_value("klog.pages"); |
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_pages); |
klog = (wchar_t *) as_get_mappable_page(klog_size); |
if (klog == NULL) { |
printf(NAME ": Error allocating memory area\n"); |
return -1; |
/branches/dynload/uspace/app/trace/trace.c |
---|
41,7 → 41,13 |
#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> |
62,22 → 68,31 |
int next_thread_id; |
ipc_call_t thread_ipc_req[THBUF_SIZE]; |
int phoneid; |
int abort_trace; |
bool abort_trace; |
uintptr_t thash; |
volatile int paused; |
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) |
{ |
92,6 → 107,19 |
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; |
178,6 → 206,10 |
void val_print(sysarg_t val, val_type_t v_type) |
{ |
long sval; |
sval = (long) val; |
switch (v_type) { |
case V_VOID: |
printf("<void>"); |
184,7 → 216,7 |
break; |
case V_INTEGER: |
printf("%ld", val); |
printf("%ld", sval); |
break; |
case V_HASH: |
193,29 → 225,29 |
break; |
case V_ERRNO: |
if (val >= -15 && val <= 0) { |
printf("%ld %s (%s)", val, |
err_desc[-val].name, |
err_desc[-val].desc); |
if (sval >= -15 && sval <= 0) { |
printf("%ld %s (%s)", sval, |
err_desc[-sval].name, |
err_desc[-sval].desc); |
} else { |
printf("%ld", val); |
printf("%ld", sval); |
} |
break; |
case V_INT_ERRNO: |
if (val >= -15 && val < 0) { |
printf("%ld %s (%s)", val, |
err_desc[-val].name, |
err_desc[-val].desc); |
if (sval >= -15 && sval < 0) { |
printf("%ld %s (%s)", sval, |
err_desc[-sval].name, |
err_desc[-sval].desc); |
} else { |
printf("%ld", val); |
printf("%ld", sval); |
} |
break; |
case V_CHAR: |
if (val >= 0x20 && val < 0x7f) { |
printf("'%c'", val); |
if (sval >= 0x20 && sval < 0x7f) { |
printf("'%c'", sval); |
} else { |
switch (val) { |
switch (sval) { |
case '\a': printf("'\\a'"); break; |
case '\b': printf("'\\b'"); break; |
case '\n': printf("'\\n'"); break; |
254,7 → 286,8 |
ipc_call_t call; |
ipcarg_t phoneid; |
if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY) |
if (sc_rc == (sysarg_t) IPC_CALLRET_FATAL || |
sc_rc == (sysarg_t) IPC_CALLRET_TEMPORARY) |
return; |
phoneid = sc_args[0]; |
274,7 → 307,8 |
ipc_call_t call; |
int rc; |
if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY) |
if (sc_rc == (sysarg_t) IPC_CALLRET_FATAL || |
sc_rc == (sysarg_t) IPC_CALLRET_TEMPORARY) |
return; |
memset(&call, 0, sizeof(call)); |
313,22 → 347,38 |
ipcp_call_sync(phoneidx, &question, &reply); |
} |
static void sc_ipc_call_sync_slow(sysarg_t *sc_args) |
static void sc_ipc_call_sync_slow_b(unsigned thread_id, sysarg_t *sc_args) |
{ |
ipc_call_t question, reply; |
ipc_call_t question; |
int rc; |
memset(&question, 0, sizeof(question)); |
rc = udebug_mem_read(phoneid, &question.args, sc_args[1], sizeof(question.args)); |
printf("dmr->%d\n", rc); |
if (rc < 0) return; |
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)); |
printf("dmr->%d\n", rc); |
if (rc < 0) return; |
rc = udebug_mem_read(phoneid, &reply.args, sc_args[2], |
sizeof(reply.args)); |
ipcp_call_sync(sc_args[0], &question, &reply); |
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) |
373,6 → 423,14 |
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(); |
} |
413,7 → 471,7 |
sc_ipc_call_sync_fast(sc_args); |
break; |
case SYS_IPC_CALL_SYNC_SLOW: |
sc_ipc_call_sync_slow(sc_args); |
sc_ipc_call_sync_slow_e(thread_id, sc_args); |
break; |
case SYS_IPC_WAIT: |
sc_ipc_wait(sc_args, sc_rc); |
444,20 → 502,26 |
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("Press R to resume (and be patient).\n"); |
while (paused) { |
usleep(1000000); |
fibril_yield(); |
printf("."); |
} |
printf("Resumed\n"); |
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, |
479,6 → 543,9 |
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); |
485,7 → 552,10 |
break; |
case UDEBUG_EVENT_THREAD_E: |
printf("Thread 0x%lx exited.\n", val0); |
abort_trace = 1; |
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); |
538,6 → 608,33 |
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) |
553,11 → 650,32 |
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; |
int c; |
ipcp_init(); |
573,29 → 691,55 |
return; |
} |
abort_trace = 0; |
abort_trace = false; |
for (i = 0; i < n_threads; i++) { |
thread_trace_start(thread_hash_buf[i]); |
} |
while(1) { |
c = getchar(); |
if (c == 'q') break; |
if (c == 'p') { |
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"); |
paused = 1; |
rc = udebug_stop(phoneid, thash); |
printf("stop -> %d\n", rc); |
} |
if (c == 'r') { |
paused = 0; |
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 = 1; |
abort_trace = true; |
udebug_end(phoneid); |
ipc_hangup(phoneid); |
627,47 → 771,58 |
}; |
next_thread_id = 1; |
paused = 0; |
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_READ, o); |
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_WRITE, o); |
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_TRUNCATE, o); |
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_MOUNT, o); |
proto_add_oper(p, VFS_IN_MOUNT, o); |
/* o = oper_new("unmount", 0, arg_def); |
proto_add_oper(p, VFS_UNMOUNT, o);*/ |
o = oper_new("open", 2, arg_def, V_INT_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_OPEN, o); |
o = oper_new("close", 1, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_CLOSE, o); |
o = oper_new("seek", 3, arg_def, V_ERRNO, 0, resp_def); |
proto_add_oper(p, VFS_SEEK, o); |
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_MKDIR, o); |
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_UNLINK, o); |
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_RENAME, o); |
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); |
proto_add_oper(p, CONSOLE_GETKEY, o); |
arg_def[0] = V_CHAR; |
o = oper_new("putchar", 1, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_PUTCHAR, o); |
o = oper_new("write", 0, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_WRITE, o); |
o = oper_new("clear", 0, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_CLEAR, o); |
677,9 → 832,7 |
resp_def[0] = V_INTEGER; resp_def[1] = V_INTEGER; |
o = oper_new("getsize", 0, arg_def, V_INTEGER, 2, resp_def); |
proto_add_oper(p, CONSOLE_GETSIZE, o); |
o = oper_new("flush", 0, arg_def, V_VOID, 0, resp_def); |
proto_add_oper(p, CONSOLE_FLUSH, o); |
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); |
757,6 → 910,7 |
--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(); |
794,6 → 948,7 |
while (*cp) printf("'%s'\n", *cp++); |
} |
task_ldr = preload_task(*argv, argv, &task_id); |
task_wait_for = true; |
return 0; |
} |
801,6 → 956,8 |
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"); |
820,12 → 977,29 |
printf("Connected to task %lld.\n", task_id); |
if (task_ldr != NULL) { |
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; |
} |
/branches/dynload/uspace/app/trace/proto.c |
---|
35,7 → 35,7 |
#include <stdio.h> |
#include <stdlib.h> |
#include <ipc/ipc.h> |
#include <libadt/hash_table.h> |
#include <adt/hash_table.h> |
#include "trace.h" |
#include "proto.h" |
46,7 → 46,7 |
hash_table_t srv_proto; |
typedef struct { |
int srv; |
unsigned srv; |
proto_t *proto; |
link_t link; |
} srv_proto_t; |
/branches/dynload/uspace/app/trace/proto.h |
---|
35,7 → 35,7 |
#ifndef PROTO_H_ |
#define PROTO_H_ |
#include <libadt/hash_table.h> |
#include <adt/hash_table.h> |
#include <ipc/ipc.h> |
#include "trace.h" |
/branches/dynload/uspace/app/trace/ipcp.c |
---|
34,7 → 34,7 |
#include <stdio.h> |
#include <stdlib.h> |
#include <libadt/hash_table.h> |
#include <adt/hash_table.h> |
#include "ipc_desc.h" |
#include "proto.h" |