ruby-magic 0.0.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,274 +1,352 @@
1
- /* :enddoc: */
2
-
3
- /*
4
- * functions.c
5
- *
6
- * Copyright 2013-2014 Krzysztof Wilczynski
7
- *
8
- * Licensed under the Apache License, Version 2.0 (the "License");
9
- * you may not use this file except in compliance with the License.
10
- * You may obtain a copy of the License at
11
- *
12
- * http://www.apache.org/licenses/LICENSE-2.0
13
- *
14
- * Unless required by applicable law or agreed to in writing, software
15
- * distributed under the License is distributed on an "AS IS" BASIS,
16
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- * See the License for the specific language governing permissions and
18
- * limitations under the License.
19
- */
1
+ #if defined(__cplusplus)
2
+ extern "C" {
3
+ #endif
20
4
 
21
5
  #include "functions.h"
22
6
 
23
- int suppress_error_output(void *data);
7
+ int check_fd(int fd);
8
+ static int safe_dup(int fd);
9
+ static int safe_close(int fd);
10
+ static int safe_cloexec(int fd);
11
+ int override_error_output(void *data);
24
12
  int restore_error_output(void *data);
25
13
 
26
- int override_current_locale(void *data);
27
- int restore_current_locale(void *data);
28
-
29
- int
30
- suppress_error_output(void *data)
14
+ inline int
15
+ check_fd(int fd)
31
16
  {
32
- int local_errno;
33
- mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
34
-
35
- save_t *s = data;
36
- assert(s != NULL && "Must be a valid pointer to `save_t' type");
17
+ errno = 0;
18
+ if (fd < 0 || (fcntl(fd, F_GETFD) < 0 && errno == EBADF)) {
19
+ errno = EBADF;
20
+ return -EBADF;
21
+ }
37
22
 
38
- s->data.file.old_fd = -1;
39
- s->data.file.new_fd = -1;
40
- s->status = -1;
23
+ return 0;
24
+ }
41
25
 
42
- fflush(stderr);
43
- fgetpos(stderr, &s->data.file.position);
26
+ static int
27
+ safe_dup(int fd)
28
+ {
29
+ int new_fd;
30
+ int local_errno;
31
+ int flags = F_DUPFD;
44
32
 
45
- s->data.file.old_fd = dup(fileno(stderr));
46
- if (s->data.file.old_fd < 0) {
47
- local_errno = errno;
48
- goto out;
49
- }
33
+ #if defined(HAVE_F_DUPFD_CLOEXEC)
34
+ flags = F_DUPFD_CLOEXEC;
35
+ #endif
50
36
 
51
- s->data.file.new_fd = open("/dev/null", O_WRONLY | O_APPEND, mode);
52
- if (s->data.file.new_fd < 0) {
53
- local_errno = errno;
37
+ new_fd = fcntl(fd, flags, fileno(stderr) + 1);
38
+ if (new_fd < 0 && errno == EINVAL) {
39
+ new_fd = dup(fd);
40
+ if (new_fd < 0) {
41
+ local_errno = errno;
42
+ goto error;
43
+ }
44
+ }
45
+ if (safe_cloexec(new_fd) < 0) {
46
+ local_errno = errno;
47
+ goto error;
48
+ }
49
+
50
+ return new_fd;
51
+ error:
52
+ errno = local_errno;
53
+ return -1;
54
+ }
54
55
 
55
- if (dup2(s->data.file.old_fd, fileno(stderr)) < 0) {
56
- local_errno = errno;
57
- goto out;
58
- }
56
+ static int
57
+ safe_close(int fd)
58
+ {
59
+ int rv;
60
+ #if defined(HAVE_POSIX_CLOSE_RESTART)
61
+ rv = posix_close(fd, 0);
62
+ #else
63
+ rv = close(fd);
64
+ if (rv < 0 && errno == EINTR)
65
+ errno = EINPROGRESS;
66
+ #endif
59
67
 
60
- close(s->data.file.old_fd);
61
- goto out;
62
- }
68
+ return rv;
69
+ }
63
70
 
64
- if (dup2(s->data.file.new_fd, fileno(stderr)) < 0) {
65
- local_errno = errno;
66
- goto out;
67
- }
71
+ static inline int
72
+ safe_cloexec(int fd)
73
+ {
74
+ int local_errno;
75
+ int flags = fcntl(fd, F_GETFD);
76
+
77
+ if (flags < 0) {
78
+ local_errno = errno;
79
+ goto error;
80
+ }
81
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
82
+ local_errno = errno;
83
+ goto error;
84
+ }
85
+
86
+ return 0;
87
+ error:
88
+ errno = local_errno;
89
+ return -1;
90
+ }
68
91
 
