/******************************************************************** * filesystem.c * * This is the source file for the sys-filesystem package for Ruby. * This is for UNIX platforms only. ********************************************************************/ #include #include #include #ifdef HAVE_SYS_MNTTAB_H /* Solaris */ #include #define MNTENT mnttab #define START_MNT(F,M) fopen(F,M) #define GET_MNT(FP,MP) (getmntent(FP,MP) == 0) #define END_MNT(F) fclose(F) #define MOUNTLIST "/etc/mnttab" #else /* All other flavors of UNIX */ #include #define MNTENT mntent #define START_MNT(F,M) setmntent(F,M) #define GET_MNT(FP,MP) ((MP = getmntent(FP)) != NULL) #define END_MNT(F) endmntent(F) #define MOUNTLIST "/etc/mtab" #endif VALUE mSys, cFilesys, cStat; /* call-seq: * Filesystem.stat(path) * * Returns a a Filesystem::Stat object containing information about the +path+ * file system. */ static VALUE fs_stat(VALUE klass, VALUE v_path){ VALUE v_stat; struct statvfs fs; char* path = StringValuePtr(v_path); if(statvfs(path, &fs) < 0) rb_sys_fail("statvfs"); v_stat = rb_funcall(cStat, rb_intern("new"), 0, 0); rb_iv_set(v_stat, "@path", v_path); rb_iv_set(v_stat, "@block_size", ULONG2NUM(fs.f_bsize)); rb_iv_set(v_stat, "@fragment_size", ULONG2NUM(fs.f_frsize)); rb_iv_set(v_stat, "@blocks", LONG2NUM(fs.f_blocks)); rb_iv_set(v_stat, "@blocks_free", LONG2NUM(fs.f_bfree)); rb_iv_set(v_stat, "@blocks_available", LONG2NUM(fs.f_bavail)); rb_iv_set(v_stat, "@files", LONG2NUM(fs.f_files)); rb_iv_set(v_stat, "@files_free", LONG2NUM(fs.f_ffree)); rb_iv_set(v_stat, "@files_available", LONG2NUM(fs.f_favail)); rb_iv_set(v_stat, "@filesystem_id", ULONG2NUM(fs.f_fsid)); rb_iv_set(v_stat, "@flags", ULONG2NUM(fs.f_flag)); rb_iv_set(v_stat, "@name_max", ULONG2NUM(fs.f_namemax)); #ifdef HAVE_ST_F_BASETYPE rb_iv_set(v_stat, "@base_type", rb_str_new2(fs.f_basetype)); #endif return rb_obj_freeze(v_stat); } /* Convenient methods for converting bytes to kilobytes, megabytes or * gigabytes. */ /* * call-seq: * fix.to_kb * * Returns +fix+ in terms of kilobytes. */ static VALUE fixnum_to_kb(VALUE self){ return ULL2NUM(NUM2ULONG(self) / 1024); } /* * call-seq: * fix.to_mb * * Returns +fix+ in terms of megabytes. */ static VALUE fixnum_to_mb(VALUE self){ return ULL2NUM(NUM2ULONG(self) / 1048576); } /* * call-seq: * fix.to_gb * * Returns +fix+ in terms of gigabytes. */ static VALUE fixnum_to_gb(VALUE self){ return ULL2NUM(NUM2ULONG(self) / 1073741824); } void Init_filesystem(){ /* Classes and Modules */ mSys = rb_define_module("Sys"); cFilesys = rb_define_class_under(mSys, "Filesystem", rb_cObject); cStat = rb_define_class_under(cFilesys, "Stat", rb_cObject); /* Singleton methods */ rb_define_singleton_method(cFilesys, "stat", fs_stat, 1); /* Stat accessors */ /* The path of the file system */ rb_define_attr(cStat, "path", 1, 0); /* The preferred system block size */ rb_define_attr(cStat, "block_size", 1, 0); /* The fragment size, i.e. fundamental file system block size */ rb_define_attr(cStat, "fragment_size", 1, 0); /* The total number of +fragment_size+ blocks in the file system */ rb_define_attr(cStat, "blocks", 1, 0); /* The total number of free blocks in the file system */ rb_define_attr(cStat, "blocks_free", 1, 0); /* The number of free blocks available to unprivileged processes */ rb_define_attr(cStat, "blocks_available", 1, 0); /* The total number of files/inodes that can be created */ rb_define_attr(cStat, "files", 1, 0); /* The total number of free files/inodes on the file system */ rb_define_attr(cStat, "files_free", 1, 0); /* The number of free files/inodes available to unprivileged processes */ rb_define_attr(cStat, "files_available", 1, 0); /* The file system identifier */ rb_define_attr(cStat, "filesystem_id", 1, 0); /* The file system type, e.g. UFS */ rb_define_attr(cStat, "base_type", 1, 0); /* A bit mask of flags. See the Constants for a list of flags */ rb_define_attr(cStat, "flags", 1, 0); /* The maximum length of a file name permitted on the file system */ rb_define_attr(cStat, "name_max", 1, 0); /* Constants */ /* The version of this package */ rb_define_const(cFilesys, "VERSION", rb_str_new2("0.1.0")); /* Read only file system */ rb_define_const(cStat, "RDONLY", INT2FIX(ST_RDONLY)); /* File system does not support suid or sgid semantics */ rb_define_const(cStat, "NOSUID", INT2FIX(ST_NOSUID)); #ifdef ST_NOTRUNC /* File system does not truncate file names longer than +name_max+ */ rb_define_const(cStat, "NOTRUNC", INT2FIX(ST_NOTRUNC)); #endif /* Aliases */ rb_define_alias(cStat, "inodes", "files"); rb_define_alias(cStat, "inodes_free", "files_free"); rb_define_alias(cStat, "inodes_available", "files_available"); /* Convenient methods for Fixnum */ rb_define_method(rb_cFixnum, "to_kb", fixnum_to_kb, 0); rb_define_method(rb_cFixnum, "to_mb", fixnum_to_mb, 0); rb_define_method(rb_cFixnum, "to_gb", fixnum_to_gb, 0); }