1 /* libSoX internal functions that apply to both formats and effects
2 * All public functions & data are prefixed with lsx_ .
3 *
4 * Copyright (c) 2008 robs@users.sourceforge.net
5 *
6 * This library is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or (at
9 * your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this library; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21
22 #include "sox_i.h"
23
24 #ifdef HAVE_IO_H
25 #include <io.h>
26 #endif
27
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31
32 #if defined(_MSC_VER) || defined(__MINGW32__)
33 #define MKTEMP_X _O_BINARY|_O_TEMPORARY
34 #else
35 #define MKTEMP_X 0
36 #endif
37
38 #ifndef HAVE_MKSTEMP
39 #include <fcntl.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #define mkstemp(t) open(mktemp(t), MKTEMP_X|O_RDWR|O_TRUNC|O_CREAT, S_IREAD|S_IWRITE)
43 #define FAKE_MKSTEMP "fake "
44 #else
45 #define FAKE_MKSTEMP
46 #endif
47
48 #ifdef WIN32
49 static int check_dir(char * buf, size_t buflen, char const * name)
50 {
51 struct stat st;
52 if (!name || stat(name, &st) || (st.st_mode & S_IFMT) != S_IFDIR)
53 {
54 return 0;
55 }
56 else
57 {
58 strncpy(buf, name, buflen);
59 buf[buflen - 1] = 0;
60 return strlen(name) == strlen(buf);
61 }
62 }
startread(sox_format_t * ft)63 #endif
64
65 FILE * lsx_tmpfile(void)
66 {
67 char const * path = sox_globals.tmp_path;
68
69 /*
70 On Win32, tmpfile() is broken - it creates the file in the root directory of
71 the current drive (the user probably doesn't have permission to write there!)
72 instead of in a valid temporary directory (like TEMP or TMP). So if tmp_path
73 is null, figure out a reasonable default.
74 To force use of tmpfile(), set sox_globals.tmp_path = "".
75 */
76 #ifdef WIN32
77 if (!path)
78 {
79 static char default_path[260] = "";
80 if (default_path[0] == 0
81 && !check_dir(default_path, sizeof(default_path), getenv("TEMP"))
82 && !check_dir(default_path, sizeof(default_path), getenv("TMP"))
83 #ifdef __CYGWIN__
84 && !check_dir(default_path, sizeof(default_path), "/tmp")
85 #endif
86 )
87 {
88 strcpy(default_path, ".");
89 }
90
91 path = default_path;
92 }
93 #endif
94
95 if (path && path[0]) {
96 /* Emulate tmpfile (delete on close); tmp dir is given tmp_path: */
97 char const * const end = "/libSoX.tmp.XXXXXX";
98 char * name = lsx_malloc(strlen(path) + strlen(end) + 1);
99 int fildes;
100 strcpy(name, path);
101 strcat(name, end);
102 fildes = mkstemp(name);
103 #ifdef HAVE_UNISTD_H
104 lsx_debug(FAKE_MKSTEMP "mkstemp, name=%s (unlinked)", name);
105 unlink(name);
106 #else
107 lsx_debug(FAKE_MKSTEMP "mkstemp, name=%s (O_TEMPORARY)", name);
108 #endif
109 free(name);
110 return fildes == -1? NULL : fdopen(fildes, "w+b");
111 }
112
113 /* Use standard tmpfile (delete on close); tmp dir is undefined: */
114 lsx_debug("tmpfile()");
115 return tmpfile();
116 }
117