diff options
| author | Tomoyuki Sahara <[email protected]> | 2016-12-19 09:03:13 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2016-12-19 09:03:13 +0900 |
| commit | 458b517c6f5d5bdf0ab2f742841279d6f43e9aac (patch) | |
| tree | 8bc99fda9bdab444173837669575b7deddc000ea /src | |
| parent | 7e8973629143de1952365803df0c45a89d462857 (diff) | |
| parent | b31b8022db8a471167f1789909a38c54d573a741 (diff) | |
| download | mruby-458b517c6f5d5bdf0ab2f742841279d6f43e9aac.tar.gz mruby-458b517c6f5d5bdf0ab2f742841279d6f43e9aac.zip | |
Merge pull request #71 from eagletmt/readlink
Add File.readlink
Diffstat (limited to 'src')
| -rw-r--r-- | src/file.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/file.c b/src/file.c index 2131db654..054cd6417 100644 --- a/src/file.c +++ b/src/file.c @@ -353,6 +353,37 @@ mrb_file_s_chmod(mrb_state *mrb, mrb_value klass) { return mrb_fixnum_value(argc); } +static mrb_value +mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) { +#if defined(_WIN32) || defined(_WIN64) + mrb_raise(mrb, E_NOTIMP_ERROR, "readlink is not supported on this platform"); + return mrb_nil_value(); // unreachable +#else + char *path, *buf; + size_t bufsize = 100; + ssize_t rc; + mrb_value ret; + int ai = mrb_gc_arena_save(mrb); + + mrb_get_args(mrb, "z", &path); + + buf = mrb_malloc(mrb, bufsize); + while ((rc = readlink(path, buf, bufsize)) == bufsize && rc != -1) { + bufsize *= 2; + buf = mrb_realloc(mrb, buf, bufsize); + } + if (rc == -1) { + mrb_free(mrb, buf); + mrb_sys_fail(mrb, path); + } + ret = mrb_str_new(mrb, buf, rc); + mrb_free(mrb, buf); + + mrb_gc_arena_restore(mrb, ai); + return ret; +#endif +} + void mrb_init_file(mrb_state *mrb) { @@ -367,6 +398,7 @@ mrb_init_file(mrb_state *mrb) mrb_define_class_method(mrb, file, "rename", mrb_file_s_rename, MRB_ARGS_REQ(2)); mrb_define_class_method(mrb, file, "symlink", mrb_file_s_symlink, MRB_ARGS_REQ(2)); mrb_define_class_method(mrb, file, "chmod", mrb_file_s_chmod, MRB_ARGS_REQ(1) | MRB_ARGS_REST()); + mrb_define_class_method(mrb, file, "readlink", mrb_file_s_readlink, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, file, "dirname", mrb_file_dirname, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, file, "basename", mrb_file_basename, MRB_ARGS_REQ(1)); |
