[gnet-dev] Unlinking, take 2
- From: Mark Ferlatte <ferlatte cryptio net>
- To: gnet-dev gnetlibrary org
- Subject: [gnet-dev] Unlinking, take 2
- Date: Thu, 25 Oct 2001 15:08:19 -0700
Patch attached against current CVS.
No longer exports gnet_unix_socket_unlink().
gnet_unix_socket_delete() now destroys socket, ignoring reference count.
gnet_unix_socket_unref() now calls _delete() if necessary.
gnet_unix_socket_server_new() now calls _unlink() before bind(), and
calls _delete() on error.
examples/echoserver-unix.c has been updated to use _delete() instead of
unlink().
And comments have been updated to improve their gtk-docness.
M
diff -urNb gnet/examples/echoserver-unix.c gnet-unix/examples/echoserver-unix.c
--- gnet/examples/echoserver-unix.c Tue Oct 23 07:46:19 2001
+++ gnet-unix/examples/echoserver-unix.c Thu Oct 25 14:58:28 2001
@@ -21,7 +21,6 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <glib.h>
@@ -36,14 +35,13 @@
static void normal_echoserver(gchar *path);
static void async_echoserver(gchar *path);
-gchar *socket_path;
+GUnixSocket *server;
int
main(int argc, char** argv)
{
gchar *path = NULL;
ServerType server_type = NORMAL;
- struct stat stbuf;
if (argc != 2 && argc != 3) {
usage(EXIT_FAILURE);
@@ -59,16 +57,6 @@
path = g_new0(gchar, strlen(argv[argc - 1]));
path = memcpy(path, argv[argc - 1], strlen(argv[argc - 1]));
- if (stat(path, &stbuf) == 0) {
- if (S_ISSOCK(stbuf.st_mode)) {
- unlink(path);
- } else {
- g_print("%s is not a socket!\n", path);
- exit(EXIT_FAILURE);
- }
- }
- socket_path = path;
-
signal(SIGINT, cleanup_on_sig);
signal(SIGTERM, cleanup_on_sig);
@@ -97,19 +85,13 @@
void
cleanup_on_sig(int signum)
{
- struct stat stbuf;
- if (stat(socket_path, &stbuf) == 0) {
- if (S_ISSOCK(stbuf.st_mode)) {
- unlink(socket_path);
- }
- }
+ gnet_unix_socket_delete(server);
exit(EXIT_SUCCESS);
}
static void
normal_echoserver(gchar *path)
{
- GUnixSocket *server;
GUnixSocket *client = NULL;
gchar buffer[1024];
guint n;
@@ -172,7 +154,6 @@
static void
async_echoserver(gchar *path)
{
- GUnixSocket *server;
GIOChannel *iochannel = NULL;
GMainLoop *main_loop = NULL;
diff -urNb gnet/src/unix.c gnet-unix/src/unix.c
--- gnet/src/unix.c Tue Oct 23 07:46:20 2001
+++ gnet-unix/src/unix.c Thu Oct 25 14:55:20 2001
@@ -22,18 +22,18 @@
#include "unix.h"
#define PATH(S) (((struct sockaddr_un *) (&(S)->sa))->sun_path)
-
+gboolean gnet_unix_socket_unlink(gchar *path);
/**
* gnet_unix_socket_connect:
* @path: Path to socket to connect to
*
- * A quick and easy GUnixSocket constructor. This connects to the
+ * A quick and easy #GUnixSocket constructor. This connects to the
* specified path. This function does block. Use this function when
* you are a client connecting to a server and you don't mind
* blocking.
*
- * Returns: A new GUnixSocket, or NULL if there was a failure.
+ * Returns: A new #GUnixSocket, or NULL if there was a failure.
*
**/
GUnixSocket *
@@ -46,11 +46,11 @@
* gnet_unix_socket_new:
* @path: Path to connect to.
*
- * Connect to a specified address. use this sort of socket when
+ * Connect to a specified address. Use this sort of socket when
* you're a client connecting to a server. This function will block
* to connect.
*
- * Returns a new GUnixSocket, or NULL if there was a failure.
+ * Returns: A new #GUnixSocket, or NULL if there was a failure.
*
**/
GUnixSocket *
@@ -83,21 +83,27 @@
* gnet_unix_socket_delete:
* @s: UnixSocket to delete.
*
- * Close and delete a GUnixSocket.
+ * Close and delete a #GUnixSocket, regardless of reference count.
*
**/
void
gnet_unix_socket_delete(GUnixSocket *s)
{
- if (s != NULL)
- gnet_unix_socket_unref(s);
+ g_return_if_fail(s != NULL);
+
+ GNET_CLOSE_SOCKET(s->sockfd); /* Don't care if this fails. */
+ if (s->iochannel)
+ g_io_channel_unref(s->iochannel);
+ if (s->server)
+ gnet_unix_socket_unlink(PATH(s));
+ g_free(s);
}
/**
* gnet_unix_socket_ref
* @s: GUnixSocket to reference
*
- * Increment the reference counter of the GUnixSocket.
+ * Increment the reference counter of a #GUnixSocket.
*
**/
void
@@ -111,7 +117,7 @@
* gnet_unix_socket_unref
* @s: GUnixSocket to unreference
*
- * Remove a reference from the GUnixSocket. When the reference count
+ * Remove a reference from the #GUnixSocket. When the reference count
* reaches 0, the socket is deleted.
*
**/
@@ -121,38 +127,20 @@
g_return_if_fail(s != NULL);
--s->ref_count;
-
if (s->ref_count == 0)
- {
- GNET_CLOSE_SOCKET(s->sockfd); /* Don't care if this fails */
- if (s->iochannel)
- g_io_channel_unref(s->iochannel);
- if (s->server)
- {
- struct stat buf;
- if (stat(PATH(s), &buf) == 0)
- {
- if (S_ISSOCK(buf.st_mode))
- {
- /* FIXME */
- unlink(PATH(s));
- }
- }
- }
- g_free(s);
- }
+ gnet_unix_socket_delete(s);
}
/**
* gnet_unix_socket_get_iochannel
* @socket: GUnixSocket to get GIOChannel from.
*
- * Get the GIOChannel for the GUnixSocket.
+ * Get the #GIOChannel for the #GUnixSocket.
*
- * For a client socket, the GIOChannel represents the data stream.
- * Use it like you would any other GIOChannel.
+ * For a client socket, the #GIOChannel represents the data stream.
+ * Use it like you would any other #GIOChannel.
*
- * For a server socket, however, the GIOChannel represents incoming
+ * For a server socket, however, the #GIOChannel represents incoming
* connections. If you can read from it, there's a connection
* waiting to be accepted.
*
@@ -161,7 +149,7 @@
* you are done with it. However, you should not close the channel -
* this is done when you delete the socket.
*
- * Returns: A GIOChannel; NULL on failure.
+ * Returns: A #GIOChannel; NULL on failure.
*
**/
GIOChannel*
@@ -197,10 +185,10 @@
* gnet_unix_socket_server_new:
* @path: Path for the socket.
*
- * Create and open a new GUnixSocket with the specified path. Use *
+ * Create and open a new #GUnixSocket with the specified path. Use
* this sort of socket when you are a server.
*
- * Returns: a new GUnixSocket, or NULL if there was a failure.
+ * Returns: a new #GUnixSocket, or NULL if there was a failure.
*
**/
GUnixSocket*
@@ -219,6 +207,10 @@
memcpy(sa_un->sun_path, path, strlen(path));
s->ref_count = 1;
s->server = TRUE;
+
+ if (! gnet_unix_socket_unlink(PATH(s)))
+ goto error;
+
s->sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (s->sockfd < 0)
goto error;
@@ -245,7 +237,7 @@
error:
if (s)
- g_free(s);
+ gnet_unix_socket_delete(s);
return NULL;
}
@@ -255,12 +247,12 @@
* @socket: GUnixSocket to accept connections from
*
* Accept connections from the socket. The socket must have been
- * created using gnet_unix_socket_server_new(); This function will
+ * created using gnet_unix_socket_server_new(). This function will
* block (use gnet_unix_socket_server_accept_nonblock() if you don't
- * want to block). If the socket's GIOChannel is readable, it DOES
+ * want to block). If the socket's #GIOChannel is readable, it DOES
* NOT mean that this function will block.
*
- * Returns: a new GUnixSocket if there is another connect, or NULL if
+ * Returns: a new #GUnixSocket if there is another connect, or NULL if
* there's an error.
*
**/
@@ -309,12 +301,12 @@
*
* Accept a connection from the socket without blocking. The socket
* must have been created using gnet_unix_socket_server_new(). This
- * function is best used with the sockets GIOChannel. If the channel
+ * function is best used with the socket's #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 GUnixSocket if there was another connect, or NULL
+ * Returns: a new #GUnixSocket if there was another connect, or NULL
* otherwise.
*
**/
@@ -355,4 +347,41 @@
memcpy(&s->sa, &sa, sizeof(s->sa));
return s;
+}
+
+
+/**
+ * gnet_unix_socket_unlink:
+ * @path: Path to socket to unlink.
+ *
+ * Verifies that the file at the end of the path is a socket, and then
+ * unlinks it.
+ *
+ * Returns: TRUE on success, FALSE on failure.
+ **/
+gboolean
+gnet_unix_socket_unlink(gchar *path)
+{
+ struct stat stbuf;
+ int r;
+
+ g_return_val_if_fail(path != NULL, FALSE);
+ r = stat(path, &stbuf);
+ if (r == 0) {
+ if (S_ISSOCK(stbuf.st_mode)) {
+ if (unlink(path) == 0) {
+ return TRUE;
+ } else {
+ /* Can't unlink */
+ return FALSE;
+ }
+ } else {
+ /* path is not a socket */
+ return FALSE;
+ }
+ } else if (errno == ENOENT) {
+ /* File doesn't exist, so we're okay */
+ return TRUE;
+ }
+ return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]