summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libc/net/socket.c21
-rw-r--r--src/libc/select.c6
2 files changed, 23 insertions, 4 deletions
diff --git a/src/libc/net/socket.c b/src/libc/net/socket.c
index 9eacbe5..04d73f4 100644
--- a/src/libc/net/socket.c
+++ b/src/libc/net/socket.c
@@ -5,6 +5,7 @@
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
+#include <string.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol) {
@@ -83,9 +84,21 @@ int setsockopt(int, int, int, const void *, socklen_t) {
}
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
- // TODO /net/ should expose local address somehow
- /* dummy output, just to satisfy curl */
- (void)sockfd; (void)addrlen;
- addr->sa_family = AF_UNSPEC;
+ // TODO /net/ should expose the local address somehow
+
+ /* Outputs a fake address, just to satisfy curl.
+ * Can't be AF_UNSPEC, as curl tries to print it with inet_ntop. */
+ (void)sockfd;
+ struct sockaddr_in dummy = {
+ .sin_family = AF_INET,
+ .sin_port = 0,
+ .sin_addr = {0},
+ };
+ if ((int)sizeof(dummy) < *addrlen) {
+ *addrlen = sizeof(dummy);
+ } else if (*addrlen < 0) {
+ return errno = EINVAL, -1;
+ }
+ memcpy(addr, &dummy, *addrlen);
return 0;
}
diff --git a/src/libc/select.c b/src/libc/select.c
index e3e95e4..20f7b71 100644
--- a/src/libc/select.c
+++ b/src/libc/select.c
@@ -21,6 +21,12 @@ select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct ti
(void)timeout;
FD_ZERO(exceptfds);
if (countset(nfds, readfds) != 0) {
+ if (countset(nfds, readfds) == 1 && countset(nfds, writefds) == 0) {
+ /* special case: if you're only waiting for a single fd to become
+ * readable, just go ahead and read() it.
+ * curl compat. */
+ return 1;
+ }
return errno = ENOSYS, -1;
}
return countset(nfds, writefds); /* assume everything is ready for writing */