use nonblocking fgets instead of fork in cmd_extscript
authorpk910 <philipp@zoelle1.de>
Sun, 11 Dec 2011 06:00:33 +0000 (07:00 +0100)
committerpk910 <philipp@zoelle1.de>
Sun, 11 Dec 2011 06:03:50 +0000 (07:03 +0100)
src/cmd_neonserv_extscript.c

index 1d97ac0fc576bb5bafa1adbfdd62c8802565713e..67374d15668560da89f828ff930925c1f8ac990c 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "cmd_neonserv.h"
+#include <fcntl.h>
 
 /*
 * argv[0]      'toys' if it's a toy command (check if toys are enabled)
 * 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);
+}
+
+
+