ecore_exe for Windows.
Not complete yet but it executes a command and kills it TODO: pipes SVN revision: 43112
This commit is contained in:
parent
e59c99485c
commit
b7bd2998c4
|
@ -120,9 +120,7 @@ extern "C" {
|
|||
};
|
||||
typedef enum _Ecore_Poller_Type Ecore_Poller_Type;
|
||||
|
||||
#ifndef _WIN32
|
||||
typedef void Ecore_Exe; /**< A handle for spawned processes */
|
||||
#endif
|
||||
typedef void Ecore_Timer; /**< A handle for timers */
|
||||
typedef void Ecore_Idler; /**< A handle for idlers */
|
||||
typedef void Ecore_Idle_Enterer; /**< A handle for idle enterers */
|
||||
|
@ -246,7 +244,6 @@ extern "C" {
|
|||
EAPI void *ecore_event_current_event_get(void);
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
EAPI void ecore_exe_run_priority_set(int pri);
|
||||
EAPI int ecore_exe_run_priority_get(void);
|
||||
EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, const void *data);
|
||||
|
@ -270,7 +267,6 @@ extern "C" {
|
|||
EAPI void ecore_exe_kill(Ecore_Exe *exe);
|
||||
EAPI void ecore_exe_signal(Ecore_Exe *exe, int num);
|
||||
EAPI void ecore_exe_hup(Ecore_Exe *exe);
|
||||
#endif
|
||||
|
||||
EAPI Ecore_Idler *ecore_idler_add(int (*func) (void *data), const void *data);
|
||||
EAPI void *ecore_idler_del(Ecore_Idler *idler);
|
||||
|
|
|
@ -16,6 +16,7 @@ ecore_anim.c \
|
|||
ecore_app.c \
|
||||
ecore_events.c \
|
||||
ecore_exe.c \
|
||||
ecore_exe_win32.c \
|
||||
ecore_getopt.c \
|
||||
ecore_hash.c \
|
||||
ecore_idle_enterer.c \
|
||||
|
|
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include "ecore_private.h"
|
||||
#include "Ecore.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define ECORE_EXE_WIN32_TIMEOUT 3000
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ECORE_EXE_WIN32_SIGINT,
|
||||
ECORE_EXE_WIN32_SIGQUIT,
|
||||
ECORE_EXE_WIN32_SIGTERM,
|
||||
ECORE_EXE_WIN32_SIGKILL
|
||||
} Ecore_Exe_Win32_Signal;
|
||||
|
||||
struct _Ecore_Exe
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
|
||||
HANDLE process; /* CloseHandle */
|
||||
HANDLE thread;
|
||||
DWORD process_id;
|
||||
DWORD thread_id;
|
||||
void *data;
|
||||
char *tag;
|
||||
char *cmd;
|
||||
Ecore_Exe_Win32_Signal sig;
|
||||
int is_suspended : 1;
|
||||
};
|
||||
|
||||
static Ecore_Exe *exes = NULL;
|
||||
|
||||
static BOOL CALLBACK _ecore_exe_enum_windows_procedure(HWND window, LPARAM data);
|
||||
|
||||
void
|
||||
_ecore_exe_init(void)
|
||||
{
|
||||
/* ECORE_EXE_EVENT_ADD = ecore_event_type_new(); */
|
||||
/* ECORE_EXE_EVENT_DEL = ecore_event_type_new(); */
|
||||
/* ECORE_EXE_EVENT_DATA = ecore_event_type_new(); */
|
||||
/* ECORE_EXE_EVENT_ERROR = ecore_event_type_new(); */
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_exe_shutdown(void)
|
||||
{
|
||||
while (exes)
|
||||
ecore_exe_free(exes);
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_run_priority_set(int pri)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI int ecore_exe_run_priority_get(void)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, const void *data)
|
||||
{
|
||||
return ecore_exe_pipe_run(exe_cmd, 0, data);
|
||||
}
|
||||
|
||||
EAPI Ecore_Exe *ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
Ecore_Exe *exe;
|
||||
char *ret = NULL;
|
||||
|
||||
exe = calloc(1, sizeof(Ecore_Exe));
|
||||
if (!exe)
|
||||
return NULL;
|
||||
|
||||
if ((flags & ECORE_EXE_USE_SH) ||
|
||||
((ret = strrchr(exe_cmd, ".bat")) && (ret[4] == '\0')))
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
snprintf(buf, PATH_MAX, "cmd.exe /c %s", exe_cmd);
|
||||
exe->cmd = strdup(buf);
|
||||
}
|
||||
else
|
||||
exe->cmd = strdup(exe_cmd);
|
||||
|
||||
if (!exe->cmd)
|
||||
goto free_exe;
|
||||
|
||||
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
ZeroMemory(&si, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
/* si.hStdError = g_hChildStd_OUT_Wr; */
|
||||
/* si.hStdOutput = g_hChildStd_OUT_Wr; */
|
||||
/* si.hStdInput = g_hChildStd_IN_Rd; */
|
||||
/* si.dwFlags |= STARTF_USESTDHANDLES; */
|
||||
|
||||
/* FIXME: gerer la priorite */
|
||||
|
||||
if (!CreateProcess(NULL, exe->cmd, NULL, NULL, TRUE,
|
||||
0, NULL, NULL, &si, &pi))
|
||||
goto free_exe_cmd;
|
||||
|
||||
exe->thread = pi.hThread;
|
||||
exe->process_id = pi.dwProcessId;
|
||||
exe->thread_id = pi.dwThreadId;
|
||||
exe->data = (void *)data;
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
if (!(exe->process = OpenProcess(PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE | SYNCHRONIZE,
|
||||
FALSE, pi.dwProcessId)))
|
||||
goto close_thread;
|
||||
|
||||
exes = (Ecore_Exe *)eina_inlist_append(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
|
||||
return exe;
|
||||
|
||||
close_thread:
|
||||
CloseHandle(pi.hThread);
|
||||
free_exe_cmd:
|
||||
free(exe->cmd);
|
||||
free_exe:
|
||||
free(exe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI int ecore_exe_send(Ecore_Exe *exe, void *data, int size)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_close_stdin(Ecore_Exe *exe)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_auto_limits_set(Ecore_Exe *exe, int start_bytes, int end_bytes, int start_lines, int end_lines)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI Ecore_Exe_Event_Data *ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_event_data_free(Ecore_Exe_Event_Data *data)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI void *ecore_exe_free(Ecore_Exe *exe)
|
||||
{
|
||||
void *data;
|
||||
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = exe->data;
|
||||
|
||||
CloseHandle(exe->process);
|
||||
CloseHandle(exe->thread);
|
||||
free(exe->cmd);
|
||||
exes = (Ecore_Exe *) eina_inlist_remove(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
|
||||
ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);
|
||||
if (exe->tag) free(exe->tag);
|
||||
free(exe);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
EAPI pid_t ecore_exe_pid_get(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pid_get");
|
||||
return -1;
|
||||
}
|
||||
return exe->process_id;
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_tag_set(Ecore_Exe *exe, const char *tag)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_set");
|
||||
return;
|
||||
}
|
||||
IF_FREE(exe->tag);
|
||||
if (tag)
|
||||
exe->tag = strdup(tag);
|
||||
}
|
||||
|
||||
EAPI char *ecore_exe_tag_get(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_get");
|
||||
return NULL;
|
||||
}
|
||||
return exe->tag;
|
||||
}
|
||||
|
||||
EAPI char *ecore_exe_cmd_get(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_cmd_get");
|
||||
return NULL;
|
||||
}
|
||||
return exe->cmd;
|
||||
}
|
||||
|
||||
EAPI void *ecore_exe_data_get(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
|
||||
return NULL;
|
||||
}
|
||||
return exe->data;
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_pause(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pause");
|
||||
return;
|
||||
}
|
||||
|
||||
if (exe->is_suspended)
|
||||
return;
|
||||
|
||||
if (SuspendThread(exe->thread) != (DWORD)-1)
|
||||
exe->is_suspended = 1;
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_continue(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_continue");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!exe->is_suspended)
|
||||
return;
|
||||
|
||||
if (ResumeThread(exe->thread) != (DWORD)-1)
|
||||
exe->is_suspended = 0;
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_interrupt(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_interrupt");
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(exe->process);
|
||||
exe->sig = ECORE_EXE_WIN32_SIGINT;
|
||||
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_quit(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_quit");
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(exe->process);
|
||||
exe->sig = ECORE_EXE_WIN32_SIGQUIT;
|
||||
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_terminate(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_terminate");
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(exe->process);
|
||||
exe->sig = ECORE_EXE_WIN32_SIGTERM;
|
||||
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_kill(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_kill");
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(exe->process);
|
||||
exe->sig = ECORE_EXE_WIN32_SIGKILL;
|
||||
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_signal(Ecore_Exe *exe, int num)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_signal");
|
||||
return;
|
||||
}
|
||||
|
||||
/* does nothing */
|
||||
}
|
||||
|
||||
EAPI void ecore_exe_hup(Ecore_Exe *exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_hup");
|
||||
return;
|
||||
}
|
||||
|
||||
/* does nothing */
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
_ecore_exe_thread_procedure(LPVOID data)
|
||||
{
|
||||
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
|
||||
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
_ecore_exe_enum_windows_procedure(HWND window, LPARAM data)
|
||||
{
|
||||
Ecore_Exe *exe;
|
||||
DWORD thread_id;
|
||||
|
||||
exe = (Ecore_Exe *)data;
|
||||
thread_id = GetWindowThreadProcessId(window, NULL);
|
||||
|
||||
if (thread_id == exe->thread_id)
|
||||
{
|
||||
/* Ctrl-C or Ctrl-Break */
|
||||
if (CreateRemoteThread(exe->process, NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE)_ecore_exe_thread_procedure, NULL,
|
||||
0, NULL))
|
||||
return FALSE;
|
||||
|
||||
if ((exe->sig == ECORE_EXE_WIN32_SIGINT) ||
|
||||
(exe->sig == ECORE_EXE_WIN32_SIGQUIT))
|
||||
return FALSE;
|
||||
|
||||
/* WM_CLOSE message */
|
||||
PostMessage(window, WM_CLOSE, 0, 0);
|
||||
if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
|
||||
return FALSE;
|
||||
|
||||
/* WM_QUIT message */
|
||||
PostMessage(window, WM_QUIT, 0, 0);
|
||||
if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
|
||||
return FALSE;
|
||||
|
||||
/* Exit process */
|
||||
if (CreateRemoteThread(exe->process, NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE)ExitProcess, NULL,
|
||||
0, NULL))
|
||||
return FALSE;
|
||||
if (exe->sig == ECORE_EXE_WIN32_SIGTERM)
|
||||
return FALSE;
|
||||
|
||||
TerminateProcess(exe->process, 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -207,9 +207,7 @@ enum _Ecore_Poller_Type
|
|||
};
|
||||
typedef enum _Ecore_Poller_Type Ecore_Poller_Type;
|
||||
|
||||
#ifndef _WIN32
|
||||
typedef struct _Ecore_Exe Ecore_Exe;
|
||||
#endif
|
||||
typedef struct _Ecore_Timer Ecore_Timer;
|
||||
typedef struct _Ecore_Idler Ecore_Idler;
|
||||
typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer;
|
||||
|
@ -418,12 +416,9 @@ int _ecore_signal_count_get(void);
|
|||
void _ecore_signal_call(void);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
static inline void _ecore_exe_init(void) { }
|
||||
static inline void _ecore_exe_shutdown(void) { }
|
||||
#else
|
||||
void _ecore_exe_init(void);
|
||||
void _ecore_exe_shutdown(void);
|
||||
#ifndef _WIN32
|
||||
Ecore_Exe *_ecore_exe_find(pid_t pid);
|
||||
void *_ecore_exe_event_del_new(void);
|
||||
void _ecore_exe_event_del_free(void *data, void *ev);
|
||||
|
|
Loading…
Reference in New Issue