From: Agathe Porte <gagath@debian.org>
Date: Fri, 3 Oct 2025 13:28:03 +0200
Subject: buffer: cast op implicitly

This fixes an -Wincompatible-pointer-types error between the generic
function pointer type in the buffer struct and the assignment of
read/write functions to the struct.

Signed-off-by: Agathe Porte <gagath@debian.org>
---
 buffer.h                            |  4 ++--
 buffer/bs_skip.c                    |  2 +-
 buffer/buffer_feed.c                |  4 ++--
 buffer/buffer_flush.c               |  4 ++--
 buffer/buffer_frombuf.c             |  2 +-
 buffer/buffer_init_read.c           |  2 +-
 buffer/buffer_init_read_allocbuf.c  |  2 +-
 buffer/buffer_init_write.c          |  2 +-
 buffer/buffer_init_write_allocbuf.c |  2 +-
 buffer/buffer_put.c                 |  6 +++---
 buffer/buffer_putflush.c            | 10 +++++-----
 buffer/buffer_tosa.c                |  2 +-
 test/uudecode.c                     |  6 +++---
 13 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/buffer.h b/buffer.h
index d35acc2..2c9c5fd 100644
--- a/buffer.h
+++ b/buffer.h
@@ -37,8 +37,8 @@ typedef struct buffer {
   int fd;		/* passed as first argument to op */
 } buffer;
 
-#define BUFFER_INIT(op,fd,buf,len) { (char*)(buf), 0, 0, (len), (op), NULL, NULL, (fd) }
-#define BUFFER_INIT_FREE(op,fd,buf,len) { (buf), 0, 0, (len), (op), NULL, buffer_free, (fd) }
+#define BUFFER_INIT(op,fd,buf,len) { (char*)(buf), 0, 0, (len), (ssize_t (*)())(op), NULL, NULL, (fd) }
+#define BUFFER_INIT_FREE(op,fd,buf,len) { (buf), 0, 0, (len), (ssize_t (*)())(op), NULL, buffer_free, (fd) }
 #define BUFFER_INIT_READ(op,fd,buf,len) BUFFER_INIT(op,fd,buf,len) /*obsolete*/
 #define BUFFER_INSIZE 8192
 #define BUFFER_OUTSIZE 8192
diff --git a/buffer/bs_skip.c b/buffer/bs_skip.c
index b75801e..804d0b3 100644
--- a/buffer/bs_skip.c
+++ b/buffer/bs_skip.c
@@ -91,7 +91,7 @@ int main() {
       write(pipes[1], iobuf, 32);
     }
   }
-  buffer_init(&b, read, pipes[0], iobuf+32, 10);
+  buffer_init(&b, (ssize_t (*)())read, pipes[0], iobuf+32, 10);
 
   bs_init_iobuf(&bs, &b);
   assert(bs_skip(&bs, 20) == 20);
diff --git a/buffer/buffer_feed.c b/buffer/buffer_feed.c
index 9d97eda..c0718de 100644
--- a/buffer/buffer_feed.c
+++ b/buffer/buffer_feed.c
@@ -1,11 +1,11 @@
 #include "buffer.h"
 
