shithub: sl

Download patch

ref: 6777c495b3f5ba30a7b2442e176433ebebef7ab7
parent: d239bae8435ef8dd6bd88c222f81708f3431b956
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Mar 7 19:07:31 EST 2025

write: throw an exception if write to the ios failed

Fixes: https://todo.sr.ht/~ft/sl/47

--- a/src/print.c
+++ b/src/print.c
@@ -7,10 +7,11 @@
 
 #define LOG2_10 3.321928094887362347870319429489
 
-static void
+static inline void
 outc(sl_ios *f, char c)
 {
-	ios_putc(f, c);
+	if(ios_putc(f, c) != 1)
+		lerrorf(sl_errio, "write failed");
 	if(c == '\n')
 		sl.hpos = 0;
 	else
@@ -20,7 +21,8 @@
 static inline void
 outsn(sl_ios *f, const char *s, usize n)
 {
-	ios_write(f, s, n);
+	if(ios_write(f, s, n) != n)
+		lerrorf(sl_errio, "write failed");
 	ssize w = u8_strwidth(s, n);
 	if(w > 0)
 		sl.hpos += w;
@@ -39,18 +41,23 @@
 	if(n > sl.scr_width-12)
 		n = 2;
 	int n0 = n;
-	ios_putc(f, '\n');
+	if(ios_putc(f, '\n') != 1)
+		goto err;
 	sl.vpos++;
 	sl.hpos = n;
 	while(n >= 8){
-		ios_putc(f, '\t');
+		if(ios_putc(f, '\t') != 1)
+			goto err;
 		n -= 8;
 	}
 	while(n){
-		ios_putc(f, ' ');
+		if(ios_putc(f, ' ') != 1)
+			goto err;
 		n--;
 	}
 	return n0;
+err:
+	lerrorf(sl_errio, "write failed");
 }
 
 void
@@ -382,10 +389,16 @@
 	sl_v label;
 	if((label = (sl_v)ptrhash_get(&sl.printconses, (void*)v)) != (sl_v)HT_NOTFOUND){
 		if(!ismarked(v)){
-			sl.hpos += ios_printf(f, "#%"PRIdPTR"#", (intptr)numval(label));
+			int n = ios_printf(f, "#%"PRIdPTR"#", (intptr)numval(label));
+			if(n < 1)
+				lerrorf(sl_errio, "write failed");
+			sl.hpos += n;
 			return true;
 		}
-		sl.hpos += ios_printf(f, "#%"PRIdPTR"=", (intptr)numval(label));
+		int n = ios_printf(f, "#%"PRIdPTR"=", (intptr)numval(label));
+		if(n < 1)
+			lerrorf(sl_errio, "write failed");
+		sl.hpos += n;
 	}
 	if(ismanaged(v))
 		unmark_cons(v);
@@ -402,9 +415,13 @@
 	}
 	sl.p_level++;
 
