[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Ayttm-commits] CVS: ayttm/src tcp_util.c,1.1,1.2 tcp_util.h,1.1,1.2
From: |
Philip S Tellis <address@hidden> |
Subject: |
[Ayttm-commits] CVS: ayttm/src tcp_util.c,1.1,1.2 tcp_util.h,1.1,1.2 |
Date: |
Fri, 07 Feb 2003 05:02:50 -0500 |
Update of /cvsroot/ayttm/ayttm/src
In directory subversions:/tmp/cvs-serv19666/src
Modified Files:
tcp_util.c tcp_util.h
Log Message:
async connect
Index: tcp_util.c
===================================================================
RCS file: /cvsroot/ayttm/ayttm/src/tcp_util.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- tcp_util.c 7 Feb 2003 08:25:33 -0000 1.1
+++ tcp_util.c 7 Feb 2003 10:02:44 -0000 1.2
@@ -33,9 +33,21 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
#include <errno.h>
-#include "tcp_util.h" /* so the compiler tells us about mismatches */
-/* we should also use the proxy here */
+#include <values.h>
+
+#include "globals.h"
+#include "debug.h"
+#include "llist.h"
+#include "plugin_api.h"
+
+
+/* so the compiler tells us about mismatches */
+#include "tcp_util.h"
+
/**
* ay_socket_new
@@ -57,21 +69,20 @@
if(last_host[0] || strcasecmp(last_host, host)!=0) {
if(!(server = gethostbyname(host))) {
- /*WARNING(("failed to look up server (%s:%d)\n%d: %s",
- host, port,
- h_errno, strerror(h_errno)));*/
errno=h_errno;
+ eb_debug(DBG_CORE, "failed to look up server
(%s:%d)\n%d: %s",
+ host, port, errno,
strerror(errno));
return -1;
}
strncpy(last_host, host, 255);
}
if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- /*WARNING(("Socket create error (%d): %s", errno,
strerror(errno)));*/
+ eb_debug(DBG_CORE, "Socket create error (%d): %s", errno,
strerror(errno));
return -1;
}
- /*LOG(("connecting to %s:%d\n", host, port));*/
+ eb_debug(DBG_CORE, "connecting to %s:%d\n", host, port);
for (p = server->h_addr_list; *p; p++)
{
@@ -80,7 +91,7 @@
memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
serv_addr.sin_port = htons(port);
- /*LOG(("trying %s", *p));*/
+ eb_debug(DBG_CORE, "trying %s", *p);
if(connect(servfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) == -1) {
#ifdef __MINGW32__
@@ -95,13 +106,12 @@
break;
}
} else {
- /*LOG(("connected"));*/
+ eb_debug(DBG_CORE, "connected");
return servfd;
}
}
- /*WARNING(("Could not connect to %s:%d\n%d:%s", host, port, errno,
- strerror(errno)));*/
+ eb_debug(DBG_CORE, "Could not connect to %s:%d\n%d:%s", host, port,
errno, strerror(errno));
close(servfd);
return -1;
}
@@ -150,4 +160,136 @@
return (n);
}
+
+struct connect_callback_data {
+ ay_socket_callback callback;
+ void * callback_data;
+
+ int ebi_tag;
+ int tag;
+};
+
+static LList * pending_connects;
+static int tag_pool=0;
+
+static void destroy_pending_connect(struct connect_callback_data * ccd)
+{
+ eb_input_remove(ccd->ebi_tag);
+ free(ccd);
+}
+
+static void connect_complete(void *data, int source, eb_input_condition
condition)
+{
+ struct connect_callback_data *ccd = data;
+ int error, err_size = sizeof(error);
+ const ay_socket_callback callback = ccd->callback;
+ void * callback_data = ccd->callback_data;
+
+ pending_connects = l_list_remove(pending_connects, ccd);
+ destroy_pending_connect(ccd);
+
+ getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &err_size);
+
+ if(error) {
+ close(source);
+ source = -1;
+ }
+
+ callback(source, error, callback_data);
+}
+
+/**
+ * ay_socket_cancel_async
+ * @tag: a tag returned by ay_socket_new_async
+ *
+ * Description: cancels a pending connect. Does nothing if the
+ * connect already completed or was never requested.
+ **/
+void ay_socket_cancel_async(int tag)
+{
+ LList * l;
+
+ for(l = pending_connects; l; l=l->next) {
+ struct connect_callback_data * ccd = l->data;
+ if(ccd->tag == tag) {
+ pending_connects = l_list_remove_link(pending_connects,
l);
+ destroy_pending_connect(ccd);
+ free(l);
+ /* if this was the last entry, decrement tag_pool */
+ if(tag == tag_pool)
+ tag_pool--;
+ return;
+ }
+ }
+}
+
+/**
+ * ay_socket_new_async
+ * @host: The host to connect to
+ * @port: The port to connect on
+ * @callback: The callback function to call after connect completes
+ * @callback_data: Callback data to pass to the callback function
+ *
+ * Description: Asynchronously connect a socket to the given host and
+ * port. NOTE: The callback function may get called before this
+ * function returns. Call ay_socket_cancel_async to cancel a connect
+ * that hasn't yet called back. Connects that callback do not need
+ * to be cancelled.
+ *
+ * Returns: 0 if connect succeeded immediately (callback is already called);
+ * -1 if connect failed immediately (callback is already called with errno);
+ * a tag that identifies the pending connect and can be used to cancel it.
+ **/
+int ay_socket_new_async(const char * host, int port, ay_socket_callback
callback, void * callback_data)
+{
+ struct sockaddr_in serv_addr;
+ static struct hostent *server;
+ int servfd;
+ struct connect_callback_data * ccd;
+ int error;
+
+ if(tag_pool >= MAXINT)
+ return -1;
+
+ if(!(server = gethostbyname(host))) {
+ errno=h_errno;
+ eb_debug(DBG_CORE, "failed to look up server (%s:%d)\n%d: %s",
+ host, port, errno, strerror(errno));
+ return -1;
+ }
+
+ if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ eb_debug(DBG_CORE, "Socket create error (%d): %s", errno,
strerror(errno));
+ return -1;
+ }
+
+ fcntl(servfd, F_SETFL, O_NONBLOCK);
+
+ eb_debug(DBG_CORE, "connecting to %s:%d\n", host, port);
+
+ memset(&serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ memcpy(&serv_addr.sin_addr.s_addr, *server->h_addr_list,
server->h_length);
+ serv_addr.sin_port = htons(port);
+
+ error = connect(servfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr));
+
+ if(!error) {
+ callback(servfd, 0, callback_data);
+ return 0;
+ } else if(error == -1 && errno == EINPROGRESS) {
+ ccd = calloc(1, sizeof(struct connect_callback_data));
+ ccd->callback = callback;
+ ccd->callback_data = callback_data;
+ ccd->tag = ++tag_pool;
+
+ pending_connects = l_list_append(pending_connects, ccd);
+ ccd->ebi_tag = eb_input_add(servfd, EB_INPUT_WRITE,
connect_complete, ccd);
+ return ccd->tag;
+ } else {
+ close(servfd);
+ callback(-1, errno, callback_data);
+ return -1;
+ }
+}
Index: tcp_util.h
===================================================================
RCS file: /cvsroot/ayttm/ayttm/src/tcp_util.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- tcp_util.h 7 Feb 2003 08:25:33 -0000 1.1
+++ tcp_util.h 7 Feb 2003 10:02:45 -0000 1.2
@@ -31,7 +31,24 @@
#ifndef __TCP_UTIL_H__
#define __TCP_UTIL_H__
-int ay_socket_new(const char * host, int port);
-int ay_tcp_readline(char * buff, int maxlen, int fd);
+/**
+ * @fd: file descriptor to connected socket; -1 if connect fails
+ * @error: 0 on success, else one of the error values returned by connect
+ * @callback_data: callback_data passed to the ay_socket_new_async function
+ **/
+typedef void ( *ay_socket_callback )(int fd, int error, void *callback_data);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ay_socket_new(const char * host, int port);
+int ay_socket_new_async(const char * host, int port, ay_socket_callback
callback, void * callback_data);
+void ay_socket_cancel_async(int tag);
+int ay_tcp_readline(char * buff, int maxlen, int fd);
+
+#ifdef __cplusplus
+}
+#endif
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Ayttm-commits] CVS: ayttm/src tcp_util.c,1.1,1.2 tcp_util.h,1.1,1.2,
Philip S Tellis <address@hidden> <=
- Prev by Date:
Re: [Ayttm-commits] CVS: ayttm/modules/msn2/libmsn2 msn_core.C,1.22,1.23
- Next by Date:
[Ayttm-commits] CVS: ayttm ChangeLog,1.285,1.286 configure.in,1.281,1.282
- Previous by thread:
[Ayttm-commits] CVS: ayttm/src chat_room.c,1.46,1.47 chat_window.c,1.47,1.48 smileys.c,1.16,1.17
- Next by thread:
[Ayttm-commits] CVS: ayttm ChangeLog,1.285,1.286 configure.in,1.281,1.282
- Index(es):