aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/syscalls.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r--winsup/cygwin/syscalls.cc29
1 files changed, 26 insertions, 3 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 9d88b60..600c6c5 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1609,10 +1609,33 @@ lseek (int fd, off_t pos, int dir)
else
{
cygheap_fdget cfd (fd);
- if (cfd >= 0)
- res = cfd->lseek (pos, dir);
- else
+ if (cfd < 0)
res = -1;
+ else if (cfd->getdents_dir ())
+ {
+ if (dir != SEEK_SET && dir != SEEK_CUR) /* No SEEK_END */
+ {
+ set_errno (EINVAL);
+ res = -1;
+ }
+ else
+ {
+ long cur;
+
+ cur = cfd->telldir (cfd->getdents_dir ());
+ if (dir == SEEK_CUR && cur == 0)
+ res = cur;
+ else
+ {
+ if (dir == SEEK_CUR)
+ pos = cur + pos;
+ cfd->seekdir (cfd->getdents_dir (), pos);
+ res = pos;
+ }
+ }
+ }
+ else
+ res = cfd->lseek (pos, dir);
}
/* Can't use %R/%lR here since res is always 8 bytes */
syscall_printf (res == -1 ? "%D = lseek(%d, %D, %d), errno %d"