
30 changed files with 11513 additions and 35 deletions
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
From 8694f63002c6b765e72c36fbf8ed46164d5303e5 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Mon, 15 Aug 2016 11:02:18 +0200 |
||||
Subject: [PATCH 150/173] lsns: missing ns/<name> is not error |
||||
MIME-Version: 1.0 |
||||
Content-Type: text/plain; charset=UTF-8 |
||||
Content-Transfer-Encoding: 8bit |
||||
|
||||
For example user namespace is optional it does not make sense to |
||||
ignore process completely if the ns/user file is missing. |
||||
|
||||
Reported-by: Michał Bartoszkiewicz <mbartoszkiewicz@gmail.com> |
||||
Upstream: http://github.com/karelzak/util-linux/commit/3082f8518f2739e9f68e660f1749acdd2b9d7a97 |
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1543428 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
sys-utils/lsns.c | 4 ++-- |
||||
1 file changed, 2 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/sys-utils/lsns.c b/sys-utils/lsns.c |
||||
index fb53a16a4..b8841b7a3 100644 |
||||
--- a/sys-utils/lsns.c |
||||
+++ b/sys-utils/lsns.c |
||||
@@ -204,7 +204,7 @@ static inline const struct colinfo *get_column_info(unsigned num) |
||||
return &infos[ get_column_id(num) ]; |
||||
} |
||||
|
||||
-static ino_t get_ns_ino(int dir, const char *nsname, ino_t *ino) |
||||
+static int get_ns_ino(int dir, const char *nsname, ino_t *ino) |
||||
{ |
||||
struct stat st; |
||||
char path[16]; |
||||
@@ -269,7 +269,7 @@ static int read_process(struct lsns *ls, pid_t pid) |
||||
continue; |
||||
|
||||
rc = get_ns_ino(dirfd(dir), ns_names[i], &p->ns_ids[i]); |
||||
- if (rc && rc != -EACCES) |
||||
+ if (rc && rc != -EACCES && rc != -ENOENT) |
||||
goto done; |
||||
rc = 0; |
||||
} |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
From 7a151a3d74b2972410103b684803e6d6b8fda15b Mon Sep 17 00:00:00 2001 |
||||
From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> |
||||
Date: Wed, 23 Nov 2016 14:13:34 +0900 |
||||
Subject: [PATCH 151/173] lsns: Fix parser for /proc/<pid>/stat which is |
||||
including space in comm |
||||
|
||||
For example, child process of spamd has |
||||
|
||||
32031 (spamd child) S 32026 32026 32026 0 -1 4210752 338 0 0 0 ... |
||||
|
||||
fscanf("%d %*s %c %d*[^\n]") in read_process() can't parse above as we |
||||
expected, because %s only skips non-whitespace. I.e. it parses like |
||||
following, |
||||
|
||||
32031 (spamd child) S 32026 32026 32026 0 -1 4210752 338 0 0 0 ... |
||||
+---+ +----+ + |
||||
%d %*s %c |
||||
|
||||
and returns 2 (pid=32031, state=c). |
||||
|
||||
This fixes it by skipping task->comm part manually. |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1543428 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/3fcbd7978980dc1a29c626b701333e27599e506d |
||||
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> |
||||
--- |
||||
sys-utils/lsns.c | 30 ++++++++++++++++++++++++++---- |
||||
1 file changed, 26 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/sys-utils/lsns.c b/sys-utils/lsns.c |
||||
index b8841b7a3..d32756508 100644 |
||||
--- a/sys-utils/lsns.c |
||||
+++ b/sys-utils/lsns.c |
||||
@@ -217,6 +217,30 @@ static int get_ns_ino(int dir, const char *nsname, ino_t *ino) |
||||
return 0; |
||||
} |
||||
|
||||
+static int parse_proc_stat(FILE *fp, pid_t *pid, char *state, pid_t *ppid) |
||||
+{ |
||||
+ char *line = NULL, *p; |
||||
+ size_t len = 0; |
||||
+ int rc; |
||||
+ |
||||
+ if (getline(&line, &len, fp) < 0) { |
||||
+ rc = -errno; |
||||
+ goto error; |
||||
+ } |
||||
+ |
||||
+ p = strrchr(line, ')'); |
||||
+ if (p == NULL || |
||||
+ sscanf(line, "%d (", pid) != 1 || |
||||
+ sscanf(p, ") %c %d*[^\n]", state, ppid) != 2) { |
||||
+ rc = -EINVAL; |
||||
+ goto error; |
||||
+ } |
||||
+ rc = 0; |
||||
+ |
||||
+error: |
||||
+ free(line); |
||||
+ return rc; |
||||
+} |
||||
|
||||
static int read_process(struct lsns *ls, pid_t pid) |
||||
{ |
||||
@@ -255,11 +279,9 @@ static int read_process(struct lsns *ls, pid_t pid) |
||||
rc = -errno; |
||||
goto done; |
||||
} |
||||
- rc = fscanf(f, "%d %*s %c %d*[^\n]", &p->pid, &p->state, &p->ppid); |
||||
- if (rc != 3) { |
||||
- rc = rc < 0 ? -errno : -EINVAL; |
||||
+ rc = parse_proc_stat(f, &p->pid, &p->state, &p->ppid); |
||||
+ if (rc < 0) |
||||
goto done; |
||||
- } |
||||
rc = 0; |
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->ns_ids); i++) { |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,757 @@
@@ -0,0 +1,757 @@
|
||||
From c465ce9765273e8e1227b192e1917826ac4eaaf7 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Thu, 31 May 2018 11:13:31 +0200 |
||||
Subject: [PATCH 152/173] libsmartcols: add basic tools necessary for new |
||||
version |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1561350 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
configure.ac | 3 + |
||||
include/carefulputc.h | 96 +++++++++++++++++++++++++++- |
||||
include/colors.h | 5 ++ |
||||
include/mbsalign.h | 9 ++- |
||||
include/strutils.h | 13 ++-- |
||||
include/ttyutils.h | 1 + |
||||
lib/Makemodule.am | 1 + |
||||
lib/color-names.c | 57 +++++++++++++++++ |
||||
lib/mbsalign.c | 172 +++++++++++++++++++++++++++++++++++++++++--------- |
||||
lib/ttyutils.c | 52 +++++++++++++++ |
||||
libfdisk/src/ask.c | 4 +- |
||||
11 files changed, 373 insertions(+), 40 deletions(-) |
||||
create mode 100644 lib/color-names.c |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index d561e01d0..8cf317dc0 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -133,6 +133,9 @@ AC_SUBST([BSD_WARN_CFLAGS]) |
||||
dnl libtool-2 |
||||
LT_INIT |
||||
|
||||
+dnl check supported linker flags |
||||
+AX_CHECK_VSCRIPT |
||||
+ |
||||
m4_ifndef([PKG_PROG_PKG_CONFIG], |
||||
[m4_fatal([Could not locate the pkg-config autoconf |
||||
macros. These are usually located in /usr/share/aclocal/pkg.m4. |
||||
diff --git a/include/carefulputc.h b/include/carefulputc.h |
||||
index a54498cfd..613d94c1e 100644 |
||||
--- a/include/carefulputc.h |
||||
+++ b/include/carefulputc.h |
||||
@@ -26,7 +26,87 @@ static inline int carefulputc(int c, FILE *fp) { |
||||
return (ret < 0) ? EOF : 0; |
||||
} |
||||
|
||||
-static inline void fputs_quoted(const char *data, FILE *out) |
||||
+/* |
||||
+ * Backported for RHEL7.6 libsmartcols |
||||
+ */ |
||||
+ |
||||
+/* |
||||
+ * Requirements enumerated via testing (V8, Firefox, IE11): |
||||
+ * |
||||
+ * var charsToEscape = []; |
||||
+ * for (var i = 0; i < 65535; i += 1) { |
||||
+ * try { |
||||
+ * JSON.parse('{"sample": "' + String.fromCodePoint(i) + '"}'); |
||||
+ * } catch (e) { |
||||
+ * charsToEscape.push(i); |
||||
+ * } |
||||
+ * } |
||||
+ */ |
||||
+static inline void fputs_quoted_case_json(const char *data, FILE *out, int dir) |
||||
+{ |
||||
+ const char *p; |
||||
+ |
||||
+ fputc('"', out); |
||||
+ for (p = data; p && *p; p++) { |
||||
+ |
||||
+ const unsigned char c = (unsigned char) *p; |
||||
+ |
||||
+ /* From http://www.json.org |
||||
+ * |
||||
+ * The double-quote and backslashes would break out a string or |
||||
+ * init an escape sequence if not escaped. |
||||
+ * |
||||
+ * Note that single-quotes and forward slashes, while they're |
||||
+ * in the JSON spec, don't break double-quoted strings. |
||||
+ */ |
||||
+ if (c == '"' || c == '\\') { |
||||
+ fputc('\\', out); |
||||
+ fputc(c, out); |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
+ /* All non-control characters OK; do the case swap as required. */ |
||||
+ if (c >= 0x20) { |
||||
+ fputc(dir == 1 ? toupper(c) : |
||||
+ dir == -1 ? tolower(c) : *p, out); |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
+ /* In addition, all chars under ' ' break Node's/V8/Chrome's, and |
||||
+ * Firefox's JSON.parse function |
||||
+ */ |
||||
+ switch (c) { |
||||
+ /* Handle short-hand cases to reduce output size. C |
||||
+ * has most of the same stuff here, so if there's an |
||||
+ * "Escape for C" function somewhere in the STL, we |
||||
+ * should probably be using it. |
||||
+ */ |
||||
+ case '\b': |
||||
+ fputs("\\b", out); |
||||
+ break; |
||||
+ case '\t': |
||||
+ fputs("\\t", out); |
||||
+ break; |
||||
+ case '\n': |
||||
+ fputs("\\n", out); |
||||
+ break; |
||||
+ case '\f': |
||||
+ fputs("\\f", out); |
||||
+ break; |
||||
+ case '\r': |
||||
+ fputs("\\r", out); |
||||
+ break; |
||||
+ default: |
||||
+ /* Other assorted control characters */ |
||||
+ fprintf(out, "\\u00%02x", c); |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ fputc('"', out); |
||||
+} |
||||
+ |
||||
+ |
||||
+static inline void fputs_quoted_case(const char *data, FILE *out, int dir) |
||||
{ |
||||
const char *p; |
||||
|
||||
@@ -34,16 +114,28 @@ static inline void fputs_quoted(const char *data, FILE *out) |
||||
for (p = data; p && *p; p++) { |
||||
if ((unsigned char) *p == 0x22 || /* " */ |
||||
(unsigned char) *p == 0x5c || /* \ */ |
||||
+ (unsigned char) *p == 0x60 || /* ` */ |
||||
+ (unsigned char) *p == 0x24 || /* $ */ |
||||
!isprint((unsigned char) *p) || |
||||
iscntrl((unsigned char) *p)) { |
||||
|
||||
fprintf(out, "\\x%02x", (unsigned char) *p); |
||||
} else |
||||
- fputc(*p, out); |
||||
+ fputc(dir == 1 ? toupper(*p) : |
||||
+ dir == -1 ? tolower(*p) : |
||||
+ *p, out); |
||||
} |
||||
fputc('"', out); |
||||
} |
||||
|
||||
+#define fputs_quoted(_d, _o) fputs_quoted_case(_d, _o, 0) |
||||
+#define fputs_quoted_upper(_d, _o) fputs_quoted_case(_d, _o, 1) |
||||
+#define fputs_quoted_lower(_d, _o) fputs_quoted_case(_d, _o, -1) |
||||
+ |
||||
+#define fputs_quoted_json(_d, _o) fputs_quoted_case_json(_d, _o, 0) |
||||
+#define fputs_quoted_json_upper(_d, _o) fputs_quoted_case_json(_d, _o, 1) |
||||
+#define fputs_quoted_json_lower(_d, _o) fputs_quoted_case_json(_d, _o, -1) |
||||
+ |
||||
static inline void fputs_nonblank(const char *data, FILE *out) |
||||
{ |
||||
const char *p; |
||||
diff --git a/include/colors.h b/include/colors.h |
||||
index dd77bf6df..39c0edf46 100644 |
||||
--- a/include/colors.h |
||||
+++ b/include/colors.h |
||||
@@ -38,6 +38,11 @@ |
||||
|
||||
#define UL_COLOR_WHITE "\033[1;37m" |
||||
|
||||
+/* maximal length of human readable name of ESC seq. */ |
||||
+#define UL_COLORNAME_MAXSZ 32 |
||||
+ |
||||
+extern const char *color_sequence_from_colorname(const char *str); |
||||
+ |
||||
/* Initialize the global variable OUT_IS_TERM */ |
||||
extern int colors_init(void); |
||||
|
||||
diff --git a/include/mbsalign.h b/include/mbsalign.h |
||||
index 5eaf606e5..0c28e6f69 100644 |
||||
--- a/include/mbsalign.h |
||||
+++ b/include/mbsalign.h |
||||
@@ -46,11 +46,18 @@ extern size_t mbsalign (const char *src, char *dest, |
||||
size_t dest_size, size_t *width, |
||||
mbs_align_t align, int flags); |
||||
|
||||
+extern size_t mbsalign_with_padding (const char *src, char *dest, size_t dest_size, |
||||
+ size_t *width, mbs_align_t align, int flags, |
||||
+ int padchar); |
||||
+ |
||||
extern size_t mbs_safe_nwidth(const char *buf, size_t bufsz, size_t *sz); |
||||
extern size_t mbs_safe_width(const char *s); |
||||
|
||||
extern char *mbs_safe_encode(const char *s, size_t *width); |
||||
-extern char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf); |
||||
+extern char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf, const char *safechars); |
||||
extern size_t mbs_safe_encode_size(size_t bytes); |
||||
|
||||
+extern char *mbs_invalid_encode(const char *s, size_t *width); |
||||
+extern char *mbs_invalid_encode_to_buffer(const char *s, size_t *width, char *buf); |
||||
+ |
||||
#endif /* UTIL_LINUX_MBSALIGN_H */ |
||||
diff --git a/include/strutils.h b/include/strutils.h |
||||
index 1f028e4ed..822fb7d49 100644 |
||||
--- a/include/strutils.h |
||||
+++ b/include/strutils.h |
||||
@@ -6,6 +6,7 @@ |
||||
#include <string.h> |
||||
#include <sys/types.h> |
||||
#include <stdio.h> |
||||
+#include <errno.h> |
||||
|
||||
/* default strtoxx_or_err() exit code */ |
||||
#ifndef STRTOXX_EXIT_CODE |
||||
@@ -57,20 +58,24 @@ static inline void xstrncpy(char *dest, const char *src, size_t n) |
||||
dest[n-1] = 0; |
||||
} |
||||
|
||||
-static inline char *strdup_to_offset(void *stru, size_t offset, const char *str) |
||||
+static inline int strdup_to_offset(void *stru, size_t offset, const char *str) |
||||
{ |
||||
char *n = NULL; |
||||
- char **o = (char **) ((char *) stru + offset); |
||||
+ char **o; |
||||
|
||||
+ if (!stru) |
||||
+ return -EINVAL; |
||||
+ |
||||
+ o = (char **) ((char *) stru + offset); |
||||
if (str) { |
||||
n = strdup(str); |
||||
if (!n) |
||||
- return NULL; |
||||
+ return -ENOMEM; |
||||
} |
||||
|
||||
free(*o); |
||||
*o = n; |
||||
- return n; |
||||
+ return 0; |
||||
} |
||||
|
||||
#define strdup_to_struct_member(_s, _m, _str) \ |
||||
diff --git a/include/ttyutils.h b/include/ttyutils.h |
||||
index 13495ba96..47fe34472 100644 |
||||
--- a/include/ttyutils.h |
||||
+++ b/include/ttyutils.h |
||||
@@ -47,6 +47,7 @@ struct chardata { |
||||
(ptr)->capslock = 0; \ |
||||
} while (0) |
||||
|
||||
+extern int get_terminal_dimension(int *cols, int *lines); |
||||
extern int get_terminal_width(void); |
||||
extern int get_terminal_name(int fd, const char **path, const char **name, |
||||
const char **number); |
||||
diff --git a/lib/Makemodule.am b/lib/Makemodule.am |
||||
index acae27afb..714233c40 100644 |
||||
--- a/lib/Makemodule.am |
||||
+++ b/lib/Makemodule.am |
||||
@@ -6,6 +6,7 @@ libcommon_la_SOURCES = \ |
||||
lib/blkdev.c \ |
||||
lib/canonicalize.c \ |
||||
lib/colors.c \ |
||||
+ lib/color-names.c \ |
||||
lib/crc32.c \ |
||||
lib/env.c \ |
||||
lib/idcache.c \ |
||||
diff --git a/lib/color-names.c b/lib/color-names.c |
||||
new file mode 100644 |
||||
index 000000000..cf37670a9 |
||||
--- /dev/null |
||||
+++ b/lib/color-names.c |
||||
@@ -0,0 +1,57 @@ |
||||
+ |
||||
+#include "c.h" |
||||
+#include "colors.h" |
||||
+ |
||||
+struct ul_color_name { |
||||
+ const char *name; |
||||
+ const char *seq; |
||||
+}; |
||||
+ |
||||
+/* |
||||
+ * qsort/bsearch buddy |
||||
+ */ |
||||
+static int cmp_color_name(const void *a0, const void *b0) |
||||
+{ |
||||
+ struct ul_color_name *a = (struct ul_color_name *) a0, |
||||
+ *b = (struct ul_color_name *) b0; |
||||
+ return strcmp(a->name, b->name); |
||||
+} |
||||
+ |
||||
+/* |
||||
+ * Maintains human readable color names |
||||
+ */ |
||||
+const char *color_sequence_from_colorname(const char *str) |
||||
+{ |
||||
+ static const struct ul_color_name basic_schemes[] = { |
||||
+ { "black", UL_COLOR_BLACK }, |
||||
+ { "blink", UL_COLOR_BLINK }, |
||||
+ { "blue", UL_COLOR_BLUE }, |
||||
+ { "bold", UL_COLOR_BOLD }, |
||||
+ { "brown", UL_COLOR_BROWN }, |
||||
+ { "cyan", UL_COLOR_CYAN }, |
||||
+ { "darkgray", UL_COLOR_DARK_GRAY }, |
||||
+ { "gray", UL_COLOR_GRAY }, |
||||
+ { "green", UL_COLOR_GREEN }, |
||||
+ { "halfbright", UL_COLOR_HALFBRIGHT }, |
||||
+ { "lightblue", UL_COLOR_BOLD_BLUE }, |
||||
+ { "lightcyan", UL_COLOR_BOLD_CYAN }, |
||||
+ { "lightgray,", UL_COLOR_GRAY }, |
||||
+ { "lightgreen", UL_COLOR_BOLD_GREEN }, |
||||
+ { "lightmagenta", UL_COLOR_BOLD_MAGENTA }, |
||||
+ { "lightred", UL_COLOR_BOLD_RED }, |
||||
+ { "magenta", UL_COLOR_MAGENTA }, |
||||
+ { "red", UL_COLOR_RED }, |
||||
+ { "reset", UL_COLOR_RESET, }, |
||||
+ { "reverse", UL_COLOR_REVERSE }, |
||||
+ { "yellow", UL_COLOR_BOLD_YELLOW }, |
||||
+ }; |
||||
+ struct ul_color_name key = { .name = (char *) str }, *res; |
||||
+ |
||||
+ if (!str) |
||||
+ return NULL; |
||||
+ |
||||
+ res = bsearch(&key, basic_schemes, ARRAY_SIZE(basic_schemes), |
||||
+ sizeof(struct ul_color_name), |
||||
+ cmp_color_name); |
||||
+ return res ? res->seq : NULL; |
||||
+} |
||||
diff --git a/lib/mbsalign.c b/lib/mbsalign.c |
||||
index b307d19f7..8fdab9ee9 100644 |
||||
--- a/lib/mbsalign.c |
||||
+++ b/lib/mbsalign.c |
||||
@@ -27,9 +27,9 @@ |
||||
|
||||
#include "c.h" |
||||
#include "mbsalign.h" |
||||
+#include "strutils.h" |
||||
#include "widechar.h" |
||||
|
||||
-#ifdef HAVE_WIDECHAR |
||||
/* Replace non printable chars. |
||||
Note \t and \n etc. are non printable. |
||||
Return 1 if replacement made, 0 otherwise. */ |
||||
@@ -43,17 +43,19 @@ |
||||
*/ |
||||
size_t mbs_safe_nwidth(const char *buf, size_t bufsz, size_t *sz) |
||||
{ |
||||
- mbstate_t st; |
||||
const char *p = buf, *last = buf; |
||||
size_t width = 0, bytes = 0; |
||||
|
||||
+#ifdef HAVE_WIDECHAR |
||||
+ mbstate_t st; |
||||
memset(&st, 0, sizeof(st)); |
||||
- |
||||
+#endif |
||||
if (p && *p && bufsz) |
||||
last = p + (bufsz - 1); |
||||
|
||||
while (p && *p && p <= last) { |
||||
- if (iscntrl((unsigned char) *p)) { |
||||
+ if ((p < last && *p == '\\' && *(p + 1) == 'x') |
||||
+ || iscntrl((unsigned char) *p)) { |
||||
width += 4, bytes += 4; /* *p encoded to \x?? */ |
||||
p++; |
||||
} |
||||
@@ -106,28 +108,36 @@ size_t mbs_safe_width(const char *s) |
||||
|
||||
/* |
||||
* Copy @s to @buf and replace control and non-printable chars with |
||||
- * \x?? hex sequence. The @width returns number of cells. |
||||
+ * \x?? hex sequence. The @width returns number of cells. The @safechars |
||||
+ * are not encoded. |
||||
* |
||||
* The @buf has to be big enough to store mbs_safe_encode_size(strlen(s))) |
||||
* bytes. |
||||
*/ |
||||
-char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf) |
||||
+char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf, const char *safechars) |
||||
{ |
||||
- mbstate_t st; |
||||
const char *p = s; |
||||
char *r; |
||||
size_t sz = s ? strlen(s) : 0; |
||||
|
||||
+#ifdef HAVE_WIDECHAR |
||||
+ mbstate_t st; |
||||
+ memset(&st, 0, sizeof(st)); |
||||
+#endif |
||||
if (!sz || !buf) |
||||
return NULL; |
||||
|
||||
- memset(&st, 0, sizeof(st)); |
||||
- |
||||
r = buf; |
||||
*width = 0; |
||||
|
||||
while (p && *p) { |
||||
- if (iscntrl((unsigned char) *p)) { |
||||
+ if (safechars && strchr(safechars, *p)) { |
||||
+ *r++ = *p++; |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
+ if ((*p == '\\' && *(p + 1) == 'x') |
||||
+ || iscntrl((unsigned char) *p)) { |
||||
sprintf(r, "\\x%02x", (unsigned char) *p); |
||||
r += 4; |
||||
*width += 4; |
||||
@@ -152,13 +162,13 @@ char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf) |
||||
r += 4; |
||||
*width += 4; |
||||
} else { |
||||
- width++; |
||||
+ (*width)++; |
||||
*r++ = *p; |
||||
} |
||||
} else if (!iswprint(wc)) { |
||||
size_t i; |
||||
for (i = 0; i < len; i++) { |
||||
- sprintf(r, "\\x%02x", (unsigned char) *p); |
||||
+ sprintf(r, "\\x%02x", (unsigned char) p[i]); |
||||
r += 4; |
||||
*width += 4; |
||||
} |
||||
@@ -177,13 +187,76 @@ char *mbs_safe_encode_to_buffer(const char *s, size_t *width, char *buf) |
||||
*width += 4; |
||||
} else { |
||||
*r++ = *p++; |
||||
- *width++; |
||||
+ (*width)++; |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
*r = '\0'; |
||||
+ return buf; |
||||
+} |
||||
|
||||
+/* |
||||
+ * Copy @s to @buf and replace broken sequences to \x?? hex sequence. The |
||||
+ * @width returns number of cells. The @safechars are not encoded. |
||||
+ * |
||||
+ * The @buf has to be big enough to store mbs_safe_encode_size(strlen(s))) |
||||
+ * bytes. |
||||
+ */ |
||||
+char *mbs_invalid_encode_to_buffer(const char *s, size_t *width, char *buf) |
||||
+{ |
||||
+ const char *p = s; |
||||
+ char *r; |
||||
+ size_t sz = s ? strlen(s) : 0; |
||||
+ |
||||
+#ifdef HAVE_WIDECHAR |
||||
+ mbstate_t st; |
||||
+ memset(&st, 0, sizeof(st)); |
||||
+#endif |
||||
+ if (!sz || !buf) |
||||
+ return NULL; |
||||
+ |
||||
+ r = buf; |
||||
+ *width = 0; |
||||
+ |
||||
+ while (p && *p) { |
||||
+#ifdef HAVE_WIDECHAR |
||||
+ wchar_t wc; |
||||
+ size_t len = mbrtowc(&wc, p, MB_CUR_MAX, &st); |
||||
+#else |
||||
+ size_t len = 1; |
||||
+#endif |
||||
+ |
||||
+ if (len == 0) |
||||
+ break; /* end of string */ |
||||
+ |
||||
+ if (len == (size_t) -1 || len == (size_t) -2) { |
||||
+ len = 1; |
||||
+ /* |
||||
+ * Not valid multibyte sequence -- maybe it's |
||||
+ * printable char according to the current locales. |
||||
+ */ |
||||
+ if (!isprint((unsigned char) *p)) { |
||||
+ sprintf(r, "\\x%02x", (unsigned char) *p); |
||||
+ r += 4; |
||||
+ *width += 4; |
||||
+ } else { |
||||
+ (*width)++; |
||||
+ *r++ = *p; |
||||
+ } |
||||
+ } else if (*p == '\\' && *(p + 1) == 'x') { |
||||
+ sprintf(r, "\\x%02x", (unsigned char) *p); |
||||
+ r += 4; |
||||
+ *width += 4; |
||||
+ } else { |
||||
+ memcpy(r, p, len); |
||||
+ r += len; |
||||
+ *width += wcwidth(wc); |
||||
+ } |
||||
+ p += len; |
||||
+ } |
||||
+ |
||||
+ *r = '\0'; |
||||
return buf; |
||||
} |
||||
|
||||
@@ -199,17 +272,39 @@ size_t mbs_safe_encode_size(size_t bytes) |
||||
char *mbs_safe_encode(const char *s, size_t *width) |
||||
{ |
||||
size_t sz = s ? strlen(s) : 0; |
||||
- char *buf; |
||||
+ char *buf, *ret = NULL; |
||||
|
||||
if (!sz) |
||||
return NULL; |
||||
buf = malloc(mbs_safe_encode_size(sz)); |
||||
- if (!buf) |
||||
- return NULL; |
||||
+ if (buf) |
||||
+ ret = mbs_safe_encode_to_buffer(s, width, buf, NULL); |
||||
+ if (!ret) |
||||
+ free(buf); |
||||
+ return ret; |
||||
+} |
||||
|
||||
- return mbs_safe_encode_to_buffer(s, width, buf); |
||||
+/* |
||||
+ * Returns allocated string where all broken widechars chars are |
||||
+ * replaced with \x?? hex sequence. |
||||
+ */ |
||||
+char *mbs_invalid_encode(const char *s, size_t *width) |
||||
+{ |
||||
+ size_t sz = s ? strlen(s) : 0; |
||||
+ char *buf, *ret = NULL; |
||||
+ |
||||
+ if (!sz) |
||||
+ return NULL; |
||||
+ buf = malloc(mbs_safe_encode_size(sz)); |
||||
+ if (buf) |
||||
+ ret = mbs_invalid_encode_to_buffer(s, width, buf); |
||||
+ if (!ret) |
||||
+ free(buf); |
||||
+ return ret; |
||||
} |
||||
|
||||
+#ifdef HAVE_WIDECHAR |
||||
+ |
||||
static bool |
||||
wc_ensure_printable (wchar_t *wchars) |
||||
{ |
||||
@@ -246,6 +341,7 @@ wc_truncate (wchar_t *wc, size_t width) |
||||
} |
||||
if (cells + next_cells > width) |
||||
break; |
||||
+ |
||||
cells += next_cells; |
||||
wc++; |
||||
} |
||||
@@ -273,7 +369,7 @@ rpl_wcswidth (const wchar_t *s, size_t n) |
||||
|
||||
return ret; |
||||
} |
||||
-#endif |
||||
+#endif /* HAVE_WIDECHAR */ |
||||
|
||||
/* Truncate multi-byte string to @width and returns number of |
||||
* bytes of the new string @str, and in @width returns number |
||||
@@ -290,7 +386,7 @@ mbs_truncate(char *str, size_t *width) |
||||
if (sz == (ssize_t) -1) |
||||
goto done; |
||||
|
||||
- wcs = malloc((sz + 1) * sizeof(wchar_t)); |
||||
+ wcs = calloc(1, (sz + 1) * sizeof(wchar_t)); |
||||
if (!wcs) |
||||
goto done; |
||||
|
||||
@@ -301,7 +397,7 @@ mbs_truncate(char *str, size_t *width) |
||||
done: |
||||
free(wcs); |
||||
#else |
||||
- if (*width < bytes) |
||||
+ if (bytes >= 0 && *width < (size_t) bytes) |
||||
bytes = *width; |
||||
#endif |
||||
if (bytes >= 0) |
||||
@@ -315,16 +411,23 @@ done: |
||||
A pointer to the terminating NUL is returned. */ |
||||
|
||||
static char* |
||||
-mbs_align_pad (char *dest, const char* dest_end, size_t n_spaces) |
||||
+mbs_align_pad (char *dest, const char* dest_end, size_t n_spaces, int padchar) |
||||
{ |
||||
/* FIXME: Should we pad with "figure space" (\u2007) |
||||
if non ascii data present? */ |
||||
- while (n_spaces-- && (dest < dest_end)) |
||||
- *dest++ = ' '; |
||||
+ for (/* nothing */; n_spaces && (dest < dest_end); n_spaces--) |
||||
+ *dest++ = padchar; |
||||
*dest = '\0'; |
||||
return dest; |
||||
} |
||||
|
||||
+size_t |
||||
+mbsalign (const char *src, char *dest, size_t dest_size, |
||||
+ size_t *width, mbs_align_t align, int flags) |
||||
+{ |
||||
+ return mbsalign_with_padding(src, dest, dest_size, width, align, flags, ' '); |
||||
+} |
||||
+ |
||||
/* Align a string, SRC, in a field of *WIDTH columns, handling multi-byte |
||||
characters; write the result into the DEST_SIZE-byte buffer, DEST. |
||||
ALIGNMENT specifies whether to left- or right-justify or to center. |
||||
@@ -339,8 +442,14 @@ mbs_align_pad (char *dest, const char* dest_end, size_t n_spaces) |
||||
Update *WIDTH to indicate how many columns were used before padding. */ |
||||
|
||||
size_t |
||||
-mbsalign (const char *src, char *dest, size_t dest_size, |
||||
- size_t *width, mbs_align_t align, int flags) |
||||
+mbsalign_with_padding (const char *src, char *dest, size_t dest_size, |
||||
+ size_t *width, mbs_align_t align, |
||||
+#ifdef HAVE_WIDECHAR |
||||
+ int flags, |
||||
+#else |
||||
+ int flags __attribute__((__unused__)), |
||||
+#endif |
||||
+ int padchar) |
||||
{ |
||||
size_t ret = -1; |
||||
size_t src_size = strlen (src) + 1; |
||||
@@ -350,10 +459,11 @@ mbsalign (const char *src, char *dest, size_t dest_size, |
||||
size_t n_cols = src_size - 1; |
||||
size_t n_used_bytes = n_cols; /* Not including NUL */ |
||||
size_t n_spaces = 0, space_left; |
||||
+ |
||||
+#ifdef HAVE_WIDECHAR |
||||
bool conversion = false; |
||||
bool wc_enabled = false; |
||||
|
||||
-#ifdef HAVE_WIDECHAR |
||||
/* In multi-byte locales convert to wide characters |
||||
to allow easy truncation. Also determine number |
||||
of screen columns used. */ |
||||
@@ -407,9 +517,9 @@ mbsalign (const char *src, char *dest, size_t dest_size, |
||||
n_cols = wc_truncate (str_wc, *width); |
||||
n_used_bytes = wcstombs (newstr, str_wc, src_size); |
||||
} |
||||
-#endif |
||||
|
||||
mbsalign_unibyte: |
||||
+#endif |
||||
|
||||
if (n_cols > *width) /* Unibyte truncation required. */ |
||||
{ |
||||
@@ -451,14 +561,14 @@ mbsalign_unibyte: |
||||
abort(); |
||||
} |
||||
|
||||
- dest = mbs_align_pad (dest, dest_end, start_spaces); |
||||
+ dest = mbs_align_pad (dest, dest_end, start_spaces, padchar); |
||||
space_left = dest_end - dest; |
||||
dest = mempcpy (dest, str_to_print, min (n_used_bytes, space_left)); |
||||
- mbs_align_pad (dest, dest_end, end_spaces); |
||||
+ mbs_align_pad (dest, dest_end, end_spaces, padchar); |
||||
} |
||||
- |
||||
+#ifdef HAVE_WIDECHAR |
||||
mbsalign_cleanup: |
||||
- |
||||
+#endif |
||||
free (str_wc); |
||||
free (newstr); |
||||
|
||||
diff --git a/lib/ttyutils.c b/lib/ttyutils.c |
||||
index ea551e26c..91497e763 100644 |
||||
--- a/lib/ttyutils.c |
||||
+++ b/lib/ttyutils.c |
||||
@@ -9,6 +9,58 @@ |
||||
#include "c.h" |
||||
#include "ttyutils.h" |
||||
|
||||
+/* |
||||
+ * Backported for RHEL7.6 libsmartcols |
||||
+ */ |
||||
+static int get_env_int(const char *name) |
||||
+{ |
||||
+ const char *cp = getenv(name); |
||||
+ |
||||
+ if (cp) { |
||||
+ char *end = NULL; |
||||
+ long x; |
||||
+ |
||||
+ errno = 0; |
||||
+ x = strtol(cp, &end, 10); |
||||
+ |
||||
+ if (errno == 0 && end && *end == '\0' && end > cp && |
||||
+ x > 0 && x <= INT_MAX) |
||||
+ return x; |
||||
+ } |
||||
+ |
||||
+ return -1; |
||||
+} |
||||
+ |
||||
+int get_terminal_dimension(int *cols, int *lines) |
||||
+{ |
||||
+ int c = 0, l = 0; |
||||
+ |
||||
+#if defined(TIOCGWINSZ) |
||||
+ struct winsize w_win; |
||||
+ if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &w_win) == 0) { |
||||
+ c = w_win.ws_col; |
||||
+ l = w_win.ws_row; |
||||
+ } |
||||
+#elif defined(TIOCGSIZE) |
||||
+ struct ttysize t_win; |
||||
+ if (ioctl (STDOUT_FILENO, TIOCGSIZE, &t_win) == 0) { |
||||
+ c = t_win.ts_cols; |
||||
+ 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) |
||||
+ *cols = c; |
||||
+ if (lines) |
||||
+ *lines = l; |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
int get_terminal_width(void) |
||||
{ |
||||
#ifdef TIOCGSIZE |
||||
diff --git a/libfdisk/src/ask.c b/libfdisk/src/ask.c |
||||
index cdb4d0124..a10f3dc82 100644 |
||||
--- a/libfdisk/src/ask.c |
||||
+++ b/libfdisk/src/ask.c |
||||
@@ -42,7 +42,7 @@ const char *fdisk_ask_get_query(struct fdisk_ask *ask) |
||||
int fdisk_ask_set_query(struct fdisk_ask *ask, const char *str) |
||||
{ |
||||
assert(ask); |
||||
- return !strdup_to_struct_member(ask, query, str) ? -ENOMEM : 0; |
||||
+ return strdup_to_struct_member(ask, query, str); |
||||
} |
||||
|
||||
int fdisk_ask_get_type(struct fdisk_ask *ask) |
||||
@@ -90,7 +90,7 @@ const char *fdisk_ask_number_get_range(struct fdisk_ask *ask) |
||||
int fdisk_ask_number_set_range(struct fdisk_ask *ask, const char *range) |
||||
{ |
||||
assert(ask); |
||||
- return !strdup_to_struct_member(ask, data.num.range, range) ? -ENOMEM : 0; |
||||
+ return strdup_to_struct_member(ask, data.num.range, range); |
||||
} |
||||
|
||||
uint64_t fdisk_ask_number_get_default(struct fdisk_ask *ask) |
||||
-- |
||||
2.14.4 |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,990 @@
@@ -0,0 +1,990 @@
|
||||
From 83f79678dbb9cb48969968fa4df57d98c67a321d Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Thu, 31 May 2018 11:44:35 +0200 |
||||
Subject: [PATCH 154/173] tests: backport libsmartcols tests |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1561350 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
tests/commands.sh | 2 + |
||||
tests/expected/libsmartcols/fromfile | 1 + |
||||
.../libsmartcols/fromfile-column-separator | 11 + |
||||
tests/expected/libsmartcols/fromfile-export | 10 + |
||||
tests/expected/libsmartcols/fromfile-hidden | 11 + |
||||
tests/expected/libsmartcols/fromfile-noextremes | 12 ++ |
||||
tests/expected/libsmartcols/fromfile-raw | 11 + |
||||
tests/expected/libsmartcols/fromfile-right | 11 + |
||||
tests/expected/libsmartcols/fromfile-right-maxout | 11 + |
||||
tests/expected/libsmartcols/fromfile-strictwidth | 11 + |
||||
tests/expected/libsmartcols/fromfile-tree | 11 + |
||||
tests/expected/libsmartcols/fromfile-tree-end | 11 + |
||||
tests/expected/libsmartcols/fromfile-tree-json | 29 +++ |
||||
tests/expected/libsmartcols/fromfile-tree-middle | 11 + |
||||
tests/expected/libsmartcols/fromfile-trunc | 11 + |
||||
tests/expected/libsmartcols/fromfile-wrap | 17 ++ |
||||
tests/expected/libsmartcols/fromfile-wrap-tree | 18 ++ |
||||
tests/expected/libsmartcols/fromfile-wrapnl | 19 ++ |
||||
tests/expected/libsmartcols/fromfile-wrapnl-tree | 19 ++ |
||||
tests/expected/libsmartcols/title | 16 ++ |
||||
tests/ts/libsmartcols/files/col-hidden | 3 + |
||||
tests/ts/libsmartcols/files/col-id | 3 + |
||||
tests/ts/libsmartcols/files/col-name | 3 + |
||||
tests/ts/libsmartcols/files/col-noextremes | 3 + |
||||
tests/ts/libsmartcols/files/col-number | 3 + |
||||
tests/ts/libsmartcols/files/col-parent | 3 + |
||||
tests/ts/libsmartcols/files/col-strict | 3 + |
||||
tests/ts/libsmartcols/files/col-string | 3 + |
||||
tests/ts/libsmartcols/files/col-tree | 3 + |
||||
tests/ts/libsmartcols/files/col-trunc | 3 + |
||||
tests/ts/libsmartcols/files/col-wrap | 3 + |
||||
tests/ts/libsmartcols/files/col-wrapnl | 3 + |
||||
tests/ts/libsmartcols/files/data-id | 10 + |
||||
tests/ts/libsmartcols/files/data-number | 10 + |
||||
tests/ts/libsmartcols/files/data-number-tiny | 10 + |
||||
tests/ts/libsmartcols/files/data-parent | 10 + |
||||
tests/ts/libsmartcols/files/data-string | 10 + |
||||
tests/ts/libsmartcols/files/data-string-extreme | 10 + |
||||
tests/ts/libsmartcols/files/data-string-long | 10 + |
||||
tests/ts/libsmartcols/files/data-string-nl | 10 + |
||||
tests/ts/libsmartcols/fromfile | 240 +++++++++++++++++++++ |
||||
tests/ts/libsmartcols/title | 28 +++ |
||||
42 files changed, 637 insertions(+) |
||||
create mode 100644 tests/expected/libsmartcols/fromfile |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-column-separator |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-export |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-hidden |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-noextremes |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-raw |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-right |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-right-maxout |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-strictwidth |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-tree |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-tree-end |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-tree-json |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-tree-middle |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-trunc |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-wrap |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-wrap-tree |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-wrapnl |
||||
create mode 100644 tests/expected/libsmartcols/fromfile-wrapnl-tree |
||||
create mode 100644 tests/expected/libsmartcols/title |
||||
create mode 100644 tests/ts/libsmartcols/files/col-hidden |
||||
create mode 100644 tests/ts/libsmartcols/files/col-id |
||||
create mode 100644 tests/ts/libsmartcols/files/col-name |
||||
create mode 100644 tests/ts/libsmartcols/files/col-noextremes |
||||
create mode 100644 tests/ts/libsmartcols/files/col-number |
||||
create mode 100644 tests/ts/libsmartcols/files/col-parent |
||||
create mode 100644 tests/ts/libsmartcols/files/col-strict |
||||
create mode 100644 tests/ts/libsmartcols/files/col-string |
||||
create mode 100644 tests/ts/libsmartcols/files/col-tree |
||||
create mode 100644 tests/ts/libsmartcols/files/col-trunc |
||||
create mode 100644 tests/ts/libsmartcols/files/col-wrap |
||||
create mode 100644 tests/ts/libsmartcols/files/col-wrapnl |
||||
create mode 100644 tests/ts/libsmartcols/files/data-id |
||||
create mode 100644 tests/ts/libsmartcols/files/data-number |
||||
create mode 100644 tests/ts/libsmartcols/files/data-number-tiny |
||||
create mode 100644 tests/ts/libsmartcols/files/data-parent |
||||
create mode 100644 tests/ts/libsmartcols/files/data-string |
||||
create mode 100644 tests/ts/libsmartcols/files/data-string-extreme |
||||
create mode 100644 tests/ts/libsmartcols/files/data-string-long |
||||
create mode 100644 tests/ts/libsmartcols/files/data-string-nl |
||||
create mode 100755 tests/ts/libsmartcols/fromfile |
||||
create mode 100755 tests/ts/libsmartcols/title |
||||
|
||||
diff --git a/tests/commands.sh b/tests/commands.sh |
||||
index e769b5dac..96b8dc97c 100644 |
||||
--- a/tests/commands.sh |
||||
+++ b/tests/commands.sh |
||||
@@ -20,6 +20,8 @@ TS_HELPER_PARTITIONS="$top_builddir/sample-partitions" |
||||
TS_HELPER_PATHS="$top_builddir/test_pathnames" |
||||
TS_HELPER_STRUTILS="$top_builddir/test_strutils" |
||||
TS_HELPER_SYSINFO="$top_builddir/test_sysinfo" |
||||
+TS_HELPER_LIBSMARTCOLS_FROMFILE="$top_builddir/sample-scols-fromfile" |
||||
+TS_HELPER_LIBSMARTCOLS_TITLE="$top_builddir/sample-scols-title" |
||||
|
||||
# paths to commands |
||||
TS_CMD_BLKID=${TS_CMD_BLKID-"$top_builddir/blkid"} |
||||
diff --git a/tests/expected/libsmartcols/fromfile b/tests/expected/libsmartcols/fromfile |
||||
new file mode 100644 |
||||
index 000000000..4155aa36f |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile |
||||
@@ -0,0 +1 @@ |
||||
+...done. |
||||
diff --git a/tests/expected/libsmartcols/fromfile-column-separator b/tests/expected/libsmartcols/fromfile-column-separator |
||||
new file mode 100644 |
||||
index 000000000..8c5aa2aff |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-column-separator |
||||
@@ -0,0 +1,11 @@ |
||||
+NAME | NUM|TRUNC |
||||
+aaaa | 0|qqqqqqqqqqqqqqqqqX |
||||
+bbb | 100|dddddddddddddX |
||||
+ccccc | 21|ffffffffffffffffffffffffffffffffffffffffX |
||||
+dddddd| 3|ssssssssssX |
||||
+ee | 411|ddddddddddddddddddddddddddX |
||||
+ffff | 5111|jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX |
||||
+gggggg|678993321|mmmmmmmmmmmmmmmmmmmX |
||||
+hhh | 7666666|lllllllllllllllllllllllllllllllllllllX |
||||
+iiiiii| 8765|yyyyyyyyyyyyyyyyyyyyyyyyyyyyX |
||||
+jj | 987456|pppppppppX |
||||
diff --git a/tests/expected/libsmartcols/fromfile-export b/tests/expected/libsmartcols/fromfile-export |
||||
new file mode 100644 |
||||
index 000000000..f63afd882 |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-export |
||||
@@ -0,0 +1,10 @@ |
||||
+NAME="aaaa" NUM="0" TRUNC="qqqqqqqqqqqqqqqqqX" |
||||
+NAME="bbb" NUM="100" TRUNC="dddddddddddddX" |
||||
+NAME="ccccc" NUM="21" TRUNC="ffffffffffffffffffffffffffffffffffffffffX" |
||||
+NAME="dddddd" NUM="3" TRUNC="ssssssssssX" |
||||
+NAME="ee" NUM="411" TRUNC="ddddddddddddddddddddddddddX" |
||||
+NAME="ffff" NUM="5111" TRUNC="jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX" |
||||
+NAME="gggggg" NUM="678993321" TRUNC="mmmmmmmmmmmmmmmmmmmX" |
||||
+NAME="hhh" NUM="7666666" TRUNC="lllllllllllllllllllllllllllllllllllllX" |
||||
+NAME="iiiiii" NUM="8765" TRUNC="yyyyyyyyyyyyyyyyyyyyyyyyyyyyX" |
||||
+NAME="jj" NUM="987456" TRUNC="pppppppppX" |
||||
diff --git a/tests/expected/libsmartcols/fromfile-hidden b/tests/expected/libsmartcols/fromfile-hidden |
||||
new file mode 100644 |
||||
index 000000000..cf50bcb3e |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-hidden |
||||
@@ -0,0 +1,11 @@ |
||||
+NAME NUM |
||||
+aaaa 0 |
||||
+bbb 100 |
||||
+ccccc 21 |
||||
+dddddd 3 |
||||
+ee 411 |
||||
+ffff 5111 |
||||
+gggggg 678993321 |
||||
+hhh 7666666 |
||||
+iiiiii 8765 |
||||
+jj 987456 |
||||
diff --git a/tests/expected/libsmartcols/fromfile-noextremes b/tests/expected/libsmartcols/fromfile-noextremes |
||||
new file mode 100644 |
||||
index 000000000..4bac08070 |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-noextremes |
||||
@@ -0,0 +1,12 @@ |
||||
+NAME NOEXTREME NUM NAME NUM |
||||
+aaaa qqqqqqX 0 aaaa 0 |
||||
+bbb ddddddddX 100 bbb 100 |
||||
+ccccc ffffffffffffffffffffffffffffffffffX |
||||
+ 21 ccccc 21 |
||||
+dddddd sssX 3 dddddd 3 |
||||
+ee ddX 411 ee 411 |
||||
+ffff jjjjjX 5111 ffff 5111 |
||||
+gggggg mmmmmmmX 678993321 gggggg 678993321 |
||||
+hhh llllllllllX 7666666 hhh 7666666 |
||||
+iiiiii yyyyyyX 8765 iiiiii 8765 |
||||
+jj pppppX 987456 jj 987456 |
||||
diff --git a/tests/expected/libsmartcols/fromfile-raw b/tests/expected/libsmartcols/fromfile-raw |
||||
new file mode 100644 |
||||
index 000000000..cc188aaab |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-raw |
||||
@@ -0,0 +1,11 @@ |
||||
+NAME NUM TRUNC |
||||
+aaaa 0 qqqqqqqqqqqqqqqqqX |
||||
+bbb 100 dddddddddddddX |
||||
+ccccc 21 ffffffffffffffffffffffffffffffffffffffffX |
||||
+dddddd 3 ssssssssssX |
||||
+ee 411 ddddddddddddddddddddddddddX |
||||
+ffff 5111 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX |
||||
+gggggg 678993321 mmmmmmmmmmmmmmmmmmmX |
||||
+hhh 7666666 lllllllllllllllllllllllllllllllllllllX |
||||
+iiiiii 8765 yyyyyyyyyyyyyyyyyyyyyyyyyyyyX |
||||
+jj 987456 pppppppppX |
||||
diff --git a/tests/expected/libsmartcols/fromfile-right b/tests/expected/libsmartcols/fromfile-right |
||||
new file mode 100644 |
||||
index 000000000..d78285a13 |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-right |
||||
@@ -0,0 +1,11 @@ |
||||
+NAME NUM STRINGS |
||||
+aaaa 0 qqqqqqqqqqqqqqqqqX |
||||
+bbb 100 dddddddddddddX |
||||
+ccccc 21 ffffffffffffffffffffffffffffffffffffffffX |
||||
+dddddd 3 ssssssssssX |
||||
+ee 411 ddddddddddddddddddddddddddX |
||||
+ffff 5111 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX |
||||
+gggggg 678993321 mmmmmmmmmmmmmmmmmmmX |
||||
+hhh 7666666 lllllllllllllllllllllllllllllllllllllX |
||||
+iiiiii 8765 yyyyyyyyyyyyyyyyyyyyyyyyyyyyX |
||||
+jj 987456 pppppppppX |
||||
diff --git a/tests/expected/libsmartcols/fromfile-right-maxout b/tests/expected/libsmartcols/fromfile-right-maxout |
||||
new file mode 100644 |
||||
index 000000000..3bcb65abd |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-right-maxout |
||||
@@ -0,0 +1,11 @@ |
||||
+NAME NUM |
||||
+aaaa 0 |
||||
+bbb 100 |
||||
+ccccc 21 |
||||
+dddddd 3 |
||||
+ee 411 |
||||
+ffff 5111 |
||||
+gggggg 678993321 |
||||
+hhh 7666666 |
||||
+iiiiii 8765 |
||||
+jj 987456 |
||||
diff --git a/tests/expected/libsmartcols/fromfile-strictwidth b/tests/expected/libsmartcols/fromfile-strictwidth |
||||
new file mode 100644 |
||||
index 000000000..41054b235 |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-strictwidth |
||||
@@ -0,0 +1,11 @@ |
||||
+NAME STRICT NUM |
||||
+aaaa 0 0 |
||||
+bbb 1 100 |
||||
+ccccc 2 21 |
||||
+dddddd 3 3 |
||||
+ee 4 411 |
||||
+ffff 5 5111 |
||||
+gggggg 6 678993321 |
||||
+hhh 7 7666666 |
||||
+iiiiii 8 8765 |
||||
+jj 9 987456 |
||||
diff --git a/tests/expected/libsmartcols/fromfile-tree b/tests/expected/libsmartcols/fromfile-tree |
||||
new file mode 100644 |
||||
index 000000000..9d345f8dc |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-tree |
||||
@@ -0,0 +1,11 @@ |
||||
+TREE ID PARENT STRINGS |
||||
+aaaa 1 0 qqqqqqqqqqqqqqqqqX |
||||
+|-bbb 2 1 dddddddddddddX |
||||
+| |-ee 5 2 ddddddddddddddddddddddddddX |
||||
+| `-ffff 6 2 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX |
||||
+|-ccccc 3 1 ffffffffffffffffffffffffffffffffffffffffX |
||||
+| `-gggggg 7 3 mmmmmmmmmmmmmmmmmmmX |
||||
+| |-hhh 8 7 lllllllllllllllllllllllllllllllllllllX |
||||
+| | `-iiiiii 9 8 yyyyyyyyyyyyyyyyyyyyyyyyyyyyX |
||||
+| `-jj 10 7 pppppppppX |
||||
+`-dddddd 4 1 ssssssssssX |
||||
diff --git a/tests/expected/libsmartcols/fromfile-tree-end b/tests/expected/libsmartcols/fromfile-tree-end |
||||
new file mode 100644 |
||||
index 000000000..41aebff56 |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-tree-end |
||||
@@ -0,0 +1,11 @@ |
||||
+ID PARENT STRINGS TREE |
||||
+ 1 0 qqqqqqqqqqqqqqqqqX aaaa |
||||
+ 2 1 dddddddddddddX |-bbb |
||||
+ 5 2 ddddddddddddddddddddddddddX | |-ee |
||||
+ 6 2 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX | `-ffff |
||||
+ 3 1 ffffffffffffffffffffffffffffffffffffffffX |-ccccc |
||||
+ 7 3 mmmmmmmmmmmmmmmmmmmX | `-gggggg |
||||
+ 8 7 lllllllllllllllllllllllllllllllllllllX | |-hhh |
||||
+ 9 8 yyyyyyyyyyyyyyyyyyyyyyyyyyyyX | | `-iiiiii |
||||
+10 7 pppppppppX | `-jj |
||||
+ 4 1 ssssssssssX `-dddddd |
||||
diff --git a/tests/expected/libsmartcols/fromfile-tree-json b/tests/expected/libsmartcols/fromfile-tree-json |
||||
new file mode 100644 |
||||
index 000000000..5b3546d0a |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-tree-json |
||||
@@ -0,0 +1,29 @@ |
||||
+{ |
||||
+ "testtable": [ |
||||
+ {"tree":"aaaa", "id":"1", "parent":"0", "strings":"qqqqqqqqqqqqqqqqqX", |
||||
+ "children": [ |
||||
+ {"tree":"bbb", "id":"2", "parent":"1", "strings":"dddddddddddddX", |
||||
+ "children": [ |
||||
+ {"tree":"ee", "id":"5", "parent":"2", "strings":"ddddddddddddddddddddddddddX"}, |
||||
+ {"tree":"ffff", "id":"6", "parent":"2", "strings":"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX"} |
||||
+ ] |
||||
+ }, |
||||
+ {"tree":"ccccc", "id":"3", "parent":"1", "strings":"ffffffffffffffffffffffffffffffffffffffffX", |
||||
+ "children": [ |
||||
+ {"tree":"gggggg", "id":"7", "parent":"3", "strings":"mmmmmmmmmmmmmmmmmmmX", |
||||
+ "children": [ |
||||
+ {"tree":"hhh", "id":"8", "parent":"7", "strings":"lllllllllllllllllllllllllllllllllllllX", |
||||
+ "children": [ |
||||
+ {"tree":"iiiiii", "id":"9", "parent":"8", "strings":"yyyyyyyyyyyyyyyyyyyyyyyyyyyyX"} |
||||
+ ] |
||||
+ }, |
||||
+ {"tree":"jj", "id":"10", "parent":"7", "strings":"pppppppppX"} |
||||
+ ] |
||||
+ } |
||||
+ ] |
||||
+ }, |
||||
+ {"tree":"dddddd", "id":"4", "parent":"1", "strings":"ssssssssssX"} |
||||
+ ] |
||||
+ } |
||||
+ ] |
||||
+} |
||||
diff --git a/tests/expected/libsmartcols/fromfile-tree-middle b/tests/expected/libsmartcols/fromfile-tree-middle |
||||
new file mode 100644 |
||||
index 000000000..b2183313c |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-tree-middle |
||||
@@ -0,0 +1,11 @@ |
||||
+ID PARENT TREE STRINGS |
||||
+ 1 0 aaaa qqqqqqqqqqqqqqqqqX |
||||
+ 2 1 |-bbb dddddddddddddX |
||||
+ 5 2 | |-ee ddddddddddddddddddddddddddX |
||||
+ 6 2 | `-ffff jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX |
||||
+ 3 1 |-ccccc ffffffffffffffffffffffffffffffffffffffffX |
||||
+ 7 3 | `-gggggg mmmmmmmmmmmmmmmmmmmX |
||||
+ 8 7 | |-hhh lllllllllllllllllllllllllllllllllllllX |
||||
+ 9 8 | | `-iiiiii yyyyyyyyyyyyyyyyyyyyyyyyyyyyX |
||||
+10 7 | `-jj pppppppppX |
||||
+ 4 1 `-dddddd ssssssssssX |
||||
diff --git a/tests/expected/libsmartcols/fromfile-trunc b/tests/expected/libsmartcols/fromfile-trunc |
||||
new file mode 100644 |
||||
index 000000000..6a095dc88 |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-trunc |
||||
@@ -0,0 +1,11 @@ |
||||
+NAME NUM TRUNC |
||||
+aaaa 0 qqqqqqqqqqqqqqqqqX |
||||
+bbb 100 dddddddddddddX |
||||
+ccccc 21 fffffffffffffffffffffff |
||||
+dddddd 3 ssssssssssX |
||||
+ee 411 ddddddddddddddddddddddd |
||||
+ffff 5111 jjjjjjjjjjjjjjjjjjjjjjj |
||||
+gggggg 678993321 mmmmmmmmmmmmmmmmmmmX |
||||
+hhh 7666666 lllllllllllllllllllllll |
||||
+iiiiii 8765 yyyyyyyyyyyyyyyyyyyyyyy |
||||
+jj 987456 pppppppppX |
||||
diff --git a/tests/expected/libsmartcols/fromfile-wrap b/tests/expected/libsmartcols/fromfile-wrap |
||||
new file mode 100644 |
||||
index 000000000..bb94f4973 |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-wrap |
||||
@@ -0,0 +1,17 @@ |
||||
+NAME NUM WRAP |
||||
+aaaa 0 qqqqqqqqqqqqqqqqqX |
||||
+bbb 100 dddddddddddddX |
||||
+ccccc 21 fffffffffffffffffffffff |
||||
+ fffffffffffffffffX |
||||
+dddddd 3 ssssssssssX |
||||
+ee 411 ddddddddddddddddddddddd |
||||
+ dddX |
||||
+ffff 5111 jjjjjjjjjjjjjjjjjjjjjjj |
||||
+ jjjjjjjjjjjjjjjjjjjjjjj |
||||
+ jjjX |
||||
+gggggg 678993321 mmmmmmmmmmmmmmmmmmmX |
||||
+hhh 7666666 lllllllllllllllllllllll |
||||
+ llllllllllllllX |
||||
+iiiiii 8765 yyyyyyyyyyyyyyyyyyyyyyy |
||||
+ yyyyyX |
||||
+jj 987456 pppppppppX |
||||
diff --git a/tests/expected/libsmartcols/fromfile-wrap-tree b/tests/expected/libsmartcols/fromfile-wrap-tree |
||||
new file mode 100644 |
||||
index 000000000..a2db7a4ac |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-wrap-tree |
||||
@@ -0,0 +1,18 @@ |
||||
+TREE ID PARENT WRAP |
||||
+aaaa 1 0 qqqqqqqqqqqqqqqqqX |
||||
+|-bbb 2 1 dddddddddddddX |
||||
+| |-ee 5 2 dddddddddddddddddddd |
||||
+| | ddddddX |
||||
+| `-ffff 6 2 jjjjjjjjjjjjjjjjjjjj |
||||
+| jjjjjjjjjjjjjjjjjjjj |
||||
+| jjjjjjjjjX |
||||
+|-ccccc 3 1 ffffffffffffffffffff |
||||
+| | ffffffffffffffffffff |
||||
+| | X |
||||
+| `-gggggg 7 3 mmmmmmmmmmmmmmmmmmmX |
||||
+| |-hhh 8 7 llllllllllllllllllll |
||||
+| | | lllllllllllllllllX |
||||
+| | `-iiiiii 9 8 yyyyyyyyyyyyyyyyyyyy |
||||
+| | yyyyyyyyX |
||||
+| `-jj 10 7 pppppppppX |
||||
+`-dddddd 4 1 ssssssssssX |
||||
diff --git a/tests/expected/libsmartcols/fromfile-wrapnl b/tests/expected/libsmartcols/fromfile-wrapnl |
||||
new file mode 100644 |
||||
index 000000000..c747ebb08 |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-wrapnl |
||||
@@ -0,0 +1,19 @@ |
||||
+NAME NUM WRAPNL |
||||
+aaaa 0 aaa |
||||
+bbb 100 bbbbb |
||||
+ccccc 21 cccc |
||||
+ CCCC |
||||
+dddddd 3 dddddddd |
||||
+ DDDD |
||||
+ DD |
||||
+ee 411 hello |
||||
+ baby |
||||
+ffff 5111 aaa |
||||
+ bbb |
||||
+ ccc |
||||
+ ddd |
||||
+gggggg 678993321 eee |
||||
+hhh 7666666 fffff |
||||
+iiiiii 8765 g |
||||
+ hhhhh |
||||
+jj 987456 ppppppppp |
||||
diff --git a/tests/expected/libsmartcols/fromfile-wrapnl-tree b/tests/expected/libsmartcols/fromfile-wrapnl-tree |
||||
new file mode 100644 |
||||
index 000000000..3862cf16a |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/fromfile-wrapnl-tree |
||||
@@ -0,0 +1,19 @@ |
||||
+TREE ID PARENT WRAPNL |
||||
+aaaa 1 0 aaa |
||||
+|-bbb 2 1 bbbbb |
||||
+| |-ee 5 2 hello |
||||
+| | baby |
||||
+| `-ffff 6 2 aaa |
||||
+| bbb |
||||
+| ccc |
||||
+| ddd |
||||
+|-ccccc 3 1 cccc |
||||
+| | CCCC |
||||
+| `-gggggg 7 3 eee |
||||
+| |-hhh 8 7 fffff |
||||
+| | `-iiiiii 9 8 g |
||||
+| | hhhhh |
||||
+| `-jj 10 7 ppppppppp |
||||
+`-dddddd 4 1 dddddddd |
||||
+ DDDD |
||||
+ DD |
||||
diff --git a/tests/expected/libsmartcols/title b/tests/expected/libsmartcols/title |
||||
new file mode 100644 |
||||
index 000000000..bb5d7225a |
||||
--- /dev/null |
||||
+++ b/tests/expected/libsmartcols/title |
||||
@@ -0,0 +1,16 @@ |
||||
+ This is right title |
||||
+NAME DATA |
||||
+foo bla bla bla |
||||
+bar alb alb alb |
||||
+This is left title (without padding) |
||||
+NAME DATA |
||||
+foo bla bla bla |
||||
+bar alb alb alb |
||||
+=======================This is center title (with padding)====================== |
||||
+NAME DATA |
||||
+foo bla bla bla |
||||
+bar alb alb alb |
||||
+This is left title (with padding)----------------------------------------------- |
||||
+NAME DATA |
||||
+foo bla bla bla |
||||
+bar alb alb alb |
||||
diff --git a/tests/ts/libsmartcols/files/col-hidden b/tests/ts/libsmartcols/files/col-hidden |
||||
new file mode 100644 |
||||
index 000000000..83182a8ee |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-hidden |
||||
@@ -0,0 +1,3 @@ |
||||
+FOO |
||||
+0 |
||||
+hidden |
||||
diff --git a/tests/ts/libsmartcols/files/col-id b/tests/ts/libsmartcols/files/col-id |
||||
new file mode 100644 |
||||
index 000000000..0188f42a0 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-id |
||||
@@ -0,0 +1,3 @@ |
||||
+ID |
||||
+0 |
||||
+right |
||||
diff --git a/tests/ts/libsmartcols/files/col-name b/tests/ts/libsmartcols/files/col-name |
||||
new file mode 100644 |
||||
index 000000000..0a98f29cf |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-name |
||||
@@ -0,0 +1,3 @@ |
||||
+NAME |
||||
+0 |
||||
+none |
||||
diff --git a/tests/ts/libsmartcols/files/col-noextremes b/tests/ts/libsmartcols/files/col-noextremes |
||||
new file mode 100644 |
||||
index 000000000..715edce7e |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-noextremes |
||||
@@ -0,0 +1,3 @@ |
||||
+NOEXTREME |
||||
+0 |
||||
+noextremes |
||||
diff --git a/tests/ts/libsmartcols/files/col-number b/tests/ts/libsmartcols/files/col-number |
||||
new file mode 100644 |
||||
index 000000000..34a70e4a4 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-number |
||||
@@ -0,0 +1,3 @@ |
||||
+NUM |
||||
+0 |
||||
+right |
||||
diff --git a/tests/ts/libsmartcols/files/col-parent b/tests/ts/libsmartcols/files/col-parent |
||||
new file mode 100644 |
||||
index 000000000..86fe08ced |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-parent |
||||
@@ -0,0 +1,3 @@ |
||||
+PARENT |
||||
+0 |
||||
+right |
||||
diff --git a/tests/ts/libsmartcols/files/col-strict b/tests/ts/libsmartcols/files/col-strict |
||||
new file mode 100644 |
||||
index 000000000..62bb96b9a |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-strict |
||||
@@ -0,0 +1,3 @@ |
||||
+STRICT |
||||
+20 |
||||
+strictwidth,right |
||||
diff --git a/tests/ts/libsmartcols/files/col-string b/tests/ts/libsmartcols/files/col-string |
||||
new file mode 100644 |
||||
index 000000000..7e2904b9f |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-string |
||||
@@ -0,0 +1,3 @@ |
||||
+STRINGS |
||||
+0 |
||||
+none |
||||
diff --git a/tests/ts/libsmartcols/files/col-tree b/tests/ts/libsmartcols/files/col-tree |
||||
new file mode 100644 |
||||
index 000000000..507688000 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-tree |
||||
@@ -0,0 +1,3 @@ |
||||
+TREE |
||||
+0 |
||||
+tree |
||||
diff --git a/tests/ts/libsmartcols/files/col-trunc b/tests/ts/libsmartcols/files/col-trunc |
||||
new file mode 100644 |
||||
index 000000000..2887b4314 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-trunc |
||||
@@ -0,0 +1,3 @@ |
||||
+TRUNC |
||||
+0 |
||||
+trunc |
||||
diff --git a/tests/ts/libsmartcols/files/col-wrap b/tests/ts/libsmartcols/files/col-wrap |
||||
new file mode 100644 |
||||
index 000000000..dc4ca340e |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-wrap |
||||
@@ -0,0 +1,3 @@ |
||||
+WRAP |
||||
+0 |
||||
+wrap |
||||
diff --git a/tests/ts/libsmartcols/files/col-wrapnl b/tests/ts/libsmartcols/files/col-wrapnl |
||||
new file mode 100644 |
||||
index 000000000..0a18fd146 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/col-wrapnl |
||||
@@ -0,0 +1,3 @@ |
||||
+WRAPNL |
||||
+0 |
||||
+wrapnl |
||||
diff --git a/tests/ts/libsmartcols/files/data-id b/tests/ts/libsmartcols/files/data-id |
||||
new file mode 100644 |
||||
index 000000000..f00c965d8 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/data-id |
||||
@@ -0,0 +1,10 @@ |
||||
+1 |
||||
+2 |
||||
+3 |
||||
+4 |
||||
+5 |
||||
+6 |
||||
+7 |
||||
+8 |
||||
+9 |
||||
+10 |
||||
diff --git a/tests/ts/libsmartcols/files/data-number b/tests/ts/libsmartcols/files/data-number |
||||
new file mode 100644 |
||||
index 000000000..562d75061 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/data-number |
||||
@@ -0,0 +1,10 @@ |
||||
+0 |
||||
+100 |
||||
+21 |
||||
+3 |
||||
+411 |
||||
+5111 |
||||
+678993321 |
||||
+7666666 |
||||
+8765 |
||||
+987456 |
||||
diff --git a/tests/ts/libsmartcols/files/data-number-tiny b/tests/ts/libsmartcols/files/data-number-tiny |
||||
new file mode 100644 |
||||
index 000000000..8b1acc12b |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/data-number-tiny |
||||
@@ -0,0 +1,10 @@ |
||||
+0 |
||||
+1 |
||||
+2 |
||||
+3 |
||||
+4 |
||||
+5 |
||||
+6 |
||||
+7 |
||||
+8 |
||||
+9 |
||||
diff --git a/tests/ts/libsmartcols/files/data-parent b/tests/ts/libsmartcols/files/data-parent |
||||
new file mode 100644 |
||||
index 000000000..aa5071608 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/data-parent |
||||
@@ -0,0 +1,10 @@ |
||||
+0 |
||||
+1 |
||||
+1 |
||||
+1 |
||||
+2 |
||||
+2 |
||||
+3 |
||||
+7 |
||||
+8 |
||||
+7 |
||||
diff --git a/tests/ts/libsmartcols/files/data-string b/tests/ts/libsmartcols/files/data-string |
||||
new file mode 100644 |
||||
index 000000000..dff6e9c80 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/data-string |
||||
@@ -0,0 +1,10 @@ |
||||
+aaaa |
||||
+bbb |
||||
+ccccc |
||||
+dddddd |
||||
+ee |
||||
+ffff |
||||
+gggggg |
||||
+hhh |
||||
+iiiiii |
||||
+jj |
||||
diff --git a/tests/ts/libsmartcols/files/data-string-extreme b/tests/ts/libsmartcols/files/data-string-extreme |
||||
new file mode 100644 |
||||
index 000000000..6fb395d7a |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/data-string-extreme |
||||
@@ -0,0 +1,10 @@ |
||||
+qqqqqqX |
||||
+ddddddddX |
||||
+ffffffffffffffffffffffffffffffffffX |
||||
+sssX |
||||
+ddX |
||||
+jjjjjX |
||||
+mmmmmmmX |
||||
+llllllllllX |
||||
+yyyyyyX |
||||
+pppppX |
||||
diff --git a/tests/ts/libsmartcols/files/data-string-long b/tests/ts/libsmartcols/files/data-string-long |
||||
new file mode 100644 |
||||
index 000000000..1b5683aa4 |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/data-string-long |
||||
@@ -0,0 +1,10 @@ |
||||
+qqqqqqqqqqqqqqqqqX |
||||
+dddddddddddddX |
||||
+ffffffffffffffffffffffffffffffffffffffffX |
||||
+ssssssssssX |
||||
+ddddddddddddddddddddddddddX |
||||
+jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX |
||||
+mmmmmmmmmmmmmmmmmmmX |
||||
+lllllllllllllllllllllllllllllllllllllX |
||||
+yyyyyyyyyyyyyyyyyyyyyyyyyyyyX |
||||
+pppppppppX |
||||
diff --git a/tests/ts/libsmartcols/files/data-string-nl b/tests/ts/libsmartcols/files/data-string-nl |
||||
new file mode 100644 |
||||
index 000000000..7822e57bc |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/files/data-string-nl |
||||
@@ -0,0 +1,10 @@ |
||||
+aaa |
||||
+bbbbb |
||||
+cccc\nCCCC |
||||
+dddddddd\nDDDD\nDD |
||||
+hello\nbaby |
||||
+aaa\nbbb\nccc\nddd |
||||
+eee |
||||
+fffff |
||||
+g\nhhhhh |
||||
+ppppppppp |
||||
diff --git a/tests/ts/libsmartcols/fromfile b/tests/ts/libsmartcols/fromfile |
||||
new file mode 100755 |
||||
index 000000000..311dd7e1e |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/fromfile |
||||
@@ -0,0 +1,240 @@ |
||||
+#!/bin/bash |
||||
+# |
||||
+# This file is part of util-linux. |
||||
+# |
||||
+# This file is free software; you can redistribute it and/or modify |
||||
+# it under the terms of the GNU General Public License as published by |
||||
+# the Free Software Foundation; either version 2 of the License, or |
||||
+# (at your option) any later version. |
||||
+# |
||||
+# This file is distributed in the hope that it will be useful, |
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
+# GNU General Public License for more details. |
||||
+# |
||||
+# |
||||
+ |
||||
+TS_TOPDIR="${0%/*}/../.." |
||||
+TS_DESC="fromfile" |
||||
+ |
||||
+. $TS_TOPDIR/functions.sh |
||||
+ts_init "$*" |
||||
+ |
||||
+TESTPROG="$TS_HELPER_LIBSMARTCOLS_FROMFILE" |
||||
+ts_check_test_command "$TESTPROG" |
||||
+ |
||||
+ts_init_subtest "tree" |
||||
+$TESTPROG --nlines 10 \ |
||||
+ --tree-id-column 1 \ |
||||
+ --tree-parent-column 2 \ |
||||
+ --column $TS_SELF/files/col-tree \ |
||||
+ --column $TS_SELF/files/col-id \ |
||||
+ --column $TS_SELF/files/col-parent \ |
||||
+ --column $TS_SELF/files/col-string \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-id \ |
||||
+ $TS_SELF/files/data-parent \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "tree-json" |
||||
+$TESTPROG --nlines 10 --json \ |
||||
+ --tree-id-column 1 \ |
||||
+ --tree-parent-column 2 \ |
||||
+ --column $TS_SELF/files/col-tree \ |
||||
+ --column $TS_SELF/files/col-id \ |
||||
+ --column $TS_SELF/files/col-parent \ |
||||
+ --column $TS_SELF/files/col-string \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-id \ |
||||
+ $TS_SELF/files/data-parent \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "tree-middle" |
||||
+$TESTPROG --nlines 10 \ |
||||
+ --tree-id-column 0 \ |
||||
+ --tree-parent-column 1 \ |
||||
+ --column $TS_SELF/files/col-id \ |
||||
+ --column $TS_SELF/files/col-parent \ |
||||
+ --column $TS_SELF/files/col-tree \ |
||||
+ --column $TS_SELF/files/col-string \ |
||||
+ $TS_SELF/files/data-id \ |
||||
+ $TS_SELF/files/data-parent \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "tree-end" |
||||
+$TESTPROG --nlines 10 \ |
||||
+ --tree-id-column 0 \ |
||||
+ --tree-parent-column 1 \ |
||||
+ --column $TS_SELF/files/col-id \ |
||||
+ --column $TS_SELF/files/col-parent \ |
||||
+ --column $TS_SELF/files/col-string \ |
||||
+ --column $TS_SELF/files/col-tree \ |
||||
+ $TS_SELF/files/data-id \ |
||||
+ $TS_SELF/files/data-parent \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "trunc" |
||||
+$TESTPROG --nlines 10 --width 40 \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ --column $TS_SELF/files/col-trunc \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "right" |
||||
+$TESTPROG --nlines 10 \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ --column $TS_SELF/files/col-string \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "right-maxout" |
||||
+$TESTPROG --nlines 10 --maxout --width 80\ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "strictwidth" |
||||
+$TESTPROG --nlines 10 \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-strict \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number-tiny \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "noextremes" |
||||
+$TESTPROG --nlines 10 --width 45 \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-noextremes \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-string-extreme \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "hidden" |
||||
+$TESTPROG --nlines 10 \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-hidden \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "wrap" |
||||
+$TESTPROG --nlines 10 --width 40 \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ --column $TS_SELF/files/col-wrap \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "wrap-tree" |
||||
+$TESTPROG --nlines 10 --width 45 \ |
||||
+ --tree-id-column 1 \ |
||||
+ --tree-parent-column 2 \ |
||||
+ --column $TS_SELF/files/col-tree \ |
||||
+ --column $TS_SELF/files/col-id \ |
||||
+ --column $TS_SELF/files/col-parent \ |
||||
+ --column $TS_SELF/files/col-wrap \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-id \ |
||||
+ $TS_SELF/files/data-parent \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "wrapnl" |
||||
+$TESTPROG --nlines 10 \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ --column $TS_SELF/files/col-wrapnl \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ $TS_SELF/files/data-string-nl \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "wrapnl-tree" |
||||
+$TESTPROG --nlines 10 \ |
||||
+ --tree-id-column 1 \ |
||||
+ --tree-parent-column 2 \ |
||||
+ --column $TS_SELF/files/col-tree \ |
||||
+ --column $TS_SELF/files/col-id \ |
||||
+ --column $TS_SELF/files/col-parent \ |
||||
+ --column $TS_SELF/files/col-wrapnl \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-id \ |
||||
+ $TS_SELF/files/data-parent \ |
||||
+ $TS_SELF/files/data-string-nl \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "raw" |
||||
+$TESTPROG --nlines 10 --raw \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ --column $TS_SELF/files/col-trunc \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "export" |
||||
+$TESTPROG --nlines 10 --export \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ --column $TS_SELF/files/col-trunc \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_init_subtest "column-separator" |
||||
+$TESTPROG --nlines 10 --colsep \| \ |
||||
+ --column $TS_SELF/files/col-name \ |
||||
+ --column $TS_SELF/files/col-number \ |
||||
+ --column $TS_SELF/files/col-trunc \ |
||||
+ $TS_SELF/files/data-string \ |
||||
+ $TS_SELF/files/data-number \ |
||||
+ $TS_SELF/files/data-string-long \ |
||||
+ >> $TS_OUTPUT 2>&1 |
||||
+ts_finalize_subtest |
||||
+ |
||||
+ts_log "...done." |
||||
+ts_finalize |
||||
diff --git a/tests/ts/libsmartcols/title b/tests/ts/libsmartcols/title |
||||
new file mode 100755 |
||||
index 000000000..a9ba6a4fd |
||||
--- /dev/null |
||||
+++ b/tests/ts/libsmartcols/title |
||||
@@ -0,0 +1,28 @@ |
||||
+#!/bin/bash |
||||
+# |
||||
+# This file is part of util-linux. |
||||
+# |
||||
+# This file is free software; you can redistribute it and/or modify |
||||
+# it under the terms of the GNU General Public License as published by |
||||
+# the Free Software Foundation; either version 2 of the License, or |
||||
+# (at your option) any later version. |
||||
+# |
||||
+# This file is distributed in the hope that it will be useful, |
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
+# GNU General Public License for more details. |
||||
+# |
||||
+# |
||||
+ |
||||
+TS_TOPDIR="${0%/*}/../.." |
||||
+TS_DESC="title" |
||||
+ |
||||
+. $TS_TOPDIR/functions.sh |
||||
+ts_init "$*" |
||||
+ |
||||
+TESTPROG="$TS_HELPER_LIBSMARTCOLS_TITLE" |
||||
+ts_check_test_command "$TESTPROG" |
||||
+ |
||||
+$TESTPROG --width 80 >> $TS_OUTPUT 2>&1 |
||||
+ |
||||
+ts_finalize |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,114 @@
@@ -0,0 +1,114 @@
|
||||
From f769cb435c4db2e7f6d11e14fe87a1c81e0912fe Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Wed, 23 May 2018 12:43:26 +0200 |
||||
Subject: [PATCH 155/173] lslogins: fix password verification |
||||
|
||||
Let's follow the standard $id$salt$encrypted password format in |
||||
verification code. |
||||
|
||||
The current code is useless and for example PWD-LOCK column is always |
||||
FALSE. |
||||
|
||||
Upstream: http://github.com/karelzak/util-linux/commit/214fbec40abf0432b8e7968f05024ee76d11b3c7 |
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1581611 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
login-utils/lslogins.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++--- |
||||
1 file changed, 74 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/login-utils/lslogins.c b/login-utils/lslogins.c |
||||
index d7a24b1fb..041053625 100644 |
||||
--- a/login-utils/lslogins.c |
||||
+++ b/login-utils/lslogins.c |
||||
@@ -541,14 +541,84 @@ static int get_nprocs(const uid_t uid) |
||||
return nprocs; |
||||
} |
||||
|
||||
+static const char *get_pwd_method(const char *str, const char **next, unsigned int *sz) |
||||
+{ |
||||
+ const char *p = str; |
||||
+ const char *res = NULL; |
||||
+ |
||||
+ if (!p || *p++ != '$') |
||||
+ return NULL; |
||||
+ |
||||
+ if (sz) |
||||
+ *sz = 0; |
||||
+ |
||||
+ switch (*p) { |
||||
+ case '1': |
||||
+ res = "MD5"; |
||||
+ if (sz) |
||||
+ *sz = 22; |
||||
+ break; |
||||
+ case '2': |
||||
+ p++; |
||||
+ if (*p == 'a' || *p == 'y') |
||||
+ res = "Blowfish"; |
||||
+ break; |
||||
+ case '5': |
||||
+ res = "SHA-256"; |
||||
+ if (sz) |
||||
+ *sz = 43; |
||||
+ break; |
||||
+ case '6': |
||||
+ res = "SHA-512"; |
||||
+ if (sz) |
||||
+ *sz = 86; |
||||
+ break; |
||||
+ default: |
||||
+ return NULL; |
||||
+ } |
||||
+ p++; |
||||
+ |
||||
+ if (!*p || *p != '$') |
||||
+ return NULL; |
||||
+ if (next) |
||||
+ *next = ++p; |
||||
+ return res; |
||||
+} |
||||
+ |
||||
+#define is_valid_pwd_char(x) (isalnum((unsigned char) (x)) || (x) == '.' || (x) == '/') |
||||
+ |
||||
static int valid_pwd(const char *str) |
||||
{ |
||||
- const char *p; |
||||
+ const char *p = str; |
||||
+ unsigned int sz = 0, n; |
||||
+ |
||||
+ /* $id$ */ |
||||
+ if (get_pwd_method(str, &p, &sz) == NULL) |
||||
+ return 0; |
||||
+ if (!*p) |
||||
+ return 0; |
||||
|
||||
- for (p = str; p && *p; p++) |
||||
- if (!isalnum((unsigned int) *p)) |
||||
+ /* salt$ */ |
||||
+ for (; p && *p; p++) { |
||||
+ if (*p == '$') { |
||||
+ p++; |
||||
+ break; |
||||
+ } |
||||
+ if (!is_valid_pwd_char(*p)) |
||||
return 0; |
||||
- return p > str ? 1 : 0; |
||||
+ } |
||||
+ if (!*p) |
||||
+ return 0; |
||||
+ |
||||
+ /* encrypted */ |
||||
+ for (n = 0; p && *p; p++, n++) { |
||||
+ if (!is_valid_pwd_char(*p)) |
||||
+ return 0; |
||||
+ } |
||||
+ |
||||
+ if (sz && n != sz) |
||||
+ return 0; |
||||
+ return 1; |
||||
} |
||||
|
||||
static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const char *username) |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
From 0ae2aa6a43a852cb0326faade1532c02aa7617a4 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Fri, 20 Apr 2018 09:50:04 +0200 |
||||
Subject: [PATCH 156/173] umount: add note about --lazy |
||||
|
||||
Unfortunately, it's pretty common that users on production systems use |
||||
lazy umount to fix some FS issues. The usual result is unwanted system |
||||
reboot, because -l is not the right way how to fix unreachable NFS or |
||||
mess with local FS with submounts. |
||||
|
||||
Note that after lazy umount /proc/self/mountinfo does not contain the |
||||
FS entry, but kernel still references the FS. It makes it very |
||||
difficult to debug. |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1566674 |
||||
Suggested-by: Steve Dickson <steved@redhat.com> |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
Upstream: http://github.com/karelzak/util-linux/commit/031800ff6c66b4d62229cfd116195950a718a21c |
||||
--- |
||||
sys-utils/umount.8 | 10 +++++++++- |
||||
1 file changed, 9 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/sys-utils/umount.8 b/sys-utils/umount.8 |
||||
index f0a712b06..71c2155b4 100644 |
||||
--- a/sys-utils/umount.8 |
||||
+++ b/sys-utils/umount.8 |
||||
@@ -54,7 +54,8 @@ working directory there, or when a swap file on it is in use. The |
||||
offending process could even be |
||||
.B umount |
||||
itself - it opens libc, and libc in its turn may open for example locale |
||||
-files. A lazy unmount avoids this problem. |
||||
+files. A lazy unmount avoids this problem, but it may introduce another |
||||
+issues. See \fB\-\-lazy\fR description bellow. |
||||
.SH OPTIONS |
||||
.TP |
||||
\fB\-a\fR, \fB\-\-all\fR |
||||
@@ -107,6 +108,13 @@ Unmount without writing in |
||||
Lazy unmount. Detach the filesystem from the filesystem hierarchy now, |
||||
and cleanup all references to the filesystem as soon as it is not busy |
||||
anymore. (Requires kernel 2.4.11 or later.) |
||||
+ |
||||
+A system reboot would be expected in near future if you're going to use this |
||||
+option for network filesystem or local filesystem with submounts. The |
||||
+recommended use-case for \fBumount -l\fR is to prevent hangs on shutdown due to |
||||
+an unreachable network share where a normal umount will hang due to a downed |
||||
+server or a network partition. Remounts of the share will not be possible. |
||||
+ |
||||
.TP |
||||
\fB\-O\fR, \fB\-\-test\-opts\fR \fIoptions,list\fR |
||||
Indicate that the actions should only be taken on file systems with the |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
From 0258872e2b45b589481e6796aa983f8749be9ada Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Thu, 10 Aug 2017 12:37:34 +0200 |
||||
Subject: [PATCH 157/173] losetup: add info about lazy detach to manpage |
||||
|
||||
Upstream: http://github.com/karelzak/util-linux/commit/60eedb0a53f14aa1169713a72325421db8e1c647 |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1566390 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
sys-utils/losetup.8 | 5 ++++- |
||||
1 file changed, 4 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/sys-utils/losetup.8 b/sys-utils/losetup.8 |
||||
index 9a8c1d597..45c220187 100644 |
||||
--- a/sys-utils/losetup.8 |
||||
+++ b/sys-utils/losetup.8 |
||||
@@ -80,7 +80,10 @@ without --list) is deprecated. |
||||
.IP "\fB\-c, \-\-set-capacity\fP \fIloopdev\fP |
||||
force loop driver to reread size of the file associated with the specified loop device |
||||
.IP "\fB\-d, \-\-detach\fP \fIloopdev\fP..." |
||||
-detach the file or device associated with the specified loop device(s) |
||||
+detach the file or device associated with the specified loop device(s). Note |
||||
+that since Linux v3.7 kernel uses "lazy device destruction". The detach |
||||
+operation does not return EBUSY error anymore if device is actively used by |
||||
+system, but it is marked by autoclear flag and destroyed later. |
||||
.IP "\fB\-D, \-\-detach-all\fP" |
||||
detach all associated loop devices |
||||
.IP "\fB\-f, \-\-find\fP" |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
From e10a3a201b2b4dc6ff9957600c9bf67a2f9de38e Mon Sep 17 00:00:00 2001 |
||||
From: Anton Blanchard <anton@samba.org> |
||||
Date: Mon, 7 Apr 2014 09:18:13 +1000 |
||||
Subject: [PATCH 158/173] setarch: Fix ppc64le architectures |
||||
|
||||
setarch currently fails on ppc64le because it tries to |
||||
use big endian architecture names. Fix it. |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1562125 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/95bf26fd68ec7f0b2dde1f022dc79d04d1a6e620 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/e60b6df54e27cdb68a75ea8a056a70f60df8f025 |
||||
Signed-off-by: Anton Blanchard <anton@samba.org> |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
sys-utils/setarch.c | 8 ++++++++ |
||||
1 file changed, 8 insertions(+) |
||||
|
||||
diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c |
||||
index 051cbefcd..b03406dd3 100644 |
||||
--- a/sys-utils/setarch.c |
||||
+++ b/sys-utils/setarch.c |
||||
@@ -149,11 +149,19 @@ set_arch(const char *pers, unsigned long options, int list) |
||||
{PER_LINUX32, "linux32", NULL}, |
||||
{PER_LINUX, "linux64", NULL}, |
||||
#if defined(__powerpc__) || defined(__powerpc64__) |
||||
+#ifdef __BIG_ENDIAN__ |
||||
{PER_LINUX32, "ppc32", "ppc"}, |
||||
{PER_LINUX32, "ppc", "ppc"}, |
||||
{PER_LINUX, "ppc64", "ppc64"}, |
||||
{PER_LINUX, "ppc64pseries", "ppc64"}, |
||||
{PER_LINUX, "ppc64iseries", "ppc64"}, |
||||
+#else |
||||
+ {PER_LINUX32, "ppc32", "ppcle"}, |
||||
+ {PER_LINUX32, "ppc", "ppcle"}, |
||||
+ {PER_LINUX32, "ppc32le", "ppcle"}, |
||||
+ {PER_LINUX32, "ppcle", "ppcle"}, |
||||
+ {PER_LINUX, "ppc64le", "ppc64le"}, |
||||
+#endif |
||||
#endif |
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__ia64__) |
||||
{PER_LINUX32, "i386", "i386"}, |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,717 @@
@@ -0,0 +1,717 @@
|
||||
From 9f2a32a8fd08bb1b48f29c88bfa398fa4eb5f2a4 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Wed, 6 Jun 2018 11:59:16 +0200 |
||||
Subject: [PATCH 159/173] fallocate: backport v2.32-164-g641af90dc |
||||
|
||||
* add --dig-holes |
||||
* add --collapse-range |
||||
* add --insert-range |
||||
* add --zero-range |
||||
|
||||
For backward compatibility with previous RHEL7 versions we keep |
||||
O_CREAT for open(). The current upstream uses O_CREAT only when |
||||
necessary. |
||||
|
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1528567 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
sys-utils/fallocate.1 | 195 ++++++++++++++++++++++------ |
||||
sys-utils/fallocate.c | 349 +++++++++++++++++++++++++++++++++++++++----------- |
||||
2 files changed, 428 insertions(+), 116 deletions(-) |
||||
|
||||
diff --git a/sys-utils/fallocate.1 b/sys-utils/fallocate.1 |
||||
index 376353013..d4821dcd1 100644 |
||||
--- a/sys-utils/fallocate.1 |
||||
+++ b/sys-utils/fallocate.1 |
||||
@@ -1,72 +1,185 @@ |
||||
-.\" -*- nroff -*- |
||||
-.TH FALLOCATE 1 "September 2011" "util-linux" "User Commands" |
||||
+.TH FALLOCATE 1 "April 2014" "util-linux" "User Commands" |
||||
.SH NAME |
||||
-fallocate \- preallocate space to a file |
||||
+fallocate \- preallocate or deallocate space to a file |
||||
.SH SYNOPSIS |
||||
.B fallocate |
||||
-.RB [ \-n ] |
||||
-.RB [ \-p ] |
||||
+.RB [ \-c | \-p | \-z ] |
||||
.RB [ \-o |
||||
.IR offset ] |
||||
.B \-l |
||||
-.IR length |
||||
+.I length |
||||
+.RB [ \-n ] |
||||
+.I filename |
||||
+.PP |
||||
+.B fallocate \-d |
||||
+.RB [ \-o |
||||
+.IR offset ] |
||||
+.RB [ \-l |
||||
+.IR length ] |
||||
.I filename |
||||
.PP |
||||
.B fallocate \-x |
||||
.RB [ \-o |
||||
.IR offset ] |
||||
-.RB \-l |
||||
-.IR length |
||||
+.B \-l |
||||
+.I length |
||||
.I filename |
||||
.SH DESCRIPTION |
||||
.B fallocate |
||||
-is used to preallocate blocks to a file. For filesystems which support the |
||||
-fallocate system call, this is done quickly by allocating blocks and marking |
||||
-them as uninitialized, requiring no IO to the data blocks. This is much faster |
||||
-than creating a file by filling it with zeros. |
||||
-.PP |
||||
-As of the Linux Kernel v2.6.31, the fallocate system call is supported by the |
||||
-btrfs, ext4, ocfs2, and xfs filesystems. |
||||
+is used to manipulate the allocated disk space for a file, |
||||
+either to deallocate or preallocate it. |
||||
+For filesystems which support the fallocate system call, |
||||
+preallocation is done quickly by allocating blocks and marking them as |
||||
+uninitialized, requiring no IO to the data blocks. |
||||
+This is much faster than creating a file by filling it with zeroes. |
||||
.PP |
||||
The exit code returned by |
||||
.B fallocate |
||||
is 0 on success and 1 on failure. |
||||
-.PP |
||||
.SH OPTIONS |
||||
-The \fIlength\fR and \fIoffset\fR arguments may be followed by the multiplicative |
||||
-suffixes KiB=1024, MiB=1024*1024, and so on for GiB, TiB, PiB, EiB, ZiB and YiB |
||||
-(the "iB" is optional, e.g. "K" has the same meaning as "KiB") or the suffixes |
||||
-KB=1000, MB=1000*1000, and so on for GB, TB, PB, EB, ZB and YB. |
||||
-.IP "\fB\-n, \-\-keep-size\fP" |
||||
+The |
||||
+.I length |
||||
+and |
||||
+.I offset |
||||
+arguments may be followed by the multiplicative suffixes KiB (=1024), |
||||
+MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB, and YiB (the "iB" is |
||||
+optional, e.g., "K" has the same meaning as "KiB") or the suffixes |
||||
+KB (=1000), MB (=1000*1000), and so on for GB, TB, PB, EB, ZB, and YB. |
||||
+.PP |
||||
+The options |
||||
+.BR \-\-collapse\-range ", " \-\-dig\-holes ", " \-\-punch\-hole , |
||||
+and |
||||
+.B \-\-zero\-range |
||||
+are mutually exclusive. |
||||
+.TP |
||||
+.BR \-c ", " \-\-collapse\-range |
||||
+Removes a byte range from a file, without leaving a hole. |
||||
+The byte range to be collapsed starts at |
||||
+.I offset |
||||
+and continues for |
||||
+.I length |
||||
+bytes. |
||||
+At the completion of the operation, |
||||
+the contents of the file starting at the location |
||||
+.IR offset + length |
||||
+will be appended at the location |
||||
+.IR offset , |
||||
+and the file will be |
||||
+.I length |
||||
+bytes smaller. |
||||
+The option |
||||
+.B \-\-keep\-size |
||||
+may not be specified for the collapse-range operation. |
||||
+.sp |
||||
+Available since Linux 3.15 for ext4 (only for extent-based files) and XFS. |
||||
+.TP |
||||
+.BR \-d ", " \-\-dig\-holes |
||||
+Detect and dig holes. |
||||
+This makes the file sparse in-place, without using extra disk space. |
||||
+The minimum size of the hole depends on filesystem I/O block size |
||||
+(usually 4096 bytes). |
||||
+Also, when using this option, |
||||
+.B \-\-keep\-size |
||||
+is implied. If no range is specified by |
||||
+.B \-\-offset |
||||
+and |
||||
+.BR \-\-length , |
||||
+then the entire file is analyzed for holes. |
||||
+.sp |
||||
+You can think of this option as doing a |
||||
+.RB """" "cp \-\-sparse" """" |
||||
+and then renaming the destination file to the original, |
||||
+without the need for extra disk space. |
||||
+.sp |
||||
+See \fB\-\-punch\-hole\fP for a list of supported filesystems. |
||||
+.TP |
||||
+.BR \-i ", " \-\-insert\-range |
||||
+Insert a hole of |
||||
+.I length |
||||
+bytes from |
||||
+.IR offset , |
||||
+shifting existing data. |
||||
+.TP |
||||
+.BR \-l ", " "\-\-length " \fIlength |
||||
+Specifies the length of the range, in bytes. |
||||
+.TP |
||||
+.BR \-n ", " \-\-keep\-size |
||||
Do not modify the apparent length of the file. This may effectively allocate |
||||
blocks past EOF, which can be removed with a truncate. |
||||
-.IP "\fB\-p, \-\-punch-hole\fP" |
||||
-Punch holes in the file, the range should not exceed the length of the file. |
||||
-.IP "\fB\-o, \-\-offset\fP \fIoffset\fP |
||||
-Specifies the beginning offset of the allocation, in bytes. |
||||
-.IP "\fB\-l, \-\-length\fP \fIlength\fP |
||||
-Specifies the length of the allocation, in bytes. |
||||
-.IP "\fB\-x , \-\-posix\fP |
||||
-Enable POSIX operation mode. In that mode allocation operation always completes, |
||||
-but it may take longer time when fast allocation is not supported by the underlying filesystem. |
||||
-.IP "\fB\-h, \-\-help\fP" |
||||
-Print help and exit. |
||||
-.IP "\fB-V, \-\-version" |
||||
-Print version and exit. |
||||
+.TP |
||||
+.BR \-o ", " "\-\-offset " \fIoffset |
||||
+Specifies the beginning offset of the range, in bytes. |
||||
+.TP |
||||
+.BR \-p ", " \-\-punch\-hole |
||||
+Deallocates space (i.e., creates a hole) in the byte range starting at |
||||
+.I offset |
||||
+and continuing for |
||||
+.I length |
||||
+bytes. |
||||
+Within the specified range, partial filesystem blocks are zeroed, |
||||
+and whole filesystem blocks are removed from the file. |
||||
+After a successful call, |
||||
+subsequent reads from this range will return zeroes. |
||||
+This option may not be specified at the same time as the |
||||
+.B \-\-zero\-range |
||||
+option. |
||||
+Also, when using this option, |
||||
+.B \-\-keep\-size |
||||
+is implied. |
||||
+.sp |
||||
+Supported for XFS (since Linux 2.6.38), ext4 (since Linux 3.0), |
||||
+Btrfs (since Linux 3.7) and tmpfs (since Linux 3.5). |
||||
+.TP |
||||
+.BR \-v ", " \-\-verbose |
||||
+Enable verbose mode. |
||||
+.TP |
||||
+.BR \-x ", " \-\-posix |
||||
+Enable POSIX operation mode. |
||||
+In that mode allocation operation always completes, |
||||
+but it may take longer time when fast allocation is not supported by |
||||
+the underlying filesystem. |
||||
+.TP |
||||
+.BR \-z ", " \-\-zero\-range |
||||
+Zeroes space in the byte range starting at |
||||
+.I offset |
||||
+and continuing for |
||||
+.I length |
||||
+bytes. |
||||
+Within the specified range, blocks are preallocated for the regions |
||||
+that span the holes in the file. |
||||
+After a successful call, |
||||
+subsequent reads from this range will return zeroes. |
||||
+.sp |
||||
+Zeroing is done within the filesystem preferably by converting the |
||||
+range into unwritten extents. This approach means that the specified |
||||
+range will not be physically zeroed out on the device (except for |
||||
+partial blocks at the either end of the range), and I/O is |
||||
+(otherwise) required only to update metadata. |
||||
+.sp |
||||
+Option \fB\-\-keep\-size\fP can be specified to prevent file length |
||||
+modification. |
||||
+.sp |
||||
+Available since Linux 3.14 for ext4 (only for extent-based files) and XFS. |
||||
+.TP |
||||
+.BR \-V ", " \-\-version |
||||
+Display version information and exit. |
||||
+.TP |
||||
+.BR \-h ", " \-\-help |
||||
+Display help text and exit. |
||||
.SH AUTHORS |
||||
-.UR sandeen@redhat.com |
||||
+.MT sandeen@redhat.com |
||||
Eric Sandeen |
||||
-.UE |
||||
+.ME |
||||
.br |
||||
-.UR kzak@redhat.com |
||||
+.MT kzak@redhat.com |
||||
Karel Zak |
||||
-.UE |
||||
+.ME |
||||
.SH SEE ALSO |
||||
+.BR truncate (1), |
||||
.BR fallocate (2), |
||||
-.BR posix_fallocate (3), |
||||
-.BR truncate (1) |
||||
+.BR posix_fallocate (3) |
||||
.SH AVAILABILITY |
||||
The fallocate command is part of the util-linux package and is available from |
||||
-.UR ftp://\:ftp.kernel.org\:/pub\:/linux\:/utils\:/util-linux/ |
||||
+.UR https://\:www.kernel.org\:/pub\:/linux\:/utils\:/util-linux/ |
||||
Linux Kernel Archive |
||||
.UE . |
||||
diff --git a/sys-utils/fallocate.c b/sys-utils/fallocate.c |
||||
index 17ae5fe69..75d89a7a9 100644 |
||||
--- a/sys-utils/fallocate.c |
||||
+++ b/sys-utils/fallocate.c |
||||
@@ -23,6 +23,7 @@ |
||||
*/ |
||||
#include <sys/stat.h> |
||||
#include <sys/types.h> |
||||
+#include <sys/mman.h> |
||||
#include <ctype.h> |
||||
#include <errno.h> |
||||
#include <fcntl.h> |
||||
@@ -31,50 +32,110 @@ |
||||
#include <unistd.h> |
||||
#include <getopt.h> |
||||
#include <limits.h> |
||||
+#include <string.h> |
||||
|
||||
#ifndef HAVE_FALLOCATE |
||||
# include <sys/syscall.h> |
||||
#endif |
||||
|
||||
-#ifdef HAVE_LINUX_FALLOC_H |
||||
-# include <linux/falloc.h> /* for FALLOC_FL_* flags */ |
||||
+#if defined(HAVE_LINUX_FALLOC_H) && \ |
||||
+ (!defined(FALLOC_FL_KEEP_SIZE) || !defined(FALLOC_FL_PUNCH_HOLE) || \ |
||||
+ !defined(FALLOC_FL_COLLAPSE_RANGE) || !defined(FALLOC_FL_ZERO_RANGE) || \ |
||||
+ !defined(FALLOC_FL_INSERT_RANGE)) |
||||
+# include <linux/falloc.h> /* non-libc fallback for FALLOC_FL_* flags */ |
||||
#endif |
||||
|
||||
+ |
||||
#ifndef FALLOC_FL_KEEP_SIZE |
||||
-# define FALLOC_FL_KEEP_SIZE 1 |
||||
+# define FALLOC_FL_KEEP_SIZE 0x1 |
||||
#endif |
||||
|
||||
#ifndef FALLOC_FL_PUNCH_HOLE |
||||
-# define FALLOC_FL_PUNCH_HOLE 2 |
||||
+# define FALLOC_FL_PUNCH_HOLE 0x2 |
||||
+#endif |
||||
+ |
||||
+#ifndef FALLOC_FL_COLLAPSE_RANGE |
||||
+# define FALLOC_FL_COLLAPSE_RANGE 0x8 |
||||
+#endif |
||||
+ |
||||
+#ifndef FALLOC_FL_ZERO_RANGE |
||||
+# define FALLOC_FL_ZERO_RANGE 0x10 |
||||
+#endif |
||||
+ |
||||
+#ifndef FALLOC_FL_INSERT_RANGE |
||||
+# define FALLOC_FL_INSERT_RANGE 0x20 |
||||
#endif |
||||
|
||||
#include "nls.h" |
||||
#include "strutils.h" |
||||
#include "c.h" |
||||
#include "closestream.h" |
||||
+#include "xalloc.h" |
||||
#include "optutils.h" |
||||
|
||||
-static void __attribute__((__noreturn__)) usage(FILE *out) |
||||
+static int verbose; |
||||
+static char *filename; |
||||
+ |
||||
+static void __attribute__((__noreturn__)) usage(void) |
||||
{ |
||||
+ FILE *out = stdout; |
||||
fputs(USAGE_HEADER, out); |
||||
fprintf(out, |
||||
_(" %s [options] <filename>\n"), program_invocation_short_name); |
||||
+ |
||||
+ fputs(USAGE_SEPARATOR, out); |
||||
+ fputs(_("Preallocate space to, or deallocate space from a file.\n"), out); |
||||
+ |
||||
fputs(USAGE_OPTIONS, out); |
||||
- fputs(_(" -n, --keep-size don't modify the length of the file\n" |
||||
- " -p, --punch-hole punch holes in the file\n" |
||||
- " -o, --offset <num> offset of the allocation, in bytes\n" |
||||
- " -l, --length <num> length of the allocation, in bytes\n"), out); |
||||
+ fputs(_(" -c, --collapse-range remove a range from the file\n"), out); |
||||
+ fputs(_(" -d, --dig-holes detect zeroes and replace with holes\n"), out); |
||||
+ fputs(_(" -i, --insert-range insert a hole at range, shifting existing data\n"), out); |
||||
+ fputs(_(" -l, --length <num> length for range operations, in bytes\n"), out); |
||||
+ fputs(_(" -n, --keep-size maintain the apparent size of the file\n"), out); |
||||
+ fputs(_(" -o, --offset <num> offset for range operations, in bytes\n"), out); |
||||
+ fputs(_(" -p, --punch-hole replace a range with a hole (implies -n)\n"), out); |
||||
+ fputs(_(" -z, --zero-range zero and ensure allocation of a range\n"), out); |
||||
#ifdef HAVE_POSIX_FALLOCATE |
||||
- fputs(_(" -x, --posix use posix_fallocate(3) instead of fallocate(2)\n"), out); |
||||
+ fputs(_(" -x, --posix use posix_fallocate(3) instead of fallocate(2)\n"), out); |
||||
#endif |
||||
+ fputs(_(" -v, --verbose verbose mode\n"), out); |
||||
+ |
||||
fputs(USAGE_SEPARATOR, out); |
||||
- fputs(USAGE_HELP, out); |
||||
- fputs(USAGE_VERSION, out); |
||||
- fprintf(out, USAGE_MAN_TAIL("fallocate(1)")); |
||||
+ printf(USAGE_HELP_OPTIONS(22)); |
||||
+ |
||||
+ printf(USAGE_MAN_TAIL("fallocate(1)")); |
||||
|
||||
- exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); |
||||
+ exit(EXIT_SUCCESS); |
||||
} |
||||
|
||||
+static loff_t cvtnum(char *s) |
||||
+{ |
||||
+ uintmax_t x; |
||||
+ |
||||
+ if (strtosize(s, &x)) |
||||
+ return -1LL; |
||||
+ |
||||
+ return x; |
||||
+} |
||||
+ |
||||
+static void xfallocate(int fd, int mode, off_t offset, off_t length) |
||||
+{ |
||||
+ int error; |
||||
+#ifdef HAVE_FALLOCATE |
||||
+ error = fallocate(fd, mode, offset, length); |
||||
+#else |
||||
+ error = syscall(SYS_fallocate, fd, mode, offset, length); |
||||
+#endif |
||||
+ /* |
||||
+ * EOPNOTSUPP: The FALLOC_FL_KEEP_SIZE is unsupported |
||||
+ * ENOSYS: The filesystem does not support sys_fallocate |
||||
+ */ |
||||
+ if (error < 0) { |
||||
+ if ((mode & FALLOC_FL_KEEP_SIZE) && errno == EOPNOTSUPP) |
||||
+ errx(EXIT_FAILURE, _("fallocate failed: keep size mode is unsupported")); |
||||
+ err(EXIT_FAILURE, _("fallocate failed")); |
||||
+ } |
||||
+} |
||||
|
||||
#ifdef HAVE_POSIX_FALLOCATE |
||||
static void xposix_fallocate(int fd, off_t offset, off_t length) |
||||
@@ -86,41 +147,163 @@ static void xposix_fallocate(int fd, off_t offset, off_t length) |
||||
} |
||||
#endif |
||||
|
||||
+/* The real buffer size has to be bufsize + sizeof(uintptr_t) */ |
||||
+static int is_nul(void *buf, size_t bufsize) |
||||
+{ |
||||
+ typedef uintptr_t word; |
||||
+ void const *vp; |
||||
+ char const *cbuf = buf, *cp; |
||||
+ word const *wp = buf; |
||||
|
||||
-static loff_t cvtnum(char *s) |
||||
+ /* set sentinel */ |
||||
+ memset((char *) buf + bufsize, '\1', sizeof(word)); |
||||
+ |
||||
+ /* Find first nonzero *word*, or the word with the sentinel. */ |
||||
+ while (*wp++ == 0) |
||||
+ continue; |
||||
+ |
||||
+ /* Find the first nonzero *byte*, or the sentinel. */ |
||||
+ vp = wp - 1; |
||||
+ cp = vp; |
||||
+ |
||||
+ while (*cp++ == 0) |
||||
+ continue; |
||||
+ |
||||
+ return cbuf + bufsize < cp; |
||||
+} |
||||
+ |
||||
+static void dig_holes(int fd, off_t file_off, off_t len) |
||||
{ |
||||
- uintmax_t x; |
||||
+ off_t file_end = len ? file_off + len : 0; |
||||
+ off_t hole_start = 0, hole_sz = 0; |
||||
+ uintmax_t ct = 0; |
||||
+ size_t bufsz; |
||||
+ char *buf; |
||||
+ struct stat st; |
||||
+#if defined(POSIX_FADV_SEQUENTIAL) && defined(HAVE_POSIX_FADVISE) |
||||
+ off_t cache_start = file_off; |
||||
+ /* |
||||
+ * We don't want to call POSIX_FADV_DONTNEED to discard cached |
||||
+ * data in PAGE_SIZE steps. IMHO it's overkill (too many syscalls). |
||||
+ * |
||||
+ * Let's assume that 1MiB (on system with 4K page size) is just |
||||
+ * a good compromise. |
||||
+ * -- kzak Feb-2014 |
||||
+ */ |
||||
+ const size_t cachesz = getpagesize() * 256; |
||||
+#endif |
||||
|
||||
- if (strtosize(s, &x)) |
||||
- return -1LL; |
||||
+ if (fstat(fd, &st) != 0) |
||||
+ err(EXIT_FAILURE, _("stat of %s failed"), filename); |
||||
|
||||
- return x; |
||||
+ bufsz = st.st_blksize; |
||||
+ |
||||
+ if (lseek(fd, file_off, SEEK_SET) < 0) |
||||
+ err(EXIT_FAILURE, _("seek on %s failed"), filename); |
||||
+ |
||||
+ /* buffer + extra space for is_nul() sentinel */ |
||||
+ buf = xmalloc(bufsz + sizeof(uintptr_t)); |
||||
+ while (file_end == 0 || file_off < file_end) { |
||||
+ /* |
||||
+ * Detect data area (skip holes) |
||||
+ */ |
||||
+ off_t end, off; |
||||
+ |
||||
+ off = lseek(fd, file_off, SEEK_DATA); |
||||
+ if ((off == -1 && errno == ENXIO) || |
||||
+ (file_end && off >= file_end)) |
||||
+ break; |
||||
+ |
||||
+ end = lseek(fd, off, SEEK_HOLE); |
||||
+ if (file_end && end > file_end) |
||||
+ end = file_end; |
||||
+ |
||||
+#if defined(POSIX_FADV_SEQUENTIAL) && defined(HAVE_POSIX_FADVISE) |
||||
+ posix_fadvise(fd, off, end, POSIX_FADV_SEQUENTIAL); |
||||
+#endif |
||||
+ /* |
||||
+ * Dig holes in the area |
||||
+ */ |
||||
+ while (off < end) { |
||||
+ ssize_t rsz = pread(fd, buf, bufsz, off); |
||||
+ if (rsz < 0 && errno) |
||||
+ err(EXIT_FAILURE, _("%s: read failed"), filename); |
||||
+ if (end && rsz > 0 && off > end - rsz) |
||||
+ rsz = end - off; |
||||
+ if (rsz <= 0) |
||||
+ break; |
||||
+ |
||||
+ if (is_nul(buf, rsz)) { |
||||
+ if (!hole_sz) /* new hole detected */ |
||||
+ hole_start = off; |
||||
+ hole_sz += rsz; |
||||
+ } else if (hole_sz) { |
||||
+ xfallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, |
||||
+ hole_start, hole_sz); |
||||
+ ct += hole_sz; |
||||
+ hole_sz = hole_start = 0; |
||||
+ } |
||||
+ |
||||
+#if defined(POSIX_FADV_DONTNEED) && defined(HAVE_POSIX_FADVISE) |
||||
+ /* discard cached data */ |
||||
+ if (off - cache_start > (off_t) cachesz) { |
||||
+ size_t clen = off - cache_start; |
||||
+ |
||||
+ clen = (clen / cachesz) * cachesz; |
||||
+ posix_fadvise(fd, cache_start, clen, POSIX_FADV_DONTNEED); |
||||
+ cache_start = cache_start + clen; |
||||
+ } |
||||
+#endif |
||||
+ off += rsz; |
||||
+ } |
||||
+ if (hole_sz) { |
||||
+ xfallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, |
||||
+ hole_start, hole_sz); |
||||
+ ct += hole_sz; |
||||
+ } |
||||
+ file_off = off; |
||||
+ } |
||||
+ |
||||
+ free(buf); |
||||
+ |
||||
+ if (verbose) { |
||||
+ char *str = size_to_human_string(SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE, ct); |
||||
+ fprintf(stdout, _("%s: %s (%ju bytes) converted to sparse holes.\n"), |
||||
+ filename, str, ct); |
||||
+ free(str); |
||||
+ } |
||||
} |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
- char *fname; |
||||
int c; |
||||
- int error = 0; |
||||
int fd; |
||||
int mode = 0; |
||||
- int posix = 0; |
||||
+ int dig = 0; |
||||
+ int posix = 0; |
||||
loff_t length = -2LL; |
||||
loff_t offset = 0; |
||||
|
||||
static const struct option longopts[] = { |
||||
- { "help", 0, 0, 'h' }, |
||||
- { "version", 0, 0, 'V' }, |
||||
- { "keep-size", 0, 0, 'n' }, |
||||
- { "punch-hole", 0, 0, 'p' }, |
||||
- { "offset", 1, 0, 'o' }, |
||||
- { "length", 1, 0, 'l' }, |
||||
- { "posix", 0, 0, 'x' }, |
||||
- { NULL, 0, 0, 0 } |
||||
+ { "help", no_argument, NULL, 'h' }, |
||||
+ { "version", no_argument, NULL, 'V' }, |
||||
+ { "keep-size", no_argument, NULL, 'n' }, |
||||
+ { "punch-hole", no_argument, NULL, 'p' }, |
||||
+ { "collapse-range", no_argument, NULL, 'c' }, |
||||
+ { "dig-holes", no_argument, NULL, 'd' }, |
||||
+ { "insert-range", no_argument, NULL, 'i' }, |
||||
+ { "zero-range", no_argument, NULL, 'z' }, |
||||
+ { "offset", required_argument, NULL, 'o' }, |
||||
+ { "length", required_argument, NULL, 'l' }, |
||||
+ { "posix", no_argument, NULL, 'x' }, |
||||
+ { "verbose", no_argument, NULL, 'v' }, |
||||
+ { NULL, 0, NULL, 0 } |
||||
}; |
||||
|
||||
- static const ul_excl_t excl[] = { /* rows and cols in ASCII order */ |
||||
- { 'x', 'n', 'p' }, |
||||
+ static const ul_excl_t excl[] = { /* rows and cols in ASCII order */ |
||||
+ { 'c', 'd', 'p', 'z' }, |
||||
+ { 'c', 'n' }, |
||||
+ { 'x', 'c', 'd', 'i', 'n', 'p', 'z'}, |
||||
{ 0 } |
||||
}; |
||||
int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; |
||||
@@ -130,29 +313,39 @@ int main(int argc, char **argv) |
||||
textdomain(PACKAGE); |
||||
atexit(close_stdout); |
||||
|
||||
- while ((c = getopt_long(argc, argv, "hVnpl:o:x", longopts, NULL)) != -1) { |
||||
+ while ((c = getopt_long(argc, argv, "hvVncpdizxl:o:", longopts, NULL)) |
||||
+ != -1) { |
||||
|
||||
err_exclusive_options(c, longopts, excl, excl_st); |
||||
|
||||
switch(c) { |
||||
case 'h': |
||||
- usage(stdout); |
||||
+ usage(); |
||||
break; |
||||
- case 'V': |
||||
- printf(UTIL_LINUX_VERSION); |
||||
- return EXIT_SUCCESS; |
||||
- case 'p': |
||||
- mode |= FALLOC_FL_PUNCH_HOLE; |
||||
- /* fall through */ |
||||
- case 'n': |
||||
- mode |= FALLOC_FL_KEEP_SIZE; |
||||
+ case 'c': |
||||
+ mode |= FALLOC_FL_COLLAPSE_RANGE; |
||||
+ break; |
||||
+ case 'd': |
||||
+ dig = 1; |
||||
+ break; |
||||
+ case 'i': |
||||
+ mode |= FALLOC_FL_INSERT_RANGE; |
||||
break; |
||||
case 'l': |
||||
length = cvtnum(optarg); |
||||
break; |
||||
+ case 'n': |
||||
+ mode |= FALLOC_FL_KEEP_SIZE; |
||||
+ break; |
||||
case 'o': |
||||
offset = cvtnum(optarg); |
||||
break; |
||||
+ case 'p': |
||||
+ mode |= FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE; |
||||
+ break; |
||||
+ case 'z': |
||||
+ mode |= FALLOC_FL_ZERO_RANGE; |
||||
+ break; |
||||
case 'x': |
||||
#ifdef HAVE_POSIX_FALLOCATE |
||||
posix = 1; |
||||
@@ -160,53 +353,59 @@ int main(int argc, char **argv) |
||||
#else |
||||
errx(EXIT_FAILURE, _("posix_fallocate support is not compiled")) |
||||
#endif |
||||
- default: |
||||
- usage(stderr); |
||||
+ case 'v': |
||||
+ verbose++; |
||||
break; |
||||
+ case 'V': |
||||
+ printf(UTIL_LINUX_VERSION); |
||||
+ return EXIT_SUCCESS; |
||||
+ default: |
||||
+ errtryhelp(EXIT_FAILURE); |
||||
} |
||||
} |
||||
|
||||
- if (length == -2LL) |
||||
- errx(EXIT_FAILURE, _("no length argument specified")); |
||||
- if (length <= 0) |
||||
- errx(EXIT_FAILURE, _("invalid length value specified")); |
||||
- if (offset < 0) |
||||
- errx(EXIT_FAILURE, _("invalid offset value specified")); |
||||
if (optind == argc) |
||||
- errx(EXIT_FAILURE, _("no filename specified.")); |
||||
+ errx(EXIT_FAILURE, _("no filename specified")); |
||||
+ |
||||
+ filename = argv[optind++]; |
||||
|
||||
- fname = argv[optind++]; |
||||
+ if (optind != argc) |
||||
+ errx(EXIT_FAILURE, _("unexpected number of arguments")); |
||||
|
||||
- if (optind != argc) { |
||||
- warnx(_("unexpected number of arguments")); |
||||
- usage(stderr); |
||||
+ if (dig) { |
||||
+ /* for --dig-holes the default is analyze all file */ |
||||
+ if (length == -2LL) |
||||
+ length = 0; |
||||
+ if (length < 0) |
||||
+ errx(EXIT_FAILURE, _("invalid length value specified")); |
||||
+ } else { |
||||
+ /* it's safer to require the range specification (--length --offset) */ |
||||
+ if (length == -2LL) |
||||
+ errx(EXIT_FAILURE, _("no length argument specified")); |
||||
+ if (length <= 0) |
||||
+ errx(EXIT_FAILURE, _("invalid length value specified")); |
||||
} |
||||
+ if (offset < 0) |
||||
+ errx(EXIT_FAILURE, _("invalid offset value specified")); |
||||
|
||||
- fd = open(fname, O_WRONLY|O_CREAT, 0644); |
||||
+ /* O_CREAT makes sense only for the default fallocate(2) behavior |
||||
+ * when mode is no specified and new space is allocated |
||||
+ * |
||||
+ * RHEL7.6: for backward compatibility in RHEL7 we keep O_CREAT there. |
||||
+ */ |
||||
+ fd = open(filename, O_RDWR | O_CREAT, |
||||
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); |
||||
if (fd < 0) |
||||
- err(EXIT_FAILURE, _("cannot open %s"), fname); |
||||
+ err(EXIT_FAILURE, _("cannot open %s"), filename); |
||||
|
||||
+ if (dig) |
||||
+ dig_holes(fd, offset, length); |
||||
#ifdef HAVE_POSIX_FALLOCATE |
||||
- if (posix) |
||||
+ else if (posix) |
||||
xposix_fallocate(fd, offset, length); |
||||
- else |
||||
#endif |
||||
- |
||||
-#ifdef HAVE_FALLOCATE |
||||
- error = fallocate(fd, mode, offset, length); |
||||
-#else |
||||
- error = syscall(SYS_fallocate, fd, mode, offset, length); |
||||
-#endif |
||||
- /* |
||||
- * EOPNOTSUPP: The FALLOC_FL_KEEP_SIZE is unsupported |
||||
- * ENOSYS: The filesystem does not support sys_fallocate |
||||
- */ |
||||
- if (error < 0) { |
||||
- if ((mode & FALLOC_FL_KEEP_SIZE) && errno == EOPNOTSUPP) |
||||
- errx(EXIT_FAILURE, |
||||
- _("keep size mode (-n option) unsupported")); |
||||
- err(EXIT_FAILURE, _("%s: fallocate failed"), fname); |
||||
- } |
||||
+ else |
||||
+ xfallocate(fd, mode, offset, length); |
||||
|
||||
close(fd); |
||||
return EXIT_SUCCESS; |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
From 7f5f61824b3b7ffa81d34481aec5a7ecca213a5a Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Wed, 3 Jan 2018 13:59:59 +0100 |
||||
Subject: [PATCH 160/173] libmount: fix mnt_table_is_fs_mounted() for rbind |
||||
|
||||
There is no difference between "bind" and "rbind" if we want to FS |
||||
root to search for the FS in mountinfo file. |
||||
|
||||
fstab: |
||||
|
||||
/dev/sdc1 /mnt/foo xfs defaults 0 0 |
||||
/mnt/foo /mnt/test none rw,rbind 0 0 |
||||
|
||||
use -a more than once: |
||||
|
||||
mount -a |
||||
mount -a |
||||
|
||||
/proc/mounts (the current result): |
||||
|
||||
/dev/sdc1 /mnt/foo xfs rw,relatime,attr2,inode64,noquota 0 0 |
||||
/dev/sdc1 /mnt/test xfs rw,relatime,attr2,inode64,noquota 0 0 |
||||
/dev/sdc1 /mnt/test xfs rw,relatime,attr2,inode64,noquota 0 0 |
||||
/dev/sdc1 /mnt/foo xfs rw,relatime,attr2,inode64,noquota 0 0 |
||||
|
||||
expected (fixed version) result: |
||||
|
||||
/dev/sdc1 /mnt/foo xfs rw,relatime,attr2,inode64,noquota 0 0 |
||||
/dev/sdc1 /mnt/test xfs rw,relatime,attr2,inode64,noquota 0 0 |
||||
|
||||
Upstream: http://github.com/karelzak/util-linux/commit/b5cc232362a60b2a7738ee250609202bd6195e49 |
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1528959 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
libmount/src/tab.c | 3 ++- |
||||
1 file changed, 2 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/libmount/src/tab.c b/libmount/src/tab.c |
||||
index 5628da6e5..dfa1da822 100644 |
||||
--- a/libmount/src/tab.c |
||||
+++ b/libmount/src/tab.c |
||||
@@ -1099,7 +1099,8 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs) |
||||
struct libmnt_fs *rootfs; |
||||
int flags = 0; |
||||
|
||||
- if (mnt_fs_get_option(fstab_fs, "bind", NULL, NULL) == 0) |
||||
+ if (mnt_fs_get_option(fstab_fs, "bind", NULL, NULL) == 0 || |
||||
+ mnt_fs_get_option(fstab_fs, "rbind", NULL, NULL) == 0) |
||||
flags = MS_BIND; |
||||
|
||||
rootfs = mnt_table_get_fs_root(tb, fstab_fs, flags, &root); |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
From 7492cf62b7334792df931469ca783878b868d0d0 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Wed, 6 Jun 2018 12:10:42 +0200 |
||||
Subject: [PATCH 161/173] mount: add ext4 to some places in man page |
||||
|
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1538721 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
sys-utils/mount.8 | 8 ++++---- |
||||
1 file changed, 4 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/sys-utils/mount.8 b/sys-utils/mount.8 |
||||
index 49cb2818f..35d782f0e 100644 |
||||
--- a/sys-utils/mount.8 |
||||
+++ b/sys-utils/mount.8 |
||||
@@ -874,7 +874,7 @@ for example tune2fs -l output for extN filesystems). |
||||
The following options apply to any filesystem that is being |
||||
mounted (but not every filesystem actually honors them - e.g., the |
||||
.B sync |
||||
-option today has effect only for ext2, ext3, fat, vfat and ufs): |
||||
+option today has effect only for ext2, ext3, ext4, fat, vfat and ufs): |
||||
|
||||
.TP |
||||
.B async |
||||
@@ -909,7 +909,7 @@ The |
||||
.BR context= |
||||
option is useful when mounting filesystems that do not support |
||||
extended attributes, such as a floppy or hard disk formatted with VFAT, or |
||||
-systems that are not normally running under SELinux, such as an ext3 formatted |
||||
+systems that are not normally running under SELinux, such as an ext3 or ext4 formatted |
||||
disk from a non-SELinux workstation. You can also use |
||||
.BR context= |
||||
on filesystems you do not trust, such as a floppy. It also helps in compatibility with |
||||
@@ -2833,7 +2833,7 @@ not specified or the filesystem is known for libblkid, for example: |
||||
.sp |
||||
.B "mount /tmp/disk.img /mnt" |
||||
.sp |
||||
-.B "mount -t ext3 /tmp/disk.img /mnt" |
||||
+.B "mount -t ext4 /tmp/disk.img /mnt" |
||||
.sp |
||||
.RE |
||||
This type of mount knows about four options, namely |
||||
@@ -2948,7 +2948,7 @@ It is possible for a corrupted filesystem to cause a crash. |
||||
.PP |
||||
Some Linux filesystems don't support |
||||
.B "\-o sync and \-o dirsync" |
||||
-(the ext2, ext3, fat and vfat filesystems |
||||
+(the ext2, ext3, ext4, fat and vfat filesystems |
||||
.I do |
||||
support synchronous updates (a la BSD) when mounted with the |
||||
.B sync |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
From 7974045302fe53629e70501f0180f30cbaa25b1e Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Wed, 6 Jun 2018 15:57:24 +0200 |
||||
Subject: [PATCH 162/173] agetty: keep c_iflags unmodified on --autologin |
||||
|
||||
agetty sets c_iflags according to interaction with serial line in |
||||
get_logname(). For --autologin it does not read from the line, so we |
||||
have no clue how to set the flags. |
||||
|
||||
The current behavior is to zeroize the flags. Unfortunately, it seems |
||||
like bad idea, because the line may be already properly initialized by |
||||
kernel (or systemd, etc.). |
||||
|
||||
The new behavior is not touch the flags on --autologin. |
||||
|
||||
Upstream: http://github.com/karelzak/util-linux/commit/2c4d86abdadab19be76abecb156da7f7dc284d81 |
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1252764 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
term-utils/agetty.8 | 4 ++++ |
||||
term-utils/agetty.c | 17 +++++++++++++---- |
||||
2 files changed, 17 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/term-utils/agetty.8 b/term-utils/agetty.8 |
||||
index a42cdf158..fe4bfd427 100644 |
||||
--- a/term-utils/agetty.8 |
||||
+++ b/term-utils/agetty.8 |
||||
@@ -94,6 +94,10 @@ password. The \-f \fIusername\fP option is added to the \fB/bin/login\fP |
||||
command line by default. The \-\-login-options option changes this default |
||||
behaviour and then only \\u is replaced by the \fIusername\fP and no other |
||||
option is added to the login command line. |
||||
+ |
||||
+Note that \fB\-\-autologin\fP may affect the way how agetty initializes the |
||||
+serial line, because on auto-login agetty does not read from the line and it |
||||
+has no opportunity optimize the line setting. |
||||
.TP |
||||
\-c, \-\-noreset |
||||
Don't reset terminal cflags (control modes). See \fItermios(3)\fP for more |
||||
diff --git a/term-utils/agetty.c b/term-utils/agetty.c |
||||
index b626cdbeb..948d77246 100644 |
||||
--- a/term-utils/agetty.c |
||||
+++ b/term-utils/agetty.c |
||||
@@ -1100,13 +1100,22 @@ static void termio_init(struct options *op, struct termios *tp) |
||||
/* Flush input and output queues, important for modems! */ |
||||
tcflush(STDIN_FILENO, TCIOFLUSH); |
||||
|
||||
+ /* The defaul is set c_iflag in termio_final() according to chardata. |
||||
+ * Unfortunately, the chardata are not set according to the serial line |
||||
+ * if --autolog is enabled. In this case we do not read from the line |
||||
+ * at all. The best what we can do in this case is to keep c_iflag |
||||
+ * unmodified for --autolog. |
||||
+ */ |
||||
+ if (!op->autolog) { |
||||
#ifdef IUTF8 |
||||
- tp->c_iflag = tp->c_iflag & IUTF8; |
||||
- if (tp->c_iflag & IUTF8) |
||||
- op->flags |= F_UTF8; |
||||
+ tp->c_iflag = tp->c_iflag & IUTF8; |
||||
+ if (tp->c_iflag & IUTF8) |
||||
+ op->flags |= F_UTF8; |
||||
#else |
||||
- tp->c_iflag = 0; |
||||
+ tp->c_iflag = 0; |
||||
#endif |
||||
+ } |
||||
+ |
||||
tp->c_lflag = 0; |
||||
tp->c_oflag &= OPOST | ONLCR; |
||||
|
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
From 94f380e223e7496804dcd68e204fba0a15df8bd7 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Mon, 25 May 2015 15:24:13 +0200 |
||||
Subject: [PATCH 163/173] sulogin: don't use strcpy(), enlarge pwd line buffer |
||||
|
||||
* according to "man getpwnam" 16384 bytes is enough to store one |
||||
passwd entry (let's use 2*BUFSIZE to avoid magic numbers in code) |
||||
|
||||
* don't use strcpy() to set empty password |
||||
|
||||
Upstream: http://github.com/karelzak/util-linux/commit/d681e0956cdca1a016346424939fe1b9c6a0a549 |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1561200 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
login-utils/sulogin.c | 14 +++++++------- |
||||
1 file changed, 7 insertions(+), 7 deletions(-) |
||||
|
||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c |
||||
index bbd67b3ee..6d03bc5ae 100644 |
||||
--- a/login-utils/sulogin.c |
||||
+++ b/login-utils/sulogin.c |
||||
@@ -373,8 +373,8 @@ static struct passwd *getrootpwent(int try_manually) |
||||
struct passwd *pw; |
||||
struct spwd *spw; |
||||
FILE *fp; |
||||
- static char line[256]; |
||||
- static char sline[256]; |
||||
+ static char line[2 * BUFSIZ]; |
||||
+ static char sline[2 * BUFSIZ]; |
||||
char *p; |
||||
|
||||
/* |
||||
@@ -410,7 +410,7 @@ static struct passwd *getrootpwent(int try_manually) |
||||
/* |
||||
* Find root in the password file. |
||||
*/ |
||||
- while ((p = fgets(line, 256, fp)) != NULL) { |
||||
+ while ((p = fgets(line, sizeof(line), fp)) != NULL) { |
||||
if (strncmp(line, "root:", 5) != 0) |
||||
continue; |
||||
p += 5; |
||||
@@ -439,12 +439,12 @@ static struct passwd *getrootpwent(int try_manually) |
||||
/* |
||||
* The password is invalid. If there is a shadow password, try it. |
||||
*/ |
||||
- strcpy(pwd.pw_passwd, ""); |
||||
+ *pwd.pw_passwd = '\0'; |
||||
if ((fp = fopen(_PATH_SHADOW_PASSWD, "r")) == NULL) { |
||||
warn(_("cannot open %s"), _PATH_PASSWD); |
||||
return &pwd; |
||||
} |
||||
- while ((p = fgets(sline, 256, fp)) != NULL) { |
||||
+ while ((p = fgets(sline, sizeof(sline), fp)) != NULL) { |
||||
if (strncmp(sline, "root:", 5) != 0) |
||||
continue; |
||||
p += 5; |
||||
@@ -458,11 +458,11 @@ static struct passwd *getrootpwent(int try_manually) |
||||
*/ |
||||
if (p == NULL) { |
||||
warnx(_("%s: no entry for root"), _PATH_SHADOW_PASSWD); |
||||
- strcpy(pwd.pw_passwd, ""); |
||||
+ *pwd.pw_passwd = '\0'; |
||||
} |
||||
if (!valid(pwd.pw_passwd)) { |
||||
warnx(_("%s: root password garbled"), _PATH_SHADOW_PASSWD); |
||||
- strcpy(pwd.pw_passwd, ""); |
||||
+ *pwd.pw_passwd = '\0'; |
||||
} |
||||
return &pwd; |
||||
} |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,175 @@
@@ -0,0 +1,175 @@
|
||||
From a08c1a6aadaa27e4070fe58242d55464d6c7a3e7 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Mon, 25 May 2015 15:30:52 +0200 |
||||
Subject: [PATCH 164/173] sulogin: improve support for locked root account |
||||
|
||||
Some installations and distributions don't use a root account password |
||||
for security reasons and use sudo instead. In that case, asking for the |
||||
password makes no sense, and it is not even considered as valid as it's just |
||||
"*" or "!". |
||||
|
||||
In these cases --force is required to just start a root shell and no |
||||
ask for password. |
||||
|
||||
I don't think it's a good idea to automatically start root shell when |
||||
locked account is detected. It's possible that the machine is on |
||||
public place and for example Ubuntu uses root account disabled by |
||||
default (and also Fedora when installed by yum/dnf without anaconda). |
||||
|
||||
The --force option forces admins to think about it... |
||||
|
||||
The distro maintainers can also use --force in their initscripts or |
||||
systemd emergency.service if they believe that promiscuous setting is |
||||
the right thing for the distro. |
||||
|
||||
Addresses: https://bugs.debian.org/326678 |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1561200 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/7ff1162e67164cb4ece19dd809c26272461aa254 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
login-utils/sulogin.8 | 13 +++++++++---- |
||||
login-utils/sulogin.c | 48 ++++++++++++++++++++++++++++++++++-------------- |
||||
2 files changed, 43 insertions(+), 18 deletions(-) |
||||
|
||||
diff --git a/login-utils/sulogin.8 b/login-utils/sulogin.8 |
||||
index b9dec165c..702487985 100644 |
||||
--- a/login-utils/sulogin.8 |
||||
+++ b/login-utils/sulogin.8 |
||||
@@ -35,8 +35,10 @@ Give root password for system maintenance |
||||
.br |
||||
(or type Control\-D for normal startup): |
||||
.PP |
||||
-.I sulogin |
||||
-will be connected to the current terminal, or to the optional tty device that |
||||
+If the root account is locked and --force is specified, no password is required. |
||||
+.PP |
||||
+.B sulogin |
||||
+will be connected to the current terminal, or to the optional \fItty\fR device that |
||||
can be specified on the command line (typically |
||||
.BR /dev/console ). |
||||
.PP |
||||
@@ -50,8 +52,11 @@ from the system fails, manually examine |
||||
.I /etc/passwd |
||||
and |
||||
.I /etc/shadow |
||||
-to get the password. If they are damaged or nonexistent, sulogin will start |
||||
-a root shell without asking for a password. |
||||
+to get the password. If these files are damaged or nonexistent, or when |
||||
+root account is locked by '!' or '*' at the begin of the password then |
||||
+.B sulogin |
||||
+will \fBstart a root shell without asking for a password\fP. |
||||
+.PP |
||||
.IP |
||||
Only use the |
||||
.B \-e |
||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c |
||||
index 6d03bc5ae..a17b91d71 100644 |
||||
--- a/login-utils/sulogin.c |
||||
+++ b/login-utils/sulogin.c |
||||
@@ -81,6 +81,13 @@ static volatile sig_atomic_t sigchild; |
||||
# define IUCLC 0 |
||||
#endif |
||||
|
||||
+static int locked_account_password(const char *passwd) |
||||
+{ |
||||
+ if (passwd && (*passwd == '*' || *passwd == '!')) |
||||
+ return 1; |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
/* |
||||
* Fix the tty modes and set reasonable defaults. |
||||
*/ |
||||
@@ -423,7 +430,6 @@ static struct passwd *getrootpwent(int try_manually) |
||||
p = line; |
||||
break; |
||||
} |
||||
- |
||||
fclose(fp); |
||||
|
||||
/* |
||||
@@ -460,7 +466,8 @@ static struct passwd *getrootpwent(int try_manually) |
||||
warnx(_("%s: no entry for root"), _PATH_SHADOW_PASSWD); |
||||
*pwd.pw_passwd = '\0'; |
||||
} |
||||
- if (!valid(pwd.pw_passwd)) { |
||||
+ /* locked accont passwords are valid too */ |
||||
+ if (!locked_account_password(pwd.pw_passwd) && !valid(pwd.pw_passwd)) { |
||||
warnx(_("%s: root password garbled"), _PATH_SHADOW_PASSWD); |
||||
*pwd.pw_passwd = '\0'; |
||||
} |
||||
@@ -470,7 +477,7 @@ static struct passwd *getrootpwent(int try_manually) |
||||
/* |
||||
* Ask by prompt for the password. |
||||
*/ |
||||
-static void doprompt(const char *crypted, struct console *con) |
||||
+static void doprompt(const char *crypted, struct console *con, int deny) |
||||
{ |
||||
struct termios tty; |
||||
|
||||
@@ -487,18 +494,25 @@ static void doprompt(const char *crypted, struct console *con) |
||||
if ((con->file = fdopen(con->fd, "r+")) == (FILE*)0) |
||||
goto err; |
||||
} |
||||
+ |
||||
+ if (deny) |
||||
+ fprintf(con->file, _("\nCannot open access to console, the root account is locked.\n" |
||||
+ "See sulogin(8) man page for more details.\n\n" |
||||
+ "Press Enter to continue.\n")); |
||||
+ else { |
||||
#if defined(USE_ONELINE) |
||||
- if (crypted[0]) |
||||
- fprintf(con->file, _("Give root password for login: ")); |
||||
- else |
||||
- fprintf(con->file, _("Press enter for login: ")); |
||||
+ if (crypted[0] && !locked_account_password(crypted)) |
||||
+ fprintf(con->file, _("Give root password for login: ")); |
||||
+ else |
||||
+ fprintf(con->file, _("Press Enter for login: ")); |
||||
#else |
||||
- if (crypted[0]) |
||||
- fprintf(con->file, _("Give root password for maintenance\n")); |
||||
- else |
||||
- fprintf(con->file, _("Press enter for maintenance")); |
||||
- fprintf(con->file, _("(or type Control-D to continue): ")); |
||||
+ if (crypted[0] && !locked_account_password(crypted)) |
||||
+ fprintf(con->file, _("Give root password for maintenance\n")); |
||||
+ else |
||||
+ fprintf(con->file, _("Press Enter for maintenance\n")); |
||||
+ fprintf(con->file, _("(or press Control-D to continue): ")); |
||||
#endif |
||||
+ } |
||||
fflush(con->file); |
||||
err: |
||||
if (con->flags & CON_SERIAL) |
||||
@@ -914,6 +928,7 @@ int main(int argc, char **argv) |
||||
goto nofork; |
||||
} |
||||
|
||||
+ |
||||
mask_signal(SIGCHLD, chld_handler, &saved_sigchld); |
||||
do { |
||||
con = list_entry(ptr, struct console, entry); |
||||
@@ -930,12 +945,17 @@ int main(int argc, char **argv) |
||||
const char *passwd = pwd->pw_passwd; |
||||
const char *answer; |
||||
int failed = 0, doshell = 0; |
||||
+ int deny = !opt_e && locked_account_password(pwd->pw_passwd); |
||||
+ |
||||
+ doprompt(passwd, con, deny); |
||||
|
||||
- doprompt(passwd, con); |
||||
if ((answer = getpasswd(con)) == NULL) |
||||
break; |
||||
+ if (deny) |
||||
+ exit(EXIT_FAILURE); |
||||
|
||||
- if (passwd[0] == '\0') |
||||
+ /* no password or locked account */ |
||||
+ if (!passwd[0] || locked_account_password(passwd)) |
||||
doshell++; |
||||
else { |
||||
const char *cryptbuf; |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
From 6bb8e6d4c38f260109852ef8b43876ea1aff3810 Mon Sep 17 00:00:00 2001 |
||||
From: Werner Fink <werner@suse.de> |
||||
Date: Tue, 22 Mar 2016 10:38:59 +0100 |
||||
Subject: [PATCH 165/173] sulogin: Always make echo work after performing |
||||
getpasswd even if root account is locked |
||||
|
||||
If the root account is locked and no password was provided then the terminal |
||||
line is not set back to do echo of the input. This correct a small overlook |
||||
in commit 7ff1162e67164cb4ece19dd809c26272461aa254 |
||||
|
||||
Upstream: http://github.com/karelzak/util-linux/commit/6988998b66b4b95c494d60599f8e3de2ffbaeece |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1561200 |
||||
Signed-off-by: Werner Fink <werner@suse.de> |
||||
--- |
||||
login-utils/sulogin.c | 3 +-- |
||||
1 file changed, 1 insertion(+), 2 deletions(-) |
||||
|
||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c |
||||
index a17b91d71..a6918282e 100644 |
||||
--- a/login-utils/sulogin.c |
||||
+++ b/login-utils/sulogin.c |
||||
@@ -676,8 +676,7 @@ quit: |
||||
alarm(0); |
||||
if (tc) |
||||
tcsetattr(fd, TCSAFLUSH, &con->tio); |
||||
- if (ret && *ret != '\0') |
||||
- tcfinal(con); |
||||
+ tcfinal(con); |
||||
printf("\r\n"); |
||||
out: |
||||
return ret; |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
From c19feb058ff5883ab7255241d13732ab66bf44f0 Mon Sep 17 00:00:00 2001 |
||||
From: Andreas Henriksson <andreas@fatal.se> |
||||
Date: Mon, 28 Nov 2016 17:24:49 +0100 |
||||
Subject: [PATCH 166/173] sulogin: make getpasswd(...) return NULL on ^D |
||||
MIME-Version: 1.0 |
||||
Content-Type: text/plain; charset=UTF-8 |
||||
Content-Transfer-Encoding: 8bit |
||||
|
||||
This makes the caller bail out early instead of evaluating the |
||||
input as a password. |
||||
|
||||
Reported-by: Bjørn Mork <bjorn@mork.no> |
||||
Addresses: http://bugs.debian.org/846112 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/60dea9d187caa700e42f37c7955116f71be912d5 |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1561200 |
||||
Signed-off-by: Andreas Henriksson <andreas@fatal.se> |
||||
--- |
||||
login-utils/sulogin.c | 1 + |
||||
1 file changed, 1 insertion(+) |
||||
|
||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c |
||||
index a6918282e..7ec349953 100644 |
||||
--- a/login-utils/sulogin.c |
||||
+++ b/login-utils/sulogin.c |
||||
@@ -661,6 +661,7 @@ static char *getpasswd(struct console *con) |
||||
ptr--; |
||||
break; |
||||
case CEOF: |
||||
+ ret = NULL; |
||||
goto quit; |
||||
default: |
||||
if ((size_t)(ptr - &pass[0]) >= (sizeof(pass) -1 )) { |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
From 971b2ecede4d2040e879d9cfb56332a2e210bed8 Mon Sep 17 00:00:00 2001 |
||||
From: Andreas Henriksson <andreas@fatal.se> |
||||
Date: Mon, 28 Nov 2016 17:24:50 +0100 |
||||
Subject: [PATCH 167/173] sulogin: bail out from getpasswd(...) on timeout |
||||
MIME-Version: 1.0 |
||||
Content-Type: text/plain; charset=UTF-8 |
||||
Content-Transfer-Encoding: 8bit |
||||
|
||||
If timeout happens while waiting in prompt, bail out instead |
||||
of retrying. |
||||
|
||||
Reported-by: Bjørn Mork <bjorn@mork.no> |
||||
Addresses: http://bugs.debian.org/846107 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/1c4b2d43926e2a7032310cd18b411d8d872cb4ed |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1561200 |
||||
Signed-off-by: Andreas Henriksson <andreas@fatal.se> |
||||
--- |
||||
login-utils/sulogin.c | 4 ++++ |
||||
1 file changed, 4 insertions(+) |
||||
|
||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c |
||||
index 7ec349953..dd73a1c50 100644 |
||||
--- a/login-utils/sulogin.c |
||||
+++ b/login-utils/sulogin.c |
||||
@@ -611,6 +611,10 @@ static char *getpasswd(struct console *con) |
||||
while (cp->eol == '\0') { |
||||
if (read(fd, &c, 1) < 1) { |
||||
if (errno == EINTR || errno == EAGAIN) { |
||||
+ if (alarm_rised) { |
||||
+ ret = NULL; |
||||
+ goto quit; |
||||
+ } |
||||
usleep(1000); |
||||
continue; |
||||
} |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
From 14a4f41a94cc4bd227940c4bd976e39d9f13e8c5 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Thu, 7 Jun 2018 12:05:08 +0200 |
||||
Subject: [PATCH 168/173] losetup: keep -f and <devname> mutually exclusive |
||||
|
||||
losetup tries to blindly use specified device as well as search for |
||||
the first free device, the result is: |
||||
|
||||
# losetup /dev/loop1 -f /tmp/tfile_loop1 |
||||
losetup: /dev/loop1: failed to set up loop device: Invalid argument |
||||
|
||||
fixed version: |
||||
|
||||
# losetup /dev/loop10 -f img |
||||
losetup: unexpected arguments |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1566432 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/c3f5a0f1d47dbc47f6d21da232d4eb1cfb7905db |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
sys-utils/losetup.c | 3 +++ |
||||
1 file changed, 3 insertions(+) |
||||
|
||||
diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c |
||||
index d9b0c9b61..8df831b8f 100644 |
||||
--- a/sys-utils/losetup.c |
||||
+++ b/sys-utils/losetup.c |
||||
@@ -545,6 +545,9 @@ int main(int argc, char **argv) |
||||
*/ |
||||
act = A_CREATE; |
||||
file = argv[optind++]; |
||||
+ |
||||
+ if (optind < argc) |
||||
+ errx(EXIT_FAILURE, _("unexpected arguments")); |
||||
} |
||||
|
||||
if (list && !act && optind == argc) |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
From 79866c4b187e9ccf37fe333e9865a8575f4a3a16 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Wed, 6 Jun 2018 10:10:20 +0200 |
||||
Subject: [PATCH 169/173] lscpu: fix mzx/min MHz reporting |
||||
|
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1579439 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
sys-utils/lscpu.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- |
||||
1 file changed, 48 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c |
||||
index 1ee73f34a..4c15de1d4 100644 |
||||
--- a/sys-utils/lscpu.c |
||||
+++ b/sys-utils/lscpu.c |
||||
@@ -1251,6 +1251,52 @@ read_configured(struct lscpu_desc *desc, int idx) |
||||
desc->configured[idx] = path_read_s32(_PATH_SYS_CPU "/cpu%d/configure", num); |
||||
} |
||||
|
||||
+/* Read overall maximum frequency of cpu */ |
||||
+static char * |
||||
+cpu_max_mhz(struct lscpu_desc *desc, char *buf, size_t bufsz) |
||||
+{ |
||||
+ int i; |
||||
+ float cpu_freq = 0.0; |
||||
+ size_t setsize = CPU_ALLOC_SIZE(maxcpus); |
||||
+ |
||||
+ if (desc->present) { |
||||
+ for (i = 0; i < desc->ncpuspos; i++) { |
||||
+ if (CPU_ISSET_S(real_cpu_num(desc, i), setsize, desc->present) |
||||
+ && desc->maxmhz[i]) { |
||||
+ float freq = atof(desc->maxmhz[i]); |
||||
+ |
||||
+ if (freq > cpu_freq) |
||||
+ cpu_freq = freq; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ snprintf(buf, bufsz, "%.4f", cpu_freq); |
||||
+ return buf; |
||||
+} |
||||
+ |
||||
+/* Read overall minimum frequency of cpu */ |
||||
+static char * |
||||
+cpu_min_mhz(struct lscpu_desc *desc, char *buf, size_t bufsz) |
||||
+{ |
||||
+ int i; |
||||
+ float cpu_freq = -1.0; |
||||
+ size_t setsize = CPU_ALLOC_SIZE(maxcpus); |
||||
+ |
||||
+ if (desc->present) { |
||||
+ for (i = 0; i < desc->ncpuspos; i++) { |
||||
+ if (CPU_ISSET_S(real_cpu_num(desc, i), setsize, desc->present) |
||||
+ && desc->minmhz[i]) { |
||||
+ float freq = atof(desc->minmhz[i]); |
||||
+ |
||||
+ if (cpu_freq < 0.0 || freq < cpu_freq) |
||||
+ cpu_freq = freq; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ snprintf(buf, bufsz, "%.4f", cpu_freq); |
||||
+ return buf; |
||||
+} |
||||
+ |
||||
static void |
||||
read_max_mhz(struct lscpu_desc *desc, int idx) |
||||
{ |
||||
@@ -1898,9 +1944,9 @@ print_summary(struct lscpu_desc *desc, struct lscpu_modifier *mod) |
||||
if (desc->static_mhz) |
||||
print_s(_("CPU static MHz:"), desc->static_mhz); |
||||
if (desc->maxmhz && desc->maxmhz[0]) |
||||
- print_s(_("CPU max MHz:"), desc->maxmhz[0]); |
||||
+ print_s(_("CPU max MHz:"), cpu_max_mhz(desc, buf, sizeof(buf))); |
||||
if (desc->minmhz && desc->minmhz[0]) |
||||
- print_s(_("CPU min MHz:"), desc->minmhz[0]); |
||||
+ print_s(_("CPU min MHz:"), cpu_min_mhz(desc, buf, sizeof(buf))); |
||||
if (desc->bogomips) |
||||
print_s(_("BogoMIPS:"), desc->bogomips); |
||||
if (desc->virtflag) { |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,253 @@
@@ -0,0 +1,253 @@
|
||||
From 8f57ecb12194a10f3dbe6eca9f4bf0b18c4be757 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Wed, 5 Mar 2014 11:06:59 +0100 |
||||
Subject: [PATCH 170/173] chcpu: cleanup return codes |
||||
|
||||
The code currently always return EXIT_SUCCESS, that's strange. It |
||||
seems better to return 0 on success, 1 on complete failure and 64 on |
||||
partial success. |
||||
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
Upstream: http://github.com/karelzak/util-linux/commit/48fc00c1c70f3dbbd8ad6ef423bbba27dd3efb69 |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1579439 |
||||
--- |
||||
sys-utils/chcpu.8 | 14 ++++++++++ |
||||
sys-utils/chcpu.c | 82 ++++++++++++++++++++++++++++++++++++++++--------------- |
||||
2 files changed, 74 insertions(+), 22 deletions(-) |
||||
|
||||
diff --git a/sys-utils/chcpu.8 b/sys-utils/chcpu.8 |
||||
index d016b86f2..125d9d2ad 100644 |
||||
--- a/sys-utils/chcpu.8 |
||||
+++ b/sys-utils/chcpu.8 |
||||
@@ -80,6 +80,20 @@ Display help information and exit. |
||||
.TP |
||||
.BR \-V , " \-\-version" |
||||
Display version information and exit. |
||||
+ |
||||
+.SH RETURN CODES |
||||
+.B chcpu |
||||
+has the following return codes: |
||||
+.TP |
||||
+.BR 0 |
||||
+success |
||||
+.TP |
||||
+.BR 1 |
||||
+failure |
||||
+.TP |
||||
+.BR 64 |
||||
+partial success |
||||
+.RE |
||||
.SH AUTHOR |
||||
.MT heiko.carstens@de.ibm.com |
||||
Heiko Carstens |
||||
diff --git a/sys-utils/chcpu.c b/sys-utils/chcpu.c |
||||
index 1162888d5..304b80d7a 100644 |
||||
--- a/sys-utils/chcpu.c |
||||
+++ b/sys-utils/chcpu.c |
||||
@@ -45,6 +45,9 @@ |
||||
|
||||
#define EXCL_ERROR "--{configure,deconfigure,disable,dispatch,enable}" |
||||
|
||||
+/* partial success, otherwise we return regular EXIT_{SUCCESS,FAILURE} */ |
||||
+#define CHCPU_EXIT_SOMEOK 64 |
||||
+ |
||||
#define _PATH_SYS_CPU "/sys/devices/system/cpu" |
||||
#define _PATH_SYS_CPU_ONLINE _PATH_SYS_CPU "/online" |
||||
#define _PATH_SYS_CPU_RESCAN _PATH_SYS_CPU "/rescan" |
||||
@@ -66,21 +69,28 @@ enum { |
||||
CMD_CPU_DISPATCH_VERTICAL, |
||||
}; |
||||
|
||||
+/* returns: 0 = success |
||||
+ * < 0 = failure |
||||
+ * > 0 = partial success |
||||
+ */ |
||||
static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
{ |
||||
unsigned int cpu; |
||||
int online, rc; |
||||
int configured = -1; |
||||
+ size_t fails = 0; |
||||
|
||||
for (cpu = 0; cpu < setsize; cpu++) { |
||||
if (!CPU_ISSET(cpu, cpu_set)) |
||||
continue; |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d", cpu)) { |
||||
printf(_("CPU %d does not exist\n"), cpu); |
||||
+ fails++; |
||||
continue; |
||||
} |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d/online", cpu)) { |
||||
printf(_("CPU %d is not hot pluggable\n"), cpu); |
||||
+ fails++; |
||||
continue; |
||||
} |
||||
online = path_read_s32(_PATH_SYS_CPU "/cpu%d/online", cpu); |
||||
@@ -96,30 +106,35 @@ static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
configured = path_read_s32(_PATH_SYS_CPU "/cpu%d/configure", cpu); |
||||
if (enable) { |
||||
rc = path_write_str("1", _PATH_SYS_CPU "/cpu%d/online", cpu); |
||||
- if ((rc == -1) && (configured == 0)) |
||||
+ if ((rc == -1) && (configured == 0)) { |
||||
warnx(_("CPU %d enable failed " |
||||
"(CPU is deconfigured)"), cpu); |
||||
- else if (rc == -1) |
||||
+ fails++; |
||||
+ } else if (rc == -1) { |
||||
warn(_("CPU %d enable failed"), cpu); |
||||
- else |
||||
+ fails++; |
||||
+ } else |
||||
printf(_("CPU %d enabled\n"), cpu); |
||||
} else { |
||||
if (onlinecpus && num_online_cpus() == 1) { |
||||
printf(_("CPU %d disable failed " |
||||
"(last enabled CPU)\n"), cpu); |
||||
+ fails++; |
||||
continue; |
||||
} |
||||
rc = path_write_str("0", _PATH_SYS_CPU "/cpu%d/online", cpu); |
||||
- if (rc == -1) |
||||
+ if (rc == -1) { |
||||
warn(_("CPU %d disable failed"), cpu); |
||||
- else { |
||||
+ fails++; |
||||
+ } else { |
||||
printf(_("CPU %d disabled\n"), cpu); |
||||
if (onlinecpus) |
||||
CPU_CLR(cpu, onlinecpus); |
||||
} |
||||
} |
||||
} |
||||
- return EXIT_SUCCESS; |
||||
+ |
||||
+ return fails == 0 ? 0 : fails == setsize ? -1 : 1; |
||||
} |
||||
|
||||
static int cpu_rescan(void) |
||||
@@ -129,7 +144,7 @@ static int cpu_rescan(void) |
||||
if (path_write_str("1", _PATH_SYS_CPU_RESCAN) == -1) |
||||
err(EXIT_FAILURE, _("Failed to trigger rescan of CPUs")); |
||||
printf(_("Triggered rescan of CPUs\n")); |
||||
- return EXIT_SUCCESS; |
||||
+ return 0; |
||||
} |
||||
|
||||
static int cpu_set_dispatch(int mode) |
||||
@@ -146,23 +161,30 @@ static int cpu_set_dispatch(int mode) |
||||
err(EXIT_FAILURE, _("Failed to set vertical dispatch mode")); |
||||
printf(_("Successfully set vertical dispatching mode\n")); |
||||
} |
||||
- return EXIT_SUCCESS; |
||||
+ return 0; |
||||
} |
||||
|
||||
+/* returns: 0 = success |
||||
+ * < 0 = failure |
||||
+ * > 0 = partial success |
||||
+ */ |
||||
static int cpu_configure(cpu_set_t *cpu_set, size_t setsize, int configure) |
||||
{ |
||||
unsigned int cpu; |
||||
int rc, current; |
||||
+ size_t fails = 0; |
||||
|
||||
for (cpu = 0; cpu < setsize; cpu++) { |
||||
if (!CPU_ISSET(cpu, cpu_set)) |
||||
continue; |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d", cpu)) { |
||||
printf(_("CPU %d does not exist\n"), cpu); |
||||
+ fails++; |
||||
continue; |
||||
} |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d/configure", cpu)) { |
||||
printf(_("CPU %d is not configurable\n"), cpu); |
||||
+ fails++; |
||||
continue; |
||||
} |
||||
current = path_read_s32(_PATH_SYS_CPU "/cpu%d/configure", cpu); |
||||
@@ -178,23 +200,27 @@ static int cpu_configure(cpu_set_t *cpu_set, size_t setsize, int configure) |
||||
is_cpu_online(cpu)) { |
||||
printf(_("CPU %d deconfigure failed " |
||||
"(CPU is enabled)\n"), cpu); |
||||
+ fails++; |
||||
continue; |
||||
} |
||||
if (configure) { |
||||
rc = path_write_str("1", _PATH_SYS_CPU "/cpu%d/configure", cpu); |
||||
- if (rc == -1) |
||||
+ if (rc == -1) { |
||||
warn(_("CPU %d configure failed"), cpu); |
||||
- else |
||||
+ fails++; |
||||
+ } else |
||||
printf(_("CPU %d configured\n"), cpu); |
||||
} else { |
||||
rc = path_write_str("0", _PATH_SYS_CPU "/cpu%d/configure", cpu); |
||||
- if (rc == -1) |
||||
+ if (rc == -1) { |
||||
warn(_("CPU %d deconfigure failed"), cpu); |
||||
- else |
||||
+ fails++; |
||||
+ } else |
||||
printf(_("CPU %d deconfigured\n"), cpu); |
||||
} |
||||
} |
||||
- return EXIT_SUCCESS; |
||||
+ |
||||
+ return fails == 0 ? 0 : fails == setsize ? -1 : 1; |
||||
} |
||||
|
||||
static void cpu_parse(char *cpu_string, cpu_set_t *cpu_set, size_t setsize) |
||||
@@ -233,7 +259,7 @@ int main(int argc, char *argv[]) |
||||
cpu_set_t *cpu_set; |
||||
size_t setsize; |
||||
int cmd = -1; |
||||
- int c; |
||||
+ int c, rc; |
||||
|
||||
static const struct option longopts[] = { |
||||
{ "configure", required_argument, 0, 'c' }, |
||||
@@ -317,19 +343,31 @@ int main(int argc, char *argv[]) |
||||
|
||||
switch (cmd) { |
||||
case CMD_CPU_ENABLE: |
||||
- return cpu_enable(cpu_set, maxcpus, 1); |
||||
+ rc = cpu_enable(cpu_set, maxcpus, 1); |
||||
+ break; |
||||
case CMD_CPU_DISABLE: |
||||
- return cpu_enable(cpu_set, maxcpus, 0); |
||||
+ rc = cpu_enable(cpu_set, maxcpus, 0); |
||||
+ break; |
||||
case CMD_CPU_CONFIGURE: |
||||
- return cpu_configure(cpu_set, maxcpus, 1); |
||||
+ rc = cpu_configure(cpu_set, maxcpus, 1); |
||||
+ break; |
||||
case CMD_CPU_DECONFIGURE: |
||||
- return cpu_configure(cpu_set, maxcpus, 0); |
||||
+ rc = cpu_configure(cpu_set, maxcpus, 0); |
||||
+ break; |
||||
case CMD_CPU_RESCAN: |
||||
- return cpu_rescan(); |
||||
+ rc = cpu_rescan(); |
||||
+ break; |
||||
case CMD_CPU_DISPATCH_HORIZONTAL: |
||||
- return cpu_set_dispatch(0); |
||||
+ rc = cpu_set_dispatch(0); |
||||
+ break; |
||||
case CMD_CPU_DISPATCH_VERTICAL: |
||||
- return cpu_set_dispatch(1); |
||||
+ rc = cpu_set_dispatch(1); |
||||
+ break; |
||||
+ default: |
||||
+ rc = -EINVAL; |
||||
+ break; |
||||
} |
||||
- return EXIT_SUCCESS; |
||||
+ |
||||
+ return rc == 0 ? EXIT_SUCCESS : |
||||
+ rc < 0 ? EXIT_FAILURE : CHCPU_EXIT_SOMEOK; |
||||
} |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
From 26c75797103da70f85a5fdd646625edb3eaa300c Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Wed, 5 Mar 2014 11:23:16 +0100 |
||||
Subject: [PATCH 171/173] chcpu: cleanup stdout/stderr usage |
||||
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
Upstream: http://github.com/karelzak/util-linux/commit/69e74525bb3212944feebc8c2848317e04d95ec0 |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1579439 |
||||
--- |
||||
sys-utils/chcpu.c | 17 +++++++---------- |
||||
1 file changed, 7 insertions(+), 10 deletions(-) |
||||
|
||||
diff --git a/sys-utils/chcpu.c b/sys-utils/chcpu.c |
||||
index 304b80d7a..ada0eaacc 100644 |
||||
--- a/sys-utils/chcpu.c |
||||
+++ b/sys-utils/chcpu.c |
||||
@@ -84,12 +84,12 @@ static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
if (!CPU_ISSET(cpu, cpu_set)) |
||||
continue; |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d", cpu)) { |
||||
- printf(_("CPU %d does not exist\n"), cpu); |
||||
+ warnx(_("CPU %d does not exist"), cpu); |
||||
fails++; |
||||
continue; |
||||
} |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d/online", cpu)) { |
||||
- printf(_("CPU %d is not hot pluggable\n"), cpu); |
||||
+ warnx(_("CPU %d is not hot pluggable"), cpu); |
||||
fails++; |
||||
continue; |
||||
} |
||||
@@ -107,8 +107,7 @@ static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
if (enable) { |
||||
rc = path_write_str("1", _PATH_SYS_CPU "/cpu%d/online", cpu); |
||||
if ((rc == -1) && (configured == 0)) { |
||||
- warnx(_("CPU %d enable failed " |
||||
- "(CPU is deconfigured)"), cpu); |
||||
+ warn(_("CPU %d enable failed (CPU is deconfigured)"), cpu); |
||||
fails++; |
||||
} else if (rc == -1) { |
||||
warn(_("CPU %d enable failed"), cpu); |
||||
@@ -117,8 +116,7 @@ static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
printf(_("CPU %d enabled\n"), cpu); |
||||
} else { |
||||
if (onlinecpus && num_online_cpus() == 1) { |
||||
- printf(_("CPU %d disable failed " |
||||
- "(last enabled CPU)\n"), cpu); |
||||
+ warnx(_("CPU %d disable failed (last enabled CPU)"), cpu); |
||||
fails++; |
||||
continue; |
||||
} |
||||
@@ -178,12 +176,12 @@ static int cpu_configure(cpu_set_t *cpu_set, size_t setsize, int configure) |
||||
if (!CPU_ISSET(cpu, cpu_set)) |
||||
continue; |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d", cpu)) { |
||||
- printf(_("CPU %d does not exist\n"), cpu); |
||||
+ warnx(_("CPU %d does not exist"), cpu); |
||||
fails++; |
||||
continue; |
||||
} |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d/configure", cpu)) { |
||||
- printf(_("CPU %d is not configurable\n"), cpu); |
||||
+ warnx(_("CPU %d is not configurable"), cpu); |
||||
fails++; |
||||
continue; |
||||
} |
||||
@@ -198,8 +196,7 @@ static int cpu_configure(cpu_set_t *cpu_set, size_t setsize, int configure) |
||||
} |
||||
if ((current == 1) && (configure == 0) && onlinecpus && |
||||
is_cpu_online(cpu)) { |
||||
- printf(_("CPU %d deconfigure failed " |
||||
- "(CPU is enabled)\n"), cpu); |
||||
+ warnx(_("CPU %d deconfigure failed (CPU is enabled)"), cpu); |
||||
fails++; |
||||
continue; |
||||
} |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
From 255a3b8bb8cbcb3f689cc3332983983bfbf9eca0 Mon Sep 17 00:00:00 2001 |
||||
From: Stanislav Brabec <sbrabec@suse.cz> |
||||
Date: Wed, 9 May 2018 18:08:32 +0200 |
||||
Subject: [PATCH 172/173] lscpu, chcpu: Avoid use of the old CPU macros |
||||
|
||||
The old CPU macros are limited to 1024 cores. As a result, lscpu cannot |
||||
count sockets on large systems. Use new scalable macros. |
||||
|
||||
Signed-off-by: Stanislav Brabec <sbrabec@suse.cz> |
||||
Cc: Michael Matz <matz@suse.de> |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1579439 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/538b50cb0a4aac56b6b3b6e4d1e8ce886854c6d8 |
||||
--- |
||||
sys-utils/chcpu.c | 6 +++--- |
||||
sys-utils/lscpu.c | 7 +++++-- |
||||
2 files changed, 8 insertions(+), 5 deletions(-) |
||||
|
||||
diff --git a/sys-utils/chcpu.c b/sys-utils/chcpu.c |
||||
index ada0eaacc..7843dfb22 100644 |
||||
--- a/sys-utils/chcpu.c |
||||
+++ b/sys-utils/chcpu.c |
||||
@@ -81,7 +81,7 @@ static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
size_t fails = 0; |
||||
|
||||
for (cpu = 0; cpu < setsize; cpu++) { |
||||
- if (!CPU_ISSET(cpu, cpu_set)) |
||||
+ if (!CPU_ISSET_S(cpu, setsize, cpu_set)) |
||||
continue; |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d", cpu)) { |
||||
warnx(_("CPU %d does not exist"), cpu); |
||||
@@ -127,7 +127,7 @@ static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
} else { |
||||
printf(_("CPU %d disabled\n"), cpu); |
||||
if (onlinecpus) |
||||
- CPU_CLR(cpu, onlinecpus); |
||||
+ CPU_CLR_S(cpu, setsize, onlinecpus); |
||||
} |
||||
} |
||||
} |
||||
@@ -173,7 +173,7 @@ static int cpu_configure(cpu_set_t *cpu_set, size_t setsize, int configure) |
||||
size_t fails = 0; |
||||
|
||||
for (cpu = 0; cpu < setsize; cpu++) { |
||||
- if (!CPU_ISSET(cpu, cpu_set)) |
||||
+ if (!CPU_ISSET_S(cpu, setsize, cpu_set)) |
||||
continue; |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d", cpu)) { |
||||
warnx(_("CPU %d does not exist"), cpu); |
||||
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c |
||||
index 4c15de1d4..002ad0d1c 100644 |
||||
--- a/sys-utils/lscpu.c |
||||
+++ b/sys-utils/lscpu.c |
||||
@@ -626,7 +626,7 @@ read_basicinfo(struct lscpu_desc *desc, struct lscpu_modifier *mod) |
||||
desc->idx2cpunum = xcalloc(desc->ncpuspos, sizeof(int)); |
||||
|
||||
for (num = 0, idx = 0; num < maxcpus; num++) { |
||||
- if (CPU_ISSET(num, tmp)) |
||||
+ if (CPU_ISSET_S(num, setsize, tmp)) |
||||
desc->idx2cpunum[idx++] = num; |
||||
} |
||||
cpuset_free(tmp); |
||||
@@ -2038,6 +2038,7 @@ int main(int argc, char *argv[]) |
||||
int c, i; |
||||
int columns[ARRAY_SIZE(coldescs)], ncolumns = 0; |
||||
int cpu_modifier_specified = 0; |
||||
+ size_t setsize; |
||||
|
||||
static const struct option longopts[] = { |
||||
{ "all", no_argument, NULL, 'a' }, |
||||
@@ -2134,10 +2135,12 @@ int main(int argc, char *argv[]) |
||||
|
||||
read_basicinfo(desc, mod); |
||||
|
||||
+ setsize = CPU_ALLOC_SIZE(maxcpus); |
||||
+ |
||||
for (i = 0; i < desc->ncpuspos; i++) { |
||||
/* only consider present CPUs */ |
||||
if (desc->present && |
||||
- !CPU_ISSET(real_cpu_num(desc, i), desc->present)) |
||||
+ !CPU_ISSET_S(real_cpu_num(desc, i), setsize, desc->present)) |
||||
continue; |
||||
read_topology(desc, i); |
||||
read_cache(desc, i); |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
From 72e09b02e7b4cf3e9e77ef02d5073d9a11f3b314 Mon Sep 17 00:00:00 2001 |
||||
From: Stanislav Brabec <sbrabec@suse.cz> |
||||
Date: Wed, 9 May 2018 22:13:07 +0200 |
||||
Subject: [PATCH 173/173] chcpu: Fix maximal number of CPUs |
||||
|
||||
chcpu.c mixed maxcpus (number of cpus) and setsize (size of CPU bit |
||||
mask). It effectively limits number of CPUs to 1/8 of the supported |
||||
amount. |
||||
|
||||
Signed-off-by: Stanislav Brabec <sbrabec@suse.cz> |
||||
Cc: Michael Matz <matz@suse.de> |
||||
Cc: Heiko Carstens <heiko.carstens@de.ibm.com> |
||||
Upstream: http://github.com/karelzak/util-linux/commit/607274943bfd3d4856b872bc4278b36903fb2182 |
||||
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1579439 |
||||
--- |
||||
sys-utils/chcpu.c | 16 ++++++++-------- |
||||
1 file changed, 8 insertions(+), 8 deletions(-) |
||||
|
||||
diff --git a/sys-utils/chcpu.c b/sys-utils/chcpu.c |
||||
index 7843dfb22..1a0157360 100644 |
||||
--- a/sys-utils/chcpu.c |
||||
+++ b/sys-utils/chcpu.c |
||||
@@ -75,12 +75,12 @@ enum { |
||||
*/ |
||||
static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
{ |
||||
- unsigned int cpu; |
||||
+ int cpu; |
||||
int online, rc; |
||||
int configured = -1; |
||||
- size_t fails = 0; |
||||
+ int fails = 0; |
||||
|
||||
- for (cpu = 0; cpu < setsize; cpu++) { |
||||
+ for (cpu = 0; cpu < maxcpus; cpu++) { |
||||
if (!CPU_ISSET_S(cpu, setsize, cpu_set)) |
||||
continue; |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d", cpu)) { |
||||
@@ -132,7 +132,7 @@ static int cpu_enable(cpu_set_t *cpu_set, size_t setsize, int enable) |
||||
} |
||||
} |
||||
|
||||
- return fails == 0 ? 0 : fails == setsize ? -1 : 1; |
||||
+ return fails == 0 ? 0 : fails == maxcpus ? -1 : 1; |
||||
} |
||||
|
||||
static int cpu_rescan(void) |
||||
@@ -168,11 +168,11 @@ static int cpu_set_dispatch(int mode) |
||||
*/ |
||||
static int cpu_configure(cpu_set_t *cpu_set, size_t setsize, int configure) |
||||
{ |
||||
- unsigned int cpu; |
||||
+ int cpu; |
||||
int rc, current; |
||||
- size_t fails = 0; |
||||
+ int fails = 0; |
||||
|
||||
- for (cpu = 0; cpu < setsize; cpu++) { |
||||
+ for (cpu = 0; cpu < maxcpus; cpu++) { |
||||
if (!CPU_ISSET_S(cpu, setsize, cpu_set)) |
||||
continue; |
||||
if (!path_exist(_PATH_SYS_CPU "/cpu%d", cpu)) { |
||||
@@ -217,7 +217,7 @@ static int cpu_configure(cpu_set_t *cpu_set, size_t setsize, int configure) |
||||
} |
||||
} |
||||
|
||||
- return fails == 0 ? 0 : fails == setsize ? -1 : 1; |
||||
+ return fails == 0 ? 0 : fails == maxcpus ? -1 : 1; |
||||
} |
||||
|
||||
static void cpu_parse(char *cpu_string, cpu_set_t *cpu_set, size_t setsize) |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
From b4d5cf4819023ce07ecd39729cdd4cde8b59ca35 Mon Sep 17 00:00:00 2001 |
||||
From: Nate Clark <nate@neworld.us> |
||||
Date: Wed, 4 Jan 2017 15:24:22 -0500 |
||||
Subject: [PATCH 174/176] libblkid/minix: Match minix superblock types |
||||
|
||||
All of the types in the minix super block are unsigned but in |
||||
probe_minix they were being treated as signed. This would cause some of |
||||
the extra sanity checks to pass on a non minix device. The types were |
||||
updated to match the return types of the helper functions in |
||||
disk-utils/minix_programs.h |
||||
|
||||
This can be checked by creating a swap partition with one of these UUIDs |
||||
35f1f264-2468-471a-bc85-acc9f4bc04a3 |
||||
35f1f264-6824-471a-bc85-acc9f4bc04a3 |
||||
35f1f264-2478-471a-bc85-acc9f4bc04a3 |
||||
35f1f264-7824-471a-bc85-acc9f4bc04a3 |
||||
|
||||
Prior to this change they would all be considered minix and swap by |
||||
blkid. |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1594681 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/a9975c1072c4975ec2df958188a80d89cabc6171 |
||||
Signed-off-by: Nate Clark <nate@neworld.us> |
||||
--- |
||||
libblkid/src/superblocks/minix.c | 3 ++- |
||||
1 file changed, 2 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/libblkid/src/superblocks/minix.c b/libblkid/src/superblocks/minix.c |
||||
index 3e80e5b22..a20d51f2c 100644 |
||||
--- a/libblkid/src/superblocks/minix.c |
||||
+++ b/libblkid/src/superblocks/minix.c |
||||
@@ -87,7 +87,8 @@ static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) |
||||
|
||||
if (version <= 2) { |
||||
struct minix_super_block *sb = (struct minix_super_block *) data; |
||||
- int zones, ninodes, imaps, zmaps, firstz; |
||||
+ unsigned long zones, ninodes, imaps, zmaps; |
||||
+ off_t firstz; |
||||
|
||||
if (sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) |
||||
return 1; |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
From 6eb3a6579768458c13c26958e1cc3fbffe2ada70 Mon Sep 17 00:00:00 2001 |
||||
From: Nate Clark <nate@neworld.us> |
||||
Date: Wed, 4 Jan 2017 15:21:17 -0500 |
||||
Subject: [PATCH 175/176] libblkid/minix: Sanity check superblock s_state for v |
||||
1 and 2 |
||||
|
||||
Swap devices with specific values in the uuid can look like minix |
||||
devices to blkid. Add an extra check to make sure the state of the |
||||
filesystem has valid state flags. |
||||
|
||||
A couple of offending swap uuids include: |
||||
35f1f264-137f-471a-bc85-acc9f4bc04a3 |
||||
35f1f264-7f13-471a-bc85-acc9f4bc04a3 |
||||
35f1f264-138f-471a-bc85-acc9f4bc04a3 |
||||
35f1f264-8f13-471a-bc85-acc9f4bc04a3 |
||||
|
||||
Without this change a swap device with any of those uuids would be |
||||
detected as minix and swap by blkid. |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1594681 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/892553b1a41b449f58462f123eca2bf2c6c56b33 |
||||
Signed-off-by: Nate Clark <nate@neworld.us> |
||||
--- |
||||
libblkid/src/superblocks/minix.c | 4 ++++ |
||||
1 file changed, 4 insertions(+) |
||||
|
||||
diff --git a/libblkid/src/superblocks/minix.c b/libblkid/src/superblocks/minix.c |
||||
index a20d51f2c..4e70fda8f 100644 |
||||
--- a/libblkid/src/superblocks/minix.c |
||||
+++ b/libblkid/src/superblocks/minix.c |
||||
@@ -93,6 +93,10 @@ static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) |
||||
if (sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) |
||||
return 1; |
||||
|
||||
+ uint16_t state = minix_swab16(swabme, sb->s_state); |
||||
+ if ((state & (MINIX_VALID_FS | MINIX_ERROR_FS)) != state) |
||||
+ return 1; |
||||
+ |
||||
zones = version == 2 ? minix_swab32(swabme, sb->s_zones) : |
||||
minix_swab16(swabme, sb->s_nzones); |
||||
ninodes = minix_swab16(swabme, sb->s_ninodes); |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
From b5d9bfe34e62cf1c57646efa0bd72ecad7d98258 Mon Sep 17 00:00:00 2001 |
||||
From: Nate Clark <nate@neworld.us> |
||||
Date: Wed, 4 Jan 2017 15:24:32 -0500 |
||||
Subject: [PATCH 176/176] libblkid/minix: Use same checks for version 3 |
||||
|
||||
fsck.minix performs the same sanity checks on all versions of the |
||||
superblock. Update the probe to perform the same sanity checks so it is |
||||
less likely a different type of filesystem will be identified as minix. |
||||
|
||||
Upstream: http://github.com/karelzak/util-linux/commit/f82c804869bb8613fa0924e3111b7eb55bb04fcd |
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1594681 |
||||
Signed-off-by: Nate Clark <nate@neworld.us> |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
libblkid/src/superblocks/minix.c | 38 +++++++++++++++++++++++--------------- |
||||
1 file changed, 23 insertions(+), 15 deletions(-) |
||||
|
||||
diff --git a/libblkid/src/superblocks/minix.c b/libblkid/src/superblocks/minix.c |
||||
index 4e70fda8f..21b3bf8bb 100644 |
||||
--- a/libblkid/src/superblocks/minix.c |
||||
+++ b/libblkid/src/superblocks/minix.c |
||||
@@ -75,6 +75,9 @@ static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) |
||||
unsigned char *ext; |
||||
const unsigned char *data; |
||||
int version = 0, swabme = 0; |
||||
+ unsigned long zones, ninodes, imaps, zmaps; |
||||
+ off_t firstz; |
||||
+ size_t zone_size; |
||||
|
||||
data = blkid_probe_get_buffer(pr, 1024, |
||||
max(sizeof(struct minix_super_block), |
||||
@@ -85,14 +88,9 @@ static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) |
||||
if (version < 1) |
||||
return 1; |
||||
|
||||
+ |
||||
if (version <= 2) { |
||||
struct minix_super_block *sb = (struct minix_super_block *) data; |
||||
- unsigned long zones, ninodes, imaps, zmaps; |
||||
- off_t firstz; |
||||
- |
||||
- if (sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) |
||||
- return 1; |
||||
- |
||||
uint16_t state = minix_swab16(swabme, sb->s_state); |
||||
if ((state & (MINIX_VALID_FS | MINIX_ERROR_FS)) != state) |
||||
return 1; |
||||
@@ -103,20 +101,30 @@ static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) |
||||
imaps = minix_swab16(swabme, sb->s_imap_blocks); |
||||
zmaps = minix_swab16(swabme, sb->s_zmap_blocks); |
||||
firstz = minix_swab16(swabme, sb->s_firstdatazone); |
||||
- |
||||
- /* sanity checks to be sure that the FS is really minix */ |
||||
- if (imaps * MINIX_BLOCK_SIZE * 8 < ninodes + 1) |
||||
- return 1; |
||||
- if (zmaps * MINIX_BLOCK_SIZE * 8 < zones - firstz + 1) |
||||
- return 1; |
||||
- |
||||
+ zone_size = sb->s_log_zone_size; |
||||
} else if (version == 3) { |
||||
struct minix3_super_block *sb = (struct minix3_super_block *) data; |
||||
|
||||
- if (sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) |
||||
- return 1; |
||||
+ zones = minix_swab32(swabme, sb->s_zones); |
||||
+ ninodes = minix_swab32(swabme, sb->s_ninodes); |
||||
+ imaps = minix_swab16(swabme, sb->s_imap_blocks); |
||||
+ zmaps = minix_swab16(swabme, sb->s_zmap_blocks); |
||||
+ firstz = minix_swab16(swabme, sb->s_firstdatazone); |
||||
+ zone_size = sb->s_log_zone_size; |
||||
} |
||||
|
||||
+ /* sanity checks to be sure that the FS is really minix. |
||||
+ * see disk-utils/fsck.minix.c read_superblock |
||||
+ */ |
||||
+ if (zone_size != 0 || ninodes == 0 || ninodes == UINT32_MAX) |
||||
+ return 1; |
||||
+ if (imaps * MINIX_BLOCK_SIZE * 8 < ninodes + 1) |
||||
+ return 1; |
||||
+ if (firstz > (off_t) zones) |
||||
+ return 1; |
||||
+ if (zmaps * MINIX_BLOCK_SIZE * 8 < zones - firstz + 1) |
||||
+ return 1; |
||||
+ |
||||
/* unfortunately, some parts of ext3 is sometimes possible to |
||||
* interpreted as minix superblock. So check for extN magic |
||||
* string. (For extN magic string and offsets see ext.c.) |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
From 4b376d1ad1b46408bc59d949c277991a9b5035eb Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Thu, 27 Oct 2016 15:30:20 +0200 |
||||
Subject: [PATCH 177/178] mount: append inverting options for mount.<type> on |
||||
"users" |
||||
|
||||
If you call mount(8) as root, then we need to append inverting options |
||||
(if specified by fstab) for "user" and "users" to /sbin/mount.<type> |
||||
command line, because for UID=0 mount.nfs follows command line rather |
||||
than the fstab setting. |
||||
|
||||
This has been originally implemented by commit |
||||
a4c0cc75ff9744299f108c259efab1bd30c8007a for the old mount(8). The |
||||
same feature is supported by libmount, unfortunately for "user" only. |
||||
We need the same also for "users" to be backwardly compatible. |
||||
|
||||
Addresses: https://github.com/karelzak/util-linux/issues/368 |
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1618711 |
||||
Upstream: http://github.com/karelzak/util-linux/commit/3c4a3de0fcb8f21bffacfd8bdc3d6fbd683c71f5 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
libmount/src/context_mount.c | 3 ++- |
||||
1 file changed, 2 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c |
||||
index 4df2646b0..0f4485592 100644 |
||||
--- a/libmount/src/context_mount.c |
||||
+++ b/libmount/src/context_mount.c |
||||
@@ -321,7 +321,8 @@ static int generate_helper_optstr(struct libmnt_context *cxt, char **optstr) |
||||
if (!*optstr) |
||||
return -ENOMEM; |
||||
|
||||
- if (cxt->user_mountflags & MNT_MS_USER) { |
||||
+ if ((cxt->user_mountflags & MNT_MS_USER) || |
||||
+ (cxt->user_mountflags & MNT_MS_USERS)) { |
||||
/* |
||||
* This is unnecessary for real user-mounts as mount.<type> |
||||
* helpers have to always follow fstab rather than mount |
||||
-- |
||||
2.14.4 |
||||
|
@ -0,0 +1,839 @@
@@ -0,0 +1,839 @@
|
||||
From f720781671c9f5421fb8101dd3bcf7b56efca131 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Mon, 20 Aug 2018 14:56:08 +0200 |
||||
Subject: [PATCH 178/178] sulogin: backport RHEL-8 version |
||||
|
||||
The new version is more robust and it does not use mmap()-ed shared |
||||
memory between sulogins instances. It also provides some fallbacks for |
||||
s390 machines. |
||||
|
||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1616264 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
configure.ac | 1 + |
||||
include/c.h | 4 + |
||||
login-utils/sulogin-consoles.c | 116 +++++++++++++------ |
||||
login-utils/sulogin.c | 253 +++++++++++++++++++++++++++-------------- |
||||
4 files changed, 252 insertions(+), 122 deletions(-) |
||||
|
||||
diff --git a/configure.ac b/configure.ac |
||||
index d561e01d0..3f07df495 100644 |
||||
--- a/configure.ac |
||||
+++ b/configure.ac |
||||
@@ -218,6 +218,7 @@ AC_CHECK_HEADERS([ \ |
||||
sys/prctl.h \ |
||||
sys/queue.h \ |
||||
sys/resource.h \ |
||||
+ sys/sysmacros.h \ |
||||
sys/socket.h \ |
||||
sys/sockio.h \ |
||||
sys/stat.h \ |
||||
diff --git a/include/c.h b/include/c.h |
||||
index 124035ea5..51d439297 100644 |
||||
--- a/include/c.h |
||||
+++ b/include/c.h |
||||
@@ -19,6 +19,10 @@ |
||||
# include <err.h> |
||||
#endif |
||||
|
||||
+#ifdef HAVE_SYS_SYSMACROS_H |
||||
+# include <sys/sysmacros.h> /* for major, minor */ |
||||
+#endif |
||||
+ |
||||
#ifndef HAVE_USLEEP |
||||
# include <time.h> |
||||
#endif |
||||
diff --git a/login-utils/sulogin-consoles.c b/login-utils/sulogin-consoles.c |
||||
index 07af33a6d..2c0eed3a4 100644 |
||||
--- a/login-utils/sulogin-consoles.c |
||||
+++ b/login-utils/sulogin-consoles.c |
||||
@@ -36,8 +36,9 @@ |
||||
# include <linux/serial.h> |
||||
# include <linux/major.h> |
||||
#endif |
||||
-#include <fcntl.h> |
||||
#include <dirent.h> |
||||
+#include <errno.h> |
||||
+#include <fcntl.h> |
||||
#include <unistd.h> |
||||
|
||||
#ifdef USE_SULOGIN_EMERGENCY_MOUNT |
||||
@@ -74,7 +75,7 @@ static int consoles_debug; |
||||
} while (0) |
||||
|
||||
static inline void __attribute__ ((__format__ (__printf__, 1, 2))) |
||||
-dbgprint(const char *mesg, ...) |
||||
+dbgprint(const char * const mesg, ...) |
||||
{ |
||||
va_list ap; |
||||
va_start(ap, mesg); |
||||
@@ -112,7 +113,7 @@ void emergency_do_mounts(void) |
||||
} |
||||
|
||||
if (stat("/", &rt) != 0) { |
||||
- warn("can not get file status of root file system\n"); |
||||
+ warn("cannot get file status of root file system\n"); |
||||
return; |
||||
} |
||||
|
||||
@@ -150,17 +151,19 @@ void emergency_do_mounts(void) { } |
||||
* the caller has to free the result |
||||
*/ |
||||
static __attribute__((__nonnull__)) |
||||
-char *oneline(const char *file) |
||||
+char *oneline(const char * const file) |
||||
{ |
||||
FILE *fp; |
||||
char *ret = NULL; |
||||
- size_t len = 0; |
||||
+ size_t dummy = 0; |
||||
+ ssize_t len; |
||||
|
||||
DBG(dbgprint("reading %s", file)); |
||||
|
||||
- if (!(fp = fopen(file, "re"))) |
||||
+ if (!(fp = fopen(file, "r" UL_CLOEXECSTR))) |
||||
return NULL; |
||||
- if (getline(&ret, &len, fp) >= 0) { |
||||
+ len = getline(&ret, &dummy, fp); |
||||
+ if (len >= 0) { |
||||
char *nl; |
||||
|
||||
if (len) |
||||
@@ -179,7 +182,7 @@ char *oneline(const char *file) |
||||
* /sys/class/tty, the caller has to free the result. |
||||
*/ |
||||
static __attribute__((__malloc__)) |
||||
-char *actattr(const char *tty) |
||||
+char *actattr(const char * const tty) |
||||
{ |
||||
char *ret, *path; |
||||
|
||||
@@ -198,7 +201,7 @@ char *actattr(const char *tty) |
||||
* /sys/class/tty. |
||||
*/ |
||||
static |
||||
-dev_t devattr(const char *tty) |
||||
+dev_t devattr(const char * const tty) |
||||
{ |
||||
dev_t dev = 0; |
||||
char *path, *value; |
||||
@@ -223,42 +226,77 @@ dev_t devattr(const char *tty) |
||||
#endif /* __linux__ */ |
||||
|
||||
/* |
||||
- * Search below /dev for the characer device in `dev_t comparedev' variable. |
||||
+ * Search below /dev for the character device in `dev_t comparedev' variable. |
||||
+ * Note that realpath(3) is used here to avoid not existent devices due the |
||||
+ * strdup(3) used in our canonicalize_path()! |
||||
*/ |
||||
static |
||||
#ifdef __GNUC__ |
||||
__attribute__((__nonnull__,__malloc__,__hot__)) |
||||
#endif |
||||
-char* scandev(DIR *dir, dev_t comparedev) |
||||
+char* scandev(DIR *dir, const dev_t comparedev) |
||||
{ |
||||
+ char path[PATH_MAX]; |
||||
char *name = NULL; |
||||
- struct dirent *dent; |
||||
- int fd; |
||||
+ const struct dirent *dent; |
||||
+ int len, fd; |
||||
|
||||
DBG(dbgprint("scanning /dev for %u:%u", major(comparedev), minor(comparedev))); |
||||
|
||||
+ /* |
||||
+ * Try udev links on character devices first. |
||||
+ */ |
||||
+ if ((len = snprintf(path, sizeof(path), |
||||
+ "/dev/char/%u:%u", major(comparedev), minor(comparedev))) > 0 && |
||||
+ (size_t)len < sizeof(path)) { |
||||
+ |
||||
+ name = realpath(path, NULL); |
||||
+ if (name) |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
fd = dirfd(dir); |
||||
rewinddir(dir); |
||||
while ((dent = readdir(dir))) { |
||||
- char path[PATH_MAX]; |
||||
struct stat st; |
||||
+ |
||||
+#ifdef _DIRENT_HAVE_D_TYPE |
||||
+ if (dent->d_type != DT_UNKNOWN && dent->d_type != DT_CHR) |
||||
+ continue; |
||||
+#endif |
||||
if (fstatat(fd, dent->d_name, &st, 0) < 0) |
||||
continue; |
||||
if (!S_ISCHR(st.st_mode)) |
||||
continue; |
||||
if (comparedev != st.st_rdev) |
||||
continue; |
||||
- if ((size_t)snprintf(path, sizeof(path), "/dev/%s", dent->d_name) >= sizeof(path)) |
||||
+ if ((len = snprintf(path, sizeof(path), "/dev/%s", dent->d_name)) < 0 || |
||||
+ (size_t)len >= sizeof(path)) |
||||
continue; |
||||
-#ifdef USE_SULOGIN_EMERGENCY_MOUNT |
||||
- if (emergency_flags & MNT_DEVTMPFS) |
||||
- mknod(path, S_IFCHR|S_IRUSR|S_IWUSR, comparedev); |
||||
-#endif |
||||
|
||||
- name = canonicalize_path(path); |
||||
- break; |
||||
+ name = realpath(path, NULL); |
||||
+ if (name) |
||||
+ goto out; |
||||
} |
||||
|
||||
+#ifdef USE_SULOGIN_EMERGENCY_MOUNT |
||||
+ /* |
||||
+ * There was no /dev mounted hence and no device was found hence we create our own. |
||||
+ */ |
||||
+ if (!name && (emergency_flags & MNT_DEVTMPFS)) { |
||||
+ |
||||
+ if ((len = snprintf(path, sizeof(path), |
||||
+ "/dev/tmp-%u:%u", major(comparedev), minor(comparedev))) < 0 || |
||||
+ (size_t)len >= sizeof(path)) |
||||
+ goto out; |
||||
+ |
||||
+ if (mknod(path, S_IFCHR|S_IRUSR|S_IWUSR, comparedev) < 0 && errno != EEXIST) |
||||
+ goto out; |
||||
+ |
||||
+ name = realpath(path, NULL); |
||||
+ } |
||||
+#endif |
||||
+out: |
||||
return name; |
||||
} |
||||
|
||||
@@ -273,12 +311,12 @@ char* scandev(DIR *dir, dev_t comparedev) |
||||
*/ |
||||
static |
||||
#ifdef __GNUC__ |
||||
-__attribute__((__nonnull__,__hot__)) |
||||
+__attribute__((__hot__)) |
||||
#endif |
||||
-int append_console(struct list_head *consoles, const char *name) |
||||
+int append_console(struct list_head *consoles, const char * const name) |
||||
{ |
||||
struct console *restrict tail; |
||||
- struct console *last = NULL; |
||||
+ const struct console *last = NULL; |
||||
|
||||
DBG(dbgprint("appenging %s", name)); |
||||
|
||||
@@ -300,7 +338,7 @@ int append_console(struct list_head *consoles, const char *name) |
||||
tail->flags = 0; |
||||
tail->fd = -1; |
||||
tail->id = last ? last->id + 1 : 0; |
||||
- tail->pid = 0; |
||||
+ tail->pid = -1; |
||||
memset(&tail->tio, 0, sizeof(tail->tio)); |
||||
|
||||
return 0; |
||||
@@ -319,11 +357,11 @@ static int detect_consoles_from_proc(struct list_head *consoles) |
||||
char fbuf[16 + 1]; |
||||
DIR *dir = NULL; |
||||
FILE *fc = NULL; |
||||
- int maj, min, rc = 1; |
||||
+ int maj, min, rc = 1, matches; |
||||
|
||||
DBG(dbgprint("trying /proc")); |
||||
|
||||
- fc = fopen("/proc/consoles", "re"); |
||||
+ fc = fopen("/proc/consoles", "r" UL_CLOEXECSTR); |
||||
if (!fc) { |
||||
rc = 2; |
||||
goto done; |
||||
@@ -332,10 +370,12 @@ static int detect_consoles_from_proc(struct list_head *consoles) |
||||
if (!dir) |
||||
goto done; |
||||
|
||||
- while (fscanf(fc, "%*s %*s (%16[^)]) %d:%d", fbuf, &maj, &min) == 3) { |
||||
+ while ((matches = fscanf(fc, "%*s %*s (%16[^)]) %d:%d", fbuf, &maj, &min)) >= 1) { |
||||
char *name; |
||||
dev_t comparedev; |
||||
|
||||
+ if (matches != 3) |
||||
+ continue; |
||||
if (!strchr(fbuf, 'E')) |
||||
continue; |
||||
comparedev = makedev(maj, min); |
||||
@@ -509,7 +549,7 @@ done: |
||||
|
||||
#ifdef TIOCGDEV |
||||
static int detect_consoles_from_tiocgdev(struct list_head *consoles, |
||||
- int fallback, |
||||
+ const int fallback, |
||||
const char *device) |
||||
{ |
||||
unsigned int devnum; |
||||
@@ -579,7 +619,7 @@ done: |
||||
* Returns 1 if stdout and stderr should be reconnected and 0 |
||||
* otherwise or less than zero on error. |
||||
*/ |
||||
-int detect_consoles(const char *device, int fallback, struct list_head *consoles) |
||||
+int detect_consoles(const char *device, const int fallback, struct list_head *consoles) |
||||
{ |
||||
int fd, reconnect = 0, rc; |
||||
dev_t comparedev = 0; |
||||
@@ -587,7 +627,7 @@ int detect_consoles(const char *device, int fallback, struct list_head *consoles |
||||
consoles_debug = getenv("CONSOLES_DEBUG") ? 1 : 0; |
||||
|
||||
if (!device || !*device) |
||||
- fd = dup(fallback); |
||||
+ fd = fallback >= 0 ? dup(fallback) : - 1; |
||||
else { |
||||
fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); |
||||
reconnect = 1; |
||||
@@ -602,6 +642,14 @@ int detect_consoles(const char *device, int fallback, struct list_head *consoles |
||||
struct stat st; |
||||
#ifdef TIOCGDEV |
||||
unsigned int devnum; |
||||
+#endif |
||||
+#ifdef __GNU__ |
||||
+ /* |
||||
+ * The Hurd always gives st_rdev as 0, which causes this |
||||
+ * method to select the first terminal it finds. |
||||
+ */ |
||||
+ close(fd); |
||||
+ goto fallback; |
||||
#endif |
||||
DBG(dbgprint("trying device/fallback file descriptor")); |
||||
|
||||
@@ -670,7 +718,7 @@ int detect_consoles(const char *device, int fallback, struct list_head *consoles |
||||
#ifdef __linux__ |
||||
console: |
||||
/* |
||||
- * Detection of devices used for Linux system consolei using |
||||
+ * Detection of devices used for Linux system console using |
||||
* the /proc/consoles API with kernel 2.6.38 and higher. |
||||
*/ |
||||
rc = detect_consoles_from_proc(consoles); |
||||
@@ -754,8 +802,7 @@ int main(int argc, char *argv[]) |
||||
{ |
||||
char *name = NULL; |
||||
int fd, re; |
||||
- LIST_HEAD(consoles); |
||||
- struct list_head *p; |
||||
+ struct list_head *p, consoles; |
||||
|
||||
if (argc == 2) { |
||||
name = argv[1]; |
||||
@@ -768,6 +815,7 @@ int main(int argc, char *argv[]) |
||||
if (!name) |
||||
errx(EXIT_FAILURE, "usage: %s [<tty>]\n", program_invocation_short_name); |
||||
|
||||
+ INIT_LIST_HEAD(&consoles); |
||||
re = detect_consoles(name, fd, &consoles); |
||||
|
||||
list_for_each(p, &consoles) { |
||||
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c |
||||
index dd73a1c50..4620ed2da 100644 |
||||
--- a/login-utils/sulogin.c |
||||
+++ b/login-utils/sulogin.c |
||||
@@ -56,8 +56,12 @@ |
||||
|
||||
#include "c.h" |
||||
#include "closestream.h" |
||||
+#include "env.h" |
||||
#include "nls.h" |
||||
#include "pathnames.h" |
||||
+#ifdef USE_PLYMOUTH_SUPPORT |
||||
+# include "plymouth-ctrl.h" |
||||
+#endif |
||||
#include "strutils.h" |
||||
#include "ttyutils.h" |
||||
#include "sulogin-consoles.h" |
||||
@@ -66,13 +70,12 @@ |
||||
static unsigned int timeout; |
||||
static int profile; |
||||
static volatile uint32_t openfd; /* Remember higher file descriptors */ |
||||
-static volatile uint32_t *usemask; |
||||
|
||||
-struct sigaction saved_sigint; |
||||
-struct sigaction saved_sigtstp; |
||||
-struct sigaction saved_sigquit; |
||||
-struct sigaction saved_sighup; |
||||
-struct sigaction saved_sigchld; |
||||
+static struct sigaction saved_sigint; |
||||
+static struct sigaction saved_sigtstp; |
||||
+static struct sigaction saved_sigquit; |
||||
+static struct sigaction saved_sighup; |
||||
+static struct sigaction saved_sigchld; |
||||
|
||||
static volatile sig_atomic_t alarm_rised; |
||||
static volatile sig_atomic_t sigchild; |
||||
@@ -81,7 +84,12 @@ static volatile sig_atomic_t sigchild; |
||||
# define IUCLC 0 |
||||
#endif |
||||
|
||||
-static int locked_account_password(const char *passwd) |
||||
+#ifndef WEXITED |
||||
+# warning "WEXITED is missing, sulogin may not work as expected" |
||||
+# define WEXITED 0 |
||||
+#endif |
||||
+ |
||||
+static int locked_account_password(const char * const passwd) |
||||
{ |
||||
if (passwd && (*passwd == '*' || *passwd == '!')) |
||||
return 1; |
||||
@@ -93,10 +101,29 @@ static int locked_account_password(const char *passwd) |
||||
*/ |
||||
static void tcinit(struct console *con) |
||||
{ |
||||
- int mode = 0, flags = 0; |
||||
+ int flags = 0, mode = 0; |
||||
struct termios *tio = &con->tio; |
||||
- int fd = con->fd; |
||||
- |
||||
+ const int fd = con->fd; |
||||
+#ifdef USE_PLYMOUTH_SUPPORT |
||||
+ struct termios lock; |
||||
+ int i = (plymouth_command(MAGIC_PING)) ? PLYMOUTH_TERMIOS_FLAGS_DELAY : 0; |
||||
+ if (i) |
||||
+ plymouth_command(MAGIC_QUIT); |
||||
+ while (i-- > 0) { |
||||
+ /* |
||||
+ * With plymouth the termios flags become changed after this |
||||
+ * function had changed the termios. |
||||
+ */ |
||||
+ memset(&lock, 0, sizeof(struct termios)); |
||||
+ if (ioctl(fd, TIOCGLCKTRMIOS, &lock) < 0) |
||||
+ break; |
||||
+ if (!lock.c_iflag && !lock.c_oflag && !lock.c_cflag && !lock.c_lflag) |
||||
+ break; |
||||
+ sleep(1); |
||||
+ } |
||||
+ memset(&lock, 0, sizeof(struct termios)); |
||||
+ ioctl(fd, TIOCSLCKTRMIOS, &lock); |
||||
+#endif |
||||
errno = 0; |
||||
|
||||
if (tcgetattr(fd, tio) < 0) { |
||||
@@ -189,20 +216,23 @@ setattr: |
||||
*/ |
||||
static void tcfinal(struct console *con) |
||||
{ |
||||
- struct termios *tio; |
||||
- int fd; |
||||
+ struct termios *tio = &con->tio; |
||||
+ const int fd = con->fd; |
||||
|
||||
if ((con->flags & CON_SERIAL) == 0) { |
||||
- setenv("TERM", "linux", 1); |
||||
+ xsetenv("TERM", "linux", 1); |
||||
return; |
||||
} |
||||
- if (con->flags & CON_NOTTY) |
||||
+ if (con->flags & CON_NOTTY) { |
||||
+ xsetenv("TERM", "dumb", 1); |
||||
return; |
||||
+ } |
||||
|
||||
- setenv("TERM", "vt102", 1); |
||||
- tio = &con->tio; |
||||
- fd = con->fd; |
||||
- |
||||
+#if defined (__s390__) || defined (__s390x__) |
||||
+ xsetenv("TERM", "dumb", 1); |
||||
+#else |
||||
+ xsetenv("TERM", "vt102", 1); |
||||
+#endif |
||||
tio->c_iflag |= (IXON | IXOFF); |
||||
tio->c_lflag |= (ICANON | ISIG | ECHO|ECHOE|ECHOK|ECHOKE); |
||||
tio->c_oflag |= OPOST; |
||||
@@ -237,11 +267,11 @@ static void tcfinal(struct console *con) |
||||
break; |
||||
case 1: /* odd parity */ |
||||
tio->c_cflag |= PARODD; |
||||
- /* fall through */ |
||||
+ /* fallthrough */ |
||||
case 2: /* even parity */ |
||||
tio->c_cflag |= PARENB; |
||||
tio->c_iflag |= (INPCK | ISTRIP); |
||||
- /* fall through */ |
||||
+ /* fallthrough */ |
||||
case (1 | 2): /* no parity bit */ |
||||
tio->c_cflag &= ~CSIZE; |
||||
tio->c_cflag |= CS7; |
||||
@@ -466,7 +496,7 @@ static struct passwd *getrootpwent(int try_manually) |
||||
warnx(_("%s: no entry for root"), _PATH_SHADOW_PASSWD); |
||||
*pwd.pw_passwd = '\0'; |
||||
} |
||||
- /* locked accont passwords are valid too */ |
||||
+ /* locked account passwords are valid too */ |
||||
if (!locked_account_password(pwd.pw_passwd) && !valid(pwd.pw_passwd)) { |
||||
warnx(_("%s: root password garbled"), _PATH_SHADOW_PASSWD); |
||||
*pwd.pw_passwd = '\0'; |
||||
@@ -524,22 +554,17 @@ err: |
||||
*/ |
||||
static void setup(struct console *con) |
||||
{ |
||||
- pid_t pid, pgrp, ppgrp, ttypgrp; |
||||
- int fd; |
||||
+ int fd = con->fd; |
||||
+ const pid_t pid = getpid(), pgrp = getpgid(0), ppgrp = |
||||
+ getpgid(getppid()), ttypgrp = tcgetpgrp(fd); |
||||
|
||||
if (con->flags & CON_NOTTY) |
||||
return; |
||||
- fd = con->fd; |
||||
|
||||
/* |
||||
* Only go through this trouble if the new |
||||
* tty doesn't fall in this process group. |
||||
*/ |
||||
- pid = getpid(); |
||||
- pgrp = getpgid(0); |
||||
- ppgrp = getpgid(getppid()); |
||||
- ttypgrp = tcgetpgrp(fd); |
||||
- |
||||
if (pgrp != ttypgrp && ppgrp != ttypgrp) { |
||||
if (pid != getsid(0)) { |
||||
if (pid == getpgid(0)) |
||||
@@ -575,21 +600,20 @@ static void setup(struct console *con) |
||||
* Ask for the password. Note that there is no default timeout as we normally |
||||
* skip this during boot. |
||||
*/ |
||||
-static char *getpasswd(struct console *con) |
||||
+static const char *getpasswd(struct console *con) |
||||
{ |
||||
struct sigaction sa; |
||||
struct termios tty; |
||||
static char pass[128], *ptr; |
||||
struct chardata *cp; |
||||
- char *ret = pass; |
||||
+ const char *ret = pass; |
||||
unsigned char tc; |
||||
char c, ascval; |
||||
int eightbit; |
||||
- int fd; |
||||
+ const int fd = con->fd; |
||||
|
||||
if (con->flags & CON_NOTTY) |
||||
goto out; |
||||
- fd = con->fd; |
||||
cp = &con->cp; |
||||
tty = con->tio; |
||||
|
||||
@@ -597,6 +621,7 @@ static char *getpasswd(struct console *con) |
||||
tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|ISIG); |
||||
tc = (tcsetattr(fd, TCSAFLUSH, &tty) == 0); |
||||
|
||||
+ sigemptyset(&sa.sa_mask); |
||||
sa.sa_handler = alrm_handler; |
||||
sa.sa_flags = 0; |
||||
sigaction(SIGALRM, &sa, NULL); |
||||
@@ -615,7 +640,7 @@ static char *getpasswd(struct console *con) |
||||
ret = NULL; |
||||
goto quit; |
||||
} |
||||
- usleep(1000); |
||||
+ usleep(250000); |
||||
continue; |
||||
} |
||||
ret = (char*)0; |
||||
@@ -627,7 +652,7 @@ static char *getpasswd(struct console *con) |
||||
case ENOENT: |
||||
break; |
||||
default: |
||||
- warn(_("%s: read failed"), con->tty); |
||||
+ warn(_("cannot read %s"), con->tty); |
||||
break; |
||||
} |
||||
goto quit; |
||||
@@ -694,8 +719,8 @@ static void sushell(struct passwd *pwd) |
||||
{ |
||||
char shell[PATH_MAX]; |
||||
char home[PATH_MAX]; |
||||
- char *p; |
||||
- char *su_shell; |
||||
+ char const *p; |
||||
+ char const *su_shell; |
||||
|
||||
/* |
||||
* Set directory and shell. |
||||
@@ -731,16 +756,16 @@ static void sushell(struct passwd *pwd) |
||||
if (getcwd(home, sizeof(home)) == NULL) |
||||
strcpy(home, "/"); |
||||
|
||||
- setenv("HOME", home, 1); |
||||
- setenv("LOGNAME", "root", 1); |
||||
- setenv("USER", "root", 1); |
||||
+ xsetenv("HOME", home, 1); |
||||
+ xsetenv("LOGNAME", "root", 1); |
||||
+ xsetenv("USER", "root", 1); |
||||
if (!profile) |
||||
- setenv("SHLVL","0",1); |
||||
+ xsetenv("SHLVL","0",1); |
||||
|
||||
/* |
||||
* Try to execute a shell. |
||||
*/ |
||||
- setenv("SHELL", su_shell, 1); |
||||
+ xsetenv("SHELL", su_shell, 1); |
||||
unmask_signal(SIGINT, &saved_sigint); |
||||
unmask_signal(SIGTSTP, &saved_sigtstp); |
||||
unmask_signal(SIGQUIT, &saved_sigquit); |
||||
@@ -765,17 +790,21 @@ static void sushell(struct passwd *pwd) |
||||
execl(su_shell, shell, NULL); |
||||
warn(_("failed to execute %s"), su_shell); |
||||
|
||||
- setenv("SHELL", "/bin/sh", 1); |
||||
+ xsetenv("SHELL", "/bin/sh", 1); |
||||
execl("/bin/sh", profile ? "-sh" : "sh", NULL); |
||||
warn(_("failed to execute %s"), "/bin/sh"); |
||||
} |
||||
|
||||
-static void usage(FILE *out) |
||||
+static void usage(void) |
||||
{ |
||||
+ FILE *out = stdout; |
||||
fputs(USAGE_HEADER, out); |
||||
fprintf(out, _( |
||||
" %s [options] [tty device]\n"), program_invocation_short_name); |
||||
|
||||
+ fputs(USAGE_SEPARATOR, out); |
||||
+ fputs(_("Single-user login.\n"), out); |
||||
+ |
||||
fputs(USAGE_OPTIONS, out); |
||||
fputs(_(" -p, --login-shell start a login shell\n" |
||||
" -t, --timeout <seconds> max time to wait for a password (default: no limit)\n" |
||||
@@ -783,32 +812,35 @@ static void usage(FILE *out) |
||||
out); |
||||
|
||||
fputs(USAGE_SEPARATOR, out); |
||||
- fputs(USAGE_HELP, out); |
||||
- fputs(USAGE_VERSION, out); |
||||
- fprintf(out, USAGE_MAN_TAIL("sulogin(8)")); |
||||
+ printf(USAGE_HELP_OPTIONS(26)); |
||||
+ printf(USAGE_MAN_TAIL("sulogin(8)")); |
||||
} |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
- LIST_HEAD(consoles); |
||||
- struct list_head *ptr; |
||||
+ struct list_head *ptr, consoles; |
||||
struct console *con; |
||||
char *tty = NULL; |
||||
struct passwd *pwd; |
||||
- int c, status = 0; |
||||
- int reconnect = 0; |
||||
+ const struct timespec sigwait = { .tv_sec = 0, .tv_nsec = 50000000 }; |
||||
+ siginfo_t status = { 0 }; |
||||
+ sigset_t set; |
||||
+ int c, reconnect = 0; |
||||
int opt_e = 0; |
||||
+ int wait = 0; |
||||
pid_t pid; |
||||
|
||||
static const struct option longopts[] = { |
||||
- { "login-shell", 0, 0, 'p' }, |
||||
- { "timeout", 1, 0, 't' }, |
||||
- { "force", 0, 0, 'e' }, |
||||
- { "help", 0, 0, 'h' }, |
||||
- { "version", 0, 0, 'V' }, |
||||
- { NULL, 0, 0, 0 } |
||||
+ { "login-shell", no_argument, NULL, 'p' }, |
||||
+ { "timeout", required_argument, NULL, 't' }, |
||||
+ { "force", no_argument, NULL, 'e' }, |
||||
+ { "help", no_argument, NULL, 'h' }, |
||||
+ { "version", no_argument, NULL, 'V' }, |
||||
+ { NULL, 0, NULL, 0 } |
||||
}; |
||||
|
||||
+ INIT_LIST_HEAD(&consoles); |
||||
+ |
||||
/* |
||||
* If we are init we need to set up a own session. |
||||
*/ |
||||
@@ -840,17 +872,16 @@ int main(int argc, char **argv) |
||||
printf(UTIL_LINUX_VERSION); |
||||
return EXIT_SUCCESS; |
||||
case 'h': |
||||
- usage(stdout); |
||||
+ usage(); |
||||
return EXIT_SUCCESS; |
||||
default: |
||||
- usage(stderr); |
||||
- /* Do not exit! */ |
||||
+ /* Do not exit! getopt prints a warning. */ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (geteuid() != 0) |
||||
- errx(EXIT_FAILURE, _("only root can run this program.")); |
||||
+ errx(EXIT_FAILURE, _("only superuser can run this program")); |
||||
|
||||
mask_signal(SIGQUIT, SIG_IGN, &saved_sigquit); |
||||
mask_signal(SIGTSTP, SIG_IGN, &saved_sigtstp); |
||||
@@ -877,7 +908,7 @@ int main(int argc, char **argv) |
||||
reconnect = detect_consoles(tty, STDIN_FILENO, &consoles); |
||||
|
||||
/* |
||||
- * If previous stdin was not the speified tty and therefore reconnected |
||||
+ * If previous stdin was not the specified tty and therefore reconnected |
||||
* to the specified tty also reconnect stdout and stderr. |
||||
*/ |
||||
if (reconnect) { |
||||
@@ -900,7 +931,7 @@ int main(int argc, char **argv) |
||||
* Get the root password. |
||||
*/ |
||||
if ((pwd = getrootpwent(opt_e)) == NULL) { |
||||
- warnx(_("cannot open password database.")); |
||||
+ warnx(_("cannot open password database")); |
||||
sleep(2); |
||||
return EXIT_FAILURE; |
||||
} |
||||
@@ -923,9 +954,6 @@ int main(int argc, char **argv) |
||||
tcinit(con); |
||||
} |
||||
ptr = (&consoles)->next; |
||||
- usemask = (uint32_t*) mmap(NULL, sizeof(uint32_t), |
||||
- PROT_READ|PROT_WRITE, |
||||
- MAP_ANONYMOUS|MAP_SHARED, -1, 0); |
||||
|
||||
if (ptr->next == &consoles) { |
||||
con = list_entry(ptr, struct console, entry); |
||||
@@ -942,7 +970,6 @@ int main(int argc, char **argv) |
||||
switch ((con->pid = fork())) { |
||||
case 0: |
||||
mask_signal(SIGCHLD, SIG_DFL, NULL); |
||||
- /* fall through */ |
||||
nofork: |
||||
setup(con); |
||||
while (1) { |
||||
@@ -971,9 +998,7 @@ int main(int argc, char **argv) |
||||
} |
||||
|
||||
if (doshell) { |
||||
- *usemask |= (1<<con->id); |
||||
sushell(pwd); |
||||
- *usemask &= ~(1<<con->id); |
||||
failed++; |
||||
} |
||||
|
||||
@@ -982,7 +1007,7 @@ int main(int argc, char **argv) |
||||
mask_signal(SIGINT, SIG_IGN, &saved_sigint); |
||||
|
||||
if (failed) { |
||||
- fprintf(stderr, _("Can not execute su shell\n\n")); |
||||
+ fprintf(stderr, _("cannot execute su shell\n\n")); |
||||
break; |
||||
} |
||||
fprintf(stderr, _("Login incorrect\n\n")); |
||||
@@ -997,7 +1022,7 @@ int main(int argc, char **argv) |
||||
exit(0); |
||||
case -1: |
||||
warn(_("fork failed")); |
||||
- /* fall through */ |
||||
+ /* fallthrough */ |
||||
default: |
||||
break; |
||||
} |
||||
@@ -1006,28 +1031,80 @@ int main(int argc, char **argv) |
||||
|
||||
} while (ptr != &consoles); |
||||
|
||||
- while ((pid = wait(&status))) { |
||||
- if (errno == ECHILD) |
||||
+ do { |
||||
+ int ret; |
||||
+ |
||||
+ status.si_pid = 0; |
||||
+ ret = waitid(P_ALL, 0, &status, WEXITED); |
||||
+ |
||||
+ if (ret == 0) |
||||
break; |
||||
- if (pid < 0) |
||||
- continue; |
||||
- list_for_each(ptr, &consoles) { |
||||
- con = list_entry(ptr, struct console, entry); |
||||
- if (con->pid == pid) { |
||||
- *usemask &= ~(1<<con->id); |
||||
+ if (ret < 0) { |
||||
+ if (errno == ECHILD) |
||||
+ break; |
||||
+ if (errno == EINTR) |
||||
continue; |
||||
- } |
||||
- if (kill(con->pid, 0) < 0) { |
||||
- *usemask &= ~(1<<con->id); |
||||
+ } |
||||
+ |
||||
+ errx(EXIT_FAILURE, _("cannot wait on su shell\n\n")); |
||||
+ |
||||
+ } while (1); |
||||
+ |
||||
+ list_for_each(ptr, &consoles) { |
||||
+ con = list_entry(ptr, struct console, entry); |
||||
+ |
||||
+ if (con->fd < 0) |
||||
+ continue; |
||||
+ if (con->pid < 0) |
||||
+ continue; |
||||
+ if (con->pid == status.si_pid) |
||||
+ con->pid = -1; |
||||
+ else { |
||||
+ kill(con->pid, SIGTERM); |
||||
+ wait++; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ sigemptyset(&set); |
||||
+ sigaddset(&set, SIGCHLD); |
||||
+ |
||||
+ do { |
||||
+ int signum, ret; |
||||
+ |
||||
+ if (!wait) |
||||
+ break; |
||||
+ |
||||
+ status.si_pid = 0; |
||||
+ ret = waitid(P_ALL, 0, &status, WEXITED|WNOHANG); |
||||
+ |
||||
+ if (ret < 0) { |
||||
+ if (errno == ECHILD) |
||||
+ break; |
||||
+ if (errno == EINTR) |
||||
continue; |
||||
+ } |
||||
+ |
||||
+ if (!ret && status.si_pid > 0) { |
||||
+ list_for_each(ptr, &consoles) { |
||||
+ con = list_entry(ptr, struct console, entry); |
||||
+ |
||||
+ if (con->fd < 0) |
||||
+ continue; |
||||
+ if (con->pid < 0) |
||||
+ continue; |
||||
+ if (con->pid == status.si_pid) { |
||||
+ con->pid = -1; |
||||
+ wait--; |
||||
+ } |
||||
} |
||||
- if (*usemask & (1<<con->id)) |
||||
- continue; |
||||
- kill(con->pid, SIGHUP); |
||||
- usleep(5000); |
||||
- kill(con->pid, SIGKILL); |
||||
+ continue; |
||||
} |
||||
- } |
||||
+ |
||||
+ signum = sigtimedwait(&set, NULL, &sigwait); |
||||
+ if (signum != SIGCHLD && signum < 0 && errno == EAGAIN) |
||||
+ break; |
||||
+ |
||||
+ } while (1); |
||||
|
||||
mask_signal(SIGCHLD, SIG_DFL, NULL); |
||||
return EXIT_SUCCESS; |
||||
-- |
||||
2.14.4 |
||||
|
Loading…
Reference in new issue