diff options
author | 2013-12-14 00:35:27 -0500 | |
---|---|---|
committer | 2013-12-14 00:35:27 -0500 | |
commit | 78c037ab970c2f38272ddd1cf3dbf7b89be86039 (patch) | |
tree | 8bc4da5eca4d021bd4c2d54e8c9f98bb575622f7 | |
parent | 396a16c8db6e0153f1507bca19c970008095a841 (diff) | |
download | textadept-78c037ab970c2f38272ddd1cf3dbf7b89be86039.tar.gz textadept-78c037ab970c2f38272ddd1cf3dbf7b89be86039.zip |
Allow process writing in experimental winapi.
Other modifications to make the return value for `io.popen()` more file-like.
-rw-r--r-- | core/file_io.lua | 27 | ||||
-rw-r--r-- | src/winapi.patch | 66 |
2 files changed, 53 insertions, 40 deletions
diff --git a/core/file_io.lua b/core/file_io.lua index 9abc3580..24a94c41 100644 --- a/core/file_io.lua +++ b/core/file_io.lua @@ -421,13 +421,23 @@ end if WIN32 then local winapi = require('winapi') io.popen = function(prog) - local code, output = winapi.execute(prog) - if not code then return code, output end - return { - read = function() return output end, + local p, f = winapi.spawn_process(os.getenv('COMSPEC')..' /c '..prog) + if not p then return nil, f end + local file + file = { + read = function(self, format) + if not format or not format:find('^%*a') then return f:read() end + local chunk, text = f:read(), {} + while chunk do + text[#text + 1] = chunk + chunk = f:read() + end + return table.concat(text, '') + end, + write = function(self, ...) f:write(...) end, lines = function() + local output, pos = file:read('*a'), 1 if not output:find('\r?\n$') then output = output..'\n' end - local pos = 1 return function() local s, e, line = output:find('([^\r\n]*)\r?\n', pos) if not s then return nil end @@ -435,8 +445,13 @@ if WIN32 then return line end end, - close = function() return true, 'exit', code end + close = function() + local _, status = p:wait(100) + if status == 'TIMEOUT' then p:kill() end + return true, 'exit', p:get_exit_code() + end } + return file end os.execute = function(prog) local code = winapi.execute(prog) diff --git a/src/winapi.patch b/src/winapi.patch index 5aa7a896..1303a538 100644 --- a/src/winapi.patch +++ b/src/winapi.patch @@ -1,5 +1,5 @@ --- a/winapi.c 2012-06-28 04:50:56.000000000 -0400 -+++ b/winapi.c 2013-11-19 15:42:27.560539900 -0500 ++++ b/winapi.c 2013-12-13 09:14:05.006746200 -0500 @@ -20,7 +20,7 @@ #ifdef __GNUC__
#include <winable.h> /* GNU GCC specific */
@@ -59,7 +59,23 @@ /// get the name of the process.
// @param full true if you want the full path; otherwise returns the base name.
// @function get_process_name
-@@ -1280,6 +1287,7 @@ +@@ -1210,6 +1217,7 @@ + lua_pushnumber(L, this->pid);
+ return 1;
+ }
++#endif
+
+ /// kill the process.
+ // @{test-spawn.lua} kills a launched process after a certain amount of output.
+@@ -1221,6 +1229,7 @@ + return 0;
+ }
+
++#if 0
+ /// get the working size of the process.
+ // @return minimum working set size
+ // @return maximum working set size.
+@@ -1280,6 +1289,7 @@ lua_pushnumber(L,fileTimeToMillisec(&kernel));
return 2;
}
@@ -67,7 +83,7 @@ /// wait for this process to finish.
// @param timeout optional timeout in millisec; defaults to waiting indefinitely.
-@@ -1293,6 +1301,7 @@ +@@ -1293,6 +1303,7 @@ return push_wait(L,this->hProcess, TIMEOUT(timeout));
}
@@ -75,7 +91,7 @@ /// run callback when this process is finished.
// @param callback the callback
// @param timeout optional timeout in millisec; defaults to waiting indefinitely.
-@@ -1320,6 +1329,7 @@ +@@ -1320,6 +1331,7 @@ #line 968 "winapi.l.c"
return push_wait_result(L, WaitForInputIdle(this->hProcess, TIMEOUT(timeout)));
}
@@ -83,14 +99,16 @@ /// exit code of this process.
// (Only makes sense if the process has in fact finished.)
-@@ -1354,15 +1364,19 @@ +@@ -1354,15 +1366,21 @@ #line 995 "winapi.l.c"
static const struct luaL_Reg Process_methods [] = {
+#if 0
{"get_process_name",l_Process_get_process_name},
{"get_pid",l_Process_get_pid},
++#endif
{"kill",l_Process_kill},
++#if 0
{"get_working_size",l_Process_get_working_size},
{"get_start_time",l_Process_get_start_time},
{"get_run_times",l_Process_get_run_times},
@@ -103,7 +121,7 @@ {"get_exit_code",l_Process_get_exit_code},
{"close",l_Process_close},
{"__gc",l_Process___gc},
-@@ -1388,6 +1402,7 @@ +@@ -1388,6 +1406,7 @@ // @{readme.md.Creating_and_working_with_Processes}
// @section Processes
@@ -111,7 +129,7 @@ /// create a process object from the id.
// @param pid the process id
// @return @{Process}
-@@ -1477,6 +1492,7 @@ +@@ -1477,6 +1496,7 @@ return 1;
}
}
@@ -119,7 +137,7 @@ // These functions are all run in background threads, and a little bit of poor man's
// OOP helps here. This is the base struct for describing threads with callbacks,
-@@ -1493,6 +1509,7 @@ +@@ -1493,6 +1513,7 @@ callback_data_
} LuaCallback, *PLuaCallback;
@@ -127,7 +145,7 @@ LuaCallback *lcb_callback(void *lcb, lua_State *L, int idx) {
LuaCallback *data;
if (lcb == NULL) {
-@@ -1510,6 +1527,7 @@ +@@ -1510,6 +1531,7 @@ LuaCallback *lcb = (LuaCallback*)data;
return call_lua(lcb->L,lcb->callback,idx,text,persist);
}
@@ -135,7 +153,7 @@ void lcb_allocate_buffer(void *data, int size) {
LuaCallback *lcb = (LuaCallback*)data;
-@@ -1535,6 +1553,7 @@ +@@ -1535,6 +1557,7 @@ #define lcb_bufsz(data) ((LuaCallback *)data)->bufsz
#define lcb_handle(data) ((LuaCallback *)data)->handle
@@ -143,7 +161,7 @@ /// Thread object. This is returned by the @{File:read_async} method and the @{make_timer},
// @{make_pipe_server} and @{watch_for_file_changes} functions. Useful to kill a thread
// and free associated resources.
-@@ -1707,6 +1726,7 @@ +@@ -1707,6 +1730,7 @@ lcb->bufsz = timeout;
return lcb_new_thread((TCB)handle_waiter,lcb);
}
@@ -151,23 +169,7 @@ /// this represents a raw Windows file handle.
// The write handle may be distinct from the read handle.
-@@ -1748,6 +1768,7 @@ - lcb_allocate_buffer(this,FILE_BUFF_SIZE);
- }
-
-+#if 0
- /// write to a file.
- // @param s text
- // @return number of bytes written.
-@@ -1761,6 +1782,7 @@ - lua_pushinteger(L,bytesWrote);
- return 1;
- }
-+#endif
-
- static BOOL raw_read (File *this) {
- DWORD bytesRead = 0;
-@@ -1785,6 +1807,7 @@ +@@ -1785,6 +1809,7 @@ }
}
@@ -175,7 +177,7 @@ static void file_reader (File *this) { // background reader thread
int n;
do {
-@@ -1806,6 +1829,7 @@ +@@ -1806,6 +1831,7 @@ this->callback = make_ref(L,callback);
return lcb_new_thread((TCB)&file_reader,this);
}
@@ -183,13 +185,9 @@ static int l_File_close(lua_State *L) {
File *this = File_arg(L,1);
-@@ -1825,9 +1849,13 @@ - #line 1318 "winapi.l.c"
-
+@@ -1827,7 +1853,9 @@ static const struct luaL_Reg File_methods [] = {
-+#if 0
{"write",l_File_write},
-+#endif
{"read",l_File_read},
+#if 0
{"read_async",l_File_read_async},
|