diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-04-22 15:45:00 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-04-22 15:45:00 +0000 |
commit | 86dc863bd84ce79d48e5ada9f57bbe24b97db948 (patch) | |
tree | 0f09d8edf917936b230dc8855bed33d0dc3ecc17 | |
parent | 900ede40532640376f7a2ee359e70df2a546e060 (diff) | |
download | ruby-86dc863bd84ce79d48e5ada9f57bbe24b97db948.tar.gz |
* win32/win32.c, include/ruby/win32.h (ustatfs): implementation of
statfs(2) clone. [EXPERIMENTAL]
* file.c (rb_io_statfs): use above function.
* configure.in, win32/Makefile.sub (struct statfs): available.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45672 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | file.c | 8 | ||||
-rw-r--r-- | include/ruby/win32.h | 15 | ||||
-rw-r--r-- | win32/Makefile.sub | 2 | ||||
-rw-r--r-- | win32/win32.c | 48 |
6 files changed, 83 insertions, 1 deletions
@@ -1,3 +1,12 @@ +Wed Apr 23 00:43:00 2014 NAKAMURA Usaku <usa@ruby-lang.org> + + * win32/win32.c, include/ruby/win32.h (ustatfs): implementation of + statfs(2) clone. [EXPERIMENTAL] + + * file.c (rb_io_statfs): use above function. + + * configure.in, win32/Makefile.sub (struct statfs): available. + Tue Apr 22 23:56:24 2014 NAKAMURA Usaku <usa@ruby-lang.org> * file.c (rb_io_stafs): use statfs(2) if fstatfs(2) is unavailable. diff --git a/configure.in b/configure.in index d7a479f4a6..d44a3c5c5f 100644 --- a/configure.in +++ b/configure.in @@ -1059,6 +1059,8 @@ main() ac_cv_func_clock_gettime=yes ac_cv_func_clock_getres=yes ac_cv_func_malloc_usable_size=no + ac_cv_struct_statfs=yes + ac_cv_member_struct_statfs_f_fstypename=yes { test "$target_cpu" = x64 && ac_cv_func___builtin_setjmp=no; } AC_CHECK_TYPE([NET_LUID], [], [], [@%:@include <windows.h> @@ -115,6 +115,8 @@ static VALUE rb_statfs_new(const struct statfs *st); #define unlink(p) rb_w32_uunlink(p) #undef rename #define rename(f, t) rb_w32_urename((f), (t)) +#undef statfs +#define statfs(f, s) ustatfs((f), (s)) #else #define STAT(p, s) stat((p), (s)) #endif @@ -1118,12 +1120,16 @@ rb_io_statfs(VALUE obj) { rb_io_t *fptr; struct statfs st; +#ifndef HAVE_FSTATFS + VALUE path; +#endif GetOpenFile(obj, fptr); #ifdef HAVE_FSTATFS if (fstatfs(fptr->fd, &st) == -1) #else - if (statfs(RSTRING_PTR(fptr->pathv), &st) == -1) + path = rb_str_encode_ospath(fptr->pathv); + if (statfs(StringValueCStr(path), &st) == -1) #endif { rb_sys_fail_path(fptr->pathv); diff --git a/include/ruby/win32.h b/include/ruby/win32.h index a6996bc95a..825b9b1cc8 100644 --- a/include/ruby/win32.h +++ b/include/ruby/win32.h @@ -262,6 +262,20 @@ struct ifaddrs { #define IFF_POINTOPOINT IFF_POINTTOPOINT #endif +/* for ustatfs() */ +typedef uint32_t fsid_t; +struct statfs { + uint32_t f_type; + uint64_t f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + int64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + fsid_t f_fsid; + char f_fstypename[MAX_PATH]; +}; + extern DWORD rb_w32_osid(void); extern rb_pid_t rb_w32_pipe_exec(const char *, const char *, int, int *, int *); extern int flock(int fd, int oper); @@ -347,6 +361,7 @@ extern int rb_w32_uaccess(const char *, int); extern char rb_w32_fd_is_text(int); extern int rb_w32_fstati64(int, struct stati64 *); extern int rb_w32_dup2(int, int); +extern int ustatfs(const char *, struct statfs *); #ifdef __BORLANDC__ extern off_t _lseeki64(int, off_t, int); diff --git a/win32/Makefile.sub b/win32/Makefile.sub index 7c84de184b..5a8479affb 100644 --- a/win32/Makefile.sub +++ b/win32/Makefile.sub @@ -699,6 +699,8 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub #define SETPGRP_VOID 1 #define RSHIFT(x,y) ((x)>>(int)y) #define HAVE_RB_FD_INIT 1 +#define HAVE_STRUCT_STATFS 1 +#define HAVE_STRUCT_STATFS_F_FSTYPENAME 1 #define RUBY_SETJMP(env) _setjmp(env) #define RUBY_LONGJMP(env,val) longjmp(env,val) #define RUBY_JMP_BUF jmp_buf diff --git a/win32/win32.c b/win32/win32.c index 79519aab67..f8b2ff0b16 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -5865,6 +5865,54 @@ rb_w32_pipe(int fds[2]) } /* License: Ruby's */ +int +ustatfs(const char *path, struct statfs *buf) +{ + WCHAR *wpath = utf8_to_wstr(path, NULL); + WCHAR root[MAX_PATH], system[8]; + DWORD serial, spc, bps, unused, total; + char *tmp; + + if (!wpath) { + return -1; + } + + if (!GetVolumePathNameW(wpath, root, sizeof(root) / sizeof(WCHAR))) { + free(wpath); + errno = map_errno(GetLastError()); + return -1; + } + free(wpath); + + if (!GetVolumeInformationW(root, NULL, 0, &serial, NULL, NULL, + system, sizeof(system) / sizeof(WCHAR))) { + errno = map_errno(GetLastError()); + return -1; + } + + if (!GetDiskFreeSpaceW(root, &spc, &bps, &unused, &total)) { + errno = map_errno(GetLastError()); + return -1; + } + + tmp = wstr_to_filecp(system, NULL); + if (!tmp) { + return -1; + } + strlcpy(buf->f_fstypename, tmp, sizeof(buf->f_fstypename)); + free(tmp); + + buf->f_type = 0; + buf->f_bsize = (uint64_t)spc * bps; + buf->f_blocks = total; + buf->f_bfree = buf->f_bavail = unused; + buf->f_files = buf->f_ffree = 0; + buf->f_fsid = serial; + + return 0; +} + +/* License: Ruby's */ static int console_emulator_p(void) { |