summaryrefslogtreecommitdiffstats
path: root/libmount/src/tab_parse.c
diff options
context:
space:
mode:
authorMasatake YAMATO2012-01-19 05:16:20 +0100
committerKarel Zak2012-01-23 13:52:51 +0100
commit485a8bfa98f8d89855b7ae0305e6698048c6f050 (patch)
tree6a9de8182079005637183a8fecbfd44879da5ca5 /libmount/src/tab_parse.c
parentmount: add info about libmount features to --version output (diff)
downloadkernel-qcow2-util-linux-485a8bfa98f8d89855b7ae0305e6698048c6f050.tar.gz
kernel-qcow2-util-linux-485a8bfa98f8d89855b7ae0305e6698048c6f050.tar.xz
kernel-qcow2-util-linux-485a8bfa98f8d89855b7ae0305e6698048c6f050.zip
libmount: scandirat based mnt_table_parse_dir implementation
In comment of `mnt_table_parse_dir' of libmount/src/tab_parse.c: /* TODO: it would be nice to have a scandir() implementation that * is able to use already opened directory */ Nowadays glibc provides `scandirat'. This patch implements `scandirat' based `mnt_table_parse_dir'. Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Diffstat (limited to 'libmount/src/tab_parse.c')
-rw-r--r--libmount/src/tab_parse.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c
index 6cd66afeb..1b0324ef4 100644
--- a/libmount/src/tab_parse.c
+++ b/libmount/src/tab_parse.c
@@ -5,6 +5,12 @@
* GNU Lesser General Public License.
*/
+#ifdef HAVE_SCANDIRAT
+#ifndef __USE_GNU
+#define __USE_GNU
+#endif /* !__USE_GNU */
+#endif /* HAVE_SCANDIRAT */
+
#include <ctype.h>
#include <limits.h>
#include <dirent.h>
@@ -429,14 +435,68 @@ int mnt_table_parse_file(struct libmnt_table *tb, const char *filename)
return rc;
}
+#ifdef HAVE_SCANDIRAT
+static int mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
+{
+ int n = 0, i;
+ int dd;
+ struct dirent **namelist = NULL;
+
+ dd = open(dirname, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
+ if (dd < 0)
+ return -errno;
+ n = scandirat(dd, ".", &namelist, NULL, versionsort);
+ if (n <= 0) {
+ close(dd);
+ return 0;
+ }
+
+ for (i = 0; i < n; i++) {
+ struct dirent *d = namelist[i];
+ struct stat st;
+ size_t namesz;
+ FILE *f;
+
+#ifdef _DIRENT_HAVE_D_TYPE
+ if (d->d_type != DT_UNKNOWN && d->d_type != DT_REG &&
+ d->d_type != DT_LNK)
+ continue;
+#endif
+ if (*d->d_name == '.')
+ continue;
+
+#define MNT_MNTTABDIR_EXTSIZ (sizeof(MNT_MNTTABDIR_EXT) - 1)
+
+ namesz = strlen(d->d_name);
+ if (!namesz || namesz < MNT_MNTTABDIR_EXTSIZ + 1 ||
+ strcmp(d->d_name + (namesz - MNT_MNTTABDIR_EXTSIZ),
+ MNT_MNTTABDIR_EXT))
+ continue;
+
+ if (fstat_at(dd, ".", d->d_name, &st, 0) ||
+ !S_ISREG(st.st_mode))
+ continue;
+
+ f = fopen_at(dd, ".", d->d_name, O_RDONLY, "r");
+ if (f) {
+ mnt_table_parse_stream(tb, f, d->d_name);
+ fclose(f);
+ }
+ }
+
+ for (i = 0; i < n; i++)
+ free(namelist[i]);
+ free(namelist);
+ close(dd);
+ return 0;
+}
+#else
static int mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
{
int n = 0, i;
DIR *dir = NULL;
struct dirent **namelist = NULL;
- /* TODO: it would be nice to have a scandir() implementation that
- * is able to use already opened directory */
n = scandir(dirname, &namelist, NULL, versionsort);
if (n <= 0)
return 0;
@@ -487,6 +547,7 @@ static int mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
closedir(dir);
return 0;
}
+#endif
struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt)
{