From abed344501d93bc1437ec8bcb94f154fe2bdfbaf Mon Sep 17 00:00:00 2001 From: satbaby Date: Wed, 22 Aug 2012 09:37:46 +0200 Subject: [PATCH] plugins.cpp: use popen2 with vfork for script plugins --- src/gui/plugins.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/gui/plugins.cpp b/src/gui/plugins.cpp index de8b7fbb0..d04e0b9a5 100644 --- a/src/gui/plugins.cpp +++ b/src/gui/plugins.cpp @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include #include @@ -313,6 +315,53 @@ void CPlugins::startPlugin(const char * const name) else printf("[CPlugins] could not find %s\n", name); +} + #include + +FILE* popen2( pid_t& pid, const char *cmdstring, const char *type) { + int pfd[2] ={-1,-1}; + FILE *fp = NULL; + + /* only allow "r" or "w" */ + if ((type[0] != 'r' && type[0] != 'w') || type[1] != 0) { + errno = EINVAL; /* required by POSIX */ + return(NULL); + } + + if (pipe(pfd) < 0) + return(NULL); /* errno set by pipe() */ + + if ((pid = vfork()) < 0) { + return(NULL); /* errno set by vfork() */ + } else if (pid == 0) { /* child */ + if (*type == 'r') { + close(pfd[0]); + if (pfd[1] != STDOUT_FILENO) { + dup2(pfd[1], STDOUT_FILENO); + close(pfd[1]); + } + } else { + close(pfd[1]); + if (pfd[0] != STDIN_FILENO) { + dup2(pfd[0], STDIN_FILENO); + close(pfd[0]); + } + } + execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); + exit(0); + } + + /* parent continues... */ + if (*type == 'r') { + close(pfd[1]); + if ((fp = fdopen(pfd[0], type)) == NULL) + return(NULL); + } else { + close(pfd[0]); + if ((fp = fdopen(pfd[1], type)) == NULL) + return(NULL); + } + return(fp); } void CPlugins::startScriptPlugin(int number) @@ -325,7 +374,8 @@ void CPlugins::startScriptPlugin(int number) script, plugin_list[number].cfgfile.c_str()); return; } - FILE *f = popen(script,"r"); + pid_t pid = 0; + FILE *f = popen2(pid,script,"r"); if (f != NULL) { char *output=NULL; @@ -335,6 +385,7 @@ void CPlugins::startScriptPlugin(int number) { scriptOutput += output; } + kill(pid, SIGINT ); pclose(f); if(output) free(output);