From 8bb05ac73a5b448b339ce0bc8d396c82c459b47f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 21:33:32 +0200 Subject: Merging upstream version 2.40. Signed-off-by: Daniel Baumann --- include/Makemodule.am | 2 ++ include/audit-arch.h | 8 +++++ include/bitops.h | 2 +- include/blkdev.h | 8 +++-- include/c.h | 31 ++++++++++++++++ include/caputils.h | 2 ++ include/column-list-table.h | 88 +++++++++++++++++++++++++++++++++++++++++++++ include/coverage.h | 25 +++++++++++++ include/crc32.h | 4 +-- include/crc32c.h | 4 +-- include/crc64.h | 4 +++ include/env.h | 2 +- include/jsonwrt.h | 4 +++ include/loopdev.h | 14 +++++--- include/mbsalign.h | 1 + include/path.h | 2 -- include/pathnames.h | 6 ++++ include/procfs.h | 1 + include/pt-gpt-partnames.h | 6 ++++ include/pt-mbr.h | 6 ++-- include/pty-session.h | 3 +- include/shells.h | 1 + include/strutils.h | 22 ++++++++++++ include/strv.h | 1 - include/timeutils.h | 18 +++++++--- include/ttyutils.h | 1 + include/xalloc.h | 50 ++++++++++++++++++++++++++ 27 files changed, 291 insertions(+), 25 deletions(-) create mode 100644 include/column-list-table.h create mode 100644 include/coverage.h (limited to 'include') diff --git a/include/Makemodule.am b/include/Makemodule.am index 068b0f8..c08e24c 100644 --- a/include/Makemodule.am +++ b/include/Makemodule.am @@ -13,6 +13,8 @@ dist_noinst_HEADERS += \ include/closestream.h \ include/colors.h \ include/color-names.h \ + include/column-list-table.h \ + include/coverage.h \ include/cpuset.h \ include/crc32.h \ include/crc32c.h \ diff --git a/include/audit-arch.h b/include/audit-arch.h index db14560..ade1824 100644 --- a/include/audit-arch.h +++ b/include/audit-arch.h @@ -59,6 +59,14 @@ # else # define SECCOMP_ARCH_NATIVE AUDIT_ARCH_LOONGARCH64 # endif +#elif __hppa__ +# if __SIZEOF_POINTER__ == 4 +# define SECCOMP_ARCH_NATIVE AUDIT_ARCH_PARISC +# else +# define SECCOMP_ARCH_NATIVE AUDIT_ARCH_PARISC64 +# endif +#elif __alpha__ +# define SECCOMP_ARCH_NATIVE AUDIT_ARCH_ALPHA #else # error Unknown target architecture #endif diff --git a/include/bitops.h b/include/bitops.h index 16ba2ab..6d2a2dd 100644 --- a/include/bitops.h +++ b/include/bitops.h @@ -31,7 +31,7 @@ # define be16toh(x) betoh16(x) # define be32toh(x) betoh32(x) # define be64toh(x) betoh64(x) -#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) +#elif defined(__NetBSD__) || defined(__DragonFly__) # define bswap_16(x) bswap16(x) # define bswap_32(x) bswap32(x) # define bswap_64(x) bswap64(x) diff --git a/include/blkdev.h b/include/blkdev.h index ffecdcb..efa33af 100644 --- a/include/blkdev.h +++ b/include/blkdev.h @@ -131,8 +131,8 @@ int blkdev_is_cdrom(int fd); /* get device's geometry - legacy */ int blkdev_get_geometry(int fd, unsigned int *h, unsigned int *s); -/* SCSI device types. Copied almost as-is from kernel header. - * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/scsi/scsi.h */ +/* SCSI device types. Copied almost as-is from kernel header + * (include/scsi/scsi_proto.h). */ #define SCSI_TYPE_DISK 0x00 #define SCSI_TYPE_TAPE 0x01 #define SCSI_TYPE_PRINTER 0x02 @@ -156,7 +156,9 @@ int blkdev_lock(int fd, const char *devname, const char *lockmode); #ifdef HAVE_LINUX_BLKZONED_H struct blk_zone_report *blkdev_get_zonereport(int fd, uint64_t sector, uint32_t nzones); #else -static inline struct blk_zone_report *blkdev_get_zonereport(int fd, uint64_t sector, uint32_t nzones) +static inline struct blk_zone_report *blkdev_get_zonereport(int fd __attribute__((unused)), + uint64_t sector __attribute__((unused)), + uint32_t nzones __attribute__((unused))) { return NULL; } diff --git a/include/c.h b/include/c.h index 2b70e8d..61b95ab 100644 --- a/include/c.h +++ b/include/c.h @@ -213,6 +213,14 @@ (type *)( (char *)__mptr - offsetof(type,member) );}) #endif +#define read_unaligned_member(p, m) __extension__ ({ \ + size_t offset = offsetof(__typeof__(* p), m); \ + __typeof__(p->m + 0) v; \ + memcpy(&v, ((unsigned char *)p) + offset, sizeof(v)); \ + v; }) + +#define member_ptr(p, m) (((unsigned char *)p) + offsetof(__typeof__(*p), m)) + #ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME # ifdef HAVE___PROGNAME extern char *__progname; @@ -294,6 +302,9 @@ void __err_oom(const char *file, unsigned int line) } #define err_oom() __err_oom(__FILE__, __LINE__) +#define err_nosys(exitcode, ...) \ + err(errno == ENOSYS ? EXIT_NOTSUPP : exitcode, __VA_ARGS__) + /* Don't use inline function to avoid '#include "nls.h"' in c.h */ @@ -449,6 +460,7 @@ static inline void __attribute__((__noreturn__)) ul_sig_err(int excode, const ch #define USAGE_COMMANDS _("\nCommands:\n") #define USAGE_ARGUMENTS _("\nArguments:\n") #define USAGE_COLUMNS _("\nAvailable output columns:\n") +#define USAGE_DEFAULT_COLUMNS _("\nDefault columns:\n") #define USAGE_SEPARATOR "\n" #define USAGE_OPTSTR_HELP _("display this help") @@ -498,6 +510,12 @@ static inline void print_features(const char **features, const char *prefix) exit(eval); \ }) +static inline int fputsln(const char *s, FILE *stream) { + if (fputs(s, stream) == EOF) + return EOF; + return fputc('\n', stdout); +} + /* * seek stuff */ @@ -564,4 +582,17 @@ static inline void print_features(const char **features, const char *prefix) #define SINT_MAX(t) (((t)1 << (sizeof(t) * 8 - 2)) - (t)1 + ((t)1 << (sizeof(t) * 8 - 2))) +#ifndef HAVE_REALLOCARRAY +static inline void *reallocarray(void *ptr, size_t nmemb, size_t size) +{ + size_t s = nmemb * size; + + if (nmemb != 0 && s / nmemb != size) { + errno = ENOMEM; + return NULL; + } + return realloc(ptr, s); +} +#endif + #endif /* UTIL_LINUX_C_H */ diff --git a/include/caputils.h b/include/caputils.h index 852903a..8fc214e 100644 --- a/include/caputils.h +++ b/include/caputils.h @@ -31,4 +31,6 @@ extern int capget(cap_user_header_t header, const cap_user_data_t data); extern int cap_last_cap(void); +extern void cap_permitted_to_ambient(void); + #endif /* CAPUTILS_H */ diff --git a/include/column-list-table.h b/include/column-list-table.h new file mode 100644 index 0000000..1629336 --- /dev/null +++ b/include/column-list-table.h @@ -0,0 +1,88 @@ +/* + * column-list-table.h - helper functions for implementing -H/--list-columns option + * + * Copyright (C) 2023 Red Hat, Inc. All rights reserved. + * Written by Masatake YAMATO + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef UTIL_LINUX_COLUMN_LIST_TABLE_H +#define UTIL_LINUX_COLUMN_LIST_TABLE_H + +#include "libsmartcols.h" +#include + +enum { CLT_COL_HOLDER, CLT_COL_TYPE, CLT_COL_DESC }; + +static inline struct libscols_table *xcolumn_list_table_new(const char *table_name, + FILE *out, + int raw, + int json) +{ + struct clt_colinfo { + const char *name; + int flags; + }; + struct libscols_table *tb; + + scols_init_debug(0); + + tb = scols_new_table(); + if (!tb) + err(EXIT_FAILURE, _("failed to allocate output table")); + + scols_table_set_name(tb, table_name); + scols_table_set_stream(tb, out); + scols_table_enable_noheadings(tb, 1); + scols_table_enable_raw(tb, raw); + scols_table_enable_json(tb, json); + + if (!scols_table_new_column(tb, "HOLDER", 0, SCOLS_FL_RIGHT)) + goto failed; + if (!scols_table_new_column(tb, "TYPE", 0, 0)) + goto failed; + if (!scols_table_new_column(tb, "DESCRIPTION", 0, 0)) + goto failed; + return tb; + + failed: + err(EXIT_FAILURE, _("failed to allocate output column")); +} + +static inline void xcolumn_list_table_append_line(struct libscols_table *tb, + const char *name, + int json_type, const char *fallback_typename, + const char *desc) +{ + struct libscols_line *ln = scols_table_new_line(tb, NULL); + if (!ln) + err(EXIT_FAILURE, _("failed to allocate output line")); + + if (scols_line_set_data(ln, CLT_COL_HOLDER, name)) + err(EXIT_FAILURE, _("failed to add output data")); + if (scols_line_set_data(ln, CLT_COL_TYPE, (json_type == SCOLS_JSON_STRING ? "": + json_type == SCOLS_JSON_ARRAY_STRING ? "": + json_type == SCOLS_JSON_ARRAY_NUMBER ? "": + json_type == SCOLS_JSON_NUMBER ? "": + json_type == SCOLS_JSON_FLOAT ? "": + json_type == SCOLS_JSON_BOOLEAN ? "": + fallback_typename ?: ""))) + err(EXIT_FAILURE, _("failed to add output data")); + if (scols_line_set_data(ln, CLT_COL_DESC, desc)) + err(EXIT_FAILURE, _("failed to add output data")); +} + +#endif diff --git a/include/coverage.h b/include/coverage.h new file mode 100644 index 0000000..8ca5b68 --- /dev/null +++ b/include/coverage.h @@ -0,0 +1,25 @@ +/* + * No copyright is claimed. This code is in the public domain; do with + * it what you wish. + */ +#ifndef UTIL_LINUX_COVERAGE_H +#define UTIL_LINUX_COVERAGE_H + +/* When built with --coverage (gcov) we need to explicitly call __gcov_dump() + * in places where we use _exit(), since _exit() skips at-exit hooks resulting + * in lost coverage. + * + * To make sure we don't miss any _exit() calls, this header file is included + * explicitly on the compiler command line via the -include directive (only + * when built with --coverage/-Db_coverage=true) + */ +void __gcov_dump(void); +__attribute__((noreturn)) void _exit(int); + +__attribute__((noreturn)) static inline void _coverage__exit(int status) { + __gcov_dump(); + _exit(status); +} +#define _exit(x) _coverage__exit(x) + +#endif diff --git a/include/crc32.h b/include/crc32.h index 81c7703..0d34da0 100644 --- a/include/crc32.h +++ b/include/crc32.h @@ -1,6 +1,6 @@ /* - * No copyright is claimed. This code is in the public domain; do with it what - * you wish. + * No copyright is claimed. This code is in the public domain; do with + * it what you wish. */ #ifndef UL_CRC32_H #define UL_CRC32_H diff --git a/include/crc32c.h b/include/crc32c.h index 3d27461..1ac6b97 100644 --- a/include/crc32c.h +++ b/include/crc32c.h @@ -1,6 +1,6 @@ /* - * No copyright is claimed. This code is in the public domain; do with it what - * you wish. + * No copyright is claimed. This code is in the public domain; do with + * it what you wish. */ #ifndef UL_CRC32C_H #define UL_CRC32C_H diff --git a/include/crc64.h b/include/crc64.h index 7cd2c4c..6bdd079 100644 --- a/include/crc64.h +++ b/include/crc64.h @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: MIT + * + * This file is licensed under the MIT License. + */ #ifndef UL_CRC64_H #define UL_CRC64_H diff --git a/include/env.h b/include/env.h index 9a0ec4f..9b29919 100644 --- a/include/env.h +++ b/include/env.h @@ -30,7 +30,7 @@ static inline void xsetenv(char const *name, char const *val, int overwrite) err(XSETENV_EXIT_CODE, _("failed to set the %s environment variable"), name); } -static inline int remote_entry(char **argv, int remove, int last) +static inline int remove_entry(char **argv, int remove, int last) { memmove(argv + remove, argv + remove + 1, sizeof(char *) * (last - remove)); return last - 1; diff --git a/include/jsonwrt.h b/include/jsonwrt.h index 421903a..b450afc 100644 --- a/include/jsonwrt.h +++ b/include/jsonwrt.h @@ -41,8 +41,12 @@ void ul_jsonwrt_value_raw(struct ul_jsonwrt *fmt, const char *name, const char *data); void ul_jsonwrt_value_s(struct ul_jsonwrt *fmt, const char *name, const char *data); +void ul_jsonwrt_value_s_sized(struct ul_jsonwrt *fmt, + const char *name, const char *data, size_t size); void ul_jsonwrt_value_u64(struct ul_jsonwrt *fmt, const char *name, uint64_t data); +void ul_jsonwrt_value_double(struct ul_jsonwrt *fmt, + const char *name, long double data); void ul_jsonwrt_value_boolean(struct ul_jsonwrt *fmt, const char *name, int data); void ul_jsonwrt_value_null(struct ul_jsonwrt *fmt, diff --git a/include/loopdev.h b/include/loopdev.h index 903adc4..d10bf7f 100644 --- a/include/loopdev.h +++ b/include/loopdev.h @@ -112,7 +112,8 @@ struct loopdev_cxt { char device[128]; /* device path (e.g. /dev/loop) */ char *filename; /* backing file for loopcxt_set_... */ int fd; /* open(/dev/looo) */ - int mode; /* fd mode O_{RDONLY,RDWR} */ + dev_t devno; /* loop device devno from /sys */ + mode_t mode; /* fd mode O_{RDONLY,RDWR} */ uint64_t blocksize; /* used by loopcxt_setup_device() */ int flags; /* LOOPDEV_FL_* flags */ @@ -120,9 +121,10 @@ struct loopdev_cxt { unsigned int extra_check:1; /* unusual stuff for iterator */ unsigned int info_failed:1; /* LOOP_GET_STATUS ioctl failed */ unsigned int control_ok:1; /* /dev/loop-control success */ + unsigned int is_lost:1; /* device in /sys, but missing in /dev */ struct path_cxt *sysfs; /* pointer to /sys/dev/block// */ - struct loop_config config; /* for GET/SET ioctl */ + struct loop_config config; /* for GET/SET ioctl */ struct loopdev_iter iter; /* scans /sys or /dev for used/free devices */ }; @@ -132,8 +134,6 @@ struct loopdev_cxt { * loopdev_cxt.flags */ enum { - LOOPDEV_FL_RDONLY = (1 << 0), /* open(/dev/loop) mode; default */ - LOOPDEV_FL_RDWR = (1 << 1), /* necessary for loop setup only */ LOOPDEV_FL_OFFSET = (1 << 4), LOOPDEV_FL_NOSYSFS = (1 << 5), LOOPDEV_FL_NOIOCTL = (1 << 6), @@ -151,7 +151,9 @@ extern int is_loopdev(const char *device); extern int loopdev_is_autoclear(const char *device); extern char *loopdev_get_backing_file(const char *device); +extern dev_t loopcxt_get_devno(struct loopdev_cxt *lc); extern int loopdev_has_backing_file(const char *device); +extern int loopcxt_is_lost(struct loopdev_cxt *lc); extern int loopdev_is_used(const char *device, const char *filename, uint64_t offset, uint64_t sizelimit, int flags); extern char *loopdev_find_by_backing_file(const char *filename, @@ -176,7 +178,7 @@ extern const char *loopcxt_get_device(struct loopdev_cxt *lc); extern struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc); extern int loopcxt_get_fd(struct loopdev_cxt *lc); -extern int loopcxt_set_fd(struct loopdev_cxt *lc, int fd, int mode); +extern int loopcxt_set_fd(struct loopdev_cxt *lc, int fd, mode_t mode); extern int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags); extern int loopcxt_deinit_iterator(struct loopdev_cxt *lc); @@ -195,8 +197,10 @@ int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit); int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize); int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags); int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename); +int loopcxt_set_refname(struct loopdev_cxt *lc, const char *refname); extern char *loopcxt_get_backing_file(struct loopdev_cxt *lc); +extern char *loopcxt_get_refname(struct loopdev_cxt *lc); extern int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno); extern int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino); extern int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset); diff --git a/include/mbsalign.h b/include/mbsalign.h index 6e56755..c142610 100644 --- a/include/mbsalign.h +++ b/include/mbsalign.h @@ -55,6 +55,7 @@ extern size_t mbs_width(const char *s); extern char *mbs_safe_encode(const char *s, size_t *width); extern char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf, const char *safechars); extern size_t mbs_safe_encode_size(size_t bytes); +extern size_t mbs_safe_decode_size(const char *s); extern char *mbs_invalid_encode(const char *s, size_t *width); extern char *mbs_invalid_encode_to_buffer(const char *s, size_t *width, char *buf); diff --git a/include/path.h b/include/path.h index 19c1be6..e523f17 100644 --- a/include/path.h +++ b/include/path.h @@ -134,8 +134,6 @@ int ul_path_countf_dirents(struct path_cxt *pc, const char *path, ...) int ul_path_next_dirent(struct path_cxt *pc, DIR **sub, const char *dirname, struct dirent **d); -FILE *ul_prefix_fopen(const char *prefix, const char *path, const char *mode); - #ifdef HAVE_CPU_SET_T # include "cpuset.h" diff --git a/include/pathnames.h b/include/pathnames.h index 56f64c3..81fa405 100644 --- a/include/pathnames.h +++ b/include/pathnames.h @@ -108,6 +108,7 @@ #define _PATH_PROC_SETGROUPS "/proc/self/setgroups" #define _PATH_PROC_FDDIR "/proc/self/fd" +#define _PATH_PROC_TIMENS_OFF "/proc/self/timens_offsets" #define _PATH_PROC_ATTR_CURRENT "/proc/self/attr/current" #define _PATH_PROC_ATTR_EXEC "/proc/self/attr/exec" @@ -226,5 +227,10 @@ #define _PATH_DEV_RFKILL "/dev/rfkill" #define _PATH_SYS_RFKILL "/sys/class/rfkill" +/* cgroup path */ +#define _PATH_SYS_CGROUP "/sys/fs/cgroup" + +/* Maximum number of PIDs system supports */ +#define _PATH_PROC_PIDMAX "/proc/sys/kernel/pid_max" #endif /* PATHNAMES_H */ diff --git a/include/procfs.h b/include/procfs.h index 25be513..14625e0 100644 --- a/include/procfs.h +++ b/include/procfs.h @@ -32,6 +32,7 @@ extern int procfs_process_get_uid(struct path_cxt *pc, uid_t *uid); extern ssize_t procfs_process_get_cmdline(struct path_cxt *pc, char *buf, size_t bufsz); extern ssize_t procfs_process_get_cmdname(struct path_cxt *pc, char *buf, size_t bufsz); extern ssize_t procfs_process_get_stat(struct path_cxt *pc, char *buf, size_t bufsz); +extern ssize_t procfs_process_get_syscall(struct path_cxt *pc, char *buf, size_t bufsz); extern int procfs_process_get_stat_nth(struct path_cxt *pc, int n, uintmax_t *re); diff --git a/include/pt-gpt-partnames.h b/include/pt-gpt-partnames.h index 2ee9068..b246eca 100644 --- a/include/pt-gpt-partnames.h +++ b/include/pt-gpt-partnames.h @@ -232,6 +232,9 @@ DEF_GUID("49F48DAA-B10E-11DC-B99B-0019D1879648", N_("NetBSD RAID")), DEF_GUID("FE3A2A5D-4F32-41A7-B725-ACCC3285A309", N_("ChromeOS kernel")), DEF_GUID("3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC", N_("ChromeOS root fs")), DEF_GUID("2E0A753D-9E48-43B0-8337-B15192CB1B5E", N_("ChromeOS reserved")), +DEF_GUID("CAB6E88E-ABF3-4102-A07A-D4BB9BE3C1D3", N_("ChromeOS firmware")), +DEF_GUID("09845860-705F-4BB5-B16C-8A8A099CAF52", N_("ChromeOS miniOS")), +DEF_GUID("3F0F8318-F146-4E6B-8222-C28C8F02E0D5", N_("ChromeOS hibernate")), /* MidnightBSD */ DEF_GUID("85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD data")), @@ -286,3 +289,6 @@ DEF_GUID("3D48CE54-1D16-11DC-8696-01301BB8A9F5", N_("DragonFlyBSD Label64")), DEF_GUID("BD215AB2-1D16-11DC-8696-01301BB8A9F5", N_("DragonFlyBSD Legacy")), DEF_GUID("61DC63AC-6E38-11DC-8513-01301BB8A9F5", N_("DragonFlyBSD HAMMER")), DEF_GUID("5CBB9AD1-862D-11DC-A94D-01301BB8A9F5", N_("DragonFlyBSD HAMMER2")), + +/* U-Boot */ +DEF_GUID("3DE21764-95BD-54BD-A5C3-4ABE786F38A8", N_("U-Boot environment")), diff --git a/include/pt-mbr.h b/include/pt-mbr.h index 93a6def..81b2aee 100644 --- a/include/pt-mbr.h +++ b/include/pt-mbr.h @@ -19,7 +19,7 @@ struct dos_partition { #define MBR_PT_OFFSET 0x1be #define MBR_PT_BOOTBITS_SIZE 440 -static inline struct dos_partition *mbr_get_partition(unsigned char *mbr, int i) +static inline struct dos_partition *mbr_get_partition(const unsigned char *mbr, int i) { return (struct dos_partition *) (mbr + MBR_PT_OFFSET + (i * sizeof(struct dos_partition))); @@ -42,7 +42,7 @@ static inline void __dos_store_4le(unsigned char *p, unsigned int val) p[3] = ((val >> 24) & 0xff); } -static inline unsigned int dos_partition_get_start(struct dos_partition *p) +static inline unsigned int dos_partition_get_start(const struct dos_partition *p) { return __dos_assemble_4le(&(p->start_sect[0])); } @@ -52,7 +52,7 @@ static inline void dos_partition_set_start(struct dos_partition *p, unsigned int __dos_store_4le(p->start_sect, n); } -static inline unsigned int dos_partition_get_size(struct dos_partition *p) +static inline unsigned int dos_partition_get_size(const struct dos_partition *p) { return __dos_assemble_4le(&(p->nr_sects[0])); } diff --git a/include/pty-session.h b/include/pty-session.h index bece863..734a7f6 100644 --- a/include/pty-session.h +++ b/include/pty-session.h @@ -1,5 +1,6 @@ /* - * This code is in the public domain; do with it what you wish. + * No copyright is claimed. This code is in the public domain; do with + * it what you wish. * * Written by Karel Zak in Jul 2019 */ diff --git a/include/shells.h b/include/shells.h index ba59ba4..c770a13 100644 --- a/include/shells.h +++ b/include/shells.h @@ -4,6 +4,7 @@ #ifndef UTIL_LINUX_SHELLS_H #define UTIL_LINUX_SHELLS_H +extern void print_shells(FILE *out, const char *format); extern int is_known_shell(const char *shell_name); #endif /* UTIL_LINUX_SHELLS_H */ diff --git a/include/strutils.h b/include/strutils.h index 07aa656..e9f8a0c 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -27,6 +27,7 @@ extern int ul_strtos64(const char *str, int64_t *num, int base); extern int ul_strtou64(const char *str, uint64_t *num, int base); extern int ul_strtos32(const char *str, int32_t *num, int base); extern int ul_strtou32(const char *str, uint32_t *num, int base); +extern int ul_strtold(const char *str, long double *num); extern int64_t str2num_or_err(const char *str, int base, const char *errmesg, int64_t low, int64_t up); extern uint64_t str2unum_or_err(const char *str, int base, const char *errmesg, uint64_t up); @@ -388,12 +389,33 @@ static inline void strrem(char *s, int rem) *p = '\0'; } +/* returns next string after \0 if before @end */ +static inline char *ul_next_string(char *p, char *end) +{ + char *last; + + if (!p || !end || p >= end) + return NULL; + + for (last = p; p < end; p++) { + if (*last == '\0' && p != last) + return p; + last = p; + } + + return NULL; +} + extern char *strnconcat(const char *s, const char *suffix, size_t b); extern char *strconcat(const char *s, const char *suffix); extern char *strfconcat(const char *s, const char *format, ...) __attribute__ ((__format__ (__printf__, 2, 3))); extern int strappend(char **a, const char *b); +extern int strfappend(char **a, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +extern int strvfappend(char **a, const char *format, va_list ap) + __attribute__ ((__format__ (__printf__, 2, 0))); extern const char *split(const char **state, size_t *l, const char *separator, int quoted); diff --git a/include/strv.h b/include/strv.h index 6091fce..db24ce4 100644 --- a/include/strv.h +++ b/include/strv.h @@ -30,7 +30,6 @@ int strv_consume_prepend(char ***l, char *value); char **strv_remove(char **l, const char *s); char **strv_new(const char *x, ...); -char **strv_new_ap(const char *x, va_list ap); static inline const char* STRV_IFNOTNULL(const char *x) { return x ? x : (const char *) -1; diff --git a/include/timeutils.h b/include/timeutils.h index a195df8..27261ab 100644 --- a/include/timeutils.h +++ b/include/timeutils.h @@ -18,6 +18,7 @@ #include #include #include +#include typedef uint64_t usec_t; typedef uint64_t nsec_t; @@ -56,8 +57,10 @@ enum { ISO_TIMEZONE = (1 << 2), ISO_DOTUSEC = (1 << 3), ISO_COMMAUSEC = (1 << 4), - ISO_T = (1 << 5), - ISO_GMTIME = (1 << 6), + ISO_DOTNSEC = (1 << 5), + ISO_COMMANSEC = (1 << 6), + ISO_T = (1 << 7), + ISO_GMTIME = (1 << 8), ISO_TIMESTAMP = ISO_DATE | ISO_TIME | ISO_TIMEZONE, ISO_TIMESTAMP_T = ISO_TIMESTAMP | ISO_T, ISO_TIMESTAMP_DOT = ISO_TIMESTAMP | ISO_DOTUSEC, @@ -71,9 +74,11 @@ enum { #define CTIME_BUFSIZ 26 #define ISO_BUFSIZ 42 -int strtimeval_iso(struct timeval *tv, int flags, char *buf, size_t bufsz); -int strtm_iso(struct tm *tm, int flags, char *buf, size_t bufsz); +int strtimeval_iso(const struct timeval *tv, int flags, char *buf, size_t bufsz); +int strtm_iso(const struct tm *tm, int flags, char *buf, size_t bufsz); int strtime_iso(const time_t *t, int flags, char *buf, size_t bufsz); +int strtimespec_iso(const struct timespec *t, int flags, char *buf, size_t bufsz); +int strtimespec_relative(const struct timespec *ts, char *buf, size_t bufsz); #define UL_SHORTTIME_THISYEAR_HHMM (1 << 1) @@ -102,4 +107,9 @@ static inline struct timeval usec_to_timeval(usec_t t) return r; } +static inline bool is_timespecset(const struct timespec *t) +{ + return t->tv_sec || t->tv_nsec; +} + #endif /* UTIL_LINUX_TIME_UTIL_H */ diff --git a/include/ttyutils.h b/include/ttyutils.h index e28a2b0..39182b6 100644 --- a/include/ttyutils.h +++ b/include/ttyutils.h @@ -88,6 +88,7 @@ struct chardata { extern int get_terminal_dimension(int *cols, int *lines); extern int get_terminal_width(int default_width); extern int get_terminal_type(const char **type); +extern char *get_terminal_default_type(const char *ttyname, int is_serial); extern int get_terminal_stdfd(void); extern int get_terminal_name(const char **path, const char **name, const char **number); diff --git a/include/xalloc.h b/include/xalloc.h index 1dee5fe..f7d42c9 100644 --- a/include/xalloc.h +++ b/include/xalloc.h @@ -17,6 +17,7 @@ #include #include "c.h" +#include "strutils.h" #ifndef XALLOC_EXIT_CODE # define XALLOC_EXIT_CODE EXIT_FAILURE @@ -46,6 +47,18 @@ void *xrealloc(void *ptr, const size_t size) return ret; } +static inline +__ul_calloc_size(2, 3) +__ul_returns_nonnull +void *xreallocarray(void *ptr, const size_t nelems, const size_t size) +{ + void *ret = reallocarray(ptr, nelems, size); + + if (!ret && size && nelems) + err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size); + return ret; +} + static inline __ul_calloc_size(1, 2) __ul_returns_nonnull @@ -113,6 +126,43 @@ int xvasprintf(char **strp, const char *fmt, va_list ap) return ret; } +static inline void xstrappend(char **a, const char *b) +{ + if (strappend(a, b) < 0) + err(XALLOC_EXIT_CODE, "cannot allocate string"); +} + +static inline void xstrputc(char **a, char c) +{ + char b[] = {c, '\0'}; + xstrappend(a, b); +} + +static inline +__attribute__((__format__(printf, 2, 0))) +int xstrvfappend(char **a, const char *format, va_list ap) +{ + int ret = strvfappend(a, format, ap); + + if (ret < 0) + err(XALLOC_EXIT_CODE, "cannot allocate string"); + return ret; + +} + +static inline +__attribute__ ((__format__ (__printf__, 2, 3))) +int xstrfappend(char **a, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = xstrvfappend(a, format, ap); + va_end(ap); + + return ret; +} static inline __attribute__((warn_unused_result)) -- cgit v1.2.3