sedna 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/{CHANGES → CHANGES.rdoc} +9 -0
  2. data/{README → README.rdoc} +23 -25
  3. data/Rakefile +32 -9
  4. data/ext/{extconf.rb → sedna/extconf.rb} +33 -21
  5. data/ext/{sedna.c → sedna/sedna.c} +48 -40
  6. data/test/sedna_test.rb +9 -9
  7. data/vendor/sedna/AUTHORS +18 -0
  8. data/vendor/sedna/COPYRIGHT +90 -0
  9. data/vendor/sedna/LICENSE +202 -0
  10. data/vendor/sedna/Makefile.include +423 -0
  11. data/vendor/sedna/Makefile.platform +31 -0
  12. data/vendor/sedna/depend.sed +48 -0
  13. data/vendor/sedna/driver/c/Makefile +98 -0
  14. data/vendor/sedna/driver/c/libsedna.c +1998 -0
  15. data/vendor/sedna/driver/c/libsedna.h +199 -0
  16. data/vendor/sedna/driver/c/sednamt.def +21 -0
  17. data/vendor/sedna/driver/c/sp_defs.h +186 -0
  18. data/vendor/sedna/kernel/common/FastXptrHash.cpp +101 -0
  19. data/vendor/sedna/kernel/common/IntHash.h +314 -0
  20. data/vendor/sedna/kernel/common/IntList.h +224 -0
  21. data/vendor/sedna/kernel/common/Makefile +30 -0
  22. data/vendor/sedna/kernel/common/SSMMsg.cpp +459 -0
  23. data/vendor/sedna/kernel/common/SSMMsg.h +142 -0
  24. data/vendor/sedna/kernel/common/XptrHash.h +435 -0
  25. data/vendor/sedna/kernel/common/argtable.c +972 -0
  26. data/vendor/sedna/kernel/common/argtable.h +896 -0
  27. data/vendor/sedna/kernel/common/base.cpp +339 -0
  28. data/vendor/sedna/kernel/common/base.h +226 -0
  29. data/vendor/sedna/kernel/common/bit_set.cpp +157 -0
  30. data/vendor/sedna/kernel/common/bit_set.h +55 -0
  31. data/vendor/sedna/kernel/common/commutil.h +67 -0
  32. data/vendor/sedna/kernel/common/config.h +62 -0
  33. data/vendor/sedna/kernel/common/counted_ptr.h +74 -0
  34. data/vendor/sedna/kernel/common/errdbg/ErrorCodes.java +1056 -0
  35. data/vendor/sedna/kernel/common/errdbg/Makefile +34 -0
  36. data/vendor/sedna/kernel/common/errdbg/assert.c +133 -0
  37. data/vendor/sedna/kernel/common/errdbg/d_printf.c +150 -0
  38. data/vendor/sedna/kernel/common/errdbg/d_printf.h +91 -0
  39. data/vendor/sedna/kernel/common/errdbg/error.codes +1743 -0
  40. data/vendor/sedna/kernel/common/errdbg/error_codes.c +531 -0
  41. data/vendor/sedna/kernel/common/errdbg/error_codes.h +549 -0
  42. data/vendor/sedna/kernel/common/errdbg/error_codes_scm.scm +527 -0
  43. data/vendor/sedna/kernel/common/errdbg/event_log.c +956 -0
  44. data/vendor/sedna/kernel/common/errdbg/event_log.h +226 -0
  45. data/vendor/sedna/kernel/common/errdbg/exceptions.cpp +155 -0
  46. data/vendor/sedna/kernel/common/errdbg/exceptions.h +559 -0
  47. data/vendor/sedna/kernel/common/errdbg/gen_error_codes +0 -0
  48. data/vendor/sedna/kernel/common/errdbg/gen_error_codes.c +345 -0
  49. data/vendor/sedna/kernel/common/gmm.cpp +192 -0
  50. data/vendor/sedna/kernel/common/gmm.h +29 -0
  51. data/vendor/sedna/kernel/common/ipc_ops.cpp +435 -0
  52. data/vendor/sedna/kernel/common/ipc_ops.h +51 -0
  53. data/vendor/sedna/kernel/common/lfsGlobals.h +12 -0
  54. data/vendor/sedna/kernel/common/lm_base.h +90 -0
  55. data/vendor/sedna/kernel/common/mmgr/Makefile +11 -0
  56. data/vendor/sedna/kernel/common/mmgr/aset.c +1185 -0
  57. data/vendor/sedna/kernel/common/mmgr/mcxt.c +741 -0
  58. data/vendor/sedna/kernel/common/mmgr/memnodes.h +70 -0
  59. data/vendor/sedna/kernel/common/mmgr/memutils.h +145 -0
  60. data/vendor/sedna/kernel/common/mmgr/se_alloc.h +321 -0
  61. data/vendor/sedna/kernel/common/mmgr/track.c +214 -0
  62. data/vendor/sedna/kernel/common/pping.cpp +672 -0
  63. data/vendor/sedna/kernel/common/pping.h +119 -0
  64. data/vendor/sedna/kernel/common/rcv_test.cpp +273 -0
  65. data/vendor/sedna/kernel/common/rcv_test.h +19 -0
  66. data/vendor/sedna/kernel/common/sedna.c +128 -0
  67. data/vendor/sedna/kernel/common/sedna.h +49 -0
  68. data/vendor/sedna/kernel/common/sedna_ef.h +52 -0
  69. data/vendor/sedna/kernel/common/sm_vmm_data.h +144 -0
  70. data/vendor/sedna/kernel/common/sp.c +93 -0
  71. data/vendor/sedna/kernel/common/sp.h +36 -0
  72. data/vendor/sedna/kernel/common/st/Makefile +20 -0
  73. data/vendor/sedna/kernel/common/st/os_linux/stacktrace.c +213 -0
  74. data/vendor/sedna/kernel/common/st/os_nt/stacktrace.c +338 -0
  75. data/vendor/sedna/kernel/common/st/os_other/stacktrace.c +39 -0
  76. data/vendor/sedna/kernel/common/st/stacktrace.h +72 -0
  77. data/vendor/sedna/kernel/common/st/stacktrfmt.c +64 -0
  78. data/vendor/sedna/kernel/common/tr_debug.cpp +112 -0
  79. data/vendor/sedna/kernel/common/tr_debug.h +22 -0
  80. data/vendor/sedna/kernel/common/u/Makefile +14 -0
  81. data/vendor/sedna/kernel/common/u/u.c +268 -0
  82. data/vendor/sedna/kernel/common/u/u.h +715 -0
  83. data/vendor/sedna/kernel/common/u/uatomic.h +12 -0
  84. data/vendor/sedna/kernel/common/u/udl.h +31 -0
  85. data/vendor/sedna/kernel/common/u/uevent.c +406 -0
  86. data/vendor/sedna/kernel/common/u/uevent.h +71 -0
  87. data/vendor/sedna/kernel/common/u/ugnames.cpp +330 -0
  88. data/vendor/sedna/kernel/common/u/ugnames.h +134 -0
  89. data/vendor/sedna/kernel/common/u/uhash_map.h +77 -0
  90. data/vendor/sedna/kernel/common/u/uhdd.c +1018 -0
  91. data/vendor/sedna/kernel/common/u/uhdd.h +206 -0
  92. data/vendor/sedna/kernel/common/u/ummap.cpp +268 -0
  93. data/vendor/sedna/kernel/common/u/ummap.h +60 -0
  94. data/vendor/sedna/kernel/common/u/umutex.c +145 -0
  95. data/vendor/sedna/kernel/common/u/umutex.h +65 -0
  96. data/vendor/sedna/kernel/common/u/upipe.cpp +244 -0
  97. data/vendor/sedna/kernel/common/u/upipe.h +74 -0
  98. data/vendor/sedna/kernel/common/u/uprocess.c +767 -0
  99. data/vendor/sedna/kernel/common/u/uprocess.h +91 -0
  100. data/vendor/sedna/kernel/common/u/usafesync.h +41 -0
  101. data/vendor/sedna/kernel/common/u/usecurity.c +150 -0
  102. data/vendor/sedna/kernel/common/u/usecurity.h +55 -0
  103. data/vendor/sedna/kernel/common/u/usem.c +891 -0
  104. data/vendor/sedna/kernel/common/u/usem.h +83 -0
  105. data/vendor/sedna/kernel/common/u/ushm.c +222 -0
  106. data/vendor/sedna/kernel/common/u/ushm.h +46 -0
  107. data/vendor/sedna/kernel/common/u/usocket.c +541 -0
  108. data/vendor/sedna/kernel/common/u/usocket.h +118 -0
  109. data/vendor/sedna/kernel/common/u/usystem.c +57 -0
  110. data/vendor/sedna/kernel/common/u/usystem.h +46 -0
  111. data/vendor/sedna/kernel/common/u/uthread.c +259 -0
  112. data/vendor/sedna/kernel/common/u/uthread.h +95 -0
  113. data/vendor/sedna/kernel/common/u/utime.c +65 -0
  114. data/vendor/sedna/kernel/common/u/utime.h +40 -0
  115. data/vendor/sedna/kernel/common/u/uutils.c +142 -0
  116. data/vendor/sedna/kernel/common/u/uutils.h +65 -0
  117. data/vendor/sedna/kernel/common/ugc.cpp +156 -0
  118. data/vendor/sedna/kernel/common/ugc.h +15 -0
  119. data/vendor/sedna/kernel/common/utils.cpp +156 -0
  120. data/vendor/sedna/kernel/common/utils.h +133 -0
  121. data/vendor/sedna/kernel/common/version.c +16 -0
  122. data/vendor/sedna/kernel/common/version.h +21 -0
  123. data/vendor/sedna/kernel/common/wustructures.h +18 -0
  124. data/vendor/sedna/kernel/common/wutypes.h +34 -0
  125. data/vendor/sedna/kernel/common/xptr.cpp +17 -0
  126. data/vendor/sedna/kernel/common/xptr.h +211 -0
  127. data/vendor/sedna/ver +1 -0
  128. metadata +142 -14
