|
@@ -6,8 +6,12 @@
|
|
*/
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
|
|
+#include <unistd.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <assert.h>
|
|
|
|
+#include <signal.h>
|
|
|
|
+#include <sys/types.h>
|
|
|
|
+#include <sys/wait.h>
|
|
|
|
|
|
#include "private.h"
|
|
#include "private.h"
|
|
|
|
|
|
@@ -15,8 +19,17 @@
|
|
bool_t clish_script_callback(const clish_shell_t * this,
|
|
bool_t clish_script_callback(const clish_shell_t * this,
|
|
const clish_command_t * cmd, const char *script)
|
|
const clish_command_t * cmd, const char *script)
|
|
{
|
|
{
|
|
- FILE *wpipe;
|
|
|
|
const char * shebang = NULL;
|
|
const char * shebang = NULL;
|
|
|
|
+ int pipefd[2];
|
|
|
|
+ pid_t cpid;
|
|
|
|
+ char buf;
|
|
|
|
+ int res;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ struct sigaction sig_old_int;
|
|
|
|
+ struct sigaction sig_old_quit;
|
|
|
|
+ struct sigaction sig_new;
|
|
|
|
+ sigset_t sig_set;
|
|
|
|
|
|
assert(this);
|
|
assert(this);
|
|
assert(cmd);
|
|
assert(cmd);
|
|
@@ -24,19 +37,65 @@ bool_t clish_script_callback(const clish_shell_t * this,
|
|
return BOOL_TRUE;
|
|
return BOOL_TRUE;
|
|
|
|
|
|
shebang = clish_command__get_shebang(cmd);
|
|
shebang = clish_command__get_shebang(cmd);
|
|
|
|
+ if (!shebang)
|
|
|
|
+ shebang = clish_shell__get_default_shebang(this);
|
|
|
|
+ assert(shebang);
|
|
#ifdef DEBUG
|
|
#ifdef DEBUG
|
|
- if (shebang)
|
|
+ fprintf(stderr, "SHEBANG: #!%s\n", shebang);
|
|
- fprintf(stderr, "SHEBANG: #!%s\n", shebang);
|
|
+ fprintf(stderr, "SCRIPT: %s\n", script);
|
|
- fprintf(stderr, "SYSTEM: %s\n", script);
|
|
|
|
#endif
|
|
#endif
|
|
- if (!shebang)
|
|
+
|
|
- return (0 == system(script)) ? BOOL_TRUE : BOOL_FALSE;
|
|
+ if (pipe(pipefd) < 0)
|
|
-
|
|
+ return BOOL_FALSE;
|
|
- wpipe = popen(shebang, "w");
|
|
+
|
|
- if (!wpipe)
|
|
+
|
|
|
|
+ sigemptyset(&sig_set);
|
|
|
|
+ sig_new.sa_flags = 0;
|
|
|
|
+ sig_new.sa_mask = sig_set;
|
|
|
|
+ sig_new.sa_handler = SIG_IGN;
|
|
|
|
+ sigaction(SIGINT, &sig_new, &sig_old_int);
|
|
|
|
+ sigaction(SIGQUIT, &sig_new, &sig_old_quit);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ cpid = fork();
|
|
|
|
+ if (cpid == -1) {
|
|
|
|
+ close(pipefd[0]);
|
|
|
|
+ close(pipefd[1]);
|
|
return BOOL_FALSE;
|
|
return BOOL_FALSE;
|
|
- fwrite(script, strlen(script) + 1, 1, wpipe);
|
|
+ }
|
|
- return (0 == pclose(wpipe)) ? BOOL_TRUE : BOOL_FALSE;
|
|
+
|
|
|
|
+
|
|
|
|
+ if (cpid == 0) {
|
|
|
|
+ FILE *wpipe;
|
|
|
|
+ int retval;
|
|
|
|
+ close(pipefd[0]);
|
|
|
|
+ dup2(pipefd[1], STDOUT_FILENO);
|
|
|
|
+ wpipe = popen(shebang, "w");
|
|
|
|
+ close(pipefd[1]);
|
|
|
|
+ if (!wpipe)
|
|
|
|
+ _exit(-1);
|
|
|
|
+ fwrite(script, strlen(script) + 1, 1, wpipe);
|
|
|
|
+ retval = pclose(wpipe);
|
|
|
|
+ _exit(WEXITSTATUS(retval));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ close(pipefd[1]);
|
|
|
|
+ while (read(pipefd[0], &buf, 1) > 0)
|
|
|
|
+ write(fileno(clish_shell__get_ostream(this)), &buf, 1);
|
|
|
|
+ close(pipefd[0]);
|
|
|
|
+ waitpid(cpid, &res, 0);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ sigaction(SIGINT, &sig_old_int, NULL);
|
|
|
|
+ sigaction(SIGQUIT, &sig_old_quit, NULL);
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG
|
|
|
|
+ fprintf(stderr, "RETCODE: %d\n", WEXITSTATUS(res));
|
|
|
|
+#endif
|
|
|
|
+ return (0 == res) ? BOOL_TRUE : BOOL_FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|