mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Hooks
- First pass at a portable 'popen' implementation. Thanks to Wim.
This commit is contained in:
parent
b989da7259
commit
f2a545bc25
1 changed files with 55 additions and 27 deletions
|
@ -24,14 +24,17 @@
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// If <iostream> is included, put it after <stdio.h>, because it includes
|
|
||||||
// <stdio.h>, and therefore would ignore the _WITH_GETLINE.
|
|
||||||
#include <cmake.h>
|
#include <cmake.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
// If <iostream> is included, put it after <stdio.h>, because it includes
|
||||||
|
// <stdio.h>, and therefore would ignore the _WITH_GETLINE.
|
||||||
#ifdef FREEBSD
|
#ifdef FREEBSD
|
||||||
#define _WITH_GETLINE
|
#define _WITH_GETLINE
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <Hooks.h>
|
#include <Hooks.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
|
@ -330,34 +333,59 @@ int Hooks::execute (
|
||||||
const std::string& input,
|
const std::string& input,
|
||||||
std::string& output)
|
std::string& output)
|
||||||
{
|
{
|
||||||
int status = -1;
|
// TODO Improve error hnadling.
|
||||||
FILE* fp = popen (command.c_str (), "r+");
|
// TODO Check errors.
|
||||||
if (fp)
|
|
||||||
|
int pin[2], pout[2];
|
||||||
|
pipe (pin);
|
||||||
|
pipe (pout);
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (!pid)
|
||||||
{
|
{
|
||||||
// Write input to fp.
|
// This is only reached in the child
|
||||||
if (input != "" &&
|
dup2 (pin[0], STDIN_FILENO);
|
||||||
input != "\n")
|
dup2 (pout[1], STDOUT_FILENO);
|
||||||
{
|
if (!execl (command.c_str (), command.c_str (), (char*) NULL))
|
||||||
fputs (input.c_str (), fp);
|
exit (1);
|
||||||
fflush (fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read output from fp.
|
|
||||||
output = "";
|
|
||||||
char* line = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
while (getline (&line, &len, fp) != -1)
|
|
||||||
{
|
|
||||||
output += line;
|
|
||||||
free (line);
|
|
||||||
line = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fflush (fp);
|
|
||||||
status = pclose (fp);
|
|
||||||
context.debug (format ("Hooks::execute {1} (status {2})", command, status));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is only reached in the parent
|
||||||
|
close (pin[0]);
|
||||||
|
close (pout[1]);
|
||||||
|
|
||||||
|
// Write input to fp.
|
||||||
|
FILE* pinf = fdopen (pin[1], "w");
|
||||||
|
if (input != "" &&
|
||||||
|
input != "\n")
|
||||||
|
{
|
||||||
|
fputs (input.c_str (), pinf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (pinf);
|
||||||
|
close (pin[1]);
|
||||||
|
|
||||||
|
// Read output from fp.
|
||||||
|
output = "";
|
||||||
|
char* line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
FILE* poutf = fdopen(pout[0], "r");
|
||||||
|
while (getline (&line, &len, poutf) != -1)
|
||||||
|
{
|
||||||
|
output += line;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line)
|
||||||
|
free (line);
|
||||||
|
fclose (poutf);
|
||||||
|
close (pout[0]);
|
||||||
|
|
||||||
|
int status = -1;
|
||||||
|
wait (&status);
|
||||||
|
if (WIFEXITED (status))
|
||||||
|
status = WEXITSTATUS (status);
|
||||||
|
|
||||||
|
context.debug (format ("Hooks::execute {1} (status {2})", command, status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue