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.
This commit is contained in:
parent
291ae2c1e7
commit
8d817b0f9e
|
@ -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>
|
Thu Oct 4 21:37:57 2001 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
* spawn.cc (perhaps_suffix): Return NULL on non-existence of file as
|
* spawn.cc (perhaps_suffix): Return NULL on non-existence of file as
|
||||||
|
|
|
@ -85,7 +85,7 @@ opendir (const char *dirname)
|
||||||
|
|
||||||
path_conv real_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;
|
goto failed;
|
||||||
|
|
||||||
if (!(statbuf.st_mode & S_IFDIR))
|
if (!(statbuf.st_mode & S_IFDIR))
|
||||||
|
|
|
@ -24,6 +24,8 @@ details. */
|
||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
|
#include "sigproc.h"
|
||||||
|
#include "pinfo.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
||||||
|
@ -847,15 +849,168 @@ rootdir(char *full_path)
|
||||||
return root;
|
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
|
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
|
int res = 0; // avoid a compiler warning
|
||||||
BY_HANDLE_FILE_INFORMATION local;
|
BY_HANDLE_FILE_INFORMATION local;
|
||||||
save_errno saved_errno;
|
save_errno saved_errno;
|
||||||
|
|
||||||
memset (buf, 0, sizeof (*buf));
|
|
||||||
|
|
||||||
/* NT 3.51 seems to have a bug when attempting to get vol serial
|
/* NT 3.51 seems to have a bug when attempting to get vol serial
|
||||||
numbers. This loop gets around this. */
|
numbers. This loop gets around this. */
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
|
|
|
@ -313,11 +313,11 @@ public:
|
||||||
|
|
||||||
virtual int open (path_conv * real_path, int flags, mode_t mode = 0);
|
virtual int open (path_conv * real_path, int flags, mode_t mode = 0);
|
||||||
virtual int close ();
|
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 ioctl (unsigned int cmd, void *);
|
||||||
virtual int fcntl (int cmd, void *);
|
virtual int fcntl (int cmd, void *);
|
||||||
virtual char const * ttyname () { return get_name(); }
|
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 int write (const void *ptr, size_t len);
|
||||||
virtual off_t lseek (off_t offset, int whence);
|
virtual off_t lseek (off_t offset, int whence);
|
||||||
virtual int lock (int, struct flock *);
|
virtual int lock (int, struct flock *);
|
||||||
|
@ -397,7 +397,7 @@ public:
|
||||||
void set_shutdown_write () {FHSETF (SHUTWR);}
|
void set_shutdown_write () {FHSETF (SHUTWR);}
|
||||||
|
|
||||||
int write (const void *ptr, size_t len);
|
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 ioctl (unsigned int cmd, void *);
|
||||||
int fcntl (int cmd, void *);
|
int fcntl (int cmd, void *);
|
||||||
off_t lseek (off_t, int) { return 0; }
|
off_t lseek (off_t, int) { return 0; }
|
||||||
|
@ -438,7 +438,7 @@ public:
|
||||||
select_record *select_except (select_record *s);
|
select_record *select_except (select_record *s);
|
||||||
int ready_for_read (int fd, DWORD howlong, int ignra);
|
int ready_for_read (int fd, DWORD howlong, int ignra);
|
||||||
void set_close_on_exec (int val);
|
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 ();
|
int close ();
|
||||||
void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);}
|
void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);}
|
||||||
int dup (fhandler_base *child);
|
int dup (fhandler_base *child);
|
||||||
|
@ -481,7 +481,7 @@ public:
|
||||||
int raw_read (void *ptr, size_t ulen);
|
int raw_read (void *ptr, size_t ulen);
|
||||||
int raw_write (const 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);
|
int dup (fhandler_base *child);
|
||||||
|
|
||||||
|
@ -522,16 +522,16 @@ protected:
|
||||||
public:
|
public:
|
||||||
fhandler_dev_tape (const char *name, int unit);
|
fhandler_dev_tape (const char *name, int unit);
|
||||||
|
|
||||||
virtual int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
virtual int close (void);
|
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:
|
private:
|
||||||
int tape_write_marks (int marktype, DWORD len);
|
int tape_write_marks (int marktype, DWORD len);
|
||||||
|
@ -557,7 +557,8 @@ public:
|
||||||
int close ();
|
int close ();
|
||||||
int lock (int, struct flock *);
|
int lock (int, struct flock *);
|
||||||
BOOL is_device () { return FALSE; }
|
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);
|
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);
|
int munmap (HANDLE h, caddr_t addr, size_t len);
|
||||||
|
@ -747,7 +748,7 @@ public:
|
||||||
|
|
||||||
int write (const void *ptr, size_t len);
|
int write (const void *ptr, size_t len);
|
||||||
void doecho (const void *str, DWORD len) { (void) write (str, 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 close ();
|
||||||
|
|
||||||
int tcflush (int);
|
int tcflush (int);
|
||||||
|
@ -818,7 +819,7 @@ public:
|
||||||
|
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int write (const void *ptr, size_t len);
|
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);
|
void init (HANDLE, DWORD, mode_t);
|
||||||
|
|
||||||
int tcsetattr (int a, const struct termios *t);
|
int tcsetattr (int a, const struct termios *t);
|
||||||
|
@ -845,7 +846,7 @@ public:
|
||||||
int accept_input ();
|
int accept_input ();
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int write (const void *ptr, size_t len);
|
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 close ();
|
||||||
|
|
||||||
int tcsetattr (int a, const struct termios *t);
|
int tcsetattr (int a, const struct termios *t);
|
||||||
|
@ -891,7 +892,7 @@ public:
|
||||||
fhandler_dev_zero (const char *name);
|
fhandler_dev_zero (const char *name);
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int write (const void *ptr, size_t len);
|
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);
|
off_t lseek (off_t offset, int whence);
|
||||||
int close (void);
|
int close (void);
|
||||||
|
|
||||||
|
@ -914,7 +915,7 @@ public:
|
||||||
int get_unit () { return unit; }
|
int get_unit () { return unit; }
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int write (const void *ptr, size_t len);
|
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);
|
off_t lseek (off_t offset, int whence);
|
||||||
int close (void);
|
int close (void);
|
||||||
int dup (fhandler_base *child);
|
int dup (fhandler_base *child);
|
||||||
|
@ -935,10 +936,10 @@ public:
|
||||||
|
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int write (const void *ptr, size_t ulen);
|
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);
|
off_t lseek (off_t offset, int whence);
|
||||||
int close (void);
|
int close (void);
|
||||||
int fstat (struct stat *buf);
|
int __stdcall fstat (struct stat *buf, path_conv *) __attribute__ ((regparm (2)));
|
||||||
int dup (fhandler_base *child);
|
int dup (fhandler_base *child);
|
||||||
|
|
||||||
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off);
|
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 is_windows (void) { return 1; }
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int write (const void *ptr, size_t len);
|
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);
|
off_t lseek (off_t offset, int whence);
|
||||||
int close (void);
|
int close (void);
|
||||||
|
|
||||||
|
@ -982,7 +983,7 @@ public:
|
||||||
int is_windows (void) { return 1; }
|
int is_windows (void) { return 1; }
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int write (const void *ptr, size_t len);
|
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 ioctl (unsigned int cmd, void *);
|
||||||
off_t lseek (off_t, int) { return 0; }
|
off_t lseek (off_t, int) { return 0; }
|
||||||
int close (void) { return 0; }
|
int close (void) { return 0; }
|
||||||
|
@ -1009,7 +1010,7 @@ public:
|
||||||
|
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int write (const void *ptr, size_t len);
|
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 ioctl (unsigned int cmd, void *);
|
||||||
off_t lseek (off_t, int);
|
off_t lseek (off_t, int);
|
||||||
int close (void);
|
int close (void);
|
||||||
|
|
|
@ -403,23 +403,15 @@ fhandler_dev_mem::fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_dev_mem::fstat (struct stat *buf)
|
fhandler_dev_mem::fstat (struct stat *buf, path_conv *pc)
|
||||||
{
|
{
|
||||||
if (!buf)
|
this->fhandler_base::fstat (buf, pc);
|
||||||
{
|
|
||||||
set_errno (EINVAL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset (buf, 0, sizeof *buf);
|
|
||||||
buf->st_mode = S_IFCHR;
|
buf->st_mode = S_IFCHR;
|
||||||
if (!wincap.has_physical_mem_access ())
|
if (wincap.has_physical_mem_access ())
|
||||||
buf->st_mode |= S_IRUSR | S_IWUSR |
|
buf->st_mode |= S_IRUSR | S_IWUSR |
|
||||||
S_IRGRP | S_IWGRP |
|
S_IRGRP | S_IWGRP |
|
||||||
S_IROTH | S_IWOTH;
|
S_IROTH | S_IWOTH;
|
||||||
buf->st_nlink = 1;
|
|
||||||
buf->st_blksize = getpagesize ();
|
buf->st_blksize = getpagesize ();
|
||||||
buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,22 +156,10 @@ fhandler_dev_raw::close (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_dev_raw::fstat (struct stat *buf)
|
fhandler_dev_raw::fstat (struct stat *buf, path_conv *pc)
|
||||||
{
|
{
|
||||||
if (!buf)
|
this->fhandler_base::fstat (buf, pc);
|
||||||
{
|
|
||||||
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;
|
|
||||||
buf->st_blksize = devbuf ? devbufsiz : 1;
|
buf->st_blksize = devbuf ? devbufsiz : 1;
|
||||||
buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,11 +148,11 @@ fhandler_dev_tape::close (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_dev_tape::fstat (struct stat *buf)
|
fhandler_dev_tape::fstat (struct stat *buf, path_conv *pc)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (! (ret = fhandler_dev_raw::fstat (buf)))
|
if (!(ret = fhandler_dev_raw::fstat (buf, pc)))
|
||||||
{
|
{
|
||||||
struct mtget get;
|
struct mtget get;
|
||||||
|
|
||||||
|
|
|
@ -952,36 +952,6 @@ fchmod (int fd, mode_t mode)
|
||||||
return chmod (path, 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
|
extern "C" int
|
||||||
_fstat (int fd, struct stat *buf)
|
_fstat (int fd, struct stat *buf)
|
||||||
{
|
{
|
||||||
|
@ -997,7 +967,7 @@ _fstat (int fd, struct stat *buf)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset (buf, 0, sizeof (struct stat));
|
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);
|
syscall_printf ("%d = fstat (%d, %x)", r, fd, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,32 +1003,6 @@ sync ()
|
||||||
return 0;
|
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 stat_suffixes[] =
|
||||||
{
|
{
|
||||||
suffix_info ("", 1),
|
suffix_info ("", 1),
|
||||||
|
@ -1071,18 +1015,13 @@ int __stdcall
|
||||||
stat_worker (const char *name, struct stat *buf, int nofollow, path_conv *pc)
|
stat_worker (const char *name, struct stat *buf, int nofollow, path_conv *pc)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
int oret;
|
|
||||||
uid_t uid;
|
|
||||||
gid_t gid;
|
|
||||||
path_conv real_path;
|
path_conv real_path;
|
||||||
fhandler_base *fh = NULL;
|
fhandler_base *fh = NULL;
|
||||||
|
|
||||||
if (!pc)
|
if (!pc)
|
||||||
pc = &real_path;
|
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))
|
if (check_null_invalid_struct_errno (buf))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -1093,110 +1032,19 @@ stat_worker (const char *name, struct stat *buf, int nofollow, path_conv *pc)
|
||||||
| PC_FULL, stat_suffixes);
|
| PC_FULL, stat_suffixes);
|
||||||
if (pc->error)
|
if (pc->error)
|
||||||
{
|
{
|
||||||
|
debug_printf ("got %d error from build_fhandler_from_name", pc->error);
|
||||||
set_errno (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
|
else
|
||||||
{
|
{
|
||||||
int ntsec_atts = 0;
|
debug_printf ("(%s, %p, %d, %p), file_attributes %d", name, buf, nofollow,
|
||||||
/* If we couldn't open the file, try a "query open" with no permissions.
|
pc, (DWORD) real_path);
|
||||||
This will allow us to determine *some* things about the file, at least. */
|
memset (buf, 0, sizeof (struct stat));
|
||||||
fh->set_query_open (TRUE);
|
res = fh->fstat (buf, pc);
|
||||||
if ((oret = fh->open (pc, open_flags, 0)))
|
delete fh;
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (fh)
|
|
||||||
delete fh;
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
syscall_printf ("%d = (%s, %p)", res, name, buf);
|
syscall_printf ("%d = (%s, %p)", res, name, buf);
|
||||||
return res;
|
return res;
|
||||||
|
|
Loading…
Reference in New Issue