Imported Upstream version 1.46.0
[platform/upstream/nghttp2.git] / third-party / mruby / mrbgems / mruby-io / test / mruby_io_test.c
index 71239a8..8bc87a0 100644 (file)
@@ -1,5 +1,7 @@
+#include <mruby/common.h>
 #include <sys/types.h>
 #include <errno.h>
+#include <string.h>
 
 #if defined(_WIN32) || defined(_WIN64)
 
@@ -7,7 +9,6 @@
 #include <io.h>
 #include <fcntl.h>
 #include <direct.h>
-#include <string.h>
 #include <stdlib.h>
 #include <malloc.h>
 
@@ -18,7 +19,9 @@ typedef int mode_t;
 #define open _open
 #define close _close
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || \
+    (defined(MRB_MINGW32_VERSION) && MRB_MINGW32_VERSION < 3021) || \
+    (defined(MRB_MINGW64_VERSION) && MRB_MINGW64_VERSION < 4000)
 #include <sys/stat.h>
 
 static int
@@ -50,10 +53,11 @@ mkdtemp(char *temp)
   #include <sys/socket.h>
   #include <unistd.h>
   #include <sys/un.h>
+  #include <fcntl.h>
+  #include <libgen.h>
 #endif
 
 #include <sys/stat.h>
-#include <stdio.h>
 #include <stdlib.h>
 
 #include "mruby.h"
@@ -61,51 +65,55 @@ mkdtemp(char *temp)
 #include "mruby/error.h"
 #include "mruby/string.h"
 #include "mruby/variable.h"
+#include <mruby/ext/io.h>
 
 static mrb_value
 mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
 {
-  char rfname[]      = "tmp.mruby-io-test-r.XXXXXXXX";
-  char wfname[]      = "tmp.mruby-io-test-w.XXXXXXXX";
-  char symlinkname[] = "tmp.mruby-io-test-l.XXXXXXXX";
-  char socketname[]  = "tmp.mruby-io-test-s.XXXXXXXX";
+#define GVNAME(n) "$mrbtest_io_" #n "name"
+  enum {IDX_READ, IDX_WRITE, IDX_LINK, IDX_SOCKET, IDX_COUNT};
+  const char *gvnames[] = {GVNAME(rf), GVNAME(wf), GVNAME(symlink), GVNAME(socket)};
+  char *fnames[IDX_COUNT];
+  int fds[IDX_COUNT];
   char msg[] = "mruby io test\n";
   mode_t mask;
-  int fd0, fd1;
   FILE *fp;
-
+  int i;
 #if !defined(_WIN32) && !defined(_WIN64)
-  int fd2, fd3;
   struct sockaddr_un sun0;
 #endif
 
-  mask = umask(077);
-  fd0 = mkstemp(rfname);
-  fd1 = mkstemp(wfname);
-  if (fd0 == -1 || fd1 == -1) {
-    mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
-    return mrb_nil_value();
-  }
-  close(fd0);
-  close(fd1);
+  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg));
 
+  mask = umask(077);
+  for (i = 0; i < IDX_COUNT; i++) {
+    mrb_value fname = mrb_str_new_capa(mrb, 0);
 #if !defined(_WIN32) && !defined(_WIN64)
-  fd2 = mkstemp(symlinkname);
-  fd3 = mkstemp(socketname);
-  if (fd2 == -1 || fd3 == -1) {
-    mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
-    return mrb_nil_value();
-  }
+    /*
+     * Workaround for not being able to bind a socket to some file systems
+     * (e.g. vboxsf, NFS). [#4981]
+     */
+    char *tmpdir = getenv("TMPDIR");
+    if (tmpdir && strlen(tmpdir) > 0) {
+      mrb_str_cat_cstr(mrb, fname, tmpdir);
+      if (*(RSTRING_END(fname)-1) != '/') mrb_str_cat_lit(mrb, fname, "/");
+    } else {
+      mrb_str_cat_lit(mrb, fname, "/tmp/");
+    }
 #endif
+    mrb_str_cat_cstr(mrb, fname, gvnames[i]+1);
+    mrb_str_cat_cstr(mrb, fname, ".XXXXXXXX");
+    fnames[i] = RSTRING_PTR(fname);
+    fds[i] = mkstemp(fnames[i]);
+    if (fds[i] == -1) {
+      mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
+    }
+    close(fds[i]);
+    mrb_gv_set(mrb, mrb_intern_cstr(mrb, gvnames[i]), fname);
+  }
   umask(mask);
 
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"), mrb_str_new_cstr(mrb, rfname));
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"), mrb_str_new_cstr(mrb, wfname));
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"), mrb_str_new_cstr(mrb, symlinkname));
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_str_new_cstr(mrb, socketname));
-  mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg));
-
-  fp = fopen(rfname, "wb");
+  fp = fopen(fnames[IDX_READ], "wb");
   if (fp == NULL) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
     return mrb_nil_value();
@@ -113,7 +121,7 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
   fputs(msg, fp);
   fclose(fp);
 
-  fp = fopen(wfname, "wb");
+  fp = fopen(fnames[IDX_WRITE], "wb");
   if (fp == NULL) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
     return mrb_nil_value();
@@ -121,29 +129,29 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
   fclose(fp);
 
 #if !defined(_WIN32) && !defined(_WIN64)
-  unlink(symlinkname);
-  close(fd2);
-  if (symlink(rfname, symlinkname) == -1) {
+  unlink(fnames[IDX_LINK]);
+  if (symlink(basename(fnames[IDX_READ]), fnames[IDX_LINK]) == -1) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link");
   }
 
