summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-08-12 06:56:09 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-08-12 06:56:09 +0000
commitedcb8975ac13b9b0dd392b3a8c18cef64546b010 (patch)
tree5acf171b97b3bb42bf8f4ee3581dd79f3f427637
parent0fe7592d74ce3553a949af420455362564b8e7b7 (diff)
* configure.in, bcc32/Makefile.sub, win32/Makefile.sub, win32/dir.h,
win32/win32.c, win32/win32.h: large file support for win32. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10720 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--bcc32/Makefile.sub7
-rw-r--r--configure.in10
-rw-r--r--win32/Makefile.sub7
-rw-r--r--win32/dir.h4
-rw-r--r--win32/win32.c201
-rw-r--r--win32/win32.h37
7 files changed, 248 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 1cdf0d2330..faa34e3189 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Aug 12 15:55:32 2006 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in, bcc32/Makefile.sub, win32/Makefile.sub, win32/dir.h,
+ win32/win32.c, win32/win32.h: large file support for win32.
+
Fri Aug 11 15:39:25 2006 Eric Hodel <drbrain@segment7.net>
* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#find_body): Make RDoc
diff --git a/bcc32/Makefile.sub b/bcc32/Makefile.sub
index b177ca023d..4c1c382891 100644
--- a/bcc32/Makefile.sub
+++ b/bcc32/Makefile.sub
@@ -214,13 +214,14 @@ $(CONFIG_H): $(MKFILES) $(srcdir)bcc32/Makefile.sub
\#define HAVE_STDLIB_H 1
\#define HAVE_STRING_H 1
\#define HAVE_MEMORY_H 1
+\#define HAVE_LONG_LONG 1
\#define HAVE_OFF_T 1
\#define SIZEOF_INT 4
\#define SIZEOF_SHORT 2
\#define SIZEOF_LONG 4
\#define SIZEOF_LONG_LONG 0
\#define SIZEOF___INT64 8
-\#define SIZEOF_OFF_T 4
+\#define SIZEOF_OFF_T 8
\#define SIZEOF_VOIDP 4
\#define SIZEOF_FLOAT 4
\#define SIZEOF_DOUBLE 8
@@ -264,7 +265,9 @@ $(CONFIG_H): $(MKFILES) $(srcdir)bcc32/Makefile.sub
\#define HAVE_WAITPID 1
\#define HAVE_FSYNC 1
\#define HAVE_GETCWD 1
-\#define HAVE_CHSIZE 1
+\#define HAVE_TRUNCATE 1
+\#define HAVE_FSEEKO 1
+\#define HAVE_FTELLO 1
\#define HAVE_TIMES 1
\#define HAVE_FCNTL 1
\#define HAVE_LINK 1
diff --git a/configure.in b/configure.in
index 0feaa29ab8..a9b1874bfb 100644
--- a/configure.in
+++ b/configure.in
@@ -218,6 +218,13 @@ fi
dnl check for large file stuff
AC_SYS_LARGEFILE
+case "$target_os" in
+mingw*)
+ ac_cv_type_off_t=yes
+ ac_cv_sizeof_off_t=8
+ ;;
+esac
+
AC_CHECK_TYPES([long long, off_t])
AC_CHECK_SIZEOF(int, 4)
@@ -378,6 +385,9 @@ mingw*) LIBS="-lshell32 -lws2_32 $LIBS"
ac_cv_func_isnan=yes
ac_cv_func_finite=yes
ac_cv_func_link=yes
+ ac_cv_func_truncate=yes
+ ac_cv_func_fseeko=yes
+ ac_cv_func_ftello=yes
ac_cv_lib_crypt_crypt=no
ac_cv_func_getpgrp_void=no
ac_cv_func_setpgrp_void=yes
diff --git a/win32/Makefile.sub b/win32/Makefile.sub
index 676f0e66ac..9a361d482c 100644
--- a/win32/Makefile.sub
+++ b/win32/Makefile.sub
@@ -237,7 +237,8 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub
#define SIZEOF_LONG_LONG 0
!endif
#define SIZEOF___INT64 8
-#define SIZEOF_OFF_T 4
+#define _INTEGRAL_MAX_BITS 64
+#define SIZEOF_OFF_T 8
#define SIZEOF_VOIDP 4
#define SIZEOF_FLOAT 4
#define SIZEOF_DOUBLE 8
@@ -297,7 +298,9 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub
#define HAVE_WAITPID 1
#define HAVE_FSYNC 1
#define HAVE_GETCWD 1
-#define HAVE_CHSIZE 1
+#define HAVE_TRUNCATE 1
+#define HAVE_FSEEKO 1
+#define HAVE_FTELLO 1
#define HAVE_TIMES 1
#define HAVE_FCNTL 1
#define HAVE_LINK 1
diff --git a/win32/dir.h b/win32/dir.h
index f472832d28..f970745fdf 100644
--- a/win32/dir.h
+++ b/win32/dir.h
@@ -29,8 +29,8 @@ typedef struct {
DIR* rb_w32_opendir(const char*);
struct direct* rb_w32_readdir(DIR *);
-long rb_w32_telldir(DIR *);
-void rb_w32_seekdir(DIR *, long);
+off_t rb_w32_telldir(DIR *);
+void rb_w32_seekdir(DIR *, off_t);
void rb_w32_rewinddir(DIR *);
void rb_w32_closedir(DIR *);
diff --git a/win32/win32.c b/win32/win32.c
index 348b8bb06e..de0da968f3 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -25,6 +25,7 @@
#include <windows.h>
#include <winbase.h>
#include <wincon.h>
+#include <share.h>
#include <shlobj.h>
#ifdef __MINGW32__
#include <mswsock.h>
@@ -1403,7 +1404,7 @@ rb_w32_opendir(const char *filename)
long idx;
char scannamespc[PATHLEN];
char *scanname = scannamespc;
- struct stat sbuf;
+ struct stati64 sbuf;
WIN32_FIND_DATA fd;
HANDLE fh;
@@ -1411,7 +1412,7 @@ rb_w32_opendir(const char *filename)
// check to see if we've got a directory
//
- if (rb_w32_stat(filename, &sbuf) < 0)
+ if (rb_w32_stati64(filename, &sbuf) < 0)
return NULL;
if (!(sbuf.st_mode & S_IFDIR) &&
(!ISALPHA(filename[0]) || filename[1] != ':' || filename[2] != '\0' ||
@@ -1570,7 +1571,7 @@ rb_w32_readdir(DIR *dirp)
// Telldir returns the current string pointer position
//
-long
+off_t
rb_w32_telldir(DIR *dirp)
{
return dirp->loc;
@@ -1581,7 +1582,7 @@ rb_w32_telldir(DIR *dirp)
// (Saved by telldir).
void
-rb_w32_seekdir(DIR *dirp, long loc)
+rb_w32_seekdir(DIR *dirp, off_t loc)
{
rb_w32_rewinddir(dirp);
@@ -3223,6 +3224,20 @@ isUNCRoot(const char *path)
return 0;
}
+#define COPY_STAT(src, dest) do { \
+ (dest).st_dev = (src).st_dev; \
+ (dest).st_ino = (src).st_ino; \
+ (dest).st_mode = (src).st_mode; \
+ (dest).st_nlink = (src).st_nlink; \
+ (dest).st_uid = (src).st_uid; \
+ (dest).st_gid = (src).st_gid; \
+ (dest).st_rdev = (src).st_rdev; \
+ (dest).st_size = (src).st_size; \
+ (dest).st_atime = (src).st_atime; \
+ (dest).st_mtime = (src).st_mtime; \
+ (dest).st_ctime = (src).st_ctime; \
+ } while (0)
+
#ifdef __BORLANDC__
#undef fstat
int
@@ -3239,6 +3254,25 @@ rb_w32_fstat(int fd, struct stat *st)
}
return ret;
}
+
+int
+rb_w32_fstati64(int fd, struct stati64 *st)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ struct stat tmp;
+ int ret = fstat(fd, &tmp);
+
+ if (ret) return ret;
+ tmp.st_mode &= ~(S_IWGRP | S_IWOTH);
+ COPY_STAT(tmp, *st);
+ if (GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &info)) {
+ if (!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
+ st->st_mode |= S_IWUSR;
+ }
+ st->st_size = ((__int64)info.nFileSizeHigh << 32) | info.nFileSizeLow;
+ }
+ return ret;
+}
#endif
static time_t
@@ -3309,12 +3343,12 @@ fileattr_to_unixmode(DWORD attr, const char *path)
}
static int
-winnt_stat(const char *path, struct stat *st)
+winnt_stat(const char *path, struct stati64 *st)
{
HANDLE h;
WIN32_FIND_DATA wfd;
- memset(st, 0, sizeof(struct stat));
+ memset(st, 0, sizeof(*st));
st->st_nlink = 1;
if (_mbspbrk(path, "?*")) {
@@ -3328,7 +3362,7 @@ winnt_stat(const char *path, struct stat *st)
st->st_atime = filetime_to_unixtime(&wfd.ftLastAccessTime);
st->st_mtime = filetime_to_unixtime(&wfd.ftLastWriteTime);
st->st_ctime = filetime_to_unixtime(&wfd.ftCreationTime);
- st->st_size = wfd.nFileSizeLow; /* TODO: 64bit support */
+ st->st_size = ((__int64)wfd.nFileSizeHigh << 32) | wfd.nFileSizeLow;
}
else {
// If runtime stat(2) is called for network shares, it fails on WinNT.
@@ -3350,6 +3384,16 @@ winnt_stat(const char *path, struct stat *st)
int
rb_w32_stat(const char *path, struct stat *st)
{
+ struct stati64 tmp;
+
+ if (rb_w32_stati64(path, &tmp)) return -1;
+ COPY_STAT(tmp, *st);
+ return 0;
+}
+
+int
+rb_w32_stati64(const char *path, struct stati64 *st)
+{
const char *p;
char *buf1, *s, *end;
int len;
@@ -3379,16 +3423,151 @@ rb_w32_stat(const char *path, struct stat *st)
*end = '\0';
else if (*end != '\\')
strcat(buf1, "\\");
- } else if (*end == '\\' || (buf1 + 1 == end && *end == ':'))
+ }
+ else if (*end == '\\' || (buf1 + 1 == end && *end == ':'))
strcat(buf1, ".");
- ret = IsWinNT() ? winnt_stat(buf1, st) : stat(buf1, st);
+ ret = IsWinNT() ? winnt_stat(buf1, st) : stati64(buf1, st);
if (ret == 0) {
st->st_mode &= ~(S_IWGRP | S_IWOTH);
}
return ret;
}
+static int
+rb_chsize(HANDLE h, off_t size)
+{
+ long upos, lpos, usize, lsize, uend, lend;
+ off_t end;
+ int ret = -1;
+ DWORD e;
+
+ if (((lpos = SetFilePointer(h, 0, (upos = 0, &upos), SEEK_CUR)) == -1L &&
+ (e = GetLastError())) ||
+ ((lend = GetFileSize(h, (DWORD *)&uend)) == -1L && (e = GetLastError()))) {
+ errno = map_errno(e);
+ return -1;
+ }
+ end = ((off_t)uend << 32) | (unsigned long)lend;
+ usize = (long)(size >> 32);
+ lsize = (long)size;
+ if (SetFilePointer(h, lsize, &usize, SEEK_SET) == -1L &&
+ (e = GetLastError())) {
+ errno = map_errno(e);
+ }
+ else if (!SetEndOfFile(h)) {
+ errno = map_errno(GetLastError());
+ }
+ else {
+ ret = 0;
+ }
+ SetFilePointer(h, lpos, &upos, SEEK_SET);
+ return ret;
+}
+
+int
+truncate(const char *path, off_t length)
+{
+ HANDLE h;
+ int ret;
+ if (IsWin95()) {
+ int fd = open(path, O_WRONLY), e;
+ if (fd == -1) return -1;
+ ret = chsize(fd, (unsigned long)length);
+ if (ret == -1) e = errno;
+ close(fd);
+ if (ret == -1) errno = e;
+ return ret;
+ }
+ h = CreateFile(path, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+ if (h == INVALID_HANDLE_VALUE) {
+ errno = map_errno(GetLastError());
+ return -1;
+ }
+ ret = rb_chsize(h, length);
+ CloseHandle(h);
+ return ret;
+}
+
+int
+ftruncate(int fd, off_t length)
+{
+ long h;
+
+ if (IsWin95()) {
+ return chsize(fd, (unsigned long)length);
+ }
+ h = _get_osfhandle(fd);
+ if (h == -1) return -1;
+ return rb_chsize((HANDLE)h, length);
+}
+
+#ifdef __BORLANDC__
+off_t
+_filelengthi64(int fd)
+{
+ DWORD u, l;
+ int e;
+
+ l = GetFileSize((HANDLE)_get_osfhandle(fd), &u);
+ if (l == (DWORD)-1L && (e = GetLastError())) {
+ errno = map_errno(e);
+ return (off_t)-1;
+ }
+ return ((off_t)u << 32) | l;
+}
+
+off_t
+_lseeki64(int fd, off_t offset, int whence)
+{
+ long u, l;
+ int e;
+ HANDLE h = (HANDLE)_get_osfhandle(fd);
+
+ if (!h) {
+ errno = EBADF;
+ return -1;
+ }
+ u = (long)(offset >> 32);
+ if ((l = SetFilePointer(h, (long)offset, &u, whence)) == -1L &&
+ (e = GetLastError())) {
+ errno = map_errno(e);
+ return -1;
+ }
+ return ((off_t)u << 32) | l;
+}
+#endif
+
+int
+fseeko(FILE *stream, off_t offset, int whence)
+{
+ off_t pos;
+ switch (whence) {
+ case SEEK_CUR:
+ if (fgetpos(stream, (fpos_t *)&pos))
+ return -1;
+ pos += offset;
+ break;
+ case SEEK_END:
+ if ((pos = _filelengthi64(fileno(stream))) == (off_t)-1)
+ return -1;
+ pos += offset;
+ break;
+ default:
+ pos = offset;
+ break;
+ }
+ return fsetpos(stream, (fpos_t *)&pos);
+}
+
+off_t
+ftello(FILE *stream)
+{
+ off_t pos;
+ if (fgetpos(stream, (fpos_t *)&pos)) return (off_t)-1;
+ return pos;
+}
+
static long
filetime_to_clock(FILETIME *ft)
{
@@ -3931,10 +4110,10 @@ rb_w32_utime(const char *path, const struct utimbuf *times)
SYSTEMTIME st;
FILETIME atime, mtime;
struct tm *tm;
- struct stat stat;
+ struct stati64 stat;
int ret = 0;
- if (rb_w32_stat(path, &stat)) {
+ if (rb_w32_stati64(path, &stat)) {
return -1;
}
diff --git a/win32/win32.h b/win32/win32.h
index 477937bbdd..4957bae0a7 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -94,6 +94,8 @@ extern DWORD rb_w32_osid(void);
#undef fgetchar
#undef fputchar
#undef utime
+#undef lseek
+#undef fstat
#define getc(_stream) rb_w32_getc(_stream)
#define getchar() rb_w32_getc(stdin)
#define putc(_c, _stream) rb_w32_putc(_c, _stream)
@@ -104,6 +106,7 @@ extern DWORD rb_w32_osid(void);
#define fgetchar() getchar()
#define fputchar(_c) putchar(_c)
#define utime(_p, _t) rb_w32_utime(_p, _t)
+#define lseek(_f, _o, _w) _lseeki64(_f, _o, _w)
#define pipe(p) _pipe(p, 2048L, O_BINARY)
#define close(h) rb_w32_close(h)
@@ -113,6 +116,7 @@ extern DWORD rb_w32_osid(void);
#define getpid() rb_w32_getpid()
#define sleep(x) rb_w32_Sleep((x)*1000)
#define Sleep(msec) (void)rb_w32_Sleep(msec)
+#define fstat(fd,st) _fstati64(fd,st)
#ifdef __BORLANDC__
#define creat(p, m) _creat(p, m)
#define eof() _eof()
@@ -121,8 +125,7 @@ extern DWORD rb_w32_osid(void);
#define tell(h) _tell(h)
#define _open _sopen
#define sopen _sopen
-#undef fstat
-#define fstat(fd,st) rb_w32_fstat(fd,st)
+#define _fstati64(fd,st) rb_w32_fstati64(fd,st)
#undef fopen
#define fopen(p, m) rb_w32_fopen(p, m)
#undef fdopen
@@ -131,8 +134,6 @@ extern DWORD rb_w32_osid(void);
#define fsopen(p, m, sh) rb_w32_fsopen(p, m, sh)
#endif
-#undef stat
-#define stat(path,st) rb_w32_stat(path,st)
#undef execv
#define execv(path,argv) rb_w32_aspawn(P_OVERLAY,path,argv)
#if !defined(__BORLANDC__) && !defined(_WIN32_WCE)
@@ -148,6 +149,25 @@ extern DWORD rb_w32_osid(void);
#define unlink(p) rb_w32_unlink(p)
#endif
+#if SIZEOF_OFF_T == 8
+#define off_t __int64
+#define stat stati64
+#if defined(__BORLANDC__)
+#define stati64(path, st) rb_w32_stati64(path, st)
+#elif !defined(_MSC_VER) || _MSC_VER < 1400
+#define stati64 _stati64
+#define _stati64(path, st) rb_w32_stati64(path, st)
+#else
+#define stati64 _stat64
+#define _stat64(path, st) rb_w32_stati64(path, st)
+#endif
+#else
+#define stat(path,st) rb_w32_stat(path,st)
+#define fstat(fd,st) rb_w32_fstat(fd,st)
+extern int rb_w32_stat(const char *, struct stat *);
+extern int rb_w32_fstat(int, struct stat *);
+#endif
+
#define strcasecmp(s1, s2) stricmp(s1, s2)
#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
#define fsync(h) _commit(h)
@@ -220,10 +240,11 @@ extern int rb_w32_isatty(int);
extern int rb_w32_mkdir(const char *, int);
extern int rb_w32_rmdir(const char *);
extern int rb_w32_unlink(const char *);
-extern int rb_w32_stat(const char *, struct stat *);
+extern int rb_w32_stati64(const char *, struct stati64 *);
#ifdef __BORLANDC__
-extern int rb_w32_fstat(int, struct stat *);
+extern int rb_w32_fstati64(int, struct stati64 *);
+extern off_t _lseeki64(int, off_t, int);
extern FILE *rb_w32_fopen(const char *, const char *);
extern FILE *rb_w32_fdopen(int, const char *);
extern FILE *rb_w32_fsopen(const char *, const char *, int);
@@ -297,6 +318,10 @@ extern FILE *rb_w32_fsopen(const char *, const char *, int);
//
#define SUFFIX
+extern int truncate(const char *path, off_t length);
+extern int ftruncate(int fd, off_t length);
+extern int fseeko(FILE *stream, off_t offset, int whence);
+extern off_t ftello(FILE *stream);
//
// stubs