stubs and comments for implementing pipes to child wrappers

SVN revision: 17876
This commit is contained in:
Carsten Haitzler 2005-10-24 08:53:50 +00:00
parent 0be8326d89
commit 909a56813f
4 changed files with 139 additions and 13 deletions

View File

@ -55,14 +55,15 @@
extern "C" {
#endif
#define ECORE_EVENT_NONE 0
#define ECORE_EVENT_EXE_EXIT 1 /**< Spawned Exe has exit event */
#define ECORE_EVENT_SIGNAL_USER 2 /**< User signal event */
#define ECORE_EVENT_SIGNAL_HUP 3 /**< Hup signal event */
#define ECORE_EVENT_SIGNAL_EXIT 4 /**< Exit signal event */
#define ECORE_EVENT_SIGNAL_POWER 5 /**< Power signal event */
#define ECORE_EVENT_NONE 0
#define ECORE_EVENT_EXE_EXIT 1 /**< Spawned Exe has exit event */
#define ECORE_EVENT_SIGNAL_USER 2 /**< User signal event */
#define ECORE_EVENT_SIGNAL_HUP 3 /**< Hup signal event */
#define ECORE_EVENT_SIGNAL_EXIT 4 /**< Exit signal event */
#define ECORE_EVENT_SIGNAL_POWER 5 /**< Power signal event */
#define ECORE_EVENT_SIGNAL_REALTIME 6 /**< Realtime signal event */
#define ECORE_EVENT_COUNT 7
#define ECORE_EVENT_EXE_DATA 7 /**< Data from a child process */
#define ECORE_EVENT_COUNT 8
#ifndef _ECORE_PRIVATE_H
enum _Ecore_Fd_Handler_Flags
@ -73,6 +74,14 @@ extern "C" {
};
typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
enum _Ecore_Exe_Flags /* FIXME: flags for executing a child with its stdin and/or stdout piped back */
{
ECORE_EXE_PIPE_READ = 1, /**< Exe Pipe Read mask */
ECORE_EXE_PIPE_WRITE = 2, /**< Exe Pipe Write mask */
ECORE_EXE_PIPE_READ_LINE_BUFFERED = 4 /**< Reads are buffered until a newline and delivered 1 event per line */
};
typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags;
#ifndef WIN32
typedef void Ecore_Exe; /**< A handle for spawned processes */
#endif
@ -86,12 +95,13 @@ extern "C" {
typedef void Ecore_Event; /**< A handle for an event */
typedef void Ecore_Animator; /**< A handle for animators */
#endif
typedef struct _Ecore_Event_Exe_Exit Ecore_Event_Exe_Exit; /**< Spawned Exe exit event */
typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< User signal event */
typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */
typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< Exit signal event */
typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< Power signal event */
typedef struct _Ecore_Event_Exe_Exit Ecore_Event_Exe_Exit; /**< Spawned Exe exit event */
typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< User signal event */
typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */
typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< Exit signal event */
typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< Power signal event */
typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; /**< Realtime signal event */
typedef struct _Ecore_Event_Exe_Data Ecore_Event_Exe_Data; /**< Data from a child process */
#ifndef WIN32
struct _Ecore_Event_Exe_Exit /** Process exit event */
@ -156,6 +166,15 @@ extern "C" {
#endif
};
#ifndef WIN32
struct _Ecore_Event_Exe_Data /** Data from a child process event */
{
Ecore_Exe *exe; /**< The handle to the process */
void *data; /**< the raw binary data from the child process that was recieved */
int size; /**< the size of this data in bytes */
};
#endif
EAPI int ecore_init(void);
EAPI int ecore_shutdown(void);
@ -176,6 +195,8 @@ extern "C" {
#ifndef WIN32
EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, const void *data);
EAPI Ecore_Exe *ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data);
EAPI int ecore_exe_pipe_write(Ecore_Exe *exe, void *data, int size);
EAPI void *ecore_exe_free(Ecore_Exe *exe);
EAPI pid_t ecore_exe_pid_get(Ecore_Exe *exe);
EAPI void ecore_exe_tag_set(Ecore_Exe *exe, const char *tag);

View File

@ -52,6 +52,92 @@ ecore_exe_run(const char *exe_cmd, const void *data)
return NULL;
}
/**
* Spawns a child process with its stdin/out available for communication.
*
* This function does the same thing as ecore_exe_run(), but also makes the
* standard in and/or out from the child process available for reading or
* writing. To write use ecore_exe_pipe_write(). To read listen to
* ECORE_EVENT_EXE_DATA events (set up a handler). Ecore may buffer read data
* until a newline character if asked to wit the @p flags. All data will be
* included in the events (newlines will not be stripped). This will only
* happen if the process is run with ECORE_EXE_PIPE_READ enabled in the flags.
*
* @param exe_cmd The command to run with @c /bin/sh.
* @param flags The flag parameters for how to deal with inter-process I/O
* @param data Data to attach to the returned process handle.
* @return A process handle to the spawned process.
* @ingroup Ecore_Exe_Basic_Group
*/
Ecore_Exe *
ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
{
Ecore_Exe *exe;
pid_t pid;
/* FIXME:
* if flags does not have read or write in them - just execute using
* ecore_exe_run() as normal.
* pipe() to creeate pipes (as necessary accoring to flags)
* in child close() parent side of pipes
* in child dup2() stdin, stdout (according to flags as necessary)
* in parent (here) close() child side of pipes
* set up fd's in ecore_exe struct FIXME - add to struct
* set up fd handler in ecore_exe struct
* see ecore_con for code and examples on this (fd's there are to a socket
* but otherwise work the same as here). the ECORE_EVENT_EXE_EXIT event
* aces like the client del event from ecore_con - signalling that the
* connection is closed. once this event has been handled the child
* ecore_exe struct is freed automatically and is no longer valid.
*/
if (!exe_cmd) return NULL;
pid = fork();
if (pid)
{
exe = calloc(1, sizeof(Ecore_Exe));
if (!exe)
{
kill(pid, SIGKILL);
return NULL;
}
ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
exe->pid = pid;
exe->data = (void *)data;
exes = _ecore_list2_append(exes, exe);
return exe;
}
setsid();
execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL);
exit(127);
return NULL;
}
/**
* Writes data to the given child process which it recieves on stdin.
*
* This function writes to a child processes standard in, with unlimited
* buffering. This call will never block. It may fail if the system runs out
* of memory.
*
* @param exe The child process to write to
* @param data The data to write
* @param size The size of the data to write, in bytes
* @return 1 if successful, 0 on failure.
* @ingroup Ecore_Exe_Basic_Group
*/
int
ecore_exe_pipe_write(Ecore_Exe *exe, void *data, int size)
{
/* FIXME: add data to buffer and flag fd handlers to wake up when write
* to child fd is available, and when it is, flush as much data as possible
* at that time (much like ecore_con). this means the parent is mallocing
* its own write buffer in process space - giving us potentially huge
* buffers, so synchronisation needs to be done at a higher level here as
* buffers could just get huge
*/
return 0;
}
/**
* Sets the string tag for the given process handle
*
@ -292,7 +378,8 @@ void *
_ecore_exe_free(Ecore_Exe *exe)
{
void *data;
/* FIXME: close fdhanlders and free buffers if they exist */
data = exe->data;
exes = _ecore_list2_remove(exes, exe);
ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);

