00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <unistd.h>
00018 #include <stdlib.h>
00019 #include <stdarg.h>
00020 #include <sys/wait.h>
00021
00022 #include "exec.h"
00023 #include "mem.h"
00024 #include "printf.h"
00025 #include "str.h"
00026 #include "strtok.h"
00027
00028 int exec_fork_pipe(char **out, const char *fmt, ...)
00029 {
00030 va_list ap;
00031 va_start(ap, fmt);
00032
00033 char *cmd;
00034
00035 if (_lucid_vasprintf(&cmd, fmt, ap) == -1) {
00036 va_end(ap);
00037 return -1;
00038 }
00039
00040 va_end(ap);
00041
00042 strtok_t _st, *st = &_st;
00043
00044 if (!strtok_init_str(st, cmd, " ", 0)) {
00045 mem_free(cmd);
00046 return -1;
00047 }
00048
00049 mem_free(cmd);
00050
00051 int argc = strtok_count(st);
00052 char **argv = mem_alloc((argc + 1) * sizeof(char *));
00053
00054 if (!argv) {
00055 strtok_free(st);
00056 return -1;
00057 }
00058
00059 if (strtok_toargv(st, argv) < 1) {
00060 mem_free(argv);
00061 strtok_free(st);
00062 return -1;
00063 }
00064
00065 int outfds[2];
00066
00067 if (pipe(outfds) == -1) {
00068 mem_free(argv);
00069 strtok_free(st);
00070 return -1;
00071 }
00072
00073 pid_t pid;
00074 int status;
00075
00076 switch ((pid = fork())) {
00077 case -1:
00078 mem_free(argv);
00079 strtok_free(st);
00080 close(outfds[0]);
00081 close(outfds[1]);
00082 return -1;
00083
00084 case 0:
00085 usleep(200);
00086
00087 close(outfds[0]);
00088
00089 dup2(outfds[1], STDOUT_FILENO);
00090 dup2(outfds[1], STDERR_FILENO);
00091
00092 execvp(argv[0], argv);
00093
00094 mem_free(argv);
00095 strtok_free(st);
00096
00097
00098 exit(1);
00099
00100 default:
00101 mem_free(argv);
00102 strtok_free(st);
00103
00104 close(outfds[1]);
00105
00106 if (out && str_readfile(outfds[0], out) == -1)
00107 return -1;
00108
00109 close(outfds[0]);
00110
00111 if (waitpid(pid, &status, 0) == -1)
00112 return -1;
00113 }
00114
00115 return status;
00116 }