diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 13:19:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 13:20:02 +0000 |
commit | 58daab21cd043e1dc37024a7f99b396788372918 (patch) | |
tree | 96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /web/server/h2o/libh2o/deps/mruby-dir | |
parent | Releasing debian version 1.43.2-1. (diff) | |
download | netdata-58daab21cd043e1dc37024a7f99b396788372918.tar.xz netdata-58daab21cd043e1dc37024a7f99b396788372918.zip |
Merging upstream version 1.44.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'web/server/h2o/libh2o/deps/mruby-dir')
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/.gitignore | 5 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/.travis.yml | 2 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/README.md | 56 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake | 6 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb | 64 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/run_test.rb | 26 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c | 154 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/src/dir.c | 281 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb | 128 | ||||
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c | 114 |
10 files changed, 836 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby-dir/.gitignore b/web/server/h2o/libh2o/deps/mruby-dir/.gitignore new file mode 100644 index 000000000..55ef3162f --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/.gitignore @@ -0,0 +1,5 @@ +gem_* +gem-* +mrb-*.a +src/*.o +/tmp diff --git a/web/server/h2o/libh2o/deps/mruby-dir/.travis.yml b/web/server/h2o/libh2o/deps/mruby-dir/.travis.yml new file mode 100644 index 000000000..ffe227284 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/web/server/h2o/libh2o/deps/mruby-dir/README.md b/web/server/h2o/libh2o/deps/mruby-dir/README.md new file mode 100644 index 000000000..d7953036d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/README.md @@ -0,0 +1,56 @@ +mruby-dir +========= + +Dir class for mruby. Supported methods are: + +`.chdir` +`.delete` +`.entries` +`.exist?` +`.foreach` +`.getwd` +`.mkdir` +`.open` +`#close` +`#each` +`#read` +`#rewind` +`#seek` +`#tell` + + +## License + +Copyright (c) 2012 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +- On Windows platforms, you must agree on addional license too: + +Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose is hereby granted without fee, provided +that this copyright and permissions notice appear in all copies and +derivatives. + +This software is supplied "as is" without express or implied warranty. + +But that said, if there are any problems please get in touch. diff --git a/web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake new file mode 100644 index 000000000..10864c81c --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake @@ -0,0 +1,6 @@ +MRuby::Gem::Specification.new('mruby-dir') do |spec| + spec.license = 'MIT and MIT-like license' + spec.authors = [ 'Internet Initiative Japan Inc.', 'Kevlin Henney'] + + spec.cc.include_paths << "#{build.root}/src" +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb b/web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb new file mode 100644 index 000000000..065ca1c22 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb @@ -0,0 +1,64 @@ +class Dir + def each(&block) + while s = self.read + block.call(s) + end + self + end + + alias pos tell + alias pos= seek + + def self.entries(path) + a = [] + self.open(path) { |d| + while s = d.read + a << s + end + } + a + end + + def self.foreach(path, &block) + if block + self.open(path).each { |f| block.call(f) } + else + self.open(path).each + end + end + + def self.open(path, &block) + if block + d = self.new(path) + begin + block.call(d) + ensure + d.close + end + else + self.new(path) + end + end + + def self.chdir(path, &block) + my = self # workaround for https://github.com/mruby/mruby/issues/1579 + if block + wd = self.getwd + begin + self._chdir(path) + block.call(path) + ensure + my._chdir(wd) + end + else + self._chdir(path) + end + end + + class << self + alias exists? exist? + alias pwd getwd + alias rmdir delete + alias unlink delete + end +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/run_test.rb b/web/server/h2o/libh2o/deps/mruby-dir/run_test.rb new file mode 100644 index 000000000..d9566a2a6 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/run_test.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +gemname = File.basename(File.dirname(File.expand_path __FILE__)) + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + build_args = ['all', 'test'] if build_args.nil? or build_args.empty? + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c b/web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c new file mode 100644 index 000000000..98728bcf7 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c @@ -0,0 +1,154 @@ +/* + + Implementation of POSIX directory browsing functions and types for Win32. + + Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) + History: Created March 1997. Updated June 2003 and July 2012. + Rights: See end of file. + +*/ + +#include <errno.h> +#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */ +#include <stdlib.h> +#include <string.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */ + +struct dirent +{ + char *d_name; +}; + +struct DIR +{ + handle_type handle; /* -1 for failed rewind */ + struct _finddata_t info; + struct dirent result; /* d_name null iff first time */ + char *name; /* null-terminated char string */ +}; + +typedef struct DIR DIR; + +DIR *opendir(const char *name) +{ + DIR *dir = 0; + + if(name && name[0]) + { + size_t base_length = strlen(name); + const char *all = /* search pattern must end with suitable wildcard */ + strchr("/\\", name[base_length - 1]) ? "*" : "/*"; + + if((dir = (DIR *) malloc(sizeof *dir)) != 0 && + (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) + { + strcat(strcpy(dir->name, name), all); + + if((dir->handle = + (handle_type) _findfirst(dir->name, &dir->info)) != -1) + { + dir->result.d_name = 0; + } + else /* rollback */ + { + free(dir->name); + free(dir); + dir = 0; + } + } + else /* rollback */ + { + free(dir); + dir = 0; + errno = ENOMEM; + } + } + else + { + errno = EINVAL; + } + + return dir; +} + +int closedir(DIR *dir) +{ + int result = -1; + + if(dir) + { + if(dir->handle != -1) + { + result = _findclose(dir->handle); + } + + free(dir->name); + free(dir); + } + + if(result == -1) /* map all errors to EBADF */ + { + errno = EBADF; + } + + return result; +} + +struct dirent *readdir(DIR *dir) +{ + struct dirent *result = 0; + + if(dir && dir->handle != -1) + { + if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) + { + result = &dir->result; + result->d_name = dir->info.name; + } + } + else + { + errno = EBADF; + } + + return result; +} + +void rewinddir(DIR *dir) +{ + if(dir && dir->handle != -1) + { + _findclose(dir->handle); + dir->handle = (handle_type) _findfirst(dir->name, &dir->info); + dir->result.d_name = 0; + } + else + { + errno = EBADF; + } +} + +#ifdef __cplusplus +} +#endif + +/* + + Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose is hereby granted without fee, provided + that this copyright and permissions notice appear in all copies and + derivatives. + + This software is supplied "as is" without express or implied warranty. + + But that said, if there are any problems please get in touch. + +*/ diff --git a/web/server/h2o/libh2o/deps/mruby-dir/src/dir.c b/web/server/h2o/libh2o/deps/mruby-dir/src/dir.c new file mode 100644 index 000000000..0f55ed93d --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/src/dir.c @@ -0,0 +1,281 @@ +/* +** dir.c - Dir +** +** See Copyright Notice in mruby.h +*/ + +#include "mruby.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/string.h" +#include "error.h" +#include <sys/types.h> +#if defined(_WIN32) || defined(_WIN64) + #define MAXPATHLEN 1024 + #if !defined(PATH_MAX) + #define PATH_MAX MAX_PATH + #endif + #define S_ISDIR(B) ((B)&_S_IFDIR) + #include "Win/dirent.c" + #include <direct.h> + #define rmdir _rmdir + #define getcwd _getcwd + #define mkdir _mkdir + #define chdir _chdir +#else + #include <sys/param.h> + #include <dirent.h> + #include <unistd.h> +#endif +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> + +/* with/without IO module */ +#ifdef ENABLE_IO +#include "mruby/ext/io.h" +#else +#define E_IO_ERROR E_RUNTIME_ERROR +#endif + +struct mrb_dir { + DIR *dir; +}; + +void +mrb_dir_free(mrb_state *mrb, void *ptr) +{ + struct mrb_dir *mdir = ptr; + + if (mdir->dir) { + closedir(mdir->dir); + mdir->dir = NULL; + } + mrb_free(mrb, mdir); +} + +static struct mrb_data_type mrb_dir_type = { "DIR", mrb_dir_free }; + +mrb_value +mrb_dir_close(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + if (closedir(mdir->dir) == -1) { + mrb_sys_fail(mrb, "closedir"); + } + mdir->dir = NULL; + return mrb_nil_value(); +} + +mrb_value +mrb_dir_init(mrb_state *mrb, mrb_value self) +{ + DIR *dir; + struct mrb_dir *mdir; + mrb_value path; + char *cpath; + + mdir = (struct mrb_dir *)DATA_PTR(self); + if (mdir) { + mrb_dir_free(mrb, mdir); + } + DATA_TYPE(self) = &mrb_dir_type; + DATA_PTR(self) = NULL; + + mdir = (struct mrb_dir *)mrb_malloc(mrb, sizeof(*mdir)); + mdir->dir = NULL; + DATA_PTR(self) = mdir; + + mrb_get_args(mrb, "S", &path); + cpath = mrb_str_to_cstr(mrb, path); + if ((dir = opendir(cpath)) == NULL) { + mrb_sys_fail(mrb, cpath); + } + mdir->dir = dir; + return self; +} + +mrb_value +mrb_dir_delete(mrb_state *mrb, mrb_value klass) +{ + mrb_value path; + char *cpath; + + mrb_get_args(mrb, "S", &path); + cpath = mrb_str_to_cstr(mrb, path); + if (rmdir(cpath) == -1) { + mrb_sys_fail(mrb, cpath); + } + return mrb_fixnum_value(0); +} + +mrb_value +mrb_dir_existp(mrb_state *mrb, mrb_value klass) +{ + mrb_value path; + struct stat sb; + char *cpath; + + mrb_get_args(mrb, "S", &path); + cpath = mrb_str_to_cstr(mrb, path); + if (stat(cpath, &sb) == 0 && S_ISDIR(sb.st_mode)) { + return mrb_true_value(); + } else { + return mrb_false_value(); + } +} + +mrb_value +mrb_dir_getwd(mrb_state *mrb, mrb_value klass) +{ + mrb_value path; + + path = mrb_str_buf_new(mrb, MAXPATHLEN); + if (getcwd(RSTRING_PTR(path), MAXPATHLEN) == NULL) { + mrb_sys_fail(mrb, "getcwd(2)"); + } + mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path))); + return path; +} + +mrb_value +mrb_dir_mkdir(mrb_state *mrb, mrb_value klass) +{ + mrb_int mode; + mrb_value spath; + char *path; + + mode = 0777; + mrb_get_args(mrb, "S|i", &spath, &mode); + path = mrb_str_to_cstr(mrb, spath); +#ifndef _WIN32 + if (mkdir(path, mode) == -1) { +#else + if (mkdir(path) == -1) { +#endif + mrb_sys_fail(mrb, path); + } + return mrb_fixnum_value(0); +} + +mrb_value +mrb_dir_chdir(mrb_state *mrb, mrb_value klass) +{ + mrb_value spath; + char *path; + + mrb_get_args(mrb, "S", &spath); + path = mrb_str_to_cstr(mrb, spath); + if (chdir(path) == -1) { + mrb_sys_fail(mrb, path); + } + return mrb_fixnum_value(0); +} + +mrb_value +mrb_dir_read(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + struct dirent *dp; + + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + dp = readdir(mdir->dir); + if (dp != NULL) { + return mrb_str_new_cstr(mrb, dp->d_name); + } else { + return mrb_nil_value(); + } +} + +mrb_value +mrb_dir_rewind(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + rewinddir(mdir->dir); + return self; +} + +mrb_value +mrb_dir_seek(mrb_state *mrb, mrb_value self) +{ + #if defined(_WIN32) || defined(_WIN64) || defined(__android__) + mrb_raise(mrb, E_RUNTIME_ERROR, "dirseek() unreliable on Win platforms"); + return self; + #else + struct mrb_dir *mdir; + mrb_int pos; + + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + mrb_get_args(mrb, "i", &pos); + seekdir(mdir->dir, (long)pos); + return self; + #endif +} + +mrb_value +mrb_dir_tell(mrb_state *mrb, mrb_value self) +{ + #if defined(_WIN32) || defined(_WIN64) || defined(__android__) + mrb_raise(mrb, E_RUNTIME_ERROR, "dirtell() unreliable on Win platforms"); + return mrb_fixnum_value(0); + #else + struct mrb_dir *mdir; + mrb_int pos; + + mdir = (struct mrb_dir *)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + pos = (mrb_int)telldir(mdir->dir); + return mrb_fixnum_value(pos); + #endif +} + +void +mrb_mruby_dir_gem_init(mrb_state *mrb) +{ + struct RClass *d; + + d = mrb_define_class(mrb, "Dir", mrb->object_class); + MRB_SET_INSTANCE_TT(d, MRB_TT_DATA); + mrb_define_class_method(mrb, d, "delete", mrb_dir_delete, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, d, "exist?", mrb_dir_existp, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, d, "getwd", mrb_dir_getwd, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, d, "mkdir", mrb_dir_mkdir, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_class_method(mrb, d, "_chdir", mrb_dir_chdir, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, d, "close", mrb_dir_close, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "initialize", mrb_dir_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, d, "read", mrb_dir_read, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "rewind", mrb_dir_rewind, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "seek", mrb_dir_seek, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, d, "tell", mrb_dir_tell, MRB_ARGS_NONE()); +} + +void +mrb_mruby_dir_gem_final(mrb_state *mrb) +{ +} diff --git a/web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb b/web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb new file mode 100644 index 000000000..cb1f1e31b --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb @@ -0,0 +1,128 @@ +assert('Dir') do + assert_equal(Class, Dir.class) +end + +assert('DirTest.setup') do + DirTest.setup +end + +assert('Dir.chdir') do + assert_equal 0, Dir.chdir(DirTest.sandbox) +end + +assert('Dir.entries') do + a = Dir.entries(DirTest.sandbox) + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir.exist?') do + assert_true Dir.exist?(DirTest.sandbox) + assert_false Dir.exist?(DirTest.sandbox + "/nosuchdir") +end + +assert('Dir.foreach') do + a = [] + Dir.foreach(DirTest.sandbox) { |s| a << s } + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir.getwd') do + s = Dir.getwd + assert_true s.kind_of? String +end + +assert('Dir.mkdir') do + m1 = DirTest.sandbox + "/mkdir1" + m2 = DirTest.sandbox + "/mkdir2" + assert_equal 0, Dir.mkdir(m1) + assert_equal 0, Dir.mkdir(m2, 0765) +end + +assert('Dir.delete') do + s = DirTest.sandbox + "/delete" + Dir.mkdir(s) + assert_true Dir.exist?(s) + + Dir.delete(s) + assert_false Dir.exist?(s) +end + +assert('Dir.open') do + a = [] + Dir.open(DirTest.sandbox) { |d| + d.each { |s| a << s } + } + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir#initialize and Dir#close') do + d = Dir.new(".") + assert_true d.instance_of? Dir + assert_nil d.close +end + +assert('Dir#close') do + d = Dir.new(".") +end + +assert('Dir#each') do + a = [] + d = Dir.open(DirTest.sandbox) + d.each { |s| a << s } + d.close + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir#read') do + a = [] + d = Dir.open(DirTest.sandbox) + while s = d.read + a << s + end + d.close + assert_true a.include? "a" + assert_true a.include? "b" +end + +assert('Dir#rewind') do + d = Dir.open(DirTest.sandbox) + while d.read; end + + assert_equal d, d.rewind + + a = [] + while s = d.read + a << s + end + d.close + assert_true a.include? "a" + assert_true a.include? "b" +end + +# Note: behaviors of seekdir(3) and telldir(3) are so platform-dependent +# that we cannot write portable tests here. + +assert('Dir#tell') do + n = nil + Dir.open(DirTest.sandbox) { |d| + n = d.tell + } + assert_true n.is_a? Integer +end + +assert('Dir#seek') do + d1 = Dir.open(DirTest.sandbox) + d1.read + n = d1.tell + d1.read + d2 = d1.seek(n) + assert_equal d1, d2 +end + +assert('DirTest.teardown') do + DirTest.teardown +end diff --git a/web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c b/web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c new file mode 100644 index 000000000..070f23a82 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c @@ -0,0 +1,114 @@ +#include <sys/types.h> +#include <sys/stat.h> + +#include <dirent.h> +#include <unistd.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mruby.h" +#include "mruby/string.h" +#include "mruby/variable.h" + + +mrb_value +mrb_dirtest_setup(mrb_state *mrb, mrb_value klass) +{ + mrb_value s; + char buf[1024]; + const char *aname = "a"; + const char *bname = "b"; + + /* save current working directory */ + if (getcwd(buf, sizeof(buf)) == NULL) { + mrb_raise(mrb, E_RUNTIME_ERROR, "getcwd() failed"); + } + mrb_cv_set(mrb, klass, mrb_intern_cstr(mrb, "pwd"), mrb_str_new_cstr(mrb, buf)); + + /* create sandbox */ + snprintf(buf, sizeof(buf), "%s/mruby-dir-test.XXXXXX", P_tmpdir); + if (mkdtemp(buf) == NULL) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdtemp(%S) failed", mrb_str_new_cstr(mrb, buf)); + } + s = mrb_str_new_cstr(mrb, buf); + mrb_cv_set(mrb, klass, mrb_intern_cstr(mrb, "sandbox"), s); + + /* go to sandbox */ + if (chdir(buf) == -1) { + rmdir(buf); + mrb_raisef(mrb, E_RUNTIME_ERROR, "chdir(%S) failed", s); + } + + /* make some directories in the sandbox */ + if (mkdir(aname, 0) == -1) { + chdir(".."); + rmdir(buf); + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdir(%S) failed", mrb_str_new_cstr(mrb, aname)); + } + if (mkdir(bname, 0) == -1) { + rmdir(aname); + chdir(".."); + rmdir(buf); + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdir(%S) failed", mrb_str_new_cstr(mrb, bname)); + } + + return mrb_true_value(); +} + +mrb_value +mrb_dirtest_teardown(mrb_state *mrb, mrb_value klass) +{ + mrb_value d, sandbox; + DIR *dirp; + struct dirent *dp; + const char *path; + + /* cleanup sandbox */ + sandbox = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); + path = mrb_str_to_cstr(mrb, sandbox); + + dirp = opendir(path); + while ((dp = readdir(dirp)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) + continue; + if (rmdir(dp->d_name) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "rmdir(%S) failed", mrb_str_new_cstr(mrb, dp->d_name)); + } + } + closedir(dirp); + + /* back to original pwd */ + d = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "pwd")); + path = mrb_str_to_cstr(mrb, d); + if (chdir(path) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "chdir(%S) failed", d); + } + + /* remove sandbox directory */ + sandbox = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); + path = mrb_str_to_cstr(mrb, sandbox); + if (rmdir(path) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "rmdir(%S) failed", sandbox); + } + + return mrb_true_value(); +} + +mrb_value +mrb_dirtest_sandbox(mrb_state *mrb, mrb_value klass) +{ + return mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); +} + +void +mrb_mruby_dir_gem_test(mrb_state *mrb) +{ + struct RClass *c = mrb_define_module(mrb, "DirTest"); + + mrb_define_class_method(mrb, c, "sandbox", mrb_dirtest_sandbox, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, c, "setup", mrb_dirtest_setup, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, c, "teardown", mrb_dirtest_teardown, MRB_ARGS_NONE()); +} + |