shithub: sox

Download patch

ref: f93bf7252fe9725fa6f13fc4c14c35de0d7e1aae
parent: 8ec2b8c82f3b9a23437cce5ea888677779e8d42a
author: robs <robs>
date: Sun Dec 7 05:44:26 EST 2008

attempt to fix tmpfile problems on cygwin

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,6 +53,7 @@
 
 check_function_exists("fseeko"           HAVE_FSEEKO)
 check_function_exists("gettimeofday"     HAVE_GETTIMEOFDAY)
+check_function_exists("mkstemp"          HAVE_MKSTEMP)
 check_function_exists("popen"            HAVE_POPEN)
 check_function_exists("strcasecmp"       HAVE_STRCASECMP)
 check_function_exists("strrstr"          HAVE_STRRSTR)
--- a/configure.ac
+++ b/configure.ac
@@ -146,7 +146,7 @@
 AC_CHECK_HEADERS(fcntl.h unistd.h byteswap.h sys/time.h sys/timeb.h sys/types.h sys/utsname.h)
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(strcasecmp strdup popen vsnprintf gettimeofday glob)
+AC_CHECK_FUNCS(strcasecmp strdup popen vsnprintf gettimeofday glob mkstemp)
 
 dnl Check if math library is needed.
 AC_CHECK_FUNC(pow)
