From fcd192014c8bbc0466bcdd4195b3d14c0ce006f9 Mon Sep 17 00:00:00 2001
From: Adam Borowski
Date: Fri, 29 Jul 2016 19:50:20 +0200
Subject: [PATCH 1/8] Instead of deleting ignored items immediately, mark them
up.
This allows filters that look at other items.
---
src/dfc.c | 18 +++++++++++++-----
src/list.h | 1 +
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/dfc.c b/src/dfc.c
index c15c05a..2fd91e0 100644
--- a/src/dfc.c
+++ b/src/dfc.c
@@ -535,28 +535,36 @@ disp(struct list *lst, const char *fstfilter, const char *fsnfilter,
if (qflag)
lst->head = msort(lst->head);
- p = lst->head;
+ for (p = lst->head; p; p = p->next) {
+ /* ignored unless proven otherwise */
+ p->ignored = 1;
- while (p != NULL) {
/* ignore when needed */
if (!aflag && (is_mnt_ignore(p) == 1)) {
- p = delete_struct_and_get_next(p);
continue;
}
/* filtering on fs type */
if (tflag && (fsfilter(p->fstype, fstfilter, nmt) == 0)) {
- p = delete_struct_and_get_next(p);
continue;
}
/* filtering on fs name */
if (pflag && (fsfilter(p->fsname, fsnfilter, nmn) == 0)) {
- p = delete_struct_and_get_next(p);
continue;
}
/* skip remote file systems */
if (lflag && is_remote(p)) {
+ continue;
+ }
+
+ p->ignored = 0;
+ }
+
+ p = lst->head;
+
+ while (p != NULL) {
+ if (p->ignored) {
p = delete_struct_and_get_next(p);
continue;
}
diff --git a/src/list.h b/src/list.h
index ece1677..c1a870e 100644
--- a/src/list.h
+++ b/src/list.h
@@ -133,6 +133,7 @@ struct fsmntinfo {
fsfilcnt_t favail; /* # of available inodes */
#endif /* __sun */
+ int ignored;
/* pointer to the next element of the list */
struct fsmntinfo *next;
};
From e92b8305a457c458850f83aba69bd64c2a70783a Mon Sep 17 00:00:00 2001
From: Adam Borowski
Date: Fri, 29 Jul 2016 20:12:00 +0200
Subject: [PATCH 2/8] Show every filesystem only once, unless -a is given.
They were listed multiple times when bind mounts or btrfs/zfs subvolumes
are in use. And in those cases, a single filesystem is often mounted many,
many times.
Filesystems whose backing store is not an absolute path are assumed to be
unique. This is not always correct (they can be bind-mounted).
In case of duplicates, the mount with a shorter path is considered more
important.
---
src/dfc.c | 24 ++++++++++++++++++++++++
src/util.c | 17 +++++++++++++++++
src/util.h | 1 +
3 files changed, 42 insertions(+)
diff --git a/src/dfc.c b/src/dfc.c
index 2fd91e0..0768575 100644
--- a/src/dfc.c
+++ b/src/dfc.c
@@ -561,6 +561,30 @@ disp(struct list *lst, const char *fstfilter, const char *fsnfilter,
p->ignored = 0;
}
+ for (p = lst->head; p; p = p->next) {
+ if (aflag || p->ignored)
+ continue;
+
+ /* doesn't have a device backing store? */
+ if (p->fsname[0] != '/')
+ continue;
+
+ struct fsmntinfo *r;
+ for (r = lst->head; r; r = r->next) {
+ if (p != r && !r->ignored && !strcmp(p->fsname, r->fsname))
+ switch (lencmp(p, r))
+ {
+ case -1:
+ default:
+ /* mounted twice on same dir? */
+ r->ignored = 1;
+ break;
+ case 1:
+ p->ignored = 1;
+ }
+ }
+ }
+
p = lst->head;
while (p != NULL) {
diff --git a/src/util.c b/src/util.c
index 6f1f690..f119176 100644
--- a/src/util.c
+++ b/src/util.c
@@ -477,6 +477,23 @@ msort(struct fsmntinfo *fmi)
return fmi;
}
+/*
+ * Compare lengths of mount points, then their paths.
+ * -1,0,1 are returned as in *cmp.
+ */
+int
+lencmp(struct fsmntinfo *a, struct fsmntinfo *b)
+{
+ size_t la = strlen(a->mntdir);
+ size_t lb = strlen(b->mntdir);
+
+ if (la < lb)
+ return -1;
+ if (la > lb)
+ return 1;
+ return strcmp(a->mntdir, b->mntdir);
+}
+
/*
* Get the with of TTY and retun it.
* 0 is returned if stdout is not a tty.
diff --git a/src/util.h b/src/util.h
index e90d25b..d71f17c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -54,6 +54,7 @@ double cvrt(double n);
int fsfilter(const char *fs, const char *filter, int nm);
int cmp(struct fsmntinfo *a, struct fsmntinfo *b);
struct fsmntinfo * msort(struct fsmntinfo *fmi);
+int lencmp(struct fsmntinfo *a, struct fsmntinfo *b);
int getttywidth(void);
void init_maxwidths(void);
int get_req_width(double fs_size);
From 50eb2eca8ee4458b04337784d9930b815ac67992 Mon Sep 17 00:00:00 2001
From: Adam Borowski
Date: Fri, 29 Jul 2016 20:40:59 +0200
Subject: [PATCH 3/8] Hide /run mounts unless they're more than half full,
unless -a is given.
On modern Debian-based systems there's usually 3 of them, on Fedora 23 4.
I'm not sure what's the good place to put this code in, as you prefer to
separate logic from presentation. It doesn't fit into is_mnt_ignore() as
it's used by some distributions at least on linux, freebsd and hurd and
that function is platform-specific.
---
src/dfc.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/dfc.c b/src/dfc.c
index 0768575..c54810f 100644
--- a/src/dfc.c
+++ b/src/dfc.c
@@ -544,6 +544,11 @@ disp(struct list *lst, const char *fstfilter, const char *fsnfilter,
continue;
}
+ /* ignore /run mounts unless they're dangerously full */
+ if (!aflag && !strncmp(p->mntdir, "/run", 4) && p->perctused < 50) {
+ continue;
+ }
+
/* filtering on fs type */
if (tflag && (fsfilter(p->fstype, fstfilter, nmt) == 0)) {
continue;
From fc71744aedb5ea171b230b73725802a54965b609 Mon Sep 17 00:00:00 2001
From: Adam Borowski
Date: Fri, 29 Jul 2016 20:55:49 +0200
Subject: [PATCH 4/8] Fix the tty width check looking at filesystems ignored by
-t, -p or -l.
It obeyed only is_mnt_ignore().
---
src/dfc.c | 31 ++++++++++++++++++-------------
src/platform/services-bsd.c | 2 --
src/platform/services-linux.c | 2 --
src/platform/services-solaris.c | 2 --
4 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/src/dfc.c b/src/dfc.c
index c54810f..dff3e0c 100644
--- a/src/dfc.c
+++ b/src/dfc.c
@@ -55,6 +55,7 @@ struct maxwidths max;
int aflag, bflag, cflag, dflag, eflag, fflag, hflag, iflag, lflag, mflag,
nflag, oflag, pflag, qflag, sflag, tflag, uflag, vflag, wflag;
int Mflag, Tflag, Wflag;
+int tty_width;
char unitflag;
int
@@ -63,7 +64,6 @@ main(int argc, char *argv[])
struct list queue;
struct display sdisp;
int ch;
- int tty_width;
int ret = EXIT_SUCCESS;
char *fsnfilter = NULL;
char *fstfilter = NULL;
@@ -419,10 +419,6 @@ main(int argc, char *argv[])
/* fetch information about the currently mounted filesystems */
fetch_info(&queue);
- /* cannot display all information if tty is too narrow */
- if (!fflag && tty_width > 0 && !eflag)
- auto_adjust(tty_width);
-
/* actually displays the info we have got */
disp(&queue, fstfilter, fsnfilter, &sdisp);
@@ -523,14 +519,6 @@ disp(struct list *lst, const char *fstfilter, const char *fsnfilter,
}
}
- /* only required for html, json and tex export */
- if (sdisp->init)
- sdisp->init();
-
- /* legend on top */
- if (!nflag)
- sdisp->print_header();
-
/* sort the list */
if (qflag)
lst->head = msort(lst->head);
@@ -590,6 +578,23 @@ disp(struct list *lst, const char *fstfilter, const char *fsnfilter,
}
}
+ for (p = lst->head; p; p = p->next) {
+ if (!p->ignored)
+ update_maxwidth(p);
+ }
+
+ /* cannot display all information if tty is too narrow */
+ if (!fflag && tty_width > 0 && !eflag)
+ auto_adjust(tty_width);
+
+ /* only required for html, json and tex export */
+ if (sdisp->init)
+ sdisp->init();
+
+ /* legend on top */
+ if (!nflag)
+ sdisp->print_header();
+
p = lst->head;
while (p != NULL) {
diff --git a/src/platform/services-bsd.c b/src/platform/services-bsd.c
index 6cef0c0..6081956 100644
--- a/src/platform/services-bsd.c
+++ b/src/platform/services-bsd.c
@@ -165,8 +165,6 @@ fetch_info(struct list *lst)
/* enqueue the element into the queue */
enqueue(lst, *fmi);
-
- update_maxwidth(fmi);
}
free(fmi);
}
diff --git a/src/platform/services-linux.c b/src/platform/services-linux.c
index 1a4a492..99683dd 100644
--- a/src/platform/services-linux.c
+++ b/src/platform/services-linux.c
@@ -152,8 +152,6 @@ fetch_info(struct list *lst)
/* enqueue the element into the queue */
enqueue(lst, *fmi);
-
- update_maxwidth(fmi);
}
/* we need to close the mtab file now */
if (fclose(mtab) == EOF)
diff --git a/src/platform/services-solaris.c b/src/platform/services-solaris.c
index 25e39e5..cab79b2 100644
--- a/src/platform/services-solaris.c
+++ b/src/platform/services-solaris.c
@@ -148,8 +148,6 @@ fetch_info(struct list *lst)
fmi->next = NULL;
enqueue(lst, *fmi);
-
- update_maxwidth(fmi);
}
if (ret > 0) {
(void)fprintf(stderr, "An error occured while reading the "
From aa44e723484a3cecaf71683eec9429b45879f47d Mon Sep 17 00:00:00 2001
From: Adam Borowski
Date: Fri, 29 Jul 2016 21:06:17 +0200
Subject: [PATCH 5/8] Silently ignore EACCESS on statvfs().
So does regular df.
---
src/platform/services-linux.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/platform/services-linux.c b/src/platform/services-linux.c
index 99683dd..7ec4e23 100644
--- a/src/platform/services-linux.c
+++ b/src/platform/services-linux.c
@@ -48,6 +48,7 @@
#include
#include
+#include
#include "extern.h"
#include "services.h"
@@ -101,6 +102,9 @@ fetch_info(struct list *lst)
continue;
/* get infos from statvfs */
if (statvfs(entbuf->mnt_dir, &vfsbuf) == -1) {
+ /* show only "real" errors, not lack of permissions */
+ if (errno == EACCES)
+ continue;
/* display a warning when a FS cannot be stated */
(void)fprintf(stderr, _("WARNING: %s was skipped "
"because it could not be stated"),
From 40722239080e6c7362c62878c43c3a79cd4eeaf9 Mon Sep 17 00:00:00 2001
From: Adam Borowski
Date: Fri, 29 Jul 2016 21:33:45 +0200
Subject: [PATCH 6/8] Fix build failure on Hurd.
This reuses the "linux" platform, as everything you use there is
glibc rather than linux specific.
---
CMakeLists.txt | 2 ++
src/dfc.c | 2 +-
src/list.h | 2 +-
src/platform/services-linux.c | 3 ++-
4 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7169940..a89f107 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,6 +34,8 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
set(BSD true)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
set(SOLARIS true)
+elseif(${CMAKE_SYSTEM_NAME} MATCHES "GNU")
+ set(LINUX true)
else()
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif()
diff --git a/src/dfc.c b/src/dfc.c
index dff3e0c..96d978e 100644
--- a/src/dfc.c
+++ b/src/dfc.c
@@ -641,7 +641,7 @@ disp(struct list *lst, const char *fstfilter, const char *fsnfilter,
if (iflag) {
ifitot += (double)p->files;
ifatot += (double)p->favail;
-#if defined(__linux__)
+#if defined(__linux__) || defined(__GLIBC__)
sdisp->print_inodes((uint64_t)(p->files),
(uint64_t)(p->favail));
#else
diff --git a/src/list.h b/src/list.h
index c1a870e..74a645b 100644
--- a/src/list.h
+++ b/src/list.h
@@ -55,7 +55,7 @@ struct fsmntinfo {
double used; /* fs used size */
/* infos to get from statvfs(3) */
-#if defined(__linux__)
+#if defined(__linux__) || defined(__GLIBC__)
int flags; /* XXX: does not exist on Linux */
unsigned long bsize; /* file system block size */
unsigned long frsize; /* fragment size */
diff --git a/src/platform/services-linux.c b/src/platform/services-linux.c
index 7ec4e23..292da99 100644
--- a/src/platform/services-linux.c
+++ b/src/platform/services-linux.c
@@ -34,13 +34,14 @@
*
* Linux implemention of services.
*/
-#ifdef __linux__
#include
#include
#include
#include
+#if defined(__linux__) || defined(__GLIBC__)
+
#ifdef NLS_ENABLED
#include
#include
From 3f0e559de5e6547844455b443f5d530178e92f85 Mon Sep 17 00:00:00 2001
From: Adam Borowski
Date: Sat, 30 Jul 2016 00:50:12 +0200
Subject: [PATCH 7/8] Fix build failure on kFreeBSD.
Like Hurd, this uses "linux" despite the real platform being FreeBSD, as
it's libc that matters.
---
CMakeLists.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a89f107..3924ece 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,6 +24,8 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(BSD true)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly")
set(BSD true)
+elseif(${CMAKE_SYSTEM_NAME} MATCHES "kFreeBSD")
+ set(LINUX true)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(BSD true)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
From 7b1af231b970adc7f7945f8b8d9d648e41e856d5 Mon Sep 17 00:00:00 2001
From: Adam Borowski
Date: Sat, 30 Jul 2016 00:53:53 +0200
Subject: [PATCH 8/8] Include linprocfs and fdescfs among pseudo filesystems.
A kfreebsd, and I guess sometimes real FreeBSD, thingy.
---
src/util.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/util.c b/src/util.c
index f119176..8081299 100644
--- a/src/util.c
+++ b/src/util.c
@@ -824,9 +824,11 @@ is_pseudofs(const char *type)
"devpts",
"devtmpfs",
"dlmfs",
+ "fdescfs",
"fuse.gvfs-fuse-daemon",
"fusectl",
"hugetlbfs",
+ "linprocfs",
"mqueue",
"nfsd",
"none",