From 91b1c8e69e8b047c62cd301ebf6f4b8627941c08 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 7 Dec 1998 17:42:52 +0000 Subject: Patch from Ian Lance Taylor : RTEMS permits using the SO_SNDTIMEO and SO_RCVTIMEO socket options to set a timeout for most socket I/O operations. However, in RTEMS 4.0.0, those options do not affect connect or accept. I don't know of any way to put a timeout on those calls in RTEMS 4.0.0; can anybody point to one. Since it is frequently useful to have a timeout on accept, and sometimes useful to have a timeout on connect shorter than the BSD system default of 75 seconds, the following patch causes SO_RCVTIMEO to affect connect and accept. --- c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h | 2 +- c/src/exec/libnetworking/rtems/rtems_glue.c | 11 +++++++++-- c/src/exec/libnetworking/rtems/rtems_syscall.c | 4 ++-- c/src/lib/libnetworking/rtems/rtems_bsdnet_internal.h | 2 +- c/src/lib/libnetworking/rtems/rtems_glue.c | 11 +++++++++-- c/src/lib/libnetworking/rtems/rtems_syscall.c | 4 ++-- c/src/libnetworking/rtems/rtems_bsdnet_internal.h | 2 +- c/src/libnetworking/rtems/rtems_glue.c | 11 +++++++++-- c/src/libnetworking/rtems/rtems_syscall.c | 4 ++-- cpukit/libnetworking/rtems/rtems_bsdnet_internal.h | 2 +- cpukit/libnetworking/rtems/rtems_glue.c | 11 +++++++++-- cpukit/libnetworking/rtems/rtems_syscall.c | 4 ++-- 12 files changed, 48 insertions(+), 20 deletions(-) diff --git a/c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h b/c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h index 559bafd4c5..453fb23c66 100644 --- a/c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h +++ b/c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h @@ -41,7 +41,7 @@ struct mdproc { * Other RTEMS/BSD glue */ struct socket; -extern void soconnsleep (struct socket *so); +extern int soconnsleep (struct socket *so); extern void soconnwakeup (struct socket *so); #define splnet() 0 #define splimp() 0 diff --git a/c/src/exec/libnetworking/rtems/rtems_glue.c b/c/src/exec/libnetworking/rtems/rtems_glue.c index aea0a548b2..f2449831f5 100644 --- a/c/src/exec/libnetworking/rtems/rtems_glue.c +++ b/c/src/exec/libnetworking/rtems/rtems_glue.c @@ -380,11 +380,12 @@ wakeup (void *p) /* * Wait for a connection/disconnection event. */ -void +int soconnsleep (struct socket *so) { rtems_event_set events; rtems_id tid; + rtems_status_code sc; /* * Soak up any pending events. @@ -404,12 +405,18 @@ soconnsleep (struct socket *so) /* * Wait for the wakeup event. */ - rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events); + sc = rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, so->so_rcv.sb_timeo, &events); /* * Relinquish ownership of the socket. */ so->so_pgid = 0; + + switch (sc) { + case RTEMS_SUCCESSFUL: return 0; + case RTEMS_TIMEOUT: return EWOULDBLOCK; + default: return ENXIO; + } } /* diff --git a/c/src/exec/libnetworking/rtems/rtems_syscall.c b/c/src/exec/libnetworking/rtems/rtems_syscall.c index 782a2f907b..93ecd47c6f 100644 --- a/c/src/exec/libnetworking/rtems/rtems_syscall.c +++ b/c/src/exec/libnetworking/rtems/rtems_syscall.c @@ -211,7 +211,7 @@ connect (int s, struct sockaddr *name, int namelen) return -1; } while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { - soconnsleep (so); + so->so_error = soconnsleep (so); } if (error == 0) { error = so->so_error; @@ -271,7 +271,7 @@ accept (int s, struct sockaddr *name, int *namelen) head->so_error = ECONNABORTED; break; } - soconnsleep (head); + head->so_error = soconnsleep (head); } if (head->so_error) { errno = head->so_error; diff --git a/c/src/lib/libnetworking/rtems/rtems_bsdnet_internal.h b/c/src/lib/libnetworking/rtems/rtems_bsdnet_internal.h index 559bafd4c5..453fb23c66 100644 --- a/c/src/lib/libnetworking/rtems/rtems_bsdnet_internal.h +++ b/c/src/lib/libnetworking/rtems/rtems_bsdnet_internal.h @@ -41,7 +41,7 @@ struct mdproc { * Other RTEMS/BSD glue */ struct socket; -extern void soconnsleep (struct socket *so); +extern int soconnsleep (struct socket *so); extern void soconnwakeup (struct socket *so); #define splnet() 0 #define splimp() 0 diff --git a/c/src/lib/libnetworking/rtems/rtems_glue.c b/c/src/lib/libnetworking/rtems/rtems_glue.c index aea0a548b2..f2449831f5 100644 --- a/c/src/lib/libnetworking/rtems/rtems_glue.c +++ b/c/src/lib/libnetworking/rtems/rtems_glue.c @@ -380,11 +380,12 @@ wakeup (void *p) /* * Wait for a connection/disconnection event. */ -void +int soconnsleep (struct socket *so) { rtems_event_set events; rtems_id tid; + rtems_status_code sc; /* * Soak up any pending events. @@ -404,12 +405,18 @@ soconnsleep (struct socket *so) /* * Wait for the wakeup event. */ - rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events); + sc = rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, so->so_rcv.sb_timeo, &events); /* * Relinquish ownership of the socket. */ so->so_pgid = 0; + + switch (sc) { + case RTEMS_SUCCESSFUL: return 0; + case RTEMS_TIMEOUT: return EWOULDBLOCK; + default: return ENXIO; + } } /* diff --git a/c/src/lib/libnetworking/rtems/rtems_syscall.c b/c/src/lib/libnetworking/rtems/rtems_syscall.c index 782a2f907b..93ecd47c6f 100644 --- a/c/src/lib/libnetworking/rtems/rtems_syscall.c +++ b/c/src/lib/libnetworking/rtems/rtems_syscall.c @@ -211,7 +211,7 @@ connect (int s, struct sockaddr *name, int namelen) return -1; } while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { - soconnsleep (so); + so->so_error = soconnsleep (so); } if (error == 0) { error = so->so_error; @@ -271,7 +271,7 @@ accept (int s, struct sockaddr *name, int *namelen) head->so_error = ECONNABORTED; break; } - soconnsleep (head); + head->so_error = soconnsleep (head); } if (head->so_error) { errno = head->so_error; diff --git a/c/src/libnetworking/rtems/rtems_bsdnet_internal.h b/c/src/libnetworking/rtems/rtems_bsdnet_internal.h index 559bafd4c5..453fb23c66 100644 --- a/c/src/libnetworking/rtems/rtems_bsdnet_internal.h +++ b/c/src/libnetworking/rtems/rtems_bsdnet_internal.h @@ -41,7 +41,7 @@ struct mdproc { * Other RTEMS/BSD glue */ struct socket; -extern void soconnsleep (struct socket *so); +extern int soconnsleep (struct socket *so); extern void soconnwakeup (struct socket *so); #define splnet() 0 #define splimp() 0 diff --git a/c/src/libnetworking/rtems/rtems_glue.c b/c/src/libnetworking/rtems/rtems_glue.c index aea0a548b2..f2449831f5 100644 --- a/c/src/libnetworking/rtems/rtems_glue.c +++ b/c/src/libnetworking/rtems/rtems_glue.c @@ -380,11 +380,12 @@ wakeup (void *p) /* * Wait for a connection/disconnection event. */ -void +int soconnsleep (struct socket *so) { rtems_event_set events; rtems_id tid; + rtems_status_code sc; /* * Soak up any pending events. @@ -404,12 +405,18 @@ soconnsleep (struct socket *so) /* * Wait for the wakeup event. */ - rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events); + sc = rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, so->so_rcv.sb_timeo, &events); /* * Relinquish ownership of the socket. */ so->so_pgid = 0; + + switch (sc) { + case RTEMS_SUCCESSFUL: return 0; + case RTEMS_TIMEOUT: return EWOULDBLOCK; + default: return ENXIO; + } } /* diff --git a/c/src/libnetworking/rtems/rtems_syscall.c b/c/src/libnetworking/rtems/rtems_syscall.c index 782a2f907b..93ecd47c6f 100644 --- a/c/src/libnetworking/rtems/rtems_syscall.c +++ b/c/src/libnetworking/rtems/rtems_syscall.c @@ -211,7 +211,7 @@ connect (int s, struct sockaddr *name, int namelen) return -1; } while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { - soconnsleep (so); + so->so_error = soconnsleep (so); } if (error == 0) { error = so->so_error; @@ -271,7 +271,7 @@ accept (int s, struct sockaddr *name, int *namelen) head->so_error = ECONNABORTED; break; } - soconnsleep (head); + head->so_error = soconnsleep (head); } if (head->so_error) { errno = head->so_error; diff --git a/cpukit/libnetworking/rtems/rtems_bsdnet_internal.h b/cpukit/libnetworking/rtems/rtems_bsdnet_internal.h index 559bafd4c5..453fb23c66 100644 --- a/cpukit/libnetworking/rtems/rtems_bsdnet_internal.h +++ b/cpukit/libnetworking/rtems/rtems_bsdnet_internal.h @@ -41,7 +41,7 @@ struct mdproc { * Other RTEMS/BSD glue */ struct socket; -extern void soconnsleep (struct socket *so); +extern int soconnsleep (struct socket *so); extern void soconnwakeup (struct socket *so); #define splnet() 0 #define splimp() 0 diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c index aea0a548b2..f2449831f5 100644 --- a/cpukit/libnetworking/rtems/rtems_glue.c +++ b/cpukit/libnetworking/rtems/rtems_glue.c @@ -380,11 +380,12 @@ wakeup (void *p) /* * Wait for a connection/disconnection event. */ -void +int soconnsleep (struct socket *so) { rtems_event_set events; rtems_id tid; + rtems_status_code sc; /* * Soak up any pending events. @@ -404,12 +405,18 @@ soconnsleep (struct socket *so) /* * Wait for the wakeup event. */ - rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events); + sc = rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, so->so_rcv.sb_timeo, &events); /* * Relinquish ownership of the socket. */ so->so_pgid = 0; + + switch (sc) { + case RTEMS_SUCCESSFUL: return 0; + case RTEMS_TIMEOUT: return EWOULDBLOCK; + default: return ENXIO; + } } /* diff --git a/cpukit/libnetworking/rtems/rtems_syscall.c b/cpukit/libnetworking/rtems/rtems_syscall.c index 782a2f907b..93ecd47c6f 100644 --- a/cpukit/libnetworking/rtems/rtems_syscall.c +++ b/cpukit/libnetworking/rtems/rtems_syscall.c @@ -211,7 +211,7 @@ connect (int s, struct sockaddr *name, int namelen) return -1; } while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { - soconnsleep (so); + so->so_error = soconnsleep (so); } if (error == 0) { error = so->so_error; @@ -271,7 +271,7 @@ accept (int s, struct sockaddr *name, int *namelen) head->so_error = ECONNABORTED; break; } - soconnsleep (head); + head->so_error = soconnsleep (head); } if (head->so_error) { errno = head->so_error; -- cgit v1.2.3