source: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-io/test/mruby_io_test.c@ 439

Last change on this file since 439 was 439, checked in by coas-nagasima, 4 years ago

mrubyを2.1.1に更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 7.3 KB
Line 
1#include <mruby/common.h>
2#include <sys/types.h>
3#include <errno.h>
4#include <string.h>
5
6#if defined(_WIN32) || defined(_WIN64)
7
8#include <winsock.h>
9#include <io.h>
10#include <fcntl.h>
11#include <direct.h>
12#include <stdlib.h>
13#include <malloc.h>
14
15#if (!defined __MINGW64__) && (!defined __MINGW32__)
16typedef int mode_t;
17#endif
18
19#define open _open
20#define close _close
21
22#if defined(_MSC_VER) || \
23 (defined(MRB_MINGW32_VERSION) && MRB_MINGW32_VERSION < 3021) || \
24 (defined(MRB_MINGW64_VERSION) && MRB_MINGW64_VERSION < 4000)
25#include <sys/stat.h>
26
27static int
28mkstemp(char *p)
29{
30 int fd;
31 char* fname = _mktemp(p);
32 if (fname == NULL)
33 return -1;
34 fd = open(fname, O_RDWR | O_CREAT | O_EXCL, _S_IREAD | _S_IWRITE);
35 if (fd >= 0)
36 return fd;
37 return -1;
38}
39#endif
40
41static char*
42mkdtemp(char *temp)
43{
44 char *path = _mktemp(temp);
45 if (path[0] == 0) return NULL;
46 if (_mkdir(path) < 0) return NULL;
47 return path;
48}
49
50#define umask(mode) _umask(mode)
51#define rmdir(path) _rmdir(path)
52#else
53 #include <sys/socket.h>
54 #include <unistd.h>
55 #include <sys/un.h>
56 #include <fcntl.h>
57#endif
58
59#include <sys/stat.h>
60#include <stdlib.h>
61
62#include "mruby.h"
63#include "mruby/array.h"
64#include "mruby/error.h"
65#include "mruby/string.h"
66#include "mruby/variable.h"
67#include <mruby/ext/io.h>
68
69int wd_save;
70int socket_available_p;
71
72#if !defined(_WIN32) && !defined(_WIN64)
73static int mrb_io_socket_available()
74{
75 int fd, retval = 0;
76 struct sockaddr_un sun0;
77 char socketname[] = "tmp.mruby-io-socket-ok.XXXXXXXX";
78 if (!(fd = mkstemp(socketname))) {
79 goto sock_test_out;
80 }
81 unlink(socketname);
82 close(fd);
83 fd = socket(AF_UNIX, SOCK_STREAM, 0);
84 if (fd == -1) {
85 goto sock_test_out;
86 }
87 sun0.sun_family = AF_UNIX;
88 strncpy(sun0.sun_path, socketname, sizeof(sun0.sun_path));
89 if (bind(fd, (struct sockaddr *)&sun0, sizeof(sun0)) == 0) {
90 retval = 1;
91 }
92sock_test_out:
93 unlink(socketname);
94 close(fd);
95 return retval;
96}
97#endif
98
99static mrb_value
100mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
101{
102 char rfname[] = "tmp.mruby-io-test-r.XXXXXXXX";
103 char wfname[] = "tmp.mruby-io-test-w.XXXXXXXX";
104 char symlinkname[] = "tmp.mruby-io-test-l.XXXXXXXX";
105 char socketname[] = "tmp.mruby-io-test-s.XXXXXXXX";
106 char msg[] = "mruby io test\n";
107 mode_t mask;
108 int fd0, fd1;
109 FILE *fp;
110
111#if !defined(_WIN32) && !defined(_WIN64)
112 int fd2, fd3;
113 struct sockaddr_un sun0;
114
115 if(!(socket_available_p = mrb_io_socket_available())) {
116 char *tmpdir;
117 wd_save = open(".", O_DIRECTORY);
118 tmpdir = getenv("TMPDIR");
119 if (tmpdir) chdir(tmpdir);
120 else chdir("/tmp");
121 }
122#endif
123
124 mask = umask(077);
125 fd0 = mkstemp(rfname);
126 fd1 = mkstemp(wfname);
127 if (fd0 == -1 || fd1 == -1) {
128 mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
129 return mrb_nil_value();
130 }
131 close(fd0);
132 close(fd1);
133
134#if !defined(_WIN32) && !defined(_WIN64)
135 fd2 = mkstemp(symlinkname);
136 fd3 = mkstemp(socketname);
137 if (fd2 == -1 || fd3 == -1) {
138 mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
139 return mrb_nil_value();
140 }
141#endif
142 umask(mask);
143
144 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"), mrb_str_new_cstr(mrb, rfname));
145 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"), mrb_str_new_cstr(mrb, wfname));
146 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"), mrb_str_new_cstr(mrb, symlinkname));
147 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_str_new_cstr(mrb, socketname));
148 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg));
149
150 fp = fopen(rfname, "wb");
151 if (fp == NULL) {
152 mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
153 return mrb_nil_value();
154 }
155 fputs(msg, fp);
156 fclose(fp);
157
158 fp = fopen(wfname, "wb");
159 if (fp == NULL) {
160 mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
161 return mrb_nil_value();
162 }
163 fclose(fp);
164
165#if !defined(_WIN32) && !defined(_WIN64)
166 unlink(symlinkname);
167 close(fd2);
168 if (symlink(rfname, symlinkname) == -1) {
169 mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link");
170 }
171
172 unlink(socketname);
173 close(fd3);
174 fd3 = socket(AF_UNIX, SOCK_STREAM, 0);
175 if (fd3 == -1) {
176 mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a socket");
177 }
178 sun0.sun_family = AF_UNIX;
179 strncpy(sun0.sun_path, socketname, sizeof(sun0.sun_path));
180 if (bind(fd3, (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
181 mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d",
182 sun0.sun_path,
183 errno);
184 }
185 close(fd3);
186#endif
187
188 return mrb_true_value();
189}
190
191static mrb_value
192mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self)
193{
194 mrb_value rfname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"));
195 mrb_value wfname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"));
196 mrb_value symlinkname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"));
197 mrb_value socketname = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"));
198
199 if (mrb_string_p(rfname)) {
200 remove(RSTRING_PTR(rfname));
201 }
202 if (mrb_string_p(wfname)) {
203 remove(RSTRING_PTR(wfname));
204 }
205 if (mrb_string_p(symlinkname)) {
206 remove(RSTRING_PTR(symlinkname));
207 }
208 if (mrb_string_p(socketname)) {
209 remove(RSTRING_PTR(socketname));
210 }
211
212 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"), mrb_nil_value());
213 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"), mrb_nil_value());
214 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"), mrb_nil_value());
215 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_nil_value());
216 mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_nil_value());
217
218#if !defined(_WIN32) && !defined(_WIN64)
219 if(!socket_available_p) {
220 fchdir(wd_save);
221 close(wd_save);
222 }
223#endif
224
225 return mrb_nil_value();
226}
227
228static mrb_value
229mrb_io_test_mkdtemp(mrb_state *mrb, mrb_value klass)
230{
231 mrb_value str;
232 char *cp;
233
234 mrb_get_args(mrb, "S", &str);
235 cp = mrb_str_to_cstr(mrb, str);
236 if (mkdtemp(cp) == NULL) {
237 mrb_sys_fail(mrb, "mkdtemp");
238 }
239 return mrb_str_new_cstr(mrb, cp);
240}
241
242static mrb_value
243mrb_io_test_rmdir(mrb_state *mrb, mrb_value klass)
244{
245 const char *cp;
246
247 mrb_get_args(mrb, "z", &cp);
248 if (rmdir(cp) == -1) {
249 mrb_sys_fail(mrb, "rmdir");
250 }
251 return mrb_true_value();
252}
253
254mrb_value
255mrb_io_win_p(mrb_state *mrb, mrb_value klass)
256{
257#if defined(_WIN32) || defined(_WIN64)
258# if defined(__CYGWIN__) || defined(__CYGWIN32__)
259 return mrb_false_value();
260# else
261 return mrb_true_value();
262# endif
263#else
264 return mrb_false_value();
265#endif
266}
267
268#ifdef MRB_WITH_IO_PREAD_PWRITE
269# define MRB_WITH_IO_PREAD_PWRITE_ENABLED TRUE
270#else
271# define MRB_WITH_IO_PREAD_PWRITE_ENABLED FALSE
272#endif
273
274void
275mrb_mruby_io_gem_test(mrb_state* mrb)
276{
277 struct RClass *io_test = mrb_define_module(mrb, "MRubyIOTestUtil");
278 mrb_define_class_method(mrb, io_test, "io_test_setup", mrb_io_test_io_setup, MRB_ARGS_NONE());
279 mrb_define_class_method(mrb, io_test, "io_test_cleanup", mrb_io_test_io_cleanup, MRB_ARGS_NONE());
280
281 mrb_define_class_method(mrb, io_test, "mkdtemp", mrb_io_test_mkdtemp, MRB_ARGS_REQ(1));
282 mrb_define_class_method(mrb, io_test, "rmdir", mrb_io_test_rmdir, MRB_ARGS_REQ(1));
283 mrb_define_class_method(mrb, io_test, "win?", mrb_io_win_p, MRB_ARGS_NONE());
284
285 mrb_define_const(mrb, io_test, "MRB_WITH_IO_PREAD_PWRITE", mrb_bool_value(MRB_WITH_IO_PREAD_PWRITE_ENABLED));
286}
Note: See TracBrowser for help on using the repository browser.