From 58f2aefece69e57be0d320027163417a3a11c2f9 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. (cherry picked from commit 80f101cec6b91b3806c3d79c5f41b440749462f8) --- src/core/audio/AudioAlsa.cpp | 27 +++++++++++++++++++++------ src/core/audio/AudioOss.cpp | 4 ++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/core/audio/AudioAlsa.cpp b/src/core/audio/AudioAlsa.cpp index 3f11e919d..7e2567b0a 100644 --- a/src/core/audio/AudioAlsa.cpp +++ b/src/core/audio/AudioAlsa.cpp @@ -46,9 +46,9 @@ AudioAlsa::AudioAlsa( bool & _success_ful, mixer * _mixer ) : m_handle( NULL ), m_hwParams( NULL ), m_swParams( NULL ), - m_convertEndian( FALSE ) + m_convertEndian( false ) { - _success_ful = FALSE; + _success_ful = false; int err; @@ -78,7 +78,22 @@ AudioAlsa::AudioAlsa( bool & _success_ful, mixer * _mixer ) : return; } - _success_ful = TRUE; + // 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; } @@ -236,8 +251,8 @@ void AudioAlsa::run() int outbuf_pos = 0; int pcmbuf_size = m_periodSize * channels(); - bool quit = FALSE; - while( quit == FALSE ) + bool quit = false; + while( quit == false ) { int_sample_t * ptr = pcmbuf; int len = pcmbuf_size; @@ -249,7 +264,7 @@ void AudioAlsa::run() const fpp_t frames = getNextBuffer( temp ); if( !frames ) { - quit = TRUE; + quit = true; memset( ptr, 0, len * sizeof( int_sample_t ) ); break; diff --git a/src/core/audio/AudioOss.cpp b/src/core/audio/AudioOss.cpp index 84ce8b123..c314de939 100644 --- a/src/core/audio/AudioOss.cpp +++ b/src/core/audio/AudioOss.cpp @@ -97,6 +97,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() *