• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 /* File operation towards STDIN, STDOUT and STDERR */
14 
15 #include "fd.h"
16 #include <assert.h>
17 #include <errno.h>
18 #include <sys/types.h>
19 #include <syscall_arch.h>
20 #include <sys/ioctl.h>
21 #include <sys/mman.h>
22 #include <chcore/memory.h>
23 #include <termios.h>
24 
25 #include <chcore-internal/procmgr_defs.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <raw_syscall.h>
29 #include "stdio.h"
30 
put(char buffer[],unsigned size)31 static void put(char buffer[], unsigned size)
32 {
33     chcore_syscall2(CHCORE_SYS_putstr, (vaddr_t)buffer, size);
34 }
35 
36 #define MAX_LINE_SIZE 4095
37 
chcore_stdio_fcntl(int fd,int cmd,int arg)38 int chcore_stdio_fcntl(int fd, int cmd, int arg)
39 {
40     int new_fd, ret = 0;
41 
42     switch (cmd) {
43     case F_DUPFD_CLOEXEC:
44     case F_DUPFD: {
45         new_fd = dup_fd_content(fd, arg);
46         return new_fd;
47     }
48     default:
49         return -EINVAL;
50     }
51     return -1;
52 }
53 
54 /* STDIN */
chcore_stdio_read(int fd,void * buf,size_t count)55 static ssize_t chcore_stdio_read(int fd, void *buf, size_t count)
56 {
57     return -EINVAL;
58 }
59 
chcore_stdin_write(int fd,void * buf,size_t count)60 static ssize_t chcore_stdin_write(int fd, void *buf, size_t count)
61 {
62     return -EINVAL;
63 }
64 
chcore_stdin_close(int fd)65 static int chcore_stdin_close(int fd)
66 {
67     free_fd(fd);
68     return 0;
69 }
70 
chcore_stdio_ioctl(int fd,unsigned long request,void * arg)71 static int chcore_stdio_ioctl(int fd, unsigned long request, void *arg)
72 {
73     /* A fake window size */
74     if (request == TIOCGWINSZ) {
75         struct winsize *ws;
76 
77         ws = (struct winsize *)arg;
78         ws->ws_row = 30;
79         ws->ws_col = 80;
80         ws->ws_xpixel = 0;
81         ws->ws_ypixel = 0;
82         return 0;
83     }
84     struct fd_desc *fdesc = fd_dic[fd];
85     assert(fdesc);
86     switch (request) {
87     case TCGETS: {
88         struct termios *t = (struct termios *)arg;
89         *t = fdesc->termios;
90         return 0;
91     }
92     case TCSETS:
93     case TCSETSW:
94     case TCSETSF: {
95         struct termios *t = (struct termios *)arg;
96         fdesc->termios = *t;
97         return 0;
98     }
99     }
100     warn("Unsupported ioctl fd=%d, cmd=0x%lx, arg=0x%lx\n", fd, request, arg);
101     return 0;
102 }
103 
chcore_stdio_poll(int fd,struct pollarg * arg)104 static int chcore_stdio_poll(int fd, struct pollarg *arg)
105 {
106     return -EINVAL;
107 }
108 
109 struct fd_ops stdin_ops = {
110     .read = chcore_stdio_read,
111     .write = chcore_stdin_write,
112     .close = chcore_stdin_close,
113     .poll = chcore_stdio_poll,
114     .ioctl = chcore_stdio_ioctl,
115     .fcntl = chcore_stdio_fcntl,
116 };
117 
118 /* STDOUT */
119 #define STDOUT_BUFSIZE 1024
120 
chcore_stdout_write(int fd,void * buf,size_t count)121 static ssize_t chcore_stdout_write(int fd, void *buf, size_t count)
122 {
123 
124     char buffer[STDOUT_BUFSIZE];
125     size_t size = 0;
126 
127     for (char *p = buf; p < (char *)buf + count; p++) {
128         if (size + 2 > STDOUT_BUFSIZE) {
129             put(buffer, size);
130             size = 0;
131         }
132 
133         if (*p == '\n') {
134             buffer[size++] = '\r';
135         }
136         buffer[size++] = *p;
137     }
138 
139     if (size > 0) {
140         put(buffer, size);
141     }
142 
143     return count;
144 }
145 
chcore_stdout_close(int fd)146 static int chcore_stdout_close(int fd)
147 {
148     free_fd(fd);
149     return 0;
150 }
151 
152 struct fd_ops stdout_ops = {
153     .read = chcore_stdio_read,
154     .write = chcore_stdout_write,
155     .close = chcore_stdout_close,
156     .poll = chcore_stdio_poll,
157     .ioctl = chcore_stdio_ioctl,
158     .fcntl = chcore_stdio_fcntl,
159 };
160 
161 /* STDERR */
chcore_stderr_read(int fd,void * buf,size_t count)162 static ssize_t chcore_stderr_read(int fd, void *buf, size_t count)
163 {
164     return -EINVAL;
165 }
166 
chcore_stderr_write(int fd,void * buf,size_t count)167 static ssize_t chcore_stderr_write(int fd, void *buf, size_t count)
168 {
169     return chcore_stdout_write(fd, buf, count);
170 }
171 
chcore_stderr_close(int fd)172 static int chcore_stderr_close(int fd)
173 {
174     free_fd(fd);
175     return 0;
176 }
177 
178 struct fd_ops stderr_ops = {
179     .read = chcore_stderr_read,
180     .write = chcore_stderr_write,
181     .close = chcore_stderr_close,
182     .poll = NULL,
183     .ioctl = chcore_stdio_ioctl,
184     .fcntl = chcore_stdio_fcntl,
185 };