chiark / gitweb /
util: add pipe_eof()
[elogind.git] / src / util.c
index a271708ba291979b17e6c4881389ad85b921ad4f..4a735dba58025345e4ef5255449ddb424c035960 100644 (file)
@@ -51,6 +51,8 @@
 #include <dlfcn.h>
 #include <sys/wait.h>
 #include <sys/capability.h>
+#include <sys/time.h>
+#include <linux/rtc.h>
 
 #include "macro.h"
 #include "util.h"
@@ -4179,6 +4181,20 @@ finish:
         return r;
 }
 
+bool dirent_is_file(struct dirent *de) {
+        assert(de);
+
+        if (ignore_file(de->d_name))
+                return false;
+
+        if (de->d_type != DT_REG &&
+            de->d_type != DT_LNK &&
+            de->d_type != DT_UNKNOWN)
+                return false;
+
+        return true;
+}
+
 void execute_directory(const char *directory, DIR *d, char *argv[]) {
         DIR *_d = NULL;
         struct dirent *de;
@@ -4212,12 +4228,7 @@ void execute_directory(const char *directory, DIR *d, char *argv[]) {
                 pid_t pid;
                 int k;
 
-                if (ignore_file(de->d_name))
-                        continue;
-
-                if (de->d_type != DT_REG &&
-                    de->d_type != DT_LNK &&
-                    de->d_type != DT_UNKNOWN)
+                if (!dirent_is_file(de))
                         continue;
 
                 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
@@ -4426,6 +4437,24 @@ char* hostname_cleanup(char *s) {
         return s;
 }
 
+int pipe_eof(int fd) {
+        struct pollfd pollfd;
+        int r;
+
+        zero(pollfd);
+        pollfd.fd = fd;
+        pollfd.events = POLLIN|POLLHUP;
+
+        r = poll(&pollfd, 1, 0);
+        if (r < 0)
+                return -errno;
+
+        if (r == 0)
+                return 0;
+
+        return pollfd.revents & POLLHUP;
+}
+
 int terminal_vhangup_fd(int fd) {
         if (ioctl(fd, TIOCVHANGUP) < 0)
                 return -errno;
@@ -4761,3 +4790,81 @@ finish:
         *strv = files;
         return r;
 }
+
+bool hwclock_is_localtime(void) {
+        FILE *f;
+        char line[LINE_MAX];
+        bool local = false;
+
+        /*
+         * The third line of adjtime is "UTC" or "LOCAL" or nothing.
+         *   # /etc/adjtime
+         *   0.0 0 0.0
+         *   0
+         *   UTC
+         */
+        f = fopen("/etc/adjtime", "re");
+        if (f) {
+                if (fgets(line, sizeof(line), f) &&
+                    fgets(line, sizeof(line), f) &&
+                    fgets(line, sizeof(line), f) ) {
+                            if (!strcmp(line, "LOCAL\n"))
+                                 local = true;
+                }
+                fclose(f);
+        }
+        return local;
+}
+
+int hwclock_apply_localtime_delta(void) {
+        const struct timeval *tv_null = NULL;
+        struct timeval tv;
+        struct tm *tm;
+        int minuteswest;
+        struct timezone tz;
+
+        gettimeofday(&tv, NULL);
+        tm = localtime(&tv.tv_sec);
+        minuteswest = tm->tm_gmtoff / 60;
+
+        tz.tz_minuteswest = -minuteswest;
+        tz.tz_dsttime = 0; /* DST_NONE*/
+
+        /*
+         * If the hardware clock does not run in UTC, but in local time:
+         * The very first time we set the kernel's timezone, it will warp
+         * the clock so that it runs in UTC instead of local time.
+         */
+        if (settimeofday(tv_null, &tz) < 0)
+                return -errno;
+        else
+                return minuteswest;
+}
+
+int hwclock_get_time(struct tm *tm) {
+        int fd;
+        int err = 0;
+
+        fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+        if (ioctl(fd, RTC_RD_TIME, tm) < 0)
+                err = -errno;
+        close(fd);
+
+        return err;
+}
+
+int hwclock_set_time(const struct tm *tm) {
+        int fd;
+        int err = 0;
+
+        fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+        if (ioctl(fd, RTC_SET_TIME, tm) < 0)
+                err = -errno;
+        close(fd);
+
+        return err;
+}