1/**
2 * \file
3 * \brief Terminal emulator.
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2010, 2012, 2013, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
13 * Attn: Systems Group.
14 */
15
16#include <stdbool.h>
17
18#include <barrelfish/barrelfish.h>
19#include <barrelfish/terminal.h>
20#include <if/terminal_config_defs.h>
21#include <term/client/client_blocking.h>
22
23size_t terminal_write(const char *data, size_t length)
24{
25    errval_t err;
26    size_t written = 0;
27    struct terminal_state *state = get_terminal_state();
28
29    if (state != NULL && state->session_domain) {
30        err = term_client_blocking_write(&state->client, data, length,
31                                         &written);
32        assert(err_is_ok(err));
33        return written;
34    } else {
35        sys_print(data, length);
36        return length;
37    }
38}
39
40size_t terminal_read(char *data, size_t count)
41{
42    errval_t err;
43    size_t read = 0;
44    struct terminal_state *state = get_terminal_state();
45
46    if (state->session_domain) {
47        err = term_client_blocking_read(&state->client, data, count, &read);
48        assert(err_is_ok(err));
49        return read;
50    } else {
51        /**
52         * Only domains that are part of a session can read from a terminal
53         * device.
54         */
55        assert(!"Daemons can't read from a terminal.");
56        return 0;
57    }
58}
59
60errval_t terminal_init(void)
61{
62    errval_t err;
63    struct capability cap;
64
65    /* Allocate and initialize dispatcher-specific state. */
66    struct terminal_state *state = malloc(sizeof(struct terminal_state));
67    if (!state) {
68        return LIB_ERR_MALLOC_FAIL;
69    }
70    set_terminal_state(state);
71
72    /* Check if domain is part of a session. */
73    err = debug_cap_identify(cap_sessionid, &cap);
74    if (err_is_ok(err)) {
75        /* Initialize libterm_client. */
76        err = term_client_blocking_init(&state->client, cap_sessionid);
77        if (err_is_fail(err)) {
78            return err;
79        }
80
81        state->session_domain = true;
82        return SYS_ERR_OK;
83    } else {
84        state->session_domain = false;
85        return SYS_ERR_OK;
86    }
87}
88
89void terminal_exit(void)
90{
91    struct terminal_state *state = get_terminal_state();
92
93    if (state != NULL && state->session_domain) {
94        term_client_blocking_exit(&state->client);
95    }
96}
97