- struct udev_monitor *udev_monitor;
- struct stat statbuf;
-
- if (udev == NULL)
- return NULL;
- if (socket_path == NULL)
- return NULL;
- udev_monitor = udev_monitor_new(udev);
- if (udev_monitor == NULL)
- return NULL;
-
- udev_monitor->sun.sun_family = AF_LOCAL;
- if (socket_path[0] == '@') {
- /* translate leading '@' to abstract namespace */
- util_strscpy(udev_monitor->sun.sun_path, sizeof(udev_monitor->sun.sun_path), socket_path);
- udev_monitor->sun.sun_path[0] = '\0';
- udev_monitor->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path);
- } else if (stat(socket_path, &statbuf) == 0 && S_ISSOCK(statbuf.st_mode)) {
- /* existing socket file */
- util_strscpy(udev_monitor->sun.sun_path, sizeof(udev_monitor->sun.sun_path), socket_path);
- udev_monitor->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path);
- } else {
- /* no socket file, assume abstract namespace socket */
- util_strscpy(&udev_monitor->sun.sun_path[1], sizeof(udev_monitor->sun.sun_path)-1, socket_path);
- udev_monitor->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path)+1;
- }
- udev_monitor->sock = socket(AF_LOCAL, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
- if (udev_monitor->sock == -1) {
- err(udev, "error getting socket: %m\n");
- free(udev_monitor);
- return NULL;
- }
-
- dbg(udev, "monitor %p created with '%s'\n", udev_monitor, socket_path);
- return udev_monitor;