glib-aux: add nm_io_sockaddr_un_set() helper

This commit is contained in:
Thomas Haller 2021-08-02 19:27:48 +02:00
parent a29d8b712f
commit 5e658530ab
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 64 additions and 2 deletions

View file

@ -7,9 +7,11 @@
#include "nm-io-utils.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include "nm-str-buf.h"
#include "nm-shared-utils.h"
@ -628,3 +630,48 @@ next:;
g_ptr_array_add(arr, NULL);
return (char **) g_ptr_array_free(arr, FALSE);
}
/*****************************************************************************/
/* taken from systemd's sockaddr_un_set_path(). */
int
nm_io_sockaddr_un_set(struct sockaddr_un *ret, NMOptionBool is_abstract, const char *path)
{
gsize l;
g_return_val_if_fail(ret, -EINVAL);
g_return_val_if_fail(path, -EINVAL);
nm_assert_is_ternary(is_abstract);
if (is_abstract == NM_OPTION_BOOL_DEFAULT)
is_abstract = nm_io_sockaddr_un_path_is_abstract(path, &path);
l = strlen(path);
if (l < 1)
return -EINVAL;
if (l > sizeof(ret->sun_path) - 1)
return -EINVAL;
if (!is_abstract) {
if (path[0] != '/') {
/* non-abstract paths must be absolute. */
return -EINVAL;
}
}
memset(ret, 0, nm_offsetof(struct sockaddr_un, sun_path));
ret->sun_family = AF_UNIX;
if (is_abstract) {
ret->sun_path[0] = '\0';
memcpy(&ret->sun_path[1], path, NM_MIN(l + 1, sizeof(ret->sun_path) - 1));
} else
memcpy(&ret->sun_path, path, l + 1);
/* For pathname addresses, we return the size with the trailing NUL.
* For abstract addresses, we return the size without the trailing NUL
* (which may not be even written). But as abstract sockets also have
* a NUL at the beginning of sun_path, the total length is always
* calculated the same. */
return (nm_offsetof(struct sockaddr_un, sun_path) + 1) + l;
}

View file

@ -60,4 +60,19 @@ void nm_g_subprocess_terminate_in_background(GSubprocess *subprocess, int timeou
char **nm_utils_find_mkstemp_files(const char *dirname, const char *filename);
static inline gboolean
nm_io_sockaddr_un_path_is_abstract(const char *path, const char **out_path)
{
if (path && path[0] == '@') {
NM_SET_OUT(out_path, &path[1]);
return TRUE;
}
NM_SET_OUT(out_path, path);
return FALSE;
}
struct sockaddr_un;
int nm_io_sockaddr_un_set(struct sockaddr_un *ret, NMOptionBool is_abstract, const char *path);
#endif /* __NM_IO_UTILS_H__ */