View File

@ -116,6 +116,13 @@ enum _Ecore_Fd_Handler_Flags
ECORE_FD_ERROR = 4
};
typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
enum _Ecore_Exe_Flags
{
ECORE_EXE_PIPE_READ = 1,
ECORE_EXE_PIPE_WRITE = 2,
ECORE_EXE_PIPE_READ_LINE_BUFFERED = 4
};
typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags;
#ifndef WIN32
typedef struct _Ecore_Exe Ecore_Exe;
@ -138,6 +145,11 @@ struct _Ecore_Exe
pid_t pid;
void *data;
char *tag;
Ecore_Fd_Handler *fd_handler; /* FIXME: the fd_handler to handle read/write to child - if this was used, or NULL if not */
void *data_buf; /* FIXME: a data buffer for data to write to the child - realloced as needed for more data and flushed when the fd handler says writes are possible */
int data_size; /* FIXME: the size in bytes of the data buffer */
int child_fd_write; /* FIXME: fd to write TO to send data to the child */
int child_fd_read; /* FIXME: fd to read FROM whne child has send us (parent) data */
};
#endif

View File

@ -161,6 +161,12 @@ _ecore_signal_call(void)
{
Ecore_Event_Exe_Exit *e;
/* FIXME: If this process is set to read from the child, DELAY
* the exe event until the pipe from the child dies and reports
* errors - THEN report and exe - so store this exe value in the
* ecore_exe struct waiting for the read fd to die then report
* final read data, THEN this exit event
*/
e = _ecore_event_exe_exit_new();
if (e)
{