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 fftw33.0.1-11Library for computing Fast Fourier
ii libc62.3.2.ds1-20GNU C Library: Shared libraries an
ii libgcc1 1:3.4.3-6 GCC support library
ii libglib1.2 1.2.10-9The GLib library of C routines
ii libglib2.0-0 2.6.1-2 The GLib library of C routines
ii libgtk1.21.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 xlibs4.3.0.dfsg.1-10 X Keyboard Extension (XKB) configu
ii xmms 1.2.10-2Versatile 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.0 -0500
+++ analyzer.cc.new 2005-01-29 15:35:19.0 -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;
}