summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Bentele2019-08-21 14:58:42 +0200
committerManuel Bentele2019-08-21 14:58:42 +0200
commit0692b963aa3cb846d8abab5ef5247c4dbb3fec96 (patch)
treef13776d25da3e1adc1445aef22e7566ac98cbe84
parentlosetup: added file format option to the man page (diff)
parentpartx: document -d vs. --nr and fix test (diff)
downloadkernel-qcow2-util-linux-kernel-qcow2.tar.gz
kernel-qcow2-util-linux-kernel-qcow2.tar.xz
kernel-qcow2-util-linux-kernel-qcow2.zip
lib/losetup: merge remote-tracking branch 'util-linux/master'kernel-qcow2
Signed-off-by: Manuel Bentele <development@manuel-bentele.de>
-rw-r--r--Documentation/TODO2
-rw-r--r--NEWS6
-rw-r--r--bash-completion/mountpoint2
-rw-r--r--configure.ac13
-rw-r--r--disk-utils/fsck.cramfs.c1
-rw-r--r--disk-utils/partx.85
-rw-r--r--disk-utils/partx.c3
-rw-r--r--disk-utils/sfdisk.83
-rw-r--r--include/carefulputc.h4
-rw-r--r--include/closestream.h7
-rw-r--r--include/pathnames.h4
-rw-r--r--include/xalloc.h6
-rw-r--r--lib/loopdev.c2
-rw-r--r--lib/path.c5
-rw-r--r--lib/ttyutils.c16
-rw-r--r--libblkid/src/partitions/dos.c7
-rw-r--r--libblkid/src/probe.c19
-rw-r--r--libblkid/src/save.c2
-rw-r--r--libblkid/src/superblocks/drbd.c19
-rw-r--r--libblkid/src/superblocks/ntfs.c24
-rw-r--r--libblkid/src/superblocks/superblocks.h1
-rw-r--r--libblkid/src/superblocks/zfs.c2
-rw-r--r--libblkid/src/verify.c4
-rw-r--r--libfdisk/docs/libfdisk-sections.txt2
-rw-r--r--libfdisk/src/alignment.c2
-rw-r--r--libfdisk/src/context.c163
-rw-r--r--libfdisk/src/dos.c6
-rw-r--r--libfdisk/src/fdiskP.h1
-rw-r--r--libfdisk/src/label.c9
-rw-r--r--libfdisk/src/libfdisk.h.in3
-rw-r--r--libfdisk/src/libfdisk.sym5
-rw-r--r--libfdisk/src/partition.c10
-rw-r--r--libfdisk/src/script.c117
-rw-r--r--libfdisk/src/table.c2
-rw-r--r--libmount/src/fs.c3
-rw-r--r--libmount/src/optstr.c4
-rw-r--r--libmount/src/tab_parse.c2
-rw-r--r--libsmartcols/docs/libsmartcols-sections.txt3
-rw-r--r--libsmartcols/samples/fromfile.c11
-rw-r--r--libsmartcols/src/libsmartcols.h.in3
-rw-r--r--libsmartcols/src/libsmartcols.sym6
-rw-r--r--libsmartcols/src/print.c81
-rw-r--r--libsmartcols/src/smartcolsP.h1
-rw-r--r--libsmartcols/src/table.c68
-rw-r--r--login-utils/chfn.c2
-rw-r--r--login-utils/last.c3
-rw-r--r--login-utils/login.c5
-rw-r--r--login-utils/su-common.c4
-rw-r--r--m4/ul.m442
-rw-r--r--misc-utils/lsblk-devtree.c2
-rw-r--r--misc-utils/lsblk.c11
-rw-r--r--po/cs.po2
-rw-r--r--po/da.po2
-rw-r--r--po/de.po4
-rw-r--r--po/es.po2
-rw-r--r--po/fr.po2
-rw-r--r--po/hr.po4
-rw-r--r--po/pl.po2
-rw-r--r--po/pt_BR.po4
-rw-r--r--po/sv.po2
-rw-r--r--po/uk.po4
-rw-r--r--sys-utils/Makemodule.am7
-rw-r--r--sys-utils/choom.11
-rw-r--r--sys-utils/choom.c2
-rw-r--r--sys-utils/dmesg.c26
-rw-r--r--sys-utils/fsfreeze.c2
-rw-r--r--sys-utils/fstrim.service.in2
-rw-r--r--sys-utils/hwclock-cmos.c47
-rw-r--r--sys-utils/hwclock.c2
-rw-r--r--sys-utils/ldattach.c2
-rw-r--r--sys-utils/losetup.c4
-rw-r--r--sys-utils/lscpu-dmi.c2
-rw-r--r--sys-utils/lscpu.15
-rw-r--r--sys-utils/lscpu.c56
-rw-r--r--sys-utils/lscpu.h9
-rw-r--r--sys-utils/lsipc.c2
-rw-r--r--sys-utils/mount.82
-rw-r--r--sys-utils/mountpoint.17
-rw-r--r--sys-utils/mountpoint.c19
-rw-r--r--sys-utils/wdctl.84
-rw-r--r--sys-utils/wdctl.c267
-rw-r--r--term-utils/agetty.c51
-rw-r--r--term-utils/wall.c3
-rw-r--r--tests/expected/column/table-empty-column-at-eol1
-rw-r--r--tests/expected/column/table-empty-column-at-eol21
-rw-r--r--tests/expected/fdisk/gpt-resize2
-rw-r--r--tests/expected/fdisk/mbr-nondos-mode.sparc189
-rw-r--r--tests/expected/fdisk/sunlabel6
-rw-r--r--tests/expected/libmount/context-X-comment (renamed from tests/expected/libmount/context-X-mount.mkdir)0
-rw-r--r--tests/expected/libmount/context-x-permanent (renamed from tests/expected/libmount/context-x-mount.mkdir)0
-rw-r--r--tests/expected/libsmartcols/fromfile-padding-default11
-rw-r--r--tests/expected/libsmartcols/fromfile-padding-maxout11
-rw-r--r--tests/expected/libsmartcols/fromfile-padding-minout11
-rw-r--r--tests/expected/lsblk/lsblk-simple-lvm-vendor38
-rw-r--r--tests/expected/lsblk/lsblk-simple-nvme-vendor22
-rw-r--r--tests/expected/misc/mountpoint0
-rw-r--r--tests/expected/misc/mountpoint-default2
-rw-r--r--tests/expected/misc/mountpoint-mutually-exclusive2
-rw-r--r--tests/expected/misc/mountpoint-nofollow2
-rwxr-xr-xtests/ts/column/table8
-rwxr-xr-xtests/ts/fdisk/mbr-nondos-mode7
-rwxr-xr-xtests/ts/libmount/context7
-rw-r--r--tests/ts/libsmartcols/files/data-string-empty10
-rwxr-xr-xtests/ts/libsmartcols/fromfile46
-rwxr-xr-xtests/ts/misc/mountpoint29
-rwxr-xr-xtests/ts/partx/partx9
-rw-r--r--text-utils/colrm.c2
-rw-r--r--text-utils/column.c2
108 files changed, 1108 insertions, 588 deletions
diff --git a/Documentation/TODO b/Documentation/TODO
index a4a8d7890..6d4c1b278 100644
--- a/Documentation/TODO
+++ b/Documentation/TODO
@@ -51,7 +51,7 @@ nsenter(1)
- read the default UID and GID from the target process.
http://thread.gmane.org/gmane.linux.utilities.util-linux-ng/9553/focus=9585
-hwlock
+hwclock
------
- use /var/lib/hwclock/drift to store hw-clock drift numbers.
- use /etc/adjtime as read-only for UTC/LOCAL information only
diff --git a/NEWS b/NEWS
index 1ae6216c6..a17abe0e5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,12 +1,12 @@
-util-linux 2.34: Jun 14 2018
+util-linux 2.34: Jun 14 2019
* see Documentation/releases/v2.34-ReleaseNotes or the complete changelog at
https://www.kernel.org/pub/linux/utils/util-linux/v2.34/v2.34-ChangeLog
-util-linux 2.34-rc2: May 30 2018
+util-linux 2.34-rc2: May 30 2019
* see Documentation/releases/v2.34-ReleaseNotes or the complete changelog at
https://www.kernel.org/pub/linux/utils/util-linux/v2.34/v2.34-rc2-ChangeLog
-util-linux 2.34-rc1: Apr 30 2018
+util-linux 2.34-rc1: Apr 30 2019
* see Documentation/releases/v2.34-ReleaseNotes or the complete changelog at
https://www.kernel.org/pub/linux/utils/util-linux/v2.34/v2.34-rc1-ChangeLog
diff --git a/bash-completion/mountpoint b/bash-completion/mountpoint
index f14327ce2..15c6d2314 100644
--- a/bash-completion/mountpoint
+++ b/bash-completion/mountpoint
@@ -11,7 +11,7 @@ _mountpoint_module()
esac
case $cur in
-*)
- OPTS="--quiet --fs-devno --devno --help --version"
+ OPTS="--quiet --nofollow --fs-devno --devno --help --version"
COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
return 0
;;
diff --git a/configure.ac b/configure.ac
index a840e20ee..3bec9769b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -756,6 +756,7 @@ UL_REQUIRES_COMPILE([widechar], [[
#include <wchar.h>
#include <wctype.h>
#include <stdio.h>
+ #include <stdlib.h>
]], [[
wchar_t wc;
wint_t w;
@@ -1515,6 +1516,18 @@ UL_BUILD_INIT([hwclock])
UL_REQUIRES_HAVE([hwclock], [io, linuxdummy], [ioperm iopl function or Linux])
AM_CONDITIONAL([BUILD_HWCLOCK], [test "x$build_hwclock" = xyes])
+AC_ARG_ENABLE([hwclock_cmos],
+ AS_HELP_STRING([--disable-hwclock-cmos], [do not use CMOS clock]),
+ [], [enable_hwclock_cmos=check]
+)
+UL_BUILD_INIT([hwclock_cmos])
+UL_REQUIRES_BUILD([hwclock_cmos], [hwclock])
+UL_REQUIRES_ARCH([hwclock_cmos], [i?86-*,x86_64*])
+AM_CONDITIONAL([USE_HWCLOCK_CMOS], [test "x$build_hwclock_cmos" = xyes])
+AS_IF([test "x$build_hwclock_cmos" = xyes ], [
+ AC_DEFINE([USE_HWCLOCK_CMOS], [1], [Define to 1 if want to use CMOS clock.])
+])
+
UL_BUILD_INIT([mkfs], [yes])
AM_CONDITIONAL([BUILD_MKFS], [test "x$build_mkfs" = xyes])
diff --git a/disk-utils/fsck.cramfs.c b/disk-utils/fsck.cramfs.c
index e1b964b64..a81995180 100644
--- a/disk-utils/fsck.cramfs.c
+++ b/disk-utils/fsck.cramfs.c
@@ -416,7 +416,6 @@ static void do_uncompress(char *path, int outfd, unsigned long offset,
curr = next;
} while (size);
}
-#include <utime.h>
static void change_file_status(char *path, struct cramfs_inode *i)
{
const struct timeval epoch[] = { {0,0}, {0,0} };
diff --git a/disk-utils/partx.8 b/disk-utils/partx.8
index 223f20918..d6ff52f08 100644
--- a/disk-utils/partx.8
+++ b/disk-utils/partx.8
@@ -53,7 +53,10 @@ Add the specified partitions, or read the disk and add all partitions.
Print the SIZE column in bytes rather than in human-readable format.
.TP
.BR \-d , " \-\-delete"
-Delete the specified partitions or all partitions.
+Delete the specified partitions or all partitions. It is not error to
+remove non-existing partitions, so this option is possible to use together with
+large \fB\-\-nr\fR ranges without care about the current partitions set on
+the device.
.TP
.BR \-g , " \-\-noheadings"
Do not print a header line with \fB\-\-show\fR or \fB\-\-raw\fR.
diff --git a/disk-utils/partx.c b/disk-utils/partx.c
index 949278eb7..e1f6b8f9e 100644
--- a/disk-utils/partx.c
+++ b/disk-utils/partx.c
@@ -328,8 +328,7 @@ static int del_parts(int fd, const char *device, dev_t devno,
}
for (i = lower; i <= upper; i++) {
- rc = partx_del_partition(fd, i);
- if (rc == 0) {
+ if (partx_del_partition(fd, i) == 0) {
if (verbose)
printf(_("%s: partition #%d removed\n"), device, i);
continue;
diff --git a/disk-utils/sfdisk.8 b/disk-utils/sfdisk.8
index ff54760ca..c7630bb37 100644
--- a/disk-utils/sfdisk.8
+++ b/disk-utils/sfdisk.8
@@ -462,7 +462,8 @@ GPT partition UUID.
GPT partition name.
.TP
.BI type= code
-A hexadecimal number (without 0x) for an MBR partition, or a GUID for a GPT partition.
+A hexadecimal number (without 0x) for an MBR partition, a GUID for a GPT partition,
+or a shortcut as for unnamed-fields format.
For backward compatibility the \fBId=\fR field has the same meaning.
.RE
.RE
diff --git a/include/carefulputc.h b/include/carefulputc.h
index 54a02bfef..f1c03566d 100644
--- a/include/carefulputc.h
+++ b/include/carefulputc.h
@@ -10,13 +10,15 @@
#include <string.h>
#include <ctype.h>
+#include "cctype.h"
+
static inline int fputc_careful(int c, FILE *fp, const char fail)
{
int ret;
if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
ret = putc(c, fp);
- else if (!isascii(c))
+ else if (!c_isascii(c))
ret = fprintf(fp, "\\%3o", (unsigned char)c);
else {
ret = putc(fail, fp);
diff --git a/include/closestream.h b/include/closestream.h
index 6a62e48e8..83df1ee7d 100644
--- a/include/closestream.h
+++ b/include/closestream.h
@@ -39,7 +39,7 @@ close_stream(FILE * stream)
static inline void
close_stdout(void)
{
- if (close_stream(stdout) != 0 && !(errno == EPIPE)) {
+ if (stdout && close_stream(stdout) != 0 && !(errno == EPIPE)) {
if (errno)
warn(_("write error"));
else
@@ -47,8 +47,11 @@ close_stdout(void)
_exit(CLOSE_EXIT_CODE);
}
- if (close_stream(stderr) != 0)
+ if (stderr && close_stream(stderr) != 0)
_exit(CLOSE_EXIT_CODE);
+
+ stdout = NULL;
+ stderr = NULL;
}
static inline void
diff --git a/include/pathnames.h b/include/pathnames.h
index ee470ee4b..2e1f19355 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -104,6 +104,7 @@
#define _PATH_SYS_BLOCK "/sys/block"
#define _PATH_SYS_DEVBLOCK "/sys/dev/block"
+#define _PATH_SYS_DEVCHAR "/sys/dev/char"
#define _PATH_SYS_CLASS "/sys/class"
#define _PATH_SYS_SCSI "/sys/bus/scsi"
@@ -167,9 +168,6 @@
/* deprecated */
#define _PATH_RAWDEVCTL_OLD "/dev/rawctl"
-/* wdctl path */
-#define _PATH_WATCHDOG_DEV "/dev/watchdog"
-
/* ipc paths */
#define _PATH_PROC_SYSV_MSG "/proc/sysvipc/msg"
#define _PATH_PROC_SYSV_SEM "/proc/sysvipc/sem"
diff --git a/include/xalloc.h b/include/xalloc.h
index 0129a85e2..48712a452 100644
--- a/include/xalloc.h
+++ b/include/xalloc.h
@@ -62,8 +62,7 @@ static inline char __attribute__((warn_unused_result)) __ul_returns_nonnull
{
char *ret;
- if (!str)
- return NULL;
+ assert(str);
ret = strdup(str);
@@ -77,8 +76,7 @@ xstrndup(const char *str, size_t size)
{
char *ret;
- if (!str)
- return NULL;
+ assert(str);
ret = strndup(str, size);
diff --git a/lib/loopdev.c b/lib/loopdev.c
index 26ab402fa..ac46f5312 100644
--- a/lib/loopdev.c
+++ b/lib/loopdev.c
@@ -127,7 +127,7 @@ int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
return 0;
}
-inline int loopcxt_has_device(struct loopdev_cxt *lc)
+int loopcxt_has_device(struct loopdev_cxt *lc)
{
return lc && *lc->device;
}
diff --git a/lib/path.c b/lib/path.c
index f7fd19592..8dce1da40 100644
--- a/lib/path.c
+++ b/lib/path.c
@@ -610,9 +610,10 @@ int ul_path_read_buffer(struct path_cxt *pc, char *buf, size_t bufsz, const char
/* Remove tailing newline (usual in sysfs) */
if (rc > 0 && *(buf + rc - 1) == '\n')
- --rc;
+ buf[--rc] = '\0';
+ else
+ buf[rc - 1] = '\0';
- buf[rc] = '\0';
return rc;
}
diff --git a/lib/ttyutils.c b/lib/ttyutils.c
index 166e49e11..8649f435a 100644
--- a/lib/ttyutils.c
+++ b/lib/ttyutils.c
@@ -47,16 +47,16 @@ int get_terminal_dimension(int *cols, int *lines)
l = t_win.ts_lines;
}
#endif
-
- if (cols && c <= 0)
- c = get_env_int("COLUMNS");
- if (lines && l <= 0)
- l = get_env_int("LINES");
-
- if (cols)
+ if (cols) {
+ if (c <= 0)
+ c = get_env_int("COLUMNS");
*cols = c;
- if (lines)
+ }
+ if (lines) {
+ if (l <= 0)
+ l = get_env_int("LINES");
*lines = l;
+ }
return 0;
}
diff --git a/libblkid/src/partitions/dos.c b/libblkid/src/partitions/dos.c
index 6c1b519f7..f8b0ee50d 100644
--- a/libblkid/src/partitions/dos.c
+++ b/libblkid/src/partitions/dos.c
@@ -14,6 +14,7 @@
#include <stdint.h>
#include "partitions.h"
+#include "superblocks/superblocks.h"
#include "aix.h"
/* see superblocks/vfat.c */
@@ -222,6 +223,12 @@ static int probe_dos_pt(blkid_probe pr,
goto nothing;
}
+ /* Another false possitive is NTFS */
+ if (blkid_probe_is_ntfs(pr) == 1) {
+ DBG(LOWPROBE, ul_debug("probably NTFS -- ignore"));
+ goto nothing;
+ }
+
/*
* Ugly exception, if the device contains a valid LVM physical volume
* and empty MBR (=no partition defined) then it's LVM and MBR should
diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c
index 1ace06a68..ae1fc06d6 100644
--- a/libblkid/src/probe.c
+++ b/libblkid/src/probe.c
@@ -846,10 +846,15 @@ failed:
* @off: begin of probing area
* @size: size of probing area (zero means whole device/file)
*
- * Assigns the device to probe control struct, resets internal buffers and
- * resets the current probing.
+ * Assigns the device to probe control struct, resets internal buffers, resets
+ * the current probing, and close previously associated device (if open by
+ * libblkid).
*
- * Returns: -1 in case of failure, or 0 on success.
+ * If @fd is < 0 than only resets the prober and returns 1. Note that
+ * blkid_reset_probe() keeps the device associated with the prober, but
+ * blkid_probe_set_device() does complete reset.
+ *
+ * Returns: -1 in case of failure, 0 on success and 1 on reset.
*/
int blkid_probe_set_device(blkid_probe pr, int fd,
blkid_loff_t off, blkid_loff_t size)
@@ -864,6 +869,11 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
close(pr->fd);
+ if (pr->disk_probe) {
+ blkid_free_probe(pr->disk_probe);
+ pr->disk_probe = NULL;
+ }
+
pr->flags &= ~BLKID_FL_PRIVATE_FD;
pr->flags &= ~BLKID_FL_TINY_DEV;
pr->flags &= ~BLKID_FL_CDROM_DEV;
@@ -879,6 +889,9 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
pr->wipe_size = 0;
pr->wipe_chain = NULL;
+ if (fd < 0)
+ return 1;
+
#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
/* Disable read-ahead */
posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
diff --git a/libblkid/src/save.c b/libblkid/src/save.c
index 21308a9cf..bceaa1139 100644
--- a/libblkid/src/save.c
+++ b/libblkid/src/save.c
@@ -213,7 +213,7 @@ int main(int argc, char **argv)
int ret;
blkid_init_debug(BLKID_DEBUG_ALL);
- if (argc > 2) {
+ if (argc != 2) {
fprintf(stderr, "Usage: %s [filename]\n"
"Test loading/saving a cache (filename)\n", argv[0]);
exit(1);
diff --git a/libblkid/src/superblocks/drbd.c b/libblkid/src/superblocks/drbd.c
index 4ebaf1739..f3601864e 100644
--- a/libblkid/src/superblocks/drbd.c
+++ b/libblkid/src/superblocks/drbd.c
@@ -45,6 +45,13 @@ enum drbd_uuid_index {
UI_EXTENDED_SIZE /* Everything. */
};
+
+/*
+ * Used by libblkid to avoid unnecessary padding at the end of the structs and
+ * too large unused structs in memory.
+ */
+#define DRBD_MD_OFFSET 4096
+
/*
* user/shared/drbdmeta.c
* Minor modifications wrt. types
@@ -63,7 +70,9 @@ struct md_on_disk_08 {
uint32_t bm_bytes_per_bit;
uint32_t reserved_u32[4];
- char reserved[8 * 512 - (8*(UI_SIZE+3)+4*11)];
+ /* Unnecessary for libblkid **
+ * char reserved[8 * 512 - (8*(UI_SIZE+3)+4*11)];
+ */
};
/*
@@ -109,7 +118,9 @@ struct meta_data_on_disk_9 {
struct peer_dev_md_on_disk_9 peers[DRBD_PEERS_MAX];
uint64_t history_uuids[HISTORY_UUIDS];
- char padding[0] __attribute__((aligned(4096)));
+ /* Unnecessary for libblkid **
+ * char padding[0] __attribute__((aligned(4096)));
+ */
} __attribute__((packed));
@@ -118,7 +129,7 @@ static int probe_drbd_84(blkid_probe pr)
struct md_on_disk_08 *md;
off_t off;
- off = pr->size - sizeof(*md);
+ off = pr->size - DRBD_MD_OFFSET;
/* Small devices cannot be drbd (?) */
if (pr->size < 0x10000)
@@ -159,7 +170,7 @@ static int probe_drbd_90(blkid_probe pr)
struct meta_data_on_disk_9 *md;
off_t off;
- off = pr->size - sizeof(*md);
+ off = pr->size - DRBD_MD_OFFSET;
/*
* Smaller ones are certainly not DRBD9 devices.
diff --git a/libblkid/src/superblocks/ntfs.c b/libblkid/src/superblocks/ntfs.c
index 5ea2a454a..90a102f89 100644
--- a/libblkid/src/superblocks/ntfs.c
+++ b/libblkid/src/superblocks/ntfs.c
@@ -78,7 +78,7 @@ struct file_attribute {
#define MFT_RECORD_ATTR_VOLUME_NAME 0x60
#define MFT_RECORD_ATTR_END 0xffffffff
-static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag)
+static int __probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag, int save_info)
{
struct ntfs_super_block *ns;
struct master_file_table_record *mft;
@@ -174,6 +174,10 @@ static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag)
if (memcmp(buf_mft, "FILE", 4))
return 1;
+ /* return if caller does not care about UUID and LABEL */
+ if (!save_info)
+ return 0;
+
mft = (struct master_file_table_record *) buf_mft;
attr_off = le16_to_cpu(mft->attrs_offset);
@@ -211,6 +215,24 @@ static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag)
return 0;
}
+static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ return __probe_ntfs(pr, mag, 1);
+}
+
+int blkid_probe_is_ntfs(blkid_probe pr)
+{
+ const struct blkid_idmag *mag = NULL;
+ int rc;
+
+ rc = blkid_probe_get_idmag(pr, &ntfs_idinfo, NULL, &mag);
+ if (rc < 0)
+ return rc; /* error */
+ if (rc != BLKID_PROBE_OK || !mag)
+ return 0;
+
+ return __probe_ntfs(pr, mag, 0) == 0 ? 1 : 0;
+}
const struct blkid_idinfo ntfs_idinfo =
{
diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h
index 3313d0245..59682c86d 100644
--- a/libblkid/src/superblocks/superblocks.h
+++ b/libblkid/src/superblocks/superblocks.h
@@ -109,5 +109,6 @@ extern int blkid_probe_set_utf8_id_label(blkid_probe pr, const char *name,
const unsigned char *data, size_t len, int enc);
extern int blkid_probe_is_bitlocker(blkid_probe pr);
+extern int blkid_probe_is_ntfs(blkid_probe pr);
#endif /* _BLKID_SUPERBLOCKS_H */
diff --git a/libblkid/src/superblocks/zfs.c b/libblkid/src/superblocks/zfs.c
index 4d4b46d55..0af14fb65 100644
--- a/libblkid/src/superblocks/zfs.c
+++ b/libblkid/src/superblocks/zfs.c
@@ -58,7 +58,7 @@ struct nvuint64 {
uint32_t nvu_type;
uint32_t nvu_elem;
uint64_t nvu_value;
-};
+} __attribute__((packed));
struct nvlist {
uint32_t nvl_unknown[3];
diff --git a/libblkid/src/verify.c b/libblkid/src/verify.c
index dbc10f254..a78c9f8f2 100644
--- a/libblkid/src/verify.c
+++ b/libblkid/src/verify.c
@@ -184,9 +184,11 @@ blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
dev->bid_name, (long long)st.st_rdev, dev->bid_type));
}
- blkid_reset_probe(cache->probe);
+ /* reset prober */
blkid_probe_reset_superblocks_filter(cache->probe);
+ blkid_probe_set_device(cache->probe, -1, 0, 0);
close(fd);
+
return dev;
}
diff --git a/libfdisk/docs/libfdisk-sections.txt b/libfdisk/docs/libfdisk-sections.txt
index f6675fe46..f148da527 100644
--- a/libfdisk/docs/libfdisk-sections.txt
+++ b/libfdisk/docs/libfdisk-sections.txt
@@ -132,6 +132,7 @@ fdisk_ref_script
fdisk_script_enable_json
fdisk_script_get_header
fdisk_script_get_nlines
+fdisk_script_set_table
fdisk_script_get_table
fdisk_script_has_force_label
fdisk_script_read_context
@@ -290,6 +291,7 @@ fdisk_unref_table
<FILE>context</FILE>
fdisk_context
fdisk_assign_device
+fdisk_assign_device_by_fd
fdisk_deassign_device
fdisk_reassign_device
fdisk_device_is_used
diff --git a/libfdisk/src/alignment.c b/libfdisk/src/alignment.c
index 426fa938c..4ae5ff08f 100644
--- a/libfdisk/src/alignment.c
+++ b/libfdisk/src/alignment.c
@@ -324,7 +324,7 @@ int fdisk_save_user_sector_size(struct fdisk_context *cxt,
*
* The smallest possible granularity for partitioning is physical sector size
* (or minimal I/O size; the bigger number win). If the user's @grain size is
- * too small than the smallest possible granularity is used. It means
+ * too small then the smallest possible granularity is used. It means
* fdisk_save_user_grain(cxt, 512) forces libfdisk to use grain as small as
* possible.
*
diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c
index 56ebb6c1e..f97f0a612 100644
--- a/libfdisk/src/context.c
+++ b/libfdisk/src/context.c
@@ -17,13 +17,13 @@
*
* The library distinguish between three types of partitioning objects.
*
- * on-disk data
+ * on-disk label data
* - disk label specific
* - probed and read by disklabel drivers when assign device to the context
* or when switch to another disk label type
* - only fdisk_write_disklabel() modify on-disk data
*
- * in-memory data
+ * in-memory label data
* - generic data and disklabel specific data stored in struct fdisk_label
* - all partitioning operations are based on in-memory data only
*
@@ -31,8 +31,12 @@
* - provides abstraction to present partitions to users
* - fdisk_partition is possible to gather to fdisk_table container
* - used as unified template for new partitions
+ * - used (with fdisk_table) in fdisk scripts
* - the struct fdisk_partition is always completely independent object and
* any change to the object has no effect to in-memory (or on-disk) label data
+ *
+ * Don't forget to inform kernel about changes by fdisk_reread_partition_table()
+ * or more smart fdisk_reread_changes().
*/
/**
@@ -483,7 +487,7 @@ int fdisk_is_ptcollision(struct fdisk_context *cxt)
* </informalexample>
*
* Note that the recommended way to list partitions is to use
- * fdisk_get_partitions() and struct fdisk_table than ask disk driver for each
+ * fdisk_get_partitions() and struct fdisk_table then ask disk driver for each
* individual partitions.
*
* Returns: maximal number of partitions for the current label.
@@ -537,7 +541,7 @@ static void reset_context(struct fdisk_context *cxt)
free(cxt->firstsector);
} else {
/* we close device only in primary context */
- if (cxt->dev_fd > -1)
+ if (cxt->dev_fd > -1 && cxt->private_fd)
close(cxt->dev_fd);
free(cxt->firstsector);
}
@@ -555,6 +559,7 @@ static void reset_context(struct fdisk_context *cxt)
memset(&cxt->dev_st, 0, sizeof(cxt->dev_st));
cxt->dev_fd = -1;
+ cxt->private_fd = 0;
cxt->firstsector = NULL;
cxt->firstsector_bufsz = 0;
@@ -568,30 +573,12 @@ static void reset_context(struct fdisk_context *cxt)
fdisk_free_wipe_areas(cxt);
}
-/**
- * fdisk_assign_device:
- * @cxt: context
- * @fname: path to the device to be handled
- * @readonly: how to open the device
- *
- * Open the device, discovery topology, geometry, detect disklabel and switch
- * the current label driver to reflect the probing result.
- *
- * Note that this function resets all generic setting in context. If the @cxt
- * is nested context then the device is assigned to the parental context and
- * necessary properties are copied to the @cxt. The change is propagated in
- * child->parent direction only. It's impossible to use a different device for
- * primary and nested contexts.
- *
- * Returns: 0 on success, < 0 on error.
- */
-int fdisk_assign_device(struct fdisk_context *cxt,
- const char *fname, int readonly)
+/* fdisk_assign_device() body */
+static int fdisk_assign_fd(struct fdisk_context *cxt, int fd,
+ const char *fname, int readonly, int privfd)
{
- int fd;
-
- DBG(CXT, ul_debugobj(cxt, "assigning device %s", fname));
assert(cxt);
+ assert(fd >= 0);
/* redirect request to parent */
if (cxt->parent) {
@@ -602,7 +589,7 @@ int fdisk_assign_device(struct fdisk_context *cxt,
* unwanted extra warnings. */
fdisk_enable_listonly(cxt->parent, fdisk_is_listonly(cxt));
- rc = fdisk_assign_device(cxt->parent, fname, readonly);
+ rc = fdisk_assign_fd(cxt->parent, fd, fname, readonly, privfd);
fdisk_enable_listonly(cxt->parent, org);
if (!rc)
@@ -614,16 +601,13 @@ int fdisk_assign_device(struct fdisk_context *cxt,
reset_context(cxt);
- fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC);
- if (fd < 0)
- goto fail;
-
if (fstat(fd, &cxt->dev_st) != 0)
goto fail;
cxt->readonly = readonly;
cxt->dev_fd = fd;
- cxt->dev_path = strdup(fname);
+ cxt->private_fd = privfd;
+ cxt->dev_path = fname ? strdup(fname) : NULL;
if (!cxt->dev_path)
goto fail;
@@ -635,15 +619,20 @@ int fdisk_assign_device(struct fdisk_context *cxt,
if (fdisk_read_firstsector(cxt) < 0)
goto fail;
- fdisk_probe_labels(cxt);
+ /* warn about obsolete stuff on the device if we aren't in list-only */
+ if (!fdisk_is_listonly(cxt) && fdisk_check_collisions(cxt) < 0)
+ goto fail;
+ fdisk_probe_labels(cxt);
fdisk_apply_label_device_properties(cxt);
- /* warn about obsolete stuff on the device if we aren't in
- * list-only mode and there is not PT yet */
- if (!fdisk_is_listonly(cxt) && !fdisk_has_label(cxt)
- && fdisk_check_collisions(cxt) < 0)
- goto fail;
+ /* Don't report collision if there is already a valid partition table.
+ * The bootbits are wiped when we create a *new* partition table only. */
+ if (fdisk_is_ptcollision(cxt) && fdisk_has_label(cxt)) {
+ cxt->pt_collision = 0;
+ free(cxt->collision);
+ cxt->collision = NULL;
+ }
DBG(CXT, ul_debugobj(cxt, "initialized for %s [%s]",
fname, readonly ? "READ-ONLY" : "READ-WRITE"));
@@ -651,19 +640,84 @@ int fdisk_assign_device(struct fdisk_context *cxt,
fail:
{
int rc = -errno;
- if (fd >= 0)
- close(fd);
DBG(CXT, ul_debugobj(cxt, "failed to assign device [rc=%d]", rc));
return rc;
}
}
/**
+ * fdisk_assign_device:
+ * @cxt: context
+ * @fname: path to the device to be handled
+ * @readonly: how to open the device
+ *
+ * Open the device, discovery topology, geometry, detect disklabel, check for
+ * collisions and switch the current label driver to reflect the probing
+ * result.
+ *
+ * If in standard mode (!= non-listonly mode) then also detects for collisions.
+ * The result is accessible by fdisk_get_collision() and
+ * fdisk_is_ptcollision(). The collision (e.g. old obsolete PT) may be removed
+ * by fdisk_enable_wipe(). Note that new PT and old PT may be on different
+ * locations.
+ *
+ * Note that this function resets all generic setting in context.
+ *
+ * If the @cxt is nested context (necessary for example to edit BSD or PMBR)
+ * then the device is assigned to the parental context and necessary properties
+ * are copied to the @cxt. The change is propagated in child->parent direction
+ * only. It's impossible to use a different device for primary and nested
+ * contexts.
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_assign_device(struct fdisk_context *cxt,
+ const char *fname, int readonly)
+{
+ int fd, rc;
+
+ DBG(CXT, ul_debugobj(cxt, "assigning device %s", fname));
+ assert(cxt);
+
+ fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC);
+ if (fd < 0) {
+ rc = -errno;
+ DBG(CXT, ul_debugobj(cxt, "failed to assign device [rc=%d]", rc));
+ return rc;
+ }
+
+ rc = fdisk_assign_fd(cxt, fd, fname, readonly, 1);
+ if (rc)
+ close(fd);
+ return rc;
+}
+
+/**
+ * fdisk_assign_device_by_fd:
+ * @cxt: context
+ * @fd: device file descriptor
+ * @fname: path to the device (used for dialogs, debugging, partition names, ...)
+ * @readonly: how to use the device
+ *
+ * Like fdisk_assign_device(), but caller is responsible to open and close the
+ * device. The library only fsync() the device on fdisk_deassign_device().
+ *
+ * The device has to be open O_RDWR on @readonly=0.
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_assign_device_by_fd(struct fdisk_context *cxt, int fd,
+ const char *fname, int readonly)
+{
+ return fdisk_assign_fd(cxt, fd, fname, readonly, 0);
+}
+
+/**
* fdisk_deassign_device:
* @cxt: context
* @nosync: disable fsync()
*
- * Close device and call fsync(). If the @cxt is nested context than the
+ * Close device and call fsync(). If the @cxt is nested context then the
* request is redirected to the parent.
*
* Returns: 0 on success, < 0 on error.
@@ -683,15 +737,19 @@ int fdisk_deassign_device(struct fdisk_context *cxt, int nosync)
DBG(CXT, ul_debugobj(cxt, "de-assigning device %s", cxt->dev_path));
- if (cxt->readonly)
+ if (cxt->readonly && cxt->private_fd)
close(cxt->dev_fd);
else {
- if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) {
+ if (fsync(cxt->dev_fd)) {
+ fdisk_warn(cxt, _("%s: fsync device failed"),
+ cxt->dev_path);
+ return -errno;
+ }
+ if (cxt->private_fd && close(cxt->dev_fd)) {
fdisk_warn(cxt, _("%s: close device failed"),
cxt->dev_path);
return -errno;
}
-
if (!nosync) {
fdisk_info(cxt, _("Syncing disks."));
sync();
@@ -700,7 +758,6 @@ int fdisk_deassign_device(struct fdisk_context *cxt, int nosync)
free(cxt->dev_path);
cxt->dev_path = NULL;
-
cxt->dev_fd = -1;
return 0;
@@ -720,7 +777,7 @@ int fdisk_deassign_device(struct fdisk_context *cxt, int nosync)
int fdisk_reassign_device(struct fdisk_context *cxt)
{
char *devname;
- int rdonly, rc;
+ int rdonly, rc, fd, privfd;
assert(cxt);
assert(cxt->dev_fd >= 0);
@@ -732,11 +789,19 @@ int fdisk_reassign_device(struct fdisk_context *cxt)
return -ENOMEM;
rdonly = cxt->readonly;
+ fd = cxt->dev_fd;
+ privfd = cxt->private_fd;
fdisk_deassign_device(cxt, 1);
- rc = fdisk_assign_device(cxt, devname, rdonly);
- free(devname);
+ if (privfd)
+ /* reopen and assign */
+ rc = fdisk_assign_device(cxt, devname, rdonly);
+ else
+ /* assign only */
+ rc = fdisk_assign_fd(cxt, fd, devname, rdonly, privfd);
+
+ free(devname);
return rc;
}
@@ -774,7 +839,7 @@ int fdisk_reread_partition_table(struct fdisk_context *cxt)
fdisk_info(cxt, _(
"The kernel still uses the old table. The "
"new table will be used at the next reboot "
- "or after you run partprobe(8) or kpartx(8)."));
+ "or after you run partprobe(8) or partx(8)."));
return -errno;
}
diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c
index 6dc276e8a..fc5bcc651 100644
--- a/libfdisk/src/dos.c
+++ b/libfdisk/src/dos.c
@@ -814,6 +814,12 @@ static int dos_probe_label(struct fdisk_context *cxt)
if (!mbr_is_valid_magic(cxt->firstsector))
return 0;
+ /* ignore disks with FAT */
+ if (cxt->collision &&
+ (strcmp(cxt->collision, "vfat") == 0 ||
+ strcmp(cxt->collision, "ntfs") == 0))
+ return 0;
+
dos_init(cxt);
get_partition_table_geometry(cxt, &h, &s);
diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h
index 19c1c7953..fefebae2a 100644
--- a/libfdisk/src/fdiskP.h
+++ b/libfdisk/src/fdiskP.h
@@ -389,6 +389,7 @@ struct fdisk_context {
pt_collision : 1, /* another PT detected by libblkid */
no_disalogs : 1, /* disable dialog-driven partititoning */
dev_model_probed : 1, /* tried to read from sys */
+ private_fd : 1, /* open by libfdisk */
listonly : 1; /* list partition, nothing else */
char *collision; /* name of already existing FS/PT */
diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c
index 2a11acad6..a18cdeaff 100644
--- a/libfdisk/src/label.c
+++ b/libfdisk/src/label.c
@@ -247,7 +247,8 @@ const struct fdisk_field *fdisk_label_get_field_by_name(
* fdisk_write_disklabel:
* @cxt: fdisk context
*
- * Write in-memory changes to disk. Be careful!
+ * This function wipes the device (if enabled by fdisk_enable_wipe()) and then
+ * it writes in-memory changes to disk. Be careful!
*
* Returns: 0 on success, otherwise, a corresponding error.
*/
@@ -636,7 +637,7 @@ int fdisk_label_is_disabled(const struct fdisk_label *lb)
* @ma: maximal number
*
* The function provides minimal and maximal geometry supported for the label,
- * if no range defined by library than returns -ENOSYS.
+ * if no range defined by library then returns -ENOSYS.
*
* Since: 2.32
*
@@ -661,7 +662,7 @@ int fdisk_label_get_geomrange_sectors(const struct fdisk_label *lb,
* @ma: maximal number
*
* The function provides minimal and maximal geometry supported for the label,
- * if no range defined by library than returns -ENOSYS.
+ * if no range defined by library then returns -ENOSYS.
*
* Since: 2.32
*
@@ -686,7 +687,7 @@ int fdisk_label_get_geomrange_heads(const struct fdisk_label *lb,
* @ma: maximal number
*
* The function provides minimal and maximal geometry supported for the label,
- * if no range defined by library than returns -ENOSYS.
+ * if no range defined by library then returns -ENOSYS.
*
* Since: 2.32
*
diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in
index 47e778a67..0669c0a7c 100644
--- a/libfdisk/src/libfdisk.h.in
+++ b/libfdisk/src/libfdisk.h.in
@@ -195,6 +195,8 @@ int fdisk_is_labeltype(struct fdisk_context *cxt, enum fdisk_labeltype id);
int fdisk_assign_device(struct fdisk_context *cxt,
const char *fname, int readonly);
+int fdisk_assign_device_by_fd(struct fdisk_context *cxt, int fd,
+ const char *fname, int readonly);
int fdisk_deassign_device(struct fdisk_context *cxt, int nosync);
int fdisk_reassign_device(struct fdisk_context *cxt);
@@ -757,6 +759,7 @@ void fdisk_unref_script(struct fdisk_script *dp);
const char *fdisk_script_get_header(struct fdisk_script *dp, const char *name);
int fdisk_script_set_header(struct fdisk_script *dp, const char *name, const char *data);
struct fdisk_table *fdisk_script_get_table(struct fdisk_script *dp);
+int fdisk_script_set_table(struct fdisk_script *dp, struct fdisk_table *tb);
int fdisk_script_get_nlines(struct fdisk_script *dp);
int fdisk_script_has_force_label(struct fdisk_script *dp);
diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym
index 8f80d7964..96fcadd71 100644
--- a/libfdisk/src/libfdisk.sym
+++ b/libfdisk/src/libfdisk.sym
@@ -303,3 +303,8 @@ FDISK_2.33 {
fdisk_get_devmodel;
fdisk_get_devno;
} FDISK_2.32;
+
+FDISK_2.35 {
+ fdisk_script_set_table;
+ fdisk_assign_device_by_fd;
+} FDISK_2.33;
diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c
index 05474a041..80a43ffde 100644
--- a/libfdisk/src/partition.c
+++ b/libfdisk/src/partition.c
@@ -85,7 +85,13 @@ static struct fdisk_partition *__copy_partition(struct fdisk_partition *o)
if (!n)
return NULL;
+
memcpy(n, o, sizeof(*n));
+
+ /* do not copy reference to lists, etc.*/
+ n->refcount = 1;
+ INIT_LIST_HEAD(&n->parts);
+
if (n->type)
fdisk_ref_parttype(n->type);
if (o->name)
@@ -100,6 +106,10 @@ static struct fdisk_partition *__copy_partition(struct fdisk_partition *o)
n->fsuuid = strdup(o->fsuuid);
if (o->fslabel)
n->fslabel = strdup(o->fslabel);
+ if (o->start_chs)
+ n->start_chs = strdup(o->start_chs);
+ if (o->end_chs)
+ n->end_chs = strdup(o->end_chs);
return n;
}
diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c
index 66be4f08c..a28983dba 100644
--- a/libfdisk/src/script.c
+++ b/libfdisk/src/script.c
@@ -7,13 +7,33 @@
/**
* SECTION: script
* @title: Script
- * @short_description: text based sfdisk compatible description of partition table
+ * @short_description: complex way to create and dump partition table
*
- * The libfdisk scripts are based on original sfdisk script (dumps). Each
+ * This interface allows to compose in-memory partition table with all details,
+ * write all partition table description to human readable text file, read it
+ * from the file, and apply the script to on-disk label.
+ *
+ * The libfdisk scripts are based on original sfdisk script (dumps). Each
* script has two parts: script headers and partition table entries
- * (partitions).
+ * (partitions). The script is possible to dump in JSON too (read JSON is not
+ * implemented yet).
*
* For more details about script format see sfdisk man page.
+ *
+ * There are four ways how to build the script:
+ *
+ * - read the current on-disk partition table by fdisk_script_read_context())
+ * - read it from text file by fdisk_script_read_file()
+ * - read it interactively from user by fdisk_script_read_line() and fdisk_script_set_fgets()
+ * - manually in code by fdisk_script_set_header() and fdisk_script_set_table()
+ *
+ * The read functions fdisk_script_read_context() and fdisk_script_read_file()
+ * creates always a new script partition table. The table (see
+ * fdisk_script_get_table()) is possible to modify by standard
+ * fdisk_table_...() functions and then apply by fdisk_apply_script().
+ *
+ * Note that script API is fully non-interactive and forces libfdisk to not use
+ * standard dialog driven partitioning as we have in fdisk(8).
*/
/* script header (e.g. unit: sectors) */
@@ -41,6 +61,8 @@ struct fdisk_script {
force_label : 1; /* label: <name> specified */
};
+static struct fdisk_parttype *translate_type_shortcuts(struct fdisk_script *dp, char *str);
+
static void fdisk_script_free_header(struct fdisk_scriptheader *fi)
{
@@ -76,12 +98,6 @@ struct fdisk_script *fdisk_new_script(struct fdisk_context *cxt)
dp->cxt = cxt;
fdisk_ref_context(cxt);
- dp->table = fdisk_new_table();
- if (!dp->table) {
- fdisk_unref_script(dp);
- return NULL;
- }
-
INIT_LIST_HEAD(&dp->headers);
return dp;
}
@@ -148,8 +164,9 @@ static void fdisk_reset_script(struct fdisk_script *dp)
assert(dp);
DBG(SCRIPT, ul_debugobj(dp, "reset"));
- fdisk_unref_table(dp->table);
- dp->table = NULL;
+
+ if (dp->table)
+ fdisk_reset_table(dp->table);
while (!list_empty(&dp->headers)) {
struct fdisk_scriptheader *fi = list_entry(dp->headers.next,
@@ -317,16 +334,58 @@ int fdisk_script_set_header(struct fdisk_script *dp,
* fdisk_script_get_table:
* @dp: script
*
- * The table (container with partitions) is possible to create by
- * fdisk_script_read_context() or fdisk_script_read_file(), otherwise
- * this function returns NULL.
+ * The table represents partitions holded by the script. The table is possible to
+ * fill by fdisk_script_read_context() or fdisk_script_read_file(). All the "read"
+ * functions remove old partitions from the table. See also fdisk_script_set_table().
*
- * Returns: NULL or script.
+ * Returns: NULL or script table.
*/
struct fdisk_table *fdisk_script_get_table(struct fdisk_script *dp)
{
assert(dp);
- return dp ? dp->table : NULL;
+
+ if (!dp->table)
+ /*
+ * Make sure user has access to the same table as script. If
+ * there is no table then create a new one and reuse it later.
+ */
+ dp->table = fdisk_new_table();
+
+ return dp->table;
+}
+
+/**
+ * fdisk_script_set_table:
+ * @dp: script
+ * @tb: table
+ *
+ * Replaces table used by script and creates a new reference to @tb. This
+ * function allows to generate a new script table independently on the current
+ * context and without any file reading.
+ *
+ * This is useful for example to create partition table with the same basic
+ * settings (e.g. label-id, ...) but with different partitions -- just call
+ * fdisk_script_read_context() to get current settings and then
+ * fdisk_script_set_table() to set a different layout.
+ *
+ * If @tb is NULL then the current script table is unreferenced.
+ *
+ * Note that script read_ functions (e.g. fdisk_script_read_context()) create
+ * always a new script table.
+ *
+ * Returns: 0 on success, <0 on error
+ */
+int fdisk_script_set_table(struct fdisk_script *dp, struct fdisk_table *tb)
+{
+ if (!dp)
+ return -EINVAL;
+
+ fdisk_ref_table(tb);
+ fdisk_unref_table(dp->table);
+ dp->table = tb;
+
+ DBG(SCRIPT, ul_debugobj(dp, "table replaced"));
+ return 0;
}
static struct fdisk_label *script_get_label(struct fdisk_script *dp)
@@ -377,7 +436,7 @@ int fdisk_script_has_force_label(struct fdisk_script *dp)
* @cxt: context
*
* Reads data from the @cxt context (on disk partition table) into the script.
- * If the context is no specified than defaults to context used for fdisk_new_script().
+ * If the context is not specified then defaults to context used for fdisk_new_script().
*
* Return: 0 on success, <0 on error.
*/
@@ -400,7 +459,7 @@ int fdisk_script_read_context(struct fdisk_script *dp, struct fdisk_context *cxt
if (!lb)
return -EINVAL;
- /* allocate and fill new table */
+ /* allocate (if not yet) and fill table */
rc = fdisk_get_partitions(cxt, &dp->table);
if (rc)
return rc;
@@ -542,7 +601,7 @@ static int write_file_json(struct fdisk_script *dp, FILE *f)
}
- if (!dp->table) {
+ if (!dp->table || fdisk_table_is_empty(dp->table)) {
DBG(SCRIPT, ul_debugobj(dp, "script table empty"));
goto done;
}
@@ -651,7 +710,7 @@ static int write_file_sfdisk(struct fdisk_script *dp, FILE *f)
devname = fi->data;
}
- if (!dp->table) {
+ if (!dp->table || fdisk_table_is_empty(dp->table)) {
DBG(SCRIPT, ul_debugobj(dp, "script table empty"));
return 0;
}
@@ -911,6 +970,7 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s)
assert(dp);
assert(s);
+ assert(dp->table);
DBG(SCRIPT, ul_debugobj(dp, " parse script line: '%s'", s));
@@ -996,8 +1056,11 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s)
rc = next_string(&p, &type);
if (rc)
break;
- pa->type = fdisk_label_parse_parttype(
- script_get_label(dp), type);
+
+ pa->type = translate_type_shortcuts(dp, type);
+ if (!pa->type)
+ pa->type = fdisk_label_parse_parttype(
+ script_get_label(dp), type);
free(type);
if (!pa->type) {
@@ -1106,6 +1169,7 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s)
assert(dp);
assert(s);
+ assert(dp->table);
pa = fdisk_new_partition();
if (!pa)
@@ -1240,11 +1304,8 @@ static int fdisk_script_read_buffer(struct fdisk_script *dp, char *s)
if (!s || !*s)
return 0; /* nothing baby, ignore */
- if (!dp->table) {
- dp->table = fdisk_new_table();
- if (!dp->table)
- return -ENOMEM;
- }
+ if (!dp->table && fdisk_script_get_table(dp) == NULL)
+ return -ENOMEM;
/* parse header lines only if no partition specified yet */
if (fdisk_table_is_empty(dp->table) && is_header_line(s))
@@ -1569,7 +1630,7 @@ static int test_stdin(struct fdisk_test *ts, int argc, char *argv[])
printf("<start>, <size>, <type>, <bootable: *|->\n");
do {
struct fdisk_partition *pa;
- size_t n = fdisk_table_get_nents(dp->table);
+ size_t n = dp->table ? fdisk_table_get_nents(dp->table) : 0;
printf(" #%zu :\n", n + 1);
rc = fdisk_script_read_line(dp, stdin, buf, sizeof(buf));
diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c
index 1f9d5a28a..8a3a935af 100644
--- a/libfdisk/src/table.c
+++ b/libfdisk/src/table.c
@@ -303,7 +303,7 @@ int fdisk_table_remove_partition(struct fdisk_table *tb, struct fdisk_partition
* @tb: returns table
*
* This function adds partitions from disklabel to @table, it allocates a new
- * table if if @table points to NULL.
+ * table if @table points to NULL.
*
* Returns: 0 on success, otherwise, a corresponding error.
*/
diff --git a/libmount/src/fs.c b/libmount/src/fs.c
index eb89bb8a3..4126ee9dc 100644
--- a/libmount/src/fs.c
+++ b/libmount/src/fs.c
@@ -188,9 +188,10 @@ struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest,
dest = mnt_new_fs();
if (!dest)
return NULL;
+
+ dest->tab = NULL;
}
- dest->tab = NULL;
dest->id = src->id;
dest->parent = src->parent;
dest->devno = src->devno;
diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c
index c0f438fe2..49fc9cc40 100644
--- a/libmount/src/optstr.c
+++ b/libmount/src/optstr.c
@@ -351,7 +351,9 @@ int mnt_optstr_deduplicate_option(char **optstr, const char *name)
end = ol.end;
opt = end && *end ? end + 1 : NULL;
}
- } while (rc == 0 && opt && *opt);
+ if (opt == NULL)
+ break;
+ } while (rc == 0 && *opt);
return rc < 0 ? rc : begin ? 0 : 1;
}
diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c
index 8e94715d2..2dfa6cbb4 100644
--- a/libmount/src/tab_parse.c
+++ b/libmount/src/tab_parse.c
@@ -154,7 +154,7 @@ static int mnt_parse_table_line(struct libmnt_fs *fs, const char *s)
if (!s || !*s)
goto done;
- /* (6) freq (optional) */
+ /* (6) passno (optional) */
s = next_s32(s, &fs->passno, &rc);
if (s && *s && rc) {
DBG(TAB, ul_debug("tab parse error: [passno]"));
diff --git a/libsmartcols/docs/libsmartcols-sections.txt b/libsmartcols/docs/libsmartcols-sections.txt
index 72c4ab866..4f3178b3a 100644
--- a/libsmartcols/docs/libsmartcols-sections.txt
+++ b/libsmartcols/docs/libsmartcols-sections.txt
@@ -132,6 +132,7 @@ scols_table_enable_export
scols_table_enable_header_repeat
scols_table_enable_json
scols_table_enable_maxout
+scols_table_enable_minout
scols_table_enable_noheadings
scols_table_enable_nolinesep
scols_table_enable_nowrap
@@ -155,6 +156,7 @@ scols_table_is_export
scols_table_is_header_repeat
scols_table_is_json
scols_table_is_maxout
+scols_table_is_minout
scols_table_is_noheadings
scols_table_is_noencoding
scols_table_is_nolinesep
@@ -165,6 +167,7 @@ scols_table_move_column
scols_table_new_column
scols_table_new_line
scols_table_next_column
+scols_table_set_columns_iter
scols_table_next_line
scols_table_reduce_termwidth
scols_table_remove_column
diff --git a/libsmartcols/samples/fromfile.c b/libsmartcols/samples/fromfile.c
index c1ab728fd..35d85489b 100644
--- a/libsmartcols/samples/fromfile.c
+++ b/libsmartcols/samples/fromfile.c
@@ -151,7 +151,8 @@ static int parse_column_data(FILE *f, struct libscols_table *tb, int col)
if (!ln)
break;
- scols_line_set_data(ln, col, str);
+ if (str && *str)
+ scols_line_set_data(ln, col, str);
}
free(str);
@@ -204,6 +205,7 @@ static void __attribute__((__noreturn__)) usage(void)
"\n %s [options] <column-data-file> ...\n\n", program_invocation_short_name);
fputs(" -m, --maxout fill all terminal width\n", out);
+ fputs(" -M, --minout minimize tailing padding\n", out);
fputs(" -c, --column <file> column definition\n", out);
fputs(" -n, --nlines <num> number of lines\n", out);
fputs(" -J, --json JSON output format\n", out);
@@ -227,6 +229,7 @@ int main(int argc, char *argv[])
static const struct option longopts[] = {
{ "maxout", 0, NULL, 'm' },
+ { "minout", 0, NULL, 'M' },
{ "column", 1, NULL, 'c' },
{ "nlines", 1, NULL, 'n' },
{ "width", 1, NULL, 'w' },
@@ -242,6 +245,7 @@ int main(int argc, char *argv[])
static const ul_excl_t excl[] = { /* rows and cols in ASCII order */
{ 'E', 'J', 'r' },
+ { 'M', 'm' },
{ 0 }
};
int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
@@ -253,7 +257,7 @@ int main(int argc, char *argv[])
if (!tb)
err(EXIT_FAILURE, "failed to create output table");
- while((c = getopt_long(argc, argv, "hCc:Ei:Jmn:p:rw:", longopts, NULL)) != -1) {
+ while((c = getopt_long(argc, argv, "hCc:Ei:JMmn:p:rw:", longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
@@ -285,6 +289,9 @@ int main(int argc, char *argv[])
case 'm':
scols_table_enable_maxout(tb, TRUE);
break;
+ case 'M':
+ scols_table_enable_minout(tb, TRUE);
+ break;
case 'r':
scols_table_enable_raw(tb, TRUE);
break;
diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in
index bd47f7898..d4be9969a 100644
--- a/libsmartcols/src/libsmartcols.h.in
+++ b/libsmartcols/src/libsmartcols.h.in
@@ -243,6 +243,7 @@ extern int scols_table_is_header_repeat(const struct libscols_table *tb);
extern int scols_table_is_empty(const struct libscols_table *tb);
extern int scols_table_is_export(const struct libscols_table *tb);
extern int scols_table_is_maxout(const struct libscols_table *tb);
+extern int scols_table_is_minout(const struct libscols_table *tb);
extern int scols_table_is_nowrap(const struct libscols_table *tb);
extern int scols_table_is_nolinesep(const struct libscols_table *tb);
extern int scols_table_is_tree(const struct libscols_table *tb);
@@ -256,6 +257,7 @@ extern int scols_table_enable_noheadings(struct libscols_table *tb, int enable);
extern int scols_table_enable_header_repeat(struct libscols_table *tb, int enable);
extern int scols_table_enable_export(struct libscols_table *tb, int enable);
extern int scols_table_enable_maxout(struct libscols_table *tb, int enable);
+extern int scols_table_enable_minout(struct libscols_table *tb, int enable);
extern int scols_table_enable_nowrap(struct libscols_table *tb, int enable);
extern int scols_table_enable_nolinesep(struct libscols_table *tb, int enable);
extern int scols_table_enable_noencoding(struct libscols_table *tb, int enable);
@@ -272,6 +274,7 @@ extern int scols_table_remove_columns(struct libscols_table *tb);
extern int scols_table_move_column(struct libscols_table *tb, struct libscols_column *pre, struct libscols_column *cl);
extern struct libscols_column *scols_table_new_column(struct libscols_table *tb, const char *name, double whint, int flags);
extern int scols_table_next_column(struct libscols_table *tb, struct libscols_iter *itr, struct libscols_column **cl);
+extern int scols_table_set_columns_iter(struct libscols_table *tb, struct libscols_iter *itr, struct libscols_column *cl);
extern const char *scols_table_get_column_separator(const struct libscols_table *tb);
extern const char *scols_table_get_line_separator(const struct libscols_table *tb);
extern size_t scols_table_get_ncols(const struct libscols_table *tb);
diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym
index e318c9054..99353be80 100644
--- a/libsmartcols/src/libsmartcols.sym
+++ b/libsmartcols/src/libsmartcols.sym
@@ -194,3 +194,9 @@ SMARTCOLS_2.34 {
scols_symbols_set_group_last_child;
scols_symbols_set_group_middle_child;
} SMARTCOLS_2.33;
+
+SMARTCOLS_2.35 {
+ scols_table_enable_minout;
+ scols_table_is_minout;
+ scols_table_set_columns_iter;
+} SMARTCOLS_2.34;
diff --git a/libsmartcols/src/print.c b/libsmartcols/src/print.c
index 986af153c..c92154219 100644
--- a/libsmartcols/src/print.c
+++ b/libsmartcols/src/print.c
@@ -50,6 +50,43 @@
#define want_repeat_header(tb) (!(tb)->header_repeat || (tb)->header_next <= (tb)->termlines_used)
+static int is_next_columns_empty(
+ struct libscols_table *tb,
+ struct libscols_column *cl,
+ struct libscols_line *ln)
+{
+ struct libscols_iter itr;
+
+ if (!tb || !cl)
+ return 0;
+ if (is_last_column(cl))
+ return 1;
+ if (!ln)
+ return 0;
+
+ scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
+ scols_table_set_columns_iter(tb, &itr, cl);
+
+ /* skip current column */
+ scols_table_next_column(tb, &itr, &cl);
+
+ while (scols_table_next_column(tb, &itr, &cl) == 0) {
+ struct libscols_cell *ce;
+ const char *data = NULL;
+
+ if (scols_column_is_hidden(cl))
+ continue;
+ if (scols_column_is_tree(cl))
+ return 0;
+
+ ce = scols_line_get_cell(ln, cl->seqnum);
+ if (ce)
+ data = scols_cell_get_data(ce);
+ if (data && *data)
+ return 0;
+ }
+ return 1;
+}
/* returns pointer to the end of used data */
static int tree_ascii_art_to_buffer(struct libscols_table *tb,
@@ -216,14 +253,20 @@ static void print_empty_cell(struct libscols_table *tb,
}
}
- if (is_last_column(cl))
+ /* minout -- don't fill */
+ if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln))
+ return;
+
+ /* default -- fill except last column */
+ if (!scols_table_is_maxout(tb) && is_last_column(cl))
return;
/* fill rest of cell with space */
for(; len_pad < cl->width; ++len_pad)
fputs(cellpadding_symbol(tb), tb->out);
- fputs(colsep(tb), tb->out);
+ if (!is_last_column(cl))
+ fputs(colsep(tb), tb->out);
}
@@ -367,13 +410,21 @@ static int print_pending_data(
fputs(UL_COLOR_RESET, tb->out);
free(data);
- if (is_last_column(cl))
+ /* minout -- don't fill */
+ if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln))
return 0;
- for (i = len; i < width; i++)
- fputs(cellpadding_symbol(tb), tb->out); /* padding */
+ /* default -- fill except last column */
+ if (!scols_table_is_maxout(tb) && is_last_column(cl))
+ return 0;
+
+ /* fill rest of cell with space */
+ for(i = len; i < width; i++)
+ fputs(cellpadding_symbol(tb), tb->out);
+
+ if (!is_last_column(cl))
+ fputs(colsep(tb), tb->out);
- fputs(colsep(tb), tb->out); /* columns separator */
return 0;
err:
free(data);
@@ -491,7 +542,7 @@ static int print_data(struct libscols_table *tb,
data = NULL;
}
- if (data) {
+ if (data && *data) {
if (scols_column_is_right(cl)) {
if (color)
fputs(color, tb->out);
@@ -518,16 +569,24 @@ static int print_data(struct libscols_table *tb,
} else
fputs(data, tb->out);
}
- for (i = len; i < width; i++)
- fputs(cellpadding_symbol(tb), tb->out); /* padding */
- if (is_last)
+ /* minout -- don't fill */
+ if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln))
return 0;
+ /* default -- fill except last column */
+ if (!scols_table_is_maxout(tb) && is_last)
+ return 0;
+
+ /* fill rest of cell with space */
+ for(i = len; i < width; i++)
+ fputs(cellpadding_symbol(tb), tb->out);
+
if (len > width && !scols_column_is_trunc(cl)) {
DBG(COL, ul_debugobj(cl, "*** data len=%zu > column width=%zu", len, width));
print_newline_padding(tb, cl, ln, buffer_get_size(buf)); /* next column starts on next line */
- } else
+
+ } else if (!is_last)
fputs(colsep(tb), tb->out); /* columns separator */
return 0;
diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h
index 3653eda07..e745a05a4 100644
--- a/libsmartcols/src/smartcolsP.h
+++ b/libsmartcols/src/smartcolsP.h
@@ -238,6 +238,7 @@ struct libscols_table {
padding_debug :1, /* output visible padding chars */
is_dummy_print :1, /* printing used for width calcualion only */
maxout :1, /* maximize output */
+ minout :1, /* minimize output (mutually exclusive to maxout) */
header_repeat :1, /* print header after libscols_table->termheight */
header_printed :1, /* header already printed */
priv_symbols :1, /* default private symbols */
diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c
index 944c1e593..e14c82b1b 100644
--- a/libsmartcols/src/table.c
+++ b/libsmartcols/src/table.c
@@ -475,6 +475,33 @@ int scols_table_next_column(struct libscols_table *tb,
}
/**
+ * scols_table_set_columns_iter:
+ * @tb: tab pointer
+ * @itr: iterator
+ * @cl: tab entry
+ *
+ * Sets @iter to the position of @cl in the file @tb.
+ *
+ * Returns: 0 on success, negative number in case of error.
+ */
+int scols_table_set_columns_iter(
+ struct libscols_table *tb,
+ struct libscols_iter *itr,
+ struct libscols_column *cl)
+{
+ if (!tb || !itr || !cl)
+ return -EINVAL;
+
+ if (cl->table != tb)
+ return -EINVAL;
+
+ SCOLS_ITER_INIT(itr, &tb->tb_columns);
+ itr->p = &cl->cl_columns;
+
+ return 0;
+}
+
+/**
* scols_table_get_ncols:
* @tb: table
*
@@ -1133,20 +1160,46 @@ int scols_table_enable_header_repeat(struct libscols_table *tb, int enable)
* @enable: 1 or 0
*
* The extra space after last column is ignored by default. The output
- * maximization use the extra space for all columns.
+ * maximization add padding for all columns.
+ *
+ * This setting is mutually exclusive to cols_table_enable_minout().
*
* Returns: 0 on success, negative number in case of an error.
*/
int scols_table_enable_maxout(struct libscols_table *tb, int enable)
{
- if (!tb)
+ if (!tb || tb->minout)
return -EINVAL;
+
DBG(TAB, ul_debugobj(tb, "maxout: %s", enable ? "ENABLE" : "DISABLE"));
tb->maxout = enable ? 1 : 0;
return 0;
}
/**
+ * scols_table_enable_minout:
+ * @tb: table
+ * @enable: 1 or 0
+ *
+ * Force library to terminate line after last column with data. The extra
+ * padding is not added to the empty cells at the end of the line. The default is fill
+ * tailing empty cells except the last line cell.
+ *
+ * This setting is mutually exclusive to cols_table_enable_maxout().
+ *
+ * Returns: 0 on success, negative number in case of an error.
+ */
+int scols_table_enable_minout(struct libscols_table *tb, int enable)
+{
+ if (!tb || tb->maxout)
+ return -EINVAL;
+
+ DBG(TAB, ul_debugobj(tb, "minout: %s", enable ? "ENABLE" : "DISABLE"));
+ tb->minout = enable ? 1 : 0;
+ return 0;
+}
+
+/**
* scols_table_enable_nowrap:
* @tb: table
* @enable: 1 or 0
@@ -1316,6 +1369,17 @@ int scols_table_is_maxout(const struct libscols_table *tb)
}
/**
+ * scols_table_is_minout
+ * @tb: table
+ *
+ * Returns: 1 if output minimization is enabled or 0
+ */
+int scols_table_is_minout(const struct libscols_table *tb)
+{
+ return tb->minout;
+}
+
+/**
* scols_table_is_tree:
* @tb: table
*
diff --git a/login-utils/chfn.c b/login-utils/chfn.c
index a2e6e099e..b7395552b 100644
--- a/login-utils/chfn.c
+++ b/login-utils/chfn.c
@@ -376,7 +376,7 @@ static int save_new_data(struct chfn_control *ctl)
ctl->newf.other);
/* remove trailing empty fields (but not subfields of ctl->newf.other) */
- if (!ctl->newf.other) {
+ if (!ctl->newf.other || !*ctl->newf.other) {
while (len > 0 && gecos[len - 1] == ',')
len--;
gecos[len] = 0;
diff --git a/login-utils/last.c b/login-utils/last.c
index 2f7d9d48f..1b1a74191 100644
--- a/login-utils/last.c
+++ b/login-utils/last.c
@@ -394,8 +394,7 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
/*
* uucp and ftp have special-type entries
*/
- utline[0] = 0;
- strncat(utline, p->ut_line, sizeof(utline) - 1);
+ mem2strcpy(utline, p->ut_line, sizeof(p->ut_line), sizeof(utline));
if (strncmp(utline, "ftp", 3) == 0 && isdigit(utline[3]))
utline[3] = 0;
if (strncmp(utline, "uucp", 4) == 0 && isdigit(utline[4]))
diff --git a/login-utils/login.c b/login-utils/login.c
index ce112b54e..6b9d27e3e 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -1355,10 +1355,7 @@ int main(int argc, char **argv)
/* if the shell field has a space: treat it like a shell script */
if (strchr(pwd->pw_shell, ' ')) {
- buff = xmalloc(strlen(pwd->pw_shell) + 6);
-
- strcpy(buff, "exec ");
- strcat(buff, pwd->pw_shell);
+ xasprintf(&buff, "exec %s", pwd->pw_shell);
childArgv[childArgc++] = "/bin/sh";
childArgv[childArgc++] = "-sh";
childArgv[childArgc++] = "-c";
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
index caabe23a6..4d91b22e4 100644
--- a/login-utils/su-common.c
+++ b/login-utils/su-common.c
@@ -1446,7 +1446,9 @@ int su_main(int argc, char **argv, int mode)
|| !su->pwd->pw_passwd
|| !su->pwd->pw_name || !*su->pwd->pw_name
|| !su->pwd->pw_dir || !*su->pwd->pw_dir)
- errx(EXIT_FAILURE, _("user %s does not exist"), su->new_user);
+ errx(EXIT_FAILURE,
+ _("user %s does not exist or the user entry does not "
+ "contain all the required fields"), su->new_user);
su->new_user = su->pwd->pw_name;
su->old_user = xgetlogin();
diff --git a/m4/ul.m4 b/m4/ul.m4
index 9b3e73d22..e32af44a3 100644
--- a/m4/ul.m4
+++ b/m4/ul.m4
@@ -208,6 +208,46 @@ AC_DEFUN([UL_EXCLUDE_ARCH], [
fi
])
+
+
+dnl UL_REQUIRES_ARCH(NAME, ARCH, [VARSUFFIX = $1])
+dnl
+dnl Modifies $build_<name> variable according to $enable_<name> and $host. The
+dnl $enable_<name> could be "yes", "no" and "check". If build_<name> is "no" then
+dnl all checks are skiped.
+dnl
+dnl The <arch> maybe a list, then at least one of the patterns in the list
+dnl have to match.
+dnl
+dnl The default <name> for $build_ and $enable_ could be overwrited by option $3.
+dnl
+AC_DEFUN([UL_REQUIRES_ARCH], [
+ m4_define([suffix], m4_default([$3],$1))
+ if test "x$[build_]suffix" != xno; then
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ [ul_archone_]suffix=no
+ m4_foreach([onearch], [$2], [
+ case "$host" in #(
+ onearch)
+ [ul_archone_]suffix=yes ;;
+ esac
+ ])dnl
+ case $[enable_]suffix:$[ul_archone_]suffix in #(
+ no:*)
+ [build_]suffix=no ;;
+ yes:no)
+ AC_MSG_ERROR([$1 selected for unsupported architecture]);;
+ yes:*)
+ [build_]suffix=yes ;;
+ check:no)
+ AC_MSG_WARN([excluded for $host architecture; not building $1])
+ [build_]suffix=no ;;
+ check:*)
+ [build_]suffix=yes ;;
+ esac
+ fi
+])
+
dnl UL_REQUIRES_HAVE(NAME, HAVENAME, HAVEDESC, [VARSUFFIX=$1])
dnl
dnl Modifies $build_<name> variable according to $enable_<name> and
@@ -248,7 +288,7 @@ AC_DEFUN([UL_REQUIRES_HAVE], [
fi
])
-dnl UL_REQUIRES_HAVE(NAME, PROGRAM_PROLOGUE, PROGRAM_BODY, DESC, [VARSUFFIX=$1])
+dnl UL_REQUIRES_COMPILE(NAME, PROGRAM_PROLOGUE, PROGRAM_BODY, DESC, [VARSUFFIX=$1])
dnl
dnl Modifies $build_<name> variable according to $enable_<name> and
dnl ability compile AC_LANG_PROGRAM(<program_prologue>, <program_body>).
diff --git a/misc-utils/lsblk-devtree.c b/misc-utils/lsblk-devtree.c
index a2aa26aed..4d15f70c1 100644
--- a/misc-utils/lsblk-devtree.c
+++ b/misc-utils/lsblk-devtree.c
@@ -384,6 +384,7 @@ static int device_dedupkey_is_equal(
return 0;
if (strcmp(dev->dedupkey, pattern->dedupkey) == 0) {
if (!device_is_partition(dev) ||
+ !dev->wholedisk->dedupkey ||
strcmp(dev->dedupkey, dev->wholedisk->dedupkey) != 0) {
DBG(DEV, ul_debugobj(dev, "%s: match deduplication pattern", dev->name));
return 1;
@@ -458,6 +459,7 @@ int lsblk_devtree_deduplicate_devices(struct lsblk_devtree *tr)
if (!pattern->dedupkey)
continue;
if (device_is_partition(pattern) &&
+ pattern->wholedisk->dedupkey &&
strcmp(pattern->dedupkey, pattern->wholedisk->dedupkey) == 0)
continue;
if (last && strcmp(pattern->dedupkey, last) == 0)
diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c
index e95af7af0..7ab9dc23c 100644
--- a/misc-utils/lsblk.c
+++ b/misc-utils/lsblk.c
@@ -774,8 +774,14 @@ static char *device_get_data(
str = get_vfs_attribute(dev, id);
break;
case COL_TARGET:
- str = xstrdup(lsblk_device_get_mountpoint(dev));
+ {
+ char *s = lsblk_device_get_mountpoint(dev);
+ if (s)
+ str = xstrdup(s);
+ else
+ str = NULL;
break;
+ }
case COL_LABEL:
prop = lsblk_device_get_properties(dev);
if (prop && prop->label)
@@ -1019,6 +1025,9 @@ static void device_to_scols(
DBG(DEV, ul_debugobj(dev, "add '%s' to scols", dev->name));
ON_DBG(DEV, if (ul_path_isopen_dirfd(dev->sysfs)) ul_debugobj(dev, " %s ---> is open!", dev->name));
+ if (!parent && dev->wholedisk)
+ parent = dev->wholedisk;
+
/* Do not print device more than one in --list mode */
if (!(lsblk->flags & LSBLK_TREE) && dev->is_printed)
return;
diff --git a/po/cs.po b/po/cs.po
index 35f6f97c9..9c5f0059c 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -14802,7 +14802,7 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <počet> omezí zařízení na <počet> bajtů souboru\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
msgstr " -b, --sector-size <číslo> nastaví velikost logického sektoru na <číslo>\n"
#: sys-utils/losetup.c:423
diff --git a/po/da.po b/po/da.po
index baf6b4577..24c6ec5ed 100644
--- a/po/da.po
+++ b/po/da.po
@@ -14702,7 +14702,7 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <num> enhed er begrænset til <num> byte af filen\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
msgstr " -b, --sector-size <num> angiv den logiske sektorstørrelse til <num>\n"
#: sys-utils/losetup.c:423
diff --git a/po/de.po b/po/de.po
index c135ce828..ef24a1da4 100644
--- a/po/de.po
+++ b/po/de.po
@@ -14835,8 +14835,8 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <Zahl> das Gerät ist auf <Zahl> Bytes der Datei beschränkt\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
-msgstr " -b --sector-size <Zahl> die logische Sekttorgröße auf <Zahl> setzen\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
+msgstr " -b, --sector-size <Zahl> die logische Sekttorgröße auf <Zahl> setzen\n"
#: sys-utils/losetup.c:423
msgid " -P, --partscan create a partitioned loop device\n"
diff --git a/po/es.po b/po/es.po
index 05e565bbb..7f1e115c0 100644
--- a/po/es.po
+++ b/po/es.po
@@ -14577,7 +14577,7 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <núm> el dispositivo está limitado a <núm> bytes del fichero\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
msgstr " -b, --sector-size <núm> establece el tamaño de sector lógico en <núm>\n"
#: sys-utils/losetup.c:423
diff --git a/po/fr.po b/po/fr.po
index b9fc060b8..f6b696d87 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -14630,7 +14630,7 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <nombre> périphérique limité à <nombre> octets du fichier\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
msgstr " -b, --sector-size <taille> définir la taille de secteur logique à <taille>\n"
#: sys-utils/losetup.c:423
diff --git a/po/hr.po b/po/hr.po
index 74ad956be..3e1db42b6 100644
--- a/po/hr.po
+++ b/po/hr.po
@@ -14752,8 +14752,8 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <broj> koristi samo taj broj bajtova datoteke\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
-msgstr " -b --sector-size <broj> veličinu logičkog sektora postavi na taj broj\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
+msgstr " -b, --sector-size <broj> veličinu logičkog sektora postavi na taj broj\n"
#: sys-utils/losetup.c:423
msgid " -P, --partscan create a partitioned loop device\n"
diff --git a/po/pl.po b/po/pl.po
index 11c53922b..2b8f631b5 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -14576,7 +14576,7 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <ile> ograniczenie do podanej liczby bajtów pliku\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
msgstr " -b, --sector-size <ile> ustawienie rozmiaru sektora logicznego\n"
#: sys-utils/losetup.c:423
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 17120cbc3..503cd8c2a 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -14721,8 +14721,8 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <núm> dispositivo limitado a <núm> bytes do arquivo\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
-msgstr " -b --sector-size <núm> define o tamanho de setor lógico para <núm>\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
+msgstr " -b, --sector-size <núm> define o tamanho de setor lógico para <núm>\n"
#: sys-utils/losetup.c:423
msgid " -P, --partscan create a partitioned loop device\n"
diff --git a/po/sv.po b/po/sv.po
index b7de28cdc..31c8c06cc 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -14550,7 +14550,7 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <num> enhet är begränsad till <num> byte i filen\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
msgstr " -b, --sector-size <storlek> ställ in logisk sektorstorlek\n"
#: sys-utils/losetup.c:423
diff --git a/po/uk.po b/po/uk.po
index b13910ba9..c814a5f44 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -14591,8 +14591,8 @@ msgid " --sizelimit <num> device is limited to <num> bytes of the fi
msgstr " --sizelimit <n> пристрій обмежено <n> байтами файла\n"
#: sys-utils/losetup.c:422
-msgid " -b --sector-size <num> set the logical sector size to <num>\n"
-msgstr " -b --sector-size <число> встановити для логічного сектора розмір <число>\n"
+msgid " -b, --sector-size <num> set the logical sector size to <num>\n"
+msgstr " -b, --sector-size <число> встановити для логічного сектора розмір <число>\n"
#: sys-utils/losetup.c:423
msgid " -P, --partscan create a partitioned loop device\n"
diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index 7c118a6de..98e2cc29b 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -451,9 +451,12 @@ dist_man_MANS += \
PATHFILES += sys-utils/hwclock.8
hwclock_SOURCES = \
sys-utils/hwclock.c \
- sys-utils/hwclock.h \
- sys-utils/hwclock-cmos.c
+ sys-utils/hwclock.h
hwclock_LDADD = $(LDADD) libcommon.la -lm
+if USE_HWCLOCK_CMOS
+hwclock_SOURCES += \
+ sys-utils/hwclock-cmos.c
+endif
if LINUX
hwclock_SOURCES += \
sys-utils/hwclock-rtc.c \
diff --git a/sys-utils/choom.1 b/sys-utils/choom.1
index 2b844cbe2..def31d5f0 100644
--- a/sys-utils/choom.1
+++ b/sys-utils/choom.1
@@ -15,6 +15,7 @@ choom \- display and adjust OOM-killer score.
.B choom
.B \-n
.I number
+.B [\-\-]
.IR command\ [ argument ...]
.SH DESCRIPTION
diff --git a/sys-utils/choom.c b/sys-utils/choom.c
index 1096ab186..b3d3e4d91 100644
--- a/sys-utils/choom.c
+++ b/sys-utils/choom.c
@@ -37,7 +37,7 @@ static void __attribute__((__noreturn__)) usage(void)
fprintf(out,
_(" %1$s [options] -p pid\n"
" %1$s [options] -n number -p pid\n"
- " %1$s [options] -n number command [args...]]\n"),
+ " %1$s [options] -n number [--] command [args...]]\n"),
program_invocation_short_name);
fputs(USAGE_SEPARATOR, out);
diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c
index f0b9b7137..9f2e5b804 100644
--- a/sys-utils/dmesg.c
+++ b/sys-utils/dmesg.c
@@ -637,25 +637,29 @@ static void safe_fwrite(const char *buf, size_t size, int indent, FILE *out)
if (len == (size_t)-1 || len == (size_t)-2) { /* invalid sequence */
memset(&s, 0, sizeof (s));
len = hex = 1;
- } else if (len > 1 && !iswprint(wc)) { /* non-printable multibyte */
- hex = 1;
- }
- i += len - 1;
-#else
- len = 1;
- if (!isprint((unsigned char) *p) &&
- !isspace((unsigned char) *p)) /* non-printable */
- hex = 1;
+ i += len - 1;
+ } else if (len > 1) {
+ if (!iswprint(wc) && !iswspace(wc)) /* non-printable multibyte */
+ hex = 1;
+ i += len - 1;
+ } else
#endif
+ {
+ len = 1;
+ if (!isprint((unsigned char) *p) &&
+ !isspace((unsigned char) *p)) /* non-printable */
+ hex = 1;
+ }
+
if (hex)
rc = fwrite_hex(p, len, out);
else if (*p == '\n' && *(p + 1) && indent) {
rc = fwrite(p, 1, len, out) != len;
if (fprintf(out, "%*s", indent, "") != indent)
rc |= 1;
- }
- else
+ } else
rc = fwrite(p, 1, len, out) != len;
+
if (rc != 0) {
if (errno != EPIPE)
err(EXIT_FAILURE, _("write failed"));
diff --git a/sys-utils/fsfreeze.c b/sys-utils/fsfreeze.c
index 4da1a6fa3..6035a1010 100644
--- a/sys-utils/fsfreeze.c
+++ b/sys-utils/fsfreeze.c
@@ -77,7 +77,7 @@ int main(int argc, char **argv)
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ close_stdout_atexit();
while ((c = getopt_long(argc, argv, "hfuV", longopts, NULL)) != -1) {
diff --git a/sys-utils/fstrim.service.in b/sys-utils/fstrim.service.in
index 516023ed8..2a8dc1d3a 100644
--- a/sys-utils/fstrim.service.in
+++ b/sys-utils/fstrim.service.in
@@ -6,7 +6,7 @@ Documentation=man:fstrim(8)
Type=oneshot
ExecStart=@sbindir@/fstrim --fstab --verbose --quiet
ProtectSystem=strict
-ProtectHome=yes
+ProtectHome=read-only
PrivateDevices=no
PrivateNetwork=yes
PrivateUsers=no
diff --git a/sys-utils/hwclock-cmos.c b/sys-utils/hwclock-cmos.c
index a11f676b8..4d3e023d9 100644
--- a/sys-utils/hwclock-cmos.c
+++ b/sys-utils/hwclock-cmos.c
@@ -56,37 +56,13 @@
#include "pathnames.h"
/* for inb, outb */
-#if defined(__i386__) || defined(__x86_64__)
-# ifdef HAVE_SYS_IO_H
-# include <sys/io.h>
-# elif defined(HAVE_ASM_IO_H)
-# include <asm/io.h>
-# else
-# undef __i386__
-# undef __x86_64__
-# warning "disable cmos access - no sys/io.h or asm/io.h"
-static void outb(int a __attribute__((__unused__)),
- int b __attribute__((__unused__)))
-{
-}
-
-static int inb(int c __attribute__((__unused__)))
-{
- return 0;
-}
-# endif /* __i386__ __x86_64__ */
+#ifdef HAVE_SYS_IO_H
+# include <sys/io.h>
+#elif defined(HAVE_ASM_IO_H)
+# include <asm/io.h>
#else
-# warning "disable cmos access - not i386 or x86_64"
-static void outb(int a __attribute__((__unused__)),
- int b __attribute__((__unused__)))
-{
-}
-
-static int inb(int c __attribute__((__unused__)))
-{
- return 0;
-}
-#endif /* for inb, outb */
+# error "no sys/io.h or asm/io.h"
+#endif /* HAVE_SYS_IO_H, HAVE_ASM_IO_H */
#include "hwclock.h"
@@ -360,7 +336,6 @@ static int set_hardware_clock_cmos(const struct hwclock_control *ctl
return 0;
}
-#if defined(__i386__) || defined(__x86_64__)
# if defined(HAVE_IOPL)
static int i386_iopl(const int level)
{
@@ -373,12 +348,6 @@ static int i386_iopl(const int level __attribute__ ((__unused__)))
return ioperm(clock_ctl_addr, 2, 1);
}
# endif
-#else
-static int i386_iopl(const int level __attribute__ ((__unused__)))
-{
- return IOPL_NOT_IMPLEMENTED;
-}
-#endif
static int get_permissions_cmos(void)
{
@@ -412,9 +381,5 @@ static struct clock_ops cmos_interface = {
*/
struct clock_ops *probe_for_cmos_clock(void)
{
-#if defined(__i386__) || defined(__x86_64__)
return &cmos_interface;
-#else
- return NULL;
-#endif
}
diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c
index a2c5cc2a4..c01a86826 100644
--- a/sys-utils/hwclock.c
+++ b/sys-utils/hwclock.c
@@ -925,8 +925,10 @@ static void determine_clock_access_method(const struct hwclock_control *ctl)
{
ur = NULL;
+#ifdef USE_HWCLOCK_CMOS
if (ctl->directisa)
ur = probe_for_cmos_clock();
+#endif
#ifdef __linux__
if (!ur)
ur = probe_for_rtc_clock(ctl);
diff --git a/sys-utils/ldattach.c b/sys-utils/ldattach.c
index 3019e5a9f..c2d2f8397 100644
--- a/sys-utils/ldattach.c
+++ b/sys-utils/ldattach.c
@@ -314,7 +314,7 @@ int main(int argc, char **argv)
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ close_stdout_atexit();
/* parse options */
if (argc == 0)
diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c
index f455b49c3..5e5ce9e28 100644
--- a/sys-utils/losetup.c
+++ b/sys-utils/losetup.c
@@ -434,7 +434,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(USAGE_SEPARATOR, out);
fputs(_(" -o, --offset <num> start at offset <num> into file\n"), out);
fputs(_(" --sizelimit <num> device is limited to <num> bytes of the file\n"), out);
- fputs(_(" -b --sector-size <num> set the logical sector size to <num>\n"), out);
+ fputs(_(" -b, --sector-size <num> set the logical sector size to <num>\n"), out);
fputs(_(" -P, --partscan create a partitioned loop device\n"), out);
fputs(_(" -r, --read-only set up a read-only loop device\n"), out);
fputs(_(" --direct-io[=<on|off>] open backing file with O_DIRECT\n"), out);
@@ -667,7 +667,7 @@ int main(int argc, char **argv)
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ close_stdout_atexit();
if (loopcxt_init(&lc, 0))
err(EXIT_FAILURE, _("failed to initialize loopcxt"));
diff --git a/sys-utils/lscpu-dmi.c b/sys-utils/lscpu-dmi.c
index 29bd2e4fc..82d8ed443 100644
--- a/sys-utils/lscpu-dmi.c
+++ b/sys-utils/lscpu-dmi.c
@@ -80,7 +80,7 @@ static void to_dmi_header(struct dmi_header *h, uint8_t *data)
{
h->type = data[0];
h->length = data[1];
- h->handle = WORD(data + 2);
+ memcpy(&h->handle, data + 2, sizeof(h->handle));
h->data = data;
}
diff --git a/sys-utils/lscpu.1 b/sys-utils/lscpu.1
index e82fa4320..cd509f72b 100644
--- a/sys-utils/lscpu.1
+++ b/sys-utils/lscpu.1
@@ -33,6 +33,11 @@ specified, \fBlscpu\fP prints the column but does not provide any data for it.
The default output formatting on terminal maybe optimized for better
readability. The output for non-terminals (e.g. pipes) is never affected by
this optimization and it is always in "Field: data\\n" format.
+.sp
+The cache sizes are reported as summary from all CPUs. The versions before
+v2.34 reported per-core sizes, but this output was confusing due to complicated
+CPUs topology and the way how caches are shared between CPUs. For more details
+about caches see \fB\-\-cache\fP.
.SS COLUMNS
Note that topology elements (core, socket, etc.) use a sequential unique ID
starting from zero, but CPU logical numbers follow the kernel where there is
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
index 0e775805e..4f1ab47e9 100644
--- a/sys-utils/lscpu.c
+++ b/sys-utils/lscpu.c
@@ -178,6 +178,11 @@ enum {
COL_CACHE_ONESIZE,
COL_CACHE_TYPE,
COL_CACHE_WAYS,
+ COL_CACHE_ALLOCPOL,
+ COL_CACHE_WRITEPOL,
+ COL_CACHE_PHYLINE,
+ COL_CACHE_SETS,
+ COL_CACHE_COHERENCYSIZE
};
@@ -215,7 +220,12 @@ static struct lscpu_coldesc coldescs_cache[] =
[COL_CACHE_NAME] = { "NAME", N_("cache name") },
[COL_CACHE_ONESIZE] = { "ONE-SIZE", N_("size of one cache"), SCOLS_FL_RIGHT },
[COL_CACHE_TYPE] = { "TYPE", N_("cache type") },
- [COL_CACHE_WAYS] = { "WAYS", N_("ways of associativity"), SCOLS_FL_RIGHT }
+ [COL_CACHE_WAYS] = { "WAYS", N_("ways of associativity"), SCOLS_FL_RIGHT },
+ [COL_CACHE_ALLOCPOL] = { "ALLOC-POLICY", N_("allocation policy") },
+ [COL_CACHE_WRITEPOL] = { "WRITE-POLICY", N_("write policy") },
+ [COL_CACHE_PHYLINE] = { "PHY-LINE", N_("number of physical cache line per cache t"), SCOLS_FL_RIGHT },
+ [COL_CACHE_SETS] = { "SETS", N_("number of sets in the cache; set lines has the same cache index"), SCOLS_FL_RIGHT },
+ [COL_CACHE_COHERENCYSIZE] = { "COHERENCY-SIZE", N_("minimum amount of data in bytes transferred from memory to cache"), SCOLS_FL_RIGHT }
};
@@ -1354,9 +1364,19 @@ read_cache(struct lscpu_desc *desc, int idx)
ca->name = xstrdup(buf);
- /* cache ways */
- ul_path_readf_s32(desc->syscpu, &ca->ways,
+ ul_path_readf_u32(desc->syscpu, &ca->ways_of_associativity,
"cpu%d/cache/index%d/ways_of_associativity", num, i);
+ ul_path_readf_u32(desc->syscpu, &ca->physical_line_partition,
+ "cpu%d/cache/index%d/physical_line_partition", num, i);
+ ul_path_readf_u32(desc->syscpu, &ca->number_of_sets,
+ "cpu%d/cache/index%d/number_of_sets", num, i);
+ ul_path_readf_u32(desc->syscpu, &ca->coherency_line_size,
+ "cpu%d/cache/index%d/coherency_line_size", num, i);
+
+ ul_path_readf_string(desc->syscpu, &ca->allocation_policy,
+ "cpu%d/cache/index%d/allocation_policy", num, i);
+ ul_path_readf_string(desc->syscpu, &ca->write_policy,
+ "cpu%d/cache/index%d/write_policy", num, i);
/* cache size */
if (ul_path_readf_buffer(desc->syscpu, buf, sizeof(buf),
@@ -1682,9 +1702,10 @@ print_caches_readable(struct lscpu_desc *desc, int cols[], int ncols,
break;
}
case COL_CACHE_WAYS:
- if (ca->ways)
- xasprintf(&data, "%d", ca->ways);
+ if (ca->ways_of_associativity)
+ xasprintf(&data, "%u", ca->ways_of_associativity);
break;
+
case COL_CACHE_TYPE:
if (ca->type)
data = xstrdup(ca->type);
@@ -1693,6 +1714,26 @@ print_caches_readable(struct lscpu_desc *desc, int cols[], int ncols,
if (ca->level)
xasprintf(&data, "%d", ca->level);
break;
+ case COL_CACHE_ALLOCPOL:
+ if (ca->allocation_policy)
+ data = xstrdup(ca->allocation_policy);
+ break;
+ case COL_CACHE_WRITEPOL:
+ if (ca->write_policy)
+ data = xstrdup(ca->write_policy);
+ break;
+ case COL_CACHE_PHYLINE:
+ if (ca->physical_line_partition)
+ xasprintf(&data, "%u", ca->physical_line_partition);
+ break;
+ case COL_CACHE_SETS:
+ if (ca->number_of_sets)
+ xasprintf(&data, "%u", ca->number_of_sets);
+ break;
+ case COL_CACHE_COHERENCYSIZE:
+ if (ca->coherency_line_size)
+ xasprintf(&data, "%u", ca->coherency_line_size);
+ break;
}
if (data && scols_line_refer_data(line, c, data))
@@ -2255,7 +2296,7 @@ int main(int argc, char *argv[])
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ close_stdout_atexit();
while ((c = getopt_long(argc, argv, "aBbC::ce::hJp::s:xyV", longopts, NULL)) != -1) {
@@ -2414,6 +2455,9 @@ int main(int argc, char *argv[])
columns[ncolumns++] = COL_CACHE_WAYS;
columns[ncolumns++] = COL_CACHE_TYPE;
columns[ncolumns++] = COL_CACHE_LEVEL;
+ columns[ncolumns++] = COL_CACHE_SETS;
+ columns[ncolumns++] = COL_CACHE_PHYLINE;
+ columns[ncolumns++] = COL_CACHE_COHERENCYSIZE;
}
print_caches_readable(desc, columns, ncolumns, mod);
break;
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 56c97e2e8..5bbdb348e 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -49,10 +49,17 @@ enum {
struct cpu_cache {
char *name;
char *type;
+ char *allocation_policy;
+ char *write_policy;
+
int level;
- int ways;
uint64_t size;
+ unsigned int ways_of_associativity;
+ unsigned int physical_line_partition;
+ unsigned int number_of_sets;
+ unsigned int coherency_line_size;
+
int nsharedmaps;
cpu_set_t **sharedmaps;
};
diff --git a/sys-utils/lsipc.c b/sys-utils/lsipc.c
index 5ba9cd7bf..5a1a3d7ac 100644
--- a/sys-utils/lsipc.c
+++ b/sys-utils/lsipc.c
@@ -1137,7 +1137,7 @@ int main(int argc, char *argv[])
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ close_stdout_atexit();
ctl->time_mode = 0;
diff --git a/sys-utils/mount.8 b/sys-utils/mount.8
index b79b4ef5f..56d3520be 100644
--- a/sys-utils/mount.8
+++ b/sys-utils/mount.8
@@ -116,7 +116,7 @@ options to avoid ambivalent interpretation of the given argument. For example:
The same filesystem may be mounted more than once, and in some cases (e.g.
network filesystems) the same filesystem may be mounted on the same
mountpoint more times. The mount command does not implement any policy to
-control this behavior. All behavior is controlled bythe kernel and it is usually
+control this behavior. All behavior is controlled by the kernel and it is usually
specific to the filesystem driver. The exception is \fB\-\-all\fR, in this case
already mounted filesystems are ignored (see \fB\-\-all\fR below for more details).
diff --git a/sys-utils/mountpoint.1 b/sys-utils/mountpoint.1
index afc469ebc..6669b13eb 100644
--- a/sys-utils/mountpoint.1
+++ b/sys-utils/mountpoint.1
@@ -1,4 +1,4 @@
-.TH MOUNTPOINT 1 "July 2014" "util-linux" "User Commands"
+.TH MOUNTPOINT 1 "August 2019" "util-linux" "User Commands"
.SH NAME
mountpoint \- see if a directory or file is a mountpoint
.SH SYNOPSIS
@@ -28,6 +28,11 @@ directory.
.BR \-q , " \-\-quiet"
Be quiet - don't print anything.
.TP
+.B "\-\-nofollow"
+Do not follow symbolic link if it the last elemnt of the
+.I directory
+path.
+.TP
.BR \-x , " \-\-devno"
Show the major/minor numbers of the given blockdevice on standard output.
.TP
diff --git a/sys-utils/mountpoint.c b/sys-utils/mountpoint.c
index 985130cba..052440bd4 100644
--- a/sys-utils/mountpoint.c
+++ b/sys-utils/mountpoint.c
@@ -47,6 +47,7 @@ struct mountpoint_control {
unsigned int
dev_devno:1,
fs_devno:1,
+ nofollow:1,
quiet:1;
};
@@ -123,6 +124,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(USAGE_OPTIONS, out);
fputs(_(" -q, --quiet quiet mode - don't print anything\n"
+ " --nofollow do not follow symlink\n"
" -d, --fs-devno print maj:min device number of the filesystem\n"
" -x, --devno print maj:min device number of the block device\n"), out);
fputs(USAGE_SEPARATOR, out);
@@ -137,8 +139,13 @@ int main(int argc, char **argv)
int c;
struct mountpoint_control ctl = { NULL };
+ enum {
+ OPT_NOFOLLOW = CHAR_MAX + 1
+ };
+
static const struct option longopts[] = {
{ "quiet", no_argument, NULL, 'q' },
+ { "nofollow", no_argument, NULL, OPT_NOFOLLOW },
{ "fs-devno", no_argument, NULL, 'd' },
{ "devno", no_argument, NULL, 'x' },
{ "help", no_argument, NULL, 'h' },
@@ -159,6 +166,9 @@ int main(int argc, char **argv)
case 'q':
ctl.quiet = 1;
break;
+ case OPT_NOFOLLOW:
+ ctl.nofollow = 1;
+ break;
case 'd':
ctl.fs_devno = 1;
break;
@@ -179,17 +189,20 @@ int main(int argc, char **argv)
warnx(_("bad usage"));
errtryhelp(EXIT_FAILURE);
}
+ if (ctl.nofollow && ctl.dev_devno)
+ errx(EXIT_FAILURE, _("%s and %s are mutually exclusive"),
+ "--devno", "--nofollow");
ctl.path = argv[optind];
-
- if (stat(ctl.path, &ctl.st)) {
+ c = ctl.nofollow ? lstat(ctl.path, &ctl.st) : stat(ctl.path, &ctl.st);
+ if (c) {
if (!ctl.quiet)
err(EXIT_FAILURE, "%s", ctl.path);
return EXIT_FAILURE;
}
if (ctl.dev_devno)
return print_devno(&ctl) ? EXIT_FAILURE : EXIT_SUCCESS;
- if (dir_to_device(&ctl)) {
+ if ((ctl.nofollow && S_ISLNK(ctl.st.st_mode)) || dir_to_device(&ctl)) {
if (!ctl.quiet)
printf(_("%s is not a mountpoint\n"), ctl.path);
return EXIT_FAILURE;
diff --git a/sys-utils/wdctl.8 b/sys-utils/wdctl.8
index 7edf80866..efd8b5917 100644
--- a/sys-utils/wdctl.8
+++ b/sys-utils/wdctl.8
@@ -14,6 +14,10 @@ Show hardware watchdog status. The default device is
If more than one device is specified then the output is separated by
one blank line.
.PP
+If the device is already used or user has no permissions to read from the device than
+.B wdctl
+reads data from sysfs. In this case information about supported features (flags) might be missing.
+.PP
Note that the number of supported watchdog features is hardware specific.
.SH OPTIONS
.TP
diff --git a/sys-utils/wdctl.c b/sys-utils/wdctl.c
index 4574e10da..8de5d5a2d 100644
--- a/sys-utils/wdctl.c
+++ b/sys-utils/wdctl.c
@@ -21,10 +21,12 @@
#include <sys/ioctl.h>
#include <getopt.h>
#include <stdio.h>
-#include <unistd.h>
#include <signal.h>
#include <assert.h>
#include <linux/watchdog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <libsmartcols.h>
@@ -36,6 +38,7 @@
#include "pathnames.h"
#include "strutils.h"
#include "carefulputc.h"
+#include "path.h"
/*
* since 2.6.18
@@ -59,10 +62,6 @@
other external alarm not a reboot */
#endif
-/* basic output flags */
-static int no_headings;
-static int raw;
-
struct wdflag {
uint32_t flag;
const char *name;
@@ -108,8 +107,8 @@ static struct colinfo infos[] = {
static int columns[ARRAY_SIZE(infos) * 2];
static int ncolumns;
-struct wdinfo {
- char *device;
+struct wd_device {
+ const char *devpath;
int timeout;
int timeleft;
@@ -117,12 +116,23 @@ struct wdinfo {
uint32_t status;
uint32_t bstatus;
+ int nowayout;
struct watchdog_info ident;
unsigned int has_timeout : 1,
has_timeleft : 1,
- has_pretimeout : 1;
+ has_pretimeout : 1,
+ has_nowayout : 1;
+};
+
+struct wd_control {
+ unsigned int show_oneline : 1,
+ show_raw : 1,
+ hide_headings : 1,
+ hide_flags : 1,
+ hide_ident : 1,
+ hide_timeouts : 1;
};
/* converts flag name to flag bit */
@@ -165,10 +175,32 @@ static struct colinfo *get_column_info(unsigned num)
return &infos[ get_column_id(num) ];
}
+/* We preffer cdev /dev/watchdog0 as this device has node in
+ * /sys/class/watchdog/. The old miscdev /dev/watchdog is fallback for old
+ * systemds only.
+ */
+static const char *get_default_device(void)
+{
+ const char **p;
+ static const char *devs[] = {
+ "/dev/watchdog0",
+ "/dev/watchdog",
+ NULL
+ };
+
+ for (p = devs; *p; p++) {
+ if (access(*p, F_OK) == 0)
+ return *p;
+ }
+
+ return NULL;
+}
+
static void __attribute__((__noreturn__)) usage(void)
{
FILE *out = stdout;
size_t i;
+ const char *dflt = get_default_device();
fputs(USAGE_HEADER, out);
fprintf(out,
@@ -193,7 +225,10 @@ static void __attribute__((__noreturn__)) usage(void)
printf(USAGE_HELP_OPTIONS(24));
fputs(USAGE_SEPARATOR, out);
- fprintf(out, _("The default device is %s.\n"), _PATH_WATCHDOG_DEV);
+ if (dflt)
+ fprintf(out, _("The default device is %s.\n"), dflt);
+ else
+ fprintf(out, _("No default device is available.\n"));
fputs(USAGE_COLUMNS, out);
for (i = 0; i < ARRAY_SIZE(infos); i++)
@@ -204,7 +239,7 @@ static void __attribute__((__noreturn__)) usage(void)
exit(EXIT_SUCCESS);
}
-static void add_flag_line(struct libscols_table *table, struct wdinfo *wd, const struct wdflag *fl)
+static void add_flag_line(struct libscols_table *table, struct wd_device *wd, const struct wdflag *fl)
{
int i;
struct libscols_line *line;
@@ -232,7 +267,7 @@ static void add_flag_line(struct libscols_table *table, struct wdinfo *wd, const
str = wd->bstatus & fl->flag ? "1" : "0";
break;
case COL_DEVICE:
- str = wd->device;
+ str = wd->devpath;
break;
default:
break;
@@ -245,13 +280,17 @@ static void add_flag_line(struct libscols_table *table, struct wdinfo *wd, const
}
}
-static int show_flags(struct wdinfo *wd, uint32_t wanted)
+static int show_flags(struct wd_control *ctl, struct wd_device *wd, uint32_t wanted)
{
size_t i;
int rc = -1;
struct libscols_table *table;
uint32_t flags;
+ /* information about supported bits is probably missing in /sys */
+ if (!wd->ident.options)
+ return 0;
+
scols_init_debug(0);
/* create output table */
@@ -260,8 +299,8 @@ static int show_flags(struct wdinfo *wd, uint32_t wanted)
warn(_("failed to allocate output table"));
return -1;
}
- scols_table_enable_raw(table, raw);
- scols_table_enable_noheadings(table, no_headings);
+ scols_table_enable_raw(table, ctl->show_raw);
+ scols_table_enable_noheadings(table, ctl->hide_headings);
/* define columns */
for (i = 0; i < (size_t) ncolumns; i++) {
@@ -287,7 +326,7 @@ static int show_flags(struct wdinfo *wd, uint32_t wanted)
}
if (flags)
- warnx(_("%s: unknown flags 0x%x\n"), wd->device, flags);
+ warnx(_("%s: unknown flags 0x%x\n"), wd->devpath, flags);
scols_print_table(table);
rc = 0;
@@ -301,25 +340,25 @@ done:
*
* Don't use err() or exit() here!
*/
-static int set_watchdog(struct wdinfo *wd, int timeout)
+static int set_watchdog(struct wd_device *wd, int timeout)
{
int fd;
sigset_t sigs, oldsigs;
int rc = 0;
- assert(wd->device);
+ assert(wd->devpath);
sigemptyset(&oldsigs);
sigfillset(&sigs);
sigprocmask(SIG_BLOCK, &sigs, &oldsigs);
- fd = open(wd->device, O_WRONLY|O_CLOEXEC);
+ fd = open(wd->devpath, O_WRONLY|O_CLOEXEC);
if (fd < 0) {
if (errno == EBUSY)
warnx(_("%s: watchdog already in use, terminating."),
- wd->device);
- warn(_("cannot open %s"), wd->device);
+ wd->devpath);
+ warn(_("cannot open %s"), wd->devpath);
return -1;
}
@@ -331,7 +370,7 @@ static int set_watchdog(struct wdinfo *wd, int timeout)
if (write(fd, &v, 1) >= 0)
break;
if (errno != EINTR) {
- warn(_("%s: failed to disarm watchdog"), wd->device);
+ warn(_("%s: failed to disarm watchdog"), wd->devpath);
break;
}
/* Let's try hard, since if we don't get this right
@@ -340,7 +379,7 @@ static int set_watchdog(struct wdinfo *wd, int timeout)
if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) != 0) {
rc = errno;
- warn(_("cannot set timeout for %s"), wd->device);
+ warn(_("cannot set timeout for %s"), wd->devpath);
}
if (close(fd))
@@ -358,29 +397,24 @@ static int set_watchdog(struct wdinfo *wd, int timeout)
*
* Don't use err() or exit() here!
*/
-static int read_watchdog(struct wdinfo *wd)
+static int read_watchdog_from_device(struct wd_device *wd)
{
int fd;
sigset_t sigs, oldsigs;
- assert(wd->device);
+ assert(wd->devpath);
sigemptyset(&oldsigs);
sigfillset(&sigs);
sigprocmask(SIG_BLOCK, &sigs, &oldsigs);
- fd = open(wd->device, O_WRONLY|O_CLOEXEC);
+ fd = open(wd->devpath, O_WRONLY|O_CLOEXEC);
- if (fd < 0) {
- if (errno == EBUSY)
- warnx(_("%s: watchdog already in use, terminating."),
- wd->device);
- warn(_("cannot open %s"), wd->device);
- return -1;
- }
+ if (fd < 0)
+ return -errno;
if (ioctl(fd, WDIOC_GETSUPPORT, &wd->ident) < 0)
- warn(_("%s: failed to get information about watchdog"), wd->device);
+ warn(_("%s: failed to get information about watchdog"), wd->devpath);
else {
ioctl(fd, WDIOC_GETSTATUS, &wd->status);
ioctl(fd, WDIOC_GETBOOTSTATUS, &wd->bstatus);
@@ -401,7 +435,7 @@ static int read_watchdog(struct wdinfo *wd)
if (write(fd, &v, 1) >= 0)
break;
if (errno != EINTR) {
- warn(_("%s: failed to disarm watchdog"), wd->device);
+ warn(_("%s: failed to disarm watchdog"), wd->devpath);
break;
}
/* Let's try hard, since if we don't get this right
@@ -415,18 +449,88 @@ static int read_watchdog(struct wdinfo *wd)
return 0;
}
-static void print_oneline(struct wdinfo *wd, uint32_t wanted,
- int noident, int notimeouts, int noflags)
+/* Returns: <0 error, 0 success, 1 unssuported */
+static int read_watchdog_from_sysfs(struct wd_device *wd)
+{
+ struct path_cxt *sys;
+ struct stat st;
+ int rc;
+
+ rc = stat(wd->devpath, &st);
+ if (rc != 0)
+ return rc;
+
+ sys = ul_new_path(_PATH_SYS_DEVCHAR "/%u:%u",
+ major(st.st_rdev), minor(st.st_rdev));
+ if (!sys)
+ return -ENOMEM;
+
+ if (ul_path_get_dirfd(sys) < 0)
+ goto nosysfs; /* device not in /sys */
+
+ if (ul_path_access(sys, F_OK, "identity") != 0)
+ goto nosysfs; /* no info in /sys (old miscdev?) */
+
+ ul_path_read_buffer(sys, (char *) wd->ident.identity, sizeof(wd->ident.identity), "identity");
+
+ ul_path_scanf(sys, "status", "%x", &wd->status);
+ ul_path_read_u32(sys, &wd->bstatus, "bootstatus");
+
+ if (ul_path_read_s32(sys, &wd->nowayout, "nowayout") == 0)
+ wd->has_nowayout = 1;
+ if (ul_path_read_s32(sys, &wd->timeout, "timeout") == 0)
+ wd->has_timeout = 1;
+ if (ul_path_read_s32(sys, &wd->pretimeout, "pretimeout") == 0)
+ wd->has_pretimeout = 1;
+ if (ul_path_read_s32(sys, &wd->timeleft, "timeleft") == 0)
+ wd->has_timeleft = 1;
+
+ ul_unref_path(sys);
+ return 0;
+nosysfs:
+ ul_unref_path(sys);
+ return 1;
+}
+
+static int read_watchdog(struct wd_device *wd)
+{
+ int rc = read_watchdog_from_device(wd);
+
+ if (rc == -EBUSY || rc == -EACCES || rc == -EPERM)
+ rc = read_watchdog_from_sysfs(wd);
+
+ if (rc) {
+ warn(_("cannot read information about %s"), wd->devpath);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void show_timeouts(struct wd_device *wd)
+{
+ if (wd->has_timeout)
+ printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeout),
+ _("Timeout:"), wd->timeout);
+ if (wd->has_pretimeout)
+ printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->pretimeout),
+ _("Pre-timeout:"), wd->pretimeout);
+ if (wd->has_timeleft)
+ printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeleft),
+ _("Timeleft:"), wd->timeleft);
+}
+
+static void print_oneline(struct wd_control *ctl, struct wd_device *wd, uint32_t wanted)
{
- printf("%s:", wd->device);
+ printf("%s:", wd->devpath);
- if (!noident) {
+ if (!ctl->hide_ident) {
printf(" VERSION=\"%x\"", wd->ident.firmware_version);
printf(" IDENTITY=");
fputs_quoted((char *) wd->ident.identity, stdout);
}
- if (!notimeouts) {
+ if (!ctl->hide_timeouts) {
if (wd->has_timeout)
printf(" TIMEOUT=\"%i\"", wd->timeout);
if (wd->has_pretimeout)
@@ -435,7 +539,7 @@ static void print_oneline(struct wdinfo *wd, uint32_t wanted,
printf(" TIMELEFT=\"%i\"", wd->timeleft);
}
- if (!noflags) {
+ if (!ctl->hide_flags) {
size_t i;
uint32_t flags = wd->ident.options;
@@ -459,26 +563,38 @@ static void print_oneline(struct wdinfo *wd, uint32_t wanted,
fputc('\n', stdout);
}
-static void show_timeouts(struct wdinfo *wd)
+static void print_device(struct wd_control *ctl, struct wd_device *wd, uint32_t wanted)
{
- if (wd->has_timeout)
- printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeout),
- _("Timeout:"), wd->timeout);
- if (wd->has_pretimeout)
- printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->pretimeout),
- _("Pre-timeout:"), wd->pretimeout);
- if (wd->has_timeleft)
- printf(P_("%-14s %2i second\n", "%-14s %2i seconds\n", wd->timeleft),
- _("Timeleft:"), wd->timeleft);
+ /* NAME=value one line output */
+ if (ctl->show_oneline) {
+ print_oneline(ctl, wd, wanted);
+ return;
+ }
+
+ /* pretty output */
+ if (!ctl->hide_ident) {
+ printf("%-15s%s\n", _("Device:"), wd->devpath);
+ printf("%-15s%s [%s %x]\n",
+ _("Identity:"),
+ wd->ident.identity,
+ _("version"),
+ wd->ident.firmware_version);
+ }
+ if (!ctl->hide_timeouts)
+ show_timeouts(wd);
+
+ if (!ctl->hide_flags)
+ show_flags(ctl, wd, wanted);
}
int main(int argc, char *argv[])
{
- struct wdinfo wd;
+ struct wd_device wd;
+ struct wd_control ctl = { .hide_headings = 0 };
int c, res = EXIT_SUCCESS, count = 0;
- char noflags = 0, noident = 0, notimeouts = 0, oneline = 0;
uint32_t wanted = 0;
int timeout = 0;
+ const char *dflt_device = NULL;
static const struct option long_opts[] = {
{ "flags", required_argument, NULL, 'f' },
@@ -528,26 +644,26 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
break;
case 'F':
- noflags = 1;
+ ctl.hide_flags = 1;
break;
case 'I':
- noident = 1;
+ ctl.hide_ident = 1;
break;
case 'T':
- notimeouts = 1;
+ ctl.hide_timeouts = 1;
break;
case 'n':
- no_headings = 1;
+ ctl.hide_headings = 1;
break;
case 'r':
- raw = 1;
+ ctl.show_raw = 1;
break;
case 'O':
- oneline = 1;
+ ctl.show_oneline = 1;
break;
case 'x':
- noident = 1;
- notimeouts = 1;
+ ctl.hide_ident = 1;
+ ctl.hide_timeouts = 1;
break;
case 'h':
@@ -567,15 +683,18 @@ int main(int argc, char *argv[])
columns[ncolumns++] = COL_BSTATUS;
}
+ /* Device no specified, use default. */
+ if (optind == argc) {
+ dflt_device = get_default_device();
+ if (!dflt_device)
+ err(EXIT_FAILURE, _("No default device is available."));
+ }
+
do {
int rc;
memset(&wd, 0, sizeof(wd));
-
- if (optind == argc)
- wd.device = _PATH_WATCHDOG_DEV;
- else
- wd.device = argv[optind++];
+ wd.devpath = dflt_device ? dflt_device : argv[optind++];
if (count)
fputc('\n', stdout);
@@ -594,24 +713,8 @@ int main(int argc, char *argv[])
continue;
}
- if (oneline) {
- print_oneline(&wd, wanted, noident, notimeouts, noflags);
- continue;
- }
+ print_device(&ctl, &wd, wanted);
- /* pretty output */
- if (!noident) {
- printf("%-15s%s\n", _("Device:"), wd.device);
- printf("%-15s%s [%s %x]\n",
- _("Identity:"),
- wd.ident.identity,
- _("version"),
- wd.ident.firmware_version);
- }
- if (!notimeouts)
- show_timeouts(&wd);
- if (!noflags)
- show_flags(&wd, wanted);
} while (optind < argc);
return res;
diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index 43dbd6dea..038152d56 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -42,6 +42,7 @@
#include "nls.h"
#include "pathnames.h"
#include "c.h"
+#include "cctype.h"
#include "widechar.h"
#include "ttyutils.h"
#include "color-names.h"
@@ -1432,7 +1433,7 @@ static void auto_baud(struct termios *tp)
if ((nread = read(STDIN_FILENO, buf, sizeof(buf) - 1)) > 0) {
buf[nread] = '\0';
for (bp = buf; bp < buf + nread; bp++)
- if (isascii(*bp) && isdigit(*bp)) {
+ if (c_isascii(*bp) && isdigit(*bp)) {
if ((speed = bcode(bp))) {
cfsetispeed(tp, speed);
cfsetospeed(tp, speed);
@@ -1903,8 +1904,6 @@ static void eval_issue_file(struct issue *ie,
f = NULL;
} while (dirname);
- fflush(stdout);
-
if ((op->flags & F_VCONSOLE) == 0)
ie->do_tcrestore = 1;
}
@@ -2393,46 +2392,40 @@ static void list_speeds(void)
* Will be used by log_err() and log_warn() therefore
* it takes a format as well as va_list.
*/
-#define str2cpy(b,s1,s2) strcat(strcpy(b,s1),s2)
-
-static void dolog(int priority, const char *fmt, va_list ap)
-{
-#ifndef USE_SYSLOG
- int fd;
+static void dolog(int priority
+#ifndef USE_SYSLOG
+ __attribute__((__unused__))
#endif
- char buf[BUFSIZ];
- char *bp;
-
+ , const char *fmt, va_list ap)
+{
+#ifdef USE_SYSLOG
/*
* If the diagnostic is reported via syslog(3), the process name is
* automatically prepended to the message. If we write directly to
* /dev/console, we must prepend the process name ourselves.
*/
-#ifdef USE_SYSLOG
- buf[0] = '\0';
- bp = buf;
-#else
- str2cpy(buf, program_invocation_short_name, ": ");
- bp = buf + strlen(buf);
-#endif /* USE_SYSLOG */
- vsnprintf(bp, sizeof(buf)-strlen(buf), fmt, ap);
-
- /*
- * Write the diagnostic directly to /dev/console if we do not use the
- * syslog(3) facility.
- */
-#ifdef USE_SYSLOG
openlog(program_invocation_short_name, LOG_PID, LOG_AUTHPRIV);
- syslog(priority, "%s", buf);
+ vsyslog(priority, fmt, ap);
closelog();
#else
+ /*
+ * Write the diagnostic directly to /dev/console if we do not use
+ * the syslog(3) facility.
+ */
+ char buf[BUFSIZ];
+ char new_fmt[BUFSIZ];
+ int fd;
+
+ snprintf(new_fmt, sizeof(new_fmt), "%s: %s\r\n",
+ program_invocation_short_name, fmt);
/* Terminate with CR-LF since the console mode is unknown. */
- strcat(bp, "\r\n");
+ vsnprintf(buf, sizeof(buf), new_fmt, ap);
+
if ((fd = open("/dev/console", 1)) >= 0) {
write_all(fd, buf, strlen(buf));
close(fd);
}
-#endif /* USE_SYSLOG */
+#endif /* USE_SYSLOG */
}
static void exit_slowly(int code)
diff --git a/term-utils/wall.c b/term-utils/wall.c
index c3e89bab9..bf92fe1b7 100644
--- a/term-utils/wall.c
+++ b/term-utils/wall.c
@@ -68,6 +68,7 @@
#include "pathnames.h"
#include "carefulputc.h"
#include "c.h"
+#include "cctype.h"
#include "fileutils.h"
#include "closestream.h"
@@ -324,7 +325,7 @@ static void buf_putc_careful(struct buffer *bs, int c)
if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n') {
buf_enlarge(bs, 1);
bs->data[bs->used++] = c;
- } else if (!isascii(c))
+ } else if (!c_isascii(c))
buf_printf(bs, "\\%3o", (unsigned char)c);
else {
char tmp[] = { '^', c ^ 0x40, '\0' };
diff --git a/tests/expected/column/table-empty-column-at-eol b/tests/expected/column/table-empty-column-at-eol
new file mode 100644
index 000000000..948cf947f
--- /dev/null
+++ b/tests/expected/column/table-empty-column-at-eol
@@ -0,0 +1 @@
+|
diff --git a/tests/expected/column/table-empty-column-at-eol2 b/tests/expected/column/table-empty-column-at-eol2
new file mode 100644
index 000000000..7c4378506
--- /dev/null
+++ b/tests/expected/column/table-empty-column-at-eol2
@@ -0,0 +1 @@
+||
diff --git a/tests/expected/fdisk/gpt-resize b/tests/expected/fdisk/gpt-resize
index 0b3c25a27..2871f1a14 100644
--- a/tests/expected/fdisk/gpt-resize
+++ b/tests/expected/fdisk/gpt-resize
@@ -35,7 +35,7 @@ Command (m for help): The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Invalid argument
-The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).
+The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or partx(8).
diff --git a/tests/expected/fdisk/mbr-nondos-mode.sparc b/tests/expected/fdisk/mbr-nondos-mode.sparc
deleted file mode 100644
index ffbbd8024..000000000
--- a/tests/expected/fdisk/mbr-nondos-mode.sparc
+++ /dev/null
@@ -1,189 +0,0 @@
-Initialize empty image
-8f4e33f3dc3e414ff94e5fb6905cba8c mbr-nondos-mode.img
-Create new DOS partition table
-8f4e33f3dc3e414ff94e5fb6905cba8c mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
--------------------
-
-Create 1st primary partition
-d5ad6d4e743430c2a61e558bb3319175 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>1 0 16064 16065 7.9M 83 Linux native
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
-<removed>3 0 32129 32130 15.7M 5 Whole disk
--------------------
-
-Set primary partition active
-d59bb4ba5914242f9a63a2d13fb68752 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>1 0 16064 16065 7.9M 83 Linux native r
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
-<removed>3 0 32129 32130 15.7M 5 Whole disk
--------------------
-
-Re-create 1st primary partition
-d8ba04bdd46cec690fa672ac8fcaf387 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>1 0 16064 16065 7.9M 83 Linux native r
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
--------------------
-
-Create 2nd primary partition
-d8ba04bdd46cec690fa672ac8fcaf387 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>1 0 16064 16065 7.9M 83 Linux native r
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
--------------------
-
-Create extended partition
-d59bb4ba5914242f9a63a2d13fb68752 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>1 0 16064 16065 7.9M 83 Linux native r
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
-<removed>3 0 32129 32130 15.7M 5 Whole disk
--------------------
-
-Create logical partitions
-d59bb4ba5914242f9a63a2d13fb68752 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>1 0 16064 16065 7.9M 83 Linux native r
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
-<removed>3 0 32129 32130 15.7M 5 Whole disk
--------------------
-
-Delete logical partitions
-d59bb4ba5914242f9a63a2d13fb68752 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>1 0 16064 16065 7.9M 83 Linux native r
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
-<removed>3 0 32129 32130 15.7M 5 Whole disk
--------------------
-
-Create another logical partition
-d59bb4ba5914242f9a63a2d13fb68752 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>1 0 16064 16065 7.9M 83 Linux native r
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
-<removed>3 0 32129 32130 15.7M 5 Whole disk
--------------------
-
-Delete primary partition
-0bd87175c4c5c3ef9a46595027b6369c mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>2 16065 32129 16065 7.9M 82 Linux swap u
-<removed>3 0 32129 32130 15.7M 5 Whole disk
--------------------
-
-Delete primary partition
-33f6e541ddcafed65d231ce3f2b76a59 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
-
-Device Start End Sectors Size Id Type Flags
-<removed>3 0 32129 32130 15.7M 5 Whole disk
--------------------
-
-Delete extended partition
-e923755cbc0054eb85341fe119be07f9 mbr-nondos-mode.img
-
----layout----------
-Disk <removed>: 20 MiB, 20971520 bytes, 40960 sectors
-Geometry: 255 heads, 63 sectors/track, 2 cylinders
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / <removed> bytes
-Disklabel type: sun
--------------------
-
diff --git a/tests/expected/fdisk/sunlabel b/tests/expected/fdisk/sunlabel
index 47b5e756b..5ada4fab1 100644
--- a/tests/expected/fdisk/sunlabel
+++ b/tests/expected/fdisk/sunlabel
@@ -18,7 +18,7 @@ I/O size (minimum/optimal): 512 bytes / <removed> bytes
Disklabel type: sun
Device Start End Cylinders Size Id Type Flags
-<removed>1 1 128 129 4M 83 Linux native
+<removed>1 1 128 129 4M 83 Linux native
Set partition sysid
df75defdb97fbd56222aed18631a22d0 sunlabel.img
Disk <removed>: 10 MiB, 10485760 bytes, 20480 sectors
@@ -29,7 +29,7 @@ I/O size (minimum/optimal): 512 bytes / <removed> bytes
Disklabel type: sun
Device Start End Cylinders Size Id Type Flags
-<removed>1 1 128 129 4M 4 SunOS usr
+<removed>1 1 128 129 4M 4 SunOS usr
Set first partition readonly
da23f66698d9a553162887621d4c7490 sunlabel.img
Disk <removed>: 10 MiB, 10485760 bytes, 20480 sectors
@@ -75,6 +75,6 @@ Disklabel type: sun
Device Start End Cylinders Size Id Type Flags
<removed>1 1 128 129 4M 4 SunOS usr ur
-<removed>2 129 325 198 6.1M 83 Linux native
+<removed>2 129 325 198 6.1M 83 Linux native
Delete all partitions
502ba7a0cfdce2849c3a99881f0590c3 sunlabel.img
diff --git a/tests/expected/libmount/context-X-mount.mkdir b/tests/expected/libmount/context-X-comment
index 7504a7e83..7504a7e83 100644
--- a/tests/expected/libmount/context-X-mount.mkdir
+++ b/tests/expected/libmount/context-X-comment
diff --git a/tests/expected/libmount/context-x-mount.mkdir b/tests/expected/libmount/context-x-permanent
index 7504a7e83..7504a7e83 100644
--- a/tests/expected/libmount/context-x-mount.mkdir
+++ b/tests/expected/libmount/context-x-permanent
diff --git a/tests/expected/libsmartcols/fromfile-padding-default b/tests/expected/libsmartcols/fromfile-padding-default
new file mode 100644
index 000000000..f935be267
--- /dev/null
+++ b/tests/expected/libsmartcols/fromfile-padding-default
@@ -0,0 +1,11 @@
+NAME.. ......NUM STRINGS STRINGS
+aaaa.. ........0 aaaa... aaaa
+bbb... ......100 bbb.... bbb
+ccccc. .......21 ccccc.. ccccc
+dddddd ........3 dddddd. dddddd
+ee.... ......411 ee..... ee
+ffff.. .....5111 .......
+gggggg 678993321 gggggg. gggggg
+hhh... ..7666666 hhh.... hhh
+iiiiii .....8765 iiiiii. iiiiii
+jj.... ...987456 jj..... jj
diff --git a/tests/expected/libsmartcols/fromfile-padding-maxout b/tests/expected/libsmartcols/fromfile-padding-maxout
new file mode 100644
index 000000000..3f73ce38b
--- /dev/null
+++ b/tests/expected/libsmartcols/fromfile-padding-maxout
@@ -0,0 +1,11 @@
+NAME.............. ..................NUM STRINGS............ STRINGS............
+aaaa.............. ....................0 aaaa............... aaaa...............
+bbb............... ..................100 bbb................ bbb................
+ccccc............. ...................21 ccccc.............. ccccc..............
+dddddd............ ....................3 dddddd............. dddddd.............
+ee................ ..................411 ee................. ee.................
+ffff.............. .................5111 ................... ...................
+gggggg............ ............678993321 gggggg............. gggggg.............
+hhh............... ..............7666666 hhh................ hhh................
+iiiiii............ .................8765 iiiiii............. iiiiii.............
+jj................ ...............987456 jj................. jj.................
diff --git a/tests/expected/libsmartcols/fromfile-padding-minout b/tests/expected/libsmartcols/fromfile-padding-minout
new file mode 100644
index 000000000..ac8eabc93
--- /dev/null
+++ b/tests/expected/libsmartcols/fromfile-padding-minout
@@ -0,0 +1,11 @@
+NAME.. ......NUM STRINGS STRINGS
+aaaa.. ........0 aaaa... aaaa
+bbb... ......100 bbb.... bbb
+ccccc. .......21 ccccc.. ccccc
+dddddd ........3 dddddd. dddddd
+ee.... ......411 ee..... ee
+ffff.. .....5111
+gggggg 678993321 gggggg. gggggg
+hhh... ..7666666 hhh.... hhh
+iiiiii .....8765 iiiiii. iiiiii
+jj.... ...987456 jj..... jj
diff --git a/tests/expected/lsblk/lsblk-simple-lvm-vendor b/tests/expected/lsblk/lsblk-simple-lvm-vendor
index 591c703af..24ee97dd4 100644
--- a/tests/expected/lsblk/lsblk-simple-lvm-vendor
+++ b/tests/expected/lsblk/lsblk-simple-lvm-vendor
@@ -1,22 +1,22 @@
NAME MODEL VENDOR REV
-loop0
-`-vg_foo.4059-lv_foo.4059
-loop1
-`-vg_foo.4059-lv_foo.4059
-loop2
-`-vg_foo.4059-lv_foo.4059
-loop3
-`-vg_foo.4059-lv_foo.4059
+loop0
+`-vg_foo.4059-lv_foo.4059
+loop1
+`-vg_foo.4059-lv_foo.4059
+loop2
+`-vg_foo.4059-lv_foo.4059
+loop3
+`-vg_foo.4059-lv_foo.4059
sda KINGSTON SH103S3 ATA BBF0
-|-sda1
-|-sda2
-|-sda3
-|-sda4
-|-sda5
-`-sda6
+|-sda1
+|-sda2
+|-sda3
+|-sda4
+|-sda5
+`-sda6
sdb WDC WD800JD-00MS ATA 1E01
-`-sdb1
-nvme0n1 KINGSTON SKC1000240G
-|-nvme0n1p1
-|-nvme0n1p2
-`-nvme0n1p3
+`-sdb1
+nvme0n1 KINGSTON SKC1000240G
+|-nvme0n1p1
+|-nvme0n1p2
+`-nvme0n1p3
diff --git a/tests/expected/lsblk/lsblk-simple-nvme-vendor b/tests/expected/lsblk/lsblk-simple-nvme-vendor
index 69e972a31..2a0a90514 100644
--- a/tests/expected/lsblk/lsblk-simple-nvme-vendor
+++ b/tests/expected/lsblk/lsblk-simple-nvme-vendor
@@ -1,14 +1,14 @@
NAME MODEL VENDOR REV
sda KINGSTON SH103S3 ATA BBF0
-|-sda1
-|-sda2
-|-sda3
-|-sda4
-|-sda5
-`-sda6
+|-sda1
+|-sda2
+|-sda3
+|-sda4
+|-sda5
+`-sda6
sdb WDC WD800JD-00MS ATA 1E01
-`-sdb1
-nvme0n1 KINGSTON SKC1000240G
-|-nvme0n1p1
-|-nvme0n1p2
-`-nvme0n1p3
+`-sdb1
+nvme0n1 KINGSTON SKC1000240G
+|-nvme0n1p1
+|-nvme0n1p2
+`-nvme0n1p3
diff --git a/tests/expected/misc/mountpoint b/tests/expected/misc/mountpoint
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/expected/misc/mountpoint
diff --git a/tests/expected/misc/mountpoint-default b/tests/expected/misc/mountpoint-default
new file mode 100644
index 000000000..9a7ac6ab3
--- /dev/null
+++ b/tests/expected/misc/mountpoint-default
@@ -0,0 +1,2 @@
+./symlink-to-root is a mountpoint
+0
diff --git a/tests/expected/misc/mountpoint-mutually-exclusive b/tests/expected/misc/mountpoint-mutually-exclusive
new file mode 100644
index 000000000..38c36f13b
--- /dev/null
+++ b/tests/expected/misc/mountpoint-mutually-exclusive
@@ -0,0 +1,2 @@
+mountpoint: --devno and --nofollow are mutually exclusive
+1
diff --git a/tests/expected/misc/mountpoint-nofollow b/tests/expected/misc/mountpoint-nofollow
new file mode 100644
index 000000000..1ba174959
--- /dev/null
+++ b/tests/expected/misc/mountpoint-nofollow
@@ -0,0 +1,2 @@
+./symlink-to-root is not a mountpoint
+1
diff --git a/tests/ts/column/table b/tests/ts/column/table
index bd1f16f3f..e64dee746 100755
--- a/tests/ts/column/table
+++ b/tests/ts/column/table
@@ -116,4 +116,12 @@ ts_init_subtest "empty-column"
printf ':a:b\n' | $TS_CMD_COLUMN --table --separator ':' --output-separator ':' >> $TS_OUTPUT 2>&1
ts_finalize_subtest
+ts_init_subtest "empty-column-at-eol"
+printf '|' | $TS_CMD_COLUMN --separator '|' --output-separator '|' --table >> $TS_OUTPUT 2>&1
+ts_finalize_subtest
+
+ts_init_subtest "empty-column-at-eol2"
+printf '||' | $TS_CMD_COLUMN --separator '|' --output-separator '|' --table >> $TS_OUTPUT 2>&1
+ts_finalize_subtest
+
ts_finalize
diff --git a/tests/ts/fdisk/mbr-nondos-mode b/tests/ts/fdisk/mbr-nondos-mode
index d3b35fa39..8fb09f1ce 100755
--- a/tests/ts/fdisk/mbr-nondos-mode
+++ b/tests/ts/fdisk/mbr-nondos-mode
@@ -37,19 +37,16 @@ FDISK_CMD_DELETE_1PRIMARY="d\n1\n" # delete first primary
FDISK_CMD_DELETE_2PRIMARY="d\n2\n" # delete first primary
FDISK_CMD_DELETE_EXTENDED="d\n3\n" # delete second primary
-# Sparc uses SUN disk labels by default and thus has a different output
+# ignore architectures where MBR is not a default
ARCH=$(uname -m)
case $ARCH in
*sparc* )
- ARCH_EXT=".sparc"
+ ts_skip "unsupported"
;;
*)
- ARCH_EXT=""
;;
esac
-TS_EXPECTED+="${ARCH_EXT}"
-
function print_layout {
echo -ne "\n---layout----------\n" >> $TS_OUTPUT
$TS_CMD_FDISK -l ${TEST_IMAGE_NAME} >> $TS_OUTPUT
diff --git a/tests/ts/libmount/context b/tests/ts/libmount/context
index 3750c701f..6dd35b193 100755
--- a/tests/ts/libmount/context
+++ b/tests/ts/libmount/context
@@ -146,8 +146,8 @@ is_mounted $MOUNTPOINT && echo "$MOUNTPOINT still mounted" >> $TS_OUTPUT 2>&1
ts_finalize_subtest
-# deprecated
-ts_init_subtest "x-mount.mkdir"
+# deprecated (x-* mount option maintained in userspace (e.g. utab)
+ts_init_subtest "x-permanent"
TS_NOEXIST="$TS_OUTDIR/${TS_TESTNAME}-${TS_SUBNAME}-noex"
[ -d $TS_NOEXIST ] && rmdir $TS_NOEXIST
@@ -159,7 +159,8 @@ $TS_CMD_UMOUNT $TS_NOEXIST
rmdir $TS_NOEXIST
-ts_init_subtest "X-mount.mkdir"
+# X-* comment
+ts_init_subtest "X-comment"
TS_NOEXIST="$TS_OUTDIR/${TS_TESTNAME}-${TS_SUBNAME}-noex"
[ -d $TS_NOEXIST ] && rmdir $TS_NOEXIST
diff --git a/tests/ts/libsmartcols/files/data-string-empty b/tests/ts/libsmartcols/files/data-string-empty
new file mode 100644
index 000000000..1f8ad34e5
--- /dev/null
+++ b/tests/ts/libsmartcols/files/data-string-empty
@@ -0,0 +1,10 @@
+aaaa
+bbb
+ccccc
+dddddd
+ee
+
+gggggg
+hhh
+iiiiii
+jj
diff --git a/tests/ts/libsmartcols/fromfile b/tests/ts/libsmartcols/fromfile
index 274081ea0..20994d661 100755
--- a/tests/ts/libsmartcols/fromfile
+++ b/tests/ts/libsmartcols/fromfile
@@ -114,6 +114,52 @@ ts_run $TESTPROG --nlines 10 --maxout --width 80\
>> $TS_OUTPUT 2>&1
ts_finalize_subtest
+ts_init_subtest "padding-default"
+export LIBSMARTCOLS_DEBUG_PADDING=on
+ts_run $TESTPROG --nlines 10 --width 80 \
+ --column $TS_SELF/files/col-name \
+ --column $TS_SELF/files/col-number \
+ --column $TS_SELF/files/col-string \
+ --column $TS_SELF/files/col-string \
+ $TS_SELF/files/data-string \
+ $TS_SELF/files/data-number \
+ $TS_SELF/files/data-string-empty \
+ $TS_SELF/files/data-string-empty \
+ >> $TS_OUTPUT 2> /dev/null
+ts_finalize_subtest
+
+ts_init_subtest "padding-maxout"
+export LIBSMARTCOLS_DEBUG_PADDING=on
+ts_run $TESTPROG --nlines 10 --width 80 \
+ --maxout \
+ --column $TS_SELF/files/col-name \
+ --column $TS_SELF/files/col-number \
+ --column $TS_SELF/files/col-string \
+ --column $TS_SELF/files/col-string \
+ $TS_SELF/files/data-string \
+ $TS_SELF/files/data-number \
+ $TS_SELF/files/data-string-empty \
+ $TS_SELF/files/data-string-empty \
+ >> $TS_OUTPUT 2> /dev/null
+ts_finalize_subtest
+
+ts_init_subtest "padding-minout"
+export LIBSMARTCOLS_DEBUG_PADDING=on
+ts_run $TESTPROG --nlines 10 --width 80 \
+ --minout \
+ --column $TS_SELF/files/col-name \
+ --column $TS_SELF/files/col-number \
+ --column $TS_SELF/files/col-string \
+ --column $TS_SELF/files/col-string \
+ $TS_SELF/files/data-string \
+ $TS_SELF/files/data-number \
+ $TS_SELF/files/data-string-empty \
+ $TS_SELF/files/data-string-empty \
+ >> $TS_OUTPUT 2> /dev/null
+ts_finalize_subtest
+
+unset LIBSMARTCOLS_DEBUG_PADDING
+
ts_init_subtest "strictwidth"
ts_run $TESTPROG --nlines 10 \
--column $TS_SELF/files/col-name \
diff --git a/tests/ts/misc/mountpoint b/tests/ts/misc/mountpoint
new file mode 100755
index 000000000..03c1ccc3e
--- /dev/null
+++ b/tests/ts/misc/mountpoint
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+TS_TOPDIR="${0%/*}/../.."
+TS_DESC="mountpoint"
+
+. $TS_TOPDIR/functions.sh
+ts_init "$*"
+
+ts_check_test_command "$TS_CMD_MOUNTPOINT"
+
+ln -s / ./symlink-to-root
+
+ts_init_subtest "default"
+$TS_CMD_MOUNTPOINT ./symlink-to-root >> $TS_OUTPUT 2>&1
+echo $? >> $TS_OUTPUT 2>&1
+ts_finalize_subtest
+
+ts_init_subtest "nofollow"
+$TS_CMD_MOUNTPOINT --nofollow ./symlink-to-root >> $TS_OUTPUT 2>&1
+echo $? >> $TS_OUTPUT 2>&1
+ts_finalize_subtest
+
+ts_init_subtest "mutually-exclusive"
+$TS_CMD_MOUNTPOINT --devno --nofollow / >> $TS_OUTPUT 2>&1
+echo $? >> $TS_OUTPUT 2>&1
+ts_finalize_subtest
+
+rm -f ./symlink-to-root
+ts_finalize
diff --git a/tests/ts/partx/partx b/tests/ts/partx/partx
index b21dc44ef..84c286a94 100755
--- a/tests/ts/partx/partx
+++ b/tests/ts/partx/partx
@@ -137,9 +137,14 @@ udevadm settle
ts_init_subtest "delete-non-existent"
#attempt to remove it again
{
+ # remove non-existing partitions (ENXIO) is not error
+ #
+ # see ab025087f91b66ee8e23a16bc49eb0d9bd421d65 and
+ # 53ae7d60cfeacd4e87bfe6fcc015b58b78ef4555
+ #
$TS_CMD_PARTX -d --nr $PARTS $TS_DEVICE &&
- echo "partx failed: removed non-existing partition" ||
- echo "partx: OK"
+ echo "partx: OK" ||
+ echo "partx failed: removed non-existing partition"
} >$TS_OUTPUT 2>&1
ts_finalize_subtest
diff --git a/text-utils/colrm.c b/text-utils/colrm.c
index d0ef2eb66..f9dfd5938 100644
--- a/text-utils/colrm.c
+++ b/text-utils/colrm.c
@@ -166,7 +166,7 @@ int main(int argc, char **argv)
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ close_stdout_atexit();
while ((opt =
getopt_long(argc, argv, "bfhl:pxVH", longopts,
diff --git a/text-utils/column.c b/text-utils/column.c
index 13b39537e..9d56e514c 100644
--- a/text-utils/column.c
+++ b/text-utils/column.c
@@ -169,7 +169,7 @@ static wchar_t *local_wcstok(wchar_t *p, const wchar_t *separator, int greedy, w
return strtok_r(p, separator, state);
#endif
if (!p) {
- if (!*state || !**state)
+ if (!*state)
return NULL;
p = *state;
}