diff options
Diffstat (limited to 'c/src/libnetworking')
-rw-r--r-- | c/src/libnetworking/kern/uipc_socket.c | 42 | ||||
-rw-r--r-- | c/src/libnetworking/rtems/rtems_glue.c | 3 | ||||
-rw-r--r-- | c/src/libnetworking/sys/socket.h | 19 | ||||
-rw-r--r-- | c/src/libnetworking/sys/socketvar.h | 2 |
4 files changed, 64 insertions, 2 deletions
diff --git a/c/src/libnetworking/kern/uipc_socket.c b/c/src/libnetworking/kern/uipc_socket.c index 04489f4017..49a5a65653 100644 --- a/c/src/libnetworking/kern/uipc_socket.c +++ b/c/src/libnetworking/kern/uipc_socket.c @@ -979,6 +979,31 @@ sosetopt(so, level, optname, m0) so->so_state &= ~SS_PRIV; break; + case SO_SNDWAKEUP: + case SO_RCVWAKEUP: + { + /* RTEMS addition. */ + struct sockwakeup *sw; + struct sockbuf *sb; + + if (m == NULL + || m->m_len != sizeof (struct sockwakeup)) { + error = EINVAL; + goto bad; + } + sw = mtod(m, struct sockwakeup *); + sb = (optname == SO_SNDWAKEUP + ? &so->so_snd + : &so->so_rcv); + sb->sb_wakeup = sw->sw_pfn; + sb->sb_wakeuparg = sw->sw_arg; + if (sw->sw_pfn) + sb->sb_flags |= SB_ASYNC; + else + sb->sb_flags &=~ SB_ASYNC; + break; + } + default: error = ENOPROTOOPT; break; @@ -1076,6 +1101,23 @@ sogetopt(so, level, optname, mp) break; } + case SO_SNDWAKEUP: + case SO_RCVWAKEUP: + { + struct sockbuf *sb; + struct sockwakeup *sw; + + /* RTEMS additions. */ + sb = (optname == SO_SNDWAKEUP + ? &so->so_snd + : &so->so_rcv); + m->m_len = sizeof (struct sockwakeup); + sw = mtod(m, struct sockwakeup *); + sw->sw_pfn = sb->sb_wakeup; + sw->sw_arg = sb->sb_wakeuparg; + break; + } + default: (void)m_free(m); return (ENOPROTOOPT); diff --git a/c/src/libnetworking/rtems/rtems_glue.c b/c/src/libnetworking/rtems/rtems_glue.c index 261d73f7b1..69f2fcc040 100644 --- a/c/src/libnetworking/rtems/rtems_glue.c +++ b/c/src/libnetworking/rtems/rtems_glue.c @@ -345,6 +345,9 @@ sowakeup(so, sb) sb->sb_flags &= ~SB_WAIT; rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT); } + if (sb->sb_wakeup) { + (*sb->sb_wakeup) (so, sb->sb_wakeuparg); + } } /* diff --git a/c/src/libnetworking/sys/socket.h b/c/src/libnetworking/sys/socket.h index 7e0f6c7572..6442581db6 100644 --- a/c/src/libnetworking/sys/socket.h +++ b/c/src/libnetworking/sys/socket.h @@ -37,6 +37,8 @@ #ifndef _SYS_SOCKET_H_ #define _SYS_SOCKET_H_ +#include <sys/cdefs.h> + /* * Definitions related to sockets: types, address families, options. */ @@ -79,6 +81,12 @@ #define SO_PRIVSTATE 0x1009 /* get/deny privileged state */ /* + * RTEMS addition: get and set wakeup functions. + */ +#define SO_SNDWAKEUP 0x1020 /* wakeup when ready to send */ +#define SO_RCVWAKEUP 0x1021 /* wakeup when ready to receive */ + +/* * Structure used for manipulating linger option. */ struct linger { @@ -87,6 +95,15 @@ struct linger { }; /* + * RTEMS addition: structure used to get and set wakeup function. + */ +struct socket; +struct sockwakeup { + void (*sw_pfn) __P((struct socket *, caddr_t)); + caddr_t sw_arg; +}; + +/* * Level number for (get/set)sockopt() to apply to socket itself. */ #define SOL_SOCKET 0xffff /* options for socket level */ @@ -327,8 +344,6 @@ struct omsghdr { #ifndef KERNEL -#include <sys/cdefs.h> - __BEGIN_DECLS int accept __P((int, struct sockaddr *, int *)); int bind __P((int, const struct sockaddr *, int)); diff --git a/c/src/libnetworking/sys/socketvar.h b/c/src/libnetworking/sys/socketvar.h index 0eae3d4aa5..5690defb43 100644 --- a/c/src/libnetworking/sys/socketvar.h +++ b/c/src/libnetworking/sys/socketvar.h @@ -89,6 +89,8 @@ struct socket { struct selinfo sb_sel; /* process selecting read/write */ short sb_flags; /* flags, see below */ u_long sb_timeo; /* timeout for read/write */ + void (*sb_wakeup) __P((struct socket *, caddr_t)); + caddr_t sb_wakeuparg; /* arg for above */ } so_rcv, so_snd; #define SB_MAX (256*1024) /* default for max chars in sockbuf */ #define SB_LOCK 0x01 /* lock on data queue */ |