Add fork_exec() function

Can be used to execute an external program. Provides the possibility to
optionally create a pipe to the new process.

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
Lukas Fleischer 2011-07-01 15:25:10 +02:00
parent 003431880e
commit 6e2b00096d
2 changed files with 72 additions and 0 deletions

View File

@ -879,6 +879,7 @@ int parse_date (char *, enum datefmt, int *, int *, int *,
void str_toupper (char *); void str_toupper (char *);
void file_close (FILE *, const char *); void file_close (FILE *, const char *);
void psleep (unsigned); void psleep (unsigned);
int fork_exec (int *, int *, const char *, char *const *);
/* vars.c */ /* vars.c */
extern int col, row; extern int col, row;

View File

@ -42,6 +42,7 @@
#include <ctype.h> #include <ctype.h>
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include "calcurse.h" #include "calcurse.h"
@ -718,3 +719,73 @@ psleep (unsigned secs)
for (unslept = sleep (secs); unslept; unslept = sleep (unslept)) for (unslept = sleep (secs); unslept; unslept = sleep (unslept))
; ;
} }
/*
* Fork and execute an external process.
*
* If pfdin and/or pfdout point to a valid address, a pipe is created and the
* appropriate file descriptors are written to pfdin/pfdout.
*/
int
fork_exec (int *pfdin, int *pfdout, const char *path, char *const *arg)
{
int pin[2], pout[2];
int pid;
if (pfdin && (pipe (pin) == -1))
return 0;
if (pfdout && (pipe (pout) == -1))
return 0;
if ((pid = fork ()) == 0)
{
if (pfdout)
{
if (dup2 (pout[0], STDIN_FILENO) < 0)
_exit (127);
close (pout[0]);
close (pout[1]);
}
if (pfdin)
{
if (dup2 (pin[1], STDOUT_FILENO) < 0)
_exit (127);
close (pin[0]);
close (pin[1]);
}
execvp (path, arg);
_exit (127);
}
else
{
if (pfdin)
close (pin[1]);
if (pfdout)
close (pout[0]);
if (pid > 0)
{
if (pfdin)
{
fcntl (pin[0], F_SETFD, FD_CLOEXEC);
*pfdin = pin[0];
}
if (pfdout)
{
fcntl (pout[1], F_SETFD, FD_CLOEXEC);
*pfdout = pout[1];
}
}
else
{
if (pfdin)
close (pin[0]);
if (pfdout)
close (pout[1]);
return 0;
}
}
return pid;
}