commit 3cf2e4b4f1912d18772a0fa476d4671c25ca2ea4 Author: coolo Date: Mon Mar 2 09:47:26 2009 +0000 more fixes from Michal Schmidt: - don't leak file descriptor to create-env - don't use the shell to call simple commands git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/icecream@934044 283d02a7-25f6-0310-bc7c-ecb5cbfe19da diff --git a/daemon/environment.cpp b/daemon/environment.cpp index fd38f8e..9dc2831 100644 --- a/daemon/environment.cpp +++ b/daemon/environment.cpp @@ -142,40 +142,48 @@ static void list_target_dirs( const string ¤t_target, const string &target closedir( envdir ); } -bool cleanup_cache( const string &basedir ) +/* Returns true if the child exited with success */ +static bool exec_and_wait( const char *const argv[] ) { - flush_debug(); pid_t pid = fork(); - if ( pid ) - { - int status = 0; + if ( pid == -1 ) { + log_perror("fork"); + return false; + } + if ( pid ) { + // parent + int status; while ( waitpid( pid, &status, 0 ) < 0 && errno == EINTR ) ; + return WIFEXITED(status) && WEXITSTATUS(status) == 0; + } + // child + _exit(execv(argv[0], const_cast(argv))); +} - if ( mkdir( basedir.c_str(), 0755 ) && errno != EEXIST ) { - if ( errno == EPERM ) - log_error() << "permission denied on mkdir " << basedir << endl; - else - log_perror( "mkdir in cleanup_cache() failed" ); - return false; - } - chown( basedir.c_str(), 0, 0 ); - chmod( basedir.c_str(), 0755 ); +bool cleanup_cache( const string &basedir ) +{ + flush_debug(); - return WIFEXITED(status); - } - // else - char **argv; - argv = new char*[5]; - argv[0] = strdup( "/bin/rm" ); - argv[1] = strdup( "-rf" ); - argv[2] = strdup( "--" ); // make sure it ends with '/' to not fall into symlink traps string bdir = basedir + '/'; - argv[3] = strdup( bdir.c_str() ); - argv[4] = NULL; + const char *const argv[] = { + "/bin/rm", "-rf", "--", bdir.c_str(), NULL + }; - _exit(execv(argv[0], argv)); + bool ret = exec_and_wait( argv ); + + if ( mkdir( basedir.c_str(), 0755 ) && errno != EEXIST ) { + if ( errno == EPERM ) + log_error() << "permission denied on mkdir " << basedir << endl; + else + log_perror( "mkdir in cleanup_cache() failed" ); + return false; + } + chown( basedir.c_str(), 0, 0 ); + chmod( basedir.c_str(), 0755 ); + + return ret; } Environments available_environmnents(const string &basedir) @@ -259,7 +267,10 @@ size_t setup_env_cache(const string &basedir, string &native_environment, uid_t _exit(1); } - if ( system( BINDIR "/icecc --build-native" ) ) { + const char *const argv[] = { + BINDIR "/icecc", "--build-native", NULL + }; + if ( !exec_and_wait( argv ) ) { log_error() << BINDIR "/icecc --build-native failed\n"; _exit(1); } diff --git a/services/comm.cpp b/services/comm.cpp index 47e7304..5ffb790 100644 --- a/services/comm.cpp +++ b/services/comm.cpp @@ -987,6 +987,12 @@ open_send_broadcast (void) return -1; } + if (fcntl (ask_fd, F_SETFD, FD_CLOEXEC) < 0) + { + log_perror("open_send_broadcast fcntl"); + close (ask_fd); + return -1; + } int optval = 1; if (setsockopt (ask_fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) {