Package: imms
Version: 2.0.1-3
Followup-For: Bug #292777

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Attached. I have only briefly tested this, so beware. This patch works
by getting rid of the call to popen (and thus the shell). It replaces it
with pipe, fork, exec, etc.

- -- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (500, 'testing'), (130, 'unstable'), (120, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.10-bohr
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)

Versions of packages imms depends on:
ii  fftw3                    3.0.1-11        Library for computing Fast Fourier
ii  libc6                    2.3.2.ds1-20    GNU C Library: Shared libraries an
ii  libgcc1                  1:3.4.3-6       GCC support library
ii  libglib1.2               1.2.10-9        The GLib library of C routines
ii  libglib2.0-0             2.6.1-2         The GLib library of C routines
ii  libgtk1.2                1.2.10-17       The GIMP Toolkit set of widgets fo
ii  libpcre3                 4.5-1.1         Perl 5 Compatible Regular Expressi
ii  libsqlite3-0             3.0.8-3         SQLite 3 shared library
ii  libstdc++5               1:3.3.5-5       The GNU Standard C++ Library v3
ii  libtag1                  1.3.1-1         TagLib Audio Meta-Data Library
ii  libx11-6                 4.3.0.dfsg.1-10 X Window System protocol client li
ii  libxext6                 4.3.0.dfsg.1-10 X Window System miscellaneous exte
ii  libxi6                   4.3.0.dfsg.1-10 X Window System Input extension li
ii  xlibs                    4.3.0.dfsg.1-10 X Keyboard Extension (XKB) configu
ii  xmms                     1.2.10-2        Versatile X audio player that look
ii  zlib1g                   1:1.2.2-3       compression library - runtime

- -- no debconf information

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFB+/PU+z+IwlXqWf4RAo/AAJ9j7Psf8FAh38PBhokHAX+KhWXFSwCfWLLc
N850NnqlEllvVuf7KpgaNhE=
=jFS1
-----END PGP SIGNATURE-----
--- analyzer.cc	2004-12-09 15:13:24.000000000 -0500
+++ analyzer.cc.new	2005-01-29 15:35:19.000000000 -0500
@@ -1,5 +1,7 @@
-#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <unistd.h>
+#include <stdio.h>
 #include <iostream>
 #include <string>
 #include <fstream>
@@ -44,17 +46,53 @@
         return -4;
     }
 
-    ostringstream command;
-    command << "nice -n 15 sox \"" << path << "\" -t .raw -w -u -c 1 -r "
-        << SAMPLERATE << " -";
-#ifdef DEBUG
-    cout << "analyzer: Executing: " << command.str() << endl;
-#endif
-    FILE *p = popen(command.str().c_str(), "r");
+	// Do a popen the long way to avoid the shell.
+	int p_fds[2];
+	if (-1 == pipe(p_fds))
+	{
+		cerr << "analyzer: Could not open pipe: " << strerror(errno)
+		     << endl;
+		return -2;
+	}
+	
+	int child_pid = fork();
+	if (child_pid == -1)
+	{
+		cerr << "analyzer: Could not fork: " << strerror(errno) << endl;
+		return -2;
+	} 
+	else if (child_pid == 0)
+	{
+		ostringstream sample_rate;
+		sample_rate << SAMPLERATE;
+
+		if (-1 == dup2(p_fds[1], STDOUT_FILENO))
+		{
+			cerr << "analyzer: Could not dup2: " << strerror(errno) << endl;
+			return -2;
+		}
+		if (-1 == nice(15))
+		{
+			cerr << "analyzer: could not renice: " << strerror(errno) << endl;
+			return -2;
+		}
+		if (-1 == execlp("sox", "sox", path.c_str(), "-t", ".raw", "-w",
+					     "-u", "-c", "1", "-r", sample_rate.str().c_str(),
+					     "-", (char*)NULL))
+		{
+		    cerr << "could not exec sox: " << strerror(errno) << endl;
+		    return -2;
+		}
+	} 
+	
+	// The child performed an exec above, so we only get here if we're
+	// the parent.
+	close(p_fds[1]); // otherwise, read wont fail.
+	FILE *p = fdopen(p_fds[0], "r");
 
     if (!p)
     {
-        cerr << "analyzer: Could not open pipe!" << endl;
+        cerr << "analyzer: Could not fdopen pipe!" << endl;
         return -2;
     }
 
@@ -77,10 +115,7 @@
         SpectrumAnalyzer analyzer(path);
 
         if (analyzer.is_known())
-        {
-            cout << "analyzer: Already analyzed - skipping." << endl;
-            return 1;
-        }
+            throw std::string("analyzer: Already analyzed - skipping.");
 
         while (fread(indata + OVERLAP, sizeof(sample_t), READSIZE, p)
                 == READSIZE)
@@ -106,7 +141,22 @@
     }
     catch (std::string &s) { cerr << s << endl; }
 
-    pclose(p);
+	fclose(p);
+	kill(child_pid, SIGKILL); // make sure
+	int sox_status;
+	if (-1 == waitpid(child_pid, &sox_status, 0))
+		cerr << "WARNING: waitpid failed: " << strerror(errno) << endl;
+
+	if (WIFEXITED(sox_status) && 0 != WEXITSTATUS(sox_status))
+	{
+		cerr << "WARNING: sox exited with unclean status "
+		     << WEXITSTATUS(sox_status) << ".\n";
+	}
+	else if (WIFSIGNALED(sox_status) && SIGKILL != WTERMSIG(sox_status))
+	{
+		cerr << "WARNING: sox exited on signal " << WTERMSIG(sox_status)
+		     << ".\n";
+	}
 
     return 0;
 }

Reply via email to