/*
- * Copyright (C) 2003-2010 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
event->udev = udev;
udev_list_init(udev, &event->run_list, false);
event->fd_signal = -1;
- event->birth_usec = now_usec();
+ event->birth_usec = now(CLOCK_MONOTONIC);
event->timeout_usec = 30 * 1000 * 1000;
return event;
}
SUBST_SYS,
};
static const struct subst_map {
- char *name;
- char fmt;
+ const char *name;
+ const char fmt;
enum subst_type type;
} map[] = {
{ .name = "devnode", .fmt = 'N', .type = SUBST_DEVNODE },
goto copy;
}
- for (i = 0; i < ARRAY_SIZE(map); i++) {
- if (strncmp(&from[1], map[i].name, strlen(map[i].name)) == 0) {
+ for (i = 0; i < ELEMENTSOF(map); i++) {
+ if (startswith(&from[1], map[i].name)) {
type = map[i].type;
from += strlen(map[i].name)+1;
goto subst;
goto copy;
}
- for (i = 0; i < ARRAY_SIZE(map); i++) {
+ for (i = 0; i < ELEMENTSOF(map); i++) {
if (from[1] == map[i].fmt) {
type = map[i].type;
from += 2;
if (dev_parent == NULL)
break;
devnode = udev_device_get_devnode(dev_parent);
- if (devnode != NULL) {
- size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
-
- l = util_strpcpy(&s, l, &devnode[devlen]);
- }
+ if (devnode != NULL)
+ l = util_strpcpy(&s, l, devnode + strlen("/dev/"));
break;
}
case SUBST_DEVNODE:
if (udev_device_get_devnode(dev) != NULL)
l = util_strpcpy(&s, l, udev_device_get_devnode(dev));
break;
- case SUBST_NAME: {
- if (event->name != NULL) {
+ case SUBST_NAME:
+ if (event->name != NULL)
l = util_strpcpy(&s, l, event->name);
- } else if (udev_device_get_devnode(dev) != NULL) {
- size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
-
- l = util_strpcpy(&s, l, &udev_device_get_devnode(dev)[devlen]);
- } else {
+ else if (udev_device_get_devnode(dev) != NULL)
+ l = util_strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
+ else
l = util_strpcpy(&s, l, udev_device_get_sysname(dev));
- }
break;
- }
case SUBST_LINKS: {
- size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
struct udev_list_entry *list_entry;
list_entry = udev_device_get_devlinks_list_entry(dev);
if (list_entry == NULL)
break;
- l = util_strpcpy(&s, l, &udev_list_entry_get_name(list_entry)[devlen]);
+ l = util_strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
- l = util_strpcpyl(&s, l, " ", &udev_list_entry_get_name(list_entry)[devlen], NULL);
+ l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
break;
}
case SUBST_ROOT:
- l = util_strpcpy(&s, l, udev_get_dev_path(event->udev));
+ l = util_strpcpy(&s, l, "/dev");
break;
case SUBST_SYS:
- l = util_strpcpy(&s, l, udev_get_sys_path(event->udev));
+ l = util_strpcpy(&s, l, "/sys");
break;
case SUBST_ENV:
if (attr == NULL) {
const char *cmd, char *const argv[], char **envp, const sigset_t *sigmask,
int fd_stdout, int fd_stderr)
{
- struct udev *udev = event->udev;
int err;
int fd;
int fd_stdout, int fd_stderr,
char *result, size_t ressize)
{
- struct udev *udev = event->udev;
size_t respos = 0;
int fd_ep = -1;
struct epoll_event ep_outpipe, ep_errpipe;
int i;
if (event->timeout_usec > 0) {
- unsigned long long age_usec;
+ usec_t age_usec;
- age_usec = now_usec() - event->birth_usec;
+ age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
if (age_usec >= event->timeout_usec) {
log_error("timeout '%s'\n", cmd);
goto out;
timeout = -1;
}
- fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), timeout);
+ fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
if (fdcount < 0) {
if (errno == EINTR)
continue;
static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
{
- struct udev *udev = event->udev;
struct pollfd pfd[1];
int err = 0;
int fdcount;
if (event->timeout_usec > 0) {
- unsigned long long age_usec;
+ usec_t age_usec;
- age_usec = now_usec() - event->birth_usec;
+ age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
if (age_usec >= event->timeout_usec)
timeout = 1000;
else
log_debug("starting '%s'\n", cmd);
- err = spawn_exec(event, cmd, argv, envp, sigmask,
- outpipe[WRITE_END], errpipe[WRITE_END]);
+ spawn_exec(event, cmd, argv, envp, sigmask,
+ outpipe[WRITE_END], errpipe[WRITE_END]);
_exit(2 );
case -1:
return err;
}
-static void rename_netif_kernel_log(struct ifreq ifr)
-{
- int klog;
- FILE *f;
-
- klog = open("/dev/kmsg", O_WRONLY);
- if (klog < 0)
- return;
-
- f = fdopen(klog, "w");
- if (f == NULL) {
- close(klog);
- return;
- }
-
- fprintf(f, "<30>udevd[%u]: renamed network interface %s to %s\n",
- getpid(), ifr.ifr_name, ifr.ifr_newname);
- fclose(f);
-}
-
static int rename_netif(struct udev_event *event)
{
struct udev_device *dev = event->dev;
int sk;
struct ifreq ifr;
- int loop;
int err;
log_debug("changing net interface name from '%s' to '%s'\n",
util_strscpy(ifr.ifr_name, IFNAMSIZ, udev_device_get_sysname(dev));
util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name);
err = ioctl(sk, SIOCSIFNAME, &ifr);
- if (err == 0) {
- rename_netif_kernel_log(ifr);
- goto out;
- }
-
- /* keep trying if the destination interface name already exists */
- err = -errno;
- if (err != -EEXIST)
- goto out;
-
- /* free our own name, another process may wait for us */
- snprintf(ifr.ifr_newname, IFNAMSIZ, "rename%u", udev_device_get_ifindex(dev));
- err = ioctl(sk, SIOCSIFNAME, &ifr);
- if (err < 0) {
- err = -errno;
- goto out;
- }
-
- /* log temporary name */
- rename_netif_kernel_log(ifr);
-
- /* wait a maximum of 90 seconds for our target to become available */
- util_strscpy(ifr.ifr_name, IFNAMSIZ, ifr.ifr_newname);
- util_strscpy(ifr.ifr_newname, IFNAMSIZ, event->name);
- loop = 90 * 20;
- while (loop--) {
- const struct timespec duration = { 0, 1000 * 1000 * 1000 / 20 };
-
- nanosleep(&duration, NULL);
-
- err = ioctl(sk, SIOCSIFNAME, &ifr);
- if (err == 0) {
- rename_netif_kernel_log(ifr);
- break;
- }
+ if (err >= 0) {
+ print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname);
+ } else {
err = -errno;
- if (err != -EEXIST)
- break;
- }
-
-out:
- if (err < 0)
log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname);
+ }
close(sk);
return err;
}
if (major(udev_device_get_devnum(dev)) != 0)
udev_node_remove(dev);
} else {
- event->dev_db = udev_device_new_from_syspath(event->udev, udev_device_get_syspath(dev));
+ event->dev_db = udev_device_new(event->udev);
if (event->dev_db != NULL) {
+ udev_device_set_syspath(event->dev_db, udev_device_get_syspath(dev));
+ udev_device_set_subsystem(event->dev_db, udev_device_get_subsystem(dev));
udev_device_read_db(event->dev_db, NULL);
udev_device_set_info_loaded(event->dev_db);
if (event->dev_db != NULL && udev_device_get_usec_initialized(event->dev_db) > 0)
udev_device_set_usec_initialized(event->dev, udev_device_get_usec_initialized(event->dev_db));
else if (udev_device_get_usec_initialized(event->dev) == 0)
- udev_device_set_usec_initialized(event->dev, now_usec());
+ udev_device_set_usec_initialized(event->dev, now(CLOCK_MONOTONIC));
/* (re)write database file */
udev_device_update_db(dev);
udev_device_unref(event->dev_db);
event->dev_db = NULL;
}
-out:
return err;
}
-int udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
+void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
{
struct udev_list_entry *list_entry;
- int err = 0;
udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
const char *cmd = udev_list_entry_get_name(list_entry);
+ enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry);
- if (strncmp(cmd, "socket:", strlen("socket:")) == 0) {
- struct udev_monitor *monitor;
+ if (builtin_cmd < UDEV_BUILTIN_MAX) {
+ char command[UTIL_PATH_SIZE];
- monitor = udev_monitor_new_from_socket(event->udev, &cmd[strlen("socket:")]);
- if (monitor == NULL)
- continue;
- udev_monitor_send_device(monitor, NULL, event->dev);
- udev_monitor_unref(monitor);
+ udev_event_apply_format(event, cmd, command, sizeof(command));
+ udev_builtin_run(event->dev, builtin_cmd, command, false);
} else {
char program[UTIL_PATH_SIZE];
char **envp;
udev_event_apply_format(event, cmd, program, sizeof(program));
envp = udev_device_get_properties_envp(event->dev);
- if (udev_event_spawn(event, program, envp, sigmask, NULL, 0) < 0) {
- if (udev_list_entry_get_num(list_entry))
- err = -1;
- }
+ udev_event_spawn(event, program, envp, sigmask, NULL, 0);
}
}
- return err;
}