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>2012-04-02 15:18:45 +0400
committerCorinna Vinschen <corinna@vinschen.de>2012-04-02 15:18:45 +0400
commit949cc8b6403f04b82ab944e3884911513e31526c (patch)
treed5e29de5abb8196ed75bafdef8208bf28a95451e /winsup/cygwin/syscalls.cc
parentda8274643c9a765fd2aff0b5d3ee203b2f3a79d0 (diff)
* fhandler.h (fhandler_base::set_ino_and_dev): Declare.
* syscalls.cc (fhandler_base::set_ino_and_dev): New method to set st_ino, st_dev, and st_rdev for devices in a single spot. (fstat64): Call fhandler_base::set_ino_and_dev instead of setting st_ino, st_dev, and st_rdev here. (stat_worker): Ditto.
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r--winsup/cygwin/syscalls.cc50
1 files changed, 34 insertions, 16 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 80d22b232..2ef94dae6 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1585,6 +1585,38 @@ stat64_to_stat32 (struct __stat64 *src, struct __stat32 *dst)
dst->st_blocks = src->st_blocks;
}
+static struct __stat64 dev_st;
+static bool dev_st_inited;
+
+void
+fhandler_base::set_ino_and_dev (struct __stat64 *buf)
+{
+ if (!buf->st_ino)
+ buf->st_ino = get_ino ();
+ /* For /dev-based devices, st_dev must be set to the device number of /dev,
+ not it's own device major/minor numbers. What we do here to speed up
+ the process is to fetch the device number of /dev only once, liberally
+ assuming that /dev doesn't change over the lifetime of a process. */
+ if (!buf->st_dev)
+ {
+ if (!strncmp (dev ().name, "/dev/", 5))
+ {
+ if (!dev_st_inited)
+ {
+ stat64 ("/dev", &dev_st);
+ dev_st_inited = true;
+ }
+ buf->st_dev = dev_st.st_dev;
+ }
+ else
+ buf->st_dev = get_device ();
+ }
+ /* Only set st_rdev if it's a device. */
+ if (!buf->st_rdev && get_major () != DEV_VIRTFS_MAJOR
+ && get_major () != DEV_CYGDRIVE_MAJOR && get_major () != DEV_DEV_MAJOR)
+ buf->st_rdev = get_device ();
+}
+
extern "C" int
fstat64 (int fd, struct __stat64 *buf)
{
@@ -1598,14 +1630,7 @@ fstat64 (int fd, struct __stat64 *buf)
memset (buf, 0, sizeof (struct __stat64));
res = cfd->fstat (buf);
if (!res)
- {
- if (!buf->st_ino)
- buf->st_ino = cfd->get_ino ();
- if (!buf->st_dev)
- buf->st_dev = cfd->get_device ();
- if (!buf->st_rdev)
- buf->st_rdev = buf->st_dev;
- }
+ cfd->set_ino_and_dev (buf);
}
syscall_printf ("%R = fstat(%d, %p)", res, fd, buf);
@@ -1744,14 +1769,7 @@ stat_worker (path_conv &pc, struct __stat64 *buf)
memset (buf, 0, sizeof (*buf));
res = fh->fstat (buf);
if (!res)
- {
- if (!buf->st_ino)
- buf->st_ino = fh->get_ino ();
- if (!buf->st_dev)
- buf->st_dev = fh->get_device ();
- if (!buf->st_rdev)
- buf->st_rdev = buf->st_dev;
- }
+ fh->set_ino_and_dev (buf);
delete fh;
}
else