summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorTomoyuki Sahara <[email protected]>2016-12-19 09:03:13 +0900
committerGitHub <[email protected]>2016-12-19 09:03:13 +0900
commit458b517c6f5d5bdf0ab2f742841279d6f43e9aac (patch)
tree8bc99fda9bdab444173837669575b7deddc000ea /src
parent7e8973629143de1952365803df0c45a89d462857 (diff)
parentb31b8022db8a471167f1789909a38c54d573a741 (diff)
downloadmruby-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.c32
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));