summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/deps/mruby-dir
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:22 +0000
commitc21c3b0befeb46a51b6bf3758ffa30813bea0ff0 (patch)
tree9754ff1ca740f6346cf8483ec915d4054bc5da2d /web/server/h2o/libh2o/deps/mruby-dir
parentAdding upstream version 1.43.2. (diff)
downloadnetdata-upstream/1.44.3.tar.xz
netdata-upstream/1.44.3.zip
Adding upstream version 1.44.3.upstream/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/.gitignore5
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/.travis.yml2
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/README.md56
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/mrbgem.rake6
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/mrblib/dir.rb64
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/run_test.rb26
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/src/Win/dirent.c154
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/src/dir.c281
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/test/dir.rb128
-rw-r--r--web/server/h2o/libh2o/deps/mruby-dir/test/dirtest.c114
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());
+}
+