summaryrefslogtreecommitdiff
path: root/libudev
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2011-04-20 01:53:03 +0200
committerKay Sievers <kay.sievers@vrfy.org>2011-04-20 01:54:38 +0200
commit2181d30a342dd9fb168b7077ae5095849e328689 (patch)
tree774ceb3aaa1640b550901aab37ef77932a9a5945 /libudev
parent131c9e9240dfd4a54cf18a1c115554110eb02226 (diff)
timeout handling without alarm()
Diffstat (limited to 'libudev')
-rw-r--r--libudev/libudev-device.c21
-rw-r--r--libudev/libudev-private.h7
-rw-r--r--libudev/libudev-util-private.c289
-rw-r--r--libudev/libudev-util.c2
4 files changed, 6 insertions, 313 deletions
diff --git a/libudev/libudev-device.c b/libudev/libudev-device.c
index a141dadf0a..0ef7260de2 100644
--- a/libudev/libudev-device.c
+++ b/libudev/libudev-device.c
@@ -69,7 +69,6 @@ struct udev_device {
struct udev_list_node tags_list;
unsigned long long int seqnum;
unsigned long long int usec_initialized;
- int event_timeout;
int timeout;
int devlink_priority;
int refcount;
@@ -376,7 +375,7 @@ struct udev_device *udev_device_new(struct udev *udev)
udev_list_init(&udev_device->sysattr_value_list);
udev_list_init(&udev_device->sysattr_list);
udev_list_init(&udev_device->tags_list);
- udev_device->event_timeout = -1;
+ udev_device->timeout = -1;
udev_device->watch_handle = -1;
/* copy global properties */
udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev))
@@ -1164,7 +1163,7 @@ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device
udev_device_read_db(udev_device, NULL);
if (udev_device->usec_initialized == 0)
return 0;
- now = usec_monotonic();
+ now = now_usec();
if (now == 0)
return 0;
return now - udev_device->usec_initialized;
@@ -1690,22 +1689,10 @@ int udev_device_get_timeout(struct udev_device *udev_device)
int udev_device_set_timeout(struct udev_device *udev_device, int timeout)
{
- udev_device->timeout = timeout;
- return 0;
-}
-int udev_device_get_event_timeout(struct udev_device *udev_device)
-{
- if (!udev_device->info_loaded)
- udev_device_read_db(udev_device, NULL);
- return udev_device->event_timeout;
-}
-
-int udev_device_set_event_timeout(struct udev_device *udev_device, int event_timeout)
-{
char num[32];
- udev_device->event_timeout = event_timeout;
- snprintf(num, sizeof(num), "%u", event_timeout);
+ udev_device->timeout = timeout;
+ snprintf(num, sizeof(num), "%u", timeout);
udev_device_add_property(udev_device, "TIMEOUT", num);
return 0;
}
diff --git a/libudev/libudev-private.h b/libudev/libudev-private.h
index 63eb0704d6..c47bbce2d6 100644
--- a/libudev/libudev-private.h
+++ b/libudev/libudev-private.h
@@ -96,8 +96,6 @@ int udev_device_has_tag(struct udev_device *udev_device, const char *tag);
int udev_device_set_knodename(struct udev_device *udev_device, const char *knodename);
int udev_device_get_timeout(struct udev_device *udev_device);
int udev_device_set_timeout(struct udev_device *udev_device, int timeout);
-int udev_device_get_event_timeout(struct udev_device *udev_device);
-int udev_device_set_event_timeout(struct udev_device *udev_device, int event_timeout);
int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum);
int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum);
unsigned long long udev_device_get_usec_initialized(struct udev_device *udev_device);
@@ -234,12 +232,9 @@ int util_delete_path(struct udev *udev, const char *path);
int util_unlink_secure(struct udev *udev, const char *filename);
uid_t util_lookup_user(struct udev *udev, const char *user);
gid_t util_lookup_group(struct udev *udev, const char *group);
-int util_run_program(struct udev *udev, const char *command, char **envp,
- char *result, size_t ressize, size_t *reslen,
- const sigset_t *sigmask);
int util_resolve_subsys_kernel(struct udev *udev, const char *string,
char *result, size_t maxsize, int read_value);
-unsigned long long usec_monotonic(void);
+unsigned long long now_usec(void);
/* libudev-selinux-private.c */
#ifndef WITH_SELINUX
diff --git a/libudev/libudev-util-private.c b/libudev/libudev-util-private.c
index 87b9edbc71..2d7f8dc758 100644
--- a/libudev/libudev-util-private.c
+++ b/libudev/libudev-util-private.c
@@ -19,9 +19,6 @@
#include <ctype.h>
#include <pwd.h>
#include <grp.h>
-#include <sys/prctl.h>
-#include <sys/epoll.h>
-#include <sys/wait.h>
#include <sys/param.h>
#include "libudev.h"
@@ -260,289 +257,3 @@ int util_resolve_subsys_kernel(struct udev *udev, const char *string,
udev_device_unref(dev);
return 0;
}
-
-static int run_program_exec(struct udev *udev, int fd_stdout, int fd_stderr,
- char *const argv[], char **envp, const sigset_t *sigmask)
-{
- int err;
- int fd;
-
- /* discard child output or connect to pipe */
- fd = open("/dev/null", O_RDWR);
- if (fd >= 0) {
- dup2(fd, STDIN_FILENO);
- if (fd_stdout < 0)
- dup2(fd, STDOUT_FILENO);
- if (fd_stderr < 0)
- dup2(fd, STDERR_FILENO);
- close(fd);
- } else {
- err(udev, "open /dev/null failed: %m\n");
- }
-
- /* connect pipes to std{out,err} */
- if (fd_stdout >= 0) {
- dup2(fd_stdout, STDOUT_FILENO);
- close(fd_stdout);
- }
- if (fd_stderr >= 0) {
- dup2(fd_stderr, STDERR_FILENO);
- close(fd_stderr);
- }
-
- /* terminate child in case parent goes away */
- prctl(PR_SET_PDEATHSIG, SIGTERM);
-
- /* restore original udev sigmask before exec */
- if (sigmask)
- sigprocmask(SIG_SETMASK, sigmask, NULL);
-
- execve(argv[0], argv, envp);
-
- /* exec failed */
- err = -errno;
- if (err == -ENOENT || err == -ENOTDIR) {
- /* may be on a filesystem which is not mounted right now */
- info(udev, "program '%s' not found\n", argv[0]);
- } else {
- /* other problems */
- err(udev, "exec of program '%s' failed\n", argv[0]);
- }
- return err;
-}
-
-static int run_program_read(struct udev *udev, int fd_stdout, int fd_stderr,
- char *const argv[], char *result, size_t ressize, size_t *reslen)
-{
- size_t respos = 0;
- int fd_ep = -1;
- struct epoll_event ep_outpipe;
- struct epoll_event ep_errpipe;
- int err = 0;
-
- /* read from child if requested */
- if (fd_stdout < 0 && fd_stderr < 0)
- return 0;
-
- fd_ep = epoll_create1(EPOLL_CLOEXEC);
- if (fd_ep < 0) {
- err = -errno;
- err(udev, "error creating epoll fd: %m\n");
- goto out;
- }
-
- if (fd_stdout >= 0) {
- memset(&ep_outpipe, 0, sizeof(struct epoll_event));
- ep_outpipe.events = EPOLLIN;
- ep_outpipe.data.ptr = &fd_stdout;
- if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stdout, &ep_outpipe) < 0) {
- err(udev, "fail to add fd to epoll: %m\n");
- goto out;
- }
- }
-
- if (fd_stderr >= 0) {
- memset(&ep_errpipe, 0, sizeof(struct epoll_event));
- ep_errpipe.events = EPOLLIN;
- ep_errpipe.data.ptr = &fd_stderr;
- if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stderr, &ep_errpipe) < 0) {
- err(udev, "fail to add fd to epoll: %m\n");
- goto out;
- }
- }
-
- /* read child output */
- while (fd_stdout >= 0 || fd_stderr >= 0) {
- int fdcount;
- struct epoll_event ev[4];
- int i;
-
- fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), -1);
- if (fdcount < 0) {
- if (errno == EINTR)
- continue;
- err(udev, "failed to poll: %m\n");
- err = -errno;
- goto out;
- }
-
- for (i = 0; i < fdcount; i++) {
- int *fd = (int *)ev[i].data.ptr;
-
- if (ev[i].events & EPOLLIN) {
- ssize_t count;
- char buf[4096];
-
- count = read(*fd, buf, sizeof(buf)-1);
- if (count <= 0)
- continue;
- buf[count] = '\0';
-
- /* store stdout result */
- if (result != NULL && *fd == fd_stdout) {
- if (respos + count < ressize) {
- memcpy(&result[respos], buf, count);
- respos += count;
- } else {
- err(udev, "ressize %zd too short\n", ressize);
- err = -ENOBUFS;
- }
- }
-
- /* log debug output only if we watch stderr */
- if (fd_stderr >= 0) {
- char *pos;
- char *line;
-
- pos = buf;
- while ((line = strsep(&pos, "\n"))) {
- if (pos != NULL || line[0] != '\0')
- info(udev, "'%s'(%s) '%s'\n", argv[0], *fd == fd_stdout ? "out" : "err" , line);
- }
- }
- } else if (ev[i].events & EPOLLHUP) {
- if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, *fd, NULL) < 0) {
- err = -errno;
- err(udev, "failed to remove fd from epoll: %m\n");
- goto out;
- }
- *fd = -1;
- }
- }
- }
-
- /* return the child's stdout string */
- if (result != NULL) {
- result[respos] = '\0';
- dbg(udev, "result='%s'\n", result);
- if (reslen != NULL)
- *reslen = respos;
- }
-out:
- if (fd_ep >= 0)
- close(fd_ep);
- return err;
-}
-
-int util_run_program(struct udev *udev, const char *command, char **envp,
- char *result, size_t ressize, size_t *reslen,
- const sigset_t *sigmask)
-{
- int status;
- int outpipe[2] = {-1, -1};
- int errpipe[2] = {-1, -1};
- pid_t pid;
- char arg[UTIL_PATH_SIZE];
- char program[UTIL_PATH_SIZE];
- char *argv[((sizeof(arg) + 1) / 2) + 1];
- int i;
- int err = 0;
-
- info(udev, "'%s' started\n", command);
-
- /* build argv from command */
- util_strscpy(arg, sizeof(arg), command);
- i = 0;
- if (strchr(arg, ' ') != NULL) {
- char *pos = arg;
-
- while (pos != NULL && pos[0] != '\0') {
- if (pos[0] == '\'') {
- /* do not separate quotes */
- pos++;
- argv[i] = strsep(&pos, "\'");
- if (pos != NULL)
- while (pos[0] == ' ')
- pos++;
- } else {
- argv[i] = strsep(&pos, " ");
- if (pos != NULL)
- while (pos[0] == ' ')
- pos++;
- }
- dbg(udev, "arg[%i] '%s'\n", i, argv[i]);
- i++;
- }
- argv[i] = NULL;
- } else {
- argv[0] = arg;
- argv[1] = NULL;
- }
-
- /* pipes from child to parent */
- if (result != NULL || udev_get_log_priority(udev) >= LOG_INFO) {
- if (pipe2(outpipe, O_NONBLOCK) != 0) {
- err = -errno;
- err(udev, "pipe failed: %m\n");
- goto out;
- }
- }
- if (udev_get_log_priority(udev) >= LOG_INFO) {
- if (pipe2(errpipe, O_NONBLOCK) != 0) {
- err = -errno;
- err(udev, "pipe failed: %m\n");
- goto out;
- }
- }
-
- /* allow programs in /lib/udev/ to be called without the path */
- if (argv[0][0] != '/') {
- util_strscpyl(program, sizeof(program), LIBEXECDIR "/", argv[0], NULL);
- argv[0] = program;
- }
-
- pid = fork();
- switch(pid) {
- case 0:
- /* child closes parent's ends of pipes */
- if (outpipe[READ_END] >= 0) {
- close(outpipe[READ_END]);
- outpipe[READ_END] = -1;
- }
- if (errpipe[READ_END] >= 0) {
- close(errpipe[READ_END]);
- errpipe[READ_END] = -1;
- }
-
- err = run_program_exec(udev, outpipe[WRITE_END], errpipe[WRITE_END], argv, envp, sigmask);
-
- _exit(1);
- case -1:
- err(udev, "fork of '%s' failed: %m\n", argv[0]);
- err = -1;
- goto out;
- default:
- /* parent closed child's ends of pipes */
- if (outpipe[WRITE_END] >= 0) {
- close(outpipe[WRITE_END]);
- outpipe[WRITE_END] = -1;
- }
- if (errpipe[WRITE_END] >= 0) {
- close(errpipe[WRITE_END]);
- errpipe[WRITE_END] = -1;
- }
-
- err = run_program_read(udev, outpipe[READ_END], errpipe[READ_END], argv, result, ressize, reslen);
-
- waitpid(pid, &status, 0);
- if (WIFEXITED(status)) {
- info(udev, "'%s' returned with exitcode %i\n", command, WEXITSTATUS(status));
- if (WEXITSTATUS(status) != 0)
- err = -1;
- } else {
- err(udev, "'%s' unexpected exit with status 0x%04x\n", command, status);
- err = -1;
- }
- }
-
-out:
- if (outpipe[READ_END] >= 0)
- close(outpipe[READ_END]);
- if (outpipe[WRITE_END] >= 0)
- close(outpipe[WRITE_END]);
- if (errpipe[READ_END] >= 0)
- close(errpipe[READ_END]);
- if (errpipe[WRITE_END] >= 0)
- close(errpipe[WRITE_END]);
- return err;
-}
diff --git a/libudev/libudev-util.c b/libudev/libudev-util.c
index 51dd017467..48eea0b898 100644
--- a/libudev/libudev-util.c
+++ b/libudev/libudev-util.c
@@ -557,7 +557,7 @@ uint64_t util_string_bloom64(const char *str)
#define USEC_PER_SEC 1000000ULL
#define NSEC_PER_USEC 1000ULL
-unsigned long long usec_monotonic(void)
+unsigned long long now_usec(void)
{
struct timespec ts;