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, Universitaetstrasse 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 = cap_direct_identify(cap_sessionid, &cap);
74    /* if domain is part of session, sessionid cap should be present and
75     * ObjType_ID */
76    if (err_is_ok(err) && cap.type == ObjType_ID) {
77        /* Initialize libterm_client. */
78        err = term_client_blocking_init(&state->client, cap_sessionid);
79        if (err_is_fail(err)) {
80            return err;
81        }
82
83        state->session_domain = true;
84        return SYS_ERR_OK;
85    } else {
86        state->session_domain = false;
87        return SYS_ERR_OK;
88    }
89}
90
91void terminal_exit(void)
92{
93    struct terminal_state *state = get_terminal_state();
94
95    if (state != NULL && state->session_domain) {
96        term_client_blocking_exit(&state->client);
97    }
98}
99