[前][次][番号順一覧][スレッド一覧]

ruby-changes:33580

From: naruse <ko1@a...>
Date: Tue, 22 Apr 2014 19:36:04 +0900 (JST)
Subject: [ruby-changes:33580] naruse:r45661 (trunk): * file.c: newly added a class File::Statfs. (experimental)

naruse	2014-04-22 19:35:57 +0900 (Tue, 22 Apr 2014)

  New Revision: 45661

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45661

  Log:
    * file.c: newly added a class File::Statfs. (experimental)

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/configure.in
    trunk/file.c
    trunk/test/ruby/test_file.rb
Index: configure.in
===================================================================
--- configure.in	(revision 45660)
+++ configure.in	(revision 45661)
@@ -1116,10 +1116,12 @@ AC_CHECK_HEADERS( \ https://github.com/ruby/ruby/blob/trunk/configure.in#L1116
   sys/syscall.h \
   fcntl.h \
   sys/fcntl.h \
+  sys/mount.h \
   sys/select.h \
   sys/time.h \
   sys/times.h \
   sys/param.h \
+  sys/vfs.h \
   syscall.h \
   pwd.h \
   grp.h \
@@ -1719,6 +1721,25 @@ AC_CHECK_TYPES([struct timezone], [], [] https://github.com/ruby/ruby/blob/trunk/configure.in#L1721
 @%:@ include <sys/time.h>
 @%:@endif])
 
