* external.cc (cygwin_internal): Add CW_CVT_MNT_OPTS to allow mount

flag parsing.  Add CW_LST_MNT_OPTS case to allow mount flag listing.
	* mount.cc (fstab_read_flags): Rename from read_flags.  Make externally
	available.  Change input string to char ** to allow returning faulty
	option.  Add flag for avoiding debug output.
	(fstab_list_flags): New function to create list of options.
	* include/sys/cygwin.h (cygwin_getinfo_types): Add CW_CVT_MNT_OPTS and
	CW_LST_MNT_OPTS.
This commit is contained in:
Corinna Vinschen 2010-04-29 08:47:44 +00:00
parent f00bc469e2
commit a11a07231b
4 changed files with 82 additions and 11 deletions

View File

@ -1,3 +1,14 @@
2010-04-29 Corinna Vinschen <corinna@vinschen.de>
* external.cc (cygwin_internal): Add CW_CVT_MNT_OPTS to allow mount
flag parsing. Add CW_LST_MNT_OPTS case to allow mount flag listing.
* mount.cc (fstab_read_flags): Rename from read_flags. Make externally
available. Change input string to char ** to allow returning faulty
option. Add flag for avoiding debug output.
(fstab_list_flags): New function to create list of options.
* include/sys/cygwin.h (cygwin_getinfo_types): Add CW_CVT_MNT_OPTS and
CW_LST_MNT_OPTS.
2010-04-28 Corinna Vinschen <corinna@vinschen.de>
* mount.cc (compare_flags): New function.

View File

@ -474,6 +474,40 @@ cygwin_internal (cygwin_getinfo_types t, ...)
internal_setlocale ();
res = 0;
}
break;
case CW_CVT_MNT_OPTS:
{
extern bool fstab_read_flags (char **, unsigned &, bool);
char **option_string = va_arg (arg, char **);
if (!option_string || !*option_string)
set_errno (EINVAL);
else
{
unsigned *pflags = va_arg (arg, unsigned *);
unsigned flags = 0;
if (fstab_read_flags (option_string, flags, true))
{
if (pflags)
*pflags = flags;
res = 0;
}
}
}
break;
case CW_LST_MNT_OPTS:
{
extern char *fstab_list_flags ();
char **option_string = va_arg (arg, char **);
if (!option_string)
set_errno (EINVAL);
else
{
*option_string = fstab_list_flags ();
if (*option_string)
res = 0;
}
}
break;
default:
set_errno (ENOSYS);

View File

@ -146,7 +146,9 @@ typedef enum
CW_EXIT_PROCESS,
CW_SET_EXTERNAL_TOKEN,
CW_GET_INSTKEY,
CW_INT_SETLOCALE
CW_INT_SETLOCALE,
CW_CVT_MNT_OPTS,
CW_LST_MNT_OPTS
} cygwin_getinfo_types;
/* Token type for CW_SET_EXTERNAL_TOKEN */

View File

@ -953,36 +953,60 @@ compare_flags (const void *a, const void *b)
return strcmp (oa->name, ob->name);
}
static bool
read_flags (char *options, unsigned &flags)
extern "C" bool
fstab_read_flags (char **options, unsigned &flags, bool external)
{
opt key;
while (*options)
while (**options)
{
char *p = strchr (options, ',');
char *p = strchr (*options, ',');
if (p)
*p++ = '\0';
else
p = strchr (options, '\0');
p = strchr (*options, '\0');
key.name = options;
opt *o = (opt *) bsearch (&key, oopts, sizeof oopts / sizeof (opt),
key.name = *options;
opt *o = (opt *) bsearch (&key, oopts,
sizeof oopts / sizeof (opt),
sizeof (opt), compare_flags);
if (!o)
{
system_printf ("invalid fstab option - '%s'", options);
if (!external)
system_printf ("invalid fstab option - '%s'", *options);
return false;
}
if (o->clear)
flags &= ~o->val;
else
flags |= o->val;
options = p;
*options = p;
}
return true;
}
extern "C" char *
fstab_list_flags ()
{
size_t len = 0;
opt *o;
for (o = oopts; o < (oopts + (sizeof (oopts) / sizeof (oopts[0]))); o++)
len += strlen (o->name) + 1;
char *buf = (char *) malloc (len);
if (buf)
{
char *bp = buf;
for (o = oopts; o < (oopts + (sizeof (oopts) / sizeof (oopts[0]))); o++)
{
bp = stpcpy (bp, o->name);
*bp++ = ',';
}
*--bp = '\0';
}
return buf;
}
bool
mount_info::from_fstab_line (char *line, bool user)
{
@ -1021,7 +1045,7 @@ mount_info::from_fstab_line (char *line, bool user)
unsigned mount_flags = MOUNT_SYSTEM | MOUNT_BINARY;
if (!strcmp (fs_type, "cygdrive"))
mount_flags |= MOUNT_NOPOSIX;
if (!read_flags (c, mount_flags))
if (!fstab_read_flags (&c, mount_flags, false))
return true;
if (user)
mount_flags &= ~MOUNT_SYSTEM;