/* Configures environment variables before shellout. Should be used in pair * with cleanup_shellout_env(). */ static void setup_shellout_env(void) { const char *mount_file; const char *term_multiplexer_fmt; char *escaped_path; char *cmd; /* Need to use internal value instead of getcwd() for a symlink directory. */ env_set("PWD", curr_view->curr_dir); mount_file = fuse_get_mount_file(curr_view->curr_dir); if(mount_file == NULL) { env_remove(FUSE_FILE_ENVVAR); return; } env_set(FUSE_FILE_ENVVAR, mount_file); switch(curr_stats.term_multiplexer) { case TM_TMUX: term_multiplexer_fmt = "tmux set-environment %s %s"; break; case TM_SCREEN: term_multiplexer_fmt = "screen -X setenv %s %s"; break; default: return; } escaped_path = shell_like_escape(mount_file, 0); cmd = format_str(term_multiplexer_fmt, FUSE_FILE_ENVVAR, escaped_path); (void)vifm_system(cmd); free(cmd); free(escaped_path); }
/* Copies example vifmrc file from shared files to the ~/.vifm directory. */ static void create_rc_file(void) { LOG_FUNC_ENTER; char command[] = CP_RC; (void)vifm_system(command); }
/* Copies help file from shared files to the ~/.vifm directory. */ static void create_help_file(void) { LOG_FUNC_ENTER; char command[] = CP_HELP; (void)vifm_system(command); }
int shellout(const char command[], ShellPause pause, int use_term_multiplexer) { char *cmd; int result; int ec; if(pause == PAUSE_ALWAYS && command != NULL && ends_with(command, "&")) { pause = PAUSE_ON_ERROR; } setup_shellout_env(); cmd = gen_shell_cmd(command, pause == PAUSE_ALWAYS, use_term_multiplexer); if(curr_stats.load_stage != 0) { endwin(); } ec = vifm_system(cmd); /* No WIFEXITED(ec) check here, since vifm_system(...) shouldn't return until * subprocess exited. */ result = WEXITSTATUS(ec); cleanup_shellout_env(); if(result != 0 && pause == PAUSE_ON_ERROR) { LOG_ERROR_MSG("Subprocess (%s) exit code: %d (0x%x); status = 0x%x", cmd, result, result, ec); pause_shell(); } free(cmd); /* Force views update. */ ui_view_schedule_reload(&lwin); ui_view_schedule_reload(&rwin); recover_after_shellout(); if(!curr_stats.skip_shellout_redraw) { /* Redraw to handle resizing of terminal that we could have missed. */ curr_stats.need_update = UT_FULL; } if(curr_stats.load_stage != 0) { curs_set(FALSE); } return result; }
/* Changes $PWD in running GNU/screen session to the specified path. Needed for * symlink directories and sshfs mounts. */ static void set_pwd_in_screen(const char path[]) { char *const escaped_dir = shell_like_escape(path, 0); char *const set_pwd = format_str("screen -X setenv PWD %s", escaped_dir); (void)vifm_system(set_pwd); free(set_pwd); free(escaped_dir); }
/* Runs the cmd in a split window of terminal multiplexer. Runs shell, if cmd * is NULL. */ static void run_in_split(const FileView *view, const char cmd[]) { char *const escaped_cmd = (cmd == NULL) ? strdup(cfg.shell) : shell_like_escape(cmd, 0); setup_shellout_env(); if(curr_stats.term_multiplexer == TM_TMUX) { char cmd[1024]; snprintf(cmd, sizeof(cmd), "tmux split-window %s", escaped_cmd); (void)vifm_system(cmd); } else if(curr_stats.term_multiplexer == TM_SCREEN) { char cmd[1024]; /* "eval" executes each argument as a separate argument, but escaping rules * are not exactly like in shell, so last command is run separately. */ char *const escaped_dir = shell_like_escape(flist_get_dir(view), 0); snprintf(cmd, sizeof(cmd), "screen -X eval chdir\\ %s 'focus bottom' " "split 'focus bottom'", escaped_dir); free(escaped_dir); (void)vifm_system(cmd); snprintf(cmd, sizeof(cmd), "screen -X screen vifm-screen-split %s", escaped_cmd); (void)vifm_system(cmd); } else { assert(0 && "Unexpected active terminal multiplexer value."); } cleanup_shellout_env(); free(escaped_cmd); }
/* Cleans up some environment changes made by setup_shellout_env() after command * execution ends. */ static void cleanup_shellout_env(void) { const char *term_multiplexer_fmt; char *cmd; switch(curr_stats.term_multiplexer) { case TM_TMUX: term_multiplexer_fmt = "tmux set-environment -u %s"; break; case TM_SCREEN: term_multiplexer_fmt = "screen -X unsetenv %s"; break; default: return; } cmd = format_str(term_multiplexer_fmt, FUSE_FILE_ENVVAR); (void)vifm_system(cmd); free(cmd); }
void fuse_unmount_all(void) { fuse_mount_t *runner; if(fuse_mounts == NULL) { return; } if(vifm_chdir("/") != 0) { return; } runner = fuse_mounts; while(runner != NULL) { char buf[14 + PATH_MAX + 1]; char *escaped_filename; escaped_filename = escape_filename(runner->mount_point, 0); snprintf(buf, sizeof(buf), "%s %s", curr_stats.fuse_umount_cmd, escaped_filename); free(escaped_filename); (void)vifm_system(buf); if(path_exists(runner->mount_point, DEREF)) { rmdir(runner->mount_point); } runner = runner->next; } leave_invalid_dir(&lwin); leave_invalid_dir(&rwin); }
int vim_run_choose_cmd(const FileView *view) { char *expanded_cmd; if(is_null_or_empty(curr_stats.on_choose)) { return 0; } if(!view->dir_entry[view->list_pos].selected) { erase_selection(curr_view); } expanded_cmd = expand_macros(curr_stats.on_choose, NULL, NULL, 1); if(vifm_system(expanded_cmd) != EXIT_SUCCESS) { free(expanded_cmd); return 1; } return 0; }