Skip to content

Commit 743873c

Browse files
ZERICO2005mateoconlechuga
authored andcommitted
add <unistd.h>, isatty, and fileno
1 parent ea4391f commit 743873c

8 files changed

Lines changed: 279 additions & 0 deletions

File tree

src/libc/__fileioc_stdio.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,42 @@
44
#include <cdefs.h>
55
#include <fileioc.h>
66
#include <stdio.h>
7+
#include <stdbool.h>
8+
9+
/*
10+
* fd mapping:
11+
* STDIN_FILENO = 0
12+
* STDOUT_FILENO = 1
13+
* STDERR_FILENO = 2
14+
* fileioc slot 1 = 3
15+
* fileioc slot 2 = 4
16+
* fileioc slot 3 = 5
17+
* fileioc slot 4 = 6
18+
* fileioc slot 5 = 7
19+
*/
720

821
__BEGIN_DECLS
922

1023
extern FILE _file_streams[FOPEN_MAX];
1124

25+
#define FILEIOC_MIN_FD_SLOT 3
26+
#define FILEIOC_MAX_FD_SLOT (FILEIOC_MIN_FD_SLOT + (FOPEN_MAX - 1))
27+
28+
static inline int fileioc_slot_to_fd(ti_var_t slot)
29+
{
30+
return (int)(slot + (FILEIOC_MIN_FD_SLOT - 1));
31+
}
32+
33+
static inline ti_var_t fd_to_fileioc_slot(int fd)
34+
{
35+
return (ti_var_t)(fd - (FILEIOC_MIN_FD_SLOT - 1));
36+
}
37+
38+
static inline bool is_fd_a_fileioc_slot(int fd)
39+
{
40+
return (fd >= FILEIOC_MIN_FD_SLOT && fd <= FILEIOC_MAX_FD_SLOT);
41+
}
42+
1243
__END_DECLS
1344

1445
#endif /* __FILEIOC_STDIO_H */

src/libc/fileno.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "__fileioc_stdio.h"
2+
#include <errno.h>
3+
#include <unistd.h>
4+
5+
int __attribute__((weak)) fileno(FILE *stream)
6+
{
7+
if (stream == NULL)
8+
{
9+
// invalid stream
10+
errno = EBADF;
11+
return -1;
12+
}
13+
14+
if (stream == stdin)
15+
{
16+
return STDIN_FILENO;
17+
}
18+
if (stream == stdout)
19+
{
20+
return STDOUT_FILENO;
21+
}
22+
if (stream == stderr)
23+
{
24+
return STDERR_FILENO;
25+
}
26+
27+
return fileioc_slot_to_fd(stream->slot);
28+
}

src/libc/include/stdio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ int remove(const char *filename);
8181

8282
int rename(const char *old_filename, const char *new_filename);
8383

84+
int fileno(FILE *stream);
85+
8486
/* standard impls */
8587

8688
int getchar(void);

src/libc/include/unistd.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef _UNISTD_H
2+
#define _UNISTD_H
3+
4+
#include <cdefs.h>
5+
6+
#define STDIN_FILENO 0
7+
#define STDOUT_FILENO 1
8+
#define STDERR_FILENO 2
9+
10+
__BEGIN_DECLS
11+
12+
int isatty(int fd);
13+
14+
__END_DECLS
15+
16+
#endif /* _UNISTD_H */

src/libc/isatty.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "__fileioc_stdio.h"
2+
#include <unistd.h>
3+
#include <errno.h>
4+
5+
int __attribute__((weak)) isatty(int fd)
6+
{
7+
if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
8+
{
9+
return 1;
10+
}
11+
if (is_fd_a_fileioc_slot(fd))
12+
{
13+
// not a terminal
14+
errno = ENOTTY;
15+
return 0;
16+
}
17+
// invalid fd
18+
errno = EBADF;
19+
return 0;
20+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"transfer_files":
3+
[
4+
"bin/DEMO.8xp"
5+
],
6+
"target":
7+
{
8+
"name": "DEMO",
9+
"isASM": true
10+
},
11+
"sequence":
12+
[
13+
"action|launch",
14+
"delay|500",
15+
"hashWait|1",
16+
"key|enter",
17+
"delay|300",
18+
"hashWait|2"
19+
],
20+
"hashes":
21+
{
22+
"1":
23+
{
24+
"description": "All tests passed",
25+
"start": "vram_start",
26+
"size": "vram_16_size",
27+
"expected_CRCs": [ "38E2AD5A" ]
28+
},
29+
"2":
30+
{
31+
"description": "Test homescreen cleared",
32+
"start": "vram_start",
33+
"size": "vram_16_size",
34+
"expected_CRCs": [ "FFAF89BA", "101734A5", "9DA19F44", "A32840C8", "349F4775" ]
35+
}
36+
}
37+
}

