From 71d35fbda475ef8f153e21701e57036739dd02d3 Mon Sep 17 00:00:00 2001 From: Alex Graveley Date: Tue, 22 May 2001 01:10:47 +0000 Subject: [PATCH] gtk-doc fixups. 2001-05-21 Alex Graveley * src/soup-core/soup-queue.c (soup_message_queue): gtk-doc fixups. * src/soup-core/soup-socket.c (soup_socket_server_new): New. (soup_socket_server_accept): New. (soup_socket_server_try_accept): New. --- ChangeLog | 8 ++ libsoup/soup-headers.c | 4 +- libsoup/soup-message.c | 2 + libsoup/soup-queue.c | 9 +- libsoup/soup-server.h | 4 +- libsoup/soup-socket.c | 283 ++++++++++++++++++++++++++++++++++++++++++++++++- libsoup/soup-socket.h | 9 ++ 7 files changed, 312 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 604ce55..a17bae6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2001-05-21 Alex Graveley + + * src/soup-core/soup-queue.c (soup_message_queue): gtk-doc fixups. + + * src/soup-core/soup-socket.c (soup_socket_server_new): New. + (soup_socket_server_accept): New. + (soup_socket_server_try_accept): New. + 2001-05-18 Rodrigo Moya * src/soup-wsdl-runtime/wsdl-soap-parse.c (wsdl_soap_headers): diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c index 1f067bb..6594d38 100644 --- a/libsoup/soup-headers.c +++ b/libsoup/soup-headers.c @@ -91,7 +91,9 @@ soup_headers_parse (gchar *str, if (!end) goto THROW_MALFORMED_HEADER; - g_hash_table_insert (dest, g_strdup (key), g_strndup (val, end - val)); + g_hash_table_insert (dest, + g_strdup (key), + g_strndup (val, end - val)); key = end; } diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c index c1d6402..7e91967 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c @@ -309,6 +309,8 @@ soup_message_get_response_header (SoupMessage *req, * Syncronously send @msg. This call will not return until the transfer is * finished successfully or there is an unrecoverable error. * + * @msg is not free'd upon return. + * * Return value: the %SoupErrorCode of the error encountered while sending, or * SOUP_ERROR_NONE. */ diff --git a/libsoup/soup-queue.c b/libsoup/soup-queue.c index 1ea40e5..c1f0aa3 100644 --- a/libsoup/soup-queue.c +++ b/libsoup/soup-queue.c @@ -597,13 +597,18 @@ soup_idle_handle_new_requests (gpointer unused) * or when an unrecoverable error occurs. * @user_data: a pointer passed to @callback. * - * Queues the message %req for sending. All messages are processed while the + * Queues the message @req for sending. All messages are processed while the * glib main loop runs. If this %SoupMessage has been processed before, any - * resources related to the last it was sent are freed. + * resources related to the time it was last sent are freed. * * If the response %SoupDataBuffer has an owner of %SOUP_BUFFER_USER_OWNED, the * message will not be queued, and @callback will be called with a * %SoupErrorCode of %SOUP_ERROR_CANCELLED. + * + * Upon message completetion, the callback specified in @callback will be + * invoked. If after returning from this callback the message has not been + * requeued using %soup_message_queue, %soup_message_free will be called on + * @req. */ void soup_message_queue (SoupMessage *req, diff --git a/libsoup/soup-server.h b/libsoup/soup-server.h index ec763a6..818bcd2 100644 --- a/libsoup/soup-server.h +++ b/libsoup/soup-server.h @@ -81,11 +81,9 @@ void soup_server_main (void); void soup_server_main_quit (void); - /* Apache module initializtion */ +/* Implement soup_server_init() in your library. */ extern void soup_server_init (void); -/* Implement soup_server_init() in your library. */ - #endif /* SOUP_SERVER_H */ diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c index 81d70b8..8b7494e 100644 --- a/libsoup/soup-socket.c +++ b/libsoup/soup-socket.c @@ -2068,9 +2068,290 @@ soup_socket_get_port(const SoupSocket* socket) return g_ntohs (SOUP_SOCKADDR_IN (socket->addr->sa).sin_port); } +/** + * soup_socket_server_new: + * @port: Port number for the socket (SOUP_SERVER_ANY_PORT if you don't care). + * + * Create and open a new #SoupSocket with the specified port number. + * Use this sort of socket when your are a server and you know what + * the port number should be (or pass 0 if you don't care what the + * port is). + * + * Returns: a new #SoupSocket, or NULL if there was a failure. + **/ +SoupSocket * +soup_socket_server_new (const gint port) +{ + SoupSocket* s; + struct sockaddr_in* sa_in; + socklen_t socklen; -#ifdef SOUP_WIN32 /*********** Windows code ***********/ + /* Create socket */ + s = g_new0 (SoupSocket, 1); + s->ref_count = 1; + + if ((s->sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + g_free (s); + return NULL; + } + + s->addr = g_new0 (SoupAddress, 1); + s->addr->ref_count = 1; + + /* Set up address and port for connection */ + sa_in = (struct sockaddr_in*) &s->addr->sa; + sa_in->sin_family = AF_INET; + sa_in->sin_addr.s_addr = g_htonl (INADDR_ANY); + sa_in->sin_port = g_htons (port); + + /* The socket is set to non-blocking mode later in the Windows + version.*/ +#ifndef SOUP_WIN32 + { + const int on = 1; + gint flags; + + /* Set REUSEADDR so we can reuse the port */ + if (setsockopt (s->sockfd, + SOL_SOCKET, + SO_REUSEADDR, + &on, + sizeof (on)) != 0) + g_warning("Can't set reuse on tcp socket\n"); + + /* Get the flags (should all be 0?) */ + flags = fcntl (s->sockfd, F_GETFL, 0); + if (flags == -1) goto ERROR; + + /* Make the socket non-blocking */ + if (fcntl (s->sockfd, F_SETFL, flags | O_NONBLOCK) == -1) + goto ERROR; + } +#endif + + /* Bind */ + if (bind (s->sockfd, &s->addr->sa, sizeof (s->addr->sa)) != 0) + goto ERROR; + + /* Get the socket name - don't care if it fails */ + socklen = sizeof (s->addr->sa); + getsockname (s->sockfd, &s->addr->sa, &socklen); + + /* Listen */ + if (listen (s->sockfd, 10) != 0) goto ERROR; + + return s; + + ERROR: + close (s->sockfd); + g_free (s->addr); + g_free (s); + return NULL; +} + +#ifndef SOUP_WIN32 /*********** Unix code ***********/ + +/** + * soup_socket_server_accept: + * @socket: #SoupSocket to accept connections from. + * + * Accept a connection from the socket. The socket must have been + * created using soup_socket_server_new(). This function will + * block (use soup_socket_server_try_accept() if you don't + * want to block). If the socket's #GIOChannel is readable, it DOES + * NOT mean that this function will not block. + * + * Returns: a new #SoupSocket if there is another connect, or NULL if + * there's an error. + **/ +SoupSocket * +soup_socket_server_accept (SoupSocket *socket) +{ + gint sockfd; + struct sockaddr sa; + socklen_t n; + fd_set fdset; + SoupSocket* s; + + g_return_val_if_fail (socket != NULL, NULL); + + try_again: + FD_ZERO (&fdset); + FD_SET (socket->sockfd, &fdset); + + if (select (socket->sockfd + 1, &fdset, NULL, NULL, NULL) == -1) { + if (errno == EINTR) goto try_again; + return NULL; + } + + n = sizeof(s->addr->sa); + + if ((sockfd = accept (socket->sockfd, &sa, &n)) == -1) { + if (errno == EWOULDBLOCK || + errno == ECONNABORTED || +#ifdef EPROTO /* OpenBSD does not have EPROTO */ + errno == EPROTO || +#endif + errno == EINTR) + goto try_again; + + return NULL; + } + + s = g_new0 (SoupSocket, 1); + s->ref_count = 1; + s->sockfd = sockfd; + + s->addr = g_new0 (SoupAddress, 1); + s->addr->ref_count = 1; + memcpy (&s->addr->sa, &sa, sizeof (s->addr->sa)); + + return s; +} + +/** + * soup_socket_server_try_accept: + * @socket: SoupSocket to accept connections from. + * + * Accept a connection from the socket without blocking. The socket + * must have been created using soup_socket_server_new(). This + * function is best used with the sockets #GIOChannel. If the + * channel is readable, then you PROBABLY have a connection. It is + * possible for the connection to close by the time you call this, so + * it may return NULL even if the channel was readable. + * + * Returns a new SoupSocket if there is another connect, or NULL + * otherwise. + **/ +SoupSocket * +soup_socket_server_try_accept (SoupSocket *socket) +{ + gint sockfd; + struct sockaddr sa; + socklen_t n; + fd_set fdset; + SoupSocket* s; + struct timeval tv = {0, 0}; + + g_return_val_if_fail (socket != NULL, NULL); + try_again: + FD_ZERO (&fdset); + FD_SET (socket->sockfd, &fdset); + + if (select (socket->sockfd + 1, &fdset, NULL, NULL, &tv) == -1) { + if (errno == EINTR) goto try_again; + return NULL; + } + + n = sizeof(sa); + + if ((sockfd = accept (socket->sockfd, &sa, &n)) == -1) { + /* If we get an error, return. We don't want to try again as we + do in soup_socket_server_accept() - it might cause a + block. */ + return NULL; + } + + s = g_new0 (SoupSocket, 1); + s->ref_count = 1; + s->sockfd = sockfd; + + s->addr = g_new0 (SoupAddress, 1); + s->addr->ref_count = 1; + memcpy (&s->addr->sa, &sa, sizeof (s->addr->sa)); + + return s; +} + +#else /*********** Windows code ***********/ + +SoupSocket * +soup_socket_server_accept (SoupSocket *socket) +{ + gint sockfd; + struct sockaddr sa; + gint n; + fd_set fdset; + SoupSocket* s; + u_long arg; + + g_return_val_if_fail (socket != NULL, NULL); + + FD_ZERO (&fdset); + FD_SET ((unsigned)socket->sockfd, &fdset); + + if (select (socket->sockfd + 1, &fdset, NULL, NULL, NULL) == -1) { + return NULL; + } + + /* make sure the socket is in blocking mode */ + + arg = 0; + if (ioctlsocket (socket->sockfd, FIONBIO, &arg)) + return NULL; + + sockfd = accept (socket->sockfd, &sa, NULL); + /* if it fails, looping isn't going to help */ + + if (sockfd == INVALID_SOCKET) { + return NULL; + } + + s = g_new0 (SoupSocket, 1); + s->ref_count = 1; + s->sockfd = sockfd; + + s->addr = g_new0 (SoupAddress, 1); + s->addr->ref_count = 1; + memcpy (&s->addr->sa, &sa, sizeof (s->addr->sa)); + + return s; +} + +SoupSocket * +soup_socket_server_try_accept (SoupSocket *socket) +{ + gint sockfd; + struct sockaddr sa; + + fd_set fdset; + SoupSocket* s; + u_long arg; + + g_return_val_if_fail (socket != NULL, NULL); + FD_ZERO (&fdset); + FD_SET ((unsigned)socket->sockfd, &fdset); + + if (select (socket->sockfd + 1, &fdset, NULL, NULL, NULL) == -1) { + return NULL; + } + /* make sure the socket is in non-blocking mode */ + + arg = 1; + if (ioctlsocket (socket->sockfd, FIONBIO, &arg)) + return NULL; + + sockfd = accept (socket->sockfd, &sa, NULL); + /* if it fails, looping isn't going to help */ + + if (sockfd == INVALID_SOCKET) { + return NULL; + } + + s = g_new0 (SoupSocket, 1); + s->ref_count = 1; + s->sockfd = sockfd; + + s->addr = g_new0 (SoupAddress, 1); + s->addr->ref_count = 1; + memcpy (&s->addr->sa, &sa, sizeof (s->addr->sa)); + + return s; +} +#endif /*********** End Windows code ***********/ + +#ifdef SOUP_WIN32 /*********** Windows code ***********/ int soup_MainCallBack (GIOChannel *iochannel, GIOCondition condition, diff --git a/libsoup/soup-socket.h b/libsoup/soup-socket.h index da99f2d..e42c967 100644 --- a/libsoup/soup-socket.h +++ b/libsoup/soup-socket.h @@ -133,4 +133,13 @@ SoupAddress *soup_socket_get_address (const SoupSocket* socket); gint soup_socket_get_port (const SoupSocket* socket); + +#define SOUP_SERVER_ANY_PORT 0 + +SoupSocket *soup_socket_server_new (const gint port); + +SoupSocket *soup_socket_server_accept (SoupSocket *socket); + +SoupSocket *soup_socket_server_try_accept (SoupSocket *socket); + #endif /* SOUP_SOCKET_H */ -- 2.7.4