Cygwin: path_conv: decouple path_types from mount types
- Remove another unfortunate amalgamation: Mount flags (MOUNT_xxx) are converted to path_types (PATH_xxx) and mixed with non-mount path_types flags in the same storage, leading to a tangled, pell-mell usage of mount flags and path flags in path_conv and symlink_info. - There's also the case of PC_NONULLEMPTY. It's used in exactly one place with a path_conv constructor only used in this single place, just to override the automatic PC_NULLEMPTY addition when calling the other path_conv constructors. Crazily, PC_NONULLEMPTY is a define, no path_types flag, despite its name. - It doesn't help that the binary flag exists as mount and path flag, while the text flag only exists as path flag. This leads to mount code using path flags to set text/binary. Very confusing is the fact that a text mount/path flag is not actually required; the mount code sets the text flag on non binary mounts anyway, so there are only two states. However, to puzzle people a bit more, path_conv::binary wrongly implies there's a third, non-binary/non-text state. Clean up this mess: - Store path flags separately from mount flags in path_conv and symlink_info classes and change all checks and testing inline methods accordingly. - Make PC_NONULLEMPTY a simple path_types flag and drop the redundant path_check constructor. - Clean up the definition of pathconv_arg, path_types, and mount flags. Use _BIT expression, newly define in cygwin/bits.h. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
@@ -11,6 +11,7 @@ details. */
|
||||
#include "cygheap_malloc.h"
|
||||
#include "nfs.h"
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <alloca.h>
|
||||
@@ -43,50 +44,32 @@ extern suffix_info stat_suffixes[];
|
||||
below path_types. Ever. */
|
||||
enum pathconv_arg
|
||||
{
|
||||
PC_SYM_FOLLOW = 0x0001,
|
||||
PC_SYM_NOFOLLOW = 0x0002,
|
||||
PC_SYM_NOFOLLOW_REP = 0x0004,
|
||||
PC_SYM_CONTENTS = 0x0008,
|
||||
PC_NOFULL = 0x0010,
|
||||
PC_NULLEMPTY = 0x0020,
|
||||
PC_DO_NOT_USE = 0x0040,
|
||||
PC_POSIX = 0x0080,
|
||||
PC_NOWARN = 0x0100,
|
||||
PC_OPEN = 0x0200, /* use open semantics */
|
||||
PC_CTTY = 0x0400, /* could later be used as ctty */
|
||||
PC_SYM_NOFOLLOW_PROCFD = 0x0800,
|
||||
PC_KEEP_HANDLE = 0x00400000,
|
||||
PC_NO_ACCESS_CHECK = 0x00800000
|
||||
PC_SYM_FOLLOW = _BIT ( 0),
|
||||
PC_SYM_NOFOLLOW = _BIT ( 1),
|
||||
PC_SYM_NOFOLLOW_REP = _BIT ( 2),
|
||||
PC_SYM_CONTENTS = _BIT ( 3),
|
||||
PC_NOFULL = _BIT ( 4),
|
||||
PC_NULLEMPTY = _BIT ( 5),
|
||||
PC_NONULLEMPTY = _BIT ( 6),
|
||||
PC_POSIX = _BIT ( 7),
|
||||
PC_NOWARN = _BIT ( 8),
|
||||
PC_OPEN = _BIT ( 9), /* use open semantics */
|
||||
PC_CTTY = _BIT (10), /* could later be used as ctty */
|
||||
PC_SYM_NOFOLLOW_PROCFD = _BIT (11),
|
||||
PC_KEEP_HANDLE = _BIT (12),
|
||||
PC_NO_ACCESS_CHECK = _BIT (13),
|
||||
PC_DONT_USE = _BIT (31) /* conversion to signed happens. */
|
||||
};
|
||||
|
||||
#define PC_NONULLEMPTY -1
|
||||
|
||||
#include "sys/mount.h"
|
||||
|
||||
enum path_types
|
||||
{
|
||||
PATH_NOTHING = 0,
|
||||
PATH_SYMLINK = MOUNT_SYMLINK,
|
||||
PATH_BINARY = MOUNT_BINARY,
|
||||
PATH_EXEC = MOUNT_EXEC,
|
||||
PATH_NOTEXEC = MOUNT_NOTEXEC,
|
||||
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
||||
PATH_SPARSE = MOUNT_SPARSE,
|
||||
PATH_RO = MOUNT_RO,
|
||||
PATH_NOACL = MOUNT_NOACL,
|
||||
PATH_NOPOSIX = MOUNT_NOPOSIX,
|
||||
PATH_DOS = MOUNT_DOS,
|
||||
PATH_IHASH = MOUNT_IHASH,
|
||||
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
|
||||
PATH_CTTY = 0x00400000, /* could later be used as ctty */
|
||||
PATH_OPEN = 0x00800000, /* use open semantics */
|
||||
/* FIXME? PATH_OPEN collides with
|
||||
PATH_NO_ACCESS_CHECK, but it looks
|
||||
like they are never used together. */
|
||||
PATH_LNK = 0x01000000,
|
||||
PATH_TEXT = 0x02000000,
|
||||
PATH_REP = 0x04000000,
|
||||
PATH_SOCKET = 0x40000000
|
||||
PATH_CTTY = _BIT ( 0), /* could later be used as ctty */
|
||||
PATH_OPEN = _BIT ( 1), /* use open semantics */
|
||||
PATH_LNK = _BIT ( 2),
|
||||
PATH_REP = _BIT ( 3),
|
||||
PATH_SYMLINK = _BIT ( 4),
|
||||
PATH_SOCKET = _BIT ( 5),
|
||||
PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */
|
||||
};
|
||||
|
||||
NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION);
|
||||
@@ -151,7 +134,8 @@ class path_conv
|
||||
UNICODE_STRING uni_path;
|
||||
DWORD symlink_length;
|
||||
const char *path;
|
||||
unsigned path_flags;
|
||||
uint32_t mount_flags;
|
||||
uint32_t path_flags;
|
||||
const char *suffix;
|
||||
const char *posix_path;
|
||||
path_conv_handle conv_handle;
|
||||
@@ -169,25 +153,24 @@ class path_conv
|
||||
const char *known_suffix () { return suffix; }
|
||||
bool isremote () const {return fs.is_remote_drive ();}
|
||||
ULONG objcaseinsensitive () const {return caseinsensitive;}
|
||||
bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); }
|
||||
bool hasgood_inode () const {return !(path_flags & PATH_IHASH); }
|
||||
bool has_acls () const {return !(mount_flags & MOUNT_NOACL)
|
||||
&& fs.has_acls (); }
|
||||
bool hasgood_inode () const {return !(mount_flags & MOUNT_IHASH); }
|
||||
bool isgood_inode (ino_t ino) const;
|
||||
bool support_sparse () const
|
||||
{
|
||||
return (path_flags & PATH_SPARSE)
|
||||
return (mount_flags & MOUNT_SPARSE)
|
||||
&& (fs_flags () & FILE_SUPPORTS_SPARSE_FILES);
|
||||
}
|
||||
int has_dos_filenames_only () const {return path_flags & PATH_DOS;}
|
||||
int has_dos_filenames_only () const {return mount_flags & MOUNT_DOS;}
|
||||
int has_buggy_reopen () const {return fs.has_buggy_reopen ();}
|
||||
int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();}
|
||||
int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();}
|
||||
int binmode () const
|
||||
{
|
||||
if (path_flags & PATH_BINARY)
|
||||
if (mount_flags & MOUNT_BINARY)
|
||||
return O_BINARY;
|
||||
if (path_flags & PATH_TEXT)
|
||||
return O_TEXT;
|
||||
return 0;
|
||||
return O_TEXT;
|
||||
}
|
||||
int issymlink () const {return path_flags & PATH_SYMLINK;}
|
||||
int is_lnk_symlink () const {return path_flags & PATH_LNK;}
|
||||
@@ -206,33 +189,33 @@ class path_conv
|
||||
#else
|
||||
int issocket () const {return dev.is_device (FH_LOCAL);}
|
||||
#endif /* __WITH_AF_UNIX */
|
||||
int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
|
||||
int iscygexec () const {return mount_flags & MOUNT_CYGWIN_EXEC;}
|
||||
int isopen () const {return path_flags & PATH_OPEN;}
|
||||
int isctty_capable () const {return path_flags & PATH_CTTY;}
|
||||
void set_cygexec (bool isset)
|
||||
{
|
||||
if (isset)
|
||||
path_flags |= PATH_CYGWIN_EXEC;
|
||||
mount_flags |= MOUNT_CYGWIN_EXEC;
|
||||
else
|
||||
path_flags &= ~PATH_CYGWIN_EXEC;
|
||||
mount_flags &= ~MOUNT_CYGWIN_EXEC;
|
||||
}
|
||||
void set_cygexec (void *target)
|
||||
{
|
||||
if (target)
|
||||
path_flags |= PATH_CYGWIN_EXEC;
|
||||
mount_flags |= MOUNT_CYGWIN_EXEC;
|
||||
else
|
||||
path_flags &= ~PATH_CYGWIN_EXEC;
|
||||
mount_flags &= ~MOUNT_CYGWIN_EXEC;
|
||||
}
|
||||
bool isro () const {return !!(path_flags & PATH_RO);}
|
||||
bool isro () const {return !!(mount_flags & MOUNT_RO);}
|
||||
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
|
||||
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
|
||||
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
|
||||
executable_states exec_state ()
|
||||
{
|
||||
extern int _check_for_executable;
|
||||
if (path_flags & PATH_ALL_EXEC)
|
||||
if (mount_flags & (MOUNT_CYGWIN_EXEC | MOUNT_EXEC))
|
||||
return is_executable;
|
||||
if (path_flags & PATH_NOTEXEC)
|
||||
if (mount_flags & MOUNT_NOTEXEC)
|
||||
return not_executable;
|
||||
if (!_check_for_executable)
|
||||
return dont_care_if_executable;
|
||||
@@ -240,48 +223,40 @@ class path_conv
|
||||
}
|
||||
|
||||
void set_symlink (DWORD n) {path_flags |= PATH_SYMLINK; symlink_length = n;}
|
||||
void set_exec (int x = 1) {path_flags |= x ? PATH_EXEC : PATH_NOTEXEC;}
|
||||
void set_exec (int x = 1) {mount_flags |= x ? MOUNT_EXEC : MOUNT_NOTEXEC;}
|
||||
|
||||
void __reg3 check (const UNICODE_STRING *upath, unsigned opt = PC_SYM_FOLLOW,
|
||||
void __reg3 check (const UNICODE_STRING *upath, uint32_t opt = PC_SYM_FOLLOW,
|
||||
const suffix_info *suffixes = NULL);
|
||||
void __reg3 check (const char *src, unsigned opt = PC_SYM_FOLLOW,
|
||||
void __reg3 check (const char *src, uint32_t opt = PC_SYM_FOLLOW,
|
||||
const suffix_info *suffixes = NULL);
|
||||
|
||||
path_conv (const device& in_dev)
|
||||
: fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
|
||||
path_flags (0), suffix (NULL), posix_path (NULL), error (0),
|
||||
dev (in_dev)
|
||||
mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL),
|
||||
error (0), dev (in_dev)
|
||||
{
|
||||
set_path (in_dev.native ());
|
||||
}
|
||||
|
||||
path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW,
|
||||
path_conv (const UNICODE_STRING *src, uint32_t opt = PC_SYM_FOLLOW,
|
||||
const suffix_info *suffixes = NULL)
|
||||
: fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
|
||||
path_flags (0), suffix (NULL), posix_path (NULL), error (0)
|
||||
mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0)
|
||||
{
|
||||
check (src, opt, suffixes);
|
||||
check (src, opt | ((opt & PC_NONULLEMPTY) ? 0 : PC_NULLEMPTY), suffixes);
|
||||
}
|
||||
|
||||
path_conv (const UNICODE_STRING *src, unsigned opt = PC_SYM_FOLLOW,
|
||||
path_conv (const char *src, uint32_t opt = PC_SYM_FOLLOW,
|
||||
const suffix_info *suffixes = NULL)
|
||||
: fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
|
||||
path_flags (0), suffix (NULL), posix_path (NULL), error (0)
|
||||
mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0)
|
||||
{
|
||||
check (src, opt | PC_NULLEMPTY, suffixes);
|
||||
}
|
||||
|
||||
path_conv (const char *src, unsigned opt = PC_SYM_FOLLOW,
|
||||
const suffix_info *suffixes = NULL)
|
||||
: fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
|
||||
path_flags (0), suffix (NULL), posix_path (NULL), error (0)
|
||||
{
|
||||
check (src, opt | PC_NULLEMPTY, suffixes);
|
||||
check (src, opt | ((opt & PC_NONULLEMPTY) ? 0 : PC_NULLEMPTY), suffixes);
|
||||
}
|
||||
|
||||
path_conv ()
|
||||
: fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
|
||||
path_flags (0), suffix (NULL), posix_path (NULL), error (0)
|
||||
mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0)
|
||||
{}
|
||||
|
||||
~path_conv ();
|
||||
|
Reference in New Issue
Block a user