[geany/geany] b032f2: Merge pull request #426 from techee/run_script_tmp
Colomban Wendling
git-noreply at xxxxx
Wed Mar 4 12:58:02 UTC 2015
Branch: refs/heads/master
Author: Colomban Wendling <ban at herbesfolles.org>
Committer: Colomban Wendling <ban at herbesfolles.org>
Date: Wed, 04 Mar 2015 12:58:02 UTC
Commit: b032f2e214eb52fb79803532fb2b7a7f581be362
https://github.com/geany/geany/commit/b032f2e214eb52fb79803532fb2b7a7f581be362
Log Message:
-----------
Merge pull request #426 from techee/run_script_tmp
Create geany_run_script.sh in the temporary directory instead of the
working directory.
Modified Paths:
--------------
doc/geany.txt
src/build.c
Modified: doc/geany.txt
5 lines changed, 3 insertions(+), 2 deletions(-)
===================================================================
@@ -3022,8 +3022,9 @@ The Terminal field of the tools preferences tab requires a command to
execute the terminal program and to pass it the name of the Geany run
script that it should execute in a Bourne compatible shell (eg /bin/sh).
The marker "%c" is substituted with the name of the Geany run script,
-which is created in the working directory set in the Build commands
-dialog, see `Build menu commands dialog`_ for details.
+which is created in the temporary directory and which changes the working
+directory to the directory set in the Build commands dialog, see
+`Build menu commands dialog`_ for details.
As an example the default (Linux) command is::
Modified: src/build.c
167 lines changed, 71 insertions(+), 96 deletions(-)
===================================================================
@@ -91,9 +91,9 @@ typedef struct RunInfo
static RunInfo *run_info;
#ifdef G_OS_WIN32
-static const gchar RUN_SCRIPT_CMD[] = "geany_run_script.bat";
+static const gchar RUN_SCRIPT_CMD[] = "geany_run_script_XXXXXX.bat";
#else
-static const gchar RUN_SCRIPT_CMD[] = "./geany_run_script.sh";
+static const gchar RUN_SCRIPT_CMD[] = "geany_run_script_XXXXXX.sh";
#endif
/* pack group (<8) and command (<32) into a user_data pointer */
@@ -128,7 +128,7 @@ static guint build_items_count = 9;
static void build_exit_cb(GPid child_pid, gint status, gpointer user_data);
static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data);
#endif
-static gboolean build_create_shellscript(const gchar *fname, const gchar *working_dir, const gchar *cmd, gboolean autoclose, GError **error);
+static gchar *build_create_shellscript(const gchar *working_dir, const gchar *cmd, gboolean autoclose, GError **error);
static GPid build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *dir);
static void set_stop_button(gboolean stop);
static void run_exit_cb(GPid child_pid, gint status, gpointer user_data);
@@ -879,54 +879,49 @@ static GPid build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *d
}
-/* Returns: NULL if there was an error, or the working directory the script was created in.
- * vte_cmd_nonscript is the location of a string which is filled with the command to be used
- * when vc->skip_run_script is set, otherwise it will be set to NULL */
-static gchar *prepare_run_script(GeanyDocument *doc, gchar **vte_cmd_nonscript, guint cmdindex)
+/* Returns: NULL if there was an error, or the command to be executed. If Geany is
+ * set to use a run script, the returned value is a path to the script that runs
+ * the command; otherwise the command itself is returned. working_dir is a pointer
+ * to the working directory from which the command is executed. Both strings are
+ * in the locale encoding. */
+static gchar *prepare_run_cmd(GeanyDocument *doc, gchar **working_dir, guint cmdindex)
{
GeanyBuildCommand *cmd = NULL;
- gchar *working_dir = NULL;
const gchar *cmd_working_dir;
gboolean autoclose = FALSE;
- gboolean result = FALSE;
- gchar *tmp;
- gchar *cmd_string;
+ gchar *cmd_string_utf8, *working_dir_utf8, *run_cmd, *cmd_string;
GError *error = NULL;
- if (vte_cmd_nonscript != NULL)
- *vte_cmd_nonscript = NULL;
-
cmd = get_build_cmd(doc, GEANY_GBG_EXEC, cmdindex, NULL);
- cmd_string = build_replace_placeholder(doc, cmd->command);
+ cmd_string_utf8 = build_replace_placeholder(doc, cmd->command);
cmd_working_dir = cmd->working_dir;
if (EMPTY(cmd_working_dir))
cmd_working_dir = "%d";
- working_dir = build_replace_placeholder(doc, cmd_working_dir); /* in utf-8 */
+ working_dir_utf8 = build_replace_placeholder(doc, cmd_working_dir);
+ *working_dir = utils_get_locale_from_utf8(working_dir_utf8);
/* only test whether working dir exists, don't change it or else Windows support will break
* (gspawn-win32-helper.exe is used by GLib and must be in $PATH which means current working
* dir where geany.exe was started from, so we can't change it) */
- if (EMPTY(working_dir) || ! g_file_test(working_dir, G_FILE_TEST_EXISTS) ||
- ! g_file_test(working_dir, G_FILE_TEST_IS_DIR))
+ if (EMPTY(*working_dir) || ! g_file_test(*working_dir, G_FILE_TEST_EXISTS) ||
+ ! g_file_test(*working_dir, G_FILE_TEST_IS_DIR))
{
ui_set_statusbar(TRUE, _("Failed to change the working directory to \"%s\""),
- !EMPTY(working_dir) ? working_dir : "<NULL>" );
- utils_free_pointers(2, cmd_string, working_dir, NULL);
+ !EMPTY(working_dir_utf8) ? working_dir_utf8 : "<NULL>" );
+ utils_free_pointers(3, cmd_string_utf8, working_dir_utf8, *working_dir, NULL);
return NULL;
}
+ cmd_string = utils_get_locale_from_utf8(cmd_string_utf8);
+
#ifdef HAVE_VTE
if (vte_info.have_vte && vc->run_in_vte)
{
if (vc->skip_run_script)
{
- if (vte_cmd_nonscript != NULL)
- *vte_cmd_nonscript = cmd_string;
- else
- g_free(cmd_string);
-
- return working_dir;
+ utils_free_pointers(2, cmd_string_utf8, working_dir_utf8, NULL);
+ return cmd_string;
}
else
/* don't wait for user input at the end of script when we are running in VTE */
@@ -934,38 +929,31 @@ static gchar *prepare_run_script(GeanyDocument *doc, gchar **vte_cmd_nonscript,
}
#endif
- /* RUN_SCRIPT_CMD should be ok in UTF8 without converting in locale because it
- * contains no umlauts */
- tmp = g_build_filename(working_dir, RUN_SCRIPT_CMD, NULL);
- result = build_create_shellscript(tmp, working_dir, cmd_string, autoclose, &error);
- if (! result)
+ run_cmd = build_create_shellscript(*working_dir, cmd_string, autoclose, &error);
+ if (!run_cmd)
{
ui_set_statusbar(TRUE, _("Failed to execute \"%s\" (start-script could not be created: %s)"),
- !EMPTY(cmd_string) ? cmd_string : NULL, error->message);
+ !EMPTY(cmd_string_utf8) ? cmd_string_utf8 : NULL, error->message);
g_error_free(error);
+ g_free(*working_dir);
}
- utils_free_pointers(2, cmd_string, tmp, NULL);
-
- if (result)
- return working_dir;
-
- g_free(working_dir);
- return NULL;
+ utils_free_pointers(3, cmd_string_utf8, working_dir_utf8, cmd_string, NULL);
+ return run_cmd;
}
static GPid build_run_cmd(GeanyDocument *doc, guint cmdindex)
{
gchar *working_dir;
- gchar *vte_cmd_nonscript = NULL;
+ gchar *run_cmd = NULL;
GError *error = NULL;
if (! DOC_VALID(doc) || doc->file_name == NULL)
return (GPid) 0;
- working_dir = prepare_run_script(doc, &vte_cmd_nonscript, cmdindex);
- if (working_dir == NULL)
+ run_cmd = prepare_run_cmd(doc, &working_dir, cmdindex);
+ if (run_cmd == NULL)
return (GPid) 0;
run_info[cmdindex].file_type_id = doc->file_type->id;
@@ -975,28 +963,23 @@ static GPid build_run_cmd(GeanyDocument *doc, guint cmdindex)
{
gchar *vte_cmd;
+ /* VTE expects commands in UTF-8 */
+ SETPTR(run_cmd, utils_get_utf8_from_locale(run_cmd));
+ SETPTR(working_dir, utils_get_utf8_from_locale(working_dir));
+
if (vc->skip_run_script)
- {
- SETPTR(vte_cmd_nonscript, utils_get_utf8_from_locale(vte_cmd_nonscript));
- vte_cmd = g_strconcat(vte_cmd_nonscript, "\n", NULL);
- g_free(vte_cmd_nonscript);
- }
+ vte_cmd = g_strconcat(run_cmd, "\n", NULL);
else
- vte_cmd = g_strconcat("\n/bin/sh ", RUN_SCRIPT_CMD, "\n", NULL);
+ vte_cmd = g_strconcat("\n/bin/sh ", run_cmd, "\n", NULL);
- /* change into current directory if it is not done by default */
- if (! vc->follow_path)
- {
- /* we need to convert the working_dir back to UTF-8 because the VTE expects it */
- gchar *utf8_working_dir = utils_get_utf8_from_locale(working_dir);
- vte_cwd(utf8_working_dir, TRUE);
- g_free(utf8_working_dir);
- }
+ vte_cwd(working_dir, TRUE);
if (! vte_send_cmd(vte_cmd))
{
ui_set_statusbar(FALSE,
_("Could not execute the file in the VTE because it probably contains a command."));
geany_debug("Could not execute the file in the VTE because it probably contains a command.");
+ if (!vc->skip_run_script)
+ g_unlink(run_cmd);
}
/* show the VTE */
@@ -1025,8 +1008,7 @@ static GPid build_run_cmd(GeanyDocument *doc, guint cmdindex)
_("Could not parse terminal command \"%s\" "
"(check Terminal tool setting in Preferences)"), tool_prefs.term_cmd);
run_info[cmdindex].pid = (GPid) 1;
- script_path = g_build_filename(working_dir, RUN_SCRIPT_CMD, NULL);
- g_unlink(script_path);
+ g_unlink(run_cmd);
goto free_strings;
}
@@ -1044,14 +1026,13 @@ static GPid build_run_cmd(GeanyDocument *doc, guint cmdindex)
_("Could not find terminal \"%s\" "
"(check path for Terminal tool setting in Preferences)"), tool_prefs.term_cmd);
run_info[cmdindex].pid = (GPid) 1;
- script_path = g_build_filename(working_dir, RUN_SCRIPT_CMD, NULL);
- g_unlink(script_path);
+ g_unlink(run_cmd);
goto free_strings;
}
for (i = 0; i < argv_len; i++)
{
- utils_str_replace_all(&(argv[i]), "%c", RUN_SCRIPT_CMD);
+ utils_str_replace_all(&(argv[i]), "%c", run_cmd);
}
if (! g_spawn_async(working_dir, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
@@ -1060,8 +1041,7 @@ static GPid build_run_cmd(GeanyDocument *doc, guint cmdindex)
geany_debug("g_spawn_async() failed: %s", error->message);
ui_set_statusbar(TRUE, _("Process failed (%s)"), error->message);
g_error_free(error);
- script_path = g_build_filename(working_dir, RUN_SCRIPT_CMD, NULL);
- g_unlink(script_path);
+ g_unlink(run_cmd);
error = NULL;
run_info[cmdindex].pid = (GPid) 0;
}
@@ -1079,6 +1059,7 @@ static GPid build_run_cmd(GeanyDocument *doc, guint cmdindex)
}
g_free(working_dir);
+ g_free(run_cmd);
return run_info[cmdindex].pid;
}
@@ -1270,36 +1251,28 @@ static void run_exit_cb(GPid child_pid, gint status, gpointer user_data)
}
-static void set_file_error_from_errno(GError **error, gint err, const gchar *prefix)
-{
- g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(err), "%s%s%s",
- prefix ? prefix : "", prefix ? ": " : "", g_strerror(err));
-}
-
-
/* write a little shellscript to call the executable (similar to anjuta_launcher but "internal")
- * fname is the full file name (including path) for the script to create */
-static gboolean build_create_shellscript(const gchar *fname, const gchar *working_dir, const gchar *cmd, gboolean autoclose, GError **error)
+ * working_dir and cmd are both in the locale encoding
+ * it returns the full file name (including path) of the created script in the locale encoding */
+static gchar *build_create_shellscript(const gchar *working_dir, const gchar *cmd, gboolean autoclose, GError **error)
{
- FILE *fp;
- gchar *str;
+ gint fd;
+ gchar *str, *fname;
gboolean success = TRUE;
#ifdef G_OS_WIN32
gchar *expanded_cmd;
#else
gchar *escaped_dir;
#endif
+ fd = g_file_open_tmp (RUN_SCRIPT_CMD, &fname, error);
+ if (fd < 0)
+ return NULL;
+ close(fd);
- fp = g_fopen(fname, "w");
- if (! fp)
- {
- set_file_error_from_errno(error, errno, "Failed to create file");
- return FALSE;
- }
#ifdef G_OS_WIN32
/* Expand environment variables like %blah%. */
expanded_cmd = win32_expand_environment_variables(cmd);
- str = g_strdup_printf("%s\n\n%s\ndel \"%%0\"\n\npause\n", expanded_cmd, (autoclose) ? "" : "pause");
+ str = g_strdup_printf("cd \"%s\"\n\n%s\n\n%s\ndel \"%%0\"\n\npause\n", working_dir, expanded_cmd, (autoclose) ? "" : "pause");
g_free(expanded_cmd);
#else
escaped_dir = g_strescape(working_dir, NULL);
@@ -1311,29 +1284,31 @@ static gboolean build_create_shellscript(const gchar *fname, const gchar *workin
g_free(escaped_dir);
#endif
- if (fputs(str, fp) < 0)
- {
- set_file_error_from_errno(error, errno, "Failed to write file");
+ if (!g_file_set_contents(fname, str, -1, error))
success = FALSE;
- }
g_free(str);
-
- if (fclose(fp) != 0)
- {
- if (error && ! *error) /* don't set error twice */
- set_file_error_from_errno(error, errno, "Failed to close file");
- success = FALSE;
- }
#ifdef __APPLE__
- if (g_chmod(fname, 0777) != 0)
+ if (success && g_chmod(fname, 0777) != 0)
{
- if (error && ! *error) /* don't set error twice */
- set_file_error_from_errno(error, errno, "Failed to make file executable");
+ if (error)
+ {
+ gint errsv = errno;
+
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv),
+ "Failed to make file executable: %s", g_strerror(errsv));
+ }
success = FALSE;
}
#endif
- return success;
+ if (!success)
+ {
+ g_unlink(fname);
+ g_free(fname);
+ fname = NULL;
+ }
+
+ return fname;
}
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list