-  unlink(socketname);
-  close(fd3);
-  fd3 = socket(AF_UNIX, SOCK_STREAM, 0);
-  if (fd3 == -1) {
+  unlink(fnames[IDX_SOCKET]);
+  fds[IDX_SOCKET] = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (fds[IDX_SOCKET] == -1) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a socket");
   }
   sun0.sun_family = AF_UNIX;
-  snprintf(sun0.sun_path, sizeof(sun0.sun_path), "%s", socketname);
-  if (bind(fd3, (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
-    mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %S: %S",
-               mrb_str_new_cstr(mrb, sun0.sun_path),
-               mrb_fixnum_value(errno));
+  strncpy(sun0.sun_path, fnames[IDX_SOCKET], sizeof(sun0.sun_path)-1);
+  sun0.sun_path[sizeof(sun0.sun_path)-1] = 0;
+  if (bind(fds[IDX_SOCKET], (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d",
+               sun0.sun_path,
+               errno);
   }
-  close(fd3);
+  close(fds[IDX_SOCKET]);
 #endif
 
   return mrb_true_value();
+#undef GVNAME
 }
 
 static mrb_value
@@ -154,16 +162,16 @@ mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self)
   mrb_value symlinkname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"));
   mrb_value socketname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"));
 
-  if (mrb_type(rfname) == MRB_TT_STRING) {
+  if (mrb_string_p(rfname)) {
     remove(RSTRING_PTR(rfname));
   }
-  if (mrb_type(wfname) == MRB_TT_STRING) {
+  if (mrb_string_p(wfname)) {
     remove(RSTRING_PTR(wfname));
   }
-  if (mrb_type(symlinkname) == MRB_TT_STRING) {
+  if (mrb_string_p(symlinkname)) {
     remove(RSTRING_PTR(symlinkname));
   }
-  if (mrb_type(socketname) == MRB_TT_STRING) {
+  if (mrb_string_p(socketname)) {
     remove(RSTRING_PTR(socketname));
   }
 
@@ -177,28 +185,6 @@ mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self)
 }
 
 static mrb_value
-mrb_io_test_file_setup(mrb_state *mrb, mrb_value self)
-{
-  mrb_value ary = mrb_io_test_io_setup(mrb, self);
-#if !defined(_WIN32) && !defined(_WIN64)
-  if (symlink("/usr/bin", "test-bin") == -1) {
-    mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link");
-  }
-#endif
-
-  return ary;
-}
-
-static mrb_value
-mrb_io_test_file_cleanup(mrb_state *mrb, mrb_value self)
-{
-  mrb_io_test_io_cleanup(mrb, self);
-  remove("test-bin");
-
-  return mrb_nil_value();
-}
-
-static mrb_value
 mrb_io_test_mkdtemp(mrb_state *mrb, mrb_value klass)
 {
   mrb_value str;
@@ -215,18 +201,16 @@ mrb_io_test_mkdtemp(mrb_state *mrb, mrb_value klass)
 static mrb_value
 mrb_io_test_rmdir(mrb_state *mrb, mrb_value klass)
 {
-  mrb_value str;
-  char *cp;
+  const char *cp;
 
-  mrb_get_args(mrb, "S", &str);
-  cp = mrb_str_to_cstr(mrb, str);
+  mrb_get_args(mrb, "z", &cp);
   if (rmdir(cp) == -1) {
     mrb_sys_fail(mrb, "rmdir");
   }
   return mrb_true_value();
 }
 
-mrb_value
+static mrb_value
 mrb_io_win_p(mrb_state *mrb, mrb_value klass)
 {
 #if defined(_WIN32) || defined(_WIN64)
@@ -240,6 +224,12 @@ mrb_io_win_p(mrb_state *mrb, mrb_value klass)
 #endif
 }
 
+#ifdef MRB_WITH_IO_PREAD_PWRITE
+# define MRB_WITH_IO_PREAD_PWRITE_ENABLED TRUE
+#else
+# define MRB_WITH_IO_PREAD_PWRITE_ENABLED FALSE
+#endif
+
 void
 mrb_mruby_io_gem_test(mrb_state* mrb)
 {
@@ -247,10 +237,9 @@ mrb_mruby_io_gem_test(mrb_state* mrb)
   mrb_define_class_method(mrb, io_test, "io_test_setup", mrb_io_test_io_setup, MRB_ARGS_NONE());
   mrb_define_class_method(mrb, io_test, "io_test_cleanup", mrb_io_test_io_cleanup, MRB_ARGS_NONE());
 
-  mrb_define_class_method(mrb, io_test, "file_test_setup", mrb_io_test_file_setup, MRB_ARGS_NONE());
-  mrb_define_class_method(mrb, io_test, "file_test_cleanup", mrb_io_test_file_cleanup, MRB_ARGS_NONE());
-
   mrb_define_class_method(mrb, io_test, "mkdtemp", mrb_io_test_mkdtemp, MRB_ARGS_REQ(1));
   mrb_define_class_method(mrb, io_test, "rmdir", mrb_io_test_rmdir, MRB_ARGS_REQ(1));
   mrb_define_class_method(mrb, io_test, "win?", mrb_io_win_p, MRB_ARGS_NONE());
+
+  mrb_define_const(mrb, io_test, "MRB_WITH_IO_PREAD_PWRITE", mrb_bool_value(MRB_WITH_IO_PREAD_PWRITE_ENABLED));
 }