fs_index.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- my_open_index
- my_read_index
- my_get_index
- my_index_info2hash
- be_index_close
- my_init_index
- free_index
- be_index_s_new
- be_index_s_open
- be_index_each
- be_index_s_foreach
- be_index_s_entries
- be_index_initialize
- be_index_read
- be_index_rewind
- be_index_reverse
- be_index_s_create
- be_index_s_remove
- be_index_s_stat
- Init_fs_index
/*
* fs_index.c
*/
#include <fs_index.h>
#include <StorageDefs.h>
#include "bfs.h"
static VALUE cIndex;
static DIR*
my_open_index(VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
dev_t dev;
DIR *dirp;
rb_secure(2);
dev = my_get_dev_for_obj(vol);
dirp = fs_open_index_dir(dev);
if (!dirp) {
if (errno == EMFILE || errno == ENFILE) {
rb_gc();
dirp = fs_open_index_dir(dev);
}
if (!dirp) {
rb_sys_fail(ROBJ_AS_CSTR(vol));
}
}
return dirp;
}
static VALUE
my_read_index(DIR *dirp)
/* [<][>][^][v][top][bottom][index][help] */
{
dirent_t *dp;
errno = 0;
dp = fs_read_index_dir(dirp);
if (!dp && errno) {
rb_sys_fail(0);
}
if (dp) {
return rb_tainted_str_new2(dp->d_name);
}
return Qnil;
}
static DIR*
my_get_index(VALUE indx)
/* [<][>][^][v][top][bottom][index][help] */
{
DIR *dirp;
Data_Get_Struct(indx, DIR, dirp);
my_check_dirp_closed(dirp, "closed index");
return dirp;
}
static VALUE
my_index_info2hash(index_info *info)
/* [<][>][^][v][top][bottom][index][help] */
{
VALUE h = rb_hash_new();
rb_hash_aset(h, rb_str_new2("type"), UINT2NUM(info->type));
rb_hash_aset(h, rb_str_new2("size"), LLONG2NUM(info->size));
rb_hash_aset(h, rb_str_new2("modification_time"), rb_time_new(info->modification_time, 0));
rb_hash_aset(h, rb_str_new2("creation_time"), rb_time_new(info->creation_time, 0));
rb_hash_aset(h, rb_str_new2("uid"), UINT2NUM(info->uid));
rb_hash_aset(h, rb_str_new2("gid"), UINT2NUM(info->gid));
return h;
}
static VALUE
be_index_close(VALUE indx)
/* [<][>][^][v][top][bottom][index][help] */
{
DIR *dirp = my_get_index(indx);
if (fs_close_index_dir(dirp) < 0) {
rb_sys_fail(ROBJ_AS_CSTR(indx));
}
DATA_PTR(indx) = NULL;
return Qnil;
}
static VALUE
my_init_index(VALUE indx, VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
if (DATA_PTR(indx)) {
be_index_close(indx);
}
DATA_PTR(indx) = my_open_index(vol);
return indx;
}
static void
free_index(DIR *dirp)
/* [<][>][^][v][top][bottom][index][help] */
{
if (dirp && (fs_close_index_dir(dirp) < 0)) {
rb_warn("%s", strerror(errno));
}
}
static VALUE
be_index_s_new(int argc, VALUE *argv, VALUE klass)
/* [<][>][^][v][top][bottom][index][help] */
{
VALUE obj = Data_Wrap_Struct(klass, 0, free_index, 0);
rb_obj_call_init(obj, argc, argv);
return obj;
}
static VALUE
be_index_s_open(VALUE klass, VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
VALUE indx;
indx = Data_Wrap_Struct(klass, 0, free_index, 0);
my_init_index(indx, vol);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, indx, be_index_close, indx);
}
return indx;
}
static VALUE
be_index_each(VALUE indx)
/* [<][>][^][v][top][bottom][index][help] */
{
DIR *dirp;
VALUE d_name;
my_check_block_given();
dirp = my_get_index(indx);
d_name = my_read_index(dirp);
while (!NIL_P(d_name)) {
rb_yield(d_name);
my_check_dirp_closed(DATA_PTR(indx), "closed index");
d_name = my_read_index(dirp);
}
return indx;
}
static VALUE
be_index_s_foreach(VALUE klass, VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
VALUE indx = rb_funcall(cIndex, i_open, 1, vol);
rb_ensure(be_index_each, indx, be_index_close, indx);
return Qnil;
}
static VALUE
be_index_s_entries(VALUE klass, VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
VALUE indx = rb_funcall(cIndex, i_open, 1, vol);
return rb_ensure(rb_Array, indx, be_index_close, indx);
}
static VALUE
be_index_initialize(VALUE indx, VALUE vol)
/* [<][>][^][v][top][bottom][index][help] */
{
if (rb_block_given_p()) {
char *cname = rb_class2name(CLASS_OF(indx));
rb_warn("%s::new() does not take block; use %s::open() instead", cname, cname);
}
my_init_index(indx, vol);
return indx;
}
static VALUE
be_index_read(VALUE indx)
/* [<][>][^][v][top][bottom][index][help] */
{
DIR *dirp = my_get_index(indx);
return my_read_index(dirp);
}
static VALUE
be_index_rewind(VALUE indx)
/* [<][>][^][v][top][bottom][index][help] */
{
DIR *dirp = my_get_index(indx);
fs_rewind_index_dir(dirp);
return indx;
}
static VALUE
be_index_reverse(VALUE indx)
/* [<][>][^][v][top][bottom][index][help] */
{
return rb_ary_reverse(rb_Array(indx));
}
static VALUE
be_index_s_create(int argc, VALUE *argv, VALUE klass)
/* [<][>][^][v][top][bottom][index][help] */
{
VALUE vol, name, type, flags;
dev_t dev;
int result, typ;
uint flgs;
typ = B_STRING_TYPE;
flgs = 0;
rb_scan_args(argc, argv, "22", &vol, &name, &type, &flags);
rb_secure(2);
Check_SafeStr(name);
if (RSTRING(name)->len >= B_ATTR_NAME_LENGTH) { /* <-- ? not found `B_INDEX_NAME_LENGTH' */
my_sys_fail(B_BAD_VALUE, RSTRING(name)->ptr);
}
dev = my_get_dev_for_obj(vol);
if (argc >= 3) {
typ = NUM2LONG(type);
}
if (argc == 4) {
flgs = NUM2ULONG(flags);
}
result = fs_create_index(dev, RSTRING(name)->ptr, typ, flgs);
if (result < 0) {
rb_sys_fail(RSTRING(name)->ptr);
}
return Qnil;
}
static VALUE
be_index_s_remove(VALUE klass, VALUE vol, VALUE name)
/* [<][>][^][v][top][bottom][index][help] */
{
dev_t dev;
int result;
rb_secure(2);
Check_SafeStr(name);
dev = my_get_dev_for_obj(vol);
result = fs_remove_index(dev, RSTRING(name)->ptr);
if (result < 0) {
rb_sys_fail(RSTRING(name)->ptr);
}
return Qnil;
}
static VALUE
be_index_s_stat(VALUE klass, VALUE vol, VALUE name)
/* [<][>][^][v][top][bottom][index][help] */
{
dev_t dev;
index_info info;
int result;
rb_secure(2);
Check_SafeStr(name);
dev = my_get_dev_for_obj(vol);
result = fs_stat_index(dev, RSTRING(name)->ptr, &info);
if (result < 0) {
rb_sys_fail(RSTRING(name)->ptr);
}
return my_index_info2hash(&info);
}
void
Init_fs_index()
/* [<][>][^][v][top][bottom][index][help] */
{
cIndex = rb_define_class_under(mBfs, "Index", rb_cObject);
rb_include_module(cIndex, rb_mEnumerable);
rb_define_singleton_method(cIndex, "new", be_index_s_new, -1);
rb_define_singleton_method(cIndex, "open", be_index_s_open, 1);
rb_define_singleton_method(cIndex, "foreach", be_index_s_foreach, 1);
rb_define_singleton_method(cIndex, "entries", be_index_s_entries, 1);
rb_define_method(cIndex, "initialize", be_index_initialize, 1);
rb_define_method(cIndex, "read", be_index_read, 0);
rb_define_method(cIndex, "each", be_index_each, 0);
rb_define_method(cIndex, "rewind", be_index_rewind, 0);
rb_define_method(cIndex, "close", be_index_close, 0);
rb_define_method(cIndex, "reverse", be_index_reverse, 0);
rb_define_singleton_method(cIndex, "create", be_index_s_create, -1);
rb_define_singleton_method(cIndex, "mkindex", be_index_s_create, -1);
rb_define_singleton_method(cIndex, "remove", be_index_s_remove, 2);
rb_define_singleton_method(cIndex, "rmindex", be_index_s_remove, 2);
rb_define_singleton_method(cIndex, "delete", be_index_s_remove, 2);
rb_define_singleton_method(cIndex, "stat", be_index_s_stat, 2);
}