-extern ssize_t buffer_stubborn_read(ssize_t (*op)(),int fd,const char* buf, size_t len,void* cookie);
+extern ssize_t buffer_stubborn_read(ssize_t (*op)(int fd,const char* buf,size_t len,void* cookie),int fd,const char* buf, size_t len,void* cookie);
 
 ssize_t buffer_feed(buffer* b) {
   if (b->p==b->n) {
     ssize_t w;
-    if ((w=buffer_stubborn_read(b->op,b->fd,b->x,b->a,b))<0)
+    if ((w=buffer_stubborn_read((ssize_t (*)(int fd,const char* buf,size_t len,void* cookie))b->op,b->fd,b->x,b->a,b))<0)
       return -1;
     b->n=(size_t)w;
     b->p=0;
diff --git a/buffer/buffer_flush.c b/buffer/buffer_flush.c
index 786cb16..1b3527d 100644
--- a/buffer/buffer_flush.c
+++ b/buffer/buffer_flush.c
@@ -1,13 +1,13 @@
 #include "buffer.h"
 
-extern ssize_t buffer_stubborn(ssize_t (*op)(),int fd,const char* buf, size_t len,void* cookie);
+extern ssize_t buffer_stubborn(ssize_t (*op)(int fd,const char* buf,size_t len,void* cookie),int fd,const char* buf, size_t len,void* cookie);
 
 extern int buffer_flush(buffer* b) {
   register size_t p;
   register ssize_t r;
   if (!(p=b->p)) return 0; /* buffer already empty */
   b->p=0;
-  r=buffer_stubborn(b->op,b->fd,b->x,p,b);
+  r=buffer_stubborn((ssize_t (*)(int fd,const char* buf,size_t len,void* cookie))b->op,b->fd,b->x,p,b);
   if (r>0) r=0;
   return (int)r;
 }
diff --git a/buffer/buffer_frombuf.c b/buffer/buffer_frombuf.c
index 0c9d931..c2075a9 100644
--- a/buffer/buffer_frombuf.c
+++ b/buffer/buffer_frombuf.c
@@ -14,6 +14,6 @@ void buffer_frombuf(buffer* b,const char* x,size_t l) {
   b->n=l;
   b->a=l;
   b->fd=0;
-  b->op=dummyreadwrite;
+  b->op=(ssize_t (*)())dummyreadwrite;
   b->deinit=0;
 }
diff --git a/buffer/buffer_init_read.c b/buffer/buffer_init_read.c
index d9c378b..cede881 100644
--- a/buffer/buffer_init_read.c
+++ b/buffer/buffer_init_read.c
@@ -3,7 +3,7 @@
 
 int buffer_init_read(buffer* b, int fd, char* y,size_t ylen) {
   if (fd==-1) return -1;
-  buffer_init(b, read, fd, y, ylen);
+  buffer_init(b, (ssize_t (*)())read, fd, y, ylen);
   return 0;
 }
 
diff --git a/buffer/buffer_init_read_allocbuf.c b/buffer/buffer_init_read_allocbuf.c
index 78df5aa..a44b456 100644
--- a/buffer/buffer_init_read_allocbuf.c
+++ b/buffer/buffer_init_read_allocbuf.c
@@ -2,6 +2,6 @@
 #include "buffer.h"
 
 int buffer_init_read_allocbuf(buffer* b, int fd, size_t ylen) {
-  return buffer_init_allocbuf(b, read, fd, ylen);
+  return buffer_init_allocbuf(b, (ssize_t (*)())read, fd, ylen);
 }
 
diff --git a/buffer/buffer_init_write.c b/buffer/buffer_init_write.c
index 48195ba..75c5a36 100644
--- a/buffer/buffer_init_write.c
+++ b/buffer/buffer_init_write.c
@@ -3,7 +3,7 @@
 
 int buffer_init_write(buffer* b, int fd, char* y,size_t ylen) {
   if (fd==-1) return -1;
-  buffer_init(b, write, fd, y, ylen);
+  buffer_init(b, (ssize_t (*)())write, fd, y, ylen);
   return 0;
 }
 
diff --git a/buffer/buffer_init_write_allocbuf.c b/buffer/buffer_init_write_allocbuf.c
index a005b6c..16d73ec 100644
--- a/buffer/buffer_init_write_allocbuf.c
+++ b/buffer/buffer_init_write_allocbuf.c
@@ -2,6 +2,6 @@
 #include "buffer.h"
 
 int buffer_init_write_allocbuf(buffer* b, int fd, size_t ylen) {
-  return buffer_init_allocbuf(b, write, fd, ylen);
+  return buffer_init_allocbuf(b, (ssize_t (*)())write, fd, ylen);
 }
 
diff --git a/buffer/buffer_put.c b/buffer/buffer_put.c
index 3a36a88..4d236d3 100644
--- a/buffer/buffer_put.c
+++ b/buffer/buffer_put.c
@@ -5,7 +5,7 @@
 #endif
 #include "buffer.h"
 
-extern ssize_t buffer_stubborn(ssize_t (*op)(),int fd,const char* buf, size_t len,void* cookie);
+extern ssize_t buffer_stubborn(ssize_t (*op)(int fd,const char* buf,size_t len,void* cookie),int fd,const char* buf, size_t len,void* cookie);
 
 #ifndef __unlikely
 #ifdef __GNUC__
@@ -18,7 +18,7 @@ extern ssize_t buffer_stubborn(ssize_t (*op)(),int fd,const char* buf, size_t le
 int buffer_put(buffer* b,const char* buf,size_t len) {
   if (__unlikely(len>b->a-b->p)) {	/* doesn't fit */
 #ifndef __MINGW32__
-    if (b->op==write) {
+    if (b->op==(ssize_t (*)())write) {
       /* if it's write, we can substitute writev */
       struct iovec v[2];
       ssize_t r;
@@ -38,7 +38,7 @@ int buffer_put(buffer* b,const char* buf,size_t len) {
 #endif
     if (buffer_flush(b)==-1) return -1;
     if (len>b->a) {
-      if (buffer_stubborn(b->op,b->fd,buf,len,b)<0) return -1;
+      if (buffer_stubborn((ssize_t (*)(int fd,const char* buf,size_t len,void* cookie))b->op,b->fd,buf,len,b)<0) return -1;
       return 0;
     }
   }
diff --git a/buffer/buffer_putflush.c b/buffer/buffer_putflush.c
index c78af7a..c86a669 100644
--- a/buffer/buffer_putflush.c
+++ b/buffer/buffer_putflush.c
@@ -14,13 +14,13 @@
 #endif
 #endif
 
-extern ssize_t buffer_stubborn(ssize_t (*op)(),int fd,const char* buf, size_t len,void* cookie);
+extern ssize_t buffer_stubborn(ssize_t (*op)(int fd,const char* buf,size_t len,void* cookie),int fd,const char* buf, size_t len,void* cookie);
 
 int buffer_putflush(buffer* b,const char* x,size_t len) {
   /* Since we know we are going to flush anyway, let's see if we can
    * optimize a bit */
   if (!b->p)	/* if the buffer is empty, just call buffer_stubborn directly */
-    return buffer_stubborn(b->op,b->fd,x,len,b);
+    return buffer_stubborn((ssize_t (*)(int fd,const char* buf,size_t len,void* cookie))b->op,b->fd,x,len,b);
 #ifndef __MINGW32__
   if (b->op==write && len>sizeof(struct iovec)*2) {
     struct iovec v[2];
@@ -37,11 +37,11 @@ int buffer_putflush(buffer* b,const char* x,size_t len) {
     if (__unlikely((size_t)w!=cl)) {
       /* partial write. ugh. */
       if ((size_t)w<v[0].iov_len) {
-	if (buffer_stubborn(b->op,b->fd,v[0].iov_base+w,v[0].iov_len-w,b) ||
-	    buffer_stubborn(b->op,b->fd,v[1].iov_base,v[0].iov_len,b)) return -1;
+	if (buffer_stubborn((ssize_t (*)(int fd,const char* buf,size_t len,void* cookie))b->op,b->fd,v[0].iov_base+w,v[0].iov_len-w,b) ||
+	    buffer_stubborn((ssize_t (*)(int fd,const char* buf,size_t len,void* cookie))b->op,b->fd,v[1].iov_base,v[0].iov_len,b)) return -1;
       } else {
 	w-=v[0].iov_len;
-	return buffer_stubborn(b->op,b->fd,v[1].iov_base+w,v[1].iov_len-w,b);
+	return buffer_stubborn((ssize_t (*)(int fd,const char* buf,size_t len,void* cookie))b->op,b->fd,v[1].iov_base+w,v[1].iov_len-w,b);
       }
     }
     b->p=0;
diff --git a/buffer/buffer_tosa.c b/buffer/buffer_tosa.c
index a10be4f..88eb50d 100644
--- a/buffer/buffer_tosa.c
+++ b/buffer/buffer_tosa.c
@@ -21,7 +21,7 @@ int buffer_tosa(buffer* b,stralloc* sa) {
   b->n=0;
   b->a=1024;
   b->fd=0;
-  b->op=strallocwrite;
+  b->op=(ssize_t (*)())strallocwrite;
   b->cookie=sa;
   b->deinit=0;
   return 0;
diff --git a/test/uudecode.c b/test/uudecode.c
index 2ce876a..462b6d1 100644
--- a/test/uudecode.c
+++ b/test/uudecode.c
@@ -111,7 +111,7 @@ int main(int argc,char* argv[]) {
       return 1;
     }
   }
-  buffer_init(&filein,read,fd,buf,sizeof buf);
+  buffer_init(&filein,(ssize_t (*)())read,fd,buf,sizeof buf);
   /* skip to "^begin " */
   for (;;) {
     if ((l=buffer_getline(&filein,line,(sizeof line)-1))==0 && line[l]!='\n') {
@@ -179,7 +179,7 @@ foundfilename:
 	      buffer_putsflush(buffer_2,"\"\n");
 	    }
 	    state=AFTERBEGIN;
-	    buffer_init(&fileout,write,ofd,obuf,sizeof obuf);
+	    buffer_init(&fileout,(ssize_t (*)())write,ofd,obuf,sizeof obuf);
 	    continue;
 	  }
 	}
@@ -254,7 +254,7 @@ foundfilename:
 	  buffer_putsflush(buffer_2,"\"\n");
 	  filename[0]=0;
 	  state=AFTERBEGIN;
-	  buffer_init(&fileout,write,ofd,obuf,sizeof obuf);
+	  buffer_init(&fileout,(ssize_t (*)())write,ofd,obuf,sizeof obuf);
 	  continue;
 	}
       }