69
- close(s->data.file.new_fd);
70
- return 0;
92
+ int
93
+ override_error_output(void *data)
94
+ {
95
+ int local_errno;
96
+ mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
97
+ save_t *s = data;
71
98
 
72
- out:
73
- s->status = local_errno;
74
- errno = s->status;
99
+ #if defined(HAVE_O_CLOEXEC)
100
+ mode |= O_CLOEXEC;
101
+ #endif
75
102
 
76
- return -1;
103
+ assert(s != NULL && \
104
+ "Must be a valid pointer to `save_t' type");
105
+
106
+ s->file.old_fd = -1;
107
+ s->file.new_fd = -1;
108
+ s->status = -1;
109
+
110
+ fflush(stderr);
111
+ fgetpos(stderr, &s->file.position);
112
+
113
+ s->file.old_fd = safe_dup(fileno(stderr));
114
+ if (s->file.old_fd < 0) {
115
+ local_errno = errno;
116
+ goto error;
117
+ }
118
+
119
+ s->file.new_fd = open("/dev/null", O_WRONLY | O_APPEND, mode);
120
+ if (s->file.new_fd < 0) {
121
+ local_errno = errno;
122
+
123
+ if (dup2(s->file.old_fd, fileno(stderr)) < 0) {
124
+ local_errno = errno;
125
+ goto error;
126
+ }
127
+
128
+ safe_close(s->file.old_fd);
129
+ goto error;
130
+ }
131
+ if (safe_cloexec(s->file.new_fd) < 0) {
132
+ local_errno = errno;
133
+ goto error;
134
+ }
135
+ if (dup2(s->file.new_fd, fileno(stderr)) < 0) {
136
+ local_errno = errno;
137
+ goto error;
138
+ }
139
+
140
+ safe_close(s->file.new_fd);
141
+
142
+ return 0;
143
+ error:
144
+ s->status = local_errno;
145
+ errno = s->status;
146
+ return -1;
77
147
  }
78
148
 
79
149
  int
80
150
  restore_error_output(void *data)
81
151
  {
82
- int local_errno;
83
-
84
- save_t *s = data;
85
- assert(s != NULL && "Must be a valid pointer to `save_t' type");
152
+ int local_errno;
153
+ save_t *s = data;
86
154
 
87
- if (s->data.file.old_fd < 0 && s->status != 0) {
88
- return -1;
89
- }
155
+ assert(s != NULL && \
156
+ "Must be a valid pointer to `save_t' type");
90
157
 
91
- fflush(stderr);
158
+ if (s->file.old_fd < 0 && s->status != 0)
159
+ return -1;
92
160
 
93
- if (dup2(s->data.file.old_fd, fileno(stderr)) < 0) {
94
- local_errno = errno;
95
- goto out;
96
- }
161
+ fflush(stderr);
97
162
 
98
- close(s->data.file.old_fd);
99
- clearerr(stderr);
100
- fsetpos(stderr, &s->data.file.position);
163
+ if (dup2(s->file.old_fd, fileno(stderr)) < 0) {
164
+ local_errno = errno;
165
+ goto error;
166
+ }
101
167
 
102
- if (setvbuf(stderr, NULL, _IONBF, 0) != 0) {
103
- local_errno = errno;
104
- goto out;
105
- }
168
+ safe_close(s->file.old_fd);
169
+ clearerr(stderr);
170
+ fsetpos(stderr, &s->file.position);
106
171
 
107
- return 0;
172
+ if (setvbuf(stderr, NULL, _IONBF, 0) != 0) {
173
+ local_errno = errno;
174
+ goto error;
175
+ }
108
176
 
109
- out:
110
- s->status = local_errno;
111
- errno = s->status;
112
-
113
- return -1;
177
+ return 0;
178
+ error:
179
+ s->status = local_errno;
180
+ errno = s->status;
181
+ return -1;
114
182
  }
115
183
 
116
- int
117
- override_current_locale(void *data)
184
+ inline magic_t
185
+ magic_open_wrapper(int flags)
118
186
  {
119
- char *current_locale = NULL;
120
-
121
- save_t *s = data;
122
- assert(s != NULL && "Must be a valid pointer to `save_t' type");
123
-
124
- s->status = -1;
125
- s->data.locale = NULL;
126
-
127
- current_locale = setlocale(LC_ALL, NULL);
128
- if (!current_locale) {
129
- goto out;
130
- }
131
-
132
- s->data.locale = strndup(current_locale, strlen(current_locale));
133
- if (!s->data.locale) {
134
- goto out;
135
- }
136
-
137
- if (!setlocale(LC_ALL, "C")) {
138
- goto out;
139
- }
187
+ return magic_open(flags);
188
+ }
140
189
 
