diff options
Diffstat (limited to 'lib/user/console.c')
| -rw-r--r-- | lib/user/console.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/lib/user/console.c b/lib/user/console.c new file mode 100644 index 0000000..22bdc8c --- /dev/null +++ b/lib/user/console.c | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <string.h> | ||
| 3 | #include <syscall.h> | ||
| 4 | #include <syscall-nr.h> | ||
| 5 | |||
| 6 | /* The standard vprintf() function, | ||
| 7 | which is like printf() but uses a va_list. */ | ||
| 8 | int | ||
| 9 | vprintf (const char *format, va_list args) | ||
| 10 | { | ||
| 11 | return vhprintf (STDOUT_FILENO, format, args); | ||
| 12 | } | ||
| 13 | |||
| 14 | /* Like printf(), but writes output to the given HANDLE. */ | ||
| 15 | int | ||
| 16 | hprintf (int handle, const char *format, ...) | ||
| 17 | { | ||
| 18 | va_list args; | ||
| 19 | int retval; | ||
| 20 | |||
| 21 | va_start (args, format); | ||
| 22 | retval = vhprintf (handle, format, args); | ||
| 23 | va_end (args); | ||
| 24 | |||
| 25 | return retval; | ||
| 26 | } | ||
| 27 | |||
| 28 | /* Writes string S to the console, followed by a new-line | ||
| 29 | character. */ | ||
| 30 | int | ||
| 31 | puts (const char *s) | ||
| 32 | { | ||
| 33 | write (STDOUT_FILENO, s, strlen (s)); | ||
| 34 | putchar ('\n'); | ||
| 35 | |||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | /* Writes C to the console. */ | ||
| 40 | int | ||
| 41 | putchar (int c) | ||
| 42 | { | ||
| 43 | char c2 = c; | ||
| 44 | write (STDOUT_FILENO, &c2, 1); | ||
| 45 | return c; | ||
| 46 | } | ||
| 47 | |||
| 48 | /* Auxiliary data for vhprintf_helper(). */ | ||
| 49 | struct vhprintf_aux | ||
| 50 | { | ||
| 51 | char buf[64]; /* Character buffer. */ | ||
| 52 | char *p; /* Current position in buffer. */ | ||
| 53 | int char_cnt; /* Total characters written so far. */ | ||
| 54 | int handle; /* Output file handle. */ | ||
| 55 | }; | ||
| 56 | |||
| 57 | static void add_char (char, void *); | ||
| 58 | static void flush (struct vhprintf_aux *); | ||
| 59 | |||
| 60 | /* Formats the printf() format specification FORMAT with | ||
| 61 | arguments given in ARGS and writes the output to the given | ||
| 62 | HANDLE. */ | ||
| 63 | int | ||
| 64 | vhprintf (int handle, const char *format, va_list args) | ||
| 65 | { | ||
| 66 | struct vhprintf_aux aux; | ||
| 67 | aux.p = aux.buf; | ||
| 68 | aux.char_cnt = 0; | ||
| 69 | aux.handle = handle; | ||
| 70 | __vprintf (format, args, add_char, &aux); | ||
| 71 | flush (&aux); | ||
| 72 | return aux.char_cnt; | ||
| 73 | } | ||
| 74 | |||
| 75 | /* Adds C to the buffer in AUX, flushing it if the buffer fills | ||
| 76 | up. */ | ||
| 77 | static void | ||
| 78 | add_char (char c, void *aux_) | ||
| 79 | { | ||
| 80 | struct vhprintf_aux *aux = aux_; | ||
| 81 | *aux->p++ = c; | ||
| 82 | if (aux->p >= aux->buf + sizeof aux->buf) | ||
| 83 | flush (aux); | ||
| 84 | aux->char_cnt++; | ||
| 85 | } | ||
| 86 | |||
| 87 | /* Flushes the buffer in AUX. */ | ||
| 88 | static void | ||
| 89 | flush (struct vhprintf_aux *aux) | ||
| 90 | { | ||
| 91 | if (aux->p > aux->buf) | ||
| 92 | write (aux->handle, aux->buf, aux->p - aux->buf); | ||
| 93 | aux->p = aux->buf; | ||
| 94 | } | ||
