#include <sys/inotify.h>
#include <sys/poll.h>
#include <libgen.h>
+#include <ctype.h>
#include "macro.h"
#include "util.h"
sl = strlen(s);
pl = strlen(postfix);
+ if (pl == 0)
+ return true;
+
if (sl < pl)
return false;
sl = strlen(s);
pl = strlen(prefix);
+ if (pl == 0)
+ return true;
+
if (sl < pl)
return false;
return memcmp(s, prefix, pl) == 0;
}
+bool startswith_no_case(const char *s, const char *prefix) {
+ size_t sl, pl;
+ unsigned i;
+
+ assert(s);
+ assert(prefix);
+
+ sl = strlen(s);
+ pl = strlen(prefix);
+
+ if (pl == 0)
+ return true;
+
+ if (sl < pl)
+ return false;
+
+ for(i = 0; i < pl; ++i) {
+ if (tolower(s[i]) != tolower(prefix[i]))
+ return false;
+ }
+
+ return true;
+}
+
bool first_word(const char *s, const char *word) {
size_t sl, wl;
if (sl < wl)
return false;
+ if (wl == 0)
+ return true;
+
if (memcmp(s, word, wl) != 0)
return false;
- return (s[wl] == 0 ||
- strchr(WHITESPACE, s[wl]));
+ return s[wl] == 0 ||
+ strchr(WHITESPACE, s[wl]);
}
int close_nointr(int fd) {
}
}
+bool path_equal(const char *a, const char *b) {
+ assert(a);
+ assert(b);
+
+ if ((a[0] == '/') != (b[0] == '/'))
+ return false;
+
+ for (;;) {
+ size_t j, k;
+
+ a += strspn(a, "/");
+ b += strspn(b, "/");
+
+ if (*a == 0 && *b == 0)
+ return true;
+
+ if (*a == 0 || *b == 0)
+ return false;
+
+ j = strcspn(a, "/");
+ k = strcspn(b, "/");
+
+ if (j != k)
+ return false;
+
+ if (memcmp(a, b, j) != 0)
+ return false;
+
+ a += j;
+ b += k;
+ }
+}
+
char *ascii_strlower(char *t) {
char *p;
return
filename[0] == '.' ||
+ streq(filename, "lost+found") ||
endswith(filename, "~") ||
endswith(filename, ".rpmnew") ||
endswith(filename, ".rpmsave") ||
while ((de = readdir(d))) {
int fd = -1;
- if (de->d_name[0] == '.')
+ if (ignore_file(de->d_name))
continue;
if ((r = safe_atoi(de->d_name, &fd)) < 0)
if (ioctl(fd, VT_ACTIVATE, vt) < 0)
r = -errno;
- close_nointr(r);
+ close_nointr_nofail(r);
return r;
}
int r;
bool need_nl = true;
+ fputs("\x1B[1m", stdout);
+
va_start(ap, text);
vprintf(text, ap);
va_end(ap);
+ fputs("\x1B[0m", stdout);
+
fflush(stdout);
if ((r = read_one_char(stdin, &c, &need_nl)) < 0) {
}
int acquire_terminal(const char *name, bool fail, bool force) {
- int fd = -1, notify = -1, r, wd;
+ int fd = -1, notify = -1, r, wd = -1;
assert(name);
}
if (notify >= 0)
- close_nointr(notify);
+ close_nointr_nofail(notify);
if ((r = reset_terminal(fd)) < 0)
log_warning("Failed to reset terminal: %s", strerror(-r));
fail:
if (fd >= 0)
- close_nointr(fd);
+ close_nointr_nofail(fd);
if (notify >= 0)
- close_nointr(notify);
+ close_nointr_nofail(notify);
return r;
}
int release_terminal(void) {
int r = 0, fd;
+ struct sigaction sa_old, sa_new;
- if ((fd = open("/dev/tty", O_RDWR)) < 0)
+ if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY)) < 0)
return -errno;
+ /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
+ * by our own TIOCNOTTY */
+
+ zero(sa_new);
+ sa_new.sa_handler = SIG_IGN;
+ sa_new.sa_flags = SA_RESTART;
+ assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
+
if (ioctl(fd, TIOCNOTTY) < 0)
r = -errno;
+ assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
+
close_nointr_nofail(fd);
return r;
}
return a.st_dev != b.st_dev;
}
+int parse_usec(const char *t, usec_t *usec) {
+ static const struct {
+ const char *suffix;
+ usec_t usec;
+ } table[] = {
+ { "sec", USEC_PER_SEC },
+ { "s", USEC_PER_SEC },
+ { "min", USEC_PER_MINUTE },
+ { "hr", USEC_PER_HOUR },
+ { "h", USEC_PER_HOUR },
+ { "d", USEC_PER_DAY },
+ { "w", USEC_PER_WEEK },
+ { "msec", USEC_PER_MSEC },
+ { "ms", USEC_PER_MSEC },
+ { "m", USEC_PER_MINUTE },
+ { "usec", 1ULL },
+ { "us", 1ULL },
+ { "", USEC_PER_SEC },
+ };
+
+ const char *p;
+ usec_t r = 0;
+
+ assert(t);
+ assert(usec);
+
+ p = t;
+ do {
+ long long l;
+ char *e;
+ unsigned i;
+
+ errno = 0;
+ l = strtoll(p, &e, 10);
+
+ if (errno != 0)
+ return -errno;
+
+ if (l < 0)
+ return -ERANGE;
+
+ if (e == p)
+ return -EINVAL;
+
+ e += strspn(e, WHITESPACE);
+
+ for (i = 0; i < ELEMENTSOF(table); i++)
+ if (startswith(e, table[i].suffix)) {
+ r += (usec_t) l * table[i].usec;
+ p = e + strlen(table[i].suffix);
+ break;
+ }
+
+ if (i >= ELEMENTSOF(table))
+ return -EINVAL;
+
+ } while (*p != 0);
+
+ *usec = r;
+
+ return 0;
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",