141
- assert(s->data.locale != NULL && "Must be a valid pointer to `char' type");
142
- s->status = 0;
190
+ inline void
191
+ magic_close_wrapper(magic_t magic)
192
+ {
193
+ magic_close(magic);
194
+ }
143
195
 
144
- out:
145
- return s->status;
196
+ inline const char*
197
+ magic_error_wrapper(magic_t magic)
198
+ {
199
+ return magic_error(magic);
146
200
  }
147
201
 
148
- int
149
- restore_current_locale(void *data)
202
+ inline int
203
+ magic_errno_wrapper(magic_t magic)
150
204
  {
151
- save_t *s = data;
152
- assert(s != NULL && "Must be a valid pointer to `save_t' type");
205
+ return magic_errno(magic);
206
+ }
153
207
 
154
- if (!s->data.locale && s->status != 0) {
155
- return -1;
156
- }
208
+ inline const char*
209
+ magic_getpath_wrapper(void)
210
+ {
211
+ /*
212
+ * The second argument translates to same value as the
213
+ * FILE_LOAD constant, which when used results in this
214
+ * function calling the get_default_magic() internally.
215
+ *
216
+ * N.B. magic_getpath() also honors the "MAGIC"
217
+ * environment variable."
218
+ */
219
+ return magic_getpath(NULL, 0);
220
+ }
157
221
 
158
- if (!setlocale(LC_ALL, s->data.locale)) {
159
- goto out;
160
- }
222
+ inline int
223
+ magic_getparam_wrapper(magic_t magic, int parameter, void *value)
224
+ {
225
+ return magic_getparam(magic, parameter, value);
226
+ }
161
227
 
162
- assert(s->data.locale != NULL && "Must be a valid pointer to `char' type");
163
- free(s->data.locale);
228
+ inline int
229
+ magic_setparam_wrapper(magic_t magic, int parameter, const void *value)
230
+ {
231
+ if (*(const int *)value < 0 || *(const size_t *)value > UINT_MAX) {
232
+ errno = EOVERFLOW;
233
+ return -EOVERFLOW;
234
+ }
164
235
 
165
- return 0;
236
+ if (parameter == MAGIC_PARAM_BYTES_MAX)
237
+ return magic_setparam(magic, parameter, value);
166
238
 
167
- out:
168
- s->data.locale = NULL;
169
- s->status = -1;
239
+ if (*(const size_t *)value > USHRT_MAX) {
240
+ errno = EOVERFLOW;
241
+ return -EOVERFLOW;
242
+ }
170
243
 
171
- return -1;
244
+ return magic_setparam(magic, parameter, value);
172
245
  }
173
246
 
174
- inline const char*
175
- magic_getpath_wrapper(void)
247
+ inline int
248
+ magic_getflags_wrapper(magic_t magic)
176
249
  {
177
- return magic_getpath(NULL, 0);
250
+ #if defined(HAVE_MAGIC_GETFLAGS)
251
+ return magic_getflags(magic);
252
+ #else
253
+ UNUSED(magic);
254
+ errno = ENOSYS;
255
+ return -ENOSYS;
256
+ #endif
178
257
  }
179
258
 
180
259
  inline int
181
- magic_setflags_wrapper(struct magic_set *ms, int flags)
260
+ magic_setflags_wrapper(magic_t magic, int flags)
182
261
  {
183
- if (flags < MAGIC_NONE || flags > MAGIC_NO_CHECK_BUILTIN) {
184
- errno = EINVAL;
185
- return -EINVAL;
186
- }
262
+ if (flags < 0 || flags > 0xfffffff) {
263
+ errno = EINVAL;
264
+ return -EINVAL;
265
+ }
187
266
 
188
267
  #if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
189
- if (flags & MAGIC_PRESERVE_ATIME) {
190
- errno = ENOSYS;
191
- return -ENOSYS;
192
- }
268
+ if (flags & MAGIC_PRESERVE_ATIME) {
269
+ errno = ENOSYS;
270
+ return -ENOSYS;
271
+ }
193
272
  #endif
194
273
 
195
- return magic_setflags(ms, flags);
274
+ return magic_setflags(magic, flags);
196
275
  }
197
276
 
198
277
  inline int