@@ -0,0 +1,74 @@
1
+ /*
2
+ * File: upipe.h
3
+ * Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
4
+ */
5
+
6
+
7
+ #ifndef _UPIPE_H
8
+ #define _UPIPE_H
9
+
10
+ #include <string>
11
+ #include "common/u/u.h"
12
+
13
+
14
+ #ifdef _WIN32
15
+ typedef HANDLE UPIPE;
16
+ #else
17
+ typedef int UPIPE;
18
+ #endif
19
+
20
+ // return value 0 indicates success
21
+ int uPipe(UPIPE* rpipe, /*read pipe*/
22
+ UPIPE* wpipe, /*write pipe*/
23
+ int inheritable, /*is handles inhereted by child processes*/
24
+ sys_call_error_fun fun
25
+ );
26
+
27
+ // positive return values indicates number of bytes read
28
+ // if return value is 0 then end of file is reached
29
+ // negative return values indicates an error
30
+ int uReadPipe(UPIPE rpipe, /*read pipe*/
31
+ void *buf, /*buffer for data*/
32
+ int nbyte, /*size of the buffer*/
33
+ sys_call_error_fun fun
34
+ );
35
+
36
+ // positive return values indicates number of bytes read
37
+ // if return value is 0 then end of file is reached
38
+ // negative return values indicates an error
39
+ int uReadPipeAll(UPIPE rpipe, // read pipe
40
+ void* buf, // buffer for data
41
+ int nbyte, // size of the buffer
42
+ sys_call_error_fun fun
43
+ );
44
+
45
+
46
+ // reads a string from pipe (reads until \0 symbol meet)
47
+ int uReadPipeMsg(UPIPE rpipe,std::string &str, sys_call_error_fun fun);
48
+
49
+ // return value indicates number of bytes actually written to the pipe
50
+ // negative return value indicates error
51
+ int uWritePipe(UPIPE wpipe, /*write pipe*/
52
+ const void *buf, /*pointer to data*/
53
+ int nbyte, /*size of the data*/
54
+ sys_call_error_fun fun
55
+ );
56
+
57
+ // return value 0 indicates success
58
+ int uWritePipeAll(UPIPE wpipe, /*write pipe*/
59
+ const void *buf, /*pointer to data*/
60
+ int nbyte, /*size of the data*/
61
+ sys_call_error_fun fun
62
+ );
63
+
64
+ // return value 0 indicates success
65
+ int uClosePipe(UPIPE upipe, sys_call_error_fun fun);
66
+
67
+ // return value 0 indicates success
68
+ int uReadPipeAll(UPIPE rpipe, std::string &str, sys_call_error_fun fun);
69
+
70
+ // return value 0 indicates success
71
+ int uPipeDoNotInherit(UPIPE *upipe, sys_call_error_fun fun);
72
+
73
+ #endif
74
+
@@ -0,0 +1,767 @@
1
+ /*
2
+ * File: uprocess.cpp
3
+ * Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
4
+ */
5
+
6
+
7
+ #include "common/u/uprocess.h"
8
+ #include "common/errdbg/d_printf.h"
9
+ #include "common/u/uutils.h"
10
+
11
+ #ifdef _WIN32
12
+ #else
13
+ #include <sys/types.h>
14
+ #include <sys/stat.h>
15
+ #include <sys/wait.h>
16
+ #include <fcntl.h>
17
+ #include <unistd.h>
18
+ #include <limits.h>
19
+ #endif
20
+
21
+
22
+
23
+ /* Change or add an environment variable.
24
+ * name (in) - name of the varilable to add or change
25
+ * value (in) - value of variable to set
26
+ * buffer (out) - if not NULL then *nix putenv() semantics is
27
+ * used, so that address of the variable's value
28
+ * is saved in this argument.
29
+ * It's your task to clean up this memory with
30
+ * free() call. On Windows NULL is returned.
31
+ * Returns:
32
+ * 0 - in case of success,
33
+ * 1 - in case of error.
34
+ */
35
+ int uSetEnvironmentVariable(const char* name, const char* value, char** buffer, sys_call_error_fun fun)
36
+ {
37
+ #ifdef _WIN32
38
+ BOOL res;
39
+ if(buffer) *buffer = NULL;
40
+ res = SetEnvironmentVariable(
41
+ name, /* environment variable name */
42
+ value); /* new value for variable */
43
+
44
+ if (res == 0) {
45
+ sys_call_error("SetEnvironmentVariable");
46
+ return 1;
47
+ }
48
+ return 0;
49
+ #else
50
+ int name_len = strlen(name);
51
+ int value_len = strlen(value);
52
+
53
+ /* This string will become the part
54
+ * of the environment, so we must not delete it there.
55
+ */
56
+ char *str = (char*)malloc(name_len + value_len + 2);
57
+ if(buffer) *buffer = str;
58
+
59
+ memcpy(str, name, name_len);
60
+ str[name_len] = '=';
61
+ memcpy(str + name_len + 1, value, value_len);
62
+ str[name_len + value_len + 1] = '\0';
63
+ int res = putenv(str);
64
+
65
+ if (res != 0) {
66
+ sys_call_error("putenv");
67
+ return 1;
68
+ }
69
+
70
+ return 0;
71
+ #endif
72
+ }
73
+
74
+ int uGetEnvironmentVariable(const char* name, char* buf, int size, sys_call_error_fun fun)
75
+ {
76
+ #ifdef _WIN32
77
+ DWORD res = 0;
78
+ memset(buf, 0, size);
79
+ res = GetEnvironmentVariable(
80
+ name, /* environment variable name */
81
+ buf,
82
+ size - 1
83
+ );
84
+ if (res == 0)
85
+ {
86
+ sys_call_error("GetEnvironmentVariable");
87
+ return 1;
88
+ }
89
+ if (res > size - 1) return 1;
90
+ return 0;
91
+ #else
92
+ char *res = getenv(name);
93
+ if (res == NULL)
94
+ {
95
+ sys_call_error("getenv");
96
+ return 1;
97
+ }
98
+ if ((int)strlen(res) > size - 1) return 1;
99
+ strcpy(buf, res);
100
+ return 0;
101
+ #endif
102
+ }
103
+
104
+ int uGetCurProcessWorkingSetSize(usize_t *MinWorkingSetSize, usize_t *MaxWorkingSetSize, sys_call_error_fun fun)
105
+ {
106
+ #ifdef _WIN32
107
+ BOOL res = GetProcessWorkingSetSize(
108
+ GetCurrentProcess(), // handle to the process
109
+ MinWorkingSetSize, // minimum working set size
110
+ MaxWorkingSetSize // maximum working set size
111
+ );
112
+ if (res == 0)
113
+ {
114
+ sys_call_error("GetProcessWorkingSetSize");
115
+ return 1;
116
+ }
117
+ return 0;
118
+ #else
119
+ *MinWorkingSetSize = *MaxWorkingSetSize = 0;
120
+ return 0;
121
+ #endif
122
+ }
123
+
124
+ int uSetCurProcessWorkingSetSize(usize_t MinWorkingSetSize, usize_t MaxWorkingSetSize, sys_call_error_fun fun)
125
+ {
126
+ #ifdef _WIN32
127
+ BOOL res = SetProcessWorkingSetSize(
128
+ GetCurrentProcess(), // handle to the process
129
+ MinWorkingSetSize, // minimum working set size
130
+ MaxWorkingSetSize // maximum working set size
131
+ );
132
+ if (res == 0)
133
+ {
134
+ sys_call_error("SetProcessWorkingSetSize");
135
+ return 1;
136
+ }
137
+ return 0;
138
+ #else
139
+ return 0;
140
+ #endif
141
+ }
142
+
143
+ /* return value 0 indicates success */
144
+ int uCreateProcess(
145
+ char *command_line, /* command line string */
146
+ bool inherit_handles, /* handle inheritance option (not implem*/
147
+ const char *cur_dir, /* current directory name */
148
+ UFlag flags,
149
+ UPHANDLE *process_handle,
150
+ UTHANDLE *thread_handle,
151
+ UPID *process_id,
152
+ UTID *thread_id,
153
+ USECURITY_ATTRIBUTES* sa,
154
+ sys_call_error_fun fun
155
+ )
156
+ {
157
+ #ifdef _WIN32
158
+
159
+ PROCESS_INFORMATION piProcInfo;
160
+ STARTUPINFO siStartInfo;
161
+ BOOL res;
162
+
163
+ ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
164
+ ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
165
+ siStartInfo.cb = sizeof(STARTUPINFO);
166
+
167
+ if(CREATE_NEW_CONSOLE == flags)
168
+ {
169
+ siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
170
+ siStartInfo.wShowWindow = SW_HIDE;
171
+ }
172
+
173
+ res = CreateProcess(
174
+ NULL, /* name of executable module */
175
+ command_line, /* command line string */
176
+ sa, /* Security attributes for the new process */
177
+ sa, /* Security attributes for the main thread */
178
+ inherit_handles ? TRUE : FALSE, /* handle inheritance option */
179
+ flags, /* creation flags */
180
+ NULL, /* use parent's environment */
181
+ cur_dir, /* use parent's current directory */
182
+ &siStartInfo, /* STARTUPINFO pointer */
183
+ &piProcInfo /* receives PROCESS_INFORMATION */
184
+ );
185
+
186
+ if (res == 0) sys_call_error("CreateProcess");
187
+
188
+ if (process_handle) *process_handle = piProcInfo.hProcess;
189
+ else if (CloseHandle(piProcInfo.hProcess) == 0) sys_call_error("CloseHandle");
190
+
191
+ if (thread_handle) *thread_handle = piProcInfo.hThread;
192
+ else if (CloseHandle(piProcInfo.hThread) == 0) sys_call_error("CloseHandle");
193
+
194
+ if (process_id) *process_id = piProcInfo.dwProcessId;
195
+ if (thread_id) *thread_id = piProcInfo.dwThreadId;
196
+
197
+ if (res == 0) return 1;
198
+ return 0;
199
+
200
+ #else
201
+ #define MAX_NUMBER_OF_ARGS 256
202
+ #define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r')
203
+
204
+ pid_t pid = 0;
205
+
206
+ if ((pid = fork()) == 0)
207
+ { /* child process */
208
+
209
+ if (flags == U_DETACHED_PROCESS)
210
+ {
211
+ /* close stdout and stderr to avoid output to console */
212
+ int null_dev = open("/dev/null", O_RDWR);
213
+ if (null_dev == -1) { sys_call_error("open"); exit(1); }
214
+
215
+ if (close(STDOUT_FILENO) == -1) { sys_call_error("close"); exit(1); }
216
+ if (close(STDERR_FILENO) == -1){ sys_call_error("close"); exit(1); }
217
+ if (close(STDIN_FILENO) == -1) { sys_call_error("close"); exit(1); }
218
+
219
+ if (dup2(null_dev, STDOUT_FILENO) == -1) { sys_call_error("dup2"); exit(1); }
220
+ if (dup2(null_dev, STDERR_FILENO) == -1) { sys_call_error("dup2"); exit(1); }
221
+ if (dup2(null_dev, STDIN_FILENO) == -1) { sys_call_error("dup2"); exit(1); }
222
+
223
+ if (close(null_dev) == -1) { sys_call_error("close"); exit(1); }
224
+ }
225
+
226
+ if (cur_dir != NULL)
227
+ {
228
+ /* change current directory to cur_dir */
229
+ if (chdir(cur_dir) != 0)
230
+ {
231
+ sys_call_error("chdir");
232
+ exit(1);
233
+ }
234
+ }
235
+
236
+ char *args[MAX_NUMBER_OF_ARGS];
237
+ memset(args, '\0', MAX_NUMBER_OF_ARGS * sizeof(char*));
238
+ int args_num = 0;
239
+
240
+ char *pred = NULL;
241
+ char *cur = command_line;
242
+
243
+ while (true)
244
+ {
245
+ while (whitespace(*cur)) cur++;
246
+
247
+ pred = cur;
248
+
249
+ while (!(whitespace(*cur) || !*cur)) cur++;
250
+
251
+ if (pred < cur)
252
+ {
253
+ args[args_num] = (char*)malloc(cur - pred + 1);
254
+ args[args_num][cur - pred] = '\0';
255
+ memcpy(args[args_num], pred, cur - pred);
256
+ args_num++;
257
+ }
258
+ else break;
259
+ }
260
+
261
+ args[args_num] = NULL;
262
+
263
+ if (execvp(args[0], args) == -1)
264
+ {
265
+ sys_call_error("execvp");
266
+ exit(1);
267
+ }
268
+
269
+ for (args_num = 0; args[args_num] != NULL; args_num++) free(args[args_num]);
270
+ }
271
+ else
272
+ {
273
+ if (pid == -1)
274
+ {
275
+ sys_call_error("fork");
276
+ return 1;
277
+ }
278
+
279
+ if (process_handle) *process_handle = 0;
280
+ if (thread_handle) *thread_handle = 0;
281
+ if (process_id) *process_id = pid;
282
+ if (thread_id) *thread_id = 0;
283
+ }
284
+ return 0;
285
+ #endif
286
+ }
287
+
288
+ int uTerminateProcess(UPID pid, UPHANDLE h, int exit_code, sys_call_error_fun fun)
289
+ {
290
+ #ifdef _WIN32
291
+ BOOL res = TerminateProcess(
292
+ h, /*handle to the process */
293
+ exit_code /* exit code for the process */
294
+ );
295
+
296
+ if (res == 0)
297
+ {
298
+ sys_call_error("TerminateProcess");
299
+ return 1;
300
+ }
301
+ return 0;
302
+ #else
303
+ if (kill(pid, SIGKILL) == -1)
304
+ {
305
+ sys_call_error("kill");
306
+ return 1;
307
+ }
308
+ return 0;
309
+ #endif
310
+ }
311
+
312
+ void uExitProcess(int exit_code, sys_call_error_fun fun)
313
+ {
314
+ #ifdef _WIN32
315
+ ExitProcess(exit_code);
316
+ #else
317
+ exit(exit_code);
318
+ #endif
319
+ }
320
+
321
+ UPID uGetCurrentProcessId(sys_call_error_fun fun)
322
+ {
323
+ #ifdef _WIN32
324
+ return GetCurrentProcessId();
325
+ #else
326
+ return getpid();
327
+ #endif
328
+ }
329
+
330
+ /* Check if process exists.
331
+ * Return values:
332
+ * 0 - process alive
333
+ * -1 - process doesn't exist
334
+ * -2 - some error occurred
335
+ *
336
+ * At present uOpenProcess is implemented via this function on
337
+ * any Nix like OS.
338
+ *
339
+ * If pid == 0 fuction always returns -1 for compatibility
340
+ * between POSIX-like operating systems. For example, FreeBSD
341
+ * has process with PID=0, Linux doesn't.
342
+ */
343
+ int
344
+ uIsProcessExist(UPID pid, UPHANDLE h, sys_call_error_fun fun) {
345
+ #ifdef _WIN32
346
+ BOOL res = FALSE;
347
+ DWORD status = 0;
348
+
349
+ if (pid == 0) return -1;
350
+
351
+ res = GetExitCodeProcess(h, &status);
352
+ if (res == 0) {
353
+ sys_call_error("GetExitCodeProcess");
354
+ return -2;
355
+ }
356
+
357
+ return (status == STILL_ACTIVE) ? 0 : -1;
358
+ #else
359
+ int res;
360
+
361
+ #ifdef HAVE_PROC /* Linux, SunOS */
362
+
363
+ char buf[U_MAX_PATH];
364
+ struct stat stf;
365
+
366
+ if (pid == 0) return -1;
367
+
368
+ strcpy(buf, "/proc/");
369
+ int2c_str(pid, buf + strlen("/proc/"));
370
+
371
+ /* Attempt to get the file attributes */
372
+ res = stat(buf, &stf);
373
+
374
+ /* On SunOS we have to handle EINTR appropriately */
375
+ while (-1 == res) {
376
+ /* There is no such file */
377
+ if ( ENOENT == errno )
378
+ return -1;
379
+ #if defined(SunOS)
380
+ else if( EINTR == errno )
381
+ res = stat(buf, &stf);
382
+ #endif
383
+ else {
384
+ sys_call_error("stat");
385
+ return -2;
386
+ }
387
+ }
388
+
389
+ return 0;
390
+
391
+ #else /* !HAVE_PROC: Darwin, FreeBSD */
392
+
393
+ if (pid == 0) return -1;
394
+
395
+ res = kill(pid, 0);
396
+
397
+ if(-1 == res) {
398
+ /* Process exists but we don't have permissions
399
+ * to send a signal.
400
+ */
401
+ if(EPERM == errno) return 0;
402
+
403
+ /* The pid doesn't exist. */
404
+ return -1;
405
+ }
406
+ else {
407
+ /* Process exists. */
408
+ return 0;
409
+ }
410
+
411
+ #endif /* HAVE_PROC */
412
+ #endif /* _WIN32 */
413
+ }
414
+
415
+ /* Win: Opens an existing local process object.
416
+ * Nix: Simply checks out if process exists.
417
+ * Return values:
418
+ * 0 - process successfully opened
419
+ * -1 - some error occured or process doesn't exist
420
+ */
421
+ int
422
+ uOpenProcess(UPID pid, UPHANDLE *h, sys_call_error_fun fun) {
423
+ #ifdef _WIN32
424
+ *h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
425
+ if (*h == NULL) {
426
+ sys_call_error("OpenProcess");
427
+ return -1;
428
+ }
429
+ else
430
+ return 0;
431
+ #else
432
+ int res = uIsProcessExist(pid, 0, fun);
433
+ *h = 0;
434
+ return (0 == res) ? 0 : -1;
435
+ #endif
436
+ }
437
+
438
+
439
+ int uCloseProcess(UPHANDLE h, sys_call_error_fun fun)
440
+ {
441
+ #ifdef _WIN32
442
+ int res;
443
+ res = CloseHandle(h);
444
+ if (res != 0) return 0;
445
+ else
446
+ {
447
+ sys_call_error("CloseHandle");
448
+ return -1;
449
+ }
450
+ #else
451
+ return 0;
452
+ #endif
453
+ }
454
+
455
+ int uWaitForChildProcess(UPID pid, UPHANDLE h, int *status, sys_call_error_fun fun)
456
+ {
457
+ #ifdef _WIN32
458
+ DWORD res1 = 0;
459
+ BOOL res2 = FALSE;
460
+ DWORD _status = 0;
461
+
462
+ res1 = WaitForSingleObject(h, INFINITE);
463
+ if (res1 == WAIT_FAILED)
464
+ {
465
+ sys_call_error("WaitForSingleObject");
466
+ return -1;
467
+ }
468
+
469
+ res2 = GetExitCodeProcess(h, &_status);
470
+ if (res2 == 0)
471
+ {
472
+ sys_call_error("GetExitCodeProcess");
473
+ return -1;
474
+ }
475
+
476
+ if (status) *status = _status;
477
+
478
+ return 0;
479
+ #else
480
+ int res = waitpid(pid, status, 0);
481
+ if (res == -1)
482
+ {
483
+ sys_call_error("waitpid");
484
+ return -1;
485
+ }
486
+
487
+ if (status)
488
+ {
489
+ if (WIFEXITED(*status))
490
+ *status = WEXITSTATUS(*status);
491
+ else return -1;
492
+ }
493
+
494
+ return 0;
495
+ #endif
496
+ }
497
+
498
+ int uWaitForProcess(UPID pid, UPHANDLE h, sys_call_error_fun fun)
499
+ {
500
+ #ifdef _WIN32
501
+ DWORD res;
502
+ res = WaitForSingleObject(h, INFINITE);
503
+
504
+ if (res == WAIT_FAILED)
505
+ {
506
+ sys_call_error("WaitForSingleObject");
507
+ return -1;
508
+ }
509
+ else
510
+ return 0;
511
+ #else
512
+ int status = 0;
513
+
514
+ for (;;)
515
+ {
516
+ status = uIsProcessExist(pid, h, __sys_call_error);
517
+ /* Error happened in uIsProcessExist */
518
+ if (-2 == status) return -1;
519
+ /* Process still alive */
520
+ if ( 0 == status) uSleep(1, __sys_call_error);
521
+ /* status == -1, there is no such process */
522
+ else break;
523
+ }
524
+
525
+ return 0;
526
+ #endif
527
+ }
528
+
529
+ int uNonBlockingWaitForChildProcess(UPID pid)
530
+ {
531
+ #ifdef _WIN32
532
+ return 0;
533
+ /// Nothing doing here
534
+ #else
535
+ int status = 0;
536
+
537
+ int res = waitpid(pid, &status, WNOHANG);
538
+
539
+ return res;
540
+ #endif
541
+ }
542
+
543
+ #if (!defined(_WIN32) && !(defined(HAVE_PROC_EXE)))
544
+
545
+ #include <pwd.h>
546
+
547
+
548
+ /* ABSOLUTE_FILENAME_P (fname): True if fname is an absolute filename */
549
+ #ifdef atarist
550
+ #define ABSOLUTE_FILENAME_P(fname) ((fname[0] == '/') || \
551
+ (fname[0] && (fname[1] == ':')))
552
+ #else
553
+ #define ABSOLUTE_FILENAME_P(fname) (fname[0] == '/')
554
+ #endif /* atarist */
555
+
556
+ /* Return the absolute name of the program named NAME. This function
557
+ searches the directories in the PATH environment variable if PROG
558
+ has no directory components. */
559
+ int find_executable(const char *name, char *buf, int size)
560
+ {
561
+ char *search;
562
+ char *p;
563
+ char tbuf[MAXPATHLEN];
564
+
565
+ if (ABSOLUTE_FILENAME_P(name))
566
+ {
567
+ /* If we can execute the named file, and it is normal, then return it. */
568
+ if (!access (name, X_OK))
569
+ {
570
+ struct stat stat_temp;
571
+
572
+ if (stat (name, &stat_temp))
573
+ return -1;
574
+
575
+ #ifndef STAT_MACROS_BROKEN
576
+ if (!S_ISREG(stat_temp.st_mode))
577
+ return -1;
578
+ #endif
579
+ strncpy(buf, name, size);
580
+ return 0;
581
+ }
582
+ }
583
+ else
584
+ {
585
+ if ((name[0] == '.') && (name[1] == '/'))
586
+ {
587
+ strcpy(tbuf, ".");
588
+
589
+ #ifdef HAVE_GETCWD
590
+ getcwd(tbuf, MAXPATHLEN);
591
+ #else
592
+ # ifdef HAVE_GETWD
593
+ getwd(tbuf);
594
+ # endif
595
+ #endif
596
+ strcat(tbuf, name + 1);
597
+ strncpy(buf, tbuf, size);
598
+ return 0;
599
+ }
600
+
601
+ if ((name[0] == '.') && (name[1] == '.') && (name[2] == '/'))
602
+ {
603
+
604
+ #ifdef HAVE_GETCWD
605
+ getcwd(tbuf, MAXPATHLEN);
606
+ strcat(tbuf, "/");
607
+ #else
608
+ # ifdef HAVE_GETWD
609
+ getwd(tbuf);
610
+ strcat(tbuf, "/");
611
+ # endif
612
+ #endif
613
+ strcat(tbuf, name);
614
+ strncpy(buf, tbuf, size);
615
+ return 0;
616
+ }
617
+
618
+ search = getenv("PATH");
619
+ p = search;
620
+
621
+ while (*p)
622
+ {
623
+ char *next;
624
+ next = tbuf;
625
+
626
+ /* Perform tilde-expansion. Stolen from GNU readline/tilde.c. */
627
+ if (p[0] == '~')
628
+ {
629
+ if (!p[1] || p[1] == '/')
630
+ {
631
+ /* Prepend $HOME to the rest of the string. */
632
+ char *temp_home = (char*)getenv("HOME");
633
+
634
+ /* If there is no HOME variable, look up the directory in
635
+ the password database. */
636
+ if (!temp_home)
637
+ {
638
+ struct passwd *entry;
639
+
640
+ entry = getpwuid(getuid());
641
+ if (entry)
642
+ temp_home = entry->pw_dir;
643
+ }
644
+
645
+ strcpy(tbuf, temp_home);
646
+ next = tbuf + strlen(tbuf);
647
+ p++;
648
+ }
649
+ else
650
+ {
651
+ char username[MAXPATHLEN];
652
+ struct passwd *user_entry;
653
+ int i;
654
+
655
+ p++; /* Skip the tilde. */
656
+ for (i = 0; *p && *p != '/' && *p != ':'; i++)
657
+ username[i] = *p ++;
658
+ username[i] = '\0';
659
+
660
+ user_entry = getpwnam(username);
661
+ if (user_entry)
662
+ {
663
+ strcpy(tbuf, user_entry->pw_dir);
664
+ next = tbuf + strlen(tbuf);
665
+ }
666
+ }
667
+
668
+ endpwent();
669
+ }
670
+
671
+ /* Copy directory name into [tbuf]. */
672
+ while (*p && *p != ':')
673
+ *next ++ = *p ++;
674
+ *next = '\0';
675
+ if (*p != '\0')
676
+ p++;
677
+
678
+ if (tbuf[0] == '.' && tbuf[1] == '\0')
679
+ {
680
+ #ifdef HAVE_GETCWD
681
+ getcwd (tbuf, MAXPATHLEN);
682
+ #else
683
+ # ifdef HAVE_GETWD
684
+ getwd (tbuf);
685
+ # endif
686
+ #endif
687
+ }
688
+
689
+ strcat(tbuf, "/");
690
+ strcat(tbuf, name);
691
+
692
+ /* If we can execute the named file, and it is normal, then return it. */
693
+ if (!access(tbuf, X_OK))
694
+ {
695
+ struct stat stat_temp;
696
+
697
+ if (stat(tbuf, &stat_temp))
698
+ continue;
699
+
700
+ #ifndef STAT_MACROS_BROKEN
701
+ if (!S_ISREG(stat_temp.st_mode))
702
+ continue;
703
+ #endif
704
+ strncpy(buf, tbuf, size);
705
+ return 0;
706
+ }
707
+ }
708
+ }
709
+
710
+ return -1;
711
+ }
712
+
713
+ #endif /* (!defined(_WIN32) && !(defined(HAVE_PROC_EXE))) */
714
+
715
+
716
+ char *program_name_argv_0 = NULL;
717
+
718
+
719
+ char* uGetImageProcPath(char *buf, sys_call_error_fun fun)
720
+ {
721
+ #ifdef _WIN32
722
+ char *p = buf;
723
+ if (GetModuleFileName(0, buf, U_MAX_PATH + 1) != 0)
724
+ {
725
+ p = strrchr(buf, '\\');
726
+ if (!p) p = buf;
727
+ }
728
+ else
729
+ sys_call_error("GetModuleFileName");
730
+
731
+ *p = '\0';
732
+ return buf;
733
+ #else
734
+ #ifdef HAVE_PROC_EXE
735
+ char *p = buf;
736
+ int len = 0;
737
+ char tmp[U_MAX_PATH + 1];
738
+
739
+ strcpy(tmp, "/proc/");
740
+ int2c_str(getpid(), tmp + strlen("/proc/"));
741
+ strcat(tmp, PROC_EXE_SUFFIX);
742
+
743
+ len = readlink(tmp, buf, U_MAX_PATH);
744
+ if (len != -1)
745
+ {
746
+ buf[len] = '\0';
747
+ p = strrchr(buf, '/');
748
+ if (!p) p = buf;
749
+ }
750
+ else sys_call_error("uGetImageProcPath");
751
+
752
+ *p = '\0';
753
+ return buf;
754
+ #else
755
+ char *p = buf;
756
+ if (find_executable(program_name_argv_0, buf, U_MAX_PATH + 1) == 0)
757
+ {
758
+ p = strrchr(buf, '/');
759
+ if (!p) p = buf;
760
+ }
761
+
762
+ *p = '\0';
763
+ return buf;
764
+ #endif
765
+ #endif
766
+ }
767
+