mirror of
https://github.com/transmission/transmission
synced 2024-12-25 17:17:31 +00:00
Use CreateProcess instead of _spawnvpe to execute scripts on Windows
This commit is contained in:
parent
7abe7c28a3
commit
8dd65cdfba
1 changed files with 66 additions and 11 deletions
|
@ -14,7 +14,7 @@
|
||||||
#include <sys/wait.h> /* wait () */
|
#include <sys/wait.h> /* wait () */
|
||||||
#include <unistd.h> /* fork (), execvp (), _exit () */
|
#include <unistd.h> /* fork (), execvp (), _exit () */
|
||||||
#else
|
#else
|
||||||
#include <process.h> /* _spawnvpe () */
|
#include <windows.h> /* CreateProcess (), GetLastError () */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -2105,39 +2105,94 @@ torrentCallScript (const tr_torrent * tor, const char * script)
|
||||||
|
|
||||||
if (script && *script)
|
if (script && *script)
|
||||||
{
|
{
|
||||||
int i;
|
size_t i;
|
||||||
char * cmd[] = { tr_strdup (script), NULL };
|
char * cmd[] = { tr_strdup (script), NULL };
|
||||||
char * env[] = {
|
char * env[] = {
|
||||||
tr_strdup_printf ("TR_APP_VERSION=%s", SHORT_VERSION_STRING),
|
tr_strdup_printf ("TR_APP_VERSION=%s", SHORT_VERSION_STRING),
|
||||||
tr_strdup_printf ("TR_TIME_LOCALTIME=%s", timeStr),
|
tr_strdup_printf ("TR_TIME_LOCALTIME=%s", timeStr),
|
||||||
tr_strdup_printf ("TR_TORRENT_DIR=%s", tor->currentDir),
|
tr_strdup_printf ("TR_TORRENT_DIR=%s", tor->currentDir),
|
||||||
tr_strdup_printf ("TR_TORRENT_ID=%d", tr_torrentId (tor)),
|
|
||||||
tr_strdup_printf ("TR_TORRENT_HASH=%s", tor->info.hashString),
|
tr_strdup_printf ("TR_TORRENT_HASH=%s", tor->info.hashString),
|
||||||
|
tr_strdup_printf ("TR_TORRENT_ID=%d", tr_torrentId (tor)),
|
||||||
tr_strdup_printf ("TR_TORRENT_NAME=%s", tr_torrentName (tor)),
|
tr_strdup_printf ("TR_TORRENT_NAME=%s", tr_torrentName (tor)),
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
tr_logAddTorInfo (tor, "Calling script \"%s\"", script);
|
tr_logAddTorInfo (tor, "Calling script \"%s\"", script);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/* Win32 environment block strings should be sorted alphabetically */
|
||||||
|
for (i = 1; env[i] != NULL; ++i)
|
||||||
|
assert (strcmp (env[i - 1], env[i]) < 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (_spawnvpe (_P_NOWAIT, script, (const char* const*)cmd, (const char* const*)env) == -1)
|
|
||||||
tr_logAddTorErr (tor, "error executing script \"%s\": %s", cmd[0], tr_strerror (errno));
|
wchar_t * wide_script = tr_win32_utf8_to_native (script, -1);
|
||||||
#else
|
|
||||||
|
size_t env_block_size = 0;
|
||||||
|
char * env_block = NULL;
|
||||||
|
for (i = 0; env[i] != NULL; ++i)
|
||||||
|
{
|
||||||
|
const size_t len = strlen (env[i]) + 1;
|
||||||
|
env_block = tr_renew (char, env_block, env_block_size + len + 1);
|
||||||
|
memcpy (env_block + env_block_size, env[i], len + 1);
|
||||||
|
env_block_size += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t * wide_env_block = NULL;
|
||||||
|
if (env_block != NULL)
|
||||||
|
{
|
||||||
|
env_block[env_block_size] = '\0';
|
||||||
|
wide_env_block = tr_win32_utf8_to_native (env_block, env_block_size + 1);
|
||||||
|
tr_free (env_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTUPINFOW si = { 0, };
|
||||||
|
si.cb = sizeof (si);
|
||||||
|
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||||
|
si.wShowWindow = SW_HIDE;
|
||||||
|
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
|
||||||
|
if (CreateProcessW (wide_script, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS |
|
||||||
|
CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW | CREATE_DEFAULT_ERROR_MODE |
|
||||||
|
DETACHED_PROCESS, wide_env_block, L"\\", &si, &pi))
|
||||||
|
{
|
||||||
|
CloseHandle (pi.hThread);
|
||||||
|
CloseHandle (pi.hProcess);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char * const message = tr_win32_format_message (GetLastError ());
|
||||||
|
tr_logAddTorErr (tor, "error executing script \"%s\": %s", script, message);
|
||||||
|
tr_free (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr_free (wide_env_block);
|
||||||
|
tr_free (wide_script);
|
||||||
|
|
||||||
|
#else /* _WIN32 */
|
||||||
|
|
||||||
signal (SIGCHLD, onSigCHLD);
|
signal (SIGCHLD, onSigCHLD);
|
||||||
|
|
||||||
if (!fork ())
|
if (!fork ())
|
||||||
{
|
{
|
||||||
for (i=0; env[i]; ++i)
|
for (i = 0; env[i] != NULL; ++i)
|
||||||
putenv (env[i]);
|
putenv (env[i]);
|
||||||
|
|
||||||
|
chdir ("/");
|
||||||
|
|
||||||
if (execvp (script, cmd) == -1)
|
if (execvp (script, cmd) == -1)
|
||||||
tr_logAddTorErr (tor, "error executing script \"%s\": %s", cmd[0], tr_strerror (errno));
|
tr_logAddTorErr (tor, "error executing script \"%s\": %s", script, tr_strerror (errno));
|
||||||
|
|
||||||
_exit (0);
|
_exit (0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i=0; cmd[i]; ++i) tr_free (cmd[i]);
|
#endif /* _WIN32 */
|
||||||
for (i=0; env[i]; ++i) tr_free (env[i]);
|
|
||||||
|
for (i = 0; cmd[i] != NULL; ++i)
|
||||||
|
tr_free (cmd[i]);
|
||||||
|
for (i = 0; env[i] != NULL; ++i)
|
||||||
|
tr_free (env[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue