From fb00a59c2f6d38b46f429f9b567562cc282d04eb Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Sat, 12 Sep 1998 14:41:04 +0000 Subject: [PATCH] at Sep 12 10:44:06 1998 Owen Taylor * gtkfilesel.c: Maintain a list of directories like /afs we know contain only directories, and avoid stat'ing files in those directories. (Because stat'ing all files in /afs is extremely expensive) To support automounters, try to open directories, even if we couldn't find them when reading their parent directory. --- ChangeLog | 17 ++++++ ChangeLog.pre-2-0 | 17 ++++++ ChangeLog.pre-2-10 | 17 ++++++ ChangeLog.pre-2-2 | 17 ++++++ ChangeLog.pre-2-4 | 17 ++++++ ChangeLog.pre-2-6 | 17 ++++++ ChangeLog.pre-2-8 | 17 ++++++ TODO | 4 +- gtk.m4 | 2 + gtk/gtkfilesel.c | 134 ++++++++++++++++++++++++++++++++------------- 10 files changed, 220 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ed33d347..e8b4f2790 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Sat Sep 12 10:44:06 1998 Owen Taylor + + * gtkfilesel.c: Maintain a list of directories like + /afs we know contain only directories, and avoid + stat'ing files in those directories. (Because + stat'ing all files in /afs is extremely expensive) + + To support automounters, try to open directories, + even if we couldn't find them when reading their + parent directory. + +Thu Sep 3 10:29:03 1998 Owen Taylor + + * gtk.m4: Conditionalize check for GTK_MAJOR_VERSION, + to allow the same gtk.m4 to work for 1.0.x and + 1.1.x. + Fri Sep 11 15:25:10 1998 Lars Hamann * gtk/gtkclist.c (gtk_clist_set_selectable): new function diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 1ed33d347..e8b4f2790 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,20 @@ +Sat Sep 12 10:44:06 1998 Owen Taylor + + * gtkfilesel.c: Maintain a list of directories like + /afs we know contain only directories, and avoid + stat'ing files in those directories. (Because + stat'ing all files in /afs is extremely expensive) + + To support automounters, try to open directories, + even if we couldn't find them when reading their + parent directory. + +Thu Sep 3 10:29:03 1998 Owen Taylor + + * gtk.m4: Conditionalize check for GTK_MAJOR_VERSION, + to allow the same gtk.m4 to work for 1.0.x and + 1.1.x. + Fri Sep 11 15:25:10 1998 Lars Hamann * gtk/gtkclist.c (gtk_clist_set_selectable): new function diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 1ed33d347..e8b4f2790 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,20 @@ +Sat Sep 12 10:44:06 1998 Owen Taylor + + * gtkfilesel.c: Maintain a list of directories like + /afs we know contain only directories, and avoid + stat'ing files in those directories. (Because + stat'ing all files in /afs is extremely expensive) + + To support automounters, try to open directories, + even if we couldn't find them when reading their + parent directory. + +Thu Sep 3 10:29:03 1998 Owen Taylor + + * gtk.m4: Conditionalize check for GTK_MAJOR_VERSION, + to allow the same gtk.m4 to work for 1.0.x and + 1.1.x. + Fri Sep 11 15:25:10 1998 Lars Hamann * gtk/gtkclist.c (gtk_clist_set_selectable): new function diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 1ed33d347..e8b4f2790 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,20 @@ +Sat Sep 12 10:44:06 1998 Owen Taylor + + * gtkfilesel.c: Maintain a list of directories like + /afs we know contain only directories, and avoid + stat'ing files in those directories. (Because + stat'ing all files in /afs is extremely expensive) + + To support automounters, try to open directories, + even if we couldn't find them when reading their + parent directory. + +Thu Sep 3 10:29:03 1998 Owen Taylor + + * gtk.m4: Conditionalize check for GTK_MAJOR_VERSION, + to allow the same gtk.m4 to work for 1.0.x and + 1.1.x. + Fri Sep 11 15:25:10 1998 Lars Hamann * gtk/gtkclist.c (gtk_clist_set_selectable): new function diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 1ed33d347..e8b4f2790 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,20 @@ +Sat Sep 12 10:44:06 1998 Owen Taylor + + * gtkfilesel.c: Maintain a list of directories like + /afs we know contain only directories, and avoid + stat'ing files in those directories. (Because + stat'ing all files in /afs is extremely expensive) + + To support automounters, try to open directories, + even if we couldn't find them when reading their + parent directory. + +Thu Sep 3 10:29:03 1998 Owen Taylor + + * gtk.m4: Conditionalize check for GTK_MAJOR_VERSION, + to allow the same gtk.m4 to work for 1.0.x and + 1.1.x. + Fri Sep 11 15:25:10 1998 Lars Hamann * gtk/gtkclist.c (gtk_clist_set_selectable): new function diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 1ed33d347..e8b4f2790 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,20 @@ +Sat Sep 12 10:44:06 1998 Owen Taylor + + * gtkfilesel.c: Maintain a list of directories like + /afs we know contain only directories, and avoid + stat'ing files in those directories. (Because + stat'ing all files in /afs is extremely expensive) + + To support automounters, try to open directories, + even if we couldn't find them when reading their + parent directory. + +Thu Sep 3 10:29:03 1998 Owen Taylor + + * gtk.m4: Conditionalize check for GTK_MAJOR_VERSION, + to allow the same gtk.m4 to work for 1.0.x and + 1.1.x. + Fri Sep 11 15:25:10 1998 Lars Hamann * gtk/gtkclist.c (gtk_clist_set_selectable): new function diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 1ed33d347..e8b4f2790 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,20 @@ +Sat Sep 12 10:44:06 1998 Owen Taylor + + * gtkfilesel.c: Maintain a list of directories like + /afs we know contain only directories, and avoid + stat'ing files in those directories. (Because + stat'ing all files in /afs is extremely expensive) + + To support automounters, try to open directories, + even if we couldn't find them when reading their + parent directory. + +Thu Sep 3 10:29:03 1998 Owen Taylor + + * gtk.m4: Conditionalize check for GTK_MAJOR_VERSION, + to allow the same gtk.m4 to work for 1.0.x and + 1.1.x. + Fri Sep 11 15:25:10 1998 Lars Hamann * gtk/gtkclist.c (gtk_clist_set_selectable): new function diff --git a/TODO b/TODO index 6f22b89b7..e0ae8d5f3 100644 --- a/TODO +++ b/TODO @@ -39,6 +39,8 @@ Bugs: * Expose events aren't being generated correctly for DND demo + * MappingNotify events produce warnings. + Additions: * implement keyboard navigation in menus @@ -272,4 +274,4 @@ Text/Edit widget: - "changed" emitted when doing deletes on empty Text widget. - - Delete IC in editable->unrealize, not editable->finalize? \ No newline at end of file + - Delete IC in editable->unrealize, not editable->finalize? diff --git a/gtk.m4 b/gtk.m4 index b7fb41979..0fcfd9f3c 100644 --- a/gtk.m4 +++ b/gtk.m4 @@ -89,6 +89,7 @@ main () printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n"); printf("*** before re-running configure\n"); } +#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION) else if ((gtk_major_version != GTK_MAJOR_VERSION) || (gtk_minor_version != GTK_MINOR_VERSION) || (gtk_micro_version != GTK_MICRO_VERSION)) @@ -98,6 +99,7 @@ main () printf("*** library (version %d.%d.%d)\n", gtk_major_version, gtk_minor_version, gtk_micro_version); } +#endif /* defined (GTK_MAJOR_VERSION) ... */ else { if ((gtk_major_version > major) || diff --git a/gtk/gtkfilesel.c b/gtk/gtkfilesel.c index f8903fbea..e6d7ff34b 100644 --- a/gtk/gtkfilesel.c +++ b/gtk/gtkfilesel.c @@ -245,13 +245,18 @@ static gchar* cmpl_completion_fullname (gchar*, CompletionState* cm static CompletionDir* open_ref_dir (gchar* text_to_complete, gchar** remaining_text, CompletionState* cmpl_state); +static gboolean check_dir (gchar *dir_name, + struct stat *result, + gboolean *stat_subdirs); static CompletionDir* open_dir (gchar* dir_name, CompletionState* cmpl_state); static CompletionDir* open_user_dir (gchar* text_to_complete, CompletionState *cmpl_state); static CompletionDir* open_relative_dir (gchar* dir_name, CompletionDir* dir, CompletionState *cmpl_state); -static CompletionDirSent* open_new_dir (gchar* dir_name, struct stat* sbuf); +static CompletionDirSent* open_new_dir (gchar* dir_name, + struct stat* sbuf, + gboolean stat_subdirs); static gint correct_dir_fullname (CompletionDir* cmpl_dir); static gint correct_parent (CompletionDir* cmpl_dir, struct stat *sbuf); @@ -1890,7 +1895,7 @@ open_relative_dir(gchar* dir_name, /* after the cache lookup fails, really open a new directory */ static CompletionDirSent* -open_new_dir(gchar* dir_name, struct stat* sbuf) +open_new_dir(gchar* dir_name, struct stat* sbuf, gboolean stat_subdirs) { CompletionDirSent* sent; DIR* directory; @@ -1968,12 +1973,17 @@ open_new_dir(gchar* dir_name, struct stat* sbuf) path_buf[path_buf_len] = '/'; strcpy(path_buf + path_buf_len + 1, dirent_ptr->d_name); - if(stat(path_buf, &ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode)) - sent->entries[i].is_dir = 1; + if (stat_subdirs) + { + if(stat(path_buf, &ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode)) + sent->entries[i].is_dir = 1; + else + /* stat may fail, and we don't mind, since it could be a + * dangling symlink. */ + sent->entries[i].is_dir = 0; + } else - /* stat may fail, and we don't mind, since it could be a - * dangling symlink. */ - sent->entries[i].is_dir = 0; + sent->entries[i].is_dir = 1; } qsort(sent->entries, sent->entry_count, sizeof(CompletionDirEntry), compare_cmpl_dir); @@ -1983,19 +1993,69 @@ open_new_dir(gchar* dir_name, struct stat* sbuf) return sent; } +static gboolean +check_dir(gchar *dir_name, struct stat *result, gboolean *stat_subdirs) +{ + /* A list of directories that we know only contain other directories. + * Trying to stat every file in these directories would be very + * expensive. + */ + + static struct { + gchar *name; + gboolean present; + struct stat statbuf; + } no_stat_dirs[] = { + { "/afs", FALSE, { 0 } }, + }; + + static gint n_no_stat_dirs = sizeof(no_stat_dirs) / sizeof(no_stat_dirs[0]); + static gboolean initialized = FALSE; + + gint i; + + if (!initialized) + { + initialized = TRUE; + for (i=0; ist_dev) && + (no_stat_dirs[i].statbuf.st_ino == result->st_ino)) + { + *stat_subdirs = FALSE; + break; + } + } + + return TRUE; +} + /* open a directory by absolute pathname */ static CompletionDir* open_dir(gchar* dir_name, CompletionState* cmpl_state) { struct stat sbuf; + gboolean stat_subdirs; CompletionDirSent *sent; GList* cdsl; - if(stat(dir_name, &sbuf) < 0) - { - cmpl_errno = errno; - return NULL; - } + if (!check_dir (dir_name, &sbuf, &stat_subdirs)) + return NULL; cdsl = cmpl_state->directory_sent_storage; @@ -2011,7 +2071,7 @@ open_dir(gchar* dir_name, CompletionState* cmpl_state) cdsl = cdsl->next; } - sent = open_new_dir(dir_name, &sbuf); + sent = open_new_dir(dir_name, &sbuf, stat_subdirs); if (sent) { cmpl_state->directory_sent_storage = @@ -2317,13 +2377,14 @@ find_completion_dir(gchar* text_to_complete, { gchar* first_slash = strchr(text_to_complete, '/'); CompletionDir* dir = cmpl_state->reference_dir; + CompletionDir* next; *remaining_text = text_to_complete; while(first_slash) { gint len = first_slash - *remaining_text; gint found = 0; - gint found_index = -1; + gchar *found_name = NULL; /* Quiet gcc */ gint i; gchar* pat_buf = g_new (gchar, len + 1); @@ -2344,40 +2405,37 @@ find_completion_dir(gchar* text_to_complete, else { found = 1; - found_index = i; + found_name = dir->sent->entries[i].entry_name; } } } - if(found) + if (!found) { - CompletionDir* next = open_relative_dir(dir->sent->entries[found_index].entry_name, - dir, cmpl_state); - - if(!next) - { - g_free (pat_buf); - return NULL; - } - - next->cmpl_parent = dir; - - dir = next; - - if(!correct_dir_fullname(dir)) - { - g_free(pat_buf); - return NULL; - } - - *remaining_text = first_slash + 1; - first_slash = strchr(*remaining_text, '/'); + /* Perhaps we are trying to open an automount directory */ + found_name = pat_buf; } - else + + next = open_relative_dir(found_name, dir, cmpl_state); + + if(!next) { g_free (pat_buf); return NULL; } + + next->cmpl_parent = dir; + + dir = next; + + if(!correct_dir_fullname(dir)) + { + g_free(pat_buf); + return NULL; + } + + *remaining_text = first_slash + 1; + first_slash = strchr(*remaining_text, '/'); g_free (pat_buf); } -- 2.43.2