[gnet-dev] Unix socket unlink func



I've been working with the Unix socket API in a project of mine, and
ended up adding a function to safely unlink the server socket.

Patch against CVS attached.

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	Wed Oct 24 17:12:15 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>
@@ -43,7 +42,6 @@
 {
   gchar *path = NULL;
   ServerType server_type = NORMAL;
-  struct stat stbuf;
 	
   if (argc !=  2 && argc != 3) {
     usage(EXIT_FAILURE);
@@ -59,14 +57,11 @@
   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 {
+  if (gnet_unix_socket_unlink(path) == FALSE) {
       g_print("%s is not a socket!\n", path);
       exit(EXIT_FAILURE);
     }
-  }
+
   socket_path = path;
 
   signal(SIGINT, cleanup_on_sig);
@@ -97,12 +92,7 @@
 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_unlink(socket_path);
   exit(EXIT_SUCCESS);
 }
 
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	Wed Oct 24 17:22:39 2001
@@ -28,12 +28,12 @@
  *  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,7 +83,7 @@
  *  gnet_unix_socket_delete:
  *  @s: UnixSocket to delete.
  *
- *  Close and delete a GUnixSocket.
+ *  Close and delete a #GUnixSocket.
  *
  **/
 void
@@ -97,7 +97,7 @@
  *  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 +111,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.  
  *
  **/
@@ -134,8 +134,7 @@
 	    {
 	      if (S_ISSOCK(buf.st_mode)) 
 		{
-		  /* FIXME */
-		  unlink(PATH(s));
+		  gnet_unix_socket_unlink(PATH(s));
 		}
 	    }
 	} 
@@ -147,12 +146,12 @@
  *  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 +160,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 +196,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*
@@ -255,12 +254,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 +308,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 +354,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;
 }
diff -urNb gnet/src/unix.h gnet-unix/src/unix.h
--- gnet/src/unix.h	Tue Oct 23 07:46:20 2001
+++ gnet-unix/src/unix.h	Wed Oct 24 14:47:05 2001
@@ -56,6 +56,8 @@
 GUnixSocket* gnet_unix_socket_server_accept (const GUnixSocket *socket);
 GUnixSocket* gnet_unix_socket_server_accept_nonblock (const GUnixSocket *socket);
 
+gboolean gnet_unix_socket_unlink(gchar *path);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]