Rodrigo Arias <[email protected]> wrote:

> 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<---

Tested & works fine here :)
_______________________________________________
Dillo-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to