shithub: femtolisp

Download patch

ref: 4ce9616cb0aba86a30097ae04eb679f1956d30ec
parent: 22bf74f3ba2d91944c38a542461c3349eb566ef5
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Jan 4 19:35:49 EST 2025

add io-truncate

Fixes: https://todo.sr.ht/~ft/femtolisp/37

--- a/ios.c
+++ b/ios.c
@@ -468,24 +468,23 @@
 	return fdpos;
 }
 
-size_t
-ios_trunc(ios_t *s, size_t size)
+int
+ios_trunc(ios_t *s, off_t size)
 {
-	if(s->state == bst_closed)
-		return 0;
+	if(s->state == bst_closed || s->readonly || size < 0)
+		return -1;
 	if(s->bm == bm_mem){
-		if(size == s->size)
-			return s->size;
-		if(size < s->size){
-			if(s->bpos > size)
+		if((size_t)size == s->size)
+			return 0;
+		if((size_t)size < s->size){
+			if(s->bpos > (size_t)size)
 				s->bpos = size;
 		}else if(_buf_realloc(s, size) == nil)
-			return s->size;
+			return -1;
 		s->size = size;
-		return size;
+		return 0;
 	}
-	// FIXME
-	return 0;
+	return ios_flush(s) == 0 ? ftruncate(s->fd, size) : -1;
 }
 
 bool
--- a/ios.h
+++ b/ios.h
@@ -25,12 +25,12 @@
 }ios_loc_t;
 
 typedef struct {
-	uint8_t *buf;		// start of buffer
-	size_t maxsize;   // space allocated to buffer
-	size_t size;	  // length of valid data in buf, >=ndirty
-	size_t bpos;	  // current position in buffer
-	size_t ndirty;	// # bytes at &buf[0] that need to be written
-	off_t fpos;	   // cached file pos
+	uint8_t *buf; // start of buffer
+	size_t maxsize; // space allocated to buffer
+	size_t size; // length of valid data in buf, >=ndirty
+	size_t bpos; // current position in buffer
+	size_t ndirty; // # bytes at &buf[0] that need to be written
+	off_t fpos; // cached file pos
 	bufmode_t bm;
 	int colnowait;
 
@@ -74,7 +74,7 @@
 off_t ios_seek_end(ios_t *s);
 off_t ios_skip(ios_t *s, off_t offs);  // relative seek
 off_t ios_pos(ios_t *s);  // get current position
-size_t ios_trunc(ios_t *s, size_t size);
+int ios_trunc(ios_t *s, off_t size);
 bool ios_eof(ios_t *s);
 int ios_flush(ios_t *s);
 void ios_close(ios_t *s);
--- a/iostream.c
+++ b/iostream.c
@@ -180,6 +180,15 @@
 	return FL_void;
 }
 
+BUILTIN("io-truncate", io_truncate)
+{
+	argcount(nargs, 2);
+	ios_t *s = toiostream(args[0]);
+	if(ios_trunc(s, tooffset(args[1])) < 0)
+		lerrorf(FL_IOError, "truncation failed");
+	return FL_void;
+}
+
 BUILTIN("io-discardbuffer", io_discardbuffer)
 {
 	argcount(nargs, 1);