Skip to content

Commit 654d399

Browse files
authored
Add function that checks whether a file handle points to a TTY device. (#1908)
* Add function that checks whether a file is a terminal device. * support isTTY function for NodeJS backend. * don't accidentally interpret 'false' string as truthy number * less code duplication.
1 parent 6a6ad30 commit 654d399

File tree

5 files changed

+45
-5
lines changed

5 files changed

+45
-5
lines changed

libs/base/System/File/Meta.idr

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ prim__fileModifiedTime : FilePtr -> PrimIO Int
2323
%foreign support "idris2_fileStatusTime"
2424
prim__fileStatusTime : FilePtr -> PrimIO Int
2525

26+
%foreign support "idris2_fileIsTTY"
27+
"node:lambda:fp=>Number(require('tty').isatty(fp.fd))"
28+
prim__fileIsTTY : FilePtr -> PrimIO Int
29+
2630
||| Check if a file exists for reading.
2731
export
2832
exists : HasIO io => String -> io Bool
@@ -75,3 +79,9 @@ fPoll : HasIO io => File -> io Bool
7579
fPoll (FHandle f)
7680
= do p <- primIO (prim__fPoll f)
7781
pure (p > 0)
82+
83+
||| Check whether the given File is a terminal device.
84+
export
85+
isTTY : HasIO io => (h : File) -> io Bool
86+
isTTY (FHandle f) = (/= 0) <$> primIO (prim__fileIsTTY f)
87+

support/c/idris_file.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ void idris2_closeFile(FILE* f) {
3030
IDRIS2_VERIFY(fclose(f) == 0, "fclose failed: %s", strerror(errno));
3131
}
3232

33+
int idris2_getFileNo(FILE* f) {
34+
#ifdef _WIN32
35+
return win32_getFileNo(f);
36+
#else
37+
return fileno(f);
38+
#endif
39+
}
40+
3341
int idris2_fileError(FILE* f) {
3442
return ferror(f);
3543
}
@@ -61,7 +69,7 @@ int idris2_removeFile(const char *filename) {
6169
}
6270

6371
int idris2_fileSize(FILE* f) {
64-
int fd = fileno(f);
72+
int fd = idris2_getFileNo(f);
6573

6674
struct stat buf;
6775
if (fstat(fd, &buf) == 0) {
@@ -80,7 +88,7 @@ int idris2_fpoll(FILE* f)
8088
struct timeval timeout;
8189
timeout.tv_sec = 1;
8290
timeout.tv_usec = 0;
83-
int fd = fileno(f);
91+
int fd = idris2_getFileNo(f);
8492

8593
FD_ZERO(&x);
8694
FD_SET(fd, &x);
@@ -172,7 +180,7 @@ int idris2_eof(FILE* f) {
172180
}
173181

174182
int idris2_fileAccessTime(FILE* f) {
175-
int fd = fileno(f);
183+
int fd = idris2_getFileNo(f);
176184

177185
struct stat buf;
178186
if (fstat(fd, &buf) == 0) {
@@ -183,7 +191,7 @@ int idris2_fileAccessTime(FILE* f) {
183191
}
184192

185193
int idris2_fileModifiedTime(FILE* f) {
186-
int fd = fileno(f);
194+
int fd = idris2_getFileNo(f);
187195

188196
struct stat buf;
189197
if (fstat(fd, &buf) == 0) {
@@ -194,7 +202,7 @@ int idris2_fileModifiedTime(FILE* f) {
194202
}
195203

196204
int idris2_fileStatusTime(FILE* f) {
197-
int fd = fileno(f);
205+
int fd = idris2_getFileNo(f);
198206

199207
struct stat buf;
200208
if (fstat(fd, &buf) == 0) {
@@ -204,6 +212,15 @@ int idris2_fileStatusTime(FILE* f) {
204212
}
205213
}
206214

215+
int idris2_fileIsTTY(FILE* f) {
216+
int fd = idris2_getFileNo(f);
217+
#ifdef _WIN32
218+
return win32_isTTY(fd);
219+
#else
220+
return isatty(fd);
221+
#endif
222+
}
223+
207224
FILE* idris2_stdin() {
208225
return stdin;
209226
}

support/c/idris_file.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ int idris2_eof(FILE* f);
3838
int idris2_fileAccessTime(FILE* f);
3939
int idris2_fileModifiedTime(FILE* f);
4040
int idris2_fileStatusTime(FILE* f);
41+
int idris2_fileIsTTY(FILE* f);
4142

4243
FILE* idris2_stdin();
4344
FILE* idris2_stdout();

support/c/windows/win_utils.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,11 @@ long win32_getNProcessors() {
179179
;
180180
}
181181

182+
int win32_getFileNo(FILE* f) {
183+
return _fileno(f);
184+
}
185+
186+
int win32_isTTY(int fd) {
187+
return _isatty(fd);
188+
}
189+

support/c/windows/win_utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <stdint.h>
22
#include <stdio.h>
3+
#include <io.h>
34

45
#pragma once
56

@@ -14,3 +15,6 @@ int win32_getErrno();
1415
int win32_getPID();
1516
long win32_getNProcessors();
1617

18+
int win32_getFileNo(FILE*);
19+
int win32_isTTY(int fd);
20+

0 commit comments

Comments
 (0)