tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Patch: Use fstab different to /etc/fstab in fstab.h



Hi,

> > in a case where it would be useful to read a fstab that is not the
> > system's own one (sysinst), i.e. lies not /etc/fstab, you can't do that
> > with fstab.h.
> > 
> > The solution would be to have a function setfstab(const char*) do set the
> > fstab you want to read. The code is about 20 lines of additional code +
> > some documentation.
> 
> I don't think this is the right way.  What if sysinst (or some future
> installer or partition editor) became multi-threaded?
I cannot really imagine what that should look like... ;-)

> I think it would be better to reimplement the functions that use fstab
> in terms of new _r variants that take an explicit fstab argument.
What about the attached diffs?

There are two diffs for fstab.c/fstab.h (note that fstab.c does not contain
weak aliases yet). There is a test program fstab-test.c, which needs to be run
in the same directory as fstab-test.file resides. It opens your fstab and the
supplied test file and checks for the mount point you supply as the first
argument.

The new functions of the interface (except for the internal fstabscan_r):

struct fstab *getfsspec_r(const char * spec, const char *path, FILE **fd);
struct fstab *getfsfile_r(const char * file, const char *path, FILE **fd);
Do the same as getfsspec/gestfsfile, but searches the fstab file *path and
use file  *fd, leaving it open.

int setfsent_r(const char *path, FILE **fd);
Does the same as setfsent, but opens *path, storing it in *fd, instead
of /etc/fstab (_PATH_FSTAB).
If you supply *fd != NULL, then *fd will be opened and *path is ignored.

void endfsent_r(FILE **fd);
Simply closes *fd, if available, just for consistency.


If you know a thorough test suite for that, please test it, I don't know much
more to test thatn fstab-test.c currently does. One could additionally open
more fstabs, e.g.


Regards, Julian
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstab.h>

#define FSTABFILE "fstab-test.file"

int
main(int argc, char *argv[]) {
        char *tmp = NULL;
        char *ttmp = NULL;
        struct fstab *file;
        FILE *fp = NULL;

        if (argc != 2)
                errx(EXIT_FAILURE, "fstab-test <mount-path>");

        if (!setfsent_r(FSTABFILE, &fp))
                printf("setfsent_r failed.\n");

        file = getfsfile(argv[1]);
        if (file) {
                tmp = strdup(file->fs_spec);
                printf("Your fstab: %s\n", tmp);
        } else {
                printf("No entry found in your fstab.\n");
        }

        file = getfsfile_r(argv[1], FSTABFILE, &fp);
        if (file) {
                ttmp = strdup(file->fs_spec);
                printf("This fstab: %s\n", ttmp);
        } else {
                printf("No entry found in this fstab.\n");
        }


        if (tmp) {
                file = getfsspec(tmp);
                if (file)
                        printf("According input (your fstab): %s\n", 
file->fs_file);
        }

        if (ttmp) {
                file = getfsspec_r(ttmp, FSTABFILE, &fp);
                if (file)
                        printf("According input (this fstab): %s\n", 
file->fs_file);
        }

        endfsent_r(&fp);
        endfsent();

        return EXIT_SUCCESS;
}

Attachment: fstab-test.file
Description: Binary data

Index: lib/libc/gen/fstab.c
===================================================================
RCS file: /cvsroot/src/lib/libc/gen/fstab.c,v
retrieving revision 1.28
diff -u -r1.28 fstab.c
--- lib/libc/gen/fstab.c        12 Aug 2006 23:49:54 -0000      1.28
+++ lib/libc/gen/fstab.c        20 Sep 2011 11:30:09 -0000
@@ -67,6 +67,7 @@
 
 static char *nextfld(char **, const char *);
 static int fstabscan(void);
+static int fstabscan_r(FILE **, struct fstab *, size_t *, const char *);
 
 
 static char *
@@ -86,6 +87,13 @@
 static int
 fstabscan(void)
 {
+       return fstabscan_r(&_fs_fp, &_fs_fstab, &_fs_lineno, _fs_file);
+}
+
+int
+fstabscan_r(FILE **fs_fp, struct fstab *fs_fstab, size_t *fs_lineno, const char
+                       *fs_file)
+{
        char *cp, *lp, *sp;
 #define        MAXLINELENGTH   1024
        static char line[MAXLINELENGTH];
@@ -96,30 +104,30 @@
            FSTAB_RW, FSTAB_RQ, FSTAB_RO, FSTAB_SW, FSTAB_DP, FSTAB_XX, NULL 
        };
 