+	int n;
 	switch(tag(v)){
 	case TAG_NUM: case TAG_NUM1:
-		sl.hpos += ios_printf(f, "%"PRIdFIXNUM, numval(v));
+		n = ios_printf(f, "%"PRIdFIXNUM, numval(v));
+		if(n < 1)
+			lerrorf(sl_errio, "write failed");
+		sl.hpos += n;
 		break;
 	case TAG_SYM:
 		name = symbol_name(v);
@@ -641,14 +658,17 @@
 static void
 cvalue_printdata(sl_ios *f, void *data, usize len, sl_v type, int weak)
 {
+	int n;
 	if(type == sl_bytesym){
 		u8int ch = *(u8int*)data;
 		if(sl.print_princ)
 			outc(f, ch);
-		else if(weak)
-			sl.hpos += ios_printf(f, "0x%hhx", ch);
-		else
-			sl.hpos += ios_printf(f, "#byte(0x%hhx)", ch);
+		else{
+			n = ios_printf(f, weak ? "0x%hhx" : "#byte(0x%hhx)", ch);
+			if(n < 1)
+				goto err;
+			sl.hpos += n;
+		}
 	}else if(type == sl_runesym){
 		Rune r = *(Rune*)data;
 		char seq[UTFmax+1];
@@ -673,8 +693,12 @@
 			default:
 				if(sl_iswprint(r))
 					outs(f, seq);
-				else
-					sl.hpos += ios_printf(f, "x%04"PRIx32, r);
+				else{
+					n = ios_printf(f, "x%04"PRIx32, r);
+					if(n < 1)
+						goto err;
+					sl.hpos += n;
+				}
 				break;
 			}
 		}
@@ -697,9 +721,12 @@
 				rep = signbit(d) ? "-nan.0" : "+nan.0";
 			else
 				rep = signbit(d) ? "-wtf.0" : "+wtf.0";
-			if(type == sl_floatsym && !sl.print_princ && !weak)
-				sl.hpos += ios_printf(f, "#%s(%s)", symbol_name(type), rep);
-			else
+			if(type == sl_floatsym && !sl.print_princ && !weak){
+				n = ios_printf(f, "#%s(%s)", symbol_name(type), rep);
+				if(n < 1)
+					goto err;
+				sl.hpos += n;
+			}else
 				outs(f, rep);
 		}else if(d == 0){
 			if(1/d < 0)
@@ -719,14 +746,19 @@
 		}
 	}else if(type == sl_u64sym){
 		u64int ui64 = *(u64int*)data;
-		if(weak || sl.print_princ)
-			sl.hpos += ios_printf(f, "%"PRIu64, ui64);
-		else
-			sl.hpos += ios_printf(f, "#%s(%"PRIu64")", symbol_name(type), ui64);
+		n = (weak || sl.print_princ)
+			? ios_printf(f, "%"PRIu64, ui64)
+			: ios_printf(f, "#%s(%"PRIu64")", symbol_name(type), ui64);
+		if(n < 1)
+			goto err;
+		sl.hpos += n;
 	}else if(type == sl_bignumsym){
 		mpint *i = *(mpint**)data;
 		char *s = mptoa(i, 10, nil, 0);
-		sl.hpos += ios_printf(f, "%s", s);
+		n = ios_printf(f, "%s", s);
+		if(n < 1)
+			goto err;
+		sl.hpos += n;
 		MEM_FREE(s);
 	}else if(issymbol(type)){
 		// handle other integer prims. we know it's smaller than uint64
@@ -734,13 +766,15 @@
 		sl_numtype nt = sym_to_numtype(type);
 		if(valid_numtype(nt)){
 			s64int i64 = conv_to_s64(data, nt);
-			if(weak || sl.print_princ)
-				sl.hpos += ios_printf(f, "%"PRId64, i64);
-			else
-				sl.hpos += ios_printf(f, "#%s(%"PRId64")", symbol_name(type), i64);
+			n = (weak || sl.print_princ)
+				? ios_printf(f, "%"PRId64, i64)
+				: ios_printf(f, "#%s(%"PRId64")", symbol_name(type), i64);
 		}else{
-			sl.hpos += ios_printf(f, "#<%s>", symbol_name(type));
+			n = ios_printf(f, "#<%s>", symbol_name(type));
 		}
+		if(n < 1)
+			goto err;
+		sl.hpos += n;
 	}else if(iscons(type)){
 		if(car_(type) == sl_arraysym){
 			usize i;
@@ -775,12 +809,12 @@
 				if(!sl.print_princ)
 					outc(f, '"');
 				for(i = 0; i < cnt; i++, data = (char*)data + elsize){
-					int n = runetochar(buf, (Rune*)data);
+					n = runetochar(buf, (Rune*)data);
 					buf[n] = 0;
-					if(sl.print_princ)
-						ios_write(f, buf, n);
-					else
+					if(!sl.print_princ)
 						print_string(f, buf, n);
+					else if(ios_write(f, buf, n) != (usize)n)
+						goto err;
 				}
 				if(!sl.print_princ)
 					outc(f, '"');
@@ -807,6 +841,8 @@
 			outc(f, ')');
 		}
 	}
+err:
+	lerrorf(sl_errio, "write failed");
 }
 
 static void