summaryrefslogtreecommitdiffstats
path: root/source/lib/socket/socket_ipv4.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-15 10:28:08 +0000
committerAndrew Tridgell <tridge@samba.org>2005-01-15 10:28:08 +0000
commit71bf6a34da0216665bb9eaa7b395c0bed9e65e1a (patch)
tree19d91e9b54639fff9ed8b05b18ee7cde04a61fcb /source/lib/socket/socket_ipv4.c
parent36f6edaed44e937cdc795d8914fffb1b9606993f (diff)
downloadsamba-71bf6a34da0216665bb9eaa7b395c0bed9e65e1a.tar.gz
samba-71bf6a34da0216665bb9eaa7b395c0bed9e65e1a.tar.xz
samba-71bf6a34da0216665bb9eaa7b395c0bed9e65e1a.zip
r4753: added the ability for the generic socket library to handle async
connect(). This required a small API change (the addition of a socket_connect_complete() method)
Diffstat (limited to 'source/lib/socket/socket_ipv4.c')
-rw-r--r--source/lib/socket/socket_ipv4.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/source/lib/socket/socket_ipv4.c b/source/lib/socket/socket_ipv4.c
index 88570512a4c..7cf2b73e4e7 100644
--- a/source/lib/socket/socket_ipv4.c
+++ b/source/lib/socket/socket_ipv4.c
@@ -1,7 +1,10 @@
/*
Unix SMB/CIFS implementation.
+
Socket IPv4 functions
+
Copyright (C) Stefan Metzmacher 2004
+ Copyright (C) Andrew Tridgell 2004-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,6 +39,34 @@ static void ipv4_tcp_close(struct socket_context *sock)
close(sock->fd);
}
+static NTSTATUS ipv4_tcp_connect_complete(struct socket_context *sock, uint32_t flags)
+{
+ int error=0, ret;
+ socklen_t len = sizeof(error);
+
+ /* check for any errors that may have occurred - this is needed
+ for non-blocking connect */
+ ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len);
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ if (error != 0) {
+ return map_nt_error_from_unix(error);
+ }
+
+ if (!(flags & SOCKET_FLAG_BLOCK)) {
+ ret = set_blocking(sock->fd, False);
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ }
+
+ sock->state = SOCKET_STATE_CLIENT_CONNECTED;
+
+ return NT_STATUS_OK;
+}
+
+
static NTSTATUS ipv4_tcp_connect(struct socket_context *sock,
const char *my_address, int my_port,
const char *srv_address, int srv_port,
@@ -79,18 +110,10 @@ static NTSTATUS ipv4_tcp_connect(struct socket_context *sock,
return map_nt_error_from_unix(errno);
}
- if (!(flags & SOCKET_FLAG_BLOCK)) {
- ret = set_blocking(sock->fd, False);
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
- }
- }
-
- sock->state = SOCKET_STATE_CLIENT_CONNECTED;
-
- return NT_STATUS_OK;
+ return ipv4_tcp_connect_complete(sock, flags);
}
+
static NTSTATUS ipv4_tcp_listen(struct socket_context *sock,
const char *my_address, int port,
int queue_size, uint32_t flags)
@@ -315,6 +338,7 @@ static const struct socket_ops ipv4_tcp_ops = {
.fn_init = ipv4_tcp_init,
.fn_connect = ipv4_tcp_connect,
+ .fn_connect_complete = ipv4_tcp_connect_complete,
.fn_listen = ipv4_tcp_listen,
.fn_accept = ipv4_tcp_accept,
.fn_recv = ipv4_tcp_recv,