53 lines
1.0 KiB
C
53 lines
1.0 KiB
C
#define _POSIX_C_SOURCE 200112L
|
|
|
|
#include <Xmd/Exec.h>
|
|
#include <Xmd/Buffer.h>
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
FILE *XmdVaPipedExecPath (ConstString file, pid_t *child, String mode, ...) {
|
|
XmdBuffer *buffer = XmdBufferNew(String);
|
|
va_list argList;
|
|
va_start(argList, mode);
|
|
|
|
while (1) {
|
|
String arg = va_arg(argList, String);
|
|
if (arg == NULL) break;
|
|
XmdBufferPush(buffer, &arg);
|
|
}
|
|
|
|
va_end(argList);
|
|
String *args = XmdBufferBreak(buffer);
|
|
FILE* pipe = XmdPipedExecPath(file, child, mode, args);
|
|
XtFree((char *)(args));
|
|
return pipe;
|
|
}
|
|
|
|
FILE *XmdPipedExecPath (
|
|
ConstString file, pid_t *child, String mode,
|
|
const String argv[]
|
|
) {
|
|
int pipes[2];
|
|
pipe(pipes);
|
|
|
|
pid_t pid = fork();
|
|
switch (pid) {
|
|
case -1: /* fail */
|
|
return NULL;
|
|
case 0: /* child */
|
|
dup2(pipes[1], STDOUT_FILENO);
|
|
close(pipes[0]);
|
|
close(pipes[1]);
|
|
execvp(file, argv);
|
|
exit(EXIT_FAILURE);
|
|
return NULL;
|
|
default: /* parent */
|
|
close(pipes[1]);
|
|
*child = pid;
|
|
return fdopen(pipes[0], mode);
|
|
}
|
|
}
|