summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-09-11 16:13:11 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-09-11 16:13:11 +0000
commitcd69ef4c8a66e7155967a8b661a014856979cf31 (patch)
tree4a351ae4a4ca91abf29c85254b85ea8da71f74b0 /src
parent59a9dfd11860888a35e96dfe51af63cea5cecfe1 (diff)
merge: add evil files
SVN revision: 76464
Diffstat (limited to 'src')
-rw-r--r--src/bin/evil/Makefile.am53
-rw-r--r--src/bin/evil/evil_suite.c221
-rw-r--r--src/bin/evil/evil_suite.h14
-rw-r--r--src/bin/evil/evil_test_dlfcn.c80
-rw-r--r--src/bin/evil/evil_test_dlfcn.h8
-rw-r--r--src/bin/evil/evil_test_environment.c178
-rw-r--r--src/bin/evil/evil_test_environment.h8
-rw-r--r--src/bin/evil/evil_test_gettimeofday.c51
-rw-r--r--src/bin/evil/evil_test_gettimeofday.h8
-rw-r--r--src/bin/evil/evil_test_link.c158
-rw-r--r--src/bin/evil/evil_test_link.h8
-rw-r--r--src/bin/evil/evil_test_memcpy.c145
-rw-r--r--src/bin/evil/evil_test_memcpy.h8
-rw-r--r--src/bin/evil/evil_test_mkstemp.c53
-rw-r--r--src/bin/evil/evil_test_mkstemp.h8
-rw-r--r--src/bin/evil/evil_test_pipe.c126
-rw-r--r--src/bin/evil/evil_test_pipe.h8
-rw-r--r--src/bin/evil/evil_test_print.c46
-rw-r--r--src/bin/evil/evil_test_print.h8
-rw-r--r--src/bin/evil/evil_test_realpath.c44
-rw-r--r--src/bin/evil/evil_test_realpath.h8
-rw-r--r--src/bin/evil/evil_test_util.c110
-rw-r--r--src/bin/evil/evil_test_util.h8
-rw-r--r--src/bin/evil/memcpy_glibc_arm.S231
-rwxr-xr-xsrc/bin/evil/memcpy_glibc_i686.S81
-rw-r--r--src/bin/evil/test_evil.c27
-rw-r--r--src/lib/evil/Evil.h186
-rw-r--r--src/lib/evil/Makefile.am132
-rw-r--r--src/lib/evil/dirent.h141
-rw-r--r--src/lib/evil/dlfcn.c272
-rw-r--r--src/lib/evil/dlfcn.h258
-rw-r--r--src/lib/evil/evil_dirent.c197
-rw-r--r--src/lib/evil/evil_errno.c9
-rw-r--r--src/lib/evil/evil_fcntl.c124
-rw-r--r--src/lib/evil/evil_fcntl.h110
-rw-r--r--src/lib/evil/evil_fnmatch.c231
-rw-r--r--src/lib/evil/evil_fnmatch_list_of_states.c77
-rw-r--r--src/lib/evil/evil_fnmatch_private.h24
-rw-r--r--src/lib/evil/evil_inet.c648
-rw-r--r--src/lib/evil/evil_inet.h149
-rw-r--r--src/lib/evil/evil_langinfo.c53
-rw-r--r--src/lib/evil/evil_langinfo.h41
-rw-r--r--src/lib/evil/evil_libgen.c103
-rw-r--r--src/lib/evil/evil_libgen.h88
-rw-r--r--src/lib/evil/evil_link_ce.c90
-rw-r--r--src/lib/evil/evil_link_xp.cpp151
-rw-r--r--src/lib/evil/evil_macro.h193
-rw-r--r--src/lib/evil/evil_macro_pop.h93
-rw-r--r--src/lib/evil/evil_main.c74
-rw-r--r--src/lib/evil/evil_main.h52
-rw-r--r--src/lib/evil/evil_mman.c234
-rw-r--r--src/lib/evil/evil_pformat.h61
-rw-r--r--src/lib/evil/evil_pformata.c2493
-rw-r--r--src/lib/evil/evil_pformatw.c9
-rw-r--r--src/lib/evil/evil_print.h37
-rw-r--r--src/lib/evil/evil_printa.c1786
-rw-r--r--src/lib/evil/evil_printw.c4
-rw-r--r--src/lib/evil/evil_private.h20
-rw-r--r--src/lib/evil/evil_pwd.c65
-rw-r--r--src/lib/evil/evil_stdio.c215
-rw-r--r--src/lib/evil/evil_stdio.h196
-rw-r--r--src/lib/evil/evil_stdlib.c453
-rw-r--r--src/lib/evil/evil_stdlib.h199
-rw-r--r--src/lib/evil/evil_string.c128
-rw-r--r--src/lib/evil/evil_string.h152
-rw-r--r--src/lib/evil/evil_time.c45
-rw-r--r--src/lib/evil/evil_time.h61
-rw-r--r--src/lib/evil/evil_unistd.c431
-rw-r--r--src/lib/evil/evil_unistd.h326
-rw-r--r--src/lib/evil/evil_util.c247
-rw-r--r--src/lib/evil/evil_util.h134
-rw-r--r--src/lib/evil/evil_uuid.c12
-rw-r--r--src/lib/evil/fnmatch.h54
-rw-r--r--src/lib/evil/gdtoa/README357
-rw-r--r--src/lib/evil/gdtoa/README.mingw20
-rw-r--r--src/lib/evil/gdtoa/arithchk.c192
-rw-r--r--src/lib/evil/gdtoa/dmisc.c196
-rw-r--r--src/lib/evil/gdtoa/dtoa.c750
-rw-r--r--src/lib/evil/gdtoa/g__fmt.c142
-rw-r--r--src/lib/evil/gdtoa/g_dfmt.c90
-rw-r--r--src/lib/evil/gdtoa/g_ffmt.c88
-rw-r--r--src/lib/evil/gdtoa/g_xfmt.c143
-rw-r--r--src/lib/evil/gdtoa/gd_arith.h6
-rw-r--r--src/lib/evil/gdtoa/gd_qnan.h12
-rw-r--r--src/lib/evil/gdtoa/gdtoa.c733
-rw-r--r--src/lib/evil/gdtoa/gdtoa.h121
-rw-r--r--src/lib/evil/gdtoa/gdtoa_fltrnds.h18
-rw-r--r--src/lib/evil/gdtoa/gdtoaimp.h645
-rw-r--r--src/lib/evil/gdtoa/gethex.c340
-rw-r--r--src/lib/evil/gdtoa/gmisc.c76
-rw-r--r--src/lib/evil/gdtoa/hd_init.c49
-rw-r--r--src/lib/evil/gdtoa/hexnan.c139
-rw-r--r--src/lib/evil/gdtoa/misc.c860
-rw-r--r--src/lib/evil/gdtoa/qnan.c116
-rw-r--r--src/lib/evil/gdtoa/smisc.c149
-rw-r--r--src/lib/evil/gdtoa/strtodg.c979
-rw-r--r--src/lib/evil/gdtoa/strtof.c77
-rw-r--r--src/lib/evil/gdtoa/strtopx.c119
-rw-r--r--src/lib/evil/gdtoa/sum.c91
-rw-r--r--src/lib/evil/gdtoa/ulp.c61
-rw-r--r--src/lib/evil/mingw32ce/errno.h111
-rw-r--r--src/lib/evil/pwd.h71
-rw-r--r--src/lib/evil/sys/mman.h149
103 files changed, 19456 insertions, 0 deletions
diff --git a/src/bin/evil/Makefile.am b/src/bin/evil/Makefile.am
new file mode 100644
index 0000000000..538bbdcc69
--- /dev/null
+++ b/src/bin/evil/Makefile.am
@@ -0,0 +1,53 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4AM_CPPFLAGS = \
5-I$(top_srcdir) \
6-I$(top_srcdir)/bin \
7-I$(top_srcdir)/src/lib \
8@EVIL_CPPFLAGS@
9
10AM_CFLAGS = @EVIL_CFLAGS@
11
12bin_PROGRAMS = evil_suite test_evil
13
14evil_suite_SOURCES = \
15evil_suite.c \
16evil_test_dlfcn.c \
17evil_test_environment.c \
18evil_test_gettimeofday.c \
19evil_test_link.c \
20evil_test_memcpy.c \
21evil_test_mkstemp.c \
22evil_test_pipe.c \
23evil_test_print.c \
24evil_test_realpath.c \
25evil_test_util.c \
26evil_suite.h \
27evil_test_dlfcn.h \
28evil_test_environment.h \
29evil_test_gettimeofday.h \
30evil_test_link.h \
31evil_test_memcpy.h \
32evil_test_mkstemp.h \
33evil_test_pipe.h \
34evil_test_print.h \
35evil_test_realpath.h \
36evil_test_util.h
37
38if EVIL_HAVE_WINCE
39
40evil_suite_SOURCES += memcpy_glibc_arm.S
41
42#else
43
44#suite_SOURCES += memcpy_glibc_i686.S
45
46endif
47
48evil_suite_LDADD = $(top_builddir)/src/lib/libdl.la $(top_builddir)/src/lib/libevil.la -lm
49evil_suite_LDFLAGS = -Wl,--enable-auto-import
50
51test_evil_SOURCES = test_evil.c
52test_evil_LDADD = $(top_builddir)/src/lib/libevil.la
53test_evil_LDFLAGS = -Wl,--enable-auto-import
diff --git a/src/bin/evil/evil_suite.c b/src/bin/evil/evil_suite.c
new file mode 100644
index 0000000000..ba928f0682
--- /dev/null
+++ b/src/bin/evil/evil_suite.c
@@ -0,0 +1,221 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdlib.h>
6#include <stdio.h>
7
8#define WIN32_LEAN_AND_MEAN
9#include <windows.h>
10#undef WIN32_LEAN_AND_MEAN
11
12#include "Evil.h"
13#include "evil_suite.h"
14#include "evil_test_dlfcn.h"
15#include "evil_test_environment.h"
16#include "evil_test_gettimeofday.h"
17#include "evil_test_link.h"
18#include "evil_test_memcpy.h"
19#include "evil_test_mkstemp.h"
20#include "evil_test_pipe.h"
21#include "evil_test_print.h"
22#include "evil_test_realpath.h"
23#include "evil_test_util.h"
24
25
26typedef int(*function)(suite *s);
27
28struct test
29{
30 const char *name;
31 function fct;
32};
33
34struct list
35{
36 void *data;
37 int succeed;
38 list *next;
39};
40
41struct suite
42{
43 LARGE_INTEGER freq;
44 LARGE_INTEGER start;
45 LARGE_INTEGER end;
46
47 list *first;
48 list *l;
49
50 int tests_count;
51 int tests_success;
52};
53
54
55static suite *
56suite_new(void)
57{
58 suite *s;
59
60 s = (suite *)malloc(sizeof(suite));
61 if (!s) return NULL;
62
63 if (!QueryPerformanceFrequency(&s->freq))
64 {
65 free(s);
66 return NULL;
67 }
68
69 s->first = NULL;
70 s->l = NULL;
71
72 s->tests_count = 0;
73 s->tests_success = 0;
74
75 return s;
76}
77
78static void
79suite_del(suite *s)
80{
81 list *l;
82 list *tmp;
83
84 if (!s) return;
85
86 l = s->first;
87 while (l)
88 {
89 tmp = l->next;
90 free(l->data);
91 free(l);
92 l = tmp;
93 }
94
95 free(s);
96}
97
98void
99suite_time_start(suite *s)
100{
101 QueryPerformanceCounter(&s->start);
102}
103
104void
105suite_time_stop(suite *s)
106{
107 QueryPerformanceCounter(&s->end);
108}
109
110double
111suite_time_get(suite *s)
112{
113 return (double)(s->end.QuadPart - s->start.QuadPart) / (double)s->freq.QuadPart;
114}
115
116static void
117suite_test_add(suite *s, const char *name, function fct)
118{
119 test *t;
120 list *l;
121
122 t = (test *)malloc(sizeof(test));
123 if (!t) return;
124
125 l = (list *)malloc(sizeof(list));
126 if (!l)
127 {
128 free(t);
129 return;
130 }
131
132 t->name = name;
133 t->fct = fct;
134
135 l->data = t;
136 l->succeed = 0;
137 l->next = NULL;
138
139 if (!s->first) s->first = l;
140
141 if (!s->l)
142 s->l = l;
143 else
144 {
145 s->l->next = l;
146 s->l =l;
147 }
148}
149
150static void
151suite_run(suite *s)
152{
153 list *l;
154
155 l = s->first;
156 while (l)
157 {
158 test *t;
159
160 t = (test *)l->data;
161 l->succeed = t->fct(s);
162 printf("%s test: %s\n", t->name, l->succeed ? "success" : "failure");
163 s->tests_count++;
164 if (l->succeed)
165 s->tests_success++;
166 l = l->next;
167 }
168}
169
170static void
171suite_show(suite *s)
172{
173 printf ("\n%d/%d tests passed (%d%%)\n",
174 s->tests_success,
175 s->tests_count,
176 (100 * s->tests_success) / s->tests_count);
177}
178
179int
180main(void)
181{
182 test tests[] = {
183 { "dlfcn ", test_dlfcn },
184 { "environment ", test_environment },
185 { "gettimeofday", test_gettimeofday },
186 { "link ", test_link },
187 { "mkstemp ", test_mkstemp },
188 { "pipe ", test_pipe },
189 { "print ", test_print },
190 { "realpath ", test_realpath },
191 { "util ", test_util },
192/* { "memcpy ", test_memcpy }, */
193 { NULL, NULL },
194 };
195 suite *s;
196 int i;
197
198 if (!evil_init())
199 return EXIT_FAILURE;
200
201 s = suite_new();
202 if (!s)
203 {
204 evil_shutdown();
205 return EXIT_FAILURE;
206 }
207
208 for (i = 0; tests[i].name; ++i)
209 {
210 suite_test_add(s, tests[i].name, tests[i].fct);
211 }
212
213 suite_run(s);
214
215 suite_show(s);
216
217 suite_del(s);
218 evil_shutdown();
219
220 return EXIT_SUCCESS;
221}
diff --git a/src/bin/evil/evil_suite.h b/src/bin/evil/evil_suite.h
new file mode 100644
index 0000000000..d3284b4fbb
--- /dev/null
+++ b/src/bin/evil/evil_suite.h
@@ -0,0 +1,14 @@
1#ifndef __EVIL_SUITE_H__
2#define __EVIL_SUITE_H__
3
4
5typedef struct test test;
6typedef struct list list;
7typedef struct suite suite;
8
9void suite_time_start(suite *s);
10void suite_time_stop(suite *s);
11double suite_time_get(suite *s);
12
13
14#endif /* __EVIL_SUITE_H__ */
diff --git a/src/bin/evil/evil_test_dlfcn.c b/src/bin/evil/evil_test_dlfcn.c
new file mode 100644
index 0000000000..fb32dd1540
--- /dev/null
+++ b/src/bin/evil/evil_test_dlfcn.c
@@ -0,0 +1,80 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <string.h>
6#include <dlfcn.h>
7
8#include <Evil.h>
9
10#include "evil_suite.h"
11#include "evil_test_dlfcn.h"
12
13
14typedef int (*_evil_init)(void);
15typedef int (*_evil_shutdwon)(void);
16
17
18static int
19test_dlfcn_test_dlopen(void)
20{
21 void *handle;
22
23 handle = dlopen("libevil-1.dll", 0);
24 if (!handle)
25 return 0;
26
27 if (dlclose(handle))
28 return 0;
29
30 return 1;
31}
32
33static int
34test_dlfcn_test_dlsym(void)
35{
36 void *handle;
37 _evil_init sym_init;
38 _evil_shutdwon sym_shutdown;
39
40 handle = dlopen("libevil-1.dll", 0);
41 if (!handle)
42 return 0;
43
44 sym_init = dlsym(handle, "evil_init");
45 if (!sym_init)
46 {
47 dlclose(handle);
48 return 0;
49 }
50
51 sym_shutdown = dlsym(handle, "evil_shutdown");
52 if (!sym_shutdown)
53 {
54 dlclose(handle);
55 return 0;
56 }
57
58 if (dlclose(handle))
59 return 0;
60
61 return 1;
62}
63
64static int
65test_dlfcn_tests_run(suite *s __UNUSED__)
66{
67 int res;
68
69 res = test_dlfcn_test_dlopen();
70 res &= test_dlfcn_test_dlsym();
71
72 return res;
73}
74
75int
76test_dlfcn(suite *s)
77{
78
79 return test_dlfcn_tests_run(s);
80}
diff --git a/src/bin/evil/evil_test_dlfcn.h b/src/bin/evil/evil_test_dlfcn.h
new file mode 100644
index 0000000000..0c9bce689e
--- /dev/null
+++ b/src/bin/evil/evil_test_dlfcn.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_DLFCN_H__
2#define __EVIL_TEST_DLFCN_H__
3
4
5int test_dlfcn(suite *s);
6
7
8#endif /* __EVIL_TEST_DLFCN_H__ */
diff --git a/src/bin/evil/evil_test_environment.c b/src/bin/evil/evil_test_environment.c
new file mode 100644
index 0000000000..3048a40124
--- /dev/null
+++ b/src/bin/evil/evil_test_environment.c
@@ -0,0 +1,178 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <string.h>
6
7#include <Evil.h>
8
9#include "evil_suite.h"
10#include "evil_test_environment.h"
11
12
13static int
14test_env_test_setenv_NULL(void)
15{
16 char *val;
17 int res;
18
19 res = setenv("EVIL_TEST_ENV", NULL, 1);
20 if (res < 0)
21 return 0;
22
23 val = getenv("EVIL_TEST_ENV");
24
25 return val ? 0 : 1;
26}
27
28static int
29test_env_test_setenv_NULL_after_set(void)
30{
31 char *val;
32 int res;
33
34 res = setenv("EVIL_TEST_ENV", "val", 1);
35 if (res < 0)
36 return 0;
37
38 val = getenv("EVIL_TEST_ENV");
39 if (!val)
40 return 0;
41
42 if (strcmp(val, "val"))
43 return 0;
44
45 res = setenv("EVIL_TEST_ENV", NULL, 1);
46 if (res < 0)
47 return 0;
48
49 val = getenv("EVIL_TEST_ENV");
50
51 return val ? 0 : 1;
52}
53
54static int
55test_env_test_getenv_one(void)
56{
57 char *val;
58 int res;
59
60 res = setenv("EVIL_TEST_ENV", "val", 1);
61 if (res < 0)
62 return 0;
63
64 val = getenv("EVIL_TEST_ENV");
65 if (!val)
66 return 0;
67
68 if (strcmp(val, "val"))
69 return 0;
70
71 return 1;
72}
73
74static int
75test_env_test_getenv_two(void)
76{
77 char *val;
78 int res;
79
80 res = setenv("EVIL_TEST_ENV1", "val1", 1);
81 if (res < 0)
82 return 0;
83
84 res = setenv("EVIL_TEST_ENV2", "val2", 1);
85 if (res < 0)
86 return 0;
87
88 val = getenv("EVIL_TEST_ENV1");
89 if (!val)
90 return 0;
91 if (strcmp(val, "val1"))
92 return 0;
93
94 val = getenv("EVIL_TEST_ENV2");
95 if (!val)
96 return 0;
97
98 if (strcmp(val, "val2"))
99 return 0;
100
101 return 1;
102}
103
104static int
105test_env_test_getenv_two_swapped(void)
106{
107 char *val;
108 int res;
109
110 res = setenv("EVIL_TEST_ENV1", "val1", 1);
111 if (res < 0)
112 return 0;
113
114 res = setenv("EVIL_TEST_ENV2", "val2", 1);
115 if (res < 0)
116 return 0;
117
118 val = getenv("EVIL_TEST_ENV2");
119 if (!val)
120 return 0;
121 if (strcmp(val, "val2"))
122 return 0;
123
124 val = getenv("EVIL_TEST_ENV1");
125 if (!val)
126 return 0;
127
128 if (strcmp(val, "val1"))
129 return 0;
130
131 return 1;
132}
133
134static int
135test_env_test_unsetenv(void)
136{
137 char *val;
138 int res;
139
140 res = setenv("EVIL_TEST_ENV", "val", 1);
141 if (res < 0)
142 return 0;
143
144 val = getenv("EVIL_TEST_ENV");
145 if (!val)
146 return 0;
147
148 if (unsetenv("EVIL_TEST_ENV") != 0)
149 return 0;
150
151 val = getenv("EVIL_TEST_ENV");
152 if (val)
153 return 0;
154
155 return 1;
156}
157
158static int
159test_env_tests_run(suite *s __UNUSED__)
160{
161 int res;
162
163 res = test_env_test_setenv_NULL();
164 res &= test_env_test_setenv_NULL_after_set();
165 res &= test_env_test_getenv_one();
166 res &= test_env_test_getenv_two();
167 res &= test_env_test_getenv_two_swapped();
168 res &= test_env_test_unsetenv();
169
170 return res;
171}
172
173int
174test_environment(suite *s)
175{
176
177 return test_env_tests_run(s);
178}
diff --git a/src/bin/evil/evil_test_environment.h b/src/bin/evil/evil_test_environment.h
new file mode 100644
index 0000000000..763ee401b1
--- /dev/null
+++ b/src/bin/evil/evil_test_environment.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_ENVIRONMENT_H__
2#define __EVIL_TEST_ENVIRONMENT_H__
3
4
5int test_environment(suite *s);
6
7
8#endif /* __EVIL_TEST_ENVIRONMENT_H__ */
diff --git a/src/bin/evil/evil_test_gettimeofday.c b/src/bin/evil/evil_test_gettimeofday.c
new file mode 100644
index 0000000000..49742eb5d3
--- /dev/null
+++ b/src/bin/evil/evil_test_gettimeofday.c
@@ -0,0 +1,51 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <string.h>
6#include <math.h>
7#include <sys/time.h>
8
9#include <Evil.h>
10
11#include "evil_suite.h"
12#include "evil_test_gettimeofday.h"
13
14static int
15test_time_test_gettimeofday(void)
16{
17 struct timeval tp1;
18 struct timeval tp2;
19 double delta;
20
21 gettimeofday (&tp1, NULL);
22
23 Sleep(1000);
24
25 gettimeofday (&tp2, NULL);
26
27 delta = (double)(tp2.tv_sec - tp1.tv_sec) + (double)(tp2.tv_usec - tp1.tv_usec) / 1000000.0;
28 if (fabs(delta - 1) > 0.005)
29 {
30 return 0;
31 }
32
33 return 1;
34}
35
36static int
37test_time_tests_run(suite *s __UNUSED__)
38{
39 int res;
40
41 res = test_time_test_gettimeofday();
42
43 return res;
44}
45
46int
47test_gettimeofday(suite *s)
48{
49
50 return test_time_tests_run(s);
51}
diff --git a/src/bin/evil/evil_test_gettimeofday.h b/src/bin/evil/evil_test_gettimeofday.h
new file mode 100644
index 0000000000..ad3155b146
--- /dev/null
+++ b/src/bin/evil/evil_test_gettimeofday.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_GETTIMEOFDAY_H__
2#define __EVIL_TEST_GETTIMEOFDAY_H__
3
4
5int test_gettimeofday(suite *s);
6
7
8#endif /* __EVIL_TEST_GETTIMEOFDAY_H__ */
diff --git a/src/bin/evil/evil_test_link.c b/src/bin/evil/evil_test_link.c
new file mode 100644
index 0000000000..cf4cd931ae
--- /dev/null
+++ b/src/bin/evil/evil_test_link.c
@@ -0,0 +1,158 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <string.h>
6
7#include <Evil.h>
8
9#include "evil_suite.h"
10#include "evil_test_link.h"
11
12static int
13test_link_test_file_create(const char *name, const char *data)
14{
15 FILE *f;
16 size_t length;
17 size_t res;
18
19 f = fopen(name, "wb");
20 if (!f)
21 return 0;
22
23 length = strlen(data) + 1;
24 res = fwrite(data, 1, length, f);
25 if (res < length)
26 {
27 fclose(f);
28 return 0;
29 }
30
31 fclose(f);
32
33 return 1;
34}
35
36static int
37test_link_test_symlink(void)
38{
39#ifdef _WIN32_WCE
40 const char *old_name = "\\efl\\evil_test_link.dat";
41 const char *new_name = "\\efl\\evil_test_link.lnk";
42#else
43 const char *old_name = "evil_test_link.dat";
44 const char *new_name = "evil_test_link.lnk";
45#endif
46
47 if (!test_link_test_file_create(old_name,
48 "evil_test_link symlink data\n"))
49 return 0;
50
51 if (symlink(old_name, new_name) < 0)
52 {
53 unlink(old_name);
54 return 0;
55 }
56
57 if (unlink(new_name) < 0)
58 {
59 unlink(old_name);
60 return 0;
61 }
62
63 if (unlink(old_name) < 0)
64 return 0;
65
66 return 1;
67}
68
69static int
70test_link_test_readlink(void)
71{
72 char buf[1024];
73#ifdef _WIN32_WCE
74 const char *old_name = "\\efl\\evil_test_link.dat";
75 const char *new_name = "\\efl\\evil_test_link.lnk";
76#else
77 const char *old_name = "evil_test_link.dat";
78 const char *new_name = "evil_test_link.lnk";
79#endif
80 const char *data = "evil_test_link symlink data\n";
81 FILE *f;
82 ssize_t s1;
83 size_t s2;
84 int l;
85
86 if (!test_link_test_file_create(old_name, data))
87 return 0;
88
89 if (symlink(old_name, new_name) < 0)
90 return 0;
91
92 if ((s1 = readlink(new_name, buf, 1023)) < 0)
93 {
94 unlink(old_name);
95 unlink(new_name);
96 return 0;
97 }
98
99 buf[s1] = '\0';
100
101 f = fopen(buf, "rb");
102 if (!f)
103 {
104 unlink(old_name);
105 unlink(new_name);
106 return 0;
107 }
108
109 l = strlen(data);
110 s2 = fread(buf, 1, l + 1, f);
111
112 if ((int)s2 != (l + 1))
113 {
114 fclose(f);
115 unlink(old_name);
116 unlink(new_name);
117 return 0;
118 }
119
120 if (strcmp(buf, data))
121 {
122 fclose(f);
123 unlink(old_name);
124 unlink(new_name);
125 return 0;
126 }
127
128 fclose(f);
129
130 if (unlink(new_name) < 0)
131 {
132 unlink(old_name);
133 return 0;
134 }
135
136 if (unlink(old_name) < 0)
137 return 0;
138
139 return 1;
140}
141
142static int
143test_link_tests_run(suite *s __UNUSED__)
144{
145 int res;
146
147 res = test_link_test_symlink();
148 res &= test_link_test_readlink();
149
150 return res;
151}
152
153int
154test_link(suite *s)
155{
156
157 return test_link_tests_run(s);
158}
diff --git a/src/bin/evil/evil_test_link.h b/src/bin/evil/evil_test_link.h
new file mode 100644
index 0000000000..6f8bfa2328
--- /dev/null
+++ b/src/bin/evil/evil_test_link.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_LINK_H__
2#define __EVIL_TEST_LINK_H__
3
4
5int test_link(suite *s);
6
7
8#endif /* __EVIL_TEST_LINK_H__ */
diff --git a/src/bin/evil/evil_test_memcpy.c b/src/bin/evil/evil_test_memcpy.c
new file mode 100644
index 0000000000..0adfe373f0
--- /dev/null
+++ b/src/bin/evil/evil_test_memcpy.c
@@ -0,0 +1,145 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdlib.h>
6#include <stdio.h>
7
8#define WIN32_LEAN_AND_MEAN
9#include <windows.h>
10#undef WIN32_LEAN_AND_MEAN
11
12#include "evil_suite.h"
13#include "evil_test_memcpy.h"
14
15
16typedef void *(*memcpy_decl)(void *dest, const void *src, size_t n);
17
18void *memcpy_glibc(void *dest, const void *src, size_t n);
19
20
21static unsigned char *buf1 = NULL;
22static unsigned char *buf2 = NULL;
23static size_t page_size = 0;
24
25
26#if defined (__MINGW32CE__) || defined (_MSC_VER)
27static int
28getpagesize()
29{
30 return 1024;
31}
32#endif /* __MINGW32CE__ || _MSC_VER */
33
34
35static void
36test_memcpy_test_run(suite *s, memcpy_decl fct, char *dst, const char *src, size_t len)
37{
38 double best;
39 int i;
40
41 best = 1000000000.0;
42
43 for (i = 0; i < 128; ++i)
44 {
45 double time;
46
47 suite_time_start(s);
48 fct(dst, src, len);
49 suite_time_stop(s);
50 time = suite_time_get(s);
51 if (time < best) best = time;
52 }
53
54 printf (" %e", best);
55}
56
57static void
58test_memcpy_tests_run(suite *s, size_t align1, size_t align2, size_t len)
59{
60 size_t i, j;
61 char *s1, *s2;
62
63 printf ("running test..\n");
64
65/* align1 &= 63; */
66/* if (align1 + len >= page_size) */
67/* return; */
68
69/* align2 &= 63; */
70/* if (align2 + len >= page_size) */
71/* return; */
72
73 s1 = (char *) (buf1 + align1);
74 s2 = (char *) (buf2 + align2);
75
76 for (i = 0, j = 1; i < len; i++, j += 23)
77 s1[i] = j;
78
79 printf ("length: %6d, align %2d/%2d:", (int)len, align1, align2);
80
81 test_memcpy_test_run(s, memcpy, s2, s1, len);
82#ifdef _WIN32_WCE
83 test_memcpy_test_run(s, memcpy_glibc, s2, s1, len);
84#endif /* _WIN32_WCE */
85
86 printf ("\n");
87}
88
89int
90test_memcpy(suite *s)
91{
92 size_t i;
93
94 page_size = 2 * 1024;
95
96 buf1 = (unsigned char *)malloc(16 * getpagesize());
97 if (!buf1) return 0;
98
99 buf2 = (unsigned char *)malloc(16 * getpagesize());
100 if (!buf2)
101 {
102 free(buf1);
103 return 0;
104 }
105
106 memset (buf1, 0xa5, page_size);
107 memset (buf2, 0x5a, page_size);
108
109 for (i = 0; i < 5; ++i)
110 {
111 test_memcpy_tests_run(s, 0, 0, 1 << i);
112 test_memcpy_tests_run(s, i, 0, 1 << i);
113 test_memcpy_tests_run(s, 0, i, 1 << i);
114 test_memcpy_tests_run(s, i, i, 1 << i);
115 }
116
117 for (i = 0; i < 32; ++i)
118 {
119 test_memcpy_tests_run(s, 0, 0, i);
120 test_memcpy_tests_run(s, i, 0, i);
121 test_memcpy_tests_run(s, 0, i, i);
122 test_memcpy_tests_run(s, i, i, i);
123 }
124
125 for (i = 3; i < 32; ++i)
126 {
127 if ((i & (i - 1)) == 0)
128 continue;
129 test_memcpy_tests_run(s, 0, 0, 16 * i);
130 test_memcpy_tests_run(s, i, 0, 16 * i);
131 test_memcpy_tests_run(s, 0, i, 16 * i);
132 test_memcpy_tests_run(s, i, i, 16 * i);
133 }
134
135 test_memcpy_tests_run(s, 0, 0, getpagesize ());
136 test_memcpy_tests_run(s, 0, 0, 2 * getpagesize ());
137 test_memcpy_tests_run(s, 0, 0, 4 * getpagesize ());
138 test_memcpy_tests_run(s, 0, 0, 8 * getpagesize ());
139 test_memcpy_tests_run(s, 0, 0, 16 * getpagesize ());
140
141 free(buf2);
142 free(buf1);
143
144 return 1;
145}
diff --git a/src/bin/evil/evil_test_memcpy.h b/src/bin/evil/evil_test_memcpy.h
new file mode 100644
index 0000000000..808dd09f37
--- /dev/null
+++ b/src/bin/evil/evil_test_memcpy.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_MEMCPY__
2#define __EVIL_TEST_MEMCPY__
3
4
5int test_memcpy(suite *s);
6
7
8#endif /* __EVIL_TEST_MEMCPY__ */
diff --git a/src/bin/evil/evil_test_mkstemp.c b/src/bin/evil/evil_test_mkstemp.c
new file mode 100644
index 0000000000..dc8c4e64f5
--- /dev/null
+++ b/src/bin/evil/evil_test_mkstemp.c
@@ -0,0 +1,53 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <string.h>
6
7#include <Evil.h>
8
9#include "evil_suite.h"
10#include "evil_test_mkstemp.h"
11
12
13static int
14test_mkstemp_test(void)
15{
16 char _template[PATH_MAX];
17#ifdef _WIN32_WCE
18 char cwd[PATH_MAX];
19#endif
20 int fd;
21
22#ifdef _WIN32_WCE
23 if (!getcwd(cwd, PATH_MAX))
24 return 0;
25 _snprintf(_template, PATH_MAX, "%s\\%s", cwd, "file_XXXXXX");
26#else
27 _snprintf(_template, PATH_MAX, "%s", "file_XXXXXX");
28#endif
29
30 fd = mkstemp(_template);
31
32 if (fd < 0)
33 return 0;
34
35 return 1;
36}
37
38static int
39test_mkstemp_run(suite *s __UNUSED__)
40{
41 int res;
42
43 res = test_mkstemp_test();
44
45 return res;
46}
47
48int
49test_mkstemp(suite *s)
50{
51
52 return test_mkstemp_run(s);
53}
diff --git a/src/bin/evil/evil_test_mkstemp.h b/src/bin/evil/evil_test_mkstemp.h
new file mode 100644
index 0000000000..f5bb0c4270
--- /dev/null
+++ b/src/bin/evil/evil_test_mkstemp.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_MKSTEMP_H__
2#define __EVIL_TEST_MKSTEMP_H__
3
4
5int test_mkstemp(suite *s);
6
7
8#endif /* __EVIL_TEST_MKSTEMP_H__ */
diff --git a/src/bin/evil/evil_test_pipe.c b/src/bin/evil/evil_test_pipe.c
new file mode 100644
index 0000000000..2fc530d545
--- /dev/null
+++ b/src/bin/evil/evil_test_pipe.c
@@ -0,0 +1,126 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdlib.h>
6#include <stdio.h>
7
8# define WIN32_LEAN_AND_MEAN
9# include <winsock2.h>
10# undef WIN32_LEAN_AND_MEAN
11
12#include <Evil.h>
13
14#include "evil_suite.h"
15#include "evil_test_pipe.h"
16
17
18#define FDREAD 0
19#define FDWRITE 1
20
21typedef struct
22{
23 int val;
24 int fd_write;
25} data;
26
27
28static DWORD WINAPI
29thread (void *param)
30{
31 data *d;
32 void *buf[1];
33
34 Sleep (2 * 1000);
35 d = (data *)param;
36 buf[0] = d;
37 send(d->fd_write, (char *)buf, sizeof(buf), 0);
38
39 return 0;
40}
41
42static int
43test_pipe_test(void)
44{
45 int sockets[2];
46 struct timeval t;
47 fd_set rfds;
48 int ret;
49 data *d;
50 DWORD thread_id;
51 HANDLE h;
52
53 FD_ZERO(&rfds);
54
55 t.tv_sec = 5;
56 t.tv_usec = 0;
57
58 if (pipe(sockets) < 0)
59 return 0;
60
61 FD_SET(sockets[FDREAD], &rfds);
62 fcntl(sockets[FDREAD], F_SETFL, O_NONBLOCK);
63
64 d = (data *)malloc(sizeof (data));
65 if (!d)
66 return 0;
67
68 d->val = 14;
69 d->fd_write = sockets[FDWRITE];
70
71 h = CreateThread(NULL, 0, thread, d, 0, &thread_id);
72 if (!h)
73
74 ret = select(sockets[FDREAD] + 1, &rfds, NULL, NULL, &t);
75
76 if (ret < 0)
77 goto free_d;
78 else if (ret == 0)
79 goto close_h;
80 else /* ret > 0 */
81 {
82 void *buf[1];
83 data *d2 = NULL;
84 int len;
85
86 while ((len = recv(sockets[FDREAD], (char *)buf, sizeof(buf), 0)) > 0)
87 {
88 if (len == sizeof(buf))
89 {
90 d2 = (data *)buf[0];
91 break;
92 }
93 }
94 if (d2 && (d2->val == d->val))
95 ret = 1;
96 else
97 ret = 0;
98 }
99
100 CloseHandle(h);
101 free(d);
102
103 return ret;
104
105 close_h:
106 CloseHandle(h);
107 free_d:
108 free(d);
109 return 0;
110}
111
112static int
113test_pipe_run(suite *s __UNUSED__)
114{
115 int res;
116
117 res = test_pipe_test();
118
119 return res;
120}
121
122int
123test_pipe(suite *s)
124{
125 return test_pipe_run(s);
126}
diff --git a/src/bin/evil/evil_test_pipe.h b/src/bin/evil/evil_test_pipe.h
new file mode 100644
index 0000000000..ff8041f716
--- /dev/null
+++ b/src/bin/evil/evil_test_pipe.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_PIPE_H__
2#define __EVIL_TEST_PIPE_H__
3
4
5int test_pipe(suite *s);
6
7
8#endif /* __EVIL_TEST_PIPE_H__ */
diff --git a/src/bin/evil/evil_test_print.c b/src/bin/evil/evil_test_print.c
new file mode 100644
index 0000000000..b930a538f4
--- /dev/null
+++ b/src/bin/evil/evil_test_print.c
@@ -0,0 +1,46 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdlib.h>
6#include <stdio.h>
7
8#include <Evil.h>
9
10#include "evil_suite.h"
11#include "evil_test_print.h"
12
13static int
14test_print_test(void)
15{
16 char buf[16];
17 int i1 = 1;
18 size_t i2 = 123456;
19 int res;
20
21 res = printf("%02hhd\n", i1);
22 if (res != 3)
23 return 0;
24
25 res = snprintf(buf, sizeof(buf), "%zu", i2);
26 if (res != 6)
27 return 0;
28
29 return 1;
30}
31
32static int
33test_print_run(suite *s __UNUSED__)
34{
35 int res;
36
37 res = test_print_test();
38
39 return res;
40}
41
42int
43test_print(suite *s)
44{
45 return test_print_run(s);
46}
diff --git a/src/bin/evil/evil_test_print.h b/src/bin/evil/evil_test_print.h
new file mode 100644
index 0000000000..2bbf43904f
--- /dev/null
+++ b/src/bin/evil/evil_test_print.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_PRINT_H__
2#define __EVIL_TEST_PRINT_H__
3
4
5int test_print(suite *s);
6
7
8#endif /* __EVIL_TEST_PRINT_H__ */
diff --git a/src/bin/evil/evil_test_realpath.c b/src/bin/evil/evil_test_realpath.c
new file mode 100644
index 0000000000..f9a48cb977
--- /dev/null
+++ b/src/bin/evil/evil_test_realpath.c
@@ -0,0 +1,44 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <string.h>
6
7#include <Evil.h>
8
9#include "evil_suite.h"
10#include "evil_test_realpath.h"
11
12
13static int
14test_realpath_test(void)
15{
16 char buf[PATH_MAX];
17 char *filename;
18 char *result;
19
20 filename = "evil_suite.exe";
21
22 if (!(result = realpath(filename, buf)))
23 return 0;
24
25 printf ("res : %s\n", buf);
26
27 return 1;
28}
29
30static int
31test_realpath_run(suite *s __UNUSED__)
32{
33 int res;
34
35 res = test_realpath_test();
36
37 return res;
38}
39
40int
41test_realpath(suite *s)
42{
43 return test_realpath_run(s);
44}
diff --git a/src/bin/evil/evil_test_realpath.h b/src/bin/evil/evil_test_realpath.h
new file mode 100644
index 0000000000..0205aad149
--- /dev/null
+++ b/src/bin/evil/evil_test_realpath.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_REALPATH_H__
2#define __EVIL_TEST_REALPATH_H__
3
4
5int test_realpath(suite *s);
6
7
8#endif /* __EVIL_TEST_REALPATH_H__ */
diff --git a/src/bin/evil/evil_test_util.c b/src/bin/evil/evil_test_util.c
new file mode 100644
index 0000000000..6226ceb040
--- /dev/null
+++ b/src/bin/evil/evil_test_util.c
@@ -0,0 +1,110 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <string.h>
6
7#include <Evil.h>
8
9#include "evil_suite.h"
10#include "evil_test_util.h"
11
12
13static int test_path_absolute_test_1(void)
14{
15 char *path;
16 int result;
17
18 path = NULL;
19 result = evil_path_is_absolute(path);
20 if (result != 0)
21 return 0;
22
23 return 1;
24}
25
26static int test_path_absolute_test_2(void)
27{
28 char *path;
29 int result;
30
31 path = "1";
32 result = evil_path_is_absolute(path);
33 if (result != 0)
34 return 0;
35
36 return 1;
37}
38
39static int test_path_absolute_test_3(void)
40{
41 char *path;
42 int result;
43
44 path = "1:\\";
45 result = evil_path_is_absolute(path);
46 if (result != 0)
47 return 0;
48
49 return 1;
50}
51
52static int test_path_absolute_test_4(void)
53{
54 char *path;
55 int result;
56
57 path = "1/\\";
58 result = evil_path_is_absolute(path);
59 if (result != 0)
60 return 0;
61
62 return 1;
63}
64
65static int test_path_absolute_test_5(void)
66{
67 char *path;
68 int result;
69
70 path = "F:/foo";
71 result = evil_path_is_absolute(path);
72 if (result == 0)
73 return 0;
74
75 return 1;
76}
77
78static int test_path_absolute_test_6(void)
79{
80 char *path;
81 int result;
82
83 path = "C:\\foo";
84 result = evil_path_is_absolute(path);
85 if (result == 0)
86 return 0;
87
88 return 1;
89}
90
91static int
92test_path_absolute_run(suite *s __UNUSED__)
93{
94 int res;
95
96 res = test_path_absolute_test_1();
97 res &= test_path_absolute_test_2();
98 res &= test_path_absolute_test_3();
99 res &= test_path_absolute_test_4();
100 res &= test_path_absolute_test_5();
101 res &= test_path_absolute_test_6();
102
103 return res;
104}
105
106int
107test_util(suite *s)
108{
109 return test_path_absolute_run(s);
110}
diff --git a/src/bin/evil/evil_test_util.h b/src/bin/evil/evil_test_util.h
new file mode 100644
index 0000000000..bee5c7a164
--- /dev/null
+++ b/src/bin/evil/evil_test_util.h
@@ -0,0 +1,8 @@
1#ifndef __EVIL_TEST_UTIL_H__
2#define __EVIL_TEST_UTIL_H__
3
4
5int test_util(suite *s);
6
7
8#endif /* __EVIL_TEST_UTIL_H__ */
diff --git a/src/bin/evil/memcpy_glibc_arm.S b/src/bin/evil/memcpy_glibc_arm.S
new file mode 100644
index 0000000000..7c42898647
--- /dev/null
+++ b/src/bin/evil/memcpy_glibc_arm.S
@@ -0,0 +1,231 @@
1/* Copyright (C) 2006 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 Contributed by MontaVista Software, Inc. (written by Nicolas Pitre)
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20
21/* Copyright (C) 2008 Vincent Torri
22 modification of the name and of the entry / end declaration
23 */
24
25/*
26 * Data preload for architectures that support it (ARM V5TE and above)
27 */
28#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
29 && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
30 && !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
31 && !defined (__ARM_ARCH_5T__))
32#define PLD(code...) code
33#else
34#define PLD(code...)
35#endif
36
37/*
38 * This can be used to enable code to cacheline align the source pointer.
39 * Experiments on tested architectures (StrongARM and XScale) didn't show
40 * this a worthwhile thing to do. That might be different in the future.
41 */
42//#define CALGN(code...) code
43#define CALGN(code...)
44
45/*
46 * Endian independent macros for shifting bytes within registers.
47 */
48#ifndef __ARMEB__
49#define pull lsr
50#define push lsl
51#else
52#define pull lsl
53#define push lsr
54#endif
55
56 .text
57
58/* Prototype: void *memcpy_glibc(void *dest, const void *src, size_t n); */
59
60 .align
61 .global memcpy_glibc
62 .func memcpy_glibc
63memcpy_glibc:
64
65 stmfd sp!, {r0, r4, lr}
66
67 subs r2, r2, #4
68 blt 8f
69 ands ip, r0, #3
70 PLD( pld [r1, #0] )
71 bne 9f
72 ands ip, r1, #3
73 bne 10f
74
751: subs r2, r2, #(28)
76 stmfd sp!, {r5 - r8}
77 blt 5f
78
79 CALGN( ands ip, r1, #31 )
80 CALGN( rsb r3, ip, #32 )
81 CALGN( sbcnes r4, r3, r2 ) @ C is always set here
82 CALGN( bcs 2f )
83 CALGN( adr r4, 6f )
84 CALGN( subs r2, r2, r3 ) @ C gets set
85 CALGN( add pc, r4, ip )
86
87 PLD( pld [r1, #0] )
882: PLD( subs r2, r2, #96 )
89 PLD( pld [r1, #28] )
90 PLD( blt 4f )
91 PLD( pld [r1, #60] )
92 PLD( pld [r1, #92] )
93
943: PLD( pld [r1, #124] )
954: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
96 subs r2, r2, #32
97 stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
98 bge 3b
99 PLD( cmn r2, #96 )
100 PLD( bge 4b )
101
1025: ands ip, r2, #28
103 rsb ip, ip, #32
104 addne pc, pc, ip @ C is always clear here
105 b 7f
1066: nop
107 ldr r3, [r1], #4
108 ldr r4, [r1], #4
109 ldr r5, [r1], #4
110 ldr r6, [r1], #4
111 ldr r7, [r1], #4
112 ldr r8, [r1], #4
113 ldr lr, [r1], #4
114
115 add pc, pc, ip
116 nop
117 nop
118 str r3, [r0], #4
119 str r4, [r0], #4
120 str r5, [r0], #4
121 str r6, [r0], #4
122 str r7, [r0], #4
123 str r8, [r0], #4
124 str lr, [r0], #4
125
126 CALGN( bcs 2b )
127
1287: ldmfd sp!, {r5 - r8}
129
1308: movs r2, r2, lsl #31
131 ldrneb r3, [r1], #1
132 ldrcsb r4, [r1], #1
133 ldrcsb ip, [r1]
134 strneb r3, [r0], #1
135 strcsb r4, [r0], #1
136 strcsb ip, [r0]
137
138 ldmfd sp!, {r0, r4, pc}
139
1409: rsb ip, ip, #4
141 cmp ip, #2
142 ldrgtb r3, [r1], #1
143 ldrgeb r4, [r1], #1
144 ldrb lr, [r1], #1
145 strgtb r3, [r0], #1
146 strgeb r4, [r0], #1
147 subs r2, r2, ip
148 strb lr, [r0], #1
149 blt 8b
150 ands ip, r1, #3
151 beq 1b
152
15310: bic r1, r1, #3
154 cmp ip, #2
155 ldr lr, [r1], #4
156 beq 17f
157 bgt 18f
158
159
160 .macro forward_copy_shift pull push
161
162 subs r2, r2, #28
163 blt 14f
164
165 CALGN( ands ip, r1, #31 )
166 CALGN( rsb ip, ip, #32 )
167 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
168 CALGN( subcc r2, r2, ip )
169 CALGN( bcc 15f )
170
17111: stmfd sp!, {r5 - r9}
172
173 PLD( pld [r1, #0] )
174 PLD( subs r2, r2, #96 )
175 PLD( pld [r1, #28] )
176 PLD( blt 13f )
177 PLD( pld [r1, #60] )
178 PLD( pld [r1, #92] )
179
18012: PLD( pld [r1, #124] )
18113: ldmia r1!, {r4, r5, r6, r7}
182 mov r3, lr, pull #\pull
183 subs r2, r2, #32
184 ldmia r1!, {r8, r9, ip, lr}
185 orr r3, r3, r4, push #\push
186 mov r4, r4, pull #\pull
187 orr r4, r4, r5, push #\push
188 mov r5, r5, pull #\pull
189 orr r5, r5, r6, push #\push
190 mov r6, r6, pull #\pull
191 orr r6, r6, r7, push #\push
192 mov r7, r7, pull #\pull
193 orr r7, r7, r8, push #\push
194 mov r8, r8, pull #\pull
195 orr r8, r8, r9, push #\push
196 mov r9, r9, pull #\pull
197 orr r9, r9, ip, push #\push
198 mov ip, ip, pull #\pull
199 orr ip, ip, lr, push #\push
200 stmia r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
201 bge 12b
202 PLD( cmn r2, #96 )
203 PLD( bge 13b )
204
205 ldmfd sp!, {r5 - r9}
206
20714: ands ip, r2, #28
208 beq 16f
209
21015: mov r3, lr, pull #\pull
211 ldr lr, [r1], #4
212 subs ip, ip, #4
213 orr r3, r3, lr, push #\push
214 str r3, [r0], #4
215 bgt 15b
216 CALGN( cmp r2, #0 )
217 CALGN( bge 11b )
218
21916: sub r1, r1, #(\push / 8)
220 b 8b
221
222 .endm
223
224
225 forward_copy_shift pull=8 push=24
226
22717: forward_copy_shift pull=16 push=16
228
22918: forward_copy_shift pull=24 push=8
230
231.endfunc
diff --git a/src/bin/evil/memcpy_glibc_i686.S b/src/bin/evil/memcpy_glibc_i686.S
new file mode 100755
index 0000000000..72da118cf0
--- /dev/null
+++ b/src/bin/evil/memcpy_glibc_i686.S
@@ -0,0 +1,81 @@
1/* Copy memory block and return pointer to beginning of destination block
2 For Intel 80x86, x>=6.
3 This file is part of the GNU C Library.
4 Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
6
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA. */
21
22# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) \
23 CHECK_BOUNDS_LOW(VAL_REG, BP_MEM); \
24 addl LENGTH, VAL_REG; \
25 cmpl 8+BP_MEM, VAL_REG; \
26 jbe 0f; /* continue if value <= high */ \
27 BOUNDS_VIOLATED; \
28 0: subl LENGTH, VAL_REG /* restore value */
29
30# define RETURN_BOUNDED_POINTER(BP_MEM) \
31 movl RTN(%esp), %edx; \
32 movl %eax, 0(%edx); \
33 movl 4+BP_MEM, %eax; \
34 movl %eax, 4(%edx); \
35 movl 8+BP_MEM, %eax; \
36 movl %eax, 8(%edx)
37
38#define PTR_SIZE 12
39#define RTN_SIZE 4
40#define LINKAGE 8
41
42#define PARMS LINKAGE /* no space for saved regs */
43#define RTN PARMS
44#define DEST RTN+RTN_SIZE
45#define SRC DEST+PTR_SIZE
46#define LEN SRC+PTR_SIZE
47
48 .text
49
50 .align
51 .global memcpy_glibc
52 .func memcpy_glibc
53memcpy_glibc:
54
55 pushl %ebp
56 movl %esp, %ebp
57
58 movl LEN(%esp), %ecx
59 movl %edi, %eax
60 movl DEST(%esp), %edi
61 movl %esi, %edx
62 movl SRC(%esp), %esi
63
64 cld
65 shrl $1, %ecx
66 jnc 1f
67 movsb
681: shrl $1, %ecx
69 jnc 2f
70 movsw
712: rep
72 movsl
73 movl %eax, %edi
74 movl %edx, %esi
75 movl DEST(%esp), %eax
76 RETURN_BOUNDED_POINTER (DEST(%esp))
77
78 movl %ebp, %esp
79 popl %ebp
80
81.endfunc
diff --git a/src/bin/evil/test_evil.c b/src/bin/evil/test_evil.c
new file mode 100644
index 0000000000..5b91172cb3
--- /dev/null
+++ b/src/bin/evil/test_evil.c
@@ -0,0 +1,27 @@
1#include <stdlib.h>
2#include <stdio.h>
3#include <sys/time.h>
4
5#include <windows.h>
6
7
8
9int
10main()
11{
12 struct timeval tv;
13 double t1 = 0.0;
14 double t2 = 0.0;
15
16 if (gettimeofday(&tv, NULL) == 0)
17 t1 = tv.tv_sec + tv.tv_usec / 1000000.0;
18
19 Sleep(3000);
20
21 if (gettimeofday(&tv, NULL) == 0)
22 t2 = tv.tv_sec + tv.tv_usec / 1000000.0;
23
24 printf ("3 seconds ? %f\n", t2 - t1);
25
26 return EXIT_SUCCESS;
27}
diff --git a/src/lib/evil/Evil.h b/src/lib/evil/Evil.h
new file mode 100644
index 0000000000..e807dffb61
--- /dev/null
+++ b/src/lib/evil/Evil.h
@@ -0,0 +1,186 @@
1#ifndef __EVIL_H__
2#define __EVIL_H__
3
4/**
5 * @mainpage Evil
6 * @image html e_big.png
7 * @author Vincent Torri
8 * @version 1.7.0
9 * @date 2008-2012
10 *
11 * @section intro_sec Introduction
12 *
13 * The Evil library is an evil library that ports some evil Unix
14 * functions to the Windows (XP or above, or Mobile) platform. The
15 * evilness is so huge that the most of the functions are not POSIX or
16 * BSD compliant.
17 *
18 * These functions are intended to be used in the Enlightenment
19 * Foundation Libraries only and can be compiled only on Windows,
20 * using MSYS/MinGW on Windows, and cross-compilation on Unix. This
21 * library is minimal in the sense that only the functions needed to
22 * compile the EFL are available. The purpose of this library is NOT
23 * to have a full POSIX emulation et it is NOT a replacement of
24 * cygwin. To compare the size of the DLL themselves, Evil is around
25 * 33 KB and cygwin DLL is around 800 KB.
26 *
27 * @section acknowledgments_sec Acknowledgments
28 *
29 * This library has receive some from people interested in the EFL or
30 * not. Among them, evil thanks to Lars Munch, Raoul Hecky, Nicolas
31 * Aguirre, Tor Lillqvist, Lance Fetters, Vincent Richomme, Paul
32 * Vixie, Daniel Stenberg, who helped the author of the library in
33 * different fields (code and tests).
34 *
35 * @section license_sec license
36 *
37 * The Evil library is distributes under a modified BSD license. See
38 * the files COPYING and COPYING-PLAIN in the top level directory for
39 * the full license text.
40 *
41 * @section reference_sec Reference API
42 *
43 * Use the horizontal menu above to navigate into the reference API
44 */
45
46/**
47 * @file Evil.h
48 * @brief The file that provides miscellaneous functions ported from Unix.
49 * @defgroup Evil Miscellaneous functions ported from Unix.
50 *
51 * This header provides miscellaneous functions that exist on Unix
52 * but not on Windows platform. They try to follow the conformance of
53 * the Unix versions.
54 */
55
56/**
57 * @cond LOCAL
58 */
59
60#ifdef __cplusplus
61extern "C" {
62#endif
63
64
65#ifndef WIN32_LEAN_AND_MEAN
66# define WIN32_LEAN_AND_MEAN
67#endif
68#include <windows.h>
69#undef WIN32_LEAN_AND_MEAN
70
71#include <stdlib.h>
72#include <stdio.h>
73#include <time.h>
74#include <limits.h>
75#include <sys/stat.h>
76#include <fcntl.h>
77#include <math.h>
78#include <direct.h>
79
80
81#ifdef _MSC_VER
82
83# include <io.h>
84
85# define F_OK 0 /* Check for file existence */
86# define X_OK 1 /* MS access() doesn't check for execute permission. */
87# define W_OK 2 /* Check for write permission */
88# define R_OK 4 /* Check for read permission */
89
90typedef DWORD pid_t;
91typedef unsigned short mode_t;
92
93typedef unsigned short uint16_t;
94typedef unsigned int uint32_t;
95typedef signed int int32_t;
96typedef __int64 int64_t;
97typedef unsigned __int64 uint64_t;
98typedef SSIZE_T ssize_t;
99
100# define strdup(s) _strdup(s)
101# define unlink(filename) _unlink(filename)
102# define fileno(f) _fileno(f)
103# define fdopen(fd,m) _fdopen((fd),(m))
104# define access(p,m) _access((p),(m))
105# define hypot(x,y) _hypot((x),(y))
106# define tzset _tzset
107
108#endif /* _MSC_VER */
109
110#ifdef _WIN32_WCE
111# ifndef offsetof
112# define offsetof(type, ident) ((size_t)&(((type*)0)->ident))
113# endif
114#endif
115
116typedef unsigned long uid_t;
117typedef unsigned long gid_t;
118
119
120#include "evil_macro.h"
121#include "evil_fcntl.h"
122#include "evil_inet.h"
123#include "evil_langinfo.h"
124#include "evil_libgen.h"
125#include "evil_main.h"
126#include "evil_print.h"
127#include "evil_stdlib.h"
128#include "evil_stdio.h"
129#include "evil_string.h"
130#include "evil_time.h"
131#include "evil_unistd.h"
132#include "evil_util.h"
133#include "evil_macro_pop.h"
134
135
136#if (defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__))
137# if defined(_MSC_VER) || defined(__MINGW32__)
138
139# ifdef S_ISDIR
140# undef S_ISDIR
141# endif
142# ifdef S_ISREG
143# undef S_ISREG
144# endif
145# define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
146# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
147
148# define S_ISLNK(m) 0
149
150# define S_IRUSR _S_IRUSR
151# define S_IWUSR _S_IWUSR
152# define S_IXUSR _S_IXUSR
153# define S_IRGRP S_IRUSR
154# define S_IROTH S_IRUSR
155# define S_IWGRP S_IWUSR
156# define S_IWOTH S_IWUSR
157# define S_IXGRP S_IXUSR
158# define S_IXOTH S_IXUSR
159
160# define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC)
161# define _S_IXUSR _S_IEXEC
162# define _S_IWUSR _S_IWRITE
163# define _S_IRUSR _S_IREAD
164
165# define mkdir(p,m) _mkdir(p)
166 /*
167# define close(fd) _close(fd)
168# define read(fd,buffer,count) _read((fd),(buffer),(count))
169# define write(fd,buffer,count) _write((fd),(buffer),(count))
170# define unlink(filename) _unlink((filename))
171# define lstat(f,s) _stat((f),(s))
172 */
173
174# endif
175#endif
176
177
178#ifdef __cplusplus
179}
180#endif
181
182/**
183 * @endcond
184 */
185
186#endif /* __EVIL_H__ */
diff --git a/src/lib/evil/Makefile.am b/src/lib/evil/Makefile.am
new file mode 100644
index 0000000000..62d0d56bf3
--- /dev/null
+++ b/src/lib/evil/Makefile.am
@@ -0,0 +1,132 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4lib_LTLIBRARIES = libevil.la libdl.la
5
6install_evilheadersdir = $(includedir)/evil-@VMAJ@
7dist_install_evilheaders_DATA = \
8Evil.h \
9evil_fcntl.h \
10evil_inet.h \
11evil_langinfo.h \
12evil_libgen.h \
13evil_macro.h \
14evil_macro_pop.h \
15evil_main.h \
16evil_print.h \
17evil_stdlib.h \
18evil_stdio.h \
19evil_string.h \
20evil_time.h \
21evil_unistd.h \
22evil_util.h
23
24stdheadersdir = $(includedir)/evil-@VMAJ@
25nobase_dist_stdheaders_DATA = pwd.h sys/mman.h fnmatch.h dirent.h dlfcn.h
26
27if EVIL_HAVE_WINCE
28
29nobase_dist_stdheaders_DATA += mingw32ce/errno.h
30
31endif
32
33# gdtoa
34libevil_la_SOURCES = \
35gdtoa/arithchk.c \
36gdtoa/dmisc.c \
37gdtoa/dtoa.c \
38gdtoa/gd_arith.h \
39gdtoa/g_dfmt.c \
40gdtoa/gd_qnan.h \
41gdtoa/gdtoa.c \
42gdtoa/gdtoa_fltrnds.h \
43gdtoa/gdtoa.h \
44gdtoa/gdtoaimp.h \
45gdtoa/gethex.c \
46gdtoa/g_ffmt.c \
47gdtoa/g__fmt.c \
48gdtoa/gmisc.c \
49gdtoa/g_xfmt.c \
50gdtoa/hd_init.c \
51gdtoa/hexnan.c \
52gdtoa/misc.c \
53gdtoa/qnan.c \
54gdtoa/smisc.c \
55gdtoa/strtodg.c \
56gdtoa/strtof.c \
57gdtoa/strtopx.c \
58gdtoa/sum.c \
59gdtoa/ulp.c
60
61#evil
62libevil_la_SOURCES += \
63evil_dirent.c \
64evil_fcntl.c \
65evil_fnmatch.c \
66evil_fnmatch_list_of_states.c \
67evil_inet.c \
68evil_langinfo.c \
69evil_libgen.c \
70evil_main.c \
71evil_mman.c \
72evil_pformata.c \
73evil_pformatw.c \
74evil_printa.c \
75evil_printw.c \
76evil_pwd.c \
77evil_stdlib.c \
78evil_stdio.c \
79evil_string.c \
80evil_time.c \
81evil_unistd.c \
82evil_util.c \
83evil_uuid.c \
84evil_pformat.h \
85evil_private.h \
86evil_fnmatch_private.h
87
88if EVIL_HAVE_WINCE
89
90libevil_la_SOURCES += evil_errno.c evil_link_ce.c
91
92else
93
94libevil_la_SOURCES += evil_link_xp.cpp
95
96endif
97
98libevil_la_CPPFLAGS = @EVIL_CPPFLAGS@
99libevil_la_CFLAGS = @EVIL_CFLAGS@
100libevil_la_CXXFLAGS = @EVIL_CXXFLAGS@
101libevil_la_LIBADD = @EVIL_LIBS@
102libevil_la_LDFLAGS = -no-undefined -Wl,--enable-auto-import -version-info @version_info@
103
104if EVIL_HAVE_WINCE
105
106libevil_la_LINK = $(LINK) $(libevil_la_LDFLAGS)
107
108else
109
110libevil_la_LINK = $(CXXLINK) $(libevil_la_LDFLAGS)
111
112endif
113
114libdl_la_SOURCES = dlfcn.c
115
116libdl_la_CPPFLAGS = @EVIL_DLFCN_CPPFLAGS@
117libdl_la_CFLAGS = @EVIL_CFLAGS@
118libdl_la_LIBADD = $(top_builddir)/src/lib/libevil.la @EVIL_DLFCN_LIBS@
119libdl_la_LDFLAGS = -no-undefined -Wl,--enable-auto-import -version-info @version_info@
120
121EXTRA_DIST = gdtoa/README gdtoa/README.mingw
122
123install-data-hook:
124 rm -f $(libdir)/libevil.la $(libdir)/libdl.la
125
126uninstall-local:
127 rm -f $(DESTDIR)$(bindir)/libevil-@VMAJ@.dll
128 rm -f $(DESTDIR)$(bindir)/libdl-@VMAJ@.dll
129 rm -f $(DESTDIR)$(libdir)/libevil.dll.a
130 rm -f $(DESTDIR)$(libdir)/libevil.a
131 rm -f $(DESTDIR)$(libdir)/libdl.dll.a
132 rm -f $(DESTDIR)$(libdir)/libdl.a
diff --git a/src/lib/evil/dirent.h b/src/lib/evil/dirent.h
new file mode 100644
index 0000000000..3fe9d12866
--- /dev/null
+++ b/src/lib/evil/dirent.h
@@ -0,0 +1,141 @@
1#ifndef __EVIL_DIRENT_H__
2#define __EVIL_DIRENT_H__
3
4#ifdef EAPI
5# undef EAPI
6#endif /* EAPI */
7
8#ifdef _WIN32
9# ifdef EFL_EVIL_BUILD
10# ifdef DLL_EXPORT
11# define EAPI __declspec(dllexport)
12# else
13# define EAPI
14# endif /* ! DLL_EXPORT */
15# else
16# define EAPI __declspec(dllimport)
17# endif /* ! EFL_EVIL_BUILD */
18#endif /* _WIN32 */
19
20
21/**
22 * @file dirent.h
23 * @brief The file that provides functions ported from Unix in dirent.h.
24 * @defgroup Evil_Dirent_Group Dirent.h functions
25 *
26 * This header provides functions ported from Unix in dirent.h.
27 *
28 * @{
29 */
30
31
32#ifdef UNICODE
33# include <wchar.h>
34#endif
35
36/**
37 * @def DT_UNKNOWN
38 * Specifies that the file type is unknown.
39 */
40#define DT_UNKNOWN 0
41
42/**
43 * @def DT_DIR
44 * Specifies that the file type is a directory.
45 */
46#define DT_DIR 4
47
48/**
49 * @typedef DIR
50 * @brief A structure that describes a directory stream.
51 */
52typedef struct DIR DIR;
53
54/**
55 * @struct dirent
56 * @brief A structure that describes a directory stream.
57 */
58struct dirent
59{
60 char d_name[260 + 1]; /**< The filename. */
61 int d_mode; /**< The mode */
62 unsigned char d_type; /**< The type */
63};
64
65
66#ifdef __cplusplus
67extern "C" {
68#endif /* __cplusplus */
69
70
71/**
72 * @brief Open the given directory.
73 *
74 * @param name The directory to open.
75 * @return A pointer to the directory stream.
76 *
77 * This function opens the directory @p name and return the directory
78 * stream. On error or if @p dir is NULL, -1 is returned, and errno is
79 * set appropriately (on Windows XP only). On success, 0 is returned.
80 *
81 * @see closedir()
82 * @see readdir()
83 *
84 * Conformity: None.
85 *
86 * Supported OS: Windows XP, CE.
87 */
88EAPI DIR *opendir(char const *name);
89
90/**
91 * @brief Close the given directory.
92 *
93 * @param dir The directory stream to close.
94 * @return A pointer to the directory stream.
95 *
96 * This function closes the stream directory @p dir. On error or is
97 * @p path is NULL or an empty string, NULL is returned, and errno is set
98 * appropriately (on Windows XP only).
99 *
100 * @see opendir()
101 * @see readdir()
102 *
103 * Conformity: None.
104 *
105 * Supported OS: Windows XP, CE.
106 */
107EAPI int closedir(DIR *dir);
108
109/**
110 * @brief Read the given directory.
111 *
112 * @param dir The directory stream to read.
113 * @return A pointer to a dirent structure, @c NULL oterhwise.
114 *
115 * This function returns a pointer to a dirent structure representing
116 * the next directory entry in the directory stream pointed to by
117 * @p dir. It returns NULL on reaching the end of the directory stream
118 * or if an error occurred and errno is set appropriately (on Windows XP only).
119 *
120 * @see opendir()
121 * @see readdir()
122 *
123 * Conformity: None.
124 *
125 * Supported OS: Windows XP, CE.
126 */
127EAPI struct dirent *readdir(DIR *dir);
128
129
130#ifdef __cplusplus
131}
132#endif /* __cplusplus */
133
134
135
136/**
137 * @}
138 */
139
140
141#endif /* __EVIL_DIRENT_H__ */
diff --git a/src/lib/evil/dlfcn.c b/src/lib/evil/dlfcn.c
new file mode 100644
index 0000000000..818cabf014
--- /dev/null
+++ b/src/lib/evil/dlfcn.c
@@ -0,0 +1,272 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdlib.h>
6
7#if defined(__MINGW32CE__) || defined(_MSC_VER)
8# include <limits.h>
9#endif /* __MINGW32CE__ || _MSC_VER */
10
11#ifndef WIN32_LEAN_AND_MEAN
12# define WIN32_LEAN_AND_MEAN
13#endif
14#include <windows.h>
15#undef WIN32_LEAN_AND_MEAN
16
17#ifdef _WIN32_WCE
18# include <tlhelp32.h> /* CreateToolhelp32Snapshot */
19#else
20# include <psapi.h> /* EnumProcessModules(Ex) */
21#endif
22
23#include "Evil.h"
24
25#include "dlfcn.h"
26
27
28static char *dl_err = NULL;
29static int dl_err_viewed = 0;
30
31static void
32get_last_error(char *desc)
33{
34 char *str;
35 size_t l1;
36 size_t l2;
37
38 str = evil_last_error_get();
39
40 l1 = strlen(desc);
41 l2 = strlen(str);
42
43 if (dl_err)
44 free(dl_err);
45
46 dl_err = (char *)malloc(sizeof(char) * (l1 + l2 + 1));
47 if (!dl_err)
48 dl_err = strdup("not enough resource");
49 else
50 {
51 memcpy(dl_err, desc, l1);
52 memcpy(dl_err + l1, str, l2);
53 dl_err[l1 + l2] = '\0';
54 }
55 free(str);
56 dl_err_viewed = 0;
57}
58
59void *
60dlopen(const char* path, int mode __UNUSED__)
61{
62 HMODULE module = NULL;
63
64 if (!path)
65 {
66 module = GetModuleHandle(NULL);
67 if (!module)
68 get_last_error("GetModuleHandle returned: ");
69 }
70 else
71 {
72 char *new_path;
73 size_t l;
74 unsigned int i;
75
76 /* according to MSDN, we must change the slash to backslash */
77 l = strlen(path);
78 new_path = (char *)malloc(sizeof(char) * (l + 1));
79 if (!new_path)
80 {
81 if (dl_err)
82 free(dl_err);
83 dl_err = strdup("not enough resource");
84 dl_err_viewed = 0;
85 return NULL;
86 }
87 for (i = 0; i <= l; i++)
88 {
89 if (path[i] == '/')
90 new_path[i] = '\\';
91 else
92 new_path[i] = path[i];
93 }
94#ifdef UNICODE
95 {
96 wchar_t *wpath;
97
98 wpath = evil_char_to_wchar(new_path);
99 module = LoadLibrary(wpath);
100 free(wpath);
101 }
102#else
103 module = LoadLibraryEx(new_path, NULL,
104 LOAD_WITH_ALTERED_SEARCH_PATH);
105#endif /* ! UNICODE */
106 if (!module)
107 get_last_error("LoadLibraryEx returned: ");
108
109 free(new_path);
110 }
111
112 return module;
113}
114
115int
116dlclose(void* handle)
117{
118 if (FreeLibrary(handle))
119 return 0;
120 else
121 {
122 get_last_error("FreeLibrary returned: ");
123 return -1;
124 }
125}
126
127void *
128dlsym(void *handle, const char *symbol)
129{
130 FARPROC fp = NULL;
131 LPCTSTR new_symbol;
132
133 if (!symbol || !*symbol) return NULL;
134
135#ifdef UNICODE
136 new_symbol = evil_char_to_wchar(symbol);
137#else
138 new_symbol = symbol;
139#endif /* UNICODE */
140
141 if (handle == RTLD_DEFAULT)
142 {
143#ifdef _WIN32_WCE
144 HANDLE snapshot;
145 MODULEENTRY32 module;
146
147 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS |
148 TH32CS_SNAPMODULE |
149 TH32CS_GETALLMODS,
150 0);
151 if (!snapshot)
152 return NULL;
153
154 module.dwSize = sizeof(module);
155 if (Module32First(snapshot, &module))
156 do {
157 fp = GetProcAddress(module.hModule, new_symbol);
158 if (fp) break;
159 } while (Module32Next(snapshot, &module));
160
161 CloseToolhelp32Snapshot(snapshot);
162#else
163 HMODULE modules[1024];
164 DWORD needed;
165 DWORD i;
166
167 /* TODO: use EnumProcessModulesEx() on Windows >= Vista */
168 if (!EnumProcessModules(GetCurrentProcess(),
169 modules, sizeof(modules), &needed))
170 return NULL;
171
172 for (i = 0; i < (needed / sizeof(HMODULE)); i++)
173 {
174 fp = GetProcAddress(modules[i], new_symbol);
175 if (fp) break;
176 }
177#endif
178 }
179 else
180 fp = GetProcAddress(handle, new_symbol);
181
182#ifdef UNICODE
183 free((void *)new_symbol);
184#endif /* UNICODE */
185
186 if (!fp)
187 get_last_error("GetProcAddress returned: ");
188
189 return fp;
190}
191
192int
193dladdr (const void *addr __UNUSED__, Dl_info *info)
194{
195 TCHAR tpath[PATH_MAX];
196 MEMORY_BASIC_INFORMATION mbi;
197 char *path;
198 char *tmp;
199 size_t length;
200 int ret = 0;
201
202 if (!info)
203 return 0;
204
205#ifdef _WIN32_WINNT
206 length = VirtualQuery(addr, &mbi, sizeof(mbi));
207 if (!length)
208 return 0;
209
210 if (mbi.State != MEM_COMMIT)
211 return 0;
212
213 if (!mbi.AllocationBase)
214 return 0;
215
216 ret = GetModuleFileName((HMODULE)mbi.AllocationBase, (LPTSTR)&tpath, PATH_MAX);
217 if (!ret)
218 return 0;
219#else
220 ret = GetModuleFileName(NULL, (LPTSTR)&tpath, PATH_MAX);
221 if (!ret)
222 return 0;
223#endif
224
225#ifdef UNICODE
226 path = evil_wchar_to_char(tpath);
227#else
228 path = tpath;
229#endif /* ! UNICODE */
230
231 length = strlen (path);
232 if (length >= PATH_MAX)
233 {
234 length = PATH_MAX - 1;
235 path[PATH_MAX - 1] = '\0';
236 }
237
238 /* replace '/' by '\' */
239 tmp = path;
240 while (*tmp)
241 {
242 if (*tmp == '/') *tmp = '\\';
243 tmp++;
244 }
245
246 memcpy (info->dli_fname, path, length + 1);
247 info->dli_fbase = NULL;
248 info->dli_sname = NULL;
249 info->dli_saddr = NULL;
250
251#ifdef UNICODE
252 free (path);
253#endif /* ! UNICODE */
254
255 return 1;
256}
257
258char *
259dlerror (void)
260{
261 if (!dl_err_viewed)
262 {
263 dl_err_viewed = 1;
264 return dl_err;
265 }
266 else
267 {
268 if (dl_err)
269 free(dl_err);
270 return NULL;
271 }
272}
diff --git a/src/lib/evil/dlfcn.h b/src/lib/evil/dlfcn.h
new file mode 100644
index 0000000000..610331b702
--- /dev/null
+++ b/src/lib/evil/dlfcn.h
@@ -0,0 +1,258 @@
1#ifndef __EVIL_DLFCN_H__
2#define __EVIL_DLFCN_H__
3
4
5#include <limits.h>
6
7
8#ifdef EAPI
9# undef EAPI
10#endif /* EAPI */
11
12#ifdef _WIN32
13# ifdef EFL_EVIL_DLFCN_BUILD
14# ifdef DLL_EXPORT
15# define EAPI __declspec(dllexport)
16# else
17# define EAPI
18# endif /* ! DLL_EXPORT */
19# else
20# define EAPI __declspec(dllimport)
21# endif /* ! EFL_EVIL_DLFCN_BUILD */
22#endif /* _WIN32 */
23
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#ifdef _WIN32_WCE
30# ifndef PATH_MAX
31# define PATH_MAX 260
32# endif
33#endif
34
35
36/**
37 * @file dlfcn.h
38 * @brief The file that provides functions to manage dynamic-link libraries
39 * @defgroup Dlfcn Functions that manage dynamic-link libraries.
40 *
41 * This header provides functions to load and unload dynamic-link
42 * libaries, to get the address of a symbol, and to get diagnostic
43 * information.
44 */
45
46
47/**
48 * @def RTLD_LAZY
49 * Lazy function call binding.
50 */
51# define RTLD_LAZY 0x00001 /* lazy function call binding */
52
53/**
54 * @def RTLD_NOW
55 * Immediate function call binding.
56 */
57# define RTLD_NOW 0x00002 /* immediate function call binding */
58
59/**
60 * @def RTLD_GLOBAL
61 * Symbols in this dlopen'ed obj are visible to other dlopen'ed objs.
62 */
63# define RTLD_GLOBAL 0x00100 /* symbols in this dlopen'ed obj are visible
64 to other dlopen'ed objs */
65
66/**
67 * @def RTLD_NODELETE
68 * Symbols are not deleted when closed.
69 */
70#define RTLD_NODELETE 0x01000 /* do not delete object when closed. */
71
72/**
73 * @def RTLD_DEFAULT
74 * Symbols are searched in all the DLL opened by the current process.
75 */
76#define RTLD_DEFAULT ((void*)1) /* search the symbol on all the DLL of the current process */
77
78/**
79 * @typedef Dl_info
80 * @brief A structure that stores infomation of a calling process.
81 */
82typedef struct Dl_info Dl_info;
83
84/**
85 * @struct Dl_info
86 * @brief A structure that stores infomation of a calling process.
87 */
88struct Dl_info
89{
90 char dli_fname[PATH_MAX]; /**< Filename of defining object */
91 void *dli_fbase; /**< Load address of that object */
92 const char *dli_sname; /**< Name of nearest lower symbol */
93 void *dli_saddr; /**< Exact value of nearest symbol */
94};
95
96/**
97 * @brief Map a specified executable module (either a .dll or .exe file)
98 * into the address space of the user process.
99 *
100 * @param path Name of the module.
101 * @param mode Unused.
102 * @return A pointer that represent the module, or @c NULL on failure.
103 *
104 * Map a specified executable module (either a .dll or .exe file)
105 * into the address space of the user process. If @p path is @c NULL,
106 * then the module corresponding to the current process is returned.
107 * Otherwise the module specified by @p path is loaded if it exists.
108 * If not, @c NULL is returned. The directory separators can be forward
109 * slash, or backward ones. Mapping a module can map other modules.
110 * @p mode is unused.
111 *
112 * If an error occurred, an error string can be retrived with dlerror().
113 *
114 * According to the OS, the search order of the module can change,
115 * according to the value of SafeDllSearchMode.
116 *
117 * - For Windows Vista, Windows Server 2003, and Windows XP SP2:
118 * SafeDLLSearchMode is enabled by default.
119 * - For Windows XP and Windows 2000 SP4: SafeDLLSearchMode is disabled
120 * by default.
121 *
122 * If SafeDllSearchMode is enabled
123 * - The directory from which the application loaded.
124 * - The system directory. Use the GetSystemDirectory() function
125 * to get the path of this directory.
126 * - The 16-bit system directory. There is no function that obtains
127 * the path of this directory, but it is searched.
128 * - The Windows directory. Use the GetWindowsDirectory() function
129 * to get the path of this directory.
130 * - The current directory.
131 * - The directories that are listed in the PATH environment variable.
132 * Note that this does not include the per-application path specified
133 * by the App Paths registry key.
134 *
135 * If SafeDllSearchMode is disabled
136 * - The directory from which the application loaded.
137 * - The current directory.
138 * - The system directory. Use the GetSystemDirectory() function
139 * to get the path of this directory.
140 * - The 16-bit system directory. There is no function that obtains
141 * the path of this directory, but it is searched.
142 * - The Windows directory. Use the GetWindowsDirectory() function
143 * to get the path of this directory.
144 * - The directories that are listed in the PATH environment variable.
145 * Note that this does not include the per-application path specified
146 * by the App Paths registry key.
147 *
148 * Conformity: None.
149 *
150 * Supported OS: Windows Vista, Windows XP or Windows 2000
151 * Professional.
152 *
153 * @ingroup Dlfcn
154 */
155EAPI void *dlopen(const char* path, int mode);
156
157/**
158 * @brief Close a dynamic-link library.
159 *
160 * @param handle Handle that references a dynamic-link library.
161 * @return O on sucess, -1 otherwise.
162 *
163 * Release a reference to the dynamic-link library referenced
164 * by @p handle. If the reference count drops to 0, the handle is
165 * removed from the address space and is rendered invalid. @p handle
166 * is the value returned by a previous call to dlopen().
167 *
168 * If no error occurred, the returned value is 0, otherwise the
169 * returned value is -1 and an error string can be retrived with
170 * dlerror().
171 *
172 * Conformity: None.
173 *
174 * Supported OS: Windows Vista, Windows XP or Windows 2000
175 * Professional.
176 *
177 * @ingroup Dlfcn
178 */
179EAPI int dlclose(void* handle);
180
181/**
182 * @brief Get the address of a symbol.
183 *
184 * @param handle Handle that references a dynamic-link library.
185 * @param symbol @c NULL-terminated string.
186 * @return O on sucess, NULL otherwise.
187 *
188 * Return the address of the code or data location specified by the
189 * string @p symbol. @p handle references a library that contains
190 * the function or variable @p symbol.
191 *
192 * If no error occurred, the returned value is the code or data
193 * location, otherwise the returned value is NULL and an error
194 * string can be retrived with dlerror().
195 *
196 * Conformity: None.
197 *
198 * Supported OS: Windows Vista, Windows XP or Windows 2000
199 * Professional.
200 *
201 * @ingroup Dlfcn
202 */
203EAPI void *dlsym(void* handle, const char* symbol);
204
205/**
206 * @brief Get the location of the current process (.exe)
207 *
208 * @param addr Unused.
209 * @param info Pointer to the Dl_info to fill.
210 * @return 1 on success, 0 otherwise.
211 *
212 * Fill the dli_fname member of @p info with the absolute name
213 * of the current calling process (.exe file that is executed).
214 * All other members are set to @c NULL.
215 *
216 * Contrary to the unix function, the full name of the shared
217 * library is not returned, but insted the full name of the current
218 * calling process (.exe file).
219 *
220 * Conformity: None.
221 *
222 * Supported OS: Windows Vista, Windows XP or Windows 2000
223 * Professional.
224 *
225 * @ingroup Dlfcn
226 */
227EAPI int dladdr (const void *addr, Dl_info *info);
228
229/**
230 * @brief Get diagnostic information
231 *
232 * @return A @c NULL-terminated string if an error occured, @c NULL
233 * otherwise.
234 *
235 * Return a @c NULL-terminated character string describing the last
236 * error that occurred on this thread during a call to dlopen(),
237 * dlsym(), or dlclose(). If no such error has occurred, dlerror()
238 * returns a null pointer. At each call to dlerror(), the error
239 * indication is reset. Thus in the case of two calls to dlerror(),
240 * where the second call follows the first immediately, the second
241 * call will always return a null pointer.
242 *
243 * Conformity: None.
244 *
245 * Supported OS: Windows Vista, Windows XP or Windows 2000
246 * Professional.
247 *
248 * @ingroup Dlfcn
249 */
250EAPI char *dlerror (void);
251
252
253#ifdef __cplusplus
254}
255#endif
256
257
258#endif /* __EVIL_DLFCN_H__ */
diff --git a/src/lib/evil/evil_dirent.c b/src/lib/evil/evil_dirent.c
new file mode 100644
index 0000000000..e02b95fe27
--- /dev/null
+++ b/src/lib/evil/evil_dirent.c
@@ -0,0 +1,197 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <dirent.h>
6
7#ifdef HAVE_ERRNO_H
8# include <errno.h>
9#endif
10
11#include "Evil.h"
12
13
14struct DIR
15{
16 struct dirent dirent;
17 WIN32_FIND_DATA data;
18 HANDLE handle;
19};
20
21
22DIR *opendir(char const *name)
23{
24 DIR *dir;
25 char *tmp1;
26 char *tmp2;
27 DWORD attr;
28 size_t l;
29#ifdef UNICODE
30 wchar_t *wname;
31 char *d_name;
32#endif
33
34 /* valid name */
35 if (!name || !*name)
36 {
37#ifdef HAVE_ERRNO_H
38 errno = ENOENT;
39#endif
40 return NULL;
41 }
42
43#ifdef UNICODE
44 wname = evil_char_to_wchar(name);
45 if (!wname)
46 {
47# ifdef HAVE_ERRNO_H
48 errno = ENOMEM;
49# endif
50 return NULL;
51 }
52
53 if((attr = GetFileAttributes(wname)) == 0xFFFFFFFF)
54#else
55 if((attr = GetFileAttributes(name)) == 0xFFFFFFFF)
56#endif
57 {
58#ifdef HAVE_ERRNO_H
59 errno = ENOENT;
60#endif
61 return NULL;
62 }
63
64#ifdef UNICODE
65 free(wname);
66#endif
67
68 /* directory */
69 if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
70 {
71#ifdef HAVE_ERRNO_H
72 errno = ENOTDIR;
73#endif
74 return NULL;
75 }
76
77 dir = (DIR *)malloc(sizeof(DIR));
78 if (!dir)
79 {
80#ifdef HAVE_ERRNO_H
81 errno = ENOMEM;
82#endif
83 return NULL;
84 }
85
86 l = strlen(name);
87 tmp1 = (char *)malloc(sizeof(char) * l + 5);
88 if (!tmp1)
89 {
90#ifdef HAVE_ERRNO_H
91 errno = ENOMEM;
92#endif
93 return NULL;
94 }
95
96 memcpy(tmp1, name, l);
97 memcpy(tmp1 + l, "\\*.*", 5);
98
99 tmp2 = tmp1;
100 while (*tmp2)
101 {
102 if (*tmp2 == '/') *tmp2 = '\\';
103 tmp2++;
104 }
105
106#ifdef UNICODE
107 wname = evil_char_to_wchar(tmp1);
108 if (!wname)
109 {
110#ifdef HAVE_ERRNO_H
111 errno = ENOMEM;
112#endif
113 free(tmp1);
114
115 return NULL;
116 }
117 dir->handle = FindFirstFile(wname, &dir->data);
118 free(wname);
119#else
120 dir->handle = FindFirstFile(tmp1, &dir->data);
121#endif
122
123 free(tmp1);
124
125 if (dir->handle == INVALID_HANDLE_VALUE)
126 {
127 free(dir);
128 return NULL;
129 }
130
131#ifdef UNICODE
132 d_name = evil_wchar_to_char(dir->data.cFileName);
133 strcpy(dir->dirent.d_name, d_name);
134 free(d_name);
135#else
136 strcpy(dir->dirent.d_name, dir->data.cFileName);
137#endif
138 dir->dirent.d_mode = (int)dir->data.dwFileAttributes;
139
140 if (dir->data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
141 dir->dirent.d_type = DT_DIR;
142 else
143 dir->dirent.d_type = DT_UNKNOWN;
144
145 return dir;
146}
147
148int closedir(DIR *dir)
149{
150 if (!dir)
151 {
152#ifdef HAVE_ERRNO_H
153 errno = EBADF;
154#endif
155 return -1;
156 }
157
158 if (dir->handle != INVALID_HANDLE_VALUE)
159 FindClose(dir->handle);
160 free(dir);
161
162 return 0;
163}
164
165struct dirent *readdir(DIR *dir)
166{
167#ifdef UNICODE
168 char *d_name;
169#endif
170
171 if (!dir)
172 {
173#ifdef HAVE_ERRNO_H
174 errno = EBADF;
175#endif
176 return NULL;
177 }
178
179 if (dir->handle == INVALID_HANDLE_VALUE)
180 return NULL;
181
182#ifdef UNICODE
183 d_name = evil_wchar_to_char(dir->data.cFileName);
184 strcpy(dir->dirent.d_name, d_name);
185 free(d_name);
186#else
187 strcpy(dir->dirent.d_name, dir->data.cFileName);
188#endif
189
190 if (!FindNextFile(dir->handle, &dir->data))
191 {
192 FindClose(dir->handle);
193 dir->handle = INVALID_HANDLE_VALUE;
194 }
195
196 return &dir->dirent;
197}
diff --git a/src/lib/evil/evil_errno.c b/src/lib/evil/evil_errno.c
new file mode 100644
index 0000000000..37cac611f0
--- /dev/null
+++ b/src/lib/evil/evil_errno.c
@@ -0,0 +1,9 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Evil.h"
6#include "mingw32ce/errno.h"
7
8
9int errno = 0;
diff --git a/src/lib/evil/evil_fcntl.c b/src/lib/evil/evil_fcntl.c
new file mode 100644
index 0000000000..7c62c2a310
--- /dev/null
+++ b/src/lib/evil/evil_fcntl.c
@@ -0,0 +1,124 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <stdio.h>
6
7#ifdef _MSC_VER
8# include <io.h> /* for _get_osfhandle _lseek and _locking */
9#endif
10
11#include <sys/locking.h>
12
13#include <winsock2.h> /* for ioctlsocket */
14
15#include "Evil.h"
16
17
18#ifdef __MINGW32CE__
19# define _get_osfhandle(FILEDES) ((HANDLE)FILEDES)
20#endif /* __MINGW32CE__ */
21
22
23/*
24 * port of fcntl function
25 *
26 */
27
28int fcntl(int fd, int cmd, ...)
29{
30 va_list va;
31 HANDLE h;
32 int res = -1;
33
34 va_start (va, cmd);
35
36 h = (HANDLE)_get_osfhandle(fd);
37 if (h == INVALID_HANDLE_VALUE)
38 return -1;
39
40 if (cmd == F_GETFD)
41 {
42#ifndef __MINGW32CE__
43 DWORD flag;
44
45 if (!GetHandleInformation(h, &flag))
46 return -1;
47
48 res = 0;
49#endif /* ! __MINGW32CE__ */
50 }
51
52 if (cmd == F_SETFD)
53 {
54 long flag;
55
56 flag = va_arg(va, long);
57 if (flag == FD_CLOEXEC)
58 {
59#ifndef __MINGW32CE__
60 if (SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0))
61 res = 0;
62#endif /* ! __MINGW32CE__ */
63 }
64 }
65 else if (cmd == F_SETFL)
66 {
67 long flag;
68
69 flag = va_arg(va, long);
70 if (flag == O_NONBLOCK)
71 {
72 u_long arg = 1;
73 int type;
74 int len;
75 int ret;
76
77 len = (int)sizeof(int);
78 ret = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, (char *)&type, &len);
79 if (!ret && (type == SOCK_STREAM))
80 {
81 if (!ioctlsocket((SOCKET)fd, FIONBIO, &arg) == SOCKET_ERROR)
82 res = 0;
83 }
84 }
85 }
86#ifndef __MINGW32CE__
87 else if ((cmd == F_SETLK) || (cmd == F_SETLKW))
88 {
89 struct flock *fl;
90 off_t length = 0;
91 long pos;
92
93 fl = va_arg(va, struct flock *);
94
95 if (fl->l_len == 0)
96 {
97 length = _lseek(fd, 0L, SEEK_END);
98 if (length != -1L)
99 res = 0;
100 }
101 fl->l_len = length - fl->l_start - 1;
102
103 pos = _lseek(fd, fl->l_start, fl->l_whence);
104 if (pos != -1L)
105 res = 0;
106
107 if ((fl->l_type == F_RDLCK) || (fl->l_type == F_WRLCK))
108 {
109 if (cmd == F_SETLK)
110 res = _locking(fd, _LK_NBLCK, fl->l_len); /* if cannot be locked, we return immediatly */
111 else /* F_SETLKW */
112 res = _locking(fd, _LK_LOCK, fl->l_len); /* otherwise, we try several times */
113 }
114
115 if (fl->l_type == F_UNLCK)
116 res = _locking(fd, _LK_UNLCK, fl->l_len);
117 }
118
119#endif /* ! __MINGW32CE__ */
120
121 va_end(va);
122
123 return res;
124}
diff --git a/src/lib/evil/evil_fcntl.h b/src/lib/evil/evil_fcntl.h
new file mode 100644
index 0000000000..194341b369
--- /dev/null
+++ b/src/lib/evil/evil_fcntl.h
@@ -0,0 +1,110 @@
1#ifndef __EVIL_FCNTL_H__
2#define __EVIL_FCNTL_H__
3
4
5# include <sys/types.h>
6
7
8/**
9 * @def FD_CLOEXEC
10 * Specifies that the file descriptor should be closed when an exec()
11 * function is invoked.
12 */
13# define FD_CLOEXEC 1
14
15/**
16 * @def O_NONBLOCK
17 * Specifies that the socket is in non-blocking mode.
18 */
19# define O_NONBLOCK 04000
20
21/**
22 * @def F_SETFD
23 * Specifies that fcntl() should set the file descriptor flags
24 * associated with the filedes argument.
25 */
26
27/**
28 * @def F_SETLK
29 * Specifies that fcntl() should set or clear a file segment lock
30 * according to the lock description pointed to by the third argument.
31 */
32
33/**
34 * @def F_SETLKW
35 * Equivalent to F_SETLK except that if a shared or exclusive lock
36 * is blocked by other locks, the thread shall wait until the request
37 * can be satisfied.
38 */
39
40# define F_GETFD 1
41# define F_SETFD 2
42# define F_SETFL 4
43# define F_SETLK 6
44# define F_SETLKW 7
45
46/**
47 * @def F_RDLCK
48 * Read (or shared) lock
49 */
50
51/**
52 * @def F_WRLCK
53 * Write (or exclusive) lock
54 */
55
56/**
57 * @def F_UNLCK
58 * Remove lock
59 */
60
61# ifndef F_RDLCK
62# define F_RDLCK 0
63# define F_WRLCK 1
64# define F_UNLCK 2
65# endif /* ! F_RDLCK */
66
67/**
68 * @struct flock
69 * @brief A structure that controls the lock of a file descriptor.
70 */
71struct flock
72{
73 short int l_type; /**< lock type: read, write, ... */
74 short int l_whence; /**< type of l_start */
75 off_t l_start; /**< starting offset */
76 off_t l_len; /**< 0 means end of the file */
77 pid_t l_pid; /**< lock owner */
78};
79
80
81/**
82 * @brief Provide control over file descriptors.
83 *
84 * @param fd The file descriptor.
85 * @param cmd The type of control.
86 * @return 0 on success, -1 otherwise.
87 *
88 * Performs one of various miscellaneous operations on @p fd.
89 * The operation in question is determined by @p cmd:
90 *
91 * - F_SETFD: Set the close-on-exec flag to the value specified
92 * by the argument after command (only the least significant
93 * bit is used).
94 * - F_SETLK and F_SETLKW: used to manage discretionary file locks.
95 * The third argument must be a pointer to a struct flock (that
96 * may be overwritten by this call).
97 *
98 * This function returns 0 on success, -1 otherwise.
99 *
100 * Conformity: None.
101 *
102 * Supported OS: Windows Vista, Windows XP or Windows 2000
103 * Professional.
104 *
105 * @ingroup Evil
106 */
107EAPI int fcntl(int fd, int cmd, ...);
108
109
110#endif /* __EVIL_FCNTL_H__ */
diff --git a/src/lib/evil/evil_fnmatch.c b/src/lib/evil/evil_fnmatch.c
new file mode 100644
index 0000000000..0b4af7bfb0
--- /dev/null
+++ b/src/lib/evil/evil_fnmatch.c
@@ -0,0 +1,231 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <assert.h>
6#include <string.h>
7
8#include "fnmatch.h"
9#include "evil_fnmatch_private.h"
10
11enum fnmatch_status
12{
13 fnmatch_not_found = 0,
14 fnmatch_found = 1,
15 fnmatch_syntax_error = 2
16};
17
18static
19size_t
20fnmatch_match_class_token(enum fnmatch_status *status,
21 const char *class_token,
22 char c)
23{
24 if (! *class_token)
25 {
26 *status = fnmatch_syntax_error;
27 return 0;
28 }
29 else if (class_token[1] == '-' && class_token[2] != ']')
30 {
31 if (class_token[0] <= c && c <= class_token[2])
32 *status = fnmatch_found;
33 return 3;
34 }
35 else
36 {
37 if (c == *class_token)
38 *status = fnmatch_found;
39 return 1;
40 }
41}
42
43static
44size_t
45fnmatch_complement_class(const char *class_token)
46{
47 switch (*class_token)
48 {
49 case 0:
50 return FNM_SYNTAXERR;
51
52 case '!':
53 return 1;
54
55 default:
56 return 0;
57 }
58}
59
60static
61size_t
62fnmatch_match_class(const char *class,
63 char c)
64{
65 const size_t complement = fnmatch_complement_class(class + 1);
66 enum fnmatch_status status;
67 size_t pos;
68
69 if (complement == FNM_SYNTAXERR)
70 return FNM_SYNTAXERR;
71
72 status = fnmatch_not_found;
73 pos = 1 + complement;
74
75 do
76 pos += fnmatch_match_class_token(&status, class + pos, c);
77 while (class[pos] && class[pos] != ']');
78
79 if (status == fnmatch_syntax_error || ! class[pos])
80 return FNM_SYNTAXERR;
81
82 if (status == fnmatch_found)
83 return complement ? 0 : pos + 1;
84 else
85 return complement ? pos + 1 : 0;
86}
87
88static
89size_t
90fnmatch_chrcasecmp(char a,
91 char b)
92{
93 if ('A' <= a && a <= 'Z')
94 a += 'a' - 'A';
95 if ('A' <= b && b <= 'Z')
96 b += 'a' - 'A';
97 return a == b;
98}
99
100static
101size_t
102fnmatch_match_token(const char *token,
103 char c,
104 e_bool leading,
105 int flags)
106{
107 if (*token == '\\' && !(flags & FNM_NOESCAPE))
108 return token[1] ? (token[1] == c ? 2 : 0) : FNM_SYNTAXERR;
109
110 if (c == '/' && (flags & FNM_PATHNAME))
111 return *token == '/';
112
113 if (c == '.' && leading && (flags & FNM_PERIOD))
114 return *token == '.';
115
116 switch (*token)
117 {
118 case '?':
119 return 1;
120
121 case '[':
122 return fnmatch_match_class(token, c);
123
124 default:
125 if (flags & FNM_CASEFOLD)
126 return fnmatch_chrcasecmp(*token, c);
127 return *token == c ? 1 : 0;
128 }
129}
130
131static
132void
133fnmatch_init_states(struct list_of_states *states)
134{
135 states->size = 1;
136 states->states[0] = 0;
137 memset(states->has, 0, states->reserved * sizeof (*states->has));
138 states->has[0] = 1;
139}
140
141static
142size_t
143fnmatch_check_finals(const char *pattern,
144 const struct list_of_states *states)
145{
146 size_t i, j;
147 for (i = 0; i < states->size; ++i)
148 {
149 e_bool match = 1;
150
151 for (j = states->states[i]; pattern[j]; ++j)
152 if (pattern[j] != '*')
153 {
154 match = 0;
155 break;
156 }
157
158 if (match)
159 return 0;
160 }
161 return FNM_NOMATCH;
162}
163
164int
165fnmatch(const char *pattern,
166 const char *string,
167 int flags)
168{
169 struct list_of_states *states;
170 struct list_of_states *new_states;
171 e_bool leading = 1;
172 char *c;
173 size_t r;
174
175 assert(pattern);
176 assert(string);
177
178 states = fnmatch_list_of_states_alloc(2, strlen(pattern));
179 new_states = states + 1;
180
181 if (! states)
182 return FNM_NOMEM;
183 fnmatch_init_states(states);
184
185
186 for (c = (char *)string; *c && states->size; ++c)
187 {
188 size_t i;
189 fnmatch_list_of_states_clear(new_states);
190
191 for (i = 0; i < states->size; ++i)
192 {
193 const size_t pos = states->states[i];
194
195 if (! pattern[pos])
196 {
197 if (*c == '/' && (flags & FNM_LEADING_DIR))
198 return 0;
199 continue;
200 }
201 else if (pattern[pos] == '*')
202 {
203 fnmatch_list_of_states_insert(states, pos + 1);
204 if ((*c != '/' || !(flags & FNM_PATHNAME)) &&
205 (*c != '.' || !leading || !(flags & FNM_PERIOD)))
206 fnmatch_list_of_states_insert(new_states, pos);
207 }
208 else
209 {
210 const size_t m = fnmatch_match_token(pattern + pos, *c,
211 leading, flags);
212
213 if (m == FNM_SYNTAXERR)
214 return FNM_SYNTAXERR;
215 else if (m)
216 fnmatch_list_of_states_insert(new_states, pos + m);
217 }
218 }
219 {
220 struct list_of_states *tmp = states;
221
222 states = new_states;
223 new_states = tmp;
224 }
225 leading = *c == '/' && (flags & FNM_PATHNAME);
226 }
227
228 r = fnmatch_check_finals(pattern, states);
229 fnmatch_list_of_states_free(states < new_states ? states : new_states, 2);
230 return (int)r;
231}
diff --git a/src/lib/evil/evil_fnmatch_list_of_states.c b/src/lib/evil/evil_fnmatch_list_of_states.c
new file mode 100644
index 0000000000..c6cfb7fe81
--- /dev/null
+++ b/src/lib/evil/evil_fnmatch_list_of_states.c
@@ -0,0 +1,77 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif /* HAVE_CONFIG_H */
4
5#include <assert.h>
6#include <stdlib.h>
7#include <string.h>
8
9#include "evil_fnmatch_private.h"
10
11struct list_of_states*
12fnmatch_list_of_states_alloc(size_t n,
13 size_t pattern_len)
14{
15 struct list_of_states *l;
16
17 const size_t reserved = pattern_len + 1;
18 const size_t states_size = sizeof (*l->states) * reserved;
19 const size_t has_size = sizeof (*l->has) * reserved;
20 const size_t states_has_size = states_size + has_size;
21 const size_t struct_size = sizeof (*l) + states_has_size;
22
23 unsigned char *states;
24 unsigned char *has;
25 size_t i;
26
27 l = malloc(n * struct_size);
28 if (!l)
29 return 0;
30
31 states = (unsigned char *) (l + n);
32 has = states + states_size;
33
34 for (i = 0; i < n; ++i)
35 {
36 l[i].reserved = reserved;
37 l[i].states = (size_t *) states;
38 l[i].has = (e_bool *) has;
39 states += states_has_size;
40 has += states_has_size;
41 }
42
43 return l;
44}
45
46void
47fnmatch_list_of_states_free(struct list_of_states *lists,
48 size_t n)
49{
50 assert(lists);
51
52 (void) n;
53 free(lists);
54}
55
56void
57fnmatch_list_of_states_insert(struct list_of_states *list,
58 size_t state)
59{
60 assert(list);
61 assert(state < list->reserved);
62
63 if (list->has[state])
64 return;
65
66 list->states[list->size++] = state;
67 list->has[state] = 1;
68}
69
70void
71fnmatch_list_of_states_clear(struct list_of_states *list)
72{
73 assert(list);
74
75 list->size = 0;
76 memset(list->has, 0, list->reserved * sizeof (*list->has));
77}
diff --git a/src/lib/evil/evil_fnmatch_private.h b/src/lib/evil/evil_fnmatch_private.h
new file mode 100644
index 0000000000..f5ced5d68f
--- /dev/null
+++ b/src/lib/evil/evil_fnmatch_private.h
@@ -0,0 +1,24 @@
1#ifndef __EVIL_FNMATCH_PRIVATE_H__
2#define __EVIL_FNMATCH_PRIVATE_H__
3
4
5typedef int e_bool;
6
7struct list_of_states
8{
9 size_t reserved;
10 size_t size;
11 size_t *states;
12 e_bool *has;
13};
14
15struct list_of_states *fnmatch_list_of_states_alloc(size_t n, size_t pattern_len);
16
17void fnmatch_list_of_states_free(struct list_of_states *lists, size_t n);
18
19void fnmatch_list_of_states_insert(struct list_of_states *list, size_t state);
20
21void fnmatch_list_of_states_clear(struct list_of_states *list);
22
23
24#endif /* __EVIL_FNMATCH_PRIVATE_H__ */
diff --git a/src/lib/evil/evil_inet.c b/src/lib/evil/evil_inet.c
new file mode 100644
index 0000000000..99ce14edc2
--- /dev/null
+++ b/src/lib/evil/evil_inet.c
@@ -0,0 +1,648 @@
1
2/*
3 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
4 * Copyright (c) 1996,1999 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * Modifications: Vincent Torri, for the integration in Evil
21 * - modification of the name of some functions
22 * * modification of the management of the error
23 */
24
25#ifdef HAVE_CONFIG_H
26# include "config.h"
27#endif /* HAVE_CONFIG_H */
28
29#include <stdio.h>
30#include <ctype.h>
31
32#ifdef HAVE_ERRNO_H
33# include <errno.h>
34#endif /* HAVE_ERRNO_H */
35
36#ifndef WIN32_LEAN_AND_MEAN
37# define WIN32_LEAN_AND_MEAN
38#endif
39#include <winsock2.h>
40#undef WIN32_LEAN_AND_MEAN
41
42#include "evil_macro.h"
43#include "evil_inet.h"
44#include "evil_private.h"
45#define APICHAR char
46#include "evil_print.h"
47
48#ifndef EMSGSIZE
49# define EMSGSIZE WSAEMSGSIZE
50#endif
51
52#ifndef EAFNOSUPPORT
53# define EAFNOSUPPORT WSAEAFNOSUPPORT
54#endif
55
56#define SPRINTF(x) ((size_t)sprintf x)
57
58#define ERRNO ((int)GetLastError())
59#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
60
61#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
62#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
63#define ISUPPER(x) (isupper((int) ((unsigned char)x)))
64
65#define NS_IN6ADDRSZ 16
66#define NS_INT16SZ 2
67#define NS_INADDRSZ sizeof(IN_ADDR)
68
69
70struct ares_in6_addr {
71 union {
72 unsigned char _S6_u8[16];
73 } _S6_un;
74};
75
76const struct ares_in6_addr ares_in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
77
78
79/*
80 * static int
81 * inet_net_pton_ipv4(src, dst, size)
82 * convert IPv4 network number from presentation to network format.
83 * accepts hex octets, hex strings, decimal octets, and /CIDR.
84 * "size" is in bytes and describes "dst".
85 * return:
86 * number of bits, either imputed classfully or specified with /CIDR,
87 * or -1 if some failure occurred (check errno). ENOENT means it was
88 * not an IPv4 network specification.
89 * note:
90 * network byte order assumed. this means 192.5.5.240/28 has
91 * 0b11110000 in its fourth octet.
92 * note:
93 * On Windows we store the error in the thread errno, not
94 * in the winsock error code. This is to avoid loosing the
95 * actual last winsock error. So use macro ERRNO to fetch the
96 * errno this funtion sets when returning (-1), not SOCKERRNO.
97 * author:
98 * Paul Vixie (ISC), June 1996
99 */
100static int
101inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size)
102{
103 static const char xdigits[] = "0123456789abcdef";
104 static const char digits[] = "0123456789";
105 int n, ch, tmp = 0, dirty, bits;
106 const unsigned char *odst = dst;
107
108 ch = *src++;
109 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
110 && ISXDIGIT(src[1])) {
111 /* Hexadecimal: Eat nybble string. */
112 if (!size)
113 goto emsgsize;
114 dirty = 0;
115 src++; /* skip x or X. */
116 while ((ch = *src++) != '\0' && ISXDIGIT(ch)) {
117 if (ISUPPER(ch))
118 ch = tolower(ch);
119 n = (int)(strchr(xdigits, ch) - xdigits);
120 if (dirty == 0)
121 tmp = n;
122 else
123 tmp = (tmp << 4) | n;
124 if (++dirty == 2) {
125 if (!size--)
126 goto emsgsize;
127 *dst++ = (unsigned char) tmp;
128 dirty = 0;
129 }
130 }
131 if (dirty) { /* Odd trailing nybble? */
132 if (!size--)
133 goto emsgsize;
134 *dst++ = (unsigned char) (tmp << 4);
135 }
136 } else if (ISDIGIT(ch)) {
137 /* Decimal: eat dotted digit string. */
138 for (;;) {
139 tmp = 0;
140 do {
141 n = (int)(strchr(digits, ch) - digits);
142 tmp *= 10;
143 tmp += n;
144 if (tmp > 255)
145 goto enoent;
146 } while ((ch = *src++) != '\0' &&
147 ISDIGIT(ch));
148 if (!size--)
149 goto emsgsize;
150 *dst++ = (unsigned char) tmp;
151 if (ch == '\0' || ch == '/')
152 break;
153 if (ch != '.')
154 goto enoent;
155 ch = *src++;
156 if (!ISDIGIT(ch))
157 goto enoent;
158 }
159 } else
160 goto enoent;
161
162 bits = -1;
163 if (ch == '/' &&
164 ISDIGIT(src[0]) && dst > odst) {
165 /* CIDR width specifier. Nothing can follow it. */
166 ch = *src++; /* Skip over the /. */
167 bits = 0;
168 do {
169 n = (int)(strchr(digits, ch) - digits);
170 bits *= 10;
171 bits += n;
172 } while ((ch = *src++) != '\0' && ISDIGIT(ch));
173 if (ch != '\0')
174 goto enoent;
175 if (bits > 32)
176 goto emsgsize;
177 }
178
179 /* Firey death and destruction unless we prefetched EOS. */
180 if (ch != '\0')
181 goto enoent;
182
183 /* If nothing was written to the destination, we found no address. */
184 if (dst == odst)
185 goto enoent;
186 /* If no CIDR spec was given, infer width from net class. */
187 if (bits == -1) {
188 if (*odst >= 240) /* Class E */
189 bits = 32;
190 else if (*odst >= 224) /* Class D */
191 bits = 8;
192 else if (*odst >= 192) /* Class C */
193 bits = 24;
194 else if (*odst >= 128) /* Class B */
195 bits = 16;
196 else /* Class A */
197 bits = 8;
198 /* If imputed mask is narrower than specified octets, widen. */
199 if (bits < ((dst - odst) * 8))
200 bits = (int)(dst - odst) * 8;
201 /*
202 * If there are no additional bits specified for a class D
203 * address adjust bits to 4.
204 */
205 if (bits == 8 && *odst == 224)
206 bits = 4;
207 }
208 /* Extend network to cover the actual mask. */
209 while (bits > ((dst - odst) * 8)) {
210 if (!size--)
211 goto emsgsize;
212 *dst++ = '\0';
213 }
214 return (bits);
215
216 enoent:
217 SET_ERRNO(ENOENT);
218 return (-1);
219
220 emsgsize:
221 SET_ERRNO(EMSGSIZE);
222 return (-1);
223}
224
225static int
226getbits(const char *src, int *bitsp)
227{
228 static const char digits[] = "0123456789";
229 int n;
230 int val;
231 char ch;
232
233 val = 0;
234 n = 0;
235 while ((ch = *src++) != '\0') {
236 const char *pch;
237
238 pch = strchr(digits, ch);
239 if (pch != NULL) {
240 if (n++ != 0 && val == 0) /* no leading zeros */
241 return (0);
242 val *= 10;
243 val += (pch - digits);
244 if (val > 128) /* range */
245 return (0);
246 continue;
247 }
248 return (0);
249 }
250 if (n == 0)
251 return (0);
252 *bitsp = val;
253 return (1);
254}
255
256static int
257getv4(const char *src, unsigned char *dst, int *bitsp)
258{
259 static const char digits[] = "0123456789";
260 unsigned char *odst = dst;
261 int n;
262 unsigned int val;
263 char ch;
264
265 val = 0;
266 n = 0;
267 while ((ch = *src++) != '\0') {
268 const char *pch;
269
270 pch = strchr(digits, ch);
271 if (pch != NULL) {
272 if (n++ != 0 && val == 0) /* no leading zeros */
273 return (0);
274 val *= 10;
275 val += (pch - digits);
276 if (val > 255) /* range */
277 return (0);
278 continue;
279 }
280 if (ch == '.' || ch == '/') {
281 if (dst - odst > 3) /* too many octets? */
282 return (0);
283 *dst++ = (unsigned char)val;
284 if (ch == '/')
285 return (getbits(src, bitsp));
286 val = 0;
287 n = 0;
288 continue;
289 }
290 return (0);
291 }
292 if (n == 0)
293 return (0);
294 if (dst - odst > 3) /* too many octets? */
295 return (0);
296 *dst++ = (unsigned char)val;
297 return (1);
298}
299
300static int
301inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size)
302{
303 static const char xdigits_l[] = "0123456789abcdef",
304 xdigits_u[] = "0123456789ABCDEF";
305 unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
306 const char *xdigits, *curtok;
307 int ch, saw_xdigit;
308 unsigned int val;
309 int digits;
310 int bits;
311 size_t bytes;
312 int words;
313 int ipv4;
314
315 memset((tp = tmp), '\0', NS_IN6ADDRSZ);
316 endp = tp + NS_IN6ADDRSZ;
317 colonp = NULL;
318 /* Leading :: requires some special handling. */
319 if (*src == ':')
320 if (*++src != ':')
321 goto enoent;
322 curtok = src;
323 saw_xdigit = 0;
324 val = 0;
325 digits = 0;
326 bits = -1;
327 ipv4 = 0;
328 while ((ch = *src++) != '\0') {
329 const char *pch;
330
331 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
332 pch = strchr((xdigits = xdigits_u), ch);
333 if (pch != NULL) {
334 val <<= 4;
335 val |= (pch - xdigits);