summaryrefslogtreecommitdiff
path: root/sys/compat/linux
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1997-11-26 08:51:09 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1997-11-26 08:51:09 +0000
commit12d89b20e1d5d54c743ee59f536d318a478d8a5a (patch)
tree9472407aca485bedff3738d51efcc154a69afe2d /sys/compat/linux
parent50663e31ee3e3fbdb87999b718e485f2bea1036a (diff)
If using async connect(), after select for writeable, if getpeername()
indicates connection failure, you can use getsockopt(SOL_SOCKET, SO_ERROR, ...) to find the error. But the linux people I guess didn't know about this, and changed connect() so that a 2nd connect() call on a failed socket returns the error directly. Fake this demented non-standard behaviour which Linux users are now starting to code to. Talk about dilution of the API...
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/linux_socket.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 8acabfe65eb..5ad1cfa5506 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_socket.c,v 1.4 1997/11/26 08:45:46 deraadt Exp $ */
+/* $OpenBSD: linux_socket.c,v 1.5 1997/11/26 08:51:08 deraadt Exp $ */
/* $NetBSD: linux_socket.c,v 1.14 1996/04/05 00:01:50 christos Exp $ */
/*
@@ -198,7 +198,37 @@ linux_connect(p, uap, retval)
SCARG(&bca, name) = (caddr_t) lca.name;
SCARG(&bca, namelen) = lca.namelen;
- return sys_connect(p, &bca, retval);
+ error = sys_connect(p, &bca, retval);
+
+ if (error == EISCONN) {
+ struct sys_getsockopt_args bga;
+ void *status, *statusl;
+ int stat, statl = sizeof stat;
+ caddr_t sg;
+
+ sg = stackgap_init(p->p_emul);
+ status = stackgap_alloc(&sg, sizeof stat);
+ statusl = stackgap_alloc(&sg, sizeof statusl);
+
+ if ((error = copyout(&statl, statusl, sizeof statl)))
+ return error;
+
+ SCARG(&bga, s) = lca.s;
+ SCARG(&bga, level) = SOL_SOCKET;
+ SCARG(&bga, name) = SO_ERROR;
+ SCARG(&bga, val) = status;
+ SCARG(&bga, avalsize) = statusl;
+
+ error = sys_getsockopt(p, &bga, retval);
+ if (error)
+ return error;
+ if ((error = copyin(status, &stat, sizeof stat)))
+ return error;
+ if (stat)
+ return stat;
+ return EISCONN;
+ }
+ return error;
}
int