From 80f101cec6b91b3806c3d79c5f41b440749462f8 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Tue, 18 Aug 2009 15:27:43 +0200 Subject: [PATCH] AudioAlsa/AudioOss: set FD_CLOEXEC flag for file descriptors Per default child processes inherit all file descriptors of their parent process. This applied for file descriptors pointing to sound devices as well. Reopening sound devices while e.g. a ZynAddSubFX process was running always failed due to this "feature". By manually setting the FD_CLOEXEC flag for the sound device file descriptors they do not get inherited by child processes anymore. --- src/core/audio/AudioAlsa.cpp | 15 +++++++++++++++ src/core/audio/AudioOss.cpp | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/src/core/audio/AudioAlsa.cpp b/src/core/audio/AudioAlsa.cpp index 437bd8963..145bf88a7 100644 --- a/src/core/audio/AudioAlsa.cpp +++ b/src/core/audio/AudioAlsa.cpp @@ -79,6 +79,21 @@ AudioAlsa::AudioAlsa( bool & _success_ful, mixer * _mixer ) : return; } + // set FD_CLOEXEC flag for all file descriptors so forked processes + // do not inherit them + struct pollfd * ufds; + int count = snd_pcm_poll_descriptors_count( m_handle ); + ufds = new pollfd[count]; + snd_pcm_poll_descriptors( m_handle, ufds, count ); + for( int i = 0; i < qMax( 3, count ); ++i ) + { + const int fd = ( i >= count ) ? ufds[0].fd+i : ufds[i].fd; + int oldflags = fcntl( fd, F_GETFD, 0 ); + if( oldflags < 0 ) + continue; + oldflags |= FD_CLOEXEC; + fcntl( fd, F_SETFD, oldflags ); + } _success_ful = true; } diff --git a/src/core/audio/AudioOss.cpp b/src/core/audio/AudioOss.cpp index 049b0ebb9..a385c4692 100644 --- a/src/core/audio/AudioOss.cpp +++ b/src/core/audio/AudioOss.cpp @@ -98,6 +98,10 @@ AudioOss::AudioOss( bool & _success_ful, mixer * _mixer ) : return; } + // set FD_CLOEXEC flag for file descriptor so forked processes + // do not inherit it + fcntl( m_audioFD, F_SETFD, fcntl( m_audioFD, F_GETFD ) | FD_CLOEXEC ); + int frag_spec; for( frag_spec = 0; static_cast( 0x01 << frag_spec ) < getMixer()->framesPerPeriod() * channels() *