-       (void)memset(&_fs_fstab, 0, sizeof(_fs_fstab));
+       (void)memset(fs_fstab, 0, sizeof(struct fstab));
        for (;;) {
-               if (!(lp = fgets(line, sizeof(line), _fs_fp)))
+               if (!(lp = fgets(line, sizeof(line), *fs_fp)))
                        return 0;
-               _fs_lineno++;
+               (*fs_lineno)++;
 /* OLD_STYLE_FSTAB */
                if (!strpbrk(lp, " \t")) {
-                       _fs_fstab.fs_spec = nextfld(&lp, sep);
-                       if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
+                       fs_fstab->fs_spec = nextfld(&lp, sep);
+                       if (!fs_fstab->fs_spec || *fs_fstab->fs_spec == '#')
                                continue;
-                       _fs_fstab.fs_file = nextfld(&lp, sep);
-                       _fs_fstab.fs_type = nextfld(&lp, sep);
-                       if (_fs_fstab.fs_type) {
-                               if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
+                       fs_fstab->fs_file = nextfld(&lp, sep);
+                       fs_fstab->fs_type = nextfld(&lp, sep);
+                       if (fs_fstab->fs_type) {
+                               if (!strcmp(fs_fstab->fs_type, FSTAB_XX))
                                        continue;
-                               _fs_fstab.fs_mntops = _fs_fstab.fs_type;
-                               _fs_fstab.fs_vfstype =
+                               fs_fstab->fs_mntops = fs_fstab->fs_type;
+                               fs_fstab->fs_vfstype =
                                    __UNCONST(
-                                   strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
+                                   strcmp(fs_fstab->fs_type, FSTAB_SW) ?
                                    "ufs" : "swap");
                                if ((cp = nextfld(&lp, sep)) != NULL) {
-                                       _fs_fstab.fs_freq = atoi(cp);
+                                       fs_fstab->fs_freq = atoi(cp);
                                        if ((cp = nextfld(&lp, sep)) != NULL) {
-                                               _fs_fstab.fs_passno = atoi(cp);
+                                               fs_fstab->fs_passno = atoi(cp);
                                                return 1;
                                        }
                                }
@@ -127,24 +135,24 @@
                        goto bad;
                }
 /* OLD_STYLE_FSTAB */
-               _fs_fstab.fs_spec = nextfld(&lp, ws);
-               if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
+               fs_fstab->fs_spec = nextfld(&lp, ws);
+               if (!fs_fstab->fs_spec || *fs_fstab->fs_spec == '#')
                        continue;
-               _fs_fstab.fs_file = nextfld(&lp, ws);
-               _fs_fstab.fs_vfstype = nextfld(&lp, ws);
-               _fs_fstab.fs_mntops = nextfld(&lp, ws);
-               if (_fs_fstab.fs_mntops == NULL)
+               fs_fstab->fs_file = nextfld(&lp, ws);
+               fs_fstab->fs_vfstype = nextfld(&lp, ws);
+               fs_fstab->fs_mntops = nextfld(&lp, ws);
+               if (fs_fstab->fs_mntops == NULL)
                        goto bad;
-               _fs_fstab.fs_freq = 0;
-               _fs_fstab.fs_passno = 0;
+               fs_fstab->fs_freq = 0;
+               fs_fstab->fs_passno = 0;
                if ((cp = nextfld(&lp, ws)) != NULL) {
-                       _fs_fstab.fs_freq = atoi(cp);
+                       fs_fstab->fs_freq = atoi(cp);
                        if ((cp = nextfld(&lp, ws)) != NULL)
-                               _fs_fstab.fs_passno = atoi(cp);
+                               fs_fstab->fs_passno = atoi(cp);
                }
 
                /* subline truncated iff line truncated */
-               (void)strlcpy(subline, _fs_fstab.fs_mntops, sizeof(subline));
+               (void)strlcpy(subline, fs_fstab->fs_mntops, sizeof(subline));
                sp = subline;
 
                while ((cp = nextfld(&sp, ",")) != NULL) {
@@ -155,21 +163,21 @@
 
                        for (tp = fstab_type; *tp; tp++)
                                if (strcmp(cp, *tp) == 0) {
-                                       _fs_fstab.fs_type = __UNCONST(*tp);
+                                       fs_fstab->fs_type = __UNCONST(*tp);
                                        break;
                                }
                        if (*tp)
                                break;
                }
-               if (_fs_fstab.fs_type == NULL)
+               if (fs_fstab->fs_type == NULL)
                        goto bad;
-               if (strcmp(_fs_fstab.fs_type, FSTAB_XX) == 0)
+               if (strcmp(fs_fstab->fs_type, FSTAB_XX) == 0)
                        continue;
                if (cp != NULL)
                        return 1;
 
 bad:
-               warnx("%s, %lu: Missing fields", _fs_file, (u_long)_fs_lineno);
+               warnx("%s, %lu: Missing fields", fs_file, (u_long)*fs_lineno);
        }
        /* NOTREACHED */
 }
@@ -185,7 +193,6 @@
 struct fstab *
 getfsspec(const char *name)
 {
-
        _DIAGASSERT(name != NULL);
 
        if (setfsent())
@@ -196,9 +203,29 @@
 }
 
 struct fstab *
-getfsfile(const char *name)
+getfsspec_r(const char *name, const char *fs_fstab_path, FILE **fs_fp)
 {
+       struct fstab *fs_fstab;
+       size_t fs_lineno = 0;
+
+       _DIAGASSERT(name != NULL);
+
+       if (setfsent_r(fs_fstab_path, fs_fp)) {
+               fs_fstab = malloc(sizeof(struct fstab));
+               if (fs_fstab == NULL)
+                       return NULL;
+               while (fstabscan_r(fs_fp, fs_fstab, &fs_lineno, fs_fstab_path))
+                       if (!strcmp(fs_fstab->fs_spec, name))
+                               return fs_fstab;
+               free(fs_fstab);
+       }
 
+       return NULL;
+}
+
+struct fstab *
+getfsfile(const char *name)
+{
        _DIAGASSERT(name != NULL);
 
        if (setfsent())
@@ -208,6 +235,27 @@
        return NULL;
 }
 
+struct fstab *
+getfsfile_r(const char *name, const char *fs_fstab_path, FILE **fs_fp)
+{
+       struct fstab *fs_fstab;
+       size_t fs_lineno = 0;
+
+       _DIAGASSERT(name != NULL);
+
+       if (setfsent_r(fs_fstab_path, fs_fp)) {
+               fs_fstab = malloc(sizeof(struct fstab));
+               if (fs_fstab == NULL)
+                       return NULL;
+               while (fstabscan_r(fs_fp, fs_fstab, &fs_lineno, fs_fstab_path))
+                       if (!strcmp(fs_fstab->fs_file, name))
+                               return fs_fstab;
+               free(fs_fstab);
+       }
+
+       return NULL;
+}
+
 int
 setfsent(void)
 {
@@ -223,6 +271,20 @@
        return 1;
 }
 
+int
+setfsent_r(const char *fs_fstab_path, FILE **fs_fp)
+{
+       if (*fs_fp) {
+               rewind(*fs_fp);
+               return 1;
+       }
+       if ((*fs_fp = fopen(fs_fstab_path, "r")) == NULL) {
+               warn("Cannot open `%s'", fs_fstab_path);
+               return 0;
+       }
+       return 1;
+}
+
 void
 endfsent(void)
 {
@@ -231,3 +293,12 @@
                _fs_fp = NULL;
        }
 }
