Hi,

On Sat, Dec 20, 2025 at 01:24:55PM +0000, [email protected] wrote:
> > Hmm, I don't think I'm catching all possible errors from that 
> > socket. Maybe this patch can help:
> > 
> > ---8<---
> > diff --git a/src/IO/control.c b/src/IO/control.c
> > index 6f677e52..c6cd15bf 100644
> > --- a/src/IO/control.c
> > +++ b/src/IO/control.c
> > @@ -110,7 +110,7 @@ static void Control_read_cb(int fd, void *data)
> >        r = read(new_fd, buf, 1);
> >        _MSG("read = %zd\n", r);
> >        if (r < 0) {
> > -         if (errno == EINTR) {
> > +         if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
> >              continue;
> >           } else {
> >              MSG_ERR("Control_read_cb %s\n", dStrerror(errno));
> > ---8<---
> >  
> > Let me know if that makes it work.
> 
> Looks to be working now! Thanks for this very cool new feature, BTW!

I took a closer look and it seems that this patch doesn't address the 
actual problem. The problem is that BSD inherits the non-blocking 
behavior while Linux doesn't (POSIX doesn't seem to indicate what should 
be done). We want the new_fd to work in blocking mode, so this patch 
should fix it for BSD and Linux (otherwise let me know):

---8<---
diff --git a/src/IO/control.c b/src/IO/control.c
index 6f677e52..0d11187e 100644
--- a/src/IO/control.c
+++ b/src/IO/control.c
@@ -95,12 +95,30 @@ static void Control_read_cb(int fd, void *data)
 
    int new_fd = accept(control_fd, NULL, NULL);
    if (new_fd < 0) {
-      if (errno != EWOULDBLOCK) {
-         MSG("accept failed: %s\n", strerror(errno));
+      if (errno == EAGAIN || errno == EWOULDBLOCK) {
+         /* Nothing? */
+         return;
+      } else {
+         MSG_ERR("accept failed: %s\n", strerror(errno));
          exit(1);
       }
-      /* Nothing? */
-      return;
+   }
+
+   /* From accept(2) man page:
+    *
+    * On Linux, the new socket returned by accept() does not inherit
+    * file status flags such as O_NONBLOCK and O_ASYNC from the
+    * listening socket. This behavior differs from the canonical BSD
+    * sockets implementation. Portable programs should not rely on
+    * inheritance or noninheritance of file status flags and always
+    * explicitly set all required flags on the socket returned from
+    * accept().
+    *
+    * So, disable O_NONBLOCK flag explicitly.
+    */
+   if (fcntl(new_fd, F_SETFL, 0) == -1) {
+      MSG_ERR("control socket fcntl failed: %s\n", strerror(errno));
+      exit(1);
    }
 
    ssize_t r;
---8<---

Best,
Rodrigo.
_______________________________________________
Dillo-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to