refactored f_popen to use luaL_Buffer

This commit is contained in:
takase1121 2020-10-10 12:30:40 +08:00
parent 711fef5299
commit a85eb88cfd
1 changed files with 14 additions and 40 deletions

View File

@ -354,15 +354,11 @@ static int f_exec(lua_State *L) {
static int f_popen(lua_State *L) { static int f_popen(lua_State *L) {
size_t len; size_t len;
const char *cmd = luaL_checklstring(L, 1, &len); const char *cmd = luaL_checklstring(L, 1, &len);
int bufferSize = luaL_optnumber(L, 2, 2048);
unsigned long exitCode = 0; unsigned long exitCode = 0;
size_t stdoutSize = bufferSize; luaL_Buffer stdoutBuf;
size_t stdoutRead = 0; luaL_buffinit(L, &stdoutBuf);
char* stdoutBuf = malloc(stdoutSize);
if (!stdoutBuf) { luaL_error(L, "buffer allocation failed"); }
#if _WIN32 #if _WIN32
char* buf = malloc(len + 32); char* buf = malloc(len + 32);
@ -376,10 +372,10 @@ static int f_popen(lua_State *L) {
sa.bInheritHandle = TRUE; sa.bInheritHandle = TRUE;
HANDLE stdoutReadHandle, stdoutWriteHandle; HANDLE stdoutReadHandle, stdoutWriteHandle;
if (! CreatePipe(&stdoutReadHandle, &stdoutWriteHandle, &sa, 0) ) { if (!CreatePipe(&stdoutReadHandle, &stdoutWriteHandle, &sa, 0)) {
luaL_error(L, "Unable to create stdout pipe"); luaL_error(L, "Unable to create stdout pipe");
} }
if (! SetHandleInformation(stdoutReadHandle, HANDLE_FLAG_INHERIT, 0) ) { if (!SetHandleInformation(stdoutReadHandle, HANDLE_FLAG_INHERIT, 0)) {
luaL_error(L, "Unable to create stdout pipe"); luaL_error(L, "Unable to create stdout pipe");
} }
@ -403,59 +399,37 @@ static int f_popen(lua_State *L) {
for (;;) { for (;;) {
if (!PeekNamedPipe(stdoutReadHandle, NULL, 0, NULL, &rem, NULL)) { if (!PeekNamedPipe(stdoutReadHandle, NULL, 0, NULL, &rem, NULL)) {
luaL_error(L, "Error peeking into stdout: %d", GetLastError()); luaL_error(L, "Error peeking into stdout: %d", GetLastError());
break;
} }
if (!GetExitCodeProcess(pi.hProcess, &exitCode)) { if (!GetExitCodeProcess(pi.hProcess, &exitCode)) {
luaL_error(L, "Error checking process exit code: %d", GetLastError()); luaL_error(L, "Error checking process exit code: %d", GetLastError());
break;
} }
if (exitCode != 259 && rem == 0) { break; }
if (exitCode != 259 && rem == 0) break;
// if there are things to read, resize and read it // if there are things to read, resize and read it
if (rem) { if (rem) {
rem++; char* b = luaL_prepbuffsize(&stdoutBuf, rem);
stdoutSize += rem; if (!ReadFile(stdoutReadHandle, b, rem, &read, NULL)) {
char* newbuf = realloc(stdoutBuf, stdoutSize);
if (newbuf == NULL) {
luaL_error(L, "Unable to allocate memory");
break;
}
stdoutBuf = newbuf;
if (!ReadFile(stdoutReadHandle, stdoutBuf + stdoutRead, rem, &read, NULL)) {
luaL_error(L, "Error reading from stdout: %d", GetLastError()); luaL_error(L, "Error reading from stdout: %d", GetLastError());
break;
} }
stdoutRead += read; luaL_addsize(&stdoutBuf, read);
} }
} }
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
stdoutBuf[stdoutRead] = '\0';
#else #else
FILE* pipe = popen(cmd, "rb"); FILE* pipe = popen(cmd, "rb");
if (pipe == NULL) { luaL_error("Unable to start process"); } if (pipe == NULL) { luaL_error("Failed to start process"); }
size_t read;
while(!feof(pipe)) { while(!feof(pipe)) {
size_t read = fread(stdoutBuf + stdoutRead, sizeof(char), 2048, pipe); char* b = luaL_prepbuffer(&stdoutBuf);
stdoutRead += read; read = fread(b, sizeof(char), LUAL_BUFFERSIZE, pipe);
if (stdoutRead >= stdoutSize) { luaL_addsize(&stdoutBuf, read);
stdoutSize = stdoutRead + 1;
char* newbuf = realloc(stdoutBuf, stdoutSize);
if (newbuf == NULL) {
luaL_error(L, "buffer allocation failed");
break;
}
}
} }
stdoutBuf[stdoutRead] = '\0';
exitCode = WEXITSTATUS(pclose(pipe)); exitCode = WEXITSTATUS(pclose(pipe));
#endif #endif
// cast buffer into lua strings luaL_pushresult(&stdoutBuf);
lua_pushstring(L, stdoutBuf);
lua_pushnumber(L, exitCode); lua_pushnumber(L, exitCode);
free(stdoutBuf);
return 2; return 2;
} }