diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-07-24 15:30:16 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-07-24 15:30:16 +0000 |
commit | e7292e8db0955dc14a3b3e67ae709a186ea68136 (patch) | |
tree | 9ef38a6adb4cb9ce01a78427d7fe6a93a28e0e39 | |
parent | 929bfb08deeab0db8345f144d03e388891695995 (diff) | |
download | libextractor-e7292e8db0955dc14a3b3e67ae709a186ea68136.tar.gz libextractor-e7292e8db0955dc14a3b3e67ae709a186ea68136.zip |
-hxing
-rw-r--r-- | src/include/extractor.h | 8 | ||||
-rw-r--r-- | src/main/extractor_plugin_main.c | 414 |
2 files changed, 215 insertions, 207 deletions
diff --git a/src/include/extractor.h b/src/include/extractor.h index e862813..a227ea5 100644 --- a/src/include/extractor.h +++ b/src/include/extractor.h | |||
@@ -418,12 +418,12 @@ struct EXTRACTOR_ExtractContext | |||
418 | * @param cls the 'cls' member of this struct | 418 | * @param cls the 'cls' member of this struct |
419 | * @param pos position to seek (see 'man lseek') | 419 | * @param pos position to seek (see 'man lseek') |
420 | * @param whence how to see (absolute to start, relative, absolute to end) | 420 | * @param whence how to see (absolute to start, relative, absolute to end) |
421 | * @return new absolute position, UINT64_MAX on error (i.e. desired position | 421 | * @return new absolute position, -1 on error (i.e. desired position |
422 | * does not exist) | 422 | * does not exist) |
423 | */ | 423 | */ |
424 | uint64_t (*seek) (void *cls, | 424 | int64_t (*seek) (void *cls, |
425 | int64_t pos, | 425 | int64_t pos, |
426 | int whence); | 426 | int whence); |
427 | 427 | ||
428 | 428 | ||
429 | /** | 429 | /** |
diff --git a/src/main/extractor_plugin_main.c b/src/main/extractor_plugin_main.c index 9cf7624..0f5b79f 100644 --- a/src/main/extractor_plugin_main.c +++ b/src/main/extractor_plugin_main.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "plibc.h" | 27 | #include "plibc.h" |
28 | #include "extractor.h" | 28 | #include "extractor.h" |
29 | #include "extractor_datasource.h" | 29 | #include "extractor_datasource.h" |
30 | #include "extractor_plugins.h" | ||
30 | #include "extractor_ipc.h" | 31 | #include "extractor_ipc.h" |
31 | #include "extractor_plugin_main.h" | 32 | #include "extractor_plugin_main.h" |
32 | #include <dirent.h> | 33 | #include <dirent.h> |
@@ -36,26 +37,62 @@ | |||
36 | #include <signal.h> | 37 | #include <signal.h> |
37 | 38 | ||
38 | 39 | ||
39 | |||
40 | /** | 40 | /** |
41 | * Opens a file (for later mmapping). | 41 | * Closure we use for processing requests inside the helper process. |
42 | * This is POSIX variant of the plugin_open_* function. | 42 | */ |
43 | * Closes a file is already opened, closes it before opening a new one. | 43 | struct ProcessingContext |
44 | * Destroy shared memory area. | ||
45 | * | ||
46 | * @param plugin plugin context | ||
47 | * @param shm_name name of the file to open. | ||
48 | * @return file id (-1 on error). That is, the result of open() syscall. | ||
49 | */ | ||
50 | static int | ||
51 | plugin_open_file (struct EXTRACTOR_PluginList *plugin, | ||
52 | const char *shm_name) | ||
53 | { | 44 | { |
54 | if (plugin->shm_id != -1) | 45 | /** |
55 | close (plugin->shm_id); | 46 | * Our plugin handle. |
56 | plugin->shm_id = open (shm_name, O_RDONLY, 0); | 47 | */ |
57 | return plugin->shm_id; | 48 | struct EXTRACTOR_PluginList *plugin; |
58 | } | 49 | |
50 | /** | ||
51 | * Shared memory area. | ||
52 | */ | ||
53 | void *shm; | ||
54 | |||
55 | /** | ||
56 | * Overall size of the file. | ||
57 | */ | ||
58 | uint64_t file_size; | ||
59 | |||
60 | /** | ||
61 | * Current read offset when reading from the SHM. | ||
62 | */ | ||
63 | uint64_t read_position; | ||
64 | |||
65 | /** | ||
66 | * Current offset of the SHM in the file. | ||
67 | */ | ||
68 | uint64_t shm_off; | ||
69 | |||
70 | /** | ||
71 | * Handle to the shared memory. | ||
72 | */ | ||
73 | int shm_id; | ||
74 | |||
75 | /** | ||
76 | * Size of the shared memory map. | ||
77 | */ | ||
78 | uint32_t shm_map_size; | ||
79 | |||
80 | /** | ||
81 | * Number of bytes ready in SHM. | ||
82 | */ | ||
83 | uint32_t shm_ready_bytes; | ||
84 | |||
85 | /** | ||
86 | * Input stream. | ||
87 | */ | ||
88 | int in; | ||
89 | |||
90 | /** | ||
91 | * Output stream. | ||
92 | */ | ||
93 | int out; | ||
94 | }; | ||
95 | |||
59 | 96 | ||
60 | 97 | ||
61 | /** | 98 | /** |
@@ -69,8 +106,12 @@ plugin_open_file (struct EXTRACTOR_PluginList *plugin, | |||
69 | * @return new absolute position, -1 on error | 106 | * @return new absolute position, -1 on error |
70 | */ | 107 | */ |
71 | static int64_t | 108 | static int64_t |
72 | pl_seek (struct EXTRACTOR_PluginList *plugin, int64_t pos, int whence) | 109 | plugin_env_seek (void *cls, |
110 | int64_t pos, | ||
111 | int whence) | ||
73 | { | 112 | { |
113 | struct ProcessingContext *pc = cls; | ||
114 | |||
74 | switch (whence) | 115 | switch (whence) |
75 | { | 116 | { |
76 | case SEEK_CUR: | 117 | case SEEK_CUR: |
@@ -123,13 +164,6 @@ pl_seek (struct EXTRACTOR_PluginList *plugin, int64_t pos, int whence) | |||
123 | } | 164 | } |
124 | 165 | ||
125 | 166 | ||
126 | static int64_t | ||
127 | pl_get_fsize (struct EXTRACTOR_PluginList *plugin) | ||
128 | { | ||
129 | return plugin->fsize; | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | 167 | /** |
134 | * Fills @data with a pointer to the data buffer. | 168 | * Fills @data with a pointer to the data buffer. |
135 | * Equivalent to read(), except you don't have to allocate and free | 169 | * Equivalent to read(), except you don't have to allocate and free |
@@ -141,9 +175,12 @@ pl_get_fsize (struct EXTRACTOR_PluginList *plugin) | |||
141 | * @param count number of bytes to read | 175 | * @param count number of bytes to read |
142 | * @return number of bytes (<= count) avalable in @data, -1 on error | 176 | * @return number of bytes (<= count) avalable in @data, -1 on error |
143 | */ | 177 | */ |
144 | static int64_t | 178 | static ssize_t |
145 | pl_read (struct EXTRACTOR_PluginList *plugin, unsigned char **data, size_t count) | 179 | plugin_env_read (void *cls, |
180 | unsigned char **data, size_t count) | ||
146 | { | 181 | { |
182 | struct ProcessingContext *pc = cls; | ||
183 | |||
147 | *data = NULL; | 184 | *data = NULL; |
148 | if (count > MAX_READ) | 185 | if (count > MAX_READ) |
149 | return -1; | 186 | return -1; |
@@ -166,41 +203,11 @@ pl_read (struct EXTRACTOR_PluginList *plugin, unsigned char **data, size_t count | |||
166 | } | 203 | } |
167 | 204 | ||
168 | 205 | ||
169 | /** | 206 | static uint64_t |
170 | * Initializes an extracting session for a plugin. | 207 | plugin_env_get_size (void *cls) |
171 | * opens the file/shm (only in OPMODE_FILE) | ||
172 | * sets shm_ptr to NULL (unmaps it, if it was mapped) | ||
173 | * sets position to 0 | ||
174 | * initializes file size to 'fsize' (may be -1) | ||
175 | * sets seek request to 0 | ||
176 | * | ||
177 | * @param plugin plugin context | ||
178 | * @param operation_mode the mode of operation (OPMODE_*) | ||
179 | * @param fsize size of the source file (may be -1) | ||
180 | * @param shm_name name of the shm or file to open | ||
181 | * @return 0 on success, non-0 on error. | ||
182 | */ | ||
183 | static int | ||
184 | init_state_method (struct EXTRACTOR_PluginList *plugin, | ||
185 | uint8_t operation_mode, | ||
186 | int64_t fsize, | ||
187 | const char *shm_name) | ||
188 | { | 208 | { |
189 | plugin->seek_request = 0; | 209 | struct ProcessingContext *pc = cls; |
190 | if (plugin->shm_ptr != NULL) | 210 | return pc->file_size; |
191 | munmap (plugin->shm_ptr, plugin->map_size); | ||
192 | plugin->shm_ptr = NULL; | ||
193 | if (operation_mode == OPMODE_FILE) | ||
194 | { | ||
195 | if (-1 == plugin_open_file (plugin, shm_name)) | ||
196 | return 1; | ||
197 | } | ||
198 | else if (-1 == plugin_open_shm (plugin, shm_name)) | ||
199 | return 1; | ||
200 | plugin->fsize = fsize; | ||
201 | plugin->shm_pos = 0; | ||
202 | plugin->fpos = 0; | ||
203 | return 0; | ||
204 | } | 211 | } |
205 | 212 | ||
206 | 213 | ||
@@ -208,7 +215,7 @@ init_state_method (struct EXTRACTOR_PluginList *plugin, | |||
208 | * Function called by a plugin in a child process. Transmits | 215 | * Function called by a plugin in a child process. Transmits |
209 | * the meta data back to the parent process. | 216 | * the meta data back to the parent process. |
210 | * | 217 | * |
211 | * @param cls closure, "int*" of the FD for transmission | 218 | * @param cls closure, "struct ProcessingContext" with the FD for transmission |
212 | * @param plugin_name name of the plugin that produced this value; | 219 | * @param plugin_name name of the plugin that produced this value; |
213 | * special values can be used (i.e. '<zlib>' for zlib being | 220 | * special values can be used (i.e. '<zlib>' for zlib being |
214 | * used in the main libextractor library and yielding | 221 | * used in the main libextractor library and yielding |
@@ -222,16 +229,17 @@ init_state_method (struct EXTRACTOR_PluginList *plugin, | |||
222 | * @return 0 to continue extracting, 1 to abort (transmission error) | 229 | * @return 0 to continue extracting, 1 to abort (transmission error) |
223 | */ | 230 | */ |
224 | static int | 231 | static int |
225 | transmit_reply (void *cls, | 232 | plugin_env_send_proc (void *cls, |
226 | const char *plugin_name, | 233 | const char *plugin_name, |
227 | enum EXTRACTOR_MetaType type, | 234 | enum EXTRACTOR_MetaType type, |
228 | enum EXTRACTOR_MetaFormat format, | 235 | enum EXTRACTOR_MetaFormat format, |
229 | const char *data_mime_type, | 236 | const char *data_mime_type, |
230 | const char *data, | 237 | const char *data, |
231 | size_t data_len) | 238 | size_t data_len) |
232 | { | 239 | { |
240 | struct ProcessingContext *pc = cls; | ||
233 | static const unsigned char meta_byte = MESSAGE_META; | 241 | static const unsigned char meta_byte = MESSAGE_META; |
234 | int *cpipe_out = cls; | 242 | int cpipe_out = pc->out; |
235 | struct IpcHeader hdr; | 243 | struct IpcHeader hdr; |
236 | size_t mime_len; | 244 | size_t mime_len; |
237 | 245 | ||
@@ -263,132 +271,126 @@ transmit_reply (void *cls, | |||
263 | 271 | ||
264 | 272 | ||
265 | /** | 273 | /** |
266 | * Main loop function for plugins. Reads a message from the plugin | 274 | * Handle an init message. The opcode itself has already been read. |
267 | * input pipe and acts on it. | ||
268 | * | 275 | * |
269 | * @param plugin plugin context | 276 | * @param pc processing context |
270 | * @param in input stream with incoming requests | 277 | * @return 0 on success, -1 on error |
271 | * @param out output stream for sending responses | 278 | */ |
272 | */ | 279 | static int |
273 | static void | 280 | handle_init_message (struct ProcessingContext *pc) |
274 | process_requests (struct EXTRACTOR_PluginList *plugin, | ||
275 | int in, | ||
276 | int out) | ||
277 | { | 281 | { |
278 | int read_result1; | 282 | struct InitMessage init; |
279 | int read_result2; | ||
280 | int read_result3; | ||
281 | int read_result4; | ||
282 | unsigned char code; | ||
283 | char *shm_name = NULL; | ||
284 | size_t shm_name_len; | ||
285 | int extract_reply; | ||
286 | struct IpcHeader hdr; | ||
287 | int do_break; | ||
288 | #ifdef WINDOWS | ||
289 | HANDLE map; | ||
290 | MEMORY_BASIC_INFORMATION mi; | ||
291 | #endif | ||
292 | 283 | ||
293 | /* The point of recursing into this function is to request | 284 | if (NULL != pc->shm) |
294 | * a seek from LE server and wait for a reply. This snipper | 285 | return -1; |
295 | * requests a seek. | 286 | if (sizeof (struct InitMessage) - 1 |
296 | */ | 287 | != read (pc->in, |
297 | if (plugin->waiting_for_update == 1) | 288 | &init.reserved, |
289 | sizeof (struct InitMessage) - 1)) | ||
290 | return -1; | ||
291 | if (init.shm_name_length > MAX_SHM_NAME) | ||
292 | return -1; | ||
298 | { | 293 | { |
299 | unsigned char seek_byte = MESSAGE_SEEK; | 294 | char shm_name[init.shm_name_length + 1]; |
300 | if (write (out, &seek_byte, 1) != 1) | 295 | |
296 | if (init.shm_name_length | ||
297 | != read (pc->in, | ||
298 | shm_name, | ||
299 | init.shm_name_length)) | ||
301 | return -1; | 300 | return -1; |
302 | if (write (out, &plugin->seek_request, sizeof (int64_t)) != sizeof (int64_t)) | 301 | shm_name[init.shm_name_length] = '\0'; |
302 | |||
303 | pc->shm_map_size = init.shm_map_size; | ||
304 | #if WINDOWS | ||
305 | pc->shm_ptr = MapViewOfFile (pc->shm_id, FILE_MAP_READ, 0, 0, 0); | ||
306 | if (NULL == pc->shm_ptr) | ||
307 | return -1; | ||
308 | #else | ||
309 | pc->shm_id = open (shm_name, O_RDONLY, 0); | ||
310 | if (-1 == pc->shm_id) | ||
303 | return -1; | 311 | return -1; |
312 | pc->shm = mmap (NULL, | ||
313 | pc->shm_map_size, | ||
314 | PROT_READ, | ||
315 | MAP_SHARED, | ||
316 | pc->shm_id, 0); | ||
317 | if ( ((void*) -1) == pc->shm) | ||
318 | return -1; | ||
319 | #endif | ||
304 | } | 320 | } |
321 | return 0; | ||
322 | } | ||
305 | 323 | ||
306 | memset (&hdr, 0, sizeof (hdr)); | 324 | |
307 | do_break = 0; | 325 | /** |
308 | while (!do_break) | 326 | * Handle a start message. The opcode itself has already been read. |
309 | { | 327 | * |
310 | read_result1 = read (in, &code, 1); | 328 | * @param pc processing context |
311 | if (read_result1 <= 0) | 329 | * @return 0 on success, -1 on error |
312 | break; | 330 | */ |
313 | switch (code) | 331 | static int |
332 | handle_start_message (struct ProcessingContext *pc) | ||
333 | { | ||
334 | struct StartMessage start; | ||
335 | struct EXTRACTOR_ExtractContext ec; | ||
336 | |||
337 | if (sizeof (struct StartMessage) - 1 | ||
338 | != read (pc->in, | ||
339 | &start.reserved, | ||
340 | sizeof (struct StartMessage) - 1)) | ||
341 | return -1; | ||
342 | pc->shm_ready_bytes = start.shm_ready_bytes; | ||
343 | pc->file_size = start.shm_file_size; | ||
344 | pc->read_position = 0; | ||
345 | pc->shm_off = 0; | ||
346 | ec.cls = pc; | ||
347 | ec.config = pc->plugin->plugin_options; | ||
348 | ec.read = &plugin_env_read; | ||
349 | ec.seek = &plugin_env_seek; | ||
350 | ec.get_size = &plugin_env_get_size; | ||
351 | ec.proc = &plugin_env_send_proc; | ||
352 | pc->plugin->extract_method (&ec); | ||
353 | } | ||
354 | |||
355 | |||
356 | /** | ||
357 | * Main loop function for plugins. Reads a message from the plugin | ||
358 | * input pipe and acts on it. | ||
359 | * | ||
360 | * @param pc processing context | ||
361 | */ | ||
362 | static void | ||
363 | process_requests (struct ProcessingContext *pc) | ||
364 | { | ||
365 | while (1) | ||
314 | { | 366 | { |
315 | case MESSAGE_INIT_STATE: | 367 | unsigned char code; |
316 | read_result2 = read (in, &plugin->operation_mode, sizeof (uint8_t)); | 368 | |
317 | read_result3 = read (in, &plugin->fsize, sizeof (int64_t)); | 369 | if (1 != read (pc->in, &code, 1)) |
318 | read_result4 = read (in, &shm_name_len, sizeof (size_t)); | 370 | break; |
319 | if ((read_result2 < sizeof (uint8_t)) || | 371 | switch (code) |
320 | (read_result3 < sizeof (int64_t)) || | 372 | { |
321 | (read_result4 < sizeof (size_t))) | 373 | case MESSAGE_INIT_STATE: |
322 | { | 374 | if (0 != handle_init_message (pc)) |
323 | do_break = 1; | 375 | return; |
324 | break; | 376 | break; |
325 | } | 377 | case MSG_EXTRACT_START: |
326 | if (plugin->operation_mode != OPMODE_MEMORY && | 378 | if (0 != handle_start_message (pc)) |
327 | plugin->operation_mode != OPMODE_DECOMPRESS && | 379 | return; |
328 | plugin->operation_mode != OPMODE_FILE) | 380 | case MSG_UPDATED_SHM: |
329 | { | 381 | /* not allowed here, we're not waiting for SHM to move! */ |
330 | do_break = 1; | 382 | return; |
331 | break; | 383 | case MSG_DISCARD_STATE: |
332 | } | 384 | /* odd, we're already in the start state... */ |
333 | if ((plugin->operation_mode == OPMODE_MEMORY || | 385 | continue; |
334 | plugin->operation_mode == OPMODE_DECOMPRESS) && | 386 | default: |
335 | shm_name_len > MAX_SHM_NAME) | 387 | /* error, unexpected message */ |
336 | { | 388 | return; |
337 | do_break = 1; | 389 | } |
338 | break; | 390 | } |
339 | } | 391 | } |
340 | /* Fsize may be -1 only in decompression mode */ | 392 | |
341 | if (plugin->operation_mode != OPMODE_DECOMPRESS && plugin->fsize <= 0) | 393 | #if 0 |
342 | { | ||
343 | do_break = 1; | ||
344 | break; | ||
345 | } | ||
346 | if (shm_name != NULL) | ||
347 | free (shm_name); | ||
348 | shm_name = malloc (shm_name_len); | ||
349 | if (shm_name == NULL) | ||
350 | { | ||
351 | do_break = 1; | ||
352 | break; | ||
353 | } | ||
354 | read_result2 = read (in, shm_name, shm_name_len); | ||
355 | if (read_result2 < shm_name_len) | ||
356 | { | ||
357 | do_break = 1; | ||
358 | break; | ||
359 | } | ||
360 | shm_name[shm_name_len - 1] = '\0'; | ||
361 | do_break = init_state_method (plugin, plugin->operation_mode, plugin->fsize, shm_name); | ||
362 | /* in OPMODE_MEMORY and OPMODE_FILE we can start extracting right away, | ||
363 | * there won't be UPDATED_SHM message, and we don't need it | ||
364 | */ | ||
365 | if (!do_break && (plugin->operation_mode == OPMODE_MEMORY || | ||
366 | plugin->operation_mode == OPMODE_FILE)) | ||
367 | { | ||
368 | extract_reply = plugin->extract_method (plugin, transmit_reply, &out); | ||
369 | unsigned char done_byte = MESSAGE_DONE; | ||
370 | if (write (out, &done_byte, 1) != 1) | ||
371 | { | ||
372 | do_break = 1; | ||
373 | break; | ||
374 | } | ||
375 | if ((plugin->specials != NULL) && | ||
376 | (NULL != strstr (plugin->specials, "force-kill"))) | ||
377 | { | ||
378 | /* we're required to die after each file since this | ||
379 | plugin only supports a single file at a time */ | ||
380 | #if !WINDOWS | ||
381 | fsync (out); | ||
382 | #else | ||
383 | _commit (out); | ||
384 | #endif | ||
385 | _exit (0); | ||
386 | } | ||
387 | } | ||
388 | break; | ||
389 | case MESSAGE_DISCARD_STATE: | ||
390 | discard_state_method (plugin); | ||
391 | break; | ||
392 | case MESSAGE_UPDATED_SHM: | 394 | case MESSAGE_UPDATED_SHM: |
393 | if (plugin->operation_mode == OPMODE_DECOMPRESS) | 395 | if (plugin->operation_mode == OPMODE_DECOMPRESS) |
394 | { | 396 | { |
@@ -413,7 +415,7 @@ process_requests (struct EXTRACTOR_PluginList *plugin, | |||
413 | } | 415 | } |
414 | #else | 416 | #else |
415 | if ((plugin->map_handle == 0) || | 417 | if ((plugin->map_handle == 0) || |
416 | (NULL == (plugin->shm_ptr = MapViewOfFile (plugin->map_handle, FILE_MAP_READ, 0, 0, 0)))) | 418 | (NULL == (plugin->shm_ptr = |
417 | { | 419 | { |
418 | do_break = 1; | 420 | do_break = 1; |
419 | break; | 421 | break; |
@@ -478,20 +480,8 @@ process_requests (struct EXTRACTOR_PluginList *plugin, | |||
478 | } | 480 | } |
479 | } | 481 | } |
480 | } | 482 | } |
481 | else | ||
482 | { | ||
483 | /* This is mostly to safely skip unrelated messages */ | ||
484 | int64_t t; | ||
485 | size_t t2; | ||
486 | read_result2 = read (in, &t, sizeof (int64_t)); | ||
487 | read_result3 = read (in, &t2, sizeof (size_t)); | ||
488 | read_result4 = read (in, &t, sizeof (int64_t)); | ||
489 | } | ||
490 | break; | ||
491 | } | ||
492 | } | ||
493 | return 0; | ||
494 | } | 483 | } |
484 | #endif | ||
495 | 485 | ||
496 | 486 | ||
497 | #ifndef WINDOWS | 487 | #ifndef WINDOWS |
@@ -536,6 +526,8 @@ void | |||
536 | EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, | 526 | EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, |
537 | int in, int out) | 527 | int in, int out) |
538 | { | 528 | { |
529 | struct ProcessingContext pc; | ||
530 | |||
539 | if (0 != EXTRACTOR_plugin_load_ (plugin)) | 531 | if (0 != EXTRACTOR_plugin_load_ (plugin)) |
540 | { | 532 | { |
541 | #if DEBUG | 533 | #if DEBUG |
@@ -560,7 +552,23 @@ EXTRACTOR_plugin_main_ (struct EXTRACTOR_PluginList *plugin, | |||
560 | open_dev_null (1, O_WRONLY); | 552 | open_dev_null (1, O_WRONLY); |
561 | #endif | 553 | #endif |
562 | } | 554 | } |
563 | process_requests (plugin, in, out); | 555 | pc.plugin = plugin; |
556 | pc.in = in; | ||
557 | pc.out = out; | ||
558 | pc.shm_id = -1; | ||
559 | pc.shm = NULL; | ||
560 | pc.shm_map_size = 0; | ||
561 | process_requests (&pc); | ||
562 | #if WINDOWS | ||
563 | if (NULL != pc.shm_ptr) | ||
564 | UnmapViewOfFile (pc.shm_ptr); | ||
565 | #else | ||
566 | if ( (NULL != pc.shm_ptr) && | ||
567 | (((void*) 1) != pc.shm_ptr) ) | ||
568 | munmap (pc.shm_ptr, pc.shm_map_size); | ||
569 | if (-1 != pc.shm_id) | ||
570 | (void) close (pc.shm_id); | ||
571 | #endif | ||
564 | } | 572 | } |
565 | 573 | ||
566 | 574 | ||