Index: hurd-0.7/pflocal/socket.c =================================================================== --- hurd-0.7.orig/pflocal/socket.c +++ hurd-0.7/pflocal/socket.c @@ -429,12 +429,17 @@ S_socket_getopt (struct sock_user *user, int level, int opt, char **value, size_t *value_len) { - int ret = 0; + struct sock *sock = user->sock; + struct pipe *pipe; + error_t err = 0; if (!user) return EOPNOTSUPP; - pthread_mutex_lock (&user->sock->lock); + if (!sock) + return EBADF; + + pthread_mutex_lock (&sock->lock); switch (level) { case SOL_SOCKET: @@ -442,40 +447,136 @@ S_socket_getopt (struct sock_user *user, { case SO_TYPE: assert (*value_len >= sizeof (int)); - *(int *)*value = user->sock->pipe_class->sock_type; + *(int *)*value = sock->pipe_class->sock_type; + *value_len = sizeof (int); + break; + case SO_RCVBUF: + assert (*value_len >= sizeof (int)); + pipe = sock->read_pipe; + if (!pipe) + { + err = EPIPE; + goto out; + } + *(int *)*value = pipe->write_limit; + *value_len = sizeof (int); + break; + case SO_SNDBUF: + assert (*value_len >= sizeof (int)); + /* XXX: write_pipe might not exist: but sock is the same */ + //pipe = sock->write_pipe; + pipe = sock->read_pipe; + if (!pipe) + { + err = EPIPE; + goto out; + } + *(int *)*value = pipe->write_limit; *value_len = sizeof (int); break; default: - ret = ENOPROTOOPT; + err = ENOPROTOOPT; break; } break; default: - ret = ENOPROTOOPT; + err = ENOPROTOOPT; break; } - pthread_mutex_unlock (&user->sock->lock); - return ret; + out: + pthread_mutex_unlock (&sock->lock); + + return err; } error_t S_socket_setopt (struct sock_user *user, int level, int opt, char *value, size_t value_len) { - int ret = 0; + struct sock *sock = user->sock; + struct pipe *pipe; + int write_limit = 0; + error_t err = 0; if (!user) return EOPNOTSUPP; - pthread_mutex_lock (&user->sock->lock); + if (!sock) + return EBADF; + + pthread_mutex_lock (&sock->lock); switch (level) { + case SOL_SOCKET: + switch (opt) + { + case SO_RCVBUF: + if (value_len != sizeof (int)) + { + err = EINVAL; + goto out; + } + pipe = sock->read_pipe; + if (!pipe) + { + err = EPIPE; + goto out; + } + write_limit = *(int *)value; + if (write_limit > 0) + { + if (write_limit > WRITE_LIMIT_MAX) + pipe->write_limit = WRITE_LIMIT_MAX; + else + pipe->write_limit = write_limit; + } + else + { + err = EINVAL; + goto out; + } + break; + case SO_SNDBUF: + if (value_len != sizeof (int)) + { + err = EINVAL; + goto out; + } + /* XXX: write_pipe might not exist: but sock is the same */ + //pipe = sock->write_pipe; + pipe = sock->read_pipe; + if (!pipe) + { + err = EPIPE; + goto out; + } + write_limit = *(int *)value; + if (write_limit > 0) + { + if (write_limit > WRITE_LIMIT_MAX) + pipe->write_limit = WRITE_LIMIT_MAX; + else + pipe->write_limit = write_limit; + } + else + { + err = EINVAL; + goto out; + } + break; + default: + err = ENOPROTOOPT; + break; + } + break; default: - ret = ENOPROTOOPT; + err = ENOPROTOOPT; break; } - pthread_mutex_unlock (&user->sock->lock); - return ret; + out: + pthread_mutex_unlock (&sock->lock); + + return err; } Index: hurd-0.7/libpipe/pipe.h =================================================================== --- hurd-0.7.orig/libpipe/pipe.h +++ hurd-0.7/libpipe/pipe.h @@ -69,6 +69,11 @@ struct pipe_select_cond pthread_cond_t cond; }; +#define WRITE_LIMIT_DEFAULT 16*1024 +#define WRITE_LIMIT_MAX 1024*1024 +//#define WRITE_LIMIT_MAX 64*1024 +#define WRITE_ATOMIC_DEFAULT 16*1024 + /* A unidirectional data pipe; it transfers data from READER to WRITER. */ struct pipe { Index: hurd-0.7/libpipe/pipe.c =================================================================== --- hurd-0.7.orig/libpipe/pipe.c +++ hurd-0.7/libpipe/pipe.c @@ -55,8 +55,8 @@ pipe_create (struct pipe_class *class, s new->writers = 0; new->flags = 0; new->class = class; - new->write_limit = 16*1024; - new->write_atomic = 16*1024; + new->write_limit = WRITE_LIMIT_DEFAULT; + new->write_atomic = WRITE_ATOMIC_DEFAULT; memset (&new->read_time, 0, sizeof(new->read_time)); memset (&new->write_time, 0, sizeof(new->write_time));