ruby-magic-static 0.3.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.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # File Magic in Ruby
2
+
3
+ This is a fork of https://github.com/kwilczynski/ruby-magic to compile a
4
+ vendored copy of libmagic.
5
+
6
+ [![Build Status](https://travis-ci.org/kwilczynski/ruby-magic.svg)](https://travis-ci.org/kwilczynski/ruby-magic)
7
+ [![Documentation Status](https://inch-ci.org/github/kwilczynski/ruby-magic.svg)](https://inch-ci.org/github/kwilczynski/ruby-magic)
8
+ [![Gem Version](https://badge.fury.io/rb/ruby-magic.svg)](http://badge.fury.io/rb/ruby-magic)
9
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
10
+
11
+ ## Introduction
12
+
13
+ Provides simple interface to [libmagic][1] for Ruby Programming Language.
14
+
15
+ ## Table of Contents
16
+
17
+ 1. [Contributing](#contributing)
18
+ 2. [Versioning](#versioning)
19
+ 3. [Author](#author)
20
+ 4. [Copyright](#copyright)
21
+ 5. [License](#license)
22
+
23
+ ## Contributing
24
+
25
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for best practices and instructions on
26
+ setting up your development environment.
27
+
28
+ ## Versioning
29
+
30
+ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
31
+ For the versions available, see the tags on this repository.
32
+
33
+ ## Author
34
+
35
+ Krzysztof Wilczyński (<kw@linux.com>)
36
+
37
+ ## Copyright
38
+
39
+ Copyright 2013-2021 Krzysztof Wilczyński
40
+
41
+ ## License
42
+
43
+ This project is licensed under the terms of the Apache License, Version 2.0 license.
44
+ To view the full license see the included [LICENSE](LICENSE) file.
45
+
46
+ [1]: https://en.wikipedia.org/wiki/File_(command)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,132 @@
1
+ #if !defined(_COMMON_H)
2
+ #define _COMMON_H 1
3
+
4
+ #if !defined(_GNU_SOURCE)
5
+ # define _GNU_SOURCE 1
6
+ #endif
7
+
8
+ #if !defined(_BSD_SOURCE)
9
+ # define _BSD_SOURCE 1
10
+ #endif
11
+
12
+ #if !defined(_DEFAULT_SOURCE)
13
+ # define _DEFAULT_SOURCE 1
14
+ #endif
15
+
16
+ #if defined(__cplusplus)
17
+ extern "C" {
18
+ #endif
19
+
20
+ #include <stdio.h>
21
+ #include <stdlib.h>
22
+ #include <limits.h>
23
+ #include <string.h>
24
+ #include <unistd.h>
25
+ #include <fcntl.h>
26
+ #include <errno.h>
27
+ #include <assert.h>
28
+ #include <sys/stat.h>
29
+ #include <magic.h>
30
+ #include <ruby.h>
31
+
32
+ #if defined(HAVE_RUBY_IO_H)
33
+ # include <ruby/io.h>
34
+ #else
35
+ # include <rubyio.h>
36
+ #endif
37
+
38
+ #if !defined(BIT)
39
+ # define BIT(n) (1 << (n))
40
+ #endif
41
+
42
+ #if !defined(UNUSED)
43
+ # define UNUSED(x) (void)(x)
44
+ #endif
45
+
46
+ #if defined(F_DUPFD_CLOEXEC)
47
+ # define HAVE_F_DUPFD_CLOEXEC 1
48
+ #endif
49
+
50
+ #if defined(O_CLOEXEC)
51
+ # define HAVE_O_CLOEXEC 1
52
+ #endif
53
+
54
+ #if defined(POSIX_CLOSE_RESTART)
55
+ # define HAVE_POSIX_CLOSE_RESTART 1
56
+ #endif
57
+
58
+ #define MAGIC_EXTENSION_SEPARATOR "/"
59
+ #define MAGIC_CONTINUE_SEPARATOR "\n- "
60
+
61
+ #if !defined(MAGIC_NO_CHECK_CSV)
62
+ # define MAGIC_NO_CHECK_CSV 0
63
+ #endif
64
+
65
+ #if !defined(MAGIC_NO_CHECK_JSON)
66
+ # define MAGIC_NO_CHECK_JSON 0
67
+ #endif
68
+
69
+ #define DATA_P(x) (RB_TYPE_P((x), T_DATA))
70
+ #define BOOLEAN_P(x) (RB_TYPE_P((x), T_TRUE) || RB_TYPE_P((x), T_FALSE))
71
+ #define STRING_P(x) (RB_TYPE_P((x), T_STRING))
72
+ #define ARRAY_P(x) (RB_TYPE_P((x), T_ARRAY))
73
+ #define FILE_P(x) (RB_TYPE_P((x), T_FILE))
74
+
75
+ #define RVAL2CBOOL(x) (RTEST(x))
76
+ #define CBOOL2RVAL(x) ((x) ? Qtrue : Qfalse)
77
+
78
+ #define RVAL2CSTR(x) (NIL_P(x) ? NULL : StringValueCStr(x))
79
+ #define CSTR2RVAL(x) ((x) == NULL ? Qnil : rb_str_new2(x))
80
+
81
+ #define RARRAY_EMPTY rb_ary_new()
82
+ #define RARRAY_EMPTY_P(a) (RARRAY_LEN(a) == 0)
83
+ #define RARRAY_FIRST(a) (RARRAY_EMPTY_P(a) ? Qnil : rb_ary_entry((a), 0))
84
+
85
+ #define CLASS_NAME(o) (NIL_P((o)) ? "nil" : rb_obj_classname((o)))
86
+
87
+ #if !defined(T_INTEGER)
88
+ # define T_INTEGER rb_cInteger
89
+ #endif
90
+
91
+ #if !defined(HAVE_RB_IO_T)
92
+ # define rb_io_t OpenFile
93
+ #endif
94
+
95
+ #if !defined(GetReadFile)
96
+ # define FPTR_TO_FD(p) ((p)->fd)
97
+ #else
98
+ # define FPTR_TO_FD(p) (fileno(GetReadFile(p)))
99
+ #endif
100
+
101
+ #define NOGVL_FUNCTION (VALUE (*)(void *))
102
+
103
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && \
104
+ defined(HAVE_RUBY_THREAD_H) && HAVE_RUBY_THREAD_H
105
+ # include <ruby/thread.h>
106
+ # define NOGVL(f, d) \
107
+ rb_thread_call_without_gvl((f), (d), RUBY_UBF_IO, NULL)
108
+ #elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
109
+ # define NOGVL(f, d) \
110
+ rb_thread_blocking_region(NOGVL_FUNCTION(f), (d), RUBY_UBF_IO, NULL)
111
+ #else
112
+ # include <rubysig.h>
113
+ static inline VALUE
114
+ fake_blocking_region(VALUE (*f)(ANYARGS), void *data)
115
+ {
116
+ VALUE rv;
117
+
118
+ TRAP_BEG;
119
+ rv = f(data);
120
+ TRAP_END;
121
+
122
+ return rv;
123
+ }
124
+ # define NOGVL(f, d) \
125
+ fake_blocking_region(NOGVL_FUNCTION(f), (d))
126
+ #endif
127
+
128
+ #if defined(__cplusplus)
129
+ }
130
+ #endif
131
+
132
+ #endif /* _COMMON_H */
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+ require 'digest'
5
+ require 'open-uri'
6
+
7
+ LIBMAGIC_TAG = '5.39'.freeze
8
+
9
+ workdir = Dir.pwd
10
+ libdir = File.join(workdir, 'file-' + LIBMAGIC_TAG)
11
+ gemdir = File.expand_path(File.join(__dir__, '../..'))
12
+ gem_ext_dir = File.join(gemdir, 'lib', 'ext')
13
+ gem_include_dir = File.join(gem_ext_dir, 'include')
14
+ gem_lib_dir = File.join(gem_ext_dir, 'lib')
15
+ build_lib_dir = File.join(libdir, 'src', '.libs')
16
+
17
+ expected_sha256 = 'f05d286a76d9556243d0cb05814929c2ecf3a5ba07963f8f70bfaaa70517fad1'
18
+ filename = "#{workdir}/file.tar.gz"
19
+
20
+ unless File.exist?(filename)
21
+ File.open(filename, 'wb') do |target_file|
22
+ URI.open("ftp://ftp.astron.com/pub/file/file-#{LIBMAGIC_TAG}.tar.gz", 'rb') do |read_file|
23
+ target_file.write(read_file.read)
24
+ end
25
+ end
26
+
27
+ checksum = Digest::SHA256.hexdigest(File.read(filename))
28
+
29
+ if checksum != expected_sha256
30
+ raise "SHA256 of #{filename} does not match: got #{checksum}, expected #{expected_sha256}"
31
+ end
32
+ end
33
+
34
+ system("tar -xzf #{filename}") || raise('ERROR')
35
+ system("cd #{libdir} && ./configure --prefix=#{gem_ext_dir} && make install") || raise('ERROR')
36
+
37
+ $LOCAL_LIBS << '-lmagic'
38
+ $LIBPATH << gem_lib_dir
39
+ $CFLAGS << " -I #{libdir}/src"
40
+
41
+ def darwin?
42
+ RbConfig::CONFIG['target_os'] =~ /darwin/
43
+ end
44
+
45
+ def windows?
46
+ RbConfig::CONFIG['target_os'] =~ /mswin|mingw32|windows/
47
+ end
48
+
49
+ if ENV['CC']
50
+ RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC']
51
+ end
52
+
53
+ ENV['CC'] = RbConfig::CONFIG['CC']
54
+
55
+ $CFLAGS += ' -std=c99 -fPIC'
56
+ $CFLAGS += ' -Wall -Wextra -pedantic'
57
+
58
+ if RbConfig::CONFIG['CC'] =~ /gcc/
59
+ $CFLAGS += ' -O3' unless $CFLAGS =~ /-O\d/
60
+ $CFLAGS += ' -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline'
61
+ end
62
+
63
+ unless darwin?
64
+ $LDFLAGS += ' -Wl,--as-needed -Wl,--no-undefined'
65
+ end
66
+
67
+ if windows?
68
+ $LDFLAGS += ' -static-libgcc'
69
+ end
70
+
71
+ %w[
72
+ CFLAGS
73
+ CXXFLAGS
74
+ CPPFLAGS
75
+ ].each do |variable|
76
+ $CFLAGS += format(' %s', ENV[variable]) if ENV[variable]
77
+ end
78
+
79
+ $LDFLAGS += format(' %s', ENV['LDFLAGS']) if ENV['LDFLAGS']
80
+
81
+ unless have_header('ruby.h')
82
+ abort "\n" + (<<-EOS).gsub(/^[ ]{,3}/, '') + "\n"
83
+ You appear to be missing Ruby development libraries and/or header
84
+ files. You can install missing compile-time dependencies in one of
85
+ the following ways:
86
+
87
+ - Debian / Ubuntu
88
+
89
+ apt-get install ruby-dev
90
+
91
+ - Red Hat / CentOS / Fedora
92
+
93
+ yum install ruby-devel or dnf install ruby-devel
94
+
95
+ - Mac OS X (Darwin)
96
+
97
+ brew install ruby (for Homebrew, see https://brew.sh)
98
+ port install ruby2.6 (for MacPorts, see https://www.macports.org)
99
+
100
+ - OpenBSD / NetBSD
101
+
102
+ pkg_add ruby (for pkgsrc, see https://www.pkgsrc.org)
103
+
104
+ - FreeBSD
105
+
106
+ pkg install ruby (for FreeBSD Ports, see https://www.freebsd.org/ports)
107
+
108
+ Alternatively, you can use either of the following Ruby version
109
+ managers in order to install Ruby locally (for your user only)
110
+ and/or system-wide:
111
+
112
+ - Ruby Version Manager (for RVM, see https://rvm.io)
113
+ - Ruby Environment (for rbenv, see https://github.com/sstephenson/rbenv)
114
+ - Change Ruby (for chruby, see https://github.com/postmodern/chruby)
115
+
116
+ More information about how to install Ruby on various platforms
117
+ available at the following web site:
118
+
119
+ https://www.ruby-lang.org/en/documentation/installation
120
+ EOS
121
+ end
122
+
123
+ have_library('ruby')
124
+
125
+ have_func('rb_thread_call_without_gvl')
126
+ have_func('rb_thread_blocking_region')
127
+
128
+ unless have_header('magic.h')
129
+ abort "\n" + (<<-EOS).gsub(/^[ ]{,3}/, '') + "\n"
130
+ You appear to be missing libmagic(3) library and/or necessary header
131
+ files. You can install missing compile-time dependencies in one of
132
+ the following ways:
133
+
134
+ - Debian / Ubuntu
135
+
136
+ apt-get install libmagic-dev
137
+
138
+ - Red Hat / CentOS / Fedora
139
+
140
+ yum install file-devel or dns install file-devel
141
+
142
+ - Mac OS X (Darwin)
143
+
144
+ brew install libmagic (for Homebrew, see https://brew.sh)
145
+ port install libmagic (for MacPorts, see https://www.macports.org)
146
+
147
+ - OpenBSD / NetBSD
148
+
149
+ pkg_add file (for pkgsrc, see https://www.pkgsrc.org)
150
+
151
+ - FreeBSD
152
+
153
+ pkg install file (for FreeBSD Ports, see https://www.freebsd.org/ports)
154
+
155
+ Alternatively, you can download recent release of the file(1) package
156
+ from the following web site and attempt to compile libmagic(3) manually:
157
+
158
+ https://www.darwinsys.com/file
159
+ EOS
160
+ end
161
+
162
+ have_library('magic')
163
+
164
+ unless have_func('magic_getpath')
165
+ abort "\n" + (<<-EOS).gsub(/^[ ]{,3}/, '') + "\n"
166
+ Your version of libmagic(3) appears to be too old.
167
+
168
+ Please, consider upgrading to at least version 5.29 or newer,
169
+ if possible. For more information about file(1) command and
170
+ libmagic(3) please visit the following web site:
171
+
172
+ https://www.darwinsys.com/file
173
+ EOS
174
+ end
175
+
176
+ have_func('magic_getflags')
177
+
178
+ %w[
179
+ utime.h
180
+ sys/types.h
181
+ sys/time.h
182
+ ].each do |h|
183
+ have_header(h)
184
+ end
185
+
186
+ %w[
187
+ utime
188
+ utimes
189
+ ].each do |f|
190
+ have_func(f)
191
+ end
192
+
193
+ dir_config('magic', [gem_include_dir], [gem_lib_dir])
194
+
195
+ create_header
196
+ create_makefile('magic/magic')
@@ -0,0 +1,344 @@
1
+ #if defined(__cplusplus)
2
+ extern "C" {
3
+ #endif
4
+
5
+ #include "functions.h"
6
+
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);
12
+ int restore_error_output(void *data);
13
+
14
+ inline int
15
+ check_fd(int fd)
16
+ {
17
+ errno = 0;
18
+ if (fd < 0 || (fcntl(fd, F_GETFD) < 0 && errno == EBADF)) {
19
+ errno = EBADF;
20
+ return -EBADF;
21
+ }
22
+
23
+ return 0;
24
+ }
25
+
26
+ static int
27
+ safe_dup(int fd)
28
+ {
29
+ int new_fd;
30
+ int local_errno;
31
+ int flags = F_DUPFD;
32
+
33
+ #if defined(HAVE_F_DUPFD_CLOEXEC)
34
+ flags = F_DUPFD_CLOEXEC;
35
+ #endif
36
+
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
+ }
55
+
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
67
+
68
+ return rv;
69
+ }
70
+
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
+ }
91
+
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;
98
+
99
+ #if defined(HAVE_O_CLOEXEC)
100
+ mode |= O_CLOEXEC;
101
+ #endif
102
+
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;
147
+ }
148
+
149
+ int
150
+ restore_error_output(void *data)
151
+ {
152
+ int local_errno;
153
+ save_t *s = data;
154
+
155
+ assert(s != NULL && \
156
+ "Must be a valid pointer to `save_t' type");
157
+
158
+ if (s->file.old_fd < 0 && s->status != 0)
159
+ return -1;
160
+
161
+ fflush(stderr);
162
+
163
+ if (dup2(s->file.old_fd, fileno(stderr)) < 0) {
164
+ local_errno = errno;
165
+ goto error;
166
+ }
167
+
168
+ safe_close(s->file.old_fd);
169
+ clearerr(stderr);
170
+ fsetpos(stderr, &s->file.position);
171
+
172
+ if (setvbuf(stderr, NULL, _IONBF, 0) != 0) {
173
+ local_errno = errno;
174
+ goto error;
175
+ }
176
+
177
+ return 0;
178
+ error:
179
+ s->status = local_errno;
180
+ errno = s->status;
181
+ return -1;
182
+ }
183
+
184
+ inline magic_t
185
+ magic_open_wrapper(int flags)
186
+ {
187
+ return magic_open(flags);
188
+ }
189
+
190
+ inline void
191
+ magic_close_wrapper(magic_t magic)
192
+ {
193
+ magic_close(magic);
194
+ }
195
+
196
+ inline const char*
197
+ magic_error_wrapper(magic_t magic)
198
+ {
199
+ return magic_error(magic);
200
+ }
201
+
202
+ inline int
203
+ magic_errno_wrapper(magic_t magic)
204
+ {
205
+ return magic_errno(magic);
206
+ }
207
+
208
+ inline const char*
209
+ magic_getpath_wrapper(void)
210
+ {
211
+ return magic_getpath(NULL, 0);
212
+ }
213
+
214
+ inline int
215
+ magic_getparam_wrapper(magic_t magic, int parameter, void *value)
216
+ {
217
+ return magic_getparam(magic, parameter, value);
218
+ }
219
+
220
+ inline int
221
+ magic_setparam_wrapper(magic_t magic, int parameter, const void *value)
222
+ {
223
+ if (*(const int *)value < 0 || *(const size_t *)value > UINT_MAX) {
224
+ errno = EOVERFLOW;
225
+ return -EOVERFLOW;
226
+ }
227
+
228
+ if (parameter == MAGIC_PARAM_BYTES_MAX)
229
+ return magic_setparam(magic, parameter, value);
230
+
231
+ if (*(const size_t *)value > USHRT_MAX) {
232
+ errno = EOVERFLOW;
233
+ return -EOVERFLOW;
234
+ }
235
+
236
+ return magic_setparam(magic, parameter, value);
237
+ }
238
+
239
+ inline int
240
+ magic_getflags_wrapper(magic_t magic)
241
+ {
242
+ #if defined(HAVE_MAGIC_GETFLAGS)
243
+ return magic_getflags(magic);
244
+ #else
245
+ UNUSED(magic);
246
+ errno = ENOSYS;
247
+ return -ENOSYS;
248
+ #endif
249
+ }
250
+
251
+ inline int
252
+ magic_setflags_wrapper(magic_t magic, int flags)
253
+ {
254
+ if (flags < 0 || flags > 0xfffffff) {
255
+ errno = EINVAL;
256
+ return -EINVAL;
257
+ }
258
+
259
+ #if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
260
+ if (flags & MAGIC_PRESERVE_ATIME) {
261
+ errno = ENOSYS;
262
+ return -ENOSYS;
263
+ }
264
+ #endif
265
+
266
+ return magic_setflags(magic, flags);
267
+ }
268
+
269
+ inline int
270
+ magic_load_wrapper(magic_t magic, const char *magic_file, int flags)
271
+ {
272
+ int rv;
273
+ MAGIC_FUNCTION(magic_load, rv, flags, magic, magic_file);
274
+ return rv;
275
+ }
276
+
277
+ inline int
278
+ magic_load_buffers_wrapper(magic_t magic, void **buffers, size_t *sizes, size_t count, int flags)
279
+ {
280
+ int rv;
281
+ MAGIC_FUNCTION(magic_load_buffers, rv, flags, magic, buffers, sizes, count);
282
+ return rv;
283
+ }
284
+
285
+ inline int
286
+ magic_compile_wrapper(magic_t magic, const char *magic_file, int flags)
287
+ {
288
+ int rv;
289
+ MAGIC_FUNCTION(magic_compile, rv, flags, magic, magic_file);
290
+ return rv;
291
+ }
292
+
293
+ inline int
294
+ magic_check_wrapper(magic_t magic, const char *magic_file, int flags)
295
+ {
296
+ int rv;
297
+ MAGIC_FUNCTION(magic_check, rv, flags, magic, magic_file);
298
+ return rv;
299
+ }
300
+
301
+ inline const char*
302
+ magic_file_wrapper(magic_t magic, const char* filename, int flags)
303
+ {
304
+ const char *cstring;
305
+ MAGIC_FUNCTION(magic_file, cstring, flags, magic, filename);
306
+ return cstring;
307
+ }
308
+
309
+ inline const char*
310
+ magic_buffer_wrapper(magic_t magic, const void *buffer, size_t size, int flags)
311
+ {
312
+ const char *cstring;
313
+ MAGIC_FUNCTION(magic_buffer, cstring, flags, magic, buffer, size);
314
+ return cstring;
315
+ }
316
+
317
+ inline const char*
318
+ magic_descriptor_wrapper(magic_t magic, int fd, int flags)
319
+ {
320
+ int local_errno;
321
+ const char *cstring;
322
+
323
+ if (check_fd(fd) < 0) {
324
+ local_errno = errno;
325
+ goto error;
326
+ }
327
+
328
+ MAGIC_FUNCTION(magic_descriptor, cstring, flags, magic, fd);
329
+ return cstring;
330
+
331
+ error:
332
+ errno = local_errno;
333
+ return NULL;
334
+ }
335
+
336
+ inline int
337
+ magic_version_wrapper(void)
338
+ {
339
+ return magic_version();
340
+ }
341
+
342
+ #if defined(__cplusplus)
343
+ }
344
+ #endif