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