+AC_CHECK_TYPES([struct statfs], [], [], [@%:@ifdef HAVE_SYS_PARAM_H
+@%:@ include <sys/param.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_MOUNT_H
+@%:@ include <sys/mount.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_VFS_H
+@%:@ include <sys/vfs.h>
+@%:@endif])
+AC_CHECK_MEMBERS([struct statfs.f_fstypename], [], [], [@%:@ifdef HAVE_SYS_PARAM_H
+@%:@ include <sys/param.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_MOUNT_H
+@%:@ include <sys/mount.h>
+@%:@endif
+@%:@ifdef HAVE_SYS_VFS_H
+@%:@ include <sys/vfs.h>
+@%:@endif])
+
 AC_CHECK_TYPES([clockid_t], [], [], [@%:@ifdef HAVE_TIME_H
 @%:@ include <time.h>
 @%:@endif
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45660)
+++ ChangeLog	(revision 45661)
@@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Apr 22 19:32:48 2014  NARUSE, Yui  <naruse@r...>
+
+	* file.c: newly added a class File::Statfs. (experimental)
+
 Tue Apr 22 08:22:33 2014  Koichi Sasada  <ko1@a...>
 
 	* gc.c (objspace_malloc_increase): don't cause GC by malloc_increase
Index: NEWS
===================================================================
--- NEWS	(revision 45660)
+++ NEWS	(revision 45661)
@@ -20,6 +20,13 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L20
     * min, min_by, max and max_by supports optional argument to return
       multiple elements.
 
+* File
+  * new class File::Statfs to hold filesystem information. (experimental)
+
+* IO
+  * New methods
+    * IO#statfs returns filesystem information as File::Statfs. (experimental)
+
 * Symbol
   * New methods
     * Symbol.find(str) returns whether given string is defined as symbol or not.
Index: test/ruby/test_file.rb
===================================================================
--- test/ruby/test_file.rb	(revision 45660)
+++ test/ruby/test_file.rb	(revision 45661)
@@ -383,4 +383,23 @@ class TestFile < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_file.rb#L383
       assert_file.not_exist?(path)
     end
   end
+
+  def test_statfs
+    open(__FILE__) do |f|
+      st = f.statfs
+      assert_kind_of File::Statfs, st
+      assert_kind_of Integer, st.type
+      assert_kind_of Integer, st.bsize
+      assert_kind_of Integer, st.blocks
+      assert_kind_of Integer, st.bfree
+      assert_kind_of Integer, st.bavail
+      assert_kind_of Integer, st.files
+      assert_kind_of Integer, st.ffree
+      assert_kind_of Integer, st.fsid
+      begin
+        assert_kind_of String, st.fstypename
+      rescue NotImplementedError
+      end
+    end
+  end
 end
Index: file.c
===================================================================
--- file.c	(revision 45660)
+++ file.c	(revision 45661)
@@ -63,6 +63,14 @@ int flock(int, int); https://github.com/ruby/ruby/blob/trunk/file.c#L63
 #include <sys/types.h>
 #include <sys/stat.h>
 
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+VALUE rb_statfs_new(const struct statfs *st);
+
 #if defined(__native_client__) && defined(NACL_NEWLIB)
 # include "nacl/utime.h"
 # include "nacl/stat.h"
@@ -139,6 +147,7 @@ be_fchown(int fd, uid_t owner, gid_t gro https://github.com/ruby/ruby/blob/trunk/file.c#L147
 VALUE rb_cFile;
 VALUE rb_mFileTest;
 VALUE rb_cStat;
+VALUE rb_cStatfs;
 
 #define insecure_obj_p(obj, level) ((level) >= 4 || ((level) > 0 && OBJ_TAINTED(obj)))
 
@@ -1086,6 +1095,34 @@ rb_file_lstat(VALUE obj) https://github.com/ruby/ruby/blob/trunk/file.c#L1095
 #endif
 }
 
+/*
+ *  call-seq:
+ *     ios.statfs    -> statfs
+ *
+ *  Returns filesystem status information for <em>ios</em> as an object of type
+ *  <code>File::Statfs</code>.
+ *
+ *     f = File.new("testfile")
+ *     s = f.statfs
+ *     s.mode   #=> "100644"
+ *     s.bsize         #=> 512
+ *     s.fstypename    #=> "zfs"
+ *
+ */
+
+static VALUE
+rb_io_statfs(VALUE obj)
+{
+    rb_io_t *fptr;
+    struct statfs st;
+
+    GetOpenFile(obj, fptr);
+    if (fstatfs(fptr->fd, &st) == -1) {
+	rb_sys_fail_path(fptr->pathv);
+    }
+    return rb_statfs_new(&st);
+}
+
 static int
 rb_group_member(GETGROUPS_T gid)
 {
@@ -5263,6 +5300,254 @@ rb_stat_sticky(VALUE obj) https://github.com/ruby/ruby/blob/trunk/file.c#L5300
     return Qfalse;
 }
 
+/* File::Statfs */
+
+static size_t
+statfs_memsize(const void *p)
+{
+    return p ? sizeof(struct statfs) : 0;
+}
+
+static const rb_data_type_t statfs_data_type = {
+    "statfs",
+    {NULL, RUBY_TYPED_DEFAULT_FREE, statfs_memsize,},
+    NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static VALUE
+statfs_new_0(VALUE klass, const struct statfs *st)
+{
+    struct statfs *nst = 0;
+
+    if (st) {
+	nst = ALLOC(struct statfs);
+	*nst = *st;
+    }
+    return TypedData_Wrap_Struct(klass, &statfs_data_type, nst);
+}
+
+VALUE
+rb_statfs_new(const struct statfs *st)
+{
+    return statfs_new_0(rb_cStatfs, st);
+}
+
+static struct statfs*
+get_statfs(VALUE self)
+{
+    struct statfs* st;
+    TypedData_Get_Struct(self, struct statfs, &statfs_data_type, st);
+    if (!st) rb_raise(rb_eTypeError, "uninitialized File::Statfs");
+    return st;
+}
+
+/*
+ *  Document-class: File::Statfs
+ *
+ *  Objects of class <code>File::Statfs</code> encapsulate common status
+ *  information for filesystem. The information is
+ *  recorded at the moment the <code>File::Statfs</code> object is
+ *  created; changes made to the filesystem after that point will not be
+ *  reflected. <code>File::Statfs</code> objects are returned by
+ *  <code>IO#statfs</code>.
+ */
+
+static VALUE
+rb_statfs_s_alloc(VALUE klass)
+{
+    return statfs_new_0(klass, 0);
+}
+
+/*
+ * call-seq:
+ *
+ *   File::Statfs.new(file_name)  -> statfs
+ *
+ * Create a File::Statfs object for the given file name (raising an
+ * exception if the file doesn't exist).
+ */
+
+static VALUE
+rb_statfs_init(VALUE obj, VALUE fname)
+{
+    struct statfs st, *nst;
+
+    rb_secure(2);
+    FilePathValue(fname);
+    fname = rb_str_encode_ospath(fname);
+    if (statfs(StringValueCStr(fname), &st) == -1) {
+	rb_sys_fail_path(fname);
+    }
+    if (DATA_PTR(obj)) {
+	xfree(DATA_PTR(obj));
+	DATA_PTR(obj) = NULL;
+    }
+    nst = ALLOC(struct statfs);
+    *nst = st;
+    DATA_PTR(obj) = nst;
+
+    return Qnil;
+}
+
+/* :nodoc: */
+static VALUE
+rb_statfs_init_copy(VALUE copy, VALUE orig)
+{
+    struct statfs *nst;
+
+    if (!OBJ_INIT_COPY(copy, orig)) return copy;
+    if (DATA_PTR(copy)) {
+	xfree(DATA_PTR(copy));
+	DATA_PTR(copy) = 0;
+    }
+    if (DATA_PTR(orig)) {
+	nst = ALLOC(struct statfs);
+	*nst = *(struct statfs*)DATA_PTR(orig);
+	DATA_PTR(copy) = nst;
+    }
+
+    return copy;
+}
+
+/*
+ *  call-seq:
+ *     st.type    -> fixnum
+ *
+ *  Returns type of filesystem.
+ *
+ *     f = File.new("testfile")
+ *     s = f.statfs
+ *     "%d" % s.type   #=> 17
+ *
+ */
+
+static VALUE
+statfs_type(VALUE self)
+{
+    return LL2NUM(get_statfs(self)->f_type);
+}
+
+/*
+ *  call-seq:
+ *     st.bsize    -> integer
+ *
+ *  Returns block size in filesystem.
+ *
+ */
+
+static VALUE
+statfs_bsize(VALUE self)
+{
+    return LL2NUM(get_statfs(self)->f_bsize);
+}
+
+/*
+ *  call-seq:
+ *     st.blocks    -> integer
+ *
+ *  Returns total data bocks of filesystem.
+ *
+ */
+
+static VALUE
+statfs_blocks(VALUE self)
+{
+    return LL2NUM(get_statfs(self)->f_blocks);
+}
+
+/*
+ *  call-seq:
+ *     st.bfree    -> integer
+ *
+ *  Returns free blocks in filesystem.
+ *
+ */
+
+static VALUE
+statfs_bfree(VALUE self)
+{
+    return LL2NUM(get_statfs(self)->f_bfree);
+}
+
+/*
+ *  call-seq:
+ *     st.bavail    -> integer
+ *
+ *  Returns available blocks to non-super user in filesystem.
+ *
+ */
+
+static VALUE
+statfs_bavail(VALUE self)
+{
+    return LL2NUM(get_statfs(self)->f_bavail);
+}
+
+/*
+ *  call-seq:
+ *     st.files    -> integer
+ *
+ *  Returns total file nodes in filesystem.
+ *
+ */
+
+static VALUE
+statfs_files(VALUE self)
+{
+    return LL2NUM(get_statfs(self)->f_files);
+}
+
+/*
+ *  call-seq:
+ *     st.ffree    -> integer
+ *
+ *  Returns free nodes in filesystem.
+ *
+ */
+
+static VALUE
+statfs_ffree(VALUE self)
+{
+    return LL2NUM(get_statfs(self)->f_ffree);
+}
+
+/*
+ *  call-seq:
+ *     st.fsid    -> integer
+ *
+ *  Returns filesystem id.
+ *
+ */
+
+static VALUE
+statfs_fsid(VALUE self)
+{
+    fsid_t n = get_statfs(self)->f_fsid;
+    return LL2NUM(*(LONG_LONG*)&n);
+}
+
+#ifdef HAVE_STRUCT_STATFS_F_FSTYPENAME
+/*
+ *  call-seq:
+ *     st.fstypename    -> string
+ *
+ *  Returns name of filesystem.
+ *
+ *     f = File.new("testfile")
+ *     s = f.statfs
+ *     s.fstypename   #=> "zfs"
+ *
+ */
+
+static VALUE
+statfs_fstypename(VALUE self)
+{
+    return rb_str_new_cstr(get_statfs(self)->f_fstypename);
+}
+#else
+#define statfs_fsname rb_f_notimplement
+#endif
+
 VALUE rb_mFConst;
 
 void
@@ -5689,6 +5974,7 @@ Init_File(void) https://github.com/ruby/ruby/blob/trunk/file.c#L5974
     rb_define_const(rb_cFile, "PATH_SEPARATOR", rb_obj_freeze(rb_str_new2(PATH_SEP)));
 
     rb_define_method(rb_cIO, "stat",  rb_io_stat, 0); /* this is IO's method */
+    rb_define_method(rb_cIO, "statfs",  rb_io_statfs, 0); /* this is IO's method */
     rb_define_method(rb_cFile, "lstat",  rb_file_lstat, 0);
 
     rb_define_method(rb_cFile, "atime", rb_file_atime, 0);
@@ -5845,4 +6131,18 @@ Init_File(void) https://github.com/ruby/ruby/blob/trunk/file.c#L6131
     rb_define_method(rb_cStat, "setuid?",  rb_stat_suid, 0);
     rb_define_method(rb_cStat, "setgid?",  rb_stat_sgid, 0);
     rb_define_method(rb_cStat, "sticky?",  rb_stat_sticky, 0);
+
+    rb_cStatfs = rb_define_class_under(rb_cFile, "Statfs", rb_cObject);
+    rb_define_alloc_func(rb_cStatfs,  rb_statfs_s_alloc);
+    rb_define_method(rb_cStatfs, "initialize", rb_statfs_init, 1);
+    rb_define_method(rb_cStatfs, "initialize_copy", rb_statfs_init_copy, 1);
+    rb_define_method(rb_cStatfs, "type", statfs_type, 0);
+    rb_define_method(rb_cStatfs, "bsize", statfs_bsize, 0);
+    rb_define_method(rb_cStatfs, "blocks", statfs_blocks, 0);
+    rb_define_method(rb_cStatfs, "bfree", statfs_bfree, 0);
+    rb_define_method(rb_cStatfs, "bavail", statfs_bavail, 0);
+    rb_define_method(rb_cStatfs, "files", statfs_files, 0);
+    rb_define_method(rb_cStatfs, "ffree", statfs_ffree, 0);
+    rb_define_method(rb_cStatfs, "fsid", statfs_fsid, 0);
+    rb_define_method(rb_cStatfs, "fstypename", statfs_fstypename, 0);
 }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]