From a916ae72b89d0bcb5fe28d55def7327e8a1f6ce0 Mon Sep 17 00:00:00 2001 From: Ruben Kerkhof Date: Sat, 25 Jul 2015 15:21:52 +0200 Subject: [PATCH] utils_mount: use reentrant getmntent_r when we can Fixes #1162 --- configure.ac | 7 +++++++ src/utils_mount.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/configure.ac b/configure.ac index 6ee6e9a5..6a664e67 100644 --- a/configure.ac +++ b/configure.ac @@ -1244,6 +1244,8 @@ have_getvfsstat="no" AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"]) have_listmntent="no" AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"]) +have_getmntent_r="no" +AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"]) have_getmntent="no" AC_CHECK_FUNCS(getmntent, [have_getmntent="c"]) @@ -5501,6 +5503,11 @@ then plugin_df="yes" fi +if test "x$c_cv_have_getmntent_r" = "xyes" +then + plugin_df="yes" +fi + # Df plugin: Check if we have either `statfs' or `statvfs' second. if test "x$plugin_df" = "xyes" then diff --git a/src/utils_mount.c b/src/utils_mount.c index b63a81ad..afeb39e1 100644 --- a/src/utils_mount.c +++ b/src/utils_mount.c @@ -571,6 +571,64 @@ static cu_mount_t *cu_mount_gen_getmntent (void) #warn "This version of `getmntent' hat not yet been implemented!" /* #endif HAVE_SEQ_GETMNTENT */ +#elif HAVE_GETMNTENT_R +static cu_mount_t *cu_mount_getmntent (void) +{ + FILE *fp; + struct mntent me; + char mntbuf[1024]; + + cu_mount_t *first = NULL; + cu_mount_t *last = NULL; + cu_mount_t *new = NULL; + + DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB); + + if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL) + { + char errbuf[1024]; + ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB, + sstrerror (errno, errbuf, sizeof (errbuf))); + return (NULL); + } + + while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) )) + { + if ((new = malloc (sizeof (cu_mount_t))) == NULL) + break; + memset (new, '\0', sizeof (cu_mount_t)); + + /* Copy values from `struct mntent *' */ + new->dir = sstrdup (me.mnt_dir); + new->spec_device = sstrdup (me.mnt_fsname); + new->type = sstrdup (me.mnt_type); + new->options = sstrdup (me.mnt_opts); + new->device = get_device_name (new->options); + new->next = NULL; + + DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}", + new->dir, new->spec_device, new->type, new->options, new->device); + + /* Append to list */ + if (first == NULL) + { + first = new; + last = new; + } + else + { + last->next = new; + last = new; + } + } + + endmntent (fp); + + DEBUG ("utils_mount: return (0x%p)", (void *) first); + + return (first); +} /* HAVE_GETMNTENT_R */ + #elif HAVE_ONE_GETMNTENT static cu_mount_t *cu_mount_getmntent (void) { -- 2.11.0