Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4690 → Rev 4691

/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.def
File deleted
/branches/dynload/uspace/app/tester/devmap/devmap1.c
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"