Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-05-20 19:11:23 +0400
committerCorinna Vinschen <corinna@vinschen.de>2008-05-20 19:11:23 +0400
commitfe6934da140da55db628d5f940e4bddbfd06a960 (patch)
tree5b69355ddcd6e6469f1f7b0be1022105d3be677c /winsup/cygwin/fhandler.cc
parent2f33b79950a24de3307e62aaa678ade9a9c11089 (diff)
* Makefile.in (DLL_OFILES): Add nfs.o.
* fhandler.cc (fhandler_base::open): Open files on NFS shares with correct access flags and EAs. * fhandler.h (fhandler_base::fstat_by_nfs_ea): Declare. * fhandler_disk_file.cc (fhandler_base::fstat_by_nfs_ea): New method. (fhandler_base::fstat_by_handle): Call fstat_by_nfs_ea for files on NFS shares. (fhandler_disk_file::fchmod): Use NFS specific method to set mode for files on NFS shares. Don't overrule errno from call to set_file_attribute with errno from NtSetInformationFile call. (fhandler_disk_file::fchown): Add comment. * mount.cc (fillout_mntent): Accommodate change in second parameter to fs_info::update. * nfs.cc: New file. * nfs.h: New file. * path.cc (fs_info::update): Take handle instead of bool as second parameter. Use that handle if it's not NULL. Only close handle if it has been opened here. Use static defined buffers instead of alloca'd buffers. (path_conv::check): Call symlink_info::check with reference to fs. Don't call fs.update here if file exists. (conv_path_list): Prefer tmp_pathbuf buffer over using alloca. (symlink_worker): Use NFS specific method to create symlinks on NFS shares. Prefer tmp_pathbuf buffer over using alloca. (symlink_info::check_shortcut): Reopen file from incoming handle with necessary FILE_GENERIC_READ flag. Prefer tmp_pathbuf buffer over using alloca. (symlink_info::check_sysfile): Ditto. (symlink_info::check_reparse_point): Use tmp_pathbuf buffer to allocate REPARSE_DATA_BUFFER. (symlink_info::check_nfs_symlink): New method. (enum symlink_t): Remove. (symlink_info::check): Don't use NtQueryAttributesFile. Rather, open file with necessary access flags and call NtQueryInformationFile. Fix error handling in case file can't be opened. For existing files, call fs_info::update here. Restructure symlink checking to accommodate the fact that the file is already open. Add case for NFS symlinks. * path.h (fs_info::update): Take handle instead of bool as second parameter.
Diffstat (limited to 'winsup/cygwin/fhandler.cc')
-rw-r--r--winsup/cygwin/fhandler.cc37
1 files changed, 36 insertions, 1 deletions
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index e38a58226..4d4d0d83d 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -28,6 +28,7 @@ details. */
#include "ntdll.h"
#include "cygtls.h"
#include "sigproc.h"
+#include "nfs.h"
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
@@ -469,6 +470,8 @@ fhandler_base::open (int flags, mode_t mode)
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
NTSTATUS status;
+ PFILE_FULL_EA_INFORMATION p = NULL;
+ ULONG plen = 0;
syscall_printf ("(%S, %p)", pc.get_nt_native_path (), flags);
@@ -522,6 +525,18 @@ fhandler_base::open (int flags, mode_t mode)
break;
}
+ if (query_open () && pc.fs_is_nfs ())
+ {
+ /* Make sure we can read EAs of files on an NFS share. Also make
+ sure that we're going to act on the file itself, even if it'a
+ a symlink. */
+ access |= FILE_READ_EA;
+ if (query_open () >= query_write_control)
+ access |= FILE_WRITE_EA;
+ plen = sizeof nfs_aol_ffei;
+ p = (PFILE_FULL_EA_INFORMATION) &nfs_aol_ffei;
+ }
+
if ((flags & O_TRUNC) && ((flags & O_ACCMODE) != O_RDONLY))
{
if (flags & O_CREAT)
@@ -578,13 +593,33 @@ fhandler_base::open (int flags, mode_t mode)
set_security_attribute (mode, &sa, sd);
attr.SecurityDescriptor = sa.lpSecurityDescriptor;
}
+ else if (pc.fs_is_nfs ())
+ {
+ /* When creating a file on an NFS share, we have to set the
+ file mode by writing a NFS fattr3 structure with the
+ correct mode bits set. */
+ access |= FILE_WRITE_EA;
+ plen = sizeof (FILE_FULL_EA_INFORMATION) + sizeof (NFS_V3_ATTR)
+ + sizeof (fattr3);
+ p = (PFILE_FULL_EA_INFORMATION) alloca (plen);
+ p->NextEntryOffset = 0;
+ p->Flags = 0;
+ p->EaNameLength = sizeof (NFS_V3_ATTR) - 1;
+ p->EaValueLength = sizeof (fattr3);
+ strcpy (p->EaName, NFS_V3_ATTR);
+ fattr3 *nfs_attr = (fattr3 *) (p->EaName
+ + p->EaNameLength + 1);
+ memset (nfs_attr, 0, sizeof (fattr3));
+ nfs_attr->type = NF3REG;
+ nfs_attr->mode = mode;
+ }
/* The file attributes are needed for later use in, e.g. fchmod. */
pc.file_attributes (file_attributes);
}
}
status = NtCreateFile (&x, access, &attr, &io, NULL, file_attributes, shared,
- create_disposition, create_options, NULL, 0);
+ create_disposition, create_options, p, plen);
if (!NT_SUCCESS (status))
{
/* Trying to create a directory should return EISDIR, not ENOENT. */