mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 23:24:39 +00:00
Improved fork reporting
Made autosuggestion work properly for tilde expansion
This commit is contained in:
parent
dc23af6b32
commit
0e3eb38f11
6 changed files with 42 additions and 18 deletions
|
@ -1961,7 +1961,7 @@ void append_path_component(wcstring &path, const wcstring &component)
|
|||
}
|
||||
|
||||
extern "C" {
|
||||
__attribute__((noinline)) void debug_thread_error(void) {}
|
||||
__attribute__((noinline)) void debug_thread_error(void) { while (1) sleep(9999999); }
|
||||
}
|
||||
|
||||
|
||||
|
@ -2015,11 +2015,11 @@ void assert_is_background_thread(const char *who)
|
|||
}
|
||||
}
|
||||
|
||||
void assert_is_locked(void *vmutex, const char *who)
|
||||
void assert_is_locked(void *vmutex, const char *who, const char *caller)
|
||||
{
|
||||
pthread_mutex_t *mutex = static_cast<pthread_mutex_t*>(vmutex);
|
||||
if (0 == pthread_mutex_trylock(mutex)) {
|
||||
fprintf(stderr, "Warning: %s is not locked when it should be. Break on debug_thread_error to debug.\n", who);
|
||||
fprintf(stderr, "Warning: %s is not locked when it should be in '%s'. Break on debug_thread_error to debug.\n", who, caller);
|
||||
debug_thread_error();
|
||||
pthread_mutex_unlock(mutex);
|
||||
}
|
||||
|
|
4
common.h
4
common.h
|
@ -268,8 +268,8 @@ void assert_is_background_thread(const char *who);
|
|||
#define ASSERT_IS_BACKGROUND_THREAD() ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(__FUNCTION__)
|
||||
|
||||
/* Useful macro for asserting that a lock is locked. This doesn't check whether this thread locked it, which it would be nice if it did, but here it is anyways. */
|
||||
void assert_is_locked(void *mutex, const char *who);
|
||||
#define ASSERT_IS_LOCKED(x) assert_is_locked((void *)(&x), #x)
|
||||
void assert_is_locked(void *mutex, const char *who, const char *caller);
|
||||
#define ASSERT_IS_LOCKED(x) assert_is_locked((void *)(&x), #x, __FUNCTION__)
|
||||
|
||||
/**
|
||||
Converts the wide character string \c in into it's narrow
|
||||
|
|
1
env.h
1
env.h
|
@ -184,6 +184,7 @@ public:
|
|||
};
|
||||
|
||||
extern bool g_log_forks;
|
||||
extern int g_fork_count;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
10
exec.cpp
10
exec.cpp
|
@ -690,7 +690,7 @@ void exec( parser_t &parser, job_t *j )
|
|||
{
|
||||
/* Call fork. No need to wait for threads since our use is confined and simple. */
|
||||
if (g_log_forks) {
|
||||
printf("Executing keepalive fork for '%ls'\n", j->command_wcstr());
|
||||
printf("fork #%d: Executing keepalive fork for '%ls'\n", g_fork_count, j->command_wcstr());
|
||||
}
|
||||
keepalive.pid = execute_fork(false);
|
||||
if( keepalive.pid == 0 )
|
||||
|
@ -1101,7 +1101,7 @@ void exec( parser_t &parser, job_t *j )
|
|||
|
||||
/* We don't have to drain threads here because our child process is simple */
|
||||
if (g_log_forks) {
|
||||
printf("Executing fork for internal buffer for '%ls'\n", p->argv0() ? p->argv0() : L"(null)");
|
||||
printf("fork #%d: Executing fork for internal buffer for '%ls'\n", g_fork_count, p->argv0() ? p->argv0() : L"(null)");
|
||||
}
|
||||
pid = execute_fork(false);
|
||||
if( pid == 0 )
|
||||
|
@ -1173,7 +1173,7 @@ void exec( parser_t &parser, job_t *j )
|
|||
if (! skip_fork && ! j->io) {
|
||||
/* PCA for some reason, fish forks a lot, even for basic builtins like echo just to write out their buffers. I'm certain a lot of this is unnecessary, but I am not sure exactly when. If j->io is NULL, then it means there's no pipes or anything, so we can certainly just write out our data. Beyond that, we may be able to do the same if io_get returns 0 for STDOUT_FILENO and STDERR_FILENO. */
|
||||
if (g_log_forks) {
|
||||
printf("Skipping fork for internal builtin for '%ls' (io is %p, job_io is %p)\n", p->argv0(), io, j->io);
|
||||
printf("fork #-: Skipping fork for internal builtin for '%ls' (io is %p, job_io is %p)\n", p->argv0(), io, j->io);
|
||||
}
|
||||
const wcstring &out = get_stdout_buffer(), &err = get_stderr_buffer();
|
||||
char *outbuff = wcs2str(out.c_str()), *errbuff = wcs2str(err.c_str());
|
||||
|
@ -1269,7 +1269,9 @@ void exec( parser_t &parser, job_t *j )
|
|||
|
||||
const wchar_t *reader_current_filename();
|
||||
if (g_log_forks) {
|
||||
printf("forking for '%s' in '%ls'\n", actual_cmd, reader_current_filename());
|
||||
const wchar_t *file = reader_current_filename();
|
||||
const wchar_t *func = parser_t::principal_parser().is_function();
|
||||
printf("fork #%d: forking for '%s' in '%ls:%ls'\n", g_fork_count, actual_cmd, file ? file : L"", func ? func : L"?");
|
||||
}
|
||||
pid = execute_fork(false);
|
||||
if( pid == 0 )
|
||||
|
|
|
@ -561,17 +561,38 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di
|
|||
{
|
||||
wcstring dir = tok_last( &tok );
|
||||
wcstring suggested_path;
|
||||
|
||||
if (is_potential_path(dir, &suggested_path, true /* require directory */)) {
|
||||
|
||||
/* suggested_path needs to actually have dir as a prefix (perhaps with different case). Handle stuff like ./ */
|
||||
bool wants_dot_slash = string_prefixes_string(L"./", dir);
|
||||
bool has_dot_slash = string_prefixes_string(L"./", suggested_path);
|
||||
|
||||
|
||||
if (wants_dot_slash && ! has_dot_slash) {
|
||||
suggested_path.insert(0, L"./");
|
||||
} else if (! wants_dot_slash && has_dot_slash) {
|
||||
suggested_path.erase(0, 2);
|
||||
}
|
||||
|
||||
bool wants_tilde = string_prefixes_string(L"~", dir);
|
||||
bool has_tilde = string_prefixes_string(L"~", suggested_path);
|
||||
if (wants_tilde && ! has_tilde) {
|
||||
// The input string has a tilde, the output string does not
|
||||
// Extract the tilde part, expand it, see if the expansion prefixes the suggestion
|
||||
// If so, replace it with the tilde part
|
||||
size_t slash_idx = dir.find(L'/');
|
||||
const wcstring tilde_part(dir, 0, slash_idx); //note that slash_idx is npos this will return everything
|
||||
|
||||
// Expand the tilde
|
||||
wcstring expanded_tilde = tilde_part;
|
||||
expand_tilde(expanded_tilde);
|
||||
|
||||
// Replace it
|
||||
if (string_prefixes_string(expanded_tilde, suggested_path)) {
|
||||
suggested_path.replace(0, expanded_tilde.size(), tilde_part);
|
||||
}
|
||||
}
|
||||
|
||||
suggestion = str;
|
||||
suggestion.erase(tok_get_pos(&tok));
|
||||
suggestion.append(suggested_path);
|
||||
|
|
16
parser.h
16
parser.h
|
@ -307,14 +307,6 @@ class parser_t {
|
|||
parser_t(const parser_t&);
|
||||
parser_t& operator=(const parser_t&);
|
||||
|
||||
/**
|
||||
Returns the name of the currently evaluated function if we are
|
||||
currently evaluating a function, null otherwise. This is tested by
|
||||
moving down the block-scope-stack, checking every block if it is of
|
||||
type FUNCTION_CALL.
|
||||
*/
|
||||
const wchar_t *is_function() const;
|
||||
|
||||
void parse_job_argument_list( process_t *p, job_t *j, tokenizer *tok, std::vector<completion_t>& );
|
||||
int parse_job( process_t *p, job_t *j, tokenizer *tok );
|
||||
void skipped_exec( job_t * j );
|
||||
|
@ -326,6 +318,14 @@ class parser_t {
|
|||
public:
|
||||
std::vector<profile_item_t> profile_items;
|
||||
|
||||
/**
|
||||
Returns the name of the currently evaluated function if we are
|
||||
currently evaluating a function, null otherwise. This is tested by
|
||||
moving down the block-scope-stack, checking every block if it is of
|
||||
type FUNCTION_CALL.
|
||||
*/
|
||||
const wchar_t *is_function() const;
|
||||
|
||||
/** Get the "principal" parser, whatever that is */
|
||||
static parser_t &principal_parser();
|
||||
|
||||
|
|
Loading…
Reference in a new issue