diff --git a/src/common.h b/src/common.h index 460554bb..589f0696 100644 --- a/src/common.h +++ b/src/common.h @@ -53,11 +53,11 @@ #define G_INPUT_READ (1 << 0) #define G_INPUT_WRITE (1 << 1) -typedef void (*GInputFunction) (void *data, int source, int condition); +typedef void (*GInputFunction) (void *data, GIOChannel *source, int condition); -int g_input_add(int source, int condition, +int g_input_add(GIOChannel *source, int condition, GInputFunction function, void *data); -int g_input_add_full(int source, int priority, int condition, +int g_input_add_full(GIOChannel *source, int priority, int condition, GInputFunction function, void *data); #define MAX_INT_STRLEN ((sizeof(int) * CHAR_BIT + 2) / 3 + 1) diff --git a/src/core/misc.c b/src/core/misc.c index 938f2a40..2363eee7 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -52,20 +52,17 @@ static int irssi_io_invoke(GIOChannel *source, GIOCondition condition, if (condition & G_IO_OUT) icond |= G_INPUT_WRITE; - if (rec->condition & icond) { - rec->function(rec->data, g_io_channel_unix_get_fd(source), - icond); - } + if (rec->condition & icond) + rec->function(rec->data, source, icond); return TRUE; } -int g_input_add_full(int source, int priority, int condition, +int g_input_add_full(GIOChannel *source, int priority, int condition, GInputFunction function, void *data) { IRSSI_INPUT_REC *rec; unsigned int result; - GIOChannel *channel; GIOCondition cond; rec = g_new(IRSSI_INPUT_REC, 1); @@ -79,15 +76,13 @@ int g_input_add_full(int source, int priority, int condition, if (condition & G_INPUT_WRITE) cond |= G_IO_OUT; - channel = g_io_channel_unix_new (source); - result = g_io_add_watch_full(channel, priority, cond, + result = g_io_add_watch_full(source, priority, cond, irssi_io_invoke, rec, g_free); - g_io_channel_unref(channel); return result; } -int g_input_add(int source, int condition, +int g_input_add(GIOChannel *source, int condition, GInputFunction function, void *data) { return g_input_add_full(source, G_PRIORITY_DEFAULT, condition, diff --git a/src/core/net-disconnect.c b/src/core/net-disconnect.c index b5f0212b..3120558f 100644 --- a/src/core/net-disconnect.c +++ b/src/core/net-disconnect.c @@ -29,7 +29,7 @@ typedef struct { time_t created; - int handle; + GIOChannel *handle; int tag; } NET_DISCONNECT_REC; @@ -85,7 +85,7 @@ static int sig_timeout_disconnect(void) /* Try to let the other side close the connection, if it still isn't disconnected after certain amount of time, close it ourself */ -void net_disconnect_later(int handle) +void net_disconnect_later(GIOChannel *handle) { NET_DISCONNECT_REC *rec; @@ -114,7 +114,7 @@ void net_disconnect_deinit(void) #ifndef WIN32 NET_DISCONNECT_REC *rec; time_t now, max; - int first; + int first, fd; struct timeval tv; fd_set set; @@ -131,12 +131,13 @@ void net_disconnect_deinit(void) continue; } + fd = g_io_channel_unix_get_fd(rec->handle); FD_ZERO(&set); - FD_SET(rec->handle, &set); + FD_SET(fd, &set); tv.tv_sec = first ? 0 : max-now; tv.tv_usec = first ? 100000 : 0; - if (select(rec->handle+1, &set, NULL, NULL, &tv) > 0 && - FD_ISSET(rec->handle, &set)) { + if (select(fd+1, &set, NULL, NULL, &tv) > 0 && + FD_ISSET(fd, &set)) { /* data coming .. check if we can close the handle */ sig_disconnect(rec); } else if (first) { diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index c6342e08..e1d99fd8 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -29,15 +29,49 @@ typedef struct { NET_CALLBACK func; void *data; - int pipes[2]; + GIOChannel *pipes[2]; int port; IPADDR *my_ip; int tag; } SIMPLE_THREAD_REC; +#define is_fatal_error(err) \ + (err != 0 && err != G_IO_ERROR_AGAIN && errno != EINTR) + +static int g_io_channel_write_block(GIOChannel *channel, void *data, int len) +{ + int err, ret, sent; + + sent = 0; + do { + err = g_io_channel_write(channel, (char *) data + sent, + len-sent, &ret); + sent += ret; + } while (ret < len && !is_fatal_error(err)); + + return err != 0 ? -1 : 0; +} + +static int g_io_channel_read_block(GIOChannel *channel, void *data, int len) +{ + time_t maxwait; + int err, ret, received; + + maxwait = time(NULL)+2; + received = 0; + do { + err = g_io_channel_read(channel, (char *) data + received, + len-received, &ret); + received += ret; + } while (received < len && time(NULL) < maxwait && + (ret != 0 || !is_fatal_error(err))); + + return received < len ? -1 : 0; +} + /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ -int net_gethostbyname_nonblock(const char *addr, int pipe) +int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe) { RESOLVED_IP_REC rec; const char *errorstr; @@ -72,9 +106,9 @@ int net_gethostbyname_nonblock(const char *addr, int pipe) rec.errlen = strlen(errorstr)+1; } - write(pipe, &rec, sizeof(rec)); + g_io_channel_write_block(pipe, &rec, sizeof(rec)); if (rec.error != 0) - write(pipe, errorstr, rec.errlen); + g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen); #ifndef WIN32 if (pid == 0) @@ -86,45 +120,24 @@ int net_gethostbyname_nonblock(const char *addr, int pipe) } /* get the resolved IP address */ -int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec) +int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec) { - time_t maxwait; - int len, ret; - rec->error = -1; rec->errorstr = NULL; /* get ip+error - try for max. 1-2 seconds */ #ifndef WIN32 - fcntl(pipe, F_SETFL, O_NONBLOCK); + fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK); #endif - maxwait = time(NULL)+2; - len = 0; - do { - ret = read(pipe, (char *) rec+len, sizeof(*rec)-len); - if (ret == -1) return -1; - - len += ret; - } while (len < sizeof(*rec) && time(NULL) < maxwait); - - if (len < sizeof(*rec)) - return -1; /* timeout */ + if (g_io_channel_read_block(pipe, rec, sizeof(*rec)) == -1) + return -1; if (rec->error) { - /* read error string */ - rec->errorstr = g_malloc(rec->errlen+1); - len = 0; - do { - ret = read(pipe, rec->errorstr+len, rec->errlen-len); - if (ret == -1) break; - len += ret; - } while (len < rec->errlen && time(NULL) < maxwait); - - if (len < rec->errlen) { - /* just ignore the rest of the error message.. */ - rec->errorstr[len] = '\0'; - } + /* read error string, if we can't read everything for some + reason, just ignore it. */ + rec->errorstr = g_malloc0(rec->errlen+1); + g_io_channel_read_block(pipe, rec->errorstr, rec->errlen); } return 0; @@ -133,7 +146,7 @@ int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec) /* Get host name, call func when finished */ int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data) { - /*FIXME*/ + /* FIXME: not implemented */ return FALSE; } @@ -147,7 +160,7 @@ void net_disconnect_nonblock(int pid) #endif } -static void simple_init(SIMPLE_THREAD_REC *rec, int handle) +static void simple_init(SIMPLE_THREAD_REC *rec, GIOChannel *handle) { g_return_if_fail(rec != NULL); @@ -155,18 +168,19 @@ static void simple_init(SIMPLE_THREAD_REC *rec, int handle) if (net_geterror(handle) != 0) { /* failed */ - close(handle); - handle = -1; + g_io_channel_close(handle); + g_io_channel_unref(handle); + handle = NULL; } rec->func(handle, rec->data); g_free(rec); } -static void simple_readpipe(SIMPLE_THREAD_REC *rec, int pipe) +static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe) { RESOLVED_IP_REC iprec; - int handle; + GIOChannel *handle; g_return_if_fail(rec != NULL); @@ -175,17 +189,19 @@ static void simple_readpipe(SIMPLE_THREAD_REC *rec, int pipe) net_gethostbyname_return(pipe, &iprec); g_free_not_null(iprec.errorstr); - close(rec->pipes[0]); - close(rec->pipes[1]); + g_io_channel_close(rec->pipes[0]); + g_io_channel_unref(rec->pipes[0]); + g_io_channel_close(rec->pipes[1]); + g_io_channel_unref(rec->pipes[1]); - handle = iprec.error == -1 ? -1 : + handle = iprec.error == -1 ? NULL : net_connect_ip(&iprec.ip, rec->port, rec->my_ip); g_free_not_null(rec->my_ip); - if (handle == -1) { + if (handle == NULL) { /* failed */ - rec->func(-1, rec->data); + rec->func(NULL, rec->data); g_free(rec); return; } @@ -209,9 +225,6 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip, return FALSE; } - /* start nonblocking host name lookup */ - net_gethostbyname_nonblock(server, fd[1]); - rec = g_new0(SIMPLE_THREAD_REC, 1); rec->port = port; if (my_ip != NULL) { @@ -220,10 +233,13 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip, } rec->func = func; rec->data = data; - rec->pipes[0] = fd[0]; - rec->pipes[1] = fd[1]; - rec->tag = g_input_add(fd[0], G_INPUT_READ, + rec->pipes[0] = g_io_channel_unix_new(fd[0]); + rec->pipes[1] = g_io_channel_unix_new(fd[1]); + + /* start nonblocking host name lookup */ + net_gethostbyname_nonblock(server, rec->pipes[1]); + rec->tag = g_input_add(rec->pipes[0], G_INPUT_READ, (GInputFunction) simple_readpipe, rec); - return 1; + return TRUE; } diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index 6e4e10f4..ced58eea 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -20,18 +20,19 @@ typedef struct { char *errorstr; } RESOLVED_NAME_REC; -typedef void (*NET_CALLBACK) (int, void *); +typedef void (*NET_CALLBACK) (GIOChannel *, void *); typedef void (*NET_HOST_CALLBACK) (RESOLVED_NAME_REC *, void *); /* nonblocking gethostbyname(), PID of the resolver child is returned. */ -int net_gethostbyname_nonblock(const char *addr, int pipe); +int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe); /* Get host's name, call func when finished */ int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data); /* get the resolved IP address. returns -1 if some error occured with read() */ -int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec); +int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec); /* Connect to server, call func when finished */ -int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip, NET_CALLBACK func, void *data); +int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip, + NET_CALLBACK func, void *data); /* Kill the resolver child */ void net_disconnect_nonblock(int pid); diff --git a/src/core/net-sendbuffer.c b/src/core/net-sendbuffer.c index 2c11fd4f..c2b0d45c 100644 --- a/src/core/net-sendbuffer.c +++ b/src/core/net-sendbuffer.c @@ -24,7 +24,7 @@ #include "net-sendbuffer.h" struct _NET_SENDBUF_REC { - int handle; + GIOChannel *handle; int bufsize; int bufpos; @@ -36,11 +36,11 @@ static int timeout_tag; /* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE is used */ -NET_SENDBUF_REC *net_sendbuffer_create(int handle, int bufsize) +NET_SENDBUF_REC *net_sendbuffer_create(GIOChannel *handle, int bufsize) { NET_SENDBUF_REC *rec; - g_return_val_if_fail(handle != -1, NULL); + g_return_val_if_fail(handle != NULL, NULL); rec = g_new0(NET_SENDBUF_REC, 1); rec->handle = handle; @@ -148,9 +148,9 @@ int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size) } /* Returns the socket handle */ -int net_sendbuffer_handle(NET_SENDBUF_REC *rec) +GIOChannel *net_sendbuffer_handle(NET_SENDBUF_REC *rec) { - g_return_val_if_fail(rec != NULL, -1); + g_return_val_if_fail(rec != NULL, NULL); return rec->handle; } diff --git a/src/core/net-sendbuffer.h b/src/core/net-sendbuffer.h index 848db9ec..54f2e5ba 100644 --- a/src/core/net-sendbuffer.h +++ b/src/core/net-sendbuffer.h @@ -7,7 +7,7 @@ typedef struct _NET_SENDBUF_REC NET_SENDBUF_REC; /* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE is used */ -NET_SENDBUF_REC *net_sendbuffer_create(int handle, int bufsize); +NET_SENDBUF_REC *net_sendbuffer_create(GIOChannel *handle, int bufsize); /* Destroy the buffer. `close' specifies if socket handle should be closed. */ void net_sendbuffer_destroy(NET_SENDBUF_REC *rec, int close); @@ -17,7 +17,7 @@ void net_sendbuffer_destroy(NET_SENDBUF_REC *rec, int close); int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size); /* Returns the socket handle */ -int net_sendbuffer_handle(NET_SENDBUF_REC *rec); +GIOChannel *net_sendbuffer_handle(NET_SENDBUF_REC *rec); void net_sendbuffer_init(void); void net_sendbuffer_deinit(void); diff --git a/src/core/network.c b/src/core/network.c index 20076739..41e8170a 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -23,7 +23,11 @@ #include "net-internal.h" #ifndef INADDR_NONE -#define INADDR_NONE INADDR_BROADCAST +# define INADDR_NONE INADDR_BROADCAST +#endif + +#ifndef EINPROGRESS +# define EINPROGESS 0 /* win32 */ #endif union sockaddr_union { @@ -41,6 +45,12 @@ union sockaddr_union { # define SIZEOF_SOCKADDR(so) (sizeof(so.sin)) #endif +#ifdef WIN32 +# define g_io_channel_new(handle) g_io_channel_win32_new_stream_socket(handle) +#else +# define g_io_channel_new(handle) g_io_channel_unix_new(handle) +#endif + /* Cygwin need this, don't know others.. */ /*#define BLOCKING_SOCKETS 1*/ @@ -128,20 +138,20 @@ int sin_get_port(union sockaddr_union *so) } /* Connect to socket */ -int net_connect(const char *addr, int port, IPADDR *my_ip) +GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) { IPADDR ip; - g_return_val_if_fail(addr != NULL, -1); + g_return_val_if_fail(addr != NULL, NULL); if (net_gethostbyname(addr, &ip) == -1) - return -1; + return NULL; return net_connect_ip(&ip, port, my_ip); } /* Connect to socket with ip address */ -int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) +GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) { union sockaddr_union so; int handle, ret, opt = 1; @@ -152,7 +162,7 @@ int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) handle = socket(ip->family, SOCK_STREAM, 0); if (handle == -1) - return -1; + return NULL; /* set socket options */ #ifndef WIN32 @@ -174,33 +184,32 @@ int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) sin_set_port(&so, port); ret = connect(handle, &so.sa, SIZEOF_SOCKADDR(so)); -#ifndef WIN32 if (ret < 0 && errno != EINPROGRESS) { close(handle); - return -1; + return NULL; } -#endif - return handle; + return g_io_channel_new(handle); } /* Disconnect socket */ -void net_disconnect(int handle) +void net_disconnect(GIOChannel *handle) { - g_return_if_fail(handle != -1); + g_return_if_fail(handle != NULL); - close(handle); + g_io_channel_close(handle); + g_io_channel_unref(handle); } /* Listen for connections on a socket. if `my_ip' is NULL, listen in any address. */ -int net_listen(IPADDR *my_ip, int *port) +GIOChannel *net_listen(IPADDR *my_ip, int *port) { union sockaddr_union so; int ret, handle, opt = 1; socklen_t len; - g_return_val_if_fail(port != NULL, -1); + g_return_val_if_fail(port != NULL, NULL); memset(&so, 0, sizeof(so)); sin_set_port(&so, *port); @@ -209,7 +218,7 @@ int net_listen(IPADDR *my_ip, int *port) /* create the socket */ handle = socket(so.sin.sin_family, SOCK_STREAM, 0); if (handle == -1) - return -1; + return NULL; /* set socket options */ #ifndef WIN32 @@ -222,44 +231,39 @@ int net_listen(IPADDR *my_ip, int *port) /* specify the address/port we want to listen in */ ret = bind(handle, &so.sa, SIZEOF_SOCKADDR(so)); - if (ret < 0) { - close(handle); - return -1; + if (ret >= 0) { + /* get the actual port we started listen */ + len = SIZEOF_SOCKADDR(so); + ret = getsockname(handle, &so.sa, &len); + if (ret >= 0) { + *port = sin_get_port(&so); + + /* start listening */ + if (listen(handle, 1) >= 0) + return g_io_channel_new(handle); + } + } - /* get the actual port we started listen */ - len = SIZEOF_SOCKADDR(so); - ret = getsockname(handle, &so.sa, &len); - if (ret < 0) { - close(handle); - return -1; - } - - *port = sin_get_port(&so); - - /* start listening */ - if (listen(handle, 1) < 0) { - close(handle); - return -1; - } - - return handle; + /* error */ + close(handle); + return NULL; } /* Accept a connection on a socket */ -int net_accept(int handle, IPADDR *addr, int *port) +GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port) { union sockaddr_union so; int ret; socklen_t addrlen; - g_return_val_if_fail(handle != -1, -1); + g_return_val_if_fail(handle != NULL, NULL); addrlen = SIZEOF_SOCKADDR(so); - ret = accept(handle, &so.sa, &addrlen); + ret = accept(g_io_channel_unix_get_fd(handle), &so.sa, &addrlen); if (ret < 0) - return -1; + return NULL; if (addr != NULL) sin_get_ip(&so, addr); if (port != NULL) *port = sin_get_port(&so); @@ -267,68 +271,54 @@ int net_accept(int handle, IPADDR *addr, int *port) #ifndef WIN32 fcntl(ret, F_SETFL, O_NONBLOCK); #endif - return ret; + return g_io_channel_new(ret); } /* Read data from socket, return number of bytes read, -1 = error */ -int net_receive(int handle, char *buf, int len) +int net_receive(GIOChannel *handle, char *buf, int len) { -#ifdef BLOCKING_SOCKETS - fd_set set; - struct timeval tv; -#endif - int ret; + int ret, err; - g_return_val_if_fail(handle != -1, -1); + g_return_val_if_fail(handle != NULL, -1); g_return_val_if_fail(buf != NULL, -1); -#ifdef BLOCKING_SOCKETS - FD_ZERO(&set); - FD_SET(handle, &set); - tv.tv_sec = 0; - tv.tv_usec = 0; - if (select(handle+1, &set, NULL, NULL, &tv) <= 0 || - !FD_ISSET(handle, &set)) return 0; -#endif - - ret = recv(handle, buf, len, 0); - if (ret == 0) + err = g_io_channel_read(handle, buf, len, &ret); + if (err == 0 && ret == 0) return -1; /* disconnected */ - if (ret == -1 && (errno == EWOULDBLOCK || errno == EAGAIN || - errno == EINTR)) + if (err == G_IO_ERROR_AGAIN || errno == EINTR) return 0; /* no bytes received */ - return ret; + return err == 0 ? ret : -1; } /* Transmit data, return number of bytes sent, -1 = error */ -int net_transmit(int handle, const char *data, int len) +int net_transmit(GIOChannel *handle, const char *data, int len) { - int n; + int ret, err; - g_return_val_if_fail(handle != -1, -1); + g_return_val_if_fail(handle != NULL, -1); g_return_val_if_fail(data != NULL, -1); - n = send(handle, data, len, 0); - if (n == -1 && (errno == EWOULDBLOCK || errno == EAGAIN || - errno == EINTR || errno == EPIPE)) + err = g_io_channel_write(handle, (char *) data, len, &ret); + if (err == G_IO_ERROR_AGAIN || errno == EINTR || errno == EPIPE) return 0; - return n > 0 ? n : -1; + return err == 0 ? ret : -1; } /* Get socket address/port */ -int net_getsockname(int handle, IPADDR *addr, int *port) +int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port) { union sockaddr_union so; socklen_t len; - g_return_val_if_fail(handle != -1, -1); + g_return_val_if_fail(handle != NULL, -1); g_return_val_if_fail(addr != NULL, -1); len = SIZEOF_SOCKADDR(so); - if (getsockname(handle, (struct sockaddr *) &so, &len) == -1) + if (getsockname(g_io_channel_unix_get_fd(handle), + (struct sockaddr *) &so, &len) == -1) return -1; sin_get_ip(&so, addr); @@ -469,12 +459,13 @@ int net_host2ip(const char *host, IPADDR *ip) } /* Get socket error */ -int net_geterror(int handle) +int net_geterror(GIOChannel *handle) { int data; socklen_t len = sizeof(data); - if (getsockopt(handle, SOL_SOCKET, SO_ERROR, (void *) &data, &len) == -1) + if (getsockopt(g_io_channel_unix_get_fd(handle), + SOL_SOCKET, SO_ERROR, (void *) &data, &len) == -1) return -1; return data; diff --git a/src/core/network.h b/src/core/network.h index 31817cdb..b1a0f6e2 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -33,24 +33,24 @@ typedef struct _ipaddr IPADDR; int net_ip_compare(IPADDR *ip1, IPADDR *ip2); /* Connect to socket */ -int net_connect(const char *addr, int port, IPADDR *my_ip); +GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip); /* Connect to socket with ip address */ -int net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); +GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip); /* Disconnect socket */ -void net_disconnect(int handle); +void net_disconnect(GIOChannel *handle); /* Try to let the other side close the connection, if it still isn't disconnected after certain amount of time, close it ourself */ -void net_disconnect_later(int handle); +void net_disconnect_later(GIOChannel *handle); /* Listen for connections on a socket */ -int net_listen(IPADDR *my_ip, int *port); +GIOChannel *net_listen(IPADDR *my_ip, int *port); /* Accept a connection on a socket */ -int net_accept(int handle, IPADDR *addr, int *port); +GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port); /* Read data from socket, return number of bytes read, -1 = error */ -int net_receive(int handle, char *buf, int len); +int net_receive(GIOChannel *handle, char *buf, int len); /* Transmit data, return number of bytes sent, -1 = error */ -int net_transmit(int handle, const char *data, int len); +int net_transmit(GIOChannel *handle, const char *data, int len); /* Get IP address for host, returns 0 = ok, others = error code for net_gethosterror() */ @@ -65,13 +65,13 @@ const char *net_gethosterror(int error); int net_hosterror_notfound(int error); /* Get socket address/port */ -int net_getsockname(int handle, IPADDR *addr, int *port); +int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port); int net_ip2host(IPADDR *ip, char *host); int net_host2ip(const char *host, IPADDR *ip); /* Get socket error */ -int net_geterror(int handle); +int net_geterror(GIOChannel *handle); int is_ipv4_address(const char *host); int is_ipv6_address(const char *host); diff --git a/src/core/server-rec.h b/src/core/server-rec.h index 58742e70..fe10b724 100644 --- a/src/core/server-rec.h +++ b/src/core/server-rec.h @@ -17,7 +17,7 @@ void *handle; /* NET_SENDBUF_REC socket */ int readtag; /* input tag */ /* for net_connect_nonblock() */ -int connect_pipe[2]; +GIOChannel *connect_pipe[2]; int connect_tag; int connect_pid; diff --git a/src/core/servers.c b/src/core/servers.c index fa9e6666..9ba883a4 100644 --- a/src/core/servers.c +++ b/src/core/servers.c @@ -51,9 +51,11 @@ void server_connect_failed(SERVER_REC *server, const char *msg) if (server->handle != NULL) net_sendbuffer_destroy(server->handle, TRUE); - if (server->connect_pipe[0] != -1) { - close(server->connect_pipe[0]); - close(server->connect_pipe[1]); + if (server->connect_pipe[0] != NULL) { + g_io_channel_close(server->connect_pipe[0]); + g_io_channel_unref(server->connect_pipe[0]); + g_io_channel_close(server->connect_pipe[1]); + g_io_channel_unref(server->connect_pipe[1]); } MODULE_DATA_DEINIT(server); @@ -129,7 +131,7 @@ void server_connect_finished(SERVER_REC *server) signal_emit("server connected", 1, server); } -static void server_connect_callback_init(SERVER_REC *server, int handle) +static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle) { int error; @@ -154,7 +156,7 @@ static void server_connect_callback_readpipe(SERVER_REC *server) SERVER_CONNECT_REC *conn; RESOLVED_IP_REC iprec; const char *errormsg; - int handle; + GIOChannel *handle; g_return_if_fail(IS_SERVER(server)); @@ -163,18 +165,20 @@ static void server_connect_callback_readpipe(SERVER_REC *server) net_gethostbyname_return(server->connect_pipe[0], &iprec); - close(server->connect_pipe[0]); - close(server->connect_pipe[1]); + g_io_channel_close(server->connect_pipe[0]); + g_io_channel_unref(server->connect_pipe[0]); + g_io_channel_close(server->connect_pipe[1]); + g_io_channel_unref(server->connect_pipe[1]); - server->connect_pipe[0] = -1; - server->connect_pipe[1] = -1; + server->connect_pipe[0] = NULL; + server->connect_pipe[1] = NULL; conn = server->connrec; - handle = iprec.error != 0 ? -1 : + handle = iprec.error != 0 ? NULL : net_connect_ip(&iprec.ip, conn->proxy != NULL ? conn->proxy_port : conn->port, conn->own_ip != NULL ? conn->own_ip : NULL); - if (handle == -1) { + if (handle == NULL) { /* failed */ if (iprec.error == 0 || !net_hosterror_notfound(iprec.error)) { /* reconnect back only if either @@ -237,19 +241,23 @@ void server_connect_init(SERVER_REC *server) int server_start_connect(SERVER_REC *server) { const char *connect_address; + int fd[2]; g_return_val_if_fail(server != NULL, FALSE); if (server->connrec->port <= 0) return FALSE; server_connect_init(server); - if (pipe(server->connect_pipe) != 0) { + if (pipe(fd) != 0) { g_warning("server_connect(): pipe() failed."); g_free(server->tag); g_free(server->nick); return FALSE; } + server->connect_pipe[0] = g_io_channel_unix_new(fd[0]); + server->connect_pipe[1] = g_io_channel_unix_new(fd[1]); + connect_address = server->connrec->proxy != NULL ? server->connrec->proxy : server->connrec->address; server->connect_pid = diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index f9a8b2c6..e8fc04a9 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -550,7 +550,9 @@ void gui_readline_init(void) cutbuffer = NULL; redir = NULL; idle_time = time(NULL); - readtag = g_input_add_full(0, G_PRIORITY_HIGH, G_INPUT_READ, (GInputFunction) readline, NULL); + readtag = g_input_add_full(g_io_channel_unix_new(0), + G_PRIORITY_HIGH, G_INPUT_READ, + (GInputFunction) readline, NULL); settings_add_str("history", "scroll_page_count", "/2"); diff --git a/src/irc/dcc/dcc-chat.c b/src/irc/dcc/dcc-chat.c index 7ebac58c..e37217f1 100644 --- a/src/irc/dcc/dcc-chat.c +++ b/src/irc/dcc/dcc-chat.c @@ -190,19 +190,20 @@ static void dcc_chat_input(DCC_REC *dcc) static void dcc_chat_listen(DCC_REC *dcc) { IPADDR ip; - int handle, port; + GIOChannel *handle; + int port; g_return_if_fail(dcc != NULL); /* accept connection */ handle = net_accept(dcc->handle, &ip, &port); - if (handle == -1) + if (handle == NULL) return; /* TODO: add paranoia check - see dcc-files.c */ g_source_remove(dcc->tagconn); - close(dcc->handle); + net_disconnect(dcc->handle); dcc->starttime = time(NULL); dcc->handle = handle; @@ -243,14 +244,14 @@ static void dcc_chat_connect(DCC_REC *dcc) g_return_if_fail(dcc != NULL); if (dcc->addrstr[0] == '\0' || - dcc->starttime != 0 || dcc->handle != -1) { + dcc->starttime != 0 || dcc->handle != NULL) { /* already sent a chat request / already chatting */ return; } dcc->handle = net_connect_ip(&dcc->addr, dcc->port, source_host_ok ? source_host_ip : NULL); - if (dcc->handle != -1) { + if (dcc->handle != NULL) { dcc->tagconn = g_input_add(dcc->handle, G_INPUT_WRITE | G_INPUT_READ, (GInputFunction) sig_chat_connected, dcc); @@ -267,8 +268,9 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server) void *free_arg; DCC_REC *dcc; IPADDR own_ip; + GIOChannel *handle; char *nick, *str, host[MAX_IP_LEN]; - int port, handle; + int port; g_return_if_fail(data != NULL); @@ -288,12 +290,13 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server) if (server == NULL || !server->connected) cmd_param_error(CMDERR_NOT_CONNECTED); - if (net_getsockname(net_sendbuffer_handle(server->handle), &own_ip, NULL) == -1) + if (net_getsockname(net_sendbuffer_handle(server->handle), + &own_ip, NULL) == -1) cmd_param_error(CMDERR_ERRNO); port = settings_get_int("dcc_port"); handle = net_listen(&own_ip, &port); - if (handle == -1) + if (handle == NULL) cmd_param_error(CMDERR_ERRNO); dcc = dcc_create(DCC_TYPE_CHAT, handle, nick, "chat", server, NULL); diff --git a/src/irc/dcc/dcc-files.c b/src/irc/dcc/dcc-files.c index b5e1a490..fa059f89 100644 --- a/src/irc/dcc/dcc-files.c +++ b/src/irc/dcc/dcc-files.c @@ -197,7 +197,7 @@ static void dcc_get_connect(DCC_REC *dcc) { dcc->handle = net_connect_ip(&dcc->addr, dcc->port, source_host_ok ? source_host_ip : NULL); - if (dcc->handle != -1) { + if (dcc->handle != NULL) { dcc->tagconn = g_input_add(dcc->handle, G_INPUT_WRITE | G_INPUT_READ, (GInputFunction) sig_dccget_connected, dcc); @@ -209,7 +209,7 @@ static void dcc_get_connect(DCC_REC *dcc) } #define dcc_is_unget(dcc) \ - ((dcc)->type == DCC_TYPE_GET && (dcc)->handle == -1) + ((dcc)->type == DCC_TYPE_GET && (dcc)->handle == NULL) /* SYNTAX: DCC GET [] */ static void cmd_dcc_get(const char *data) @@ -268,7 +268,7 @@ static void dcc_resume_send(DCC_REC *dcc, int port) #define is_accept_ok(type, dcc) \ (g_strcasecmp(type, "ACCEPT") != 0 || \ ((dcc)->type == DCC_TYPE_GET && \ - (dcc)->get_type == DCC_GET_RESUME && (dcc)->handle == -1)) + (dcc)->get_type == DCC_GET_RESUME && (dcc)->handle == NULL)) static void dcc_ctcp_msg(const char *data, IRC_SERVER_REC *server, const char *sender, const char *sendaddr, @@ -453,14 +453,15 @@ static void dcc_send_read_size(DCC_REC *dcc) /* input function: DCC SEND - someone tried to connect to our socket */ static void dcc_send_init(DCC_REC *dcc) { - int handle, port; + GIOChannel *handle; IPADDR addr; + int port; g_return_if_fail(dcc != NULL); /* accept connection */ handle = net_accept(dcc->handle, &addr, &port); - if (handle == -1) + if (handle == NULL) return; /* TODO: some kind of paranoia check would be nice. it would check @@ -468,7 +469,7 @@ static void dcc_send_init(DCC_REC *dcc) address who connected us. */ g_source_remove(dcc->tagconn); - close(dcc->handle); + net_disconnect(dcc->handle); dcc->starttime = time(NULL); dcc->fastsend = settings_get_bool("dcc_fast_send"); @@ -501,10 +502,11 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, void *item) char *target, *fname, *str, *ptr; void *free_arg; char host[MAX_IP_LEN]; - int hfile, hlisten, port; + int hfile, port; long fsize; DCC_REC *dcc, *chat; IPADDR own_ip; + GIOChannel *handle, *hlisten; g_return_if_fail(data != NULL); @@ -549,7 +551,9 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, void *item) lseek(hfile, 0, SEEK_SET); /* get the IP address we use with IRC server */ - if (net_getsockname(chat != NULL ? chat->handle : net_sendbuffer_handle(server->handle), &own_ip, NULL) == -1) { + handle = chat != NULL ? chat->handle : + net_sendbuffer_handle(server->handle); + if (net_getsockname(handle, &own_ip, NULL) == -1) { close(hfile); cmd_param_error(CMDERR_ERRNO); } @@ -557,7 +561,7 @@ static void cmd_dcc_send(const char *data, IRC_SERVER_REC *server, void *item) /* start listening */ port = settings_get_int("dcc_port"); hlisten = net_listen(&own_ip, &port); - if (hlisten == -1) { + if (hlisten == NULL) { close(hfile); cmd_param_error(CMDERR_ERRNO); } diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c index b2223e6a..5f8891e4 100644 --- a/src/irc/dcc/dcc.c +++ b/src/irc/dcc/dcc.c @@ -52,7 +52,7 @@ GSList *dcc_conns; static int dcc_timeouttag; /* Create new DCC record */ -DCC_REC *dcc_create(int type, int handle, const char *nick, const char *arg, +DCC_REC *dcc_create(int type, GIOChannel *handle, const char *nick, const char *arg, IRC_SERVER_REC *server, DCC_REC *chat) { DCC_REC *dcc; @@ -110,7 +110,7 @@ void dcc_destroy(DCC_REC *dcc) signal_emit("dcc destroyed", 1, dcc); if (dcc->fhandle != -1) close(dcc->fhandle); - if (dcc->handle != -1) net_disconnect(dcc->handle); + if (dcc->handle != NULL) net_disconnect(dcc->handle); if (dcc->tagconn != -1) g_source_remove(dcc->tagconn); if (dcc->tagread != -1) g_source_remove(dcc->tagread); if (dcc->tagwrite != -1) g_source_remove(dcc->tagwrite); @@ -304,21 +304,21 @@ static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char if (olddcc != NULL) { /* same DCC request offered again */ if (olddcc->type == DCC_TYPE_CHAT && - olddcc->handle != -1 && olddcc->starttime == 0) { + olddcc->handle != NULL && olddcc->starttime == 0) { /* we requested dcc chat, they requested dcc chat from us .. allow it. */ dcc_destroy(olddcc); } else { /* if the connection isn't open, update the port, otherwise just ignore */ - if (olddcc->handle == -1) + if (olddcc->handle == NULL) olddcc->port = port; cmd_params_free(free_arg); return; } } - dcc = dcc_create(dcctype, -1, sender, arg, server, chat); + dcc = dcc_create(dcctype, NULL, sender, arg, server, chat); dcc_get_address(addrstr, &dcc->addr); net_ip2host(&dcc->addr, dcc->addrstr); dcc->port = port; diff --git a/src/irc/dcc/dcc.h b/src/irc/dcc/dcc.h index 693c676e..b97e4a21 100644 --- a/src/irc/dcc/dcc.h +++ b/src/irc/dcc/dcc.h @@ -40,7 +40,7 @@ typedef struct DCC_REC { int port; /* port we're connected in */ long size, transfd, skipped; /* file size / bytes transferred / skipped at start */ - int handle; /* socket handle */ + GIOChannel *handle; /* socket handle */ void *sendbuf; int tagconn, tagread, tagwrite; int fhandle; /* file handle */ @@ -80,7 +80,7 @@ const char *dcc_type2str(int type); int dcc_str2type(const char *type); void dcc_make_address(IPADDR *ip, char *host); -DCC_REC *dcc_create(int type, int handle, const char *nick, const char *arg, IRC_SERVER_REC *server, DCC_REC *chat); +DCC_REC *dcc_create(int type, GIOChannel *handle, const char *nick, const char *arg, IRC_SERVER_REC *server, DCC_REC *chat); void dcc_destroy(DCC_REC *dcc); /* Send a CTCP message/notify to target. Send the CTCP via DCC chat if