From 3122008704ad07fe4982de0e642576ca7613d7bf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 5 Mar 2009 04:33:40 +0100 Subject: try to detect when stupid clients forks and refuse all service from then on --- src/pulse/fork-detect.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/pulse/fork-detect.c (limited to 'src/pulse/fork-detect.c') diff --git a/src/pulse/fork-detect.c b/src/pulse/fork-detect.c new file mode 100644 index 00000000..f10fc029 --- /dev/null +++ b/src/pulse/fork-detect.c @@ -0,0 +1,59 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Lennart Poettering + + PulseAudio 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. + + PulseAudio 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 + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#include "fork-detect.h" + +int pa_detect_fork(void) { + static pa_atomic_t pid = PA_ATOMIC_INIT((int) -1); + + /* Some really stupid applications (Hey, vim, that means you!) + * love to fork after initializing + * gtk/libcanberra/pulseaudio. This is really bad style. We + * however have to deal with this cleanly, so we try to detect the + * forks making sure all our calls fail cleanly after the fork. */ + + pa_assert(sizeof(pa_atomic_t) >= sizeof(pid_t)); + + for (;;) { + pid_t stored_pid = (pid_t) pa_atomic_load(&pid); + + /* First let's check whether the current pid matches the stored one */ + if (stored_pid == getpid()) + return FALSE; + + /* Does it contain a different PID than ours? Then the process got forked. */ + if ((int) stored_pid != (int) -1) + return TRUE; + + /* Ok, it still contains no PID, then store it */ + if (pa_atomic_cmpxchg(&pid, (int) -1, (int) getpid())) + return FALSE; + } +} -- cgit