aos/usr/hello/hello.c

200 lines
8.9 KiB
C

/**
* \file
* \brief Hello world application
*/
/*
* Copyright (c) 2016 ETH Zurich.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
* ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
* Attn: Systems Group.
*/
#include <stdio.h>
#include <string.h>
#include <aos/aos.h>
#include <aos/aos_rpc.h>
#include <aos/deferred.h>
#include <aos/ump_chan.h>
#define HELLO_CMD_CATCH "catch"
#define HELLO_CMD_SPAWN "spawn"
#define HELLO_CMD_SPAWN_REMOTE "spawn_remote"
#define HELLO_CMD_ECHOCLIENT "echoclient"
#define HELLO_CMD_IO "io"
#define HELLO_CMDLINE_READ_LEN 100
#define HELLO_TEST_MESSAGE "Hello Server! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
__attribute__((__used__))
static int null_dereference(void *ignored) {
debug_printf("[null_dereference] Oh no! :O\n");
// cause a page fault (slight offset from null simulates NULL struct field access)
*((volatile char *)(NULL + 7));
return 1;
}
__attribute__((__used__))
static void handle_payload_recv(void *arg, size_t payload_size, void *payload) {
printf("Echo client: Received payload(%lu): %.*s\n", payload_size, payload_size, payload);
}
__attribute__((__used__))
static void handle_header_recv(void *arg, size_t header_size, void *header, size_t payload_size) {
printf("Echo client: Received header: %u\n", *(uint8_t *)header);
printf("Echo client: Payload is %lu bytes\n", payload_size);
void *payload = malloc(payload_size);
assert(payload != NULL);
ump_recv_payload(arg, payload, handle_payload_recv, NULL);
}
__attribute__((__used__))
static void handle_send(void *arg, struct ump_send_queue_entry *entry) {
printf("Echo client: Message sent!\n");
}
int main(int argc, char *argv[])
{
errval_t err;
printf("Hello, world!\n");
// test page fault handling by doing a null dereference on a different thread
// thread_create(null_dereference, NULL);
// barrelfish_usleep(10000000);
printf("argv:\n");
for(int i = 0; i < argc; ++i) {
printf(" %d -> %s\n", i, argv[i]);
}
struct aos_rpc *rpc = aos_rpc_get_init_channel();
err = aos_rpc_send_number(rpc, 1234);
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to send RPC");
err = aos_rpc_send_string(rpc, "Hello World via RPC!");
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to send RPC");
// try to spawn a child using rpc
if (argc > 1 && !strncmp(argv[1], HELLO_CMD_SPAWN, sizeof(HELLO_CMD_SPAWN))) {
debug_printf("Waiting for 1s before showing shell because kernel getchar blocks everything!\n");
barrelfish_usleep(1000000);
debug_printf("# ");
// try to read cmdline from the terminal (a very very primitive shell)
char cmdline[HELLO_CMDLINE_READ_LEN+1];
for(int i = 0; i < HELLO_CMDLINE_READ_LEN; ++i) {
char c = getchar();
if(c == '\r') {
printf("\n");
cmdline[i] = '\0';
break;
}
if(c == 0x7f) {
if (i > 0) {
printf("\b \b"); fflush(stdout);
}
--i;
if(i >= 0) --i;
continue;
}
cmdline[i] = c;
printf("%c", c); fflush(stdout);
}
cmdline[HELLO_CMDLINE_READ_LEN] = '\0';
printf("Got command line: %s\n", cmdline);
// start process
domainid_t pid;
rpc = aos_rpc_get_process_channel();
err = aos_rpc_process_spawn(rpc, cmdline, 0, &pid);
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to spawn process");
printf("Started a new process!\n");
// get process name
char *name;
err = aos_rpc_process_get_name(rpc, pid, &name);
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to get process name");
printf("Process Name: %s\n", name);
// get all PIDs
domainid_t *pids;
size_t pid_count;
err = aos_rpc_process_get_all_pids(rpc, &pids, &pid_count);
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to get all PIDs");
printf("PIDs:\n");
for(size_t i = 0; i < pid_count; ++i) {
printf(" %lu\n", pids[i]);
}
}
// if we receive the catch command, RUN!
if (argc > 1 && !strncmp(argv[1], HELLO_CMD_CATCH, sizeof(HELLO_CMD_CATCH))) {
int iter = 0;
while(1) {
printf("Catch me if you can! %d\n", iter);
// wait for 1 second
barrelfish_usleep(1000000);
++iter;
}
}
if (argc > 1 && !strncmp(argv[1], HELLO_CMD_SPAWN_REMOTE, sizeof(HELLO_CMD_SPAWN_REMOTE))) {
printf("Spawning process on core 1...\n");
domainid_t pid;
rpc = aos_rpc_get_process_channel();
err = aos_rpc_process_spawn(rpc, "hello world", 1, &pid);
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to spawn process");
printf("Spawn succeeded, pid=%"PRIuDOMAINID"\n", pid);
}
if (argc > 1 && !strncmp(argv[1], HELLO_CMD_ECHOCLIENT, sizeof(HELLO_CMD_ECHOCLIENT))) {
printf("Echo client: Connecting to echo server...\n");
struct capref echo_cap;
for (int attempts = 0; attempts < 50; attempts++) {
err = aos_rpc_ump_connect(rpc, UMP_SERVER_ECHO, &echo_cap);
if (err != LIB_ERR_UMP_NOT_REGISTERED) break;
barrelfish_usleep(100000);
}
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to connect to echo server");
printf("Echo client: Connected to echo server.\n");
// Create the two uni-directional channels
struct ump_send_chan *send_chan;
struct ump_recv_chan *recv_chan;
err = ump_chan_init(UMP_ROLE_CLIENT, &send_chan, &recv_chan, 1, echo_cap, NULL);
if (err_is_fail(err)) return err;
// send a message to the server
printf("Echo client: Sending Message\n");
uint8_t *value_to_send = malloc(sizeof(uint8_t));
*value_to_send = 37;
struct ump_send_queue_entry *entry = malloc(sizeof(struct ump_send_queue_entry));
ump_send(send_chan, entry, 1, value_to_send, sizeof(HELLO_TEST_MESSAGE), HELLO_TEST_MESSAGE, handle_send, NULL);
// try to receive and print a message from the server
printf("Echo client: Receiving Message\n");
ump_recv_header(recv_chan, handle_header_recv, recv_chan);
}
if (argc > 1 && !strncmp(argv[1], HELLO_CMD_IO, sizeof(HELLO_CMD_IO))) {
int testInteger;
printf("Hi! Please enter an integer: ");
scanf("%d", &testInteger);
printf("number = %d",testInteger);
char name_input[20];
printf("Please enter your name: ");
scanf("%s", name_input);
printf("why hello there, %s", name_input);
}
return EXIT_SUCCESS;
}