--- a/src/8svx.c
+++ b/src/8svx.c
@@ -234,7 +234,7 @@
         /* open channel output files */
         p->ch[0] = ft->fp;
         for (i = 1; i < ft->signal.channels; i++) {
-                if ((p->ch[i] = tmpfile()) == NULL)
+                if ((p->ch[i] = lsx_tmpfile()) == NULL)
                 {
                         lsx_fail_errno(ft,errno,"Can't open channel output file");
                         return(SOX_EOF);
--- a/src/getopt.c
+++ b/src/getopt.c
@@ -1,3 +1,4 @@
+#include "soxconfig.h"
 /* Getopt for GNU.
    NOTE: getopt is now part of the C library, so if you don't know what
    "Keep this file name-space clean" means, talk to drepper@gnu.org
--- a/src/libsox.c
+++ b/src/libsox.c
@@ -49,7 +49,7 @@
   8192,
   0,
   0,
-  NULL, NULL, NULL};
+  NULL, NULL, NULL, NULL};
 
 void sox_output_message(FILE *file, const char *filename, const char *fmt, va_list ap)
 {
--- a/src/libsox_i.c
+++ b/src/libsox_i.c
@@ -1,13 +1,65 @@
 /* libSoX internal functions that apply to both formats and effects
  * All public functions & data are prefixed with lsx_ .
  *
- * Copyright 1998-2008 Chris Bagwell and SoX Contributors
- * Copyright 1991 Lance Norskog And Sundry Contributors
+ * Copyright (c) 2008 robs@users.sourceforge.net
  *
- * This source code is freely redistributable and may be used for
- * any purpose.  This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+
 #include "sox_i.h"
+
+#ifdef HAVE_IO_H
+  #include <io.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+  #include <unistd.h>
+  #define MKTEMP_FLAGS O_RDWR|O_TRUNC|O_CREAT, S_IREAD|S_IWRITE
+#else
+  #define MKTEMP_FLAGS _O_RDWR|_O_TRUNC|_O_CREAT|_O_BINARY|_O_TEMPORARY, _S_IREAD|_S_IWRITE
+#endif
+
+#ifndef HAVE_MKSTEMP
+  #include <fcntl.h>
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #define mkstemp(t) open(mktemp(t), MKTEMP_FLAGS)
+  #define FAKE_MKSTEMP "fake "
+#else
+  #define FAKE_MKSTEMP
+#endif
+
+FILE * lsx_tmpfile(void)
+{
+  if (sox_globals.tmp_path) {
+    char const * const end = "/libSoX.tmp.XXXXXX";
+    char * name = lsx_malloc(strlen(sox_globals.tmp_path) + strlen(end) + 1);
+    int fildes;
+    strcpy(name, sox_globals.tmp_path);
+    strcat(name, end);
+    fildes = mkstemp(name);
+#ifdef HAVE_UNISTD_H
+    lsx_debug(FAKE_MKSTEMP "mkstemp, name=%s (unlinked)", name);
+    unlink(name);
+#else
+    lsx_debug(FAKE_MKSTEMP "mkstemp, name=%s (O_TEMPORARY)", name);
+#endif
+    free(name);
+    return fildes == -1? NULL : fdopen(fildes, "w+");
+  }
+  lsx_debug("tmpfile()");
+  return tmpfile();
+}
--- a/src/normalise.c
+++ b/src/normalise.c
@@ -44,7 +44,7 @@
   if (!(p->individual || p->balance))
     effp->flows = 1;
   p->norm0 = p->max = p->min = 0;
-  p->tmp_file = tmpfile();
+  p->tmp_file = lsx_tmpfile();
   if (p->tmp_file == NULL) {
     lsx_fail("can't create temporary file: %s", strerror(errno));
     return SOX_EOF;
@@ -113,7 +113,7 @@
 static int stop(sox_effect_t * effp)
 {
   priv_t * p = (priv_t *)effp->priv;
-  fclose(p->tmp_file); /* auto-deleted by tmpfile */
+  fclose(p->tmp_file); /* auto-deleted by lsx_tmpfile */
   return SOX_SUCCESS;
 }
 
--- a/src/repeat.c
+++ b/src/repeat.c
@@ -42,7 +42,7 @@
   if (p->repeats == 0)
     return SOX_EFF_NULL;
 
-  if ((p->tmp_file = tmpfile()) == NULL) {
+  if ((p->tmp_file = lsx_tmpfile()) == NULL) {
     lsx_fail("can't create temporary file: %s", strerror(errno));
     return SOX_EOF;
   }
--- a/src/reverse.c
+++ b/src/reverse.c
@@ -7,7 +7,7 @@
  */
 
 /*
- * "reverse" effect, uses a temporary file created by tmpfile().
+ * "reverse" effect, uses a temporary file created by lsx_tmpfile().
  */
 
 #include "sox_i.h"
@@ -22,7 +22,7 @@
 {
   priv_t * p = (priv_t *)effp->priv;
   p->pos = 0;
-  p->tmp_file = tmpfile();
+  p->tmp_file = lsx_tmpfile();
   if (p->tmp_file == NULL) {
     lsx_fail("can't create temporary file: %s", strerror(errno));
     return SOX_EOF;
@@ -73,7 +73,7 @@
 static int stop(sox_effect_t * effp)
 {
   priv_t * p = (priv_t *)effp->priv;
-  fclose(p->tmp_file); /* auto-deleted by tmpfile */
+  fclose(p->tmp_file); /* auto-deleted by lsx_tmpfile */
   return SOX_SUCCESS;
 }
 
--- a/src/sox.c
+++ b/src/sox.c
@@ -1617,6 +1617,7 @@
 "--replay-gain track|album|off  Default: off (sox, rec), track (play)",
 "-R                       Use default random numbers (same on each run of SoX)",
 "-S, --show-progress      Display progress while processing audio data",
+"--temp DIRECTORY         Specify the directory to use temporary files",
 "--version                Display version number of SoX and exit",
 "-V[LEVEL]                Increment or set verbosity level (default 2); levels:",
 "                           1: failure messages",
@@ -1816,6 +1817,7 @@
     {"version"         ,       no_argument, NULL, 0},
     {"output"          , required_argument, NULL, 0},
     {"effects-file"    , required_argument, NULL, 0},
+    {"temp"            , required_argument, NULL, 0},
 
     {"bits"            , required_argument, NULL, 'b'},
     {"channels"        , required_argument, NULL, 'c'},
@@ -2000,6 +2002,10 @@
         effects_filename = strdup(optarg);
         break;
 
+      case 16:
+        sox_globals.tmp_path = strdup(optarg);
+        break;
+
       }
       break;
 
@@ -2407,6 +2413,15 @@
   return str_len >= end_len && !strcmp(str + str_len - end_len, end);
 }
 
+#ifdef __CYGWIN__
+static char * check_dir(char * name)
+{
+  struct stat st;
+  return !name || stat(name, &st) || (st.st_mode & S_IFMT) != S_IFDIR?
+      NULL : name;
+}
+#endif
+
 int main(int argc, char **argv)
 {
   size_t i;
@@ -2441,6 +2456,20 @@
 #endif
 
   parse_options_and_filenames(argc, argv);
+
+#ifdef __CYGWIN__
+  if (sox_globals.tmp_path && !*sox_globals.tmp_path) {
+    free(sox_globals.tmp_path);
+    sox_globals.tmp_path = NULL;
+  }
+  else if (!sox_globals.tmp_path) {
+    if (!(sox_globals.tmp_path = check_dir(getenv("TEMP"))))
+      if (!(sox_globals.tmp_path = check_dir(getenv("TMP"))))
+        if (!(sox_globals.tmp_path = check_dir("/tmp")))
+          sox_globals.tmp_path = ".";
+    sox_globals.tmp_path = lsx_strdup(sox_globals.tmp_path);
+  }
+#endif
 
   if (sox_globals.verbosity > 2)
     display_SoX_version(stderr);
--- a/src/sox.h
+++ b/src/sox.h
@@ -186,6 +186,7 @@
   char const * stdin_in_use_by;
   char const * stdout_in_use_by;
   char const * subsystem;
+  char       * tmp_path;
 } sox_globals_t;
 extern sox_globals_t sox_globals;
 
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -51,6 +51,8 @@
 #define FMT_size_t "lu"
 #endif
 
+FILE * lsx_tmpfile(void);
+
 void lsx_debug_more(char const * fmt, ...) PRINTF;
 void lsx_debug_most(char const * fmt, ...) PRINTF;
 
--- a/src/soxconfig.h.cmake
+++ b/src/soxconfig.h.cmake
@@ -20,6 +20,7 @@
 #cmakedefine HAVE_MAD_H               1
 #cmakedefine HAVE_MP3                 1
 #cmakedefine HAVE_MAGIC               1
+#cmakedefine HAVE_MKSTEMP             1
 #cmakedefine HAVE_OGG_SPEEX           1
 #cmakedefine HAVE_OGG_VORBIS          1
 #cmakedefine HAVE_POPEN               1
--- a/src/util.h
+++ b/src/util.h
@@ -43,6 +43,7 @@
 #define stat _stat
 #define strdup _strdup
 #define timeb _timeb
+#define unlink _unlink
 #endif
 
 #if defined(DOS) || defined(WIN32) || defined(__NT__) || defined(__DJGPP__) || defined(__OS2__)