summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog26
-rw-r--r--winsup/cygwin/dir.cc2
-rw-r--r--winsup/cygwin/fhandler.cc161
-rw-r--r--winsup/cygwin/fhandler.h45
-rw-r--r--winsup/cygwin/fhandler_mem.cc14
-rw-r--r--winsup/cygwin/fhandler_raw.cc16
-rw-r--r--winsup/cygwin/fhandler_tape.cc4
-rw-r--r--winsup/cygwin/syscalls.cc168
8 files changed, 223 insertions, 213 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index e125866c4..d09b8a5c5 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,29 @@
+Thu Oct 4 23:17:49 2001 Christopher Faylor <cgf@cygnus.com>
+
+ Add second path_conv * argument to fstat()s throughout.
+ * fhandler.h: Change read and fstat to regparm/stdcall throughout.
+ (fhandler_base::fstat): Just declare. Don't define.
+ (fhandler_disk_file::fstat_helper): Declare.
+ * fhandler.cc (fhandler_base::fstat): Move here from fhandler.h, adapt
+ from former stat_dev().
+ (fhandler_disk_file::fstat): Move most of the disk-file-specific logic
+ from stat_worker to here. Use fstat_helper to derive final fstat
+ output.
+ (fhandler_disk_file::fstat_helper): New method, renamed from former
+ fstat method.
+ (num_entries): Moved here from syscalls.cc.
+ * fhandler_mem.cc (fhandler_dev_mem::fstat): Use base class to
+ initialize most stuff. Invert has_physical_mem_access test for
+ establishing permissions.
+ * fhandler_raw.cc (fhandler_dev_raw::fstat): Eliminate unneed test and
+ memory clearing. Use base class to initialize most stuff.
+ * syscalls.cc (stat_dev): Eliminate.
+ (stat_worker): Simply call fstat method to generate fstat output. Move
+ all device specific code to appropriate fstats.
+
+ * dir.cc (opendir): Pass correct arg to stat_worker to allow following
+ symlinks.
+
Thu Oct 4 21:37:57 2001 Christopher Faylor <cgf@cygnus.com>
* spawn.cc (perhaps_suffix): Return NULL on non-existence of file as
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index 39ec9e9d9..6ca1695ed 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -85,7 +85,7 @@ opendir (const char *dirname)
path_conv real_dirname;
- if (stat_worker (dirname, &statbuf, 1, &real_dirname) == -1)
+ if (stat_worker (dirname, &statbuf, 0, &real_dirname) == -1)
goto failed;
if (!(statbuf.st_mode & S_IFDIR))
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 0bad75cc9..6e2db18df 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -24,6 +24,8 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "shared_info.h"
+#include "sigproc.h"
+#include "pinfo.h"
#include <assert.h>
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
@@ -847,15 +849,168 @@ rootdir(char *full_path)
return root;
}
+int __stdcall
+fhandler_base::fstat (struct stat *buf, path_conv *)
+{
+ switch (get_device ())
+ {
+ case FH_PIPEW:
+ buf->st_mode = STD_WBITS | S_IWGRP | S_IWOTH;
+ break;
+ case FH_PIPER:
+ buf->st_mode = STD_RBITS;
+ break;
+ default:
+ buf->st_mode = STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
+ break;
+ }
+
+ buf->st_mode |= get_device () == FH_FLOPPY ? S_IFBLK : S_IFCHR;
+ buf->st_nlink = 1;
+ buf->st_blksize = S_BLKSIZE;
+ buf->st_dev = buf->st_rdev = FHDEVN (get_device ()) << 8 | (get_unit () & 0xff);
+ buf->st_ino = get_namehash ();
+ buf->st_atime = buf->st_mtime = buf->st_ctime = time (NULL);
+ return 0;
+}
+
+static int
+num_entries (const char *win32_name)
+{
+ WIN32_FIND_DATA buf;
+ HANDLE handle;
+ char buf1[MAX_PATH];
+ int count = 0;
+
+ strcpy (buf1, win32_name);
+ int len = strlen (buf1);
+ if (len == 0 || isdirsep (buf1[len - 1]))
+ strcat (buf1, "*");
+ else
+ strcat (buf1, "/*"); /* */
+
+ handle = FindFirstFileA (buf1, &buf);
+
+ if (handle == INVALID_HANDLE_VALUE)
+ return 0;
+ count ++;
+ while (FindNextFileA (handle, &buf))
+ {
+ if ((buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ count ++;
+ }
+ FindClose (handle);
+ return count;
+}
+
int
-fhandler_disk_file::fstat (struct stat *buf)
+fhandler_disk_file::fstat (struct stat *buf, path_conv *pc)
+{
+ int res = -1;
+ int oret;
+ uid_t uid;
+ gid_t gid;
+ int open_flags = O_RDONLY | O_BINARY | O_DIROPEN;
+
+ if (!pc)
+ return fstat_helper (buf);
+
+ if ((oret = open (pc, open_flags, 0)))
+ /* ok */;
+ else
+ {
+ int ntsec_atts = 0;
+ /* If we couldn't open the file, try a "query open" with no permissions.
+ This will allow us to determine *some* things about the file, at least. */
+ set_query_open (TRUE);
+ if ((oret = open (pc, open_flags, 0)))
+ /* ok */;
+ else if (allow_ntsec && pc->has_acls () && get_errno () == EACCES
+ && !get_file_attribute (TRUE, get_win32_name (), &ntsec_atts, &uid, &gid)
+ && !ntsec_atts && uid == myself->uid && gid == myself->gid)
+ {
+ /* Check a special case here. If ntsec is ON it happens
+ that a process creates a file using mode 000 to disallow
+ other processes access. In contrast to UNIX, this results
+ in a failing open call in the same process. Check that
+ case. */
+ set_file_attribute (TRUE, get_win32_name (), 0400);
+ oret = open (pc, open_flags, 0);
+ set_file_attribute (TRUE, get_win32_name (), ntsec_atts);
+ }
+ }
+ if (oret)
+ {
+ res = fstat_helper (buf);
+ /* The number of links to a directory includes the
+ number of subdirectories in the directory, since all
+ those subdirectories point to it.
+ This is too slow on remote drives, so we do without it and
+ set the number of links to 2. */
+ /* Unfortunately the count of 2 confuses `find (1)' command. So
+ let's try it with `1' as link count. */
+ if (pc->isdir ())
+ buf->st_nlink = (pc->isremote ()
+ ? 1 : num_entries (pc->get_win32 ()));
+ close ();
+ }
+ else if (pc->exists ())
+ {
+ /* Unfortunately, the above open may fail if the file exists, though.
+ So we have to care for this case here, too. */
+ WIN32_FIND_DATA wfd;
+ HANDLE handle;
+ buf->st_nlink = 1;
+ if (pc->isdir () && pc->isremote ())
+ buf->st_nlink = num_entries (pc->get_win32 ());
+ buf->st_dev = FHDEVN (FH_DISK) << 8;
+ buf->st_ino = hash_path_name (0, pc->get_win32 ());
+ if (pc->isdir ())
+ buf->st_mode = S_IFDIR;
+ else if (pc->issymlink ())
+ buf->st_mode = S_IFLNK;
+ else if (pc->issocket ())
+ buf->st_mode = S_IFSOCK;
+ else
+ buf->st_mode = S_IFREG;
+ if (!pc->has_acls ()
+ || get_file_attribute (TRUE, pc->get_win32 (),
+ &buf->st_mode,
+ &buf->st_uid, &buf->st_gid))
+ {
+ buf->st_mode |= STD_RBITS | STD_XBITS;
+ if (!(pc->has_attribute (FILE_ATTRIBUTE_READONLY)))
+ buf->st_mode |= STD_WBITS;
+ if (pc->issymlink ())
+ buf->st_mode |= S_IRWXU | S_IRWXG | S_IRWXO;
+ get_file_attribute (FALSE, pc->get_win32 (),
+ NULL, &buf->st_uid, &buf->st_gid);
+ }
+ if ((handle = FindFirstFile (pc->get_win32 (), &wfd))
+ != INVALID_HANDLE_VALUE)
+ {
+ buf->st_atime = to_time_t (&wfd.ftLastAccessTime);
+ buf->st_mtime = to_time_t (&wfd.ftLastWriteTime);
+ buf->st_ctime = to_time_t (&wfd.ftCreationTime);
+ buf->st_size = wfd.nFileSizeLow;
+ buf->st_blksize = S_BLKSIZE;
+ buf->st_blocks = ((unsigned long) buf->st_size +
+ S_BLKSIZE-1) / S_BLKSIZE;
+ FindClose (handle);
+ }
+ res = 0;
+ }
+
+ return res;
+}
+
+int
+fhandler_disk_file::fstat_helper (struct stat *buf)
{
int res = 0; // avoid a compiler warning
BY_HANDLE_FILE_INFORMATION local;
save_errno saved_errno;
- memset (buf, 0, sizeof (*buf));
-
/* NT 3.51 seems to have a bug when attempting to get vol serial
numbers. This loop gets around this. */
for (int i = 0; i < 2; i++)
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 6f80b61b5..5a07c43c9 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -313,11 +313,11 @@ public:
virtual int open (path_conv * real_path, int flags, mode_t mode = 0);
virtual int close ();
- virtual int fstat (struct stat *buf) { return stat_dev (get_device (), get_unit (), get_namehash (), buf); }
+ virtual int __stdcall fstat (struct stat *buf, path_conv *) __attribute__ ((regparm (2)));
virtual int ioctl (unsigned int cmd, void *);
virtual int fcntl (int cmd, void *);
virtual char const * ttyname () { return get_name(); }
- virtual int read (void *ptr, size_t len);
+ virtual int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
virtual int write (const void *ptr, size_t len);
virtual off_t lseek (off_t offset, int whence);
virtual int lock (int, struct flock *);
@@ -397,7 +397,7 @@ public:
void set_shutdown_write () {FHSETF (SHUTWR);}
int write (const void *ptr, size_t len);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
int ioctl (unsigned int cmd, void *);
int fcntl (int cmd, void *);
off_t lseek (off_t, int) { return 0; }
@@ -438,7 +438,7 @@ public:
select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
void set_close_on_exec (int val);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
int close ();
void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);}
int dup (fhandler_base *child);
@@ -481,7 +481,7 @@ public:
int raw_read (void *ptr, size_t ulen);
int raw_write (const void *ptr, size_t ulen);
- int fstat (struct stat *buf);
+ int __stdcall fstat (struct stat *buf, path_conv *) __attribute__ ((regparm (2)));
int dup (fhandler_base *child);
@@ -522,16 +522,16 @@ protected:
public:
fhandler_dev_tape (const char *name, int unit);
- virtual int open (path_conv *, int flags, mode_t mode = 0);
- virtual int close (void);
+ int open (path_conv *, int flags, mode_t mode = 0);
+ int close (void);
- virtual off_t lseek (off_t offset, int whence);
+ off_t lseek (off_t offset, int whence);
- virtual int fstat (struct stat *buf);
+ int __stdcall fstat (struct stat *buf, path_conv *) __attribute__ ((regparm (2)));
- virtual int dup (fhandler_base *child);
+ int dup (fhandler_base *child);
- virtual int ioctl (unsigned int cmd, void *buf);
+ int ioctl (unsigned int cmd, void *buf);
private:
int tape_write_marks (int marktype, DWORD len);
@@ -557,7 +557,8 @@ public:
int close ();
int lock (int, struct flock *);
BOOL is_device () { return FALSE; }
- int fstat (struct stat *buf);
+ int __stdcall fstat (struct stat *buf, path_conv *pc) __attribute__ ((regparm (2)));
+ int __stdcall fstat_helper (struct stat *buf) __attribute__ ((regparm (1)));
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
int munmap (HANDLE h, caddr_t addr, size_t len);
@@ -747,7 +748,7 @@ public:
int write (const void *ptr, size_t len);
void doecho (const void *str, DWORD len) { (void) write (str, len); }
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
int close ();
int tcflush (int);
@@ -818,7 +819,7 @@ public:
int open (path_conv *, int flags, mode_t mode = 0);
int write (const void *ptr, size_t len);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
void init (HANDLE, DWORD, mode_t);
int tcsetattr (int a, const struct termios *t);
@@ -845,7 +846,7 @@ public:
int accept_input ();
int open (path_conv *, int flags, mode_t mode = 0);
int write (const void *ptr, size_t len);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
int close ();
int tcsetattr (int a, const struct termios *t);
@@ -891,7 +892,7 @@ public:
fhandler_dev_zero (const char *name);
int open (path_conv *, int flags, mode_t mode = 0);
int write (const void *ptr, size_t len);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
off_t lseek (off_t offset, int whence);
int close (void);
@@ -914,7 +915,7 @@ public:
int get_unit () { return unit; }
int open (path_conv *, int flags, mode_t mode = 0);
int write (const void *ptr, size_t len);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
off_t lseek (off_t offset, int whence);
int close (void);
int dup (fhandler_base *child);
@@ -935,10 +936,10 @@ public:
int open (path_conv *, int flags, mode_t mode = 0);
int write (const void *ptr, size_t ulen);
- int read (void *ptr, size_t ulen);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
off_t lseek (off_t offset, int whence);
int close (void);
- int fstat (struct stat *buf);
+ int __stdcall fstat (struct stat *buf, path_conv *) __attribute__ ((regparm (2)));
int dup (fhandler_base *child);
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
@@ -957,7 +958,7 @@ public:
int is_windows (void) { return 1; }
int open (path_conv *, int flags, mode_t mode = 0);
int write (const void *ptr, size_t len);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
off_t lseek (off_t offset, int whence);
int close (void);
@@ -982,7 +983,7 @@ public:
int is_windows (void) { return 1; }
int open (path_conv *, int flags, mode_t mode = 0);
int write (const void *ptr, size_t len);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
int ioctl (unsigned int cmd, void *);
off_t lseek (off_t, int) { return 0; }
int close (void) { return 0; }
@@ -1009,7 +1010,7 @@ public:
int open (path_conv *, int flags, mode_t mode = 0);
int write (const void *ptr, size_t len);
- int read (void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (2)));
int ioctl (unsigned int cmd, void *);
off_t lseek (off_t, int);
int close (void);
diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc
index d99ab1c3d..7a839e99d 100644
--- a/winsup/cygwin/fhandler_mem.cc
+++ b/winsup/cygwin/fhandler_mem.cc
@@ -403,23 +403,15 @@ fhandler_dev_mem::fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
}
int
-fhandler_dev_mem::fstat (struct stat *buf)
+fhandler_dev_mem::fstat (struct stat *buf, path_conv *pc)
{
- if (!buf)
- {
- set_errno (EINVAL);
- return -1;
- }
-
- memset (buf, 0, sizeof *buf);
+ this->fhandler_base::fstat (buf, pc);
buf->st_mode = S_IFCHR;
- if (!wincap.has_physical_mem_access ())
+ if (wincap.has_physical_mem_access ())
buf->st_mode |= S_IRUSR | S_IWUSR |
S_IRGRP | S_IWGRP |
S_IROTH | S_IWOTH;
- buf->st_nlink = 1;
buf->st_blksize = getpagesize ();
- buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
return 0;
}
diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc
index 53d59060a..f487ddd3b 100644
--- a/winsup/cygwin/fhandler_raw.cc
+++ b/winsup/cygwin/fhandler_raw.cc
@@ -156,22 +156,10 @@ fhandler_dev_raw::close (void)
}
int
-fhandler_dev_raw::fstat (struct stat *buf)
+fhandler_dev_raw::fstat (struct stat *buf, path_conv *pc)
{
- if (!buf)
- {
- set_errno (EINVAL);
- return -1;
- }
-
- memset (buf, 0, sizeof *buf);
- buf->st_mode = S_IFCHR |
- S_IRUSR | S_IWUSR |
- S_IRGRP | S_IWGRP |
- S_IROTH | S_IWOTH;
- buf->st_nlink = 1;
+ this->fhandler_base::fstat (buf, pc);
buf->st_blksize = devbuf ? devbufsiz : 1;
- buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
return 0;
}
diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc
index 8b658924e..a2bf46b8e 100644
--- a/winsup/cygwin/fhandler_tape.cc
+++ b/winsup/cygwin/fhandler_tape.cc
@@ -148,11 +148,11 @@ fhandler_dev_tape::close (void)
}
int
-fhandler_dev_tape::fstat (struct stat *buf)
+fhandler_dev_tape::fstat (struct stat *buf, path_conv *pc)
{
int ret;
- if (! (ret = fhandler_dev_raw::fstat (buf)))
+ if (!(ret = fhandler_dev_raw::fstat (buf, pc)))
{
struct mtget get;
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index aa5afc35a..d41cb2b10 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -952,36 +952,6 @@ fchmod (int fd, mode_t mode)
return chmod (path, mode);
}
-/* Cygwin internal */
-static int
-num_entries (const char *win32_name)
-{
- WIN32_FIND_DATA buf;
- HANDLE handle;
- char buf1[MAX_PATH];
- int count = 0;
-
- strcpy (buf1, win32_name);
- int len = strlen (buf1);
- if (len == 0 || isdirsep (buf1[len - 1]))
- strcat (buf1, "*");
- else
- strcat (buf1, "/*"); /* */
-
- handle = FindFirstFileA (buf1, &buf);
-
- if (handle == INVALID_HANDLE_VALUE)
- return 0;
- count ++;
- while (FindNextFileA (handle, &buf))
- {
- if ((buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- count ++;
- }
- FindClose (handle);
- return count;
-}
-
extern "C" int
_fstat (int fd, struct stat *buf)
{
@@ -997,7 +967,7 @@ _fstat (int fd, struct stat *buf)
else
{
memset (buf, 0, sizeof (struct stat));
- r = cygheap->fdtab[fd]->fstat (buf);
+ r = cygheap->fdtab[fd]->fstat (buf, NULL);
syscall_printf ("%d = fstat (%d, %x)", r, fd, buf);
}
@@ -1033,32 +1003,6 @@ sync ()
return 0;
}
-int __stdcall
-stat_dev (DWORD devn, int unit, unsigned long ino, struct stat *buf)
-{
- sigframe thisframe (mainthread);
- switch (devn)
- {
- case FH_PIPEW:
- buf->st_mode = STD_WBITS | S_IWGRP | S_IWOTH;
- break;
- case FH_PIPER:
- buf->st_mode = STD_RBITS;
- break;
- default:
- buf->st_mode = STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
- break;
- }
-
- buf->st_mode |= devn == FH_FLOPPY ? S_IFBLK : S_IFCHR;
- buf->st_blksize = S_BLKSIZE;
- buf->st_nlink = 1;
- buf->st_dev = buf->st_rdev = FHDEVN (devn) << 8 | (unit & 0xff);
- buf->st_ino = ino;
- buf->st_atime = buf->st_mtime = buf->st_ctime = time (NULL);
- return 0;
-}
-
suffix_info stat_suffixes[] =
{
suffix_info ("", 1),
@@ -1071,18 +1015,13 @@ int __stdcall
stat_worker (const char *name, struct stat *buf, int nofollow, path_conv *pc)
{
int res = -1;
- int oret;
- uid_t uid;
- gid_t gid;
path_conv real_path;
fhandler_base *fh = NULL;
if (!pc)
pc = &real_path;
- MALLOC_CHECK;
- int open_flags = O_RDONLY | O_BINARY | O_DIROPEN
- | (nofollow ? O_NOSYMLINK : 0);
+ MALLOC_CHECK;
if (check_null_invalid_struct_errno (buf))
goto done;
@@ -1093,110 +1032,19 @@ stat_worker (const char *name, struct stat *buf, int nofollow, path_conv *pc)
| PC_FULL, stat_suffixes);
if (pc->error)
{
+ debug_printf ("got %d error from build_fhandler_from_name", pc->error);
set_errno (pc->error);
- goto done;
}
-
- debug_printf ("(%s, %p, %d, %p)", name, buf, nofollow, pc);
-
- memset (buf, 0, sizeof (struct stat));
-
- if (pc->is_device ())
- return stat_dev (pc->get_devn (), pc->get_unitn (),
- hash_path_name (0, pc->get_win32 ()), buf);
-
- debug_printf ("%d = file_attributes for '%s'", (DWORD) real_path,
- (char *) real_path);
-
- if ((oret = fh->open (pc, open_flags, 0)))
- /* ok */;
else
{
- int ntsec_atts = 0;
- /* If we couldn't open the file, try a "query open" with no permissions.
- This will allow us to determine *some* things about the file, at least. */
- fh->set_query_open (TRUE);
- if ((oret = fh->open (pc, open_flags, 0)))
- /* ok */;
- else if (allow_ntsec && pc->has_acls () && get_errno () == EACCES
- && !get_file_attribute (TRUE, real_path, &ntsec_atts, &uid, &gid)
- && !ntsec_atts && uid == myself->uid && gid == myself->gid)
- {
- /* Check a special case here. If ntsec is ON it happens
- that a process creates a file using mode 000 to disallow
- other processes access. In contrast to UNIX, this results
- in a failing open call in the same process. Check that
- case. */
- set_file_attribute (TRUE, real_path, 0400);
- oret = fh->open (pc, open_flags, 0);
- set_file_attribute (TRUE, real_path, ntsec_atts);
- }
- }
- if (oret)
- {
- res = fh->fstat (buf);
- /* The number of links to a directory includes the
- number of subdirectories in the directory, since all
- those subdirectories point to it.
- This is too slow on remote drives, so we do without it and
- set the number of links to 2. */
- /* Unfortunately the count of 2 confuses `find (1)' command. So
- let's try it with `1' as link count. */
- if (pc->isdir ())
- buf->st_nlink = (pc->isremote ()
- ? 1 : num_entries (pc->get_win32 ()));
- fh->close ();
- }
- else if (pc->exists ())
- {
- /* Unfortunately, the above open may fail if the file exists, though.
- So we have to care for this case here, too. */
- WIN32_FIND_DATA wfd;
- HANDLE handle;
- buf->st_nlink = 1;
- if (pc->isdir () && pc->isremote ())
- buf->st_nlink = num_entries (pc->get_win32 ());
- buf->st_dev = FHDEVN (FH_DISK) << 8;
- buf->st_ino = hash_path_name (0, pc->get_win32 ());
- if (pc->isdir ())
- buf->st_mode = S_IFDIR;
- else if (pc->issymlink ())
- buf->st_mode = S_IFLNK;
- else if (pc->issocket ())
- buf->st_mode = S_IFSOCK;
- else
- buf->st_mode = S_IFREG;
- if (!pc->has_acls ()
- || get_file_attribute (TRUE, pc->get_win32 (),
- &buf->st_mode,
- &buf->st_uid, &buf->st_gid))
- {
- buf->st_mode |= STD_RBITS | STD_XBITS;
- if (!(pc->has_attribute (FILE_ATTRIBUTE_READONLY)))
- buf->st_mode |= STD_WBITS;
- if (pc->issymlink ())
- buf->st_mode |= S_IRWXU | S_IRWXG | S_IRWXO;
- get_file_attribute (FALSE, pc->get_win32 (),
- NULL, &buf->st_uid, &buf->st_gid);
- }
- if ((handle = FindFirstFile (pc->get_win32 (), &wfd))
- != INVALID_HANDLE_VALUE)
- {
- buf->st_atime = to_time_t (&wfd.ftLastAccessTime);
- buf->st_mtime = to_time_t (&wfd.ftLastWriteTime);
- buf->st_ctime = to_time_t (&wfd.ftCreationTime);
- buf->st_size = wfd.nFileSizeLow;
- buf->st_blksize = S_BLKSIZE;
- buf->st_blocks = ((unsigned long) buf->st_size +
- S_BLKSIZE-1) / S_BLKSIZE;
- FindClose (handle);
- }
- res = 0;
+ debug_printf ("(%s, %p, %d, %p), file_attributes %d", name, buf, nofollow,
+ pc, (DWORD) real_path);
+ memset (buf, 0, sizeof (struct stat));
+ res = fh->fstat (buf, pc);
+ delete fh;
}
done:
- if (fh)
- delete fh;
MALLOC_CHECK;
syscall_printf ("%d = (%s, %p)", res, name, buf);
return res;