fs_info.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- my_get_dev_for_path
- my_get_dev_for_obj
- my_get_fs_info
- my_volume_new
- be_volume_s_new
- be_volume_s_boot
- be_volume_s_each
- be_volume_s_reverse
- my_get_stat
- be_volume_initialize
- be_volume_dev
- be_volume_root
- be_volume_flags
- be_volume_block_size
- be_volume_io_size
- be_volume_total_blocks
- be_volume_free_blocks
- be_volume_total_nodes
- be_volume_free_nodes
- be_volume_device_name
- be_volume_volume_name
- be_volume_fsh_name
- be_volume_removable_p
- be_volume_read_only_p
- be_volume_persistent_p
- be_volume_shared_p
- be_volume_knows_mime_p
- be_volume_knows_attr_p
- be_volume_knows_query_p
- be_volume_each_value
- be_volume_each_pair
- be_volume_members
- be_volume_values
- be_volume_cmp
- be_volume_inspect
- Init_fs_info
/*
* fs_info.c
*/
#include <fs_info.h>
#include "bfs.h"
#define VOLUME_P(x) rb_obj_is_kind_of((x), cVolume)
static VALUE cVolume;
static ID i_dev;
static dev_t
my_get_dev_for_path(const char *path)
/* [<][>][^][v][top][bottom][index][help] */
{
dev_t dev = dev_for_path(path);
if (dev < 0) {
my_sys_fail(dev, path);
}
return dev;
}
dev_t
my_get_dev_for_obj(VALUE obj)
/* [<][>][^][v][top][bottom][index][help] */
{
if (FILE_P(obj)) { /* obj == File obj */
OpenFile *fptr;
GetOpenFile(obj, fptr);
return my_get_dev_for_path(fptr->path);
}
else if (NUMERIC_P(obj)) { /* obj == device num */
return NUM2LONG(obj);
}
else if (VOLUME_P(obj)) { /* obj == Volume obj */
return NUM2LONG(rb_funcall2(obj, i_dev, 0, 0));
}
else if (DIR_P(obj)) { /* obj == Dir obj */
VALUE str;
str = my_get_path_for_dirobj(obj);
return my_get_dev_for_path(RSTRING(str)->ptr);
}
/* obj == path strings */
return my_get_dev_for_path(STR2CSTR(obj));
}
static fs_info*
my_get_fs_info(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
fs_info *info;
Data_Get_Struct(vol, fs_info, info);
if (!info) {
rb_raise(rb_eIOError,
"This %s already released", rb_class2name(CLASS_OF(vol)));
}
return info;
}
static VALUE
my_volume_new(dev_t dev)
/* [<][>][^][v][top][bottom][index][help] */
{
fs_info *info;
rb_secure(2);
info = ALLOC(fs_info);
if (fs_stat_dev(dev, info) < 0) {
char str[12+12];
free(info);
sprintf(str, "dev num: `%ld'", dev);
rb_sys_fail(str);
}
return Data_Wrap_Struct(cVolume, 0, free, info);
}
static VALUE
be_volume_s_new(int argc, VALUE *argv, VALUE klass)
/* [<][>][^][v][top][bottom][index][help] */
{
VALUE obj = Data_Wrap_Struct(klass, 0, free, 0);
rb_obj_call_init(obj, argc, argv);
return obj;
}
static VALUE
be_volume_s_boot(VALUE klass)
/* [<][>][^][v][top][bottom][index][help] */
{
dev_t dev = my_get_dev_for_path("/boot");
return my_volume_new(dev);
}
static VALUE
be_volume_s_each(VALUE klass)
/* [<][>][^][v][top][bottom][index][help] */
{
int32 pos = 0;
dev_t dev;
my_check_block_given();
while ((dev = next_dev(&pos)) >= 0) {
rb_yield(my_volume_new(dev));
}
return klass;
}
static VALUE
be_volume_s_reverse(VALUE klass)
/* [<][>][^][v][top][bottom][index][help] */
{
return rb_ary_reverse(rb_Array(klass));
}
static fs_info*
my_get_stat(VALUE path)
/* [<][>][^][v][top][bottom][index][help] */
{
fs_info *info;
dev_t dev;
rb_secure(2);
dev = my_get_dev_for_obj(path);
info = ALLOC(fs_info);
if (fs_stat_dev(dev, info) < 0) {
free(info);
rb_sys_fail(ROBJ_AS_CSTR(path));
}
return info;
}
static VALUE
be_volume_initialize(VALUE vol, VALUE path)
/* [<][>][^][v][top][bottom][index][help] */
{
if (DATA_PTR(vol)) {
free(DATA_PTR(vol));
DATA_PTR(vol) = NULL;
}
DATA_PTR(vol) = my_get_stat(path);
return vol;
}
static VALUE
be_volume_dev(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return INT2NUM(my_get_fs_info(vol)->dev);
}
static VALUE
be_volume_root(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return LLONG2NUM(my_get_fs_info(vol)->root);
}
static VALUE
be_volume_flags(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return UINT2NUM(my_get_fs_info(vol)->flags);
}
static VALUE
be_volume_block_size(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return LLONG2NUM(my_get_fs_info(vol)->block_size);
}
static VALUE
be_volume_io_size(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return LLONG2NUM(my_get_fs_info(vol)->io_size);
}
static VALUE
be_volume_total_blocks(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return LLONG2NUM(my_get_fs_info(vol)->total_blocks);
}
static VALUE
be_volume_free_blocks(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return LLONG2NUM(my_get_fs_info(vol)->free_blocks);
}
static VALUE
be_volume_total_nodes(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return LLONG2NUM(my_get_fs_info(vol)->total_nodes);
}
static VALUE
be_volume_free_nodes(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return LLONG2NUM(my_get_fs_info(vol)->free_nodes);
}
static VALUE
be_volume_device_name(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return rb_tainted_str_new2(my_get_fs_info(vol)->device_name);
}
static VALUE
be_volume_volume_name(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return rb_tainted_str_new2(my_get_fs_info(vol)->volume_name);
}
static VALUE
be_volume_fsh_name(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return rb_tainted_str_new2(my_get_fs_info(vol)->fsh_name);
}
static VALUE
be_volume_removable_p(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return ((my_get_fs_info(vol)->flags & B_FS_IS_REMOVABLE)
? Qtrue:Qfalse);
}
static VALUE
be_volume_read_only_p(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return ((my_get_fs_info(vol)->flags & B_FS_IS_READONLY)
? Qtrue:Qfalse);
}
static VALUE
be_volume_persistent_p(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return ((my_get_fs_info(vol)->flags & B_FS_IS_PERSISTENT)
? Qtrue:Qfalse);
}
static VALUE
be_volume_shared_p(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return ((my_get_fs_info(vol)->flags & B_FS_IS_SHARED)
? Qtrue:Qfalse);
}
static VALUE
be_volume_knows_mime_p(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return ((my_get_fs_info(vol)->flags & B_FS_HAS_MIME)
? Qtrue:Qfalse);
}
static VALUE
be_volume_knows_attr_p(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return ((my_get_fs_info(vol)->flags & B_FS_HAS_ATTR)
? Qtrue:Qfalse);
}
static VALUE
be_volume_knows_query_p(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return ((my_get_fs_info(vol)->flags & B_FS_HAS_QUERY)
? Qtrue:Qfalse);
}
static struct {
char *name; VALUE (*func)();
} st_info[] = {
{ "dev", be_volume_dev },
{ "root", be_volume_root },
{ "flags", be_volume_flags },
{ "block_size", be_volume_block_size },
{ "io_size", be_volume_io_size },
{ "total_blocks", be_volume_total_blocks },
{ "free_blocks", be_volume_free_blocks },
{ "total_nodes", be_volume_total_nodes },
{ "free_nodes", be_volume_free_nodes },
{ "device_name", be_volume_device_name },
{ "volume_name", be_volume_volume_name },
{ "fsh_name", be_volume_fsh_name },
{ 0, 0 }
};
static VALUE
be_volume_each_value(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
int i;
my_check_block_given();
for (i=0; st_info[i].name; i++) {
rb_yield((*st_info[i].func)(vol));
}
return vol;
}
static VALUE
be_volume_each_pair(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
int i;
my_check_block_given();
for (i=0; st_info[i].name; i++) {
rb_yield(rb_ary_new3(2, rb_str_new2(st_info[i].name),
(*st_info[i].func)(vol)));
}
return vol;
}
static VALUE
be_volume_members(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
int i;
VALUE ary = rb_ary_new();
for (i=0; st_info[i].name; i++) {
rb_ary_push(ary, rb_str_new2(st_info[i].name));
}
return ary;
}
static VALUE
be_volume_values(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
return rb_Array(vol);
}
static VALUE
be_volume_cmp(VALUE vol, VALUE other)
/* [<][>][^][v][top][bottom][index][help] */
{
dev_t dev1 = my_get_fs_info(vol)->dev;
dev_t dev2 = my_get_fs_info(other)->dev;
if (dev1 == dev2) {
return INT2FIX(0);
}
else if (dev1 < dev2) {
return INT2FIX(-1);
}
return INT2FIX(1);
}
static VALUE
be_volume_inspect(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
VALUE str;
int i;
str = rb_str_new2("#<");
rb_str_cat2(str, rb_class2name(CLASS_OF(vol)));
rb_str_cat2(str, " ");
rb_str_cat2(str, st_info[0].name);
rb_str_cat2(str, "=");
rb_str_append(str, rb_inspect((*st_info[0].func)(vol)));
for (i=1; st_info[i].name; i++) {
rb_str_cat2(str, ", ");
rb_str_cat2(str, st_info[i].name);
rb_str_cat2(str, "=");
rb_str_append(str, rb_inspect((*st_info[i].func)(vol)));
}
rb_str_cat2(str, ">");
OBJ_INFECT(str, vol);
return str;
}
void
Init_fs_info()
/* [<][>][^][v][top][bottom][index][help] */
{
i_dev = rb_intern("dev");
cVolume = rb_define_class_under(mBfs, "Volume", rb_cObject);
rb_extend_object(cVolume, rb_mEnumerable);
rb_include_module(cVolume, rb_mEnumerable);
rb_include_module(cVolume, rb_mComparable);
rb_define_singleton_method(cVolume, "new", be_volume_s_new, -1);
rb_define_singleton_method(cVolume, "boot", be_volume_s_boot, 0);
rb_define_singleton_method(cVolume, "each", be_volume_s_each, 0);
rb_define_singleton_method(cVolume, "reverse", be_volume_s_reverse, 0);
rb_define_method(cVolume, "initialize", be_volume_initialize, 1);
rb_define_method(cVolume, "dev", be_volume_dev, 0);
rb_define_method(cVolume, "root", be_volume_root, 0);
rb_define_method(cVolume, "flags", be_volume_flags, 0);
rb_define_method(cVolume, "block_size", be_volume_block_size, 0);
rb_define_method(cVolume, "io_size", be_volume_io_size, 0);
rb_define_method(cVolume, "total_blocks", be_volume_total_blocks, 0);
rb_define_method(cVolume, "free_blocks", be_volume_free_blocks, 0);
rb_define_method(cVolume, "total_nodes", be_volume_total_nodes, 0);
rb_define_method(cVolume, "free_nodes", be_volume_free_nodes, 0);
rb_define_method(cVolume, "device_name", be_volume_device_name, 0);
rb_define_method(cVolume, "volume_name", be_volume_volume_name, 0);
rb_define_method(cVolume, "fsh_name", be_volume_fsh_name, 0);
rb_define_method(cVolume, "removable?", be_volume_removable_p, 0);
rb_define_method(cVolume, "read_only?", be_volume_read_only_p, 0);
rb_define_method(cVolume, "persistent?", be_volume_persistent_p, 0);
rb_define_method(cVolume, "shared?", be_volume_shared_p, 0);
rb_define_method(cVolume, "knows_mime?", be_volume_knows_mime_p, 0);
rb_define_method(cVolume, "knows_attr?", be_volume_knows_attr_p, 0);
rb_define_method(cVolume, "knows_query?", be_volume_knows_query_p, 0);
rb_define_method(cVolume, "to_i", be_volume_dev, 0);
rb_define_method(cVolume, "each", be_volume_each_value, 0);
rb_define_method(cVolume, "each_value", be_volume_each_value, 0);
rb_define_method(cVolume, "each_pair", be_volume_each_pair, 0);
rb_define_method(cVolume, "members", be_volume_members, 0);
rb_define_method(cVolume, "values", be_volume_values, 0);
rb_define_method(cVolume, "<=>", be_volume_cmp, 1);
rb_define_method(cVolume, "inspect", be_volume_inspect, 0);
}