test/standalone/fileno/makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# ----------------------------
2+
# Makefile Options
3+
# ----------------------------
4+
5+
NAME = DEMO
6+
ICON = icon.png
7+
DESCRIPTION = "CE C Toolchain Demo"
8+
COMPRESSED = NO
9+
ARCHIVED = NO
10+
11+
CFLAGS = -Wall -Wextra -ffreestanding -Oz
12+
CXXFLAGS = -Wall -Wextra -ffreestanding -Oz
13+
14+
# ----------------------------
15+
16+
include $(shell cedev-config --makefile)
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#include <stdbool.h>
2+
#include <stdio.h>
3+
#include <ti/screen.h>
4+
#include <ti/getcsc.h>
5+
#include <ti/sprintf.h>
6+
#include <sys/util.h>
7+
#include <errno.h>
8+
#include <unistd.h>
9+
#include <stdint.h>
10+
#include <algorithm>
11+
12+
#define C(expr) if (!(expr)) { return __LINE__; }
13+
14+
static const char *name_1 = "foo1";
15+
static const char *name_2 = "bar2";
16+
17+
constexpr int FILEIOC_SLOT_COUNT = 5;
18+
constexpr int MIN_FILEIOC_SLOT = 1 + std::max(STDIN_FILENO, std::max(STDOUT_FILENO, STDERR_FILENO));
19+
constexpr int MAX_FILEIOC_SLOT = MIN_FILEIOC_SLOT + (FILEIOC_SLOT_COUNT - 1);
20+
21+
static bool is_fileioc_fd(int fd) {
22+
if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) {
23+
return false;
24+
}
25+
return (fd >= MIN_FILEIOC_SLOT && fd <= MAX_FILEIOC_SLOT);
26+
}
27+
28+
int run_tests(void) {
29+
30+
// create some files
31+
FILE *file_1 = fopen(name_1, "w");
32+
C(file_1 != NULL);
33+
FILE *file_2 = fopen(name_2, "a+");
34+
C(file_2 != NULL);
35+
36+
C(errno == 0);
37+
38+
// test fileno
39+
40+
int fileno_1 = fileno(file_1);
41+
C(is_fileioc_fd(fileno_1));
42+
int fileno_2 = fileno(file_2);
43+
C(is_fileioc_fd(fileno_2));
44+
45+
C(fileno_1 != fileno_2);
46+
C(errno == 0);
47+
48+
int fileno_stdin = fileno(stdin);
49+
int fileno_stdout = fileno(stdout);
50+
int fileno_stderr = fileno(stderr);
51+
52+
C(fileno_stdin == STDIN_FILENO);
53+
C(fileno_stdout == STDOUT_FILENO);
54+
55+
// we current define stdout to be stderr
56+
if (stdout != stderr) {
57+
C(fileno_stderr == STDERR_FILENO);
58+
} else {
59+
C(fileno_stderr == STDOUT_FILENO);
60+
}
61+
C(errno == 0);
62+
63+
int fileno_nullptr = fileno(nullptr);
64+
C(fileno_nullptr == -1);
65+
C(errno == EBADF);
66+
67+
errno = 0;
68+
69+
// we currently treat stdin/stdout/stderr as a tty/terminal
70+
C(isatty(fileno_stdin) == 1);
71+
C(isatty(fileno_stdout) == 1);
72+
C(isatty(fileno_stderr) == 1);
73+
C(errno == 0);
74+
75+
// test invalid fd
76+
C(isatty(-1) == 0);
77+
C(errno == EBADF);
78+
errno = 0;
79+
C(isatty(MAX_FILEIOC_SLOT + 1) == 0);
80+
C(errno == EBADF);
81+
errno = 0;
82+
83+
// test valid fd that are not a terminal
84+
C(isatty(fileno_1) == 0);
85+
C(errno == ENOTTY);
86+
errno = 0;
87+
C(isatty(fileno_2) == 0);
88+
C(errno == ENOTTY);
89+
errno = 0;
90+
91+
// remove the files
92+
C(fclose(file_1) == 0);
93+
file_1 = fopen(name_1, "r+");
94+
C(file_1 != NULL);
95+
C(fclose(file_2) == 0);
96+
C(remove(name_2) == 0);
97+
C(fclose(file_1) == 0);
98+
C(remove(name_1) == 0);
99+
C(errno == 0);
100+
101+
// attempt to read a removed file
102+
file_1 = fopen(name_1, "r");
103+
C(file_1 == NULL);
104+
105+
// discard errno value
106+
errno = 0;
107+
108+
return 0;
109+
}
110+
111+
extern "C" int main(void) {
112+
os_ClrHome();
113+
errno = 0;
114+
int failed_test = run_tests();
115+
if (errno != 0) {
116+
perror("errno");
117+
}
118+
if (failed_test != 0) {
119+
char buf[sizeof("Failed test L-8388608")];
120+
boot_sprintf(buf, "Failed test L%d", failed_test);
121+
puts(buf);
122+
} else {
123+
puts("All tests passed");
124+
}
125+
126+
while (!os_GetCSC());
127+
128+
return 0;
129+
}

0 commit comments

Comments
 (0)