ref: facd3c51451032dd786eb32ca87b53b79e5aebee
parent: caef97a3e1fc28e966e4695b839f173d8f0e30e7
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Jan 1 20:30:57 EST 2025
io streams: preserve the filename even after close Also marked the stream as closed properly and do not try to do anything with it anymore. Working with already closed streams is not supposed to work.
--- a/ios.c
+++ b/ios.c
@@ -208,6 +208,9 @@
size_t tot = 0;
size_t got, avail;
+ if(s->state == bst_closed)
+ return 0;
+
while(n > 0){
avail = s->size - s->bpos;
@@ -270,7 +273,8 @@
return _ios_read(s, dest, n, 0);
}
-size_t
+// ensure at least n bytes are buffered if possible. returns # available.
+static size_t
ios_readprep(ios_t *s, size_t n)
{
if(s->state == bst_wr && s->bm != bm_mem){
@@ -314,10 +318,8 @@
size_t
ios_write(ios_t *s, const void *data, size_t n)
{
- if(s->readonly)
+ if(s->readonly || s->state == bst_closed || n == 0)
return 0;
- if(n == 0)
- return 0;
size_t space;
size_t wrote = 0;
@@ -371,6 +373,8 @@
off_t
ios_seek(ios_t *s, off_t pos)
{
+ if(s->state == bst_closed)
+ return 0;
s->_eof = 0;
if(s->bm == bm_mem){
if((size_t)pos > s->size)
@@ -389,6 +393,8 @@
off_t
ios_seek_end(ios_t *s)
{
+ if(s->state == bst_closed)
+ return 0;
s->_eof = 1;
if(s->bm == bm_mem){
s->bpos = s->size;
@@ -405,6 +411,8 @@
off_t
ios_skip(ios_t *s, off_t offs)
{
+ if(s->state == bst_closed)
+ return 0;
if(offs != 0){
if(offs > 0){
if(offs <= (off_t)(s->size-s->bpos)){
@@ -440,6 +448,8 @@
off_t
ios_pos(ios_t *s)
{
+ if(s->state == bst_closed)
+ return 0;
if(s->bm == bm_mem)
return (off_t)s->bpos;
@@ -461,6 +471,8 @@
size_t
ios_trunc(ios_t *s, size_t size)
{
+ if(s->state == bst_closed)
+ return 0;
if(s->bm == bm_mem){
if(size == s->size)
return s->size;
@@ -472,13 +484,15 @@
s->size = size;
return size;
}
- //todo
+ // FIXME
return 0;
}
-int
+bool
ios_eof(ios_t *s)
{
+ if(s->state == bst_closed)
+ return true;
if(s->bm == bm_mem)
return s->_eof;
return s->fd == -1 || s->_eof;
@@ -534,6 +548,8 @@
void
ios_close(ios_t *s)
{
+ if(s->state == bst_closed)
+ return;
ios_flush(s);
if(s->fd != -1 && s->ownfd)
close(s->fd);
@@ -542,6 +558,12 @@
MEM_FREE(s->buf);
s->buf = nil;
s->size = s->maxsize = s->bpos = 0;
+ s->state = bst_closed;
+}
+
+void
+ios_free(ios_t *s)
+{
if(s->loc.filename != emptystr){
MEM_FREE(s->loc.filename);
s->loc.filename = emptystr;
@@ -953,6 +975,8 @@
char *str;
int c;
+ if(s->state == bst_closed)
+ return -1;
/* skip allocations if no buffering needed */
if(s->bm == bm_none && (s->state == bst_none || s->state == bst_wr))
return vdprintf(s->fd, format, args);
--- a/ios.h
+++ b/ios.h
@@ -12,6 +12,7 @@
bst_none,
bst_rd,
bst_wr,
+ bst_closed,
}bufstate_t;
#define IOS_INLSIZE 128
@@ -74,9 +75,10 @@
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_eof(ios_t *s);
+bool ios_eof(ios_t *s);
int ios_flush(ios_t *s);
void ios_close(ios_t *s);
+void ios_free(ios_t *s);
uint8_t *ios_takebuf(ios_t *s, size_t *psize); // null-terminate and release buffer to caller
// set buffer space to use
int ios_setbuf(ios_t *s, uint8_t *buf, size_t size, int own);
@@ -85,8 +87,6 @@
size_t ios_copy(ios_t *to, ios_t *from, size_t nbytes);
size_t ios_copyall(ios_t *to, ios_t *from);
size_t ios_copyuntil(ios_t *to, ios_t *from, uint8_t delim);
-// 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, double ws);
--- a/iostream.c
+++ b/iostream.c
@@ -22,6 +22,7 @@
{
ios_t *s = value2c(ios_t*, self);
ios_close(s);
+ ios_free(s);
}
static void