* same with xv6
[mascara-docs.git] / i386 / MIT / course / src / git.lab / lib / console.c
blobfe35ff71f378a68390cece6bffd7d5849153c1bb
2 #include <inc/string.h>
3 #include <inc/lib.h>
5 void
6 cputchar(int ch)
8 char c = ch;
10 // Unlike standard Unix's putchar,
11 // the cputchar function _always_ outputs to the system console.
12 sys_cputs(&c, 1);
15 int
16 getchar(void)
18 unsigned char c;
19 int r;
21 // JOS does, however, support standard _input_ redirection,
22 // allowing the user to redirect script files to the shell and such.
23 // getchar() reads a character from file descriptor 0.
24 r = read(0, &c, 1);
25 if (r < 0)
26 return r;
27 if (r < 1)
28 return -E_EOF;
29 return c;
33 // "Real" console file descriptor implementation.
34 // The putchar/getchar functions above will still come here by default,
35 // but now can be redirected to files, pipes, etc., via the fd layer.
37 static ssize_t devcons_read(struct Fd*, void*, size_t);
38 static ssize_t devcons_write(struct Fd*, const void*, size_t);
39 static int devcons_close(struct Fd*);
40 static int devcons_stat(struct Fd*, struct Stat*);
42 struct Dev devcons =
44 .dev_id = 'c',
45 .dev_name = "cons",
46 .dev_read = devcons_read,
47 .dev_write = devcons_write,
48 .dev_close = devcons_close,
49 .dev_stat = devcons_stat
52 int
53 iscons(int fdnum)
55 int r;
56 struct Fd *fd;
58 if ((r = fd_lookup(fdnum, &fd)) < 0)
59 return r;
60 return fd->fd_dev_id == devcons.dev_id;
63 int
64 opencons(void)
66 int r;
67 struct Fd* fd;
69 if ((r = fd_alloc(&fd)) < 0)
70 return r;
71 if ((r = sys_page_alloc(0, fd, PTE_P|PTE_U|PTE_W|PTE_SHARE)) < 0)
72 return r;
73 fd->fd_dev_id = devcons.dev_id;
74 fd->fd_omode = O_RDWR;
75 return fd2num(fd);
78 static ssize_t
79 devcons_read(struct Fd *fd, void *vbuf, size_t n)
81 int c;
83 if (n == 0)
84 return 0;
86 while ((c = sys_cgetc()) == 0)
87 sys_yield();
88 if (c < 0)
89 return c;
90 if (c == 0x04) // ctl-d is eof
91 return 0;
92 *(char*)vbuf = c;
93 return 1;
96 static ssize_t
97 devcons_write(struct Fd *fd, const void *vbuf, size_t n)
99 int tot, m;
100 char buf[128];
102 // mistake: have to nul-terminate arg to sys_cputs,
103 // so we have to copy vbuf into buf in chunks and nul-terminate.
104 for (tot = 0; tot < n; tot += m) {
105 m = n - tot;
106 if (m > sizeof(buf) - 1)
107 m = sizeof(buf) - 1;
108 memmove(buf, (char*)vbuf + tot, m);
109 sys_cputs(buf, m);
111 return tot;
114 static int
115 devcons_close(struct Fd *fd)
117 USED(fd);
119 return 0;
122 static int
123 devcons_stat(struct Fd *fd, struct Stat *stat)
125 strcpy(stat->st_name, "<cons>");
126 return 0;