1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#include "drivers/tty/ldisc.h"
#include <drivers/keyboard.h>
#include <drivers/tty/tty.h>
#include <errno.h>
#include <util/bits.h>
#include <util/debug.h>
#include <util/string.h>
#define ldisc_to_tty(ldisc) CONTAINER_OF((ldisc), tty_t, tty_ldisc)
/**
* Initialize the line discipline. Don't forget to wipe the buffer associated
* with the line discipline clean.
*
* @param ldisc line discipline.
*/
void ldisc_init(ldisc_t *ldisc)
{
NOT_YET_IMPLEMENTED("DRIVERS: ldisc_init");
}
/**
* While there are no new characters to be read from the line discipline's
* buffer, you should make the current thread to sleep on the line discipline's
* read queue. Note that this sleep can be cancelled. What conditions must be met
* for there to be no characters to be read?
*
* @param ldisc the line discipline
* @param lock the lock associated with `ldisc`
* @return 0 if there are new characters to be read or the ldisc is full.
* If the sleep was interrupted, return what
* `sched_cancellable_sleep_on` returned (i.e. -EINTR)
*/
long ldisc_wait_read(ldisc_t *ldisc)
{
NOT_YET_IMPLEMENTED("DRIVERS: ldisc_wait_read");
return -1;
}
/**
* Reads `count` bytes (at max) from the line discipline's buffer into the
* provided buffer. Keep in mind the the ldisc's buffer is circular.
*
* If you encounter a new line symbol before you have read `count` bytes, you
* should stop copying and return the bytes read until now.
*
* If you encounter an `EOT` you should stop reading and you should NOT include
* the `EOT` in the count of the number of bytes read
*
* @param ldisc the line discipline
* @param buf the buffer to read into.
* @param count the maximum number of bytes to read from ldisc.
* @return the number of bytes read from the ldisc.
*/
size_t ldisc_read(ldisc_t *ldisc, char *buf, size_t count)
{
NOT_YET_IMPLEMENTED("DRIVERS: ldisc_read");
return 0;
}
/**
* Place the character received into the ldisc's buffer. You should also update
* relevant fields of the struct.
*
* An easier way of handling new characters is making sure that you always have
* one byte left in the line discipline. This way, if the new character you
* received is a new line symbol (user hit enter), you can still place the new
* line symbol into the buffer; if the new character is not a new line symbol,
* you shouldn't place it into the buffer so that you can leave the space for
* a new line symbol in the future.
*
* If the line discipline is full, all incoming characters should be ignored.
*
* Here are some special cases to consider:
* 1. If the character is a backspace:
* * if there is a character to remove you must also emit a `\b` to
* the vterminal.
* 2. If the character is end of transmission (EOT) character (typing ctrl-d)
* 3. If the character is end of text (ETX) character (typing ctrl-c)
* 4. If your buffer is almost full and what you received is not a new line
* symbol
*
* If you did receive a new line symbol, you should wake up the thread that is
* sleeping on the wait queue of the line discipline. You should also
* emit a `\n` to the vterminal by using `vterminal_write`.
*
* If you encounter the `EOT` character, you should add it to the buffer,
* cook the buffer, and wake up the reader (but do not emit an `\n` character
* to the vterminal)
*
* In case of `ETX` you should cause the input line to be effectively transformed
* into a cooked blank line. You should clear uncooked portion of the line, by
* adjusting ldisc_head.
*
* Finally, if the none of the above cases apply you should fallback to
* `vterminal_key_pressed`.
*
* Don't forget to write the corresponding characters to the virtual terminal
* when it applies!
*
* @param ldisc the line discipline
* @param c the new character
*/
void ldisc_key_pressed(ldisc_t *ldisc, char c)
{
NOT_YET_IMPLEMENTED("DRIVERS: ldisc_key_pressed");
}
/**
* Copy the raw part of the line discipline buffer into the buffer provided.
*
* @param ldisc the line discipline
* @param s the character buffer to write to
* @return the number of bytes copied
*/
size_t ldisc_get_current_line_raw(ldisc_t *ldisc, char *s)
{
NOT_YET_IMPLEMENTED("DRIVERS: ldisc_get_current_line_raw");
return 0;
}
|