199
- magic_load_wrapper(struct magic_set *ms, const char *magicfile, int flags)
278
+ magic_load_wrapper(magic_t magic, const char *magic_file, int flags)
200
279
  {
201
- int rv;
202
-
203
- MAGIC_FUNCTION(magic_load, rv, flags, ms, magicfile);
204
-
205
- return rv;
280
+ int rv;
281
+ MAGIC_FUNCTION(magic_load, rv, flags, magic, magic_file);
282
+ return rv;
206
283
  }
207
284
 
208
285
  inline int
209
- magic_compile_wrapper(struct magic_set *ms, const char *magicfile, int flags)
286
+ magic_load_buffers_wrapper(magic_t magic, void **buffers, size_t *sizes, size_t count, int flags)
210
287
  {
211
- int rv;
212
-
213
- MAGIC_FUNCTION(magic_compile, rv, flags, ms, magicfile);
214
-
215
- return rv;
288
+ int rv;
289
+ MAGIC_FUNCTION(magic_load_buffers, rv, flags, magic, buffers, sizes, count);
290
+ return rv;
216
291
  }
217
292
 
218
293
  inline int
219
- magic_check_wrapper(struct magic_set *ms, const char *magicfile, int flags)
294
+ magic_compile_wrapper(magic_t magic, const char *magic_file, int flags)
220
295
  {
221
- int rv;
222
-
223
- MAGIC_FUNCTION(magic_check, rv, flags, ms, magicfile);
296
+ int rv;
297
+ MAGIC_FUNCTION(magic_compile, rv, flags, magic, magic_file);
298
+ return rv;
299
+ }
224
300
 
225
- return rv;
301
+ inline int
302
+ magic_check_wrapper(magic_t magic, const char *magic_file, int flags)
303
+ {
304
+ int rv;
305
+ MAGIC_FUNCTION(magic_check, rv, flags, magic, magic_file);
306
+ return rv;
226
307
  }
227
308
 
228
309
  inline const char*
229
- magic_file_wrapper(struct magic_set *ms, const char* filename, int flags)
310
+ magic_file_wrapper(magic_t magic, const char* filename, int flags)
230
311
  {
231
- const char *cstring;
232
-
233
- MAGIC_FUNCTION(magic_file, cstring, flags, ms, filename);
234
-
235
- return cstring;
312
+ const char *cstring;
313
+ MAGIC_FUNCTION(magic_file, cstring, flags, magic, filename);
314
+ return cstring;
236
315
  }
237
316
 
238
317
  inline const char*
239
- magic_buffer_wrapper(struct magic_set *ms, const void *buffer, size_t size, int flags)
318
+ magic_buffer_wrapper(magic_t magic, const void *buffer, size_t size, int flags)
240
319
  {
241
- const char *cstring;
242
-
243
- MAGIC_FUNCTION(magic_buffer, cstring, flags, ms, buffer, size);
244
-
245
- return cstring;
320
+ const char *cstring;
321
+ MAGIC_FUNCTION(magic_buffer, cstring, flags, magic, buffer, size);
322
+ return cstring;
246
323
  }
247
324
 
248
325
  inline const char*
249
- magic_descriptor_wrapper(struct magic_set *ms, int fd, int flags)
326
+ magic_descriptor_wrapper(magic_t magic, int fd, int flags)
250
327
  {
251
- const char *cstring;
328
+ int local_errno;
329
+ const char *cstring;
330
+
331
+ if (check_fd(fd) < 0) {
332
+ local_errno = errno;
333
+ goto error;
334
+ }
252
335
 
253
- MAGIC_FUNCTION(magic_descriptor, cstring, flags, ms, fd);
336
+ MAGIC_FUNCTION(magic_descriptor, cstring, flags, magic, fd);
337
+ return cstring;
254
338
 
255
- return cstring;
339
+ error:
340
+ errno = local_errno;
341
+ return NULL;
256
342
  }
257
343
 
258
344
  inline int
259
345
  magic_version_wrapper(void)
260
346
  {
261
- #if defined(HAVE_MAGIC_VERSION)
262
- return magic_version();
263
- #else
264
- # if defined(HAVE_WARNING)
265
- # warning "function `int magic_version(void)' not implemented"
266
- # else
267
- # pragma message("function `int magic_version(void)' not implemented")
268
- # endif
269
- errno = ENOSYS;
270
- return -ENOSYS;
271
- #endif
347
+ return magic_version();
272
348
  }
273
349
 
274
- /* vim: set ts=8 sw=4 sts=2 et : */
350
+ #if defined(__cplusplus)
351
+ }
352
+ #endif