diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index 51eaa7f75..5d7193939 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,3 +1,27 @@ +2009-07-22 Corinna Vinschen + + * Makefile.in (path-mount.o): Add a rule to build stripped down version + of path.cc for usage in mount. + (mount.exe): Add dependency to path-mount.o. + * mount.cc (force): Convert to bool value. Accommodate throughout. + (from_fstab): New function. + (do_mount_from_fstab): New function. + (longopts): Add --all option. + (opts): Add -a option. + (usage): Document -a/--all option. + (main): Handle -a option as well as single parameter. + * path.cc: Add FSTAB_ONLY conditional to allow building path-mount.o. + (mount_table): Remove static storage class. + (max_mount_entry): Ditto. + (root_here): Unused. Remove. + (from_fstab_line): Remove static. + * path.h (struct mnt_t): Define here rather than in path.cc. + (from_fstab_line): Declare. + (mount_table): Declare. + (max_mount_entry): Declare. + * utils.sgml (mount): Document -a/--all option and mounting of single + path from fstab files. + 2009-07-15 Corinna Vinschen * strace.cc (main): Open trace output file in UNIX mode. diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in index 48555e676..3dac26ada 100644 --- a/winsup/utils/Makefile.in +++ b/winsup/utils/Makefile.in @@ -69,6 +69,10 @@ MINGW_OBJS := bloda.o cygcheck.o dump_setup.o ldh.o path.o strace.o strace.exe: path.o cygcheck.exe: bloda.o path.o dump_setup.o +path-mount.o: path.cc + $(CXX) -c $(CXXFLAGS) -DFSTAB_ONLY -I$(updir) $< -o $@ +mount.exe: path-mount.o + # Provide any necessary per-target variable overrides. cygcheck.exe: MINGW_LDFLAGS += -lntdll cygpath.exe: ALL_LDFLAGS += -lcygwin -lntdll diff --git a/winsup/utils/mount.cc b/winsup/utils/mount.cc index a7903946c..3412feccb 100644 --- a/winsup/utils/mount.cc +++ b/winsup/utils/mount.cc @@ -16,8 +16,10 @@ details. */ #include #include #include +#include #include #include +#include "path.h" #ifdef errno #undef errno @@ -35,7 +37,7 @@ static void change_cygdrive_prefix (const char *new_prefix, int flags); static int mount_already_exists (const char *posix_path, int flags); // static short create_missing_dirs = FALSE; -static short force = FALSE; +static bool force = false; static const char version[] = "$Revision$"; static const char *progname; @@ -111,8 +113,71 @@ do_mount (const char *dev, const char *where, int flags) exit (0); } +static void +from_fstab (bool user) +{ + char path[PATH_MAX]; + char buf[65536]; + mnt_t *m = mount_table + max_mount_entry; + + strcpy (path, "/etc/fstab"); + if (user) + { + strcat (path, ".d/"); + strcat (path, getlogin ()); + } + FILE *fh = fopen (path, "rt"); + if (!fh) + return; + while (fgets (buf, 65536, fh)) + { + char *c = strrchr (buf, '\n'); + if (*c) + *c = '\0'; + if (from_fstab_line (m, buf, user)) + ++m; + } + max_mount_entry = m - mount_table; + fclose (fh); +} + +static void +do_mount_from_fstab (const char *where) +{ + force = true; + /* Read fstab entries. */ + from_fstab (false); + from_fstab (true); + /* Loop through fstab entries and see if it matches `where'. If `where' + is NULL, all entries match. */ + bool exists = false; + for (mnt_t *m = mount_table; m - mount_table < max_mount_entry; ++m) + if (!(m->flags & MOUNT_CYGDRIVE) && (!where || !strcmp (where, m->posix))) + { + exists = true; + /* Compare with existing mount table. If the entry doesn't exist, + mount it. */ + FILE *mt = setmntent ("/-not-used-", "r"); + struct mntent *p; + + while ((p = getmntent (mt)) != NULL) + if (!strcmp (m->posix, p->mnt_dir)) + break; + if (!p) + do_mount (m->native, m->posix, m->flags); + endmntent (mt); + if (where) + break; + } + if (!exists && where) + fprintf (stderr, + "%s: can't find %s in /etc/fstab or in /etc/fstab.d/$USER\n", + progname, where); +} + static struct option longopts[] = { + {"all", no_argument, NULL, 'a'}, {"change-cygdrive-prefix", no_argument, NULL, 'c'}, {"force", no_argument, NULL, 'f'}, {"help", no_argument, NULL, 'h' }, @@ -123,7 +188,7 @@ static struct option longopts[] = {NULL, 0, NULL, 0} }; -static char opts[] = "cfhmpvo:"; +static char opts[] = "acfhmpvo:"; struct opt { @@ -151,8 +216,11 @@ static void usage (FILE *where = stderr) { fprintf (where, "Usage: %s [OPTION] [ ]\n\ + %s -a\n\ + %s \n\ Display information about mounted filesystems, or mount a filesystem\n\ \n\ + -a, --all mount all filesystems mentioned in fstab\n\ -c, --change-cygdrive-prefix change the cygdrive path prefix to \n\ -f, --force force mount, don't warn about missing mount\n\ point directories\n\ @@ -163,7 +231,7 @@ Display information about mounted filesystems, or mount a filesystem\n\ -p, --show-cygdrive-prefix show user and/or system cygdrive path prefix\n\ -v, --version output version information and exit\n\ \n\ -Valid options are:\n\n ", progname); +Valid options are:\n\n ", progname, progname, progname); for (opt *o = oopts; o < (oopts + (sizeof (oopts) / sizeof (oopts[0]))); o++) fprintf (where, "%s%s", o == oopts ? "" : ",", o->name); fputs ("\n\n", where); @@ -212,7 +280,8 @@ main (int argc, char **argv) nada, saw_change_cygdrive_prefix, saw_show_cygdrive_prefix, - saw_mount_commands + saw_mount_commands, + saw_mount_all, } do_what = nada; progname = strrchr (argv[0], '/'); @@ -232,6 +301,12 @@ main (int argc, char **argv) while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) switch (i) { + case 'a': + if (do_what == nada) + do_what = saw_mount_all; + else + usage (); + break; case 'c': if (do_what == nada) do_what = saw_change_cygdrive_prefix; @@ -239,7 +314,7 @@ main (int argc, char **argv) usage (); break; case 'f': - force = TRUE; + force = true; break; case 'h': usage (stdout); @@ -251,7 +326,9 @@ main (int argc, char **argv) usage (); break; case 'o': - if (*options) + if (do_what == saw_mount_all) + usage (); + else if (*options) options = concat3 (options, ",", optarg); else options = strdup (optarg); @@ -320,16 +397,20 @@ main (int argc, char **argv) usage (); mount_entries (); break; + case saw_mount_all: + if (optind <= argc) + usage (); + do_mount_from_fstab (NULL); + break; default: - if (optind != (argc - 1)) + if (optind == argc) + do_mount_from_fstab (argv[optind]); + else if (optind != (argc - 1)) { - if (optind >= argc) - fprintf (stderr, "%s: not enough arguments\n", progname); - else - fprintf (stderr, "%s: too many arguments\n", progname); + fprintf (stderr, "%s: too many arguments\n", progname); usage (); } - if (force || !mount_already_exists (argv[optind + 1], flags)) + else if (force || !mount_already_exists (argv[optind + 1], flags)) do_mount (argv[optind], argv[optind + 1], flags); else { diff --git a/winsup/utils/path.cc b/winsup/utils/path.cc index a10c574e7..63eda1640 100644 --- a/winsup/utils/path.cc +++ b/winsup/utils/path.cc @@ -27,6 +27,7 @@ details. */ #include "cygwin/include/mntent.h" #include "testsuite.h" +#ifndef FSTAB_ONLY /* Used when treating / and \ as equivalent. */ #define isslash(ch) \ ({ \ @@ -245,25 +246,17 @@ readlink (HANDLE fh, char *path, int maxlen) else return false; } - -struct mnt_t -{ - char *native; - char *posix; - unsigned flags; -}; +#endif /* !FSTAB_ONLY */ #ifndef TESTSUITE -static mnt_t mount_table[255]; -static int max_mount_entry; +mnt_t mount_table[255]; +int max_mount_entry; #else # define TESTSUITE_MOUNT_TABLE # include "testsuite.h" # undef TESTSUITE_MOUNT_TABLE #endif -mnt_t *root_here = NULL; - inline void unconvert_slashes (char* name) { @@ -355,7 +348,7 @@ read_flags (char *options, unsigned &flags) return true; } -static bool +bool from_fstab_line (mnt_t *m, char *line, bool user) { char *native_path, *posix_path, *fs_type; @@ -440,6 +433,8 @@ from_fstab_line (mnt_t *m, char *line, bool user) return true; } +#ifndef FSTAB_ONLY + #define BUFSIZE 65536 static char * @@ -540,7 +535,10 @@ from_fstab (bool user, PWCHAR path, PWCHAR path_end) max_mount_entry = m - mount_table; CloseHandle (h); } -#endif +#endif /* !FSTAB_ONLY */ +#endif /* !TESTSUITE */ + +#ifndef FSTAB_ONLY static int mnt_sort (const void *a, const void *b) @@ -900,3 +898,5 @@ getmntent (FILE *) m++; return &mnt; } + +#endif /* !FSTAB_ONLY */ diff --git a/winsup/utils/path.h b/winsup/utils/path.h index 48739df74..a5c77ef58 100644 --- a/winsup/utils/path.h +++ b/winsup/utils/path.h @@ -1,6 +1,6 @@ /* path.h - Copyright 2001, 2002, 2003 Red Hat, Inc. + Copyright 2001, 2002, 2003, 2006, 2008, 2009 Red Hat, Inc. This file is part of Cygwin. @@ -8,6 +8,13 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ +struct mnt_t +{ + char *native; + char *posix; + unsigned flags; +}; + char *cygpath (const char *s, ...); char *cygpath_rel (const char *cwd, const char *s, ...); bool is_exe (HANDLE); @@ -15,5 +22,11 @@ bool is_symlink (HANDLE); bool readlink (HANDLE, char *, int); int get_word (HANDLE, int); int get_dword (HANDLE, int); +bool from_fstab_line (mnt_t *m, char *line, bool user); +extern mnt_t mount_table[255]; +extern int max_mount_entry; + +#ifndef SYMLINK_MAX #define SYMLINK_MAX 4095 /* PATH_MAX - 1 */ +#endif diff --git a/winsup/utils/utils.sgml b/winsup/utils/utils.sgml index a3caeb6df..2e6e9c1c0 100644 --- a/winsup/utils/utils.sgml +++ b/winsup/utils/utils.sgml @@ -729,8 +729,11 @@ up as file owners in ls -l output. Usage: mount [OPTION] [<win32path> <posixpath>] + mount -a + mount <posixpath> Display information about mounted filesystems, or mount a filesystem + -a, --all mount all filesystems mentioned in fstab -c, --change-cygdrive-prefix change the cygdrive path prefix to <posixpath> -f, --force force mount, don't warn about missing mount point directories @@ -836,6 +839,30 @@ most of the options are duplicates of other mount flags): user mount points. System mount points can only be specified in the /etc/fstab file. +If you added mount points to /etc/fstab or your +/etc/fstab.d/<username> file, you can add these +mount points to your current user session using the -a/--all +option, or by specifing the posix path alone on the command line. As an +example, consider you added a mount point with the POSIX path +/my/mount. You can add this mount point with either +one of the following two commands to your current user session. + + +$ mount /my/mount +$ mount -a + + +The first command just adds the /my/mount mount +point to your current session, the mount -a adds all +new mount points to your user session. + +If you change a mount point to point to another native path, or +if you changed the flags of a mount point, you have to umount +the mount point first, before you can add it again. Please note that +all such added mount points are added as user mount points, and that the +rule that system mount points can't be removed or replaced in a running +session still applies. + The -m option causes the mount utility to output the current mount table in a series of fstab entries.