ruby-magic 0.0.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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