Remove the unneeded win32_spawn() and win32_get_exit_status()
These are not part of the plugin interface, and are not used in Geany any more after the spawn changes.
This commit is contained in:
parent
7bebf64f3d
commit
47a7b507a7
493
src/win32.c
493
src/win32.c
@ -57,31 +57,6 @@
|
||||
#include <glib/gstdio.h>
|
||||
#include <gdk/gdkwin32.h>
|
||||
|
||||
#define BUFSIZE 4096
|
||||
#define CMDSIZE 32768
|
||||
|
||||
struct _geany_win32_spawn
|
||||
{
|
||||
HANDLE hChildStdinRd;
|
||||
HANDLE hChildStdinWr;
|
||||
HANDLE hChildStdoutRd;
|
||||
HANDLE hChildStdoutWr;
|
||||
HANDLE hChildStderrRd;
|
||||
HANDLE hChildStderrWr;
|
||||
HANDLE hInputFile;
|
||||
HANDLE hStdout;
|
||||
HANDLE hStderr;
|
||||
HANDLE processId;
|
||||
DWORD dwExitCode;
|
||||
};
|
||||
typedef struct _geany_win32_spawn geany_win32_spawn;
|
||||
|
||||
static gboolean GetContentFromHandle(HANDLE hFile, gchar **content, GError **error);
|
||||
static HANDLE GetTempFileHandle(GError **error);
|
||||
static gboolean CreateChildProcess(geany_win32_spawn *gw_spawn, TCHAR *szCmdline,
|
||||
const TCHAR *dir, GError **error);
|
||||
static VOID ReadFromPipe(HANDLE hRead, HANDLE hWrite, HANDLE hFile, GError **error);
|
||||
|
||||
|
||||
/* The timer handle used to refresh windows below modal native dialogs. If
|
||||
* ever more than one dialog can be shown at a time, this needs to be changed
|
||||
@ -837,17 +812,6 @@ void win32_open_browser(const gchar *uri)
|
||||
}
|
||||
|
||||
|
||||
/* Returns TRUE if the command, which child_pid refers to, returned with a successful exit code,
|
||||
* otherwise FALSE. */
|
||||
gboolean win32_get_exit_status(GPid child_pid)
|
||||
{
|
||||
DWORD exit_code;
|
||||
GetExitCodeProcess(child_pid, &exit_code);
|
||||
|
||||
return (exit_code == 0);
|
||||
}
|
||||
|
||||
|
||||
static FILE *open_std_handle(DWORD handle, const char *mode)
|
||||
{
|
||||
HANDLE lStdHandle;
|
||||
@ -929,302 +893,10 @@ void win32_init_debug_code(void)
|
||||
/* create a console window to get log messages on Windows,
|
||||
* especially useful when generating tags files */
|
||||
debug_setup_console();
|
||||
/* Enable GLib process spawn debug mode when Geany was started with the debug flag */
|
||||
g_setenv("G_SPAWN_WIN32_DEBUG", "1", FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gchar *create_temp_file(void)
|
||||
{
|
||||
gchar *name;
|
||||
gint fd;
|
||||
|
||||
fd = g_file_open_tmp("tmp_XXXXXX", &name, NULL);
|
||||
if (fd == -1)
|
||||
name = NULL;
|
||||
else
|
||||
close(fd);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/* Sometimes this blocks for 30s before aborting when there are several
|
||||
* pages of (error) output and sometimes hangs - see the FIXME.
|
||||
* Also gw_spawn.dwExitCode seems to be not set properly. */
|
||||
/* Process spawning implementation for Windows, by Pierre Joye.
|
||||
* Don't call this function directly, use utils_spawn_[a]sync() instead. */
|
||||
static
|
||||
gboolean _broken_win32_spawn(const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags,
|
||||
gchar **std_out, gchar **std_err, gint *exit_status, GError **error)
|
||||
{
|
||||
TCHAR buffer[CMDSIZE]=TEXT("");
|
||||
TCHAR cmdline[CMDSIZE] = TEXT("");
|
||||
TCHAR* lpPart[CMDSIZE]={NULL};
|
||||
DWORD retval = 0;
|
||||
gint argc = 0, i;
|
||||
gint cmdpos = 0;
|
||||
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
BOOL fSuccess;
|
||||
geany_win32_spawn gw_spawn;
|
||||
|
||||
/* Temp file */
|
||||
HANDLE hStdoutTempFile = NULL;
|
||||
HANDLE hStderrTempFile = NULL;
|
||||
|
||||
gchar *stdout_content = NULL;
|
||||
gchar *stderr_content = NULL;
|
||||
|
||||
while (argv[argc])
|
||||
{
|
||||
++argc;
|
||||
}
|
||||
g_return_val_if_fail (std_out == NULL ||
|
||||
!(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
|
||||
g_return_val_if_fail (std_err == NULL ||
|
||||
!(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
|
||||
|
||||
if (flags & G_SPAWN_SEARCH_PATH)
|
||||
{
|
||||
retval = SearchPath(NULL, argv[0], ".exe", sizeof(buffer), buffer, lpPart);
|
||||
if (retval > 0)
|
||||
g_snprintf(cmdline, sizeof(cmdline), "\"%s\"", buffer);
|
||||
else
|
||||
g_strlcpy(cmdline, argv[0], sizeof(cmdline));
|
||||
cmdpos = 1;
|
||||
}
|
||||
|
||||
for (i = cmdpos; i < argc; i++)
|
||||
{
|
||||
g_snprintf(cmdline, sizeof(cmdline), "%s %s", cmdline, argv[i]);
|
||||
/*MessageBox(NULL, cmdline, cmdline, MB_OK);*/
|
||||
}
|
||||
|
||||
if (std_err != NULL)
|
||||
{
|
||||
hStderrTempFile = GetTempFileHandle(error);
|
||||
if (hStderrTempFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("win32_spawn: Second CreateFile failed (%d)", (gint) GetLastError());
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR, "%s", msg);
|
||||
g_free(msg);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (std_out != NULL)
|
||||
{
|
||||
hStdoutTempFile = GetTempFileHandle(error);
|
||||
if (hStdoutTempFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("win32_spawn: Second CreateFile failed (%d)", (gint) GetLastError());
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR, "%s", msg);
|
||||
g_free(msg);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the bInheritHandle flag so pipe handles are inherited. */
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
/* Get the handle to the current STDOUT and STDERR. */
|
||||
gw_spawn.hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
gw_spawn.hStderr = GetStdHandle(STD_ERROR_HANDLE);
|
||||
gw_spawn.dwExitCode = 0;
|
||||
|
||||
/* Create a pipe for the child process's STDOUT. */
|
||||
if (! CreatePipe(&(gw_spawn.hChildStdoutRd), &(gw_spawn.hChildStdoutWr), &saAttr, 0))
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("win32_spawn: Stdout pipe creation failed (%d)", (gint) GetLastError());
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR_PIPE, "%s", msg);
|
||||
g_free(msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ensure that the read handle to the child process's pipe for STDOUT is not inherited.*/
|
||||
SetHandleInformation(gw_spawn.hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);
|
||||
|
||||
/* Create a pipe for the child process's STDERR. */
|
||||
if (! CreatePipe(&(gw_spawn.hChildStderrRd), &(gw_spawn.hChildStderrWr), &saAttr, 0))
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("win32_spawn: Stderr pipe creation failed");
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR_PIPE, "%s", msg);
|
||||
g_free(msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ensure that the read handle to the child process's pipe for STDOUT is not inherited.*/
|
||||
SetHandleInformation(gw_spawn.hChildStderrRd, HANDLE_FLAG_INHERIT, 0);
|
||||
|
||||
/* Create a pipe for the child process's STDIN. */
|
||||
if (! CreatePipe(&(gw_spawn.hChildStdinRd), &(gw_spawn.hChildStdinWr), &saAttr, 0))
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("win32_spawn: Stdin pipe creation failed");
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR_PIPE, "%s", msg);
|
||||
g_free(msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ensure that the write handle to the child process's pipe for STDIN is not inherited. */
|
||||
SetHandleInformation(gw_spawn.hChildStdinWr, HANDLE_FLAG_INHERIT, 0);
|
||||
|
||||
/* Now create the child process. */
|
||||
fSuccess = CreateChildProcess(&gw_spawn, cmdline, dir, error);
|
||||
if (exit_status)
|
||||
{
|
||||
*exit_status = gw_spawn.dwExitCode;
|
||||
}
|
||||
|
||||
if (! fSuccess)
|
||||
{
|
||||
geany_debug("win32_spawn: Create process failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Read from pipe that is the standard output for child process. */
|
||||
if (std_out != NULL)
|
||||
{
|
||||
ReadFromPipe(gw_spawn.hChildStdoutRd, gw_spawn.hChildStdoutWr, hStdoutTempFile, error);
|
||||
if (! GetContentFromHandle(hStdoutTempFile, &stdout_content, error))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*std_out = stdout_content;
|
||||
}
|
||||
|
||||
if (std_err != NULL)
|
||||
{
|
||||
ReadFromPipe(gw_spawn.hChildStderrRd, gw_spawn.hChildStderrWr, hStderrTempFile, error);
|
||||
if (! GetContentFromHandle(hStderrTempFile, &stderr_content, error))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*std_err = stderr_content;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Note: g_spawn is broken for receiving both stdio and stderr e.g. when
|
||||
* running make and there are compile errors. See glib/giowin32.c header
|
||||
* comment about Windows bugs, e.g. #338943 */
|
||||
/* Simple replacement for _broken_win32_spawn().
|
||||
* flags is ignored, G_SPAWN_SEARCH_PATH is implied.
|
||||
* Don't call this function directly, use utils_spawn_[a]sync() instead.
|
||||
* Adapted from tm_workspace_create_global_tags(). */
|
||||
gboolean win32_spawn(const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags,
|
||||
gchar **std_out, gchar **std_err, gint *exit_status, GError **error)
|
||||
{
|
||||
gint ret;
|
||||
gboolean fail;
|
||||
gchar *tmp_file = create_temp_file();
|
||||
gchar *tmp_errfile = create_temp_file();
|
||||
gchar *command;
|
||||
gchar *locale_command;
|
||||
|
||||
if (env != NULL)
|
||||
{
|
||||
return _broken_win32_spawn(dir, argv, env, flags, std_out, std_err,
|
||||
exit_status, error);
|
||||
}
|
||||
if (!tmp_file || !tmp_errfile)
|
||||
{
|
||||
g_warning("%s: Could not create temporary files!", G_STRFUNC);
|
||||
return FALSE;
|
||||
}
|
||||
command = g_strjoinv(" ", argv);
|
||||
SETPTR(command, g_strdup_printf("cmd.exe /S /C \"%s >%s 2>%s\"",
|
||||
command, tmp_file, tmp_errfile));
|
||||
locale_command = g_locale_from_utf8(command, -1, NULL, NULL, NULL);
|
||||
if (! locale_command)
|
||||
locale_command = g_strdup(command);
|
||||
geany_debug("WIN32: actually running command:\n%s", command);
|
||||
g_chdir(dir);
|
||||
errno = 0;
|
||||
ret = system(locale_command);
|
||||
/* the command can return -1 as an exit code, so check errno also */
|
||||
fail = ret == -1 && errno;
|
||||
if (!fail)
|
||||
{
|
||||
if (std_out != NULL)
|
||||
g_file_get_contents(tmp_file, std_out, NULL, NULL);
|
||||
if (std_err != NULL)
|
||||
g_file_get_contents(tmp_errfile, std_err, NULL, NULL);
|
||||
}
|
||||
else if (error)
|
||||
g_set_error_literal(error, G_SPAWN_ERROR, errno, g_strerror(errno));
|
||||
|
||||
g_free(command);
|
||||
g_free(locale_command);
|
||||
g_unlink(tmp_file);
|
||||
g_free(tmp_file);
|
||||
g_unlink(tmp_errfile);
|
||||
g_free(tmp_errfile);
|
||||
if (exit_status)
|
||||
*exit_status = ret;
|
||||
|
||||
return !fail;
|
||||
}
|
||||
|
||||
|
||||
static gboolean GetContentFromHandle(HANDLE hFile, gchar **content, GError **error)
|
||||
{
|
||||
DWORD filesize;
|
||||
gchar * buffer;
|
||||
DWORD dwRead;
|
||||
|
||||
filesize = GetFileSize(hFile, NULL);
|
||||
if (filesize < 1)
|
||||
{
|
||||
*content = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
buffer = g_malloc(filesize + 1);
|
||||
if (! buffer)
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("GetContentFromHandle: Alloc failed");
|
||||
g_set_error(error, G_SPAWN_ERROR, G_SPAWN_ERROR, "%s", msg);
|
||||
g_free(msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
|
||||
if (! ReadFile(hFile, buffer, filesize, &dwRead, NULL) || dwRead == 0)
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("GetContentFromHandle: Cannot read tempfile");
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR_FAILED, "%s", msg);
|
||||
g_free(msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! CloseHandle(hFile))
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("GetContentFromHandle: CloseHandle failed (%d)", (gint) GetLastError());
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR_FAILED, "%s", msg);
|
||||
g_free(msg);
|
||||
g_free(buffer);
|
||||
*content = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
buffer[filesize] = '\0';
|
||||
*content = buffer;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gchar *win32_expand_environment_variables(const gchar *str)
|
||||
{
|
||||
gchar expCmdline[32768]; /* 32768 is the limit for ExpandEnvironmentStrings() */
|
||||
@ -1236,171 +908,6 @@ gchar *win32_expand_environment_variables(const gchar *str)
|
||||
}
|
||||
|
||||
|
||||
static gboolean CreateChildProcess(geany_win32_spawn *gw_spawn, TCHAR *szCmdline,
|
||||
const TCHAR *dir, GError **error)
|
||||
{
|
||||
PROCESS_INFORMATION piProcInfo;
|
||||
STARTUPINFOW siStartInfo;
|
||||
BOOL bFuncRetn = FALSE;
|
||||
gchar *expandedCmdline;
|
||||
wchar_t w_commandline[CMDSIZE];
|
||||
wchar_t w_dir[MAX_PATH];
|
||||
|
||||
/* Set up members of the PROCESS_INFORMATION structure. */
|
||||
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
/* Set up members of the STARTUPINFO structure.*/
|
||||
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
|
||||
|
||||
siStartInfo.cb = sizeof(STARTUPINFO);
|
||||
siStartInfo.hStdError = gw_spawn->hChildStderrWr;
|
||||
siStartInfo.hStdOutput = gw_spawn->hChildStdoutWr;
|
||||
siStartInfo.hStdInput = gw_spawn->hChildStdinRd;
|
||||
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
/* Expand environment variables like %blah%. */
|
||||
expandedCmdline = win32_expand_environment_variables(szCmdline);
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, expandedCmdline, -1, w_commandline, G_N_ELEMENTS(w_commandline));
|
||||
MultiByteToWideChar(CP_UTF8, 0, dir, -1, w_dir, G_N_ELEMENTS(w_dir));
|
||||
|
||||
/* Create the child process. */
|
||||
bFuncRetn = CreateProcessW(NULL,
|
||||
w_commandline, /* command line */
|
||||
NULL, /* process security attributes */
|
||||
NULL, /* primary thread security attributes */
|
||||
TRUE, /* handles are inherited */
|
||||
CREATE_NO_WINDOW, /* creation flags */
|
||||
NULL, /* use parent's environment */
|
||||
w_dir, /* use parent's current directory */
|
||||
&siStartInfo, /* STARTUPINFO pointer */
|
||||
&piProcInfo); /* receives PROCESS_INFORMATION */
|
||||
|
||||
g_free(expandedCmdline);
|
||||
|
||||
if (bFuncRetn == 0)
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("CreateChildProcess: CreateProcess failed (%s)", msg);
|
||||
g_set_error(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, "%s", msg);
|
||||
g_free(msg);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gint i;
|
||||
gsize ms = 30*1000;
|
||||
|
||||
/* FIXME: this seems to timeout when there are many lines
|
||||
* to read - maybe because the child's pipe is full */
|
||||
for (i = 0; i < 2 &&
|
||||
WaitForSingleObject(piProcInfo.hProcess, ms) == WAIT_TIMEOUT; i++)
|
||||
{
|
||||
ui_set_statusbar(FALSE, _("Process timed out after %.02f s!"), ms / 1000.0F);
|
||||
geany_debug("CreateChildProcess: timed out");
|
||||
TerminateProcess(piProcInfo.hProcess, WAIT_TIMEOUT); /* NOTE: This will not kill grandkids. */
|
||||
}
|
||||
|
||||
if (!GetExitCodeProcess(piProcInfo.hProcess, &gw_spawn->dwExitCode))
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("GetExitCodeProcess failed: %s", msg);
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR_FAILED, "%s", msg);
|
||||
g_free(msg);
|
||||
}
|
||||
CloseHandle(piProcInfo.hProcess);
|
||||
CloseHandle(piProcInfo.hThread);
|
||||
return bFuncRetn;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static VOID ReadFromPipe(HANDLE hRead, HANDLE hWrite, HANDLE hFile, GError **error)
|
||||
{
|
||||
DWORD dwRead, dwWritten;
|
||||
CHAR chBuf[BUFSIZE];
|
||||
|
||||
/* Close the write end of the pipe before reading from the
|
||||
read end of the pipe. */
|
||||
if (! CloseHandle(hWrite))
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("ReadFromPipe: Closing handle failed");
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR_PIPE, "%s", msg);
|
||||
g_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read output from the child process, and write to parent's STDOUT. */
|
||||
for (;;)
|
||||
{
|
||||
if (! ReadFile(hRead, chBuf, BUFSIZE, &dwRead, NULL) || dwRead == 0)
|
||||
break;
|
||||
|
||||
if (! WriteFile(hFile, chBuf, dwRead, &dwWritten, NULL))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static HANDLE GetTempFileHandle(GError **error)
|
||||
{
|
||||
/* Temp file */
|
||||
DWORD dwBufSize = BUFSIZE;
|
||||
UINT uRetVal;
|
||||
TCHAR szTempName[BUFSIZE];
|
||||
TCHAR lpPathBuffer[BUFSIZE];
|
||||
DWORD dwRetVal;
|
||||
HANDLE hTempFile;
|
||||
|
||||
/* Get the temp path. */
|
||||
dwRetVal = GetTempPath(dwBufSize, /* length of the buffer*/
|
||||
lpPathBuffer); /* buffer for path */
|
||||
|
||||
if (dwRetVal > dwBufSize || (dwRetVal == 0))
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("GetTempFileHandle: GetTempPath failed (%d)", (gint) GetLastError());
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR, "%s", msg);
|
||||
g_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a temporary file for STDOUT. */
|
||||
uRetVal = GetTempFileName(lpPathBuffer, /* directory for tmp files */
|
||||
TEXT("GEANY_VCDIFF_"), /* temp file name prefix */
|
||||
0, /* create unique name */
|
||||
szTempName); /* buffer for name */
|
||||
if (uRetVal == 0)
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("GetTempFileName failed (%d)", (gint) GetLastError());
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR, "%s", msg);
|
||||
g_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hTempFile = CreateFile((LPTSTR) szTempName, /* file name */
|
||||
GENERIC_READ | GENERIC_WRITE, /* open r-w */
|
||||
0, /* do not share */
|
||||
NULL, /* default security */
|
||||
CREATE_ALWAYS, /* overwrite existing */
|
||||
FILE_ATTRIBUTE_NORMAL,/* normal file */
|
||||
NULL); /* no template */
|
||||
|
||||
if (hTempFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
gchar *msg = g_win32_error_message(GetLastError());
|
||||
geany_debug("GetTempFileHandle: Second CreateFile failed (%d)", (gint) GetLastError());
|
||||
g_set_error(error, G_SPAWN_ERROR, G_FILE_ERROR, "%s", msg);
|
||||
g_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
return hTempFile;
|
||||
}
|
||||
|
||||
|
||||
/* From GDK (they got it from MS Knowledge Base article Q130698) */
|
||||
static gboolean resolve_link(HWND hWnd, wchar_t *link, gchar **lpszPath)
|
||||
{
|
||||
|
@ -60,11 +60,6 @@ void win32_init_debug_code(void);
|
||||
|
||||
void win32_set_working_directory(const gchar *dir);
|
||||
|
||||
gboolean win32_get_exit_status(GPid child_pid);
|
||||
|
||||
gboolean win32_spawn(const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags,
|
||||
gchar **std_out, gchar **std_err, gint *exit_status, GError **error);
|
||||
|
||||
gchar *win32_get_shortcut_target(const gchar *file_name);
|
||||
|
||||
gchar *win32_get_installation_dir(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user