Skip to content

Commit f69cf1e

Browse files
authored
wasip2: Implement isatty (WebAssembly#674)
This commit fills out the implementation of `isatty` for WASIp2 by calling the various `wasi:*/terminal-*` functions. The presence of a terminal indicates that it's a TTY, and otherwise it's a normal fd but not a tty.
1 parent 624325f commit f69cf1e

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

libc-bottom-half/headers/private/wasi/descriptor_table.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ typedef struct descriptor_vtable_t {
5757
int (*fcntl_getfl)(void*);
5858
/// Implementation of `fnctl(fd, F_SETFL)`.
5959
int (*fcntl_setfl)(void*, int);
60+
/// Implementation of `isatty`-the-function.
61+
int (*isatty)(void*);
6062

6163
// =====================================================================
6264
// Sockets-related APIs

libc-bottom-half/sources/isatty.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
int __isatty(int fd) {
1212
#ifdef __wasilibc_use_wasip2
1313
// Translate the file descriptor into an internal handle
14-
filesystem_borrow_descriptor_t file_handle;
15-
if (fd_to_file_handle(fd, &file_handle) < 0)
14+
descriptor_table_entry_t *entry = descriptor_table_get_ref(fd);
15+
if (!entry)
1616
return 0;
17+
if (!entry->vtable->isatty) {
18+
errno = ENOTTY;
19+
return 0;
20+
}
1721

18-
errno = ENOTTY;
19-
return 0;
22+
return entry->vtable->isatty(entry->data);
2023
#else
2124

2225
__wasi_fdstat_t statbuf;

libc-bottom-half/sources/wasip2_stdio.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,45 @@ static int stdio_fcntl_getfl(void *data) {
9191
}
9292
}
9393

94+
static int stdio_isatty(void *data) {
95+
stdio_t *stdio = (stdio_t *)data;
96+
switch (stdio->fd) {
97+
case 0: {
98+
terminal_stdin_own_terminal_input_t term_input;
99+
if (!terminal_stdin_get_terminal_stdin(&term_input))
100+
break;
101+
terminal_input_terminal_input_drop_own(term_input);
102+
return 1;
103+
}
104+
case 1: {
105+
terminal_stdout_own_terminal_output_t term_output;
106+
if (!terminal_stdout_get_terminal_stdout(&term_output))
107+
break;
108+
terminal_output_terminal_output_drop_own(term_output);
109+
return 1;
110+
}
111+
case 2: {
112+
terminal_stderr_own_terminal_output_t term_output;
113+
if (!terminal_stderr_get_terminal_stderr(&term_output))
114+
break;
115+
terminal_output_terminal_output_drop_own(term_output);
116+
return 1;
117+
}
118+
default:
119+
break;
120+
}
121+
122+
errno = ENOTTY;
123+
return 0;
124+
}
125+
94126
static descriptor_vtable_t stdio_vtable = {
95127
.free = stdio_free,
96128
.get_read_stream = stdio_get_read_stream,
97129
.get_write_stream = stdio_get_write_stream,
98130
.fstat = stdio_fstat,
99131
.fcntl_getfl = stdio_fcntl_getfl,
132+
.isatty = stdio_isatty,
100133
};
101134

102135
static int stdio_add(int fd) {

test/src/isatty.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,16 @@ int main(void)
2828

2929
// make sure isatty can be called on stdio fds, but don't test what the
3030
// actual value is yet.
31-
isatty(0);
31+
int stdin_isatty = isatty(0);
3232
TEST(errno != EBADF);
33-
isatty(1);
33+
int stdout_isatty = isatty(1);
3434
TEST(errno != EBADF);
35-
isatty(2);
35+
int stderr_isatty = isatty(2);
3636
TEST(errno != EBADF);
3737

38+
printf("stdin isatty: %d\n", stdin_isatty);
39+
printf("stdout isatty: %d\n", stdout_isatty);
40+
printf("stderr isatty: %d\n", stderr_isatty);
41+
3842
return t_status;
3943
}

0 commit comments

Comments
 (0)