shithub: femtolisp

Download patch

ref: 10e8e99e07e8bfc3d2fc68efe95a572e8adc65a0
parent: 23e857034070229923a7b3b800d608ab0e14236d
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Nov 3 13:45:02 EST 2024

add io-wait

--- a/ios.c
+++ b/ios.c
@@ -844,6 +844,32 @@
 }
 
 int
+ios_wait(ios_t *s, int us)
+{
+	if(s->bpos < s->size)
+		return 1;
+	if(s->_eof)
+		return IOS_EOF;
+#ifdef __plan9__
+	USED(us);
+	return 1; // FIXME(sigrid): wait for input, but not too much
+#else
+	struct timeval t, *pt = nil;
+	if(us >= 0){
+		t.tv_sec = us / 1000000;
+		t.tv_usec = us % 1000000;
+		pt = &t;
+	}
+	fd_set f;
+	FD_ZERO(&f);
+	FD_SET(s->fd, &f);
+	int r;
+	while((r = select(s->fd+1, &f, nil, nil, pt)) == EINTR);
+	return r && FD_ISSET(s->fd, &f);
+#endif
+}
+
+int
 ios_getutf8(ios_t *s, Rune *r)
 {
 	int c;
--- a/ios.h
+++ b/ios.h
@@ -84,6 +84,8 @@
 // ensure at least n bytes are buffered if possible. returns # available.
 size_t ios_readprep(ios_t *from, size_t n);
 
+int ios_wait(ios_t *s, int us);
+
 /* stream creation */
 ios_t *ios_file(ios_t *s, char *fname, int rd, int wr, int create, int trunc);
 ios_t *ios_mem(ios_t *s, size_t initsize);
--- a/iostream.c
+++ b/iostream.c
@@ -145,6 +145,20 @@
 	return mk_rune(r);
 }
 
+BUILTIN("io-wait", io_wait)
+{
+	if(nargs > 2)
+		argcount(nargs, 2);
+	ios_t *s = toiostream(args[0]);
+	int us = nargs > 0 ? tooffset(args[1]) : -1;
+	int r = ios_wait(s, us);
+	if(r >= 0)
+		return r ? FL_T : FL_F;
+	if(r == IOS_EOF)
+		return FL_EOF;
+	lerrorf(IOError, "i/o error");
+}
+
 BUILTIN("io-putc", io_putc)
 {
 	argcount(nargs, 2);
@@ -198,7 +212,7 @@
 	ios_t *s = toiostream(args[0]);
 	size_t pos = toulong(args[1]);
 	off_t res = ios_seek(s, (off_t)pos);
-	if(res == -1)
+	if(res < 0)
 		return FL_F;
 	return FL_T;
 }
@@ -208,7 +222,7 @@
 	argcount(nargs, 1);
 	ios_t *s = toiostream(args[0]);
 	off_t res = ios_pos(s);
-	if(res == -1)
+	if(res < 0)
 		return FL_F;
 	return size_wrap((size_t)res);
 }