From 358961c4bf4176e910bce5f74f83aa17fce7f327 Mon Sep 17 00:00:00 2001 From: pk910 Date: Sun, 11 Dec 2011 07:00:33 +0100 Subject: [PATCH] use nonblocking fgets instead of fork in cmd_extscript --- src/cmd_neonserv_extscript.c | 78 +++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/cmd_neonserv_extscript.c b/src/cmd_neonserv_extscript.c index 1d97ac0..67374d1 100644 --- a/src/cmd_neonserv_extscript.c +++ b/src/cmd_neonserv_extscript.c @@ -16,6 +16,7 @@ */ #include "cmd_neonserv.h" +#include /* * argv[0] 'toys' if it's a toy command (check if toys are enabled) @@ -23,6 +24,16 @@ * argv[argc-1] all arguments passed to the command */ +static TIMEQ_CALLBACK(neonserv_cmd_extscript_callback); + +struct neonserv_cmd_extscript_cache { + struct ClientSocket *client, *textclient; + struct UserNode *user; + struct ChanNode *chan; + int answere_channel; + FILE *pipe; +}; + CMD_BIND(neonserv_cmd_extscript) { int i, j; char *args[MAXNUMPARAMS]; @@ -111,38 +122,41 @@ CMD_BIND(neonserv_cmd_extscript) { } command[commandpos] = '\0'; //we should now have a valid command - struct ClientSocket *textbot = getTextBot(); - #ifndef WIN32 - pid_t pID = fork(); - if (pID == 0) { //We're the child process :D - pID = fork(); - if(pID < 0) exit(EXIT_FAILURE); - if(pID != 0) exit(EXIT_SUCCESS); - #endif - FILE *fp; - fp = popen(command, "r"); - if (fp) { - char *a; - while (fgets(command, 1024, fp) != NULL) { - if((a = strchr(command, '\n'))) - *a = '\0'; - if(answere_channel) - putsock(client, "PRIVMSG %s :%s", chan->name, command); - else - reply(textbot, user, "%s", command); - } - pclose(fp); - } else { - reply(getTextBot(), user, "internal bot error - please contact an administrator!"); - } - #ifndef WIN32 - exit(EXIT_FAILURE); - } else if (pID < 0) { - reply(getTextBot(), user, "internal bot error - please contact an administrator!"); - } else { - //parent bot - continue program - wait(NULL); + + struct neonserv_cmd_extscript_cache *cache = malloc(sizeof(*cache)); + if (!cache) { + perror("malloc() failed"); + return; } - #endif + cache->client = client; + cache->textclient = getTextBot(); + cache->user = user; + cache->chan = chan; + cache->answere_channel = answere_channel; + cache->pipe = popen(command, "r"); + fcntl(fileno(cache->pipe), F_SETFL, O_NONBLOCK); + timeq_add(1, neonserv_cmd_extscript_callback, cache); } +static TIMEQ_CALLBACK(neonserv_cmd_extscript_callback) { + struct neonserv_cmd_extscript_cache *cache = data; + char command[512]; + char *a; + if(feof(cache->pipe)) { + pclose(cache->pipe); + free(cache); + return; + } + while (fgets(command, 512, cache->pipe) != NULL) { + if((a = strchr(command, '\n'))) + *a = '\0'; + if(cache->answere_channel) + putsock(cache->client, "PRIVMSG %s :%s", cache->chan->name, command); + else + reply(cache->textclient, cache->user, "%s", command); + } + timeq_add(1, neonserv_cmd_extscript_callback, cache); +} + + + -- 2.20.1