I am a pedant and I like if my audiofiles have correct homogenous tags and names. I dislike missing album or artist field and filenames like “01 – Track 01”. That’s why I adore Easytag (http://projects.gnome.org/easytag/) – a robust tag editor with tasty features like tag encoding conversion or retrieving tags from filenames.
I found only one problem in Easytag. It allows to open the selected file with an audio player. The thing is that if you use Audacious, then it will occasionally switch to its default skin.
Audacious is a free advanced audio player for Linux and many other UNIX-compatible systems. It focuses on low resource usage, high audio quality, and support for a wide range of audio formats. Winamp.wsz skin files, a type of Zip archive, can be used directly, or can be unarchived to individual directories. The program can use Windows Bitmap (.bmp) graphics from the Winamp archive, although native skins for Linux are usually rendered in Portable Network Graphics (.png) format. Audacious 1.x allows the user to adjust the RGB color balance of any skin, effectively making a basic white skin equivalent to a host of colorized skins without editing them manually.
For example, I have chosen Classic 1.3 skin. When I select Run Audio Player, my Audacious reverts to Default skin.
Several tests shown that this problem happens only with archived skins, so, it was definitely a sign that the problem was in Audacious itself.
Easytag allows to provide a command line to launch audio player, so let’s set it as
audacious --verbose -p and run Easytag from a terminal to see debug output produced by Audacious.
That’s what I was looking for:
As far as we know, Audacious has a highly modular architecture, that’s why it has a special skins plugin. This plugin runs
unzip subprocess to unpack the skin archive and switches to Default skin if it has encountered problems.
But… what problems? Let’s check up the output directory:
unzip had done his job, but Audacious complained! It’s time to look at skin plugin source in hope that it will throw light.
Now we see that Audacious calls
system function from standard C library. According to the manual,
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed… The value returned is -1 on error (e.g., fork(2) failed), and the return status of the command otherwise.
Still no ideas. Let’s look at
system implementation. We can find it in
glibc-2.15/sysdeps/posix/system.c. It’s quite straightforward.
SIGQUIT handling, calls
waitpid to retrieve the command exit status.
fork was successful since archive was really unzipped. What problems can happen in
ECHILD (for wait()) The calling process does not have any unwaited-for
ECHILD (for waitpid() or waitid()) The process specified by pid (wait‐
pid()) or idtype and id (waitid()) does not exist or is not a
child of the calling process. (This can happen for one’s own
child if the action for SIGCHLD is set to SIG_IGN. See also the
Linux Notes section about threads.)
EINTR WNOHANG was not set and an unblocked signal or a SIGCHLD was
caught; see signal(7).
EINVAL The options argument was invalid.
This can happen for one's own child if the action for SIGCHLD is set to SIG_IGN looks suspicious. Grep it!
We are on the right way! Easytag sets
SIGCHLD handler to
SIG_IGN, that’s why its child processes do not become zombies. But Audacious inherits this
SIG_IGN behavior (the manual says that child processes inherit such signal handlers from parents) and cannot perform a successful
waitpid. That’s why
system function returns failure even for a successful unzipping.
Audacious Winamp Skin
It’s very easy to fix the bug. The problem is in Easytag, not in Audacious. It’s enough to set a normal handler for
SIGCHLD. The handler will be called each time when a child process exits. This process resides in zombie state. The handler simply calls
wait (this friend of
waitpid waits for _any_ child process) thus removing zombie’s control block and freeing kernel resources that were still used by the zombie:
Skins Para Audacious
setup_sigchld(), compile, and run Easytag – and any archived skin will be rendered without problems!