#include <fcntl.h>
#include <limits.h>
#include <poll.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
}
static struct sockaddr *
-create_unix_address_from_path (const char *path,
- bool is_abstract,
- size_t *address_size)
+create_unix_address_from_path (const char *path,
+ ply_unix_socket_type_t type,
+ size_t *address_size)
{
struct sockaddr_un *address;
address->sun_family = AF_UNIX;
/* a socket is marked as abstract if its path has the
- * NUL byte at the beginning of the buffer instead of
- * the end
+ * NUL byte at the beginning of the buffer.
*
* Note, we depend on the memory being zeroed by the calloc
* call above.
*/
- if (!is_abstract)
+ if (type == PLY_UNIX_SOCKET_TYPE_ABSTRACT)
strncpy (address->sun_path, path, sizeof (address->sun_path) - 1);
else
strncpy (address->sun_path + 1, path, sizeof (address->sun_path) - 1);
- if (address_size != NULL)
- *address_size = sizeof (struct sockaddr_un);
+ assert (address_size != NULL);
+
+ /* it's very popular to trim the trailing zeros off the end of the path these
+ * days for abstract sockets. Unfortunately, the 0s are part of the name, so
+ * both client and server have to agree.
+ */
+ if (type == PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT)
+ {
+ *address_size = offsetof (struct sockaddr_un, sun_path)
+ + 1 /* NUL */ +
+ strlen (address->sun_path + 1) /* path */;
+ }
+ else
+ {
+ *address_size = sizeof (struct sockaddr_un);
+ }
return (struct sockaddr *) address;
}
int
-ply_connect_to_unix_socket (const char *path,
- bool is_abstract)
+ply_connect_to_unix_socket (const char *path,
+ ply_unix_socket_type_t type)
{
struct sockaddr *address;
size_t address_size;
if (fd < 0)
return -1;
- address = create_unix_address_from_path (path, is_abstract, &address_size);
+ address = create_unix_address_from_path (path, type, &address_size);
if (connect (fd, address, address_size) < 0)
{
}
int
-ply_listen_to_unix_socket (const char *path,
- bool is_abstract)
+ply_listen_to_unix_socket (const char *path,
+ ply_unix_socket_type_t type)
{
struct sockaddr *address;
size_t address_size;
if (fd < 0)
return -1;
- address = create_unix_address_from_path (path, is_abstract, &address_size);
+ address = create_unix_address_from_path (path, type, &address_size);
if (bind (fd, address, address_size) < 0)
{
return -1;
}
- if (!is_abstract)
+ if (type == PLY_UNIX_SOCKET_TYPE_CONCRETE)
{
if (fchmod (fd, 0600) < 0)
{
typedef intptr_t ply_daemon_handle_t;
+typedef enum
+{
+ PLY_UNIX_SOCKET_TYPE_CONCRETE = 0,
+ PLY_UNIX_SOCKET_TYPE_ABSTRACT,
+ PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT
+} ply_unix_socket_type_t;
+
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
#define ply_round_to_multiple(n, m) (((n) + (((m) - 1))) & ~((m) - 1))
bool ply_open_unidirectional_pipe (int *sender_fd,
int *receiver_fd);
-int ply_connect_to_unix_socket (const char *path,
- bool is_abstract);
+int ply_connect_to_unix_socket (const char *path,
+ ply_unix_socket_type_t type);
int ply_listen_to_unix_socket (const char *path,
- bool is_abstract);
+ ply_unix_socket_type_t type);
bool ply_get_credentials_from_fd (int fd,
pid_t *pid,
uid_t *uid,