* dtable.cc (dtable::dup_worker): Reset path_conv handle in duplicated

fhandler.
	* fhandler.cc (fhandler_base::fstatvfs): Keep handle in created
	path_conv.
	* fhandler.h (fhandler_base::get_stat_access): New method.
	(fhandler_base::get_stat_handle): New method.
	* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Use handle
	returned by get_stat_handle.  Only request inode from system if it
	isn't already set in the fhandler, and only for filesystems supporting
	them.
	(fhandler_base::fstat_fs): Use handle returned by get_stat_handle.
	Change the way open_fs is called.  Explain why.
	(fhandler_base::fstat_helper): Use handle returned by get_stat_handle.
	Never use 0 inode number.  Simplify executable recognition by re-using
	get_stat_handle if file could be opened with sufficient rights.
	(fhandler_disk_file::fstatvfs): Use handle returned by get_stat_handle.
	(fhandler_disk_file::facl): Use handle returned by get_stat_handle in
	GETACL and GETACLCNT cases.
	(fhandler_disk_file::link): Use handle returned by get_stat_handle
	instead of opening file here again.  Add comment.
	(readdir_get_ino): Keep handle in created path_conv and drop
	opening file.
	* ntdll.h (wait_pending): New helper function.
	* path.cc (symlink_info::check): Drop unused 'opt' parameter from
	declaration.  Add path_conv_handle argument.
	(path_conv::check): Make sure conv_handle is closed.  Keep
	PC_KEEP_HANDLE flag in pflags_or.  Accommodate call to sym.check to
	new args.
	(path_conv::~path_conv): Close conv_handle.
	(symlink_info::check_shortcut): Don't re-open file here, just use
	incoming handle.  Drop goto's and label out.
	(symlink_info::check_sysfile): Don't re-open file here, just use
	incoming handle.  Keep track of file position to accommodate the fact
	that file has been opened asynchronously in calling function.
	(symlink_info::check_nfs_symlink): Don't re-open file here, just use
	incoming handle.
	(symlink_info::check): Drop unused 'opt' parameter.  Add
	path_conv_handle argument.  Always try to open file with GENERIC_READ
	rights first to allow reading file content w/o having to re-open the
	file.  Drop back to READ_CONTROL | FILE_READ_ATTRIBUTES otherwise.
	Call symlink test functions (except for check_reparse_point) only if
	file could be opened with GENERIC_READ.  Keep file handle open if
	PC_KEEP_HANDLE is set in pflags.
	* path.h (enum pathconv_arg): Add PC_KEEP_HANDLE flag.
	(class path_conv_handle): New class.
	(class path_conv): Add conv_handle member.
	(path_conv::operator =): Duplicate conv_handle.
	(path_conv::handle): New method.
	(path_conv::access): New method.
	(path_conv::reset_conv_handle): New method.
	(path_conv::close_conv_handle): New method.
This commit is contained in:
Corinna Vinschen
2010-06-15 12:05:15 +00:00
parent 51ec3f5c98
commit 5a0d1edba4
10 changed files with 260 additions and 157 deletions

View File

@ -57,6 +57,7 @@ enum pathconv_arg
PC_CHECK_EA = 0x0040,
PC_POSIX = 0x0080,
PC_NOWARN = 0x0100,
PC_KEEP_HANDLE = 0x00400000,
PC_NO_ACCESS_CHECK = 0x00800000
};
@ -86,6 +87,33 @@ enum path_types
PATH_SOCKET = 0x40000000
};
class path_conv_handle
{
HANDLE hdl;
ACCESS_MASK acc;
public:
path_conv_handle () : hdl (NULL), acc (0) {}
inline void set (HANDLE h, ACCESS_MASK a) { hdl = h; acc = a; }
inline void close ()
{
if (hdl)
CloseHandle (hdl);
set (NULL, 0);
}
inline void dup (path_conv_handle &pch)
{
if (!DuplicateHandle (GetCurrentProcess (), pch.handle (),
GetCurrentProcess (), &hdl,
0, TRUE, DUPLICATE_SAME_ACCESS))
{
hdl = NULL;
acc = 0;
}
}
inline HANDLE handle () const { return hdl; }
inline ACCESS_MASK access () const { return acc; }
};
class symlink_info;
class path_conv
@ -98,6 +126,7 @@ class path_conv
void add_ext_from_sym (symlink_info&);
DWORD symlink_length;
const char *path;
path_conv_handle conv_handle;
public:
unsigned path_flags;
const char *known_suffix;
@ -220,6 +249,7 @@ class path_conv
{
memcpy (this, &pc, sizeof pc);
path = cstrdup (pc.path);
conv_handle.dup (pc.conv_handle);
normalized_path = cstrdup(pc.normalized_path);
wide_path = NULL;
return *this;
@ -250,6 +280,11 @@ class path_conv
}
bool is_binary ();
HANDLE handle () const { return conv_handle.handle (); }
ACCESS_MASK access () const { return conv_handle.access (); }
void reset_conv_handle () { conv_handle.set (NULL, 0); }
void close_conv_handle () { conv_handle.close (); }
__ino64_t get_ino_by_handle (HANDLE h);
#if 0 /* obsolete, method still exists in fhandler_disk_file.cc */
unsigned __stdcall ndisk_links (DWORD);