+
+void
+endfsent_r(FILE **fs_fp)
+{
+       if (*fs_fp) {
+               (void)fclose(*fs_fp);
+               *fs_fp = NULL;
+       }
+}
Index: include/fstab.h
===================================================================
RCS file: /cvsroot/src/include/fstab.h,v
retrieving revision 1.11
diff -u -r1.11 fstab.h
--- include/fstab.h     3 Feb 2005 04:39:32 -0000       1.11
+++ include/fstab.h     20 Sep 2011 11:29:43 -0000
@@ -35,6 +35,7 @@
 #define _FSTAB_H_
 
 #include <sys/cdefs.h>
+#include <stdio.h>
 
 /*
  * File system table, see fstab(5).
@@ -70,9 +71,13 @@
 __BEGIN_DECLS
 struct fstab *getfsent(void);
 struct fstab *getfsspec(const char *);
+struct fstab *getfsspec_r(const char *, const char *, FILE **);
 struct fstab *getfsfile(const char *);
+struct fstab *getfsfile_r(const char *, const char *, FILE **);
 int setfsent(void);
+int setfsent_r(const char *, FILE **);
 void endfsent(void);
+void endfsent_r(FILE **);
 __END_DECLS
 
 #endif /* !_FSTAB_H_ */

Attachment: signature.asc
Description: PGP signature



Home | Main Index | Thread Index | Old Index