diff options
Diffstat (limited to 'src/basic')
57 files changed, 505 insertions, 289 deletions
diff --git a/src/basic/af-list.c b/src/basic/af-list.c index f396115a34..07dfff6ad4 100644 --- a/src/basic/af-list.c +++ b/src/basic/af-list.c @@ -19,16 +19,16 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/socket.h> #include <string.h> +#include <sys/socket.h> -#include "util.h" #include "af-list.h" +#include "util.h" static const struct af_name* lookup_af(register const char *str, register unsigned int len); -#include "af-to-name.h" #include "af-from-name.h" +#include "af-to-name.h" const char *af_to_name(int id) { diff --git a/src/basic/arphrd-list.c b/src/basic/arphrd-list.c index 284043cd90..03d8ad7403 100644 --- a/src/basic/arphrd-list.c +++ b/src/basic/arphrd-list.c @@ -22,13 +22,13 @@ #include <net/if_arp.h> #include <string.h> -#include "util.h" #include "arphrd-list.h" +#include "util.h" static const struct arphrd_name* lookup_arphrd(register const char *str, register unsigned int len); -#include "arphrd-to-name.h" #include "arphrd-from-name.h" +#include "arphrd-to-name.h" const char *arphrd_to_name(int id) { diff --git a/src/basic/async.c b/src/basic/async.c index c3135f0efe..cfc5d224e1 100644 --- a/src/basic/async.c +++ b/src/basic/async.c @@ -68,7 +68,7 @@ int asynchronous_sync(void) { } static void *close_thread(void *p) { - assert_se(close_nointr(PTR_TO_INT(p)) != -EBADF); + assert_se(close_nointr(PTR_TO_FD(p)) != -EBADF); return NULL; } @@ -84,7 +84,7 @@ int asynchronous_close(int fd) { if (fd >= 0) { PROTECT_ERRNO; - r = asynchronous_job(close_thread, INT_TO_PTR(fd)); + r = asynchronous_job(close_thread, FD_TO_PTR(fd)); if (r < 0) assert_se(close_nointr(fd) != -EBADF); } diff --git a/src/basic/audit-util.h b/src/basic/audit-util.h index 6de331c73e..026d3cd9b1 100644 --- a/src/basic/audit-util.h +++ b/src/basic/audit-util.h @@ -21,8 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <sys/types.h> #define AUDIT_SESSION_INVALID ((uint32_t) -1) diff --git a/src/basic/bitmap.h b/src/basic/bitmap.h index 2874bc99f7..9ce7b42d00 100644 --- a/src/basic/bitmap.h +++ b/src/basic/bitmap.h @@ -21,8 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "macro.h" #include "hashmap.h" +#include "macro.h" typedef struct Bitmap Bitmap; diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c index 290fabdeff..be40dc5702 100644 --- a/src/basic/btrfs-util.c +++ b/src/basic/btrfs-util.c @@ -105,7 +105,7 @@ int btrfs_is_filesystem(int fd) { return F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC); } -int btrfs_is_subvol(int fd) { +int btrfs_is_subvol_fd(int fd) { struct stat st; assert(fd >= 0); @@ -121,6 +121,18 @@ int btrfs_is_subvol(int fd) { return btrfs_is_filesystem(fd); } +int btrfs_is_subvol(const char *path) { + _cleanup_close_ int fd = -1; + + assert(path); + + fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY); + if (fd < 0) + return -errno; + + return btrfs_is_subvol_fd(fd); +} + int btrfs_subvol_make(const char *path) { struct btrfs_ioctl_vol_args args = {}; _cleanup_close_ int fd = -1; @@ -1423,12 +1435,16 @@ static int copy_quota_hierarchy(int fd, uint64_t old_subvol_id, uint64_t new_sub return n_old_qgroups; r = btrfs_subvol_get_parent(fd, old_subvol_id, &old_parent_id); - if (r < 0) + if (r == -ENXIO) + /* We have no parent, hence nothing to copy. */ + n_old_parent_qgroups = 0; + else if (r < 0) return r; - - n_old_parent_qgroups = btrfs_qgroup_find_parents(fd, old_parent_id, &old_parent_qgroups); - if (n_old_parent_qgroups < 0) - return n_old_parent_qgroups; + else { + n_old_parent_qgroups = btrfs_qgroup_find_parents(fd, old_parent_id, &old_parent_qgroups); + if (n_old_parent_qgroups < 0) + return n_old_parent_qgroups; + } for (i = 0; i < n_old_qgroups; i++) { uint64_t id; @@ -1682,7 +1698,7 @@ int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlag assert(old_fd >= 0); assert(new_path); - r = btrfs_is_subvol(old_fd); + r = btrfs_is_subvol_fd(old_fd); if (r < 0) return r; if (r == 0) { @@ -1868,7 +1884,7 @@ int btrfs_subvol_auto_qgroup_fd(int fd, uint64_t subvol_id, bool insert_intermed */ if (subvol_id == 0) { - r = btrfs_is_subvol(fd); + r = btrfs_is_subvol_fd(fd); if (r < 0) return r; if (!r) @@ -1885,14 +1901,19 @@ int btrfs_subvol_auto_qgroup_fd(int fd, uint64_t subvol_id, bool insert_intermed if (n > 0) /* already parent qgroups set up, let's bail */ return 0; + qgroups = mfree(qgroups); + r = btrfs_subvol_get_parent(fd, subvol_id, &parent_subvol); - if (r < 0) + if (r == -ENXIO) + /* No parent, hence no qgroup memberships */ + n = 0; + else if (r < 0) return r; - - qgroups = mfree(qgroups); - n = btrfs_qgroup_find_parents(fd, parent_subvol, &qgroups); - if (n < 0) - return n; + else { + n = btrfs_qgroup_find_parents(fd, parent_subvol, &qgroups); + if (n < 0) + return n; + } if (insert_intermediary_qgroup) { uint64_t lowest = 256, new_qgroupid; diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h index fc9efd72d5..8c11ce35d2 100644 --- a/src/basic/btrfs-util.h +++ b/src/basic/btrfs-util.h @@ -56,7 +56,9 @@ typedef enum BtrfsRemoveFlags { } BtrfsRemoveFlags; int btrfs_is_filesystem(int fd); -int btrfs_is_subvol(int fd); + +int btrfs_is_subvol_fd(int fd); +int btrfs_is_subvol(const char *path); int btrfs_reflink(int infd, int outfd); int btrfs_clone_range(int infd, uint64_t in_offset, int ofd, uint64_t out_offset, uint64_t sz); diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c index 7151fc3d0c..8f60561ede 100644 --- a/src/basic/calendarspec.c +++ b/src/basic/calendarspec.c @@ -23,9 +23,10 @@ #include <string.h> #include "alloc-util.h" -#include "string-util.h" #include "calendarspec.h" #include "fileio.h" +#include "parse-util.h" +#include "string-util.h" #define BITS_WEEKDAYS 127 @@ -49,7 +50,7 @@ void calendar_spec_free(CalendarSpec *c) { free_chain(c->day); free_chain(c->hour); free_chain(c->minute); - free_chain(c->second); + free_chain(c->microsecond); free(c); } @@ -135,7 +136,7 @@ int calendar_spec_normalize(CalendarSpec *c) { sort_chain(&c->day); sort_chain(&c->hour); sort_chain(&c->minute); - sort_chain(&c->second); + sort_chain(&c->microsecond); return 0; } @@ -177,7 +178,7 @@ _pure_ bool calendar_spec_valid(CalendarSpec *c) { if (!chain_valid(c->minute, 0, 59)) return false; - if (!chain_valid(c->second, 0, 59)) + if (!chain_valid(c->microsecond, 0, 60*USEC_PER_SEC-1)) return false; return true; @@ -232,7 +233,7 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) { } } -static void format_chain(FILE *f, int space, const CalendarComponent *c) { +static void format_chain(FILE *f, int space, const CalendarComponent *c, bool usec) { assert(f); if (!c) { @@ -241,14 +242,25 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c) { } assert(c->value >= 0); - fprintf(f, "%0*i", space, c->value); - - if (c->repeat > 0) - fprintf(f, "/%i", c->repeat); + if (!usec) + fprintf(f, "%0*i", space, c->value); + else if (c->value % USEC_PER_SEC == 0) + fprintf(f, "%0*i", space, (int) (c->value / USEC_PER_SEC)); + else + fprintf(f, "%0*i.%06i", space, (int) (c->value / USEC_PER_SEC), (int) (c->value % USEC_PER_SEC)); + + if (c->repeat > 0) { + if (!usec) + fprintf(f, "/%i", c->repeat); + else if (c->repeat % USEC_PER_SEC == 0) + fprintf(f, "/%i", (int) (c->repeat / USEC_PER_SEC)); + else + fprintf(f, "/%i.%06i", (int) (c->repeat / USEC_PER_SEC), (int) (c->repeat % USEC_PER_SEC)); + } if (c->next) { fputc(',', f); - format_chain(f, space, c->next); + format_chain(f, space, c->next, usec); } } @@ -270,17 +282,17 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) { fputc(' ', f); } - format_chain(f, 4, c->year); + format_chain(f, 4, c->year, false); fputc('-', f); - format_chain(f, 2, c->month); + format_chain(f, 2, c->month, false); fputc('-', f); - format_chain(f, 2, c->day); + format_chain(f, 2, c->day, false); fputc(' ', f); - format_chain(f, 2, c->hour); + format_chain(f, 2, c->hour, false); fputc(':', f); - format_chain(f, 2, c->minute); + format_chain(f, 2, c->minute, false); fputc(':', f); - format_chain(f, 2, c->second); + format_chain(f, 2, c->microsecond, true); if (c->utc) fputs(" UTC", f); @@ -391,35 +403,70 @@ static int parse_weekdays(const char **p, CalendarSpec *c) { } } -static int prepend_component(const char **p, CalendarComponent **c) { - unsigned long value, repeat = 0; - char *e = NULL, *ee = NULL; - CalendarComponent *cc; - - assert(p); - assert(c); +static int parse_component_decimal(const char **p, bool usec, unsigned long *res) { + unsigned long value; + const char *e = NULL; + char *ee = NULL; + int r; errno = 0; - value = strtoul(*p, &e, 10); + value = strtoul(*p, &ee, 10); if (errno > 0) return -errno; - if (e == *p) + if (ee == *p) return -EINVAL; if ((unsigned long) (int) value != value) return -ERANGE; + e = ee; - if (*e == '/') { - repeat = strtoul(e+1, &ee, 10); - if (errno > 0) - return -errno; - if (ee == e+1) - return -EINVAL; - if ((unsigned long) (int) repeat != repeat) - return -ERANGE; - if (repeat <= 0) + if (usec) { + if (value * USEC_PER_SEC / USEC_PER_SEC != value) return -ERANGE; - e = ee; + value *= USEC_PER_SEC; + if (*e == '.') { + unsigned add; + + e++; + r = parse_fractional_part_u(&e, 6, &add); + if (r < 0) + return r; + + if (add + value < value) + return -ERANGE; + value += add; + } + } + + *p = e; + *res = value; + + return 0; +} + +static int prepend_component(const char **p, bool usec, CalendarComponent **c) { + unsigned long value, repeat = 0; + CalendarComponent *cc; + int r; + const char *e; + + assert(p); + assert(c); + + e = *p; + + r = parse_component_decimal(&e, usec, &value); + if (r < 0) + return r; + + if (*e == '/') { + e++; + r = parse_component_decimal(&e, usec, &repeat); + if (r < 0) + return r; + + if (repeat == 0) + return -ERANGE; } if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != ':') @@ -438,13 +485,31 @@ static int prepend_component(const char **p, CalendarComponent **c) { if (*e ==',') { *p += 1; - return prepend_component(p, c); + return prepend_component(p, usec, c); } return 0; } -static int parse_chain(const char **p, CalendarComponent **c) { +static int const_chain(int value, CalendarComponent **c) { + CalendarComponent *cc = NULL; + + assert(c); + + cc = new0(CalendarComponent, 1); + if (!cc) + return -ENOMEM; + + cc->value = value; + cc->repeat = 0; + cc->next = *c; + + *c = cc; + + return 0; +} + +static int parse_chain(const char **p, bool usec, CalendarComponent **c) { const char *t; CalendarComponent *cc = NULL; int r; @@ -455,12 +520,19 @@ static int parse_chain(const char **p, CalendarComponent **c) { t = *p; if (t[0] == '*') { + if (usec) { + r = const_chain(0, c); + if (r < 0) + return r; + (*c)->repeat = USEC_PER_SEC; + } else + *c = NULL; + *p = t + 1; - *c = NULL; return 0; } - r = prepend_component(&t, &cc); + r = prepend_component(&t, usec, &cc); if (r < 0) { free_chain(cc); return r; @@ -471,24 +543,6 @@ static int parse_chain(const char **p, CalendarComponent **c) { return 0; } -static int const_chain(int value, CalendarComponent **c) { - CalendarComponent *cc = NULL; - - assert(c); - - cc = new0(CalendarComponent, 1); - if (!cc) - return -ENOMEM; - - cc->value = value; - cc->repeat = 0; - cc->next = *c; - - *c = cc; - - return 0; -} - static int parse_date(const char **p, CalendarSpec *c) { const char *t; int r; @@ -503,7 +557,7 @@ static int parse_date(const char **p, CalendarSpec *c) { if (*t == 0) return 0; - r = parse_chain(&t, &first); + r = parse_chain(&t, false, &first); if (r < 0) return r; @@ -519,7 +573,7 @@ static int parse_date(const char **p, CalendarSpec *c) { } t++; - r = parse_chain(&t, &second); + r = parse_chain(&t, false, &second); if (r < 0) { free_chain(first); return r; @@ -540,7 +594,7 @@ static int parse_date(const char **p, CalendarSpec *c) { } t++; - r = parse_chain(&t, &third); + r = parse_chain(&t, false, &third); if (r < 0) { free_chain(first); free_chain(second); @@ -582,7 +636,7 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) { goto finish; } - r = parse_chain(&t, &h); + r = parse_chain(&t, false, &h); if (r < 0) goto fail; @@ -592,7 +646,7 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) { } t++; - r = parse_chain(&t, &m); + r = parse_chain(&t, false, &m); if (r < 0) goto fail; @@ -610,7 +664,7 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) { } t++; - r = parse_chain(&t, &s); + r = parse_chain(&t, true, &s); if (r < 0) goto fail; @@ -639,7 +693,8 @@ finish: *p = t; c->hour = h; c->minute = m; - c->second = s; + c->microsecond = s; + return 0; fail: @@ -671,7 +726,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { } if (strcaseeq(p, "minutely")) { - r = const_chain(0, &c->second); + r = const_chain(0, &c->microsecond); if (r < 0) goto fail; @@ -679,7 +734,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { r = const_chain(0, &c->minute); if (r < 0) goto fail; - r = const_chain(0, &c->second); + r = const_chain(0, &c->microsecond); if (r < 0) goto fail; @@ -690,7 +745,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { r = const_chain(0, &c->minute); if (r < 0) goto fail; - r = const_chain(0, &c->second); + r = const_chain(0, &c->microsecond); if (r < 0) goto fail; @@ -704,7 +759,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { r = const_chain(0, &c->minute); if (r < 0) goto fail; - r = const_chain(0, &c->second); + r = const_chain(0, &c->microsecond); if (r < 0) goto fail; @@ -724,7 +779,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { r = const_chain(0, &c->minute); if (r < 0) goto fail; - r = const_chain(0, &c->second); + r = const_chain(0, &c->microsecond); if (r < 0) goto fail; @@ -738,7 +793,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { r = const_chain(0, &c->minute); if (r < 0) goto fail; - r = const_chain(0, &c->second); + r = const_chain(0, &c->microsecond); if (r < 0) goto fail; @@ -765,7 +820,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { r = const_chain(0, &c->minute); if (r < 0) goto fail; - r = const_chain(0, &c->second); + r = const_chain(0, &c->microsecond); if (r < 0) goto fail; @@ -789,7 +844,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) { r = const_chain(0, &c->minute); if (r < 0) goto fail; - r = const_chain(0, &c->second); + r = const_chain(0, &c->microsecond); if (r < 0) goto fail; @@ -906,14 +961,16 @@ static bool matches_weekday(int weekdays_bits, const struct tm *tm, bool utc) { return (weekdays_bits & (1 << k)); } -static int find_next(const CalendarSpec *spec, struct tm *tm) { +static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) { struct tm c; + int tm_usec; int r; assert(spec); assert(tm); c = *tm; + tm_usec = *usec; for (;;) { /* Normalize the current date */ @@ -927,7 +984,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) { if (r > 0) { c.tm_mon = 0; c.tm_mday = 1; - c.tm_hour = c.tm_min = c.tm_sec = 0; + c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0; } if (r < 0 || tm_out_of_bounds(&c, spec->utc)) return r; @@ -938,29 +995,29 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) { if (r > 0) { c.tm_mday = 1; - c.tm_hour = c.tm_min = c.tm_sec = 0; + c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0; } if (r < 0 || tm_out_of_bounds(&c, spec->utc)) { c.tm_year ++; c.tm_mon = 0; c.tm_mday = 1; - c.tm_hour = c.tm_min = c.tm_sec = 0; + c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0; continue; } r = find_matching_component(spec->day, &c.tm_mday); if (r > 0) - c.tm_hour = c.tm_min = c.tm_sec = 0; + c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0; if (r < 0 || tm_out_of_bounds(&c, spec->utc)) { c.tm_mon ++; c.tm_mday = 1; - c.tm_hour = c.tm_min = c.tm_sec = 0; + c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0; continue; } if (!matches_weekday(spec->weekdays_bits, &c, spec->utc)) { c.tm_mday++; - c.tm_hour = c.tm_min = c.tm_sec = 0; + c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0; continue; } @@ -969,7 +1026,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) { c.tm_min = c.tm_sec = 0; if (r < 0 || tm_out_of_bounds(&c, spec->utc)) { c.tm_mday ++; - c.tm_hour = c.tm_min = c.tm_sec = 0; + c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0; continue; } @@ -978,19 +1035,23 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) { c.tm_sec = 0; if (r < 0 || tm_out_of_bounds(&c, spec->utc)) { c.tm_hour ++; - c.tm_min = c.tm_sec = 0; + c.tm_min = c.tm_sec = tm_usec = 0; continue; } - r = find_matching_component(spec->second, &c.tm_sec); + c.tm_sec = c.tm_sec * USEC_PER_SEC + tm_usec; + r = find_matching_component(spec->microsecond, &c.tm_sec); + tm_usec = c.tm_sec % USEC_PER_SEC; + c.tm_sec /= USEC_PER_SEC; + if (r < 0 || tm_out_of_bounds(&c, spec->utc)) { c.tm_min ++; - c.tm_sec = 0; + c.tm_sec = tm_usec = 0; continue; } - *tm = c; + *usec = tm_usec; return 0; } } @@ -999,14 +1060,17 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next) struct tm tm; time_t t; int r; + usec_t tm_usec; assert(spec); assert(next); - t = (time_t) (usec / USEC_PER_SEC) + 1; + usec++; + t = (time_t) (usec / USEC_PER_SEC); assert_se(localtime_or_gmtime_r(&t, &tm, spec->utc)); + tm_usec = usec % USEC_PER_SEC; - r = find_next(spec, &tm); + r = find_next(spec, &tm, &tm_usec); if (r < 0) return r; @@ -1014,6 +1078,6 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next) if (t == (time_t) -1) return -EINVAL; - *next = (usec_t) t * USEC_PER_SEC; + *next = (usec_t) t * USEC_PER_SEC + tm_usec; return 0; } diff --git a/src/basic/calendarspec.h b/src/basic/calendarspec.h index 56dc02f391..75b699682a 100644 --- a/src/basic/calendarspec.h +++ b/src/basic/calendarspec.h @@ -25,6 +25,7 @@ * time, a la cron */ #include <stdbool.h> + #include "util.h" typedef struct CalendarComponent { @@ -44,7 +45,7 @@ typedef struct CalendarSpec { CalendarComponent *hour; CalendarComponent *minute; - CalendarComponent *second; + CalendarComponent *microsecond; } CalendarSpec; void calendar_spec_free(CalendarSpec *c); diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c index 4d391510bc..f0974900cd 100644 --- a/src/basic/cap-list.c +++ b/src/basic/cap-list.c @@ -28,8 +28,8 @@ static const struct capability_name* lookup_capability(register const char *str, register unsigned int len); -#include "cap-to-name.h" #include "cap-from-name.h" +#include "cap-to-name.h" const char *capability_to_name(int id) { diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 01359fa7cb..a80ee60bd3 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -21,12 +21,12 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/types.h> -#include <stdio.h> #include <dirent.h> +#include <stdio.h> +#include <sys/types.h> -#include "set.h" #include "def.h" +#include "set.h" /* An enum of well known cgroup controllers */ typedef enum CGroupController { diff --git a/src/basic/errno-list.c b/src/basic/errno-list.c index 34d1331486..22869e4136 100644 --- a/src/basic/errno-list.c +++ b/src/basic/errno-list.c @@ -21,14 +21,14 @@ #include <string.h> -#include "util.h" #include "errno-list.h" +#include "util.h" static const struct errno_name* lookup_errno(register const char *str, register unsigned int len); -#include "errno-to-name.h" #include "errno-from-name.h" +#include "errno-to-name.h" const char *errno_to_name(int id) { diff --git a/src/basic/escape.c b/src/basic/escape.c index 4815161b09..42a84c9317 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -89,20 +89,20 @@ size_t cescape_char(char c, char *buf) { return buf - buf_old; } -char *cescape(const char *s) { - char *r, *t; +char *cescape_length(const char *s, size_t n) { const char *f; + char *r, *t; - assert(s); + assert(s || n == 0); /* Does C style string escaping. May be reversed with * cunescape(). */ - r = new(char, strlen(s)*4 + 1); + r = new(char, n*4 + 1); if (!r) return NULL; - for (f = s, t = r; *f; f++) + for (f = s, t = r; f < s + n; f++) t += cescape_char(*f, t); *t = 0; @@ -110,6 +110,12 @@ char *cescape(const char *s) { return r; } +char *cescape(const char *s) { + assert(s); + + return cescape_length(s, strlen(s)); +} + int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) { int r = 1; diff --git a/src/basic/escape.h b/src/basic/escape.h index 85ba909081..52ebf11c4a 100644 --- a/src/basic/escape.h +++ b/src/basic/escape.h @@ -21,8 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/types.h> #include <inttypes.h> +#include <sys/types.h> /* What characters are special in the shell? */ /* must be escaped outside and inside double-quotes */ @@ -35,6 +35,7 @@ typedef enum UnescapeFlags { } UnescapeFlags; char *cescape(const char *s); +char *cescape_length(const char *s, size_t n); size_t cescape_char(char c, char *buf); int cunescape(const char *s, UnescapeFlags flags, char **ret); diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c index fcff753ada..4c83731540 100644 --- a/src/basic/exit-status.c +++ b/src/basic/exit-status.c @@ -19,12 +19,12 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdlib.h> #include <signal.h> +#include <stdlib.h> #include "exit-status.h" -#include "set.h" #include "macro.h" +#include "set.h" const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) { diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h index 1ca10f0383..5ce1592eeb 100644 --- a/src/basic/fd-util.h +++ b/src/basic/fd-util.h @@ -21,13 +21,17 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdio.h> #include <dirent.h> #include <stdbool.h> +#include <stdio.h> #include <sys/socket.h> #include "macro.h" +/* Make sure we can distinguish fd 0 and NULL */ +#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1) +#define PTR_TO_FD(p) (PTR_TO_INT(p)-1) + int close_nointr(int fd); int safe_close(int fd); void safe_close_pair(int p[]); diff --git a/src/basic/fdset.c b/src/basic/fdset.c index 42b0b2b98f..e5452f3bb0 100644 --- a/src/basic/fdset.c +++ b/src/basic/fdset.c @@ -19,8 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <errno.h> #include <dirent.h> +#include <errno.h> #include <fcntl.h> #include "sd-daemon.h" @@ -36,10 +36,6 @@ #define MAKE_SET(s) ((Set*) s) #define MAKE_FDSET(s) ((FDSet*) s) -/* Make sure we can distinguish fd 0 and NULL */ -#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1) -#define PTR_TO_FD(p) (PTR_TO_INT(p)-1) - FDSet *fdset_new(void) { return MAKE_FDSET(set_new(NULL)); } diff --git a/src/basic/fileio-label.c b/src/basic/fileio-label.c index f596f1d11f..0405822ce0 100644 --- a/src/basic/fileio-label.c +++ b/src/basic/fileio-label.c @@ -20,9 +20,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "util.h" -#include "selinux-util.h" #include "fileio-label.h" +#include "selinux-util.h" +#include "util.h" int write_string_file_atomic_label(const char *fn, const char *line) { int r; diff --git a/src/basic/fileio-label.h b/src/basic/fileio-label.h index 25fa351be2..9feb3cccb5 100644 --- a/src/basic/fileio-label.h +++ b/src/basic/fileio-label.h @@ -23,6 +23,7 @@ ***/ #include <stdio.h> + #include "fileio.h" int write_string_file_atomic_label(const char *fn, const char *line); diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index 902c7e295b..5fbb7bc4c3 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -22,10 +22,10 @@ ***/ #include <fcntl.h> +#include <limits.h> #include <sys/inotify.h> #include <sys/types.h> #include <unistd.h> -#include <limits.h> #include "time-util.h" diff --git a/src/basic/gunicode.h b/src/basic/gunicode.h index e70818fdd7..b03aa43160 100644 --- a/src/basic/gunicode.h +++ b/src/basic/gunicode.h @@ -6,8 +6,8 @@ #pragma once -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> char *utf8_prev_char (const char *p); diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c index 4109a08c6c..6e501ef6ff 100644 --- a/src/basic/hashmap.c +++ b/src/basic/hashmap.c @@ -380,7 +380,7 @@ static unsigned base_bucket_hash(HashmapBase *h, const void *p) { h->hash_ops->hash(p, &state); - siphash24_finalize((uint8_t*)&hash, &state); + hash = siphash24_finalize(&state); return (unsigned) (hash % n_buckets(h)); } diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c index ea0528c6fc..c57a3cbd60 100644 --- a/src/basic/hostname-util.c +++ b/src/basic/hostname-util.c @@ -72,7 +72,7 @@ static bool hostname_valid_char(char c) { * allow_trailing_dot is true and at least two components are present * in the name. Note that due to the restricted charset and length * this call is substantially more conservative than - * dns_domain_is_valid(). + * dns_name_is_valid(). */ bool hostname_is_valid(const char *s, bool allow_trailing_dot) { unsigned n_dots = 0; diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index f4e24121e7..b75c39aac7 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -44,7 +44,7 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) { assert(u); if (family == AF_INET) - return (be32toh(u->in.s_addr) & 0xFFFF0000) == (169U << 24 | 254U << 16); + return (be32toh(u->in.s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16); if (family == AF_INET6) return IN6_IS_ADDR_LINKLOCAL(&u->in6); @@ -52,6 +52,19 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) { return -EAFNOSUPPORT; } +int in_addr_is_localhost(int family, const union in_addr_union *u) { + assert(u); + + if (family == AF_INET) + /* All of 127.x.x.x is localhost. */ + return (be32toh(u->in.s_addr) & UINT32_C(0xFF000000)) == UINT32_C(127) << 24; + + if (family == AF_INET6) + return IN6_IS_ADDR_LOOPBACK(&u->in6); + + return -EAFNOSUPPORT; +} + int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) { assert(a); assert(b); diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h index 51af08868c..58f55b3418 100644 --- a/src/basic/in-addr-util.h +++ b/src/basic/in-addr-util.h @@ -33,6 +33,7 @@ union in_addr_union { int in_addr_is_null(int family, const union in_addr_union *u); int in_addr_is_link_local(int family, const union in_addr_union *u); +int in_addr_is_localhost(int family, const union in_addr_union *u); int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b); int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); diff --git a/src/basic/ioprio.h b/src/basic/ioprio.h index e5c71d0043..d8bb6eb497 100644 --- a/src/basic/ioprio.h +++ b/src/basic/ioprio.h @@ -4,8 +4,8 @@ /* This is minimal version of Linux' linux/ioprio.h header file, which * is licensed GPL2 */ -#include <unistd.h> #include <sys/syscall.h> +#include <unistd.h> /* * Gives us 8 prio classes with 13-bits of data for each class diff --git a/src/basic/json.c b/src/basic/json.c index 716705e5ff..9d5dedb934 100644 --- a/src/basic/json.c +++ b/src/basic/json.c @@ -23,9 +23,9 @@ #include <sys/types.h> #include "alloc-util.h" +#include "hexdecoct.h" #include "json.h" #include "macro.h" -#include "hexdecoct.h" #include "string-util.h" #include "utf8.h" diff --git a/src/basic/json.h b/src/basic/json.h index e0b4d810b5..8a7d79cb17 100644 --- a/src/basic/json.h +++ b/src/basic/json.h @@ -22,6 +22,7 @@ ***/ #include <stdbool.h> + #include "util.h" enum { diff --git a/src/basic/label.c b/src/basic/label.c index 82f10b21bd..f33502f90f 100644 --- a/src/basic/label.c +++ b/src/basic/label.c @@ -19,10 +19,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include "label.h" #include "selinux-util.h" #include "smack-util.h" #include "util.h" -#include "label.h" int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { int r, q; diff --git a/src/basic/lockfile-util.c b/src/basic/lockfile-util.c index 87c3aef7af..0bdbae480b 100644 --- a/src/basic/lockfile-util.c +++ b/src/basic/lockfile-util.c @@ -19,12 +19,12 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdlib.h> -#include <stdbool.h> #include <errno.h> -#include <string.h> -#include <stdio.h> #include <limits.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <sys/file.h> #include "alloc-util.h" diff --git a/src/basic/login-util.c b/src/basic/login-util.c index 832f477bd2..41cef14e73 100644 --- a/src/basic/login-util.c +++ b/src/basic/login-util.c @@ -20,8 +20,8 @@ ***/ #include "def.h" -#include "string-util.h" #include "login-util.h" +#include "string-util.h" bool session_id_valid(const char *id) { diff --git a/src/basic/memfd-util.h b/src/basic/memfd-util.h index 2cb404ea81..3e4de008a4 100644 --- a/src/basic/memfd-util.h +++ b/src/basic/memfd-util.h @@ -21,8 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/types.h> #include <inttypes.h> +#include <sys/types.h> int memfd_new(const char *name); int memfd_new_and_map(const char *name, size_t sz, void **p); diff --git a/src/basic/mempool.c b/src/basic/mempool.c index d5d98d8829..9ee6e6a76d 100644 --- a/src/basic/mempool.c +++ b/src/basic/mempool.c @@ -20,8 +20,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include "mempool.h" #include "macro.h" +#include "mempool.h" #include "util.h" struct pool { diff --git a/src/basic/mkdir-label.c b/src/basic/mkdir-label.c index 76bbc1edda..c241ef6064 100644 --- a/src/basic/mkdir-label.c +++ b/src/basic/mkdir-label.c @@ -20,8 +20,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <unistd.h> #include <stdio.h> +#include <unistd.h> #include "label.h" #include "mkdir.h" diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c index 0214c4627e..5d7fb9a12d 100644 --- a/src/basic/mkdir.c +++ b/src/basic/mkdir.c @@ -19,8 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <string.h> #include <errno.h> +#include <string.h> #include "fs-util.h" #include "mkdir.h" diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h index 6c617ab305..da10e90ff2 100644 --- a/src/basic/ordered-set.h +++ b/src/basic/ordered-set.h @@ -29,6 +29,17 @@ static inline OrderedSet* ordered_set_new(const struct hash_ops *ops) { return (OrderedSet*) ordered_hashmap_new(ops); } +static inline int ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops) { + if (*s) + return 0; + + *s = ordered_set_new(ops); + if (!*s) + return -ENOMEM; + + return 0; +} + static inline OrderedSet* ordered_set_free(OrderedSet *s) { ordered_hashmap_free((OrderedHashmap*) s); return NULL; diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index 151067e916..3ae99d9334 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -490,3 +490,39 @@ int safe_atod(const char *s, double *ret_d) { *ret_d = (double) d; return 0; } + +int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { + size_t i; + unsigned val = 0; + const char *s; + + s = *p; + + /* accept any number of digits, strtoull is limted to 19 */ + for(i=0; i < digits; i++,s++) { + if (*s < '0' || *s > '9') { + if (i == 0) + return -EINVAL; + + /* too few digits, pad with 0 */ + for (; i < digits; i++) + val *= 10; + + break; + } + + val *= 10; + val += *s - '0'; + } + + /* maybe round up */ + if (*s >= '5' && *s <= '9') + val++; + + s += strspn(s, DIGITS); + + *p = s; + *res = val; + + return 0; +} diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index 408690d0b3..125de53d7a 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -90,3 +90,5 @@ static inline int safe_atoli(const char *s, long int *ret_u) { #endif int safe_atod(const char *s, double *ret_d); + +int parse_fractional_part_u(const char **s, size_t digits, unsigned *res); diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 72633ebf70..fdc7e1bdef 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -19,12 +19,12 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdbool.h> -#include <sys/types.h> #include <alloca.h> +#include <signal.h> +#include <stdbool.h> #include <stdio.h> #include <string.h> -#include <signal.h> +#include <sys/types.h> #include "formats-util.h" #include "macro.h" diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c index a821a3d5bb..e8ce5cfd96 100644 --- a/src/basic/selinux-util.c +++ b/src/basic/selinux-util.c @@ -24,15 +24,15 @@ #include <sys/un.h> #ifdef HAVE_SELINUX -#include <selinux/selinux.h> -#include <selinux/label.h> #include <selinux/context.h> +#include <selinux/label.h> +#include <selinux/selinux.h> #endif #include "alloc-util.h" -#include "strv.h" #include "path-util.h" #include "selinux-util.h" +#include "strv.h" #ifdef HAVE_SELINUX DEFINE_TRIVIAL_CLEANUP_FUNC(security_context_t, freecon); diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h index 2afcaec183..d19984c5fe 100644 --- a/src/basic/selinux-util.h +++ b/src/basic/selinux-util.h @@ -21,8 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/socket.h> #include <stdbool.h> +#include <sys/socket.h> #include "macro.h" diff --git a/src/basic/set.h b/src/basic/set.h index 4554ef2d49..5fd7de08f9 100644 --- a/src/basic/set.h +++ b/src/basic/set.h @@ -27,7 +27,6 @@ Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); #define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS) - static inline Set *set_free(Set *s) { internal_hashmap_free(HASHMAP_BASE(s)); return NULL; diff --git a/src/basic/sigbus.c b/src/basic/sigbus.c index 0108603fe8..c535c89d52 100644 --- a/src/basic/sigbus.c +++ b/src/basic/sigbus.c @@ -23,8 +23,8 @@ #include <sys/mman.h> #include "macro.h" -#include "util.h" #include "sigbus.h" +#include "util.h" #define SIGBUS_QUEUE_MAX 64 diff --git a/src/basic/siphash24.c b/src/basic/siphash24.c index 3b61961389..10fc56da69 100644 --- a/src/basic/siphash24.c +++ b/src/basic/siphash24.c @@ -17,9 +17,9 @@ coding style) */ -#include "sparse-endian.h" - #include "siphash24.h" +#include "sparse-endian.h" +#include "unaligned.h" #include "util.h" static inline uint64_t rotate_left(uint64_t x, uint8_t b) { @@ -53,37 +53,40 @@ void siphash24_init(struct siphash *state, const uint8_t k[16]) { assert(state); assert(k); - k0 = le64toh(*(le64_t*) k); - k1 = le64toh(*(le64_t*) (k + 8)); - - /* "somepseudorandomlygeneratedbytes" */ - state->v0 = 0x736f6d6570736575ULL ^ k0; - state->v1 = 0x646f72616e646f6dULL ^ k1; - state->v2 = 0x6c7967656e657261ULL ^ k0; - state->v3 = 0x7465646279746573ULL ^ k1; - state->padding = 0; - state->inlen = 0; + k0 = unaligned_read_le64(k); + k1 = unaligned_read_le64(k + 8); + + *state = (struct siphash) { + /* "somepseudorandomlygeneratedbytes" */ + .v0 = 0x736f6d6570736575ULL ^ k0, + .v1 = 0x646f72616e646f6dULL ^ k1, + .v2 = 0x6c7967656e657261ULL ^ k0, + .v3 = 0x7465646279746573ULL ^ k1, + .padding = 0, + .inlen = 0, + }; } void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) { - uint64_t m; + const uint8_t *in = _in; const uint8_t *end = in + inlen; - unsigned left = state->inlen & 7; + size_t left = state->inlen & 7; + uint64_t m; assert(in); assert(state); - /* update total length */ + /* Update total length */ state->inlen += inlen; - /* if padding exists, fill it out */ + /* If padding exists, fill it out */ if (left > 0) { - for ( ; in < end && left < 8; in ++, left ++ ) - state->padding |= ( ( uint64_t )*in ) << (left * 8); + for ( ; in < end && left < 8; in ++, left ++) + state->padding |= ((uint64_t) *in) << (left * 8); if (in == end && left < 8) - /* we did not have enough input to fill out the padding completely */ + /* We did not have enough input to fill out the padding completely */ return; #ifdef DEBUG @@ -93,6 +96,7 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) { printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); printf("(%3zu) compress padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t)state->padding); #endif + state->v3 ^= state->padding; sipround(state); sipround(state); @@ -101,10 +105,10 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) { state->padding = 0; } - end -= ( state->inlen % sizeof (uint64_t) ); + end -= (state->inlen % sizeof(uint64_t)); - for ( ; in < end; in += 8 ) { - m = le64toh(*(le64_t*) in); + for ( ; in < end; in += 8) { + m = unaligned_read_le64(in); #ifdef DEBUG printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); @@ -119,38 +123,41 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) { } left = state->inlen & 7; - - switch(left) - { - case 7: state->padding |= ((uint64_t) in[6]) << 48; - - case 6: state->padding |= ((uint64_t) in[5]) << 40; - - case 5: state->padding |= ((uint64_t) in[4]) << 32; - - case 4: state->padding |= ((uint64_t) in[3]) << 24; - - case 3: state->padding |= ((uint64_t) in[2]) << 16; - - case 2: state->padding |= ((uint64_t) in[1]) << 8; - - case 1: state->padding |= ((uint64_t) in[0]); break; - - case 0: break; + switch (left) { + case 7: + state->padding |= ((uint64_t) in[6]) << 48; + case 6: + state->padding |= ((uint64_t) in[5]) << 40; + case 5: + state->padding |= ((uint64_t) in[4]) << 32; + case 4: + state->padding |= ((uint64_t) in[3]) << 24; + case 3: + state->padding |= ((uint64_t) in[2]) << 16; + case 2: + state->padding |= ((uint64_t) in[1]) << 8; + case 1: + state->padding |= ((uint64_t) in[0]); + case 0: + break; } } -void siphash24_finalize(uint8_t out[8], struct siphash *state) { +uint64_t siphash24_finalize(struct siphash *state) { uint64_t b; - b = state->padding | (( ( uint64_t )state->inlen ) << 56); + assert(state); + + b = state->padding | (((uint64_t) state->inlen) << 56); + #ifdef DEBUG - printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t)state->v0); - printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t)state->v1); - printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t)state->v2); - printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t)state->v3); + printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0); + printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1); + printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2); + printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3); printf("(%3zu) padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t) state->padding); #endif + state->v3 ^= b; sipround(state); sipround(state); @@ -169,14 +176,17 @@ void siphash24_finalize(uint8_t out[8], struct siphash *state) { sipround(state); sipround(state); - *(le64_t*)out = htole64(state->v0 ^ state->v1 ^ state->v2 ^ state->v3); + return state->v0 ^ state->v1 ^ state->v2 ^ state->v3; } -/* SipHash-2-4 */ -void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) { +uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]) { struct siphash state; + assert(in); + assert(k); + siphash24_init(&state, k); - siphash24_compress(_in, inlen, &state); - siphash24_finalize(out, &state); + siphash24_compress(in, inlen, &state); + + return siphash24_finalize(&state); } diff --git a/src/basic/siphash24.h b/src/basic/siphash24.h index 6c5cd98ee8..ba4f7d01b6 100644 --- a/src/basic/siphash24.h +++ b/src/basic/siphash24.h @@ -4,16 +4,16 @@ #include <sys/types.h> struct siphash { - uint64_t v0; - uint64_t v1; - uint64_t v2; - uint64_t v3; - uint64_t padding; - size_t inlen; + uint64_t v0; + uint64_t v1; + uint64_t v2; + uint64_t v3; + uint64_t padding; + size_t inlen; }; void siphash24_init(struct siphash *state, const uint8_t k[16]); void siphash24_compress(const void *in, size_t inlen, struct siphash *state); -void siphash24_finalize(uint8_t out[8], struct siphash *state); +uint64_t siphash24_finalize(struct siphash *state); -void siphash24(uint8_t out[8], const void *in, size_t inlen, const uint8_t k[16]); +uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]); diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index c60f2556af..129ffa811c 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -21,9 +21,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/socket.h> -#include <netinet/in.h> #include <netinet/ether.h> +#include <netinet/in.h> +#include <sys/socket.h> #include <sys/un.h> #include <linux/netlink.h> #include <linux/if_packet.h> diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h index 909b220a24..fb92464274 100644 --- a/src/basic/stat-util.h +++ b/src/basic/stat-util.h @@ -52,9 +52,8 @@ int path_is_os_tree(const char *path); int files_same(const char *filea, const char *fileb); /* The .f_type field of struct statfs is really weird defined on - * different archs. Let's use our own type we know is sufficiently - * larger to store the possible values. */ -typedef long statfs_f_type_t; + * different archs. Let's give its type a name. */ +typedef typeof(((struct statfs*)NULL)->f_type) statfs_f_type_t; bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_; int fd_check_fstype(int fd, statfs_f_type_t magic_value); diff --git a/src/basic/strv.c b/src/basic/strv.c index ba6df716a7..771781f9fc 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -27,8 +27,8 @@ #include "alloc-util.h" #include "escape.h" #include "string-util.h" -#include "util.h" #include "strv.h" +#include "util.h" char *strv_find(char **l, const char *name) { char **i; diff --git a/src/basic/strxcpyx.c b/src/basic/strxcpyx.c index 6542c0abf5..088ba53c29 100644 --- a/src/basic/strxcpyx.c +++ b/src/basic/strxcpyx.c @@ -27,6 +27,7 @@ #include <stdio.h> #include <string.h> + #include "strxcpyx.h" size_t strpcpy(char **dest, size_t size, const char *src) { diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index f2185c1c11..b2c7a297ae 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -19,8 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdbool.h> #include <stdarg.h> +#include <stdbool.h> #include <stdio.h> #include "macro.h" diff --git a/src/basic/time-util.c b/src/basic/time-util.c index b36fbe4f09..b9da6991da 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -27,6 +27,7 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" +#include "parse-util.h" #include "path-util.h" #include "string-util.h" #include "strv.h" @@ -323,15 +324,15 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { const char *suffix; usec_t usec; } table[] = { - { "y", USEC_PER_YEAR }, - { "month", USEC_PER_MONTH }, - { "w", USEC_PER_WEEK }, - { "d", USEC_PER_DAY }, - { "h", USEC_PER_HOUR }, - { "min", USEC_PER_MINUTE }, - { "s", USEC_PER_SEC }, - { "ms", USEC_PER_MSEC }, - { "us", 1 }, + { "y", USEC_PER_YEAR }, + { "month", USEC_PER_MONTH }, + { "w", USEC_PER_WEEK }, + { "d", USEC_PER_DAY }, + { "h", USEC_PER_HOUR }, + { "min", USEC_PER_MINUTE }, + { "s", USEC_PER_SEC }, + { "ms", USEC_PER_MSEC }, + { "us", 1 }, }; unsigned i; @@ -658,29 +659,18 @@ int parse_timestamp(const char *t, usec_t *usec) { parse_usec: { - char *end; - unsigned long long val; - size_t l; + unsigned add; k++; - if (*k < '0' || *k > '9') + r = parse_fractional_part_u(&k, 6, &add); + if (r < 0) return -EINVAL; - /* base 10 instead of base 0, .09 is not base 8 */ - errno = 0; - val = strtoull(k, &end, 10); - if (*end || errno) + if (*k) return -EINVAL; - l = end-k; - - /* val has l digits, make them 6 */ - for (; l < 6; l++) - val *= 10; - for (; l > 6; l--) - val /= 10; + x_usec = add; - x_usec = val; } from_tm: @@ -711,33 +701,34 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) { const char *suffix; usec_t usec; } table[] = { - { "seconds", USEC_PER_SEC }, - { "second", USEC_PER_SEC }, - { "sec", USEC_PER_SEC }, - { "s", USEC_PER_SEC }, + { "seconds", USEC_PER_SEC }, + { "second", USEC_PER_SEC }, + { "sec", USEC_PER_SEC }, + { "s", USEC_PER_SEC }, { "minutes", USEC_PER_MINUTE }, - { "minute", USEC_PER_MINUTE }, - { "min", USEC_PER_MINUTE }, - { "months", USEC_PER_MONTH }, - { "month", USEC_PER_MONTH }, - { "msec", USEC_PER_MSEC }, - { "ms", USEC_PER_MSEC }, - { "m", USEC_PER_MINUTE }, - { "hours", USEC_PER_HOUR }, - { "hour", USEC_PER_HOUR }, - { "hr", USEC_PER_HOUR }, - { "h", USEC_PER_HOUR }, - { "days", USEC_PER_DAY }, - { "day", USEC_PER_DAY }, - { "d", USEC_PER_DAY }, - { "weeks", USEC_PER_WEEK }, - { "week", USEC_PER_WEEK }, - { "w", USEC_PER_WEEK }, - { "years", USEC_PER_YEAR }, - { "year", USEC_PER_YEAR }, - { "y", USEC_PER_YEAR }, - { "usec", 1ULL }, - { "us", 1ULL }, + { "minute", USEC_PER_MINUTE }, + { "min", USEC_PER_MINUTE }, + { "months", USEC_PER_MONTH }, + { "month", USEC_PER_MONTH }, + { "M", USEC_PER_MONTH }, + { "msec", USEC_PER_MSEC }, + { "ms", USEC_PER_MSEC }, + { "m", USEC_PER_MINUTE }, + { "hours", USEC_PER_HOUR }, + { "hour", USEC_PER_HOUR }, + { "hr", USEC_PER_HOUR }, + { "h", USEC_PER_HOUR }, + { "days", USEC_PER_DAY }, + { "day", USEC_PER_DAY }, + { "d", USEC_PER_DAY }, + { "weeks", USEC_PER_WEEK }, + { "week", USEC_PER_WEEK }, + { "w", USEC_PER_WEEK }, + { "years", USEC_PER_YEAR }, + { "year", USEC_PER_YEAR }, + { "y", USEC_PER_YEAR }, + { "usec", 1ULL }, + { "us", 1ULL }, }; const char *p, *s; diff --git a/src/basic/unaligned.h b/src/basic/unaligned.h index d6181dd9a9..a8115eaa1f 100644 --- a/src/basic/unaligned.h +++ b/src/basic/unaligned.h @@ -21,8 +21,11 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <endian.h> #include <stdint.h> +/* BE */ + static inline uint16_t unaligned_read_be16(const void *_u) { const uint8_t *u = _u; @@ -64,3 +67,47 @@ static inline void unaligned_write_be64(void *_u, uint64_t a) { unaligned_write_be32(u, (uint32_t) (a >> 32)); unaligned_write_be32(u + 4, (uint32_t) a); } + +/* LE */ + +static inline uint16_t unaligned_read_le16(const void *_u) { + const uint8_t *u = _u; + + return (((uint16_t) u[1]) << 8) | + ((uint16_t) u[0]); +} + +static inline uint32_t unaligned_read_le32(const void *_u) { + const uint8_t *u = _u; + + return (((uint32_t) unaligned_read_le16(u + 2)) << 16) | + ((uint32_t) unaligned_read_le16(u)); +} + +static inline uint64_t unaligned_read_le64(const void *_u) { + const uint8_t *u = _u; + + return (((uint64_t) unaligned_read_le32(u + 4)) << 32) | + ((uint64_t) unaligned_read_le32(u)); +} + +static inline void unaligned_write_le16(void *_u, uint16_t a) { + uint8_t *u = _u; + + u[0] = (uint8_t) a; + u[1] = (uint8_t) (a >> 8); +} + +static inline void unaligned_write_le32(void *_u, uint32_t a) { + uint8_t *u = _u; + + unaligned_write_le16(u, (uint16_t) a); + unaligned_write_le16(u + 2, (uint16_t) (a >> 16)); +} + +static inline void unaligned_write_le64(void *_u, uint64_t a) { + uint8_t *u = _u; + + unaligned_write_le32(u, (uint32_t) a); + unaligned_write_le32(u + 4, (uint32_t) (a >> 32)); +} diff --git a/src/basic/user-util.c b/src/basic/user-util.c index d6c936db37..397880b0b1 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -19,8 +19,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <pwd.h> #include <grp.h> +#include <pwd.h> #include "alloc-util.h" #include "fd-util.h" diff --git a/src/basic/user-util.h b/src/basic/user-util.h index 11ff6674cf..6106e138be 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -21,8 +21,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/types.h> #include <stdbool.h> +#include <sys/types.h> bool uid_is_valid(uid_t uid); diff --git a/src/basic/utf8.c b/src/basic/utf8.c index 7600d99903..b4063a4cec 100644 --- a/src/basic/utf8.c +++ b/src/basic/utf8.c @@ -44,10 +44,10 @@ */ #include <errno.h> -#include <stdlib.h> #include <inttypes.h> -#include <string.h> #include <stdbool.h> +#include <stdlib.h> +#include <string.h> #include "alloc-util.h" #include "hexdecoct.h" diff --git a/src/basic/util.c b/src/basic/util.c index 08bdcd28f2..58617b354a 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -73,6 +73,7 @@ #include "build.h" #include "def.h" #include "device-nodes.h" +#include "dirent-util.h" #include "env-util.h" #include "escape.h" #include "exit-status.h" @@ -81,19 +82,20 @@ #include "formats-util.h" #include "gunicode.h" #include "hashmap.h" +#include "hexdecoct.h" #include "hostname-util.h" #include "ioprio.h" #include "log.h" #include "macro.h" #include "missing.h" #include "mkdir.h" -#include "hexdecoct.h" #include "parse-util.h" #include "path-util.h" #include "process-util.h" #include "random-util.h" #include "signal-util.h" #include "sparse-endian.h" +#include "stat-util.h" #include "string-table.h" #include "string-util.h" #include "strv.h" @@ -102,8 +104,6 @@ #include "utf8.h" #include "util.h" #include "virt.h" -#include "dirent-util.h" -#include "stat-util.h" /* Put this test here for a lack of better place */ assert_cc(EAGAIN == EWOULDBLOCK); @@ -206,7 +206,7 @@ static int do_execute(char **directories, usec_t timeout, char *argv[]) { log_debug("Spawned %s as " PID_FMT ".", path, pid); - r = hashmap_put(pids, UINT_TO_PTR(pid), path); + r = hashmap_put(pids, PID_TO_PTR(pid), path); if (r < 0) return log_oom(); path = NULL; @@ -224,10 +224,10 @@ static int do_execute(char **directories, usec_t timeout, char *argv[]) { _cleanup_free_ char *path = NULL; pid_t pid; - pid = PTR_TO_UINT(hashmap_first_key(pids)); + pid = PTR_TO_PID(hashmap_first_key(pids)); assert(pid > 0); - path = hashmap_remove(pids, UINT_TO_PTR(pid)); + path = hashmap_remove(pids, PID_TO_PTR(pid)); assert(path); wait_for_terminate_and_warn(path, pid, true); diff --git a/src/basic/virt.c b/src/basic/virt.c index d088b7a804..b82680a54b 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -24,6 +24,8 @@ #include <unistd.h> #include "alloc-util.h" +#include "dirent-util.h" +#include "fd-util.h" #include "fileio.h" #include "process-util.h" #include "stat-util.h" @@ -267,13 +269,20 @@ int detect_vm(void) { if (cached_found >= 0) return cached_found; - r = detect_vm_cpuid(); + /* We have to use the correct order here: + * Some virtualization technologies do use KVM hypervisor but are + * expected to be detected as something else. So detect DMI first. + * + * An example is Virtualbox since version 5.0, which uses KVM backend. + * Detection via DMI works corretly, the CPU ID would find KVM + * only. */ + r = detect_vm_dmi(); if (r < 0) return r; if (r != VIRTUALIZATION_NONE) goto finish; - r = detect_vm_dmi(); + r = detect_vm_cpuid(); if (r < 0) return r; if (r != VIRTUALIZATION_NONE) |