Commit fb00a59c authored by Owen Taylor's avatar Owen Taylor

at Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>

	* 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.
parent cb7c4d6c
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
* 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 <otaylor@redhat.com>
* 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 <lars@gtk.org> Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
* gtk/gtkclist.c (gtk_clist_set_selectable): new function * gtk/gtkclist.c (gtk_clist_set_selectable): new function
......
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
* 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 <otaylor@redhat.com>
* 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 <lars@gtk.org> Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
* gtk/gtkclist.c (gtk_clist_set_selectable): new function * gtk/gtkclist.c (gtk_clist_set_selectable): new function
......
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
* 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 <otaylor@redhat.com>
* 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 <lars@gtk.org> Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
* gtk/gtkclist.c (gtk_clist_set_selectable): new function * gtk/gtkclist.c (gtk_clist_set_selectable): new function
......
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
* 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 <otaylor@redhat.com>
* 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 <lars@gtk.org> Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
* gtk/gtkclist.c (gtk_clist_set_selectable): new function * gtk/gtkclist.c (gtk_clist_set_selectable): new function
......
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
* 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 <otaylor@redhat.com>
* 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 <lars@gtk.org> Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
* gtk/gtkclist.c (gtk_clist_set_selectable): new function * gtk/gtkclist.c (gtk_clist_set_selectable): new function
......
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
* 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 <otaylor@redhat.com>
* 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 <lars@gtk.org> Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
* gtk/gtkclist.c (gtk_clist_set_selectable): new function * gtk/gtkclist.c (gtk_clist_set_selectable): new function
......
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
* 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 <otaylor@redhat.com>
* 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 <lars@gtk.org> Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
* gtk/gtkclist.c (gtk_clist_set_selectable): new function * gtk/gtkclist.c (gtk_clist_set_selectable): new function
......
...@@ -39,6 +39,8 @@ Bugs: ...@@ -39,6 +39,8 @@ Bugs:
* Expose events aren't being generated correctly for DND demo * Expose events aren't being generated correctly for DND demo
* MappingNotify events produce warnings.
Additions: Additions:
* implement keyboard navigation in menus * implement keyboard navigation in menus
...@@ -272,4 +274,4 @@ Text/Edit widget: ...@@ -272,4 +274,4 @@ Text/Edit widget:
- "changed" emitted when doing deletes on empty Text widget. - "changed" emitted when doing deletes on empty Text widget.
- Delete IC in editable->unrealize, not editable->finalize? - Delete IC in editable->unrealize, not editable->finalize?
\ No newline at end of file
...@@ -89,6 +89,7 @@ main () ...@@ -89,6 +89,7 @@ main ()
printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n"); printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n");
printf("*** before re-running configure\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) || else if ((gtk_major_version != GTK_MAJOR_VERSION) ||
(gtk_minor_version != GTK_MINOR_VERSION) || (gtk_minor_version != GTK_MINOR_VERSION) ||
(gtk_micro_version != GTK_MICRO_VERSION)) (gtk_micro_version != GTK_MICRO_VERSION))
...@@ -98,6 +99,7 @@ main () ...@@ -98,6 +99,7 @@ main ()
printf("*** library (version %d.%d.%d)\n", printf("*** library (version %d.%d.%d)\n",
gtk_major_version, gtk_minor_version, gtk_micro_version); gtk_major_version, gtk_minor_version, gtk_micro_version);
} }
#endif /* defined (GTK_MAJOR_VERSION) ... */
else else
{ {
if ((gtk_major_version > major) || if ((gtk_major_version > major) ||
......
...@@ -245,13 +245,18 @@ static gchar* cmpl_completion_fullname (gchar*, CompletionState* cm ...@@ -245,13 +245,18 @@ static gchar* cmpl_completion_fullname (gchar*, CompletionState* cm
static CompletionDir* open_ref_dir (gchar* text_to_complete, static CompletionDir* open_ref_dir (gchar* text_to_complete,
gchar** remaining_text, gchar** remaining_text,
CompletionState* cmpl_state); CompletionState* cmpl_state);
static gboolean check_dir (gchar *dir_name,
struct stat *result,
gboolean *stat_subdirs);
static CompletionDir* open_dir (gchar* dir_name, static CompletionDir* open_dir (gchar* dir_name,
CompletionState* cmpl_state); CompletionState* cmpl_state);
static CompletionDir* open_user_dir (gchar* text_to_complete, static CompletionDir* open_user_dir (gchar* text_to_complete,
CompletionState *cmpl_state); CompletionState *cmpl_state);
static CompletionDir* open_relative_dir (gchar* dir_name, CompletionDir* dir, static CompletionDir* open_relative_dir (gchar* dir_name, CompletionDir* dir,
CompletionState *cmpl_state); 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_dir_fullname (CompletionDir* cmpl_dir);
static gint correct_parent (CompletionDir* cmpl_dir, static gint correct_parent (CompletionDir* cmpl_dir,
struct stat *sbuf); struct stat *sbuf);
...@@ -1890,7 +1895,7 @@ open_relative_dir(gchar* dir_name, ...@@ -1890,7 +1895,7 @@ open_relative_dir(gchar* dir_name,
/* after the cache lookup fails, really open a new directory */ /* after the cache lookup fails, really open a new directory */
static CompletionDirSent* 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; CompletionDirSent* sent;
DIR* directory; DIR* directory;
...@@ -1968,12 +1973,17 @@ open_new_dir(gchar* dir_name, struct stat* sbuf) ...@@ -1968,12 +1973,17 @@ open_new_dir(gchar* dir_name, struct stat* sbuf)
path_buf[path_buf_len] = '/'; path_buf[path_buf_len] = '/';
strcpy(path_buf + path_buf_len + 1, dirent_ptr->d_name); strcpy(path_buf + path_buf_len + 1, dirent_ptr->d_name);
if(stat(path_buf, &ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode)) if (stat_subdirs)
sent->entries[i].is_dir = 1; {
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 else
/* stat may fail, and we don't mind, since it could be a sent->entries[i].is_dir = 1;
* dangling symlink. */
sent->entries[i].is_dir = 0;
} }
qsort(sent->entries, sent->entry_count, sizeof(CompletionDirEntry), compare_cmpl_dir); qsort(sent->entries, sent->entry_count, sizeof(CompletionDirEntry), compare_cmpl_dir);
...@@ -1983,19 +1993,69 @@ open_new_dir(gchar* dir_name, struct stat* sbuf) ...@@ -1983,19 +1993,69 @@ open_new_dir(gchar* dir_name, struct stat* sbuf)
return sent; 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; i<n_no_stat_dirs; i++)
{
if (stat(no_stat_dirs[i].name, &no_stat_dirs[i].statbuf) == 0)
no_stat_dirs[i].present = TRUE;
}
}
if(stat(dir_name, result) < 0)
{
cmpl_errno = errno;
return FALSE;
}
*stat_subdirs = TRUE;
for (i=0; i<n_no_stat_dirs; i++)
{
if (no_stat_dirs[i].present &&
(no_stat_dirs[i].statbuf.st_dev == result->st_dev) &&
(no_stat_dirs[i].statbuf.st_ino == result->st_ino))
{
*stat_subdirs = FALSE;
break;
}
}
return TRUE;
}
/* open a directory by absolute pathname */ /* open a directory by absolute pathname */
static CompletionDir* static CompletionDir*
open_dir(gchar* dir_name, CompletionState* cmpl_state) open_dir(gchar* dir_name, CompletionState* cmpl_state)
{ {
struct stat sbuf; struct stat sbuf;
gboolean stat_subdirs;
CompletionDirSent *sent; CompletionDirSent *sent;
GList* cdsl; GList* cdsl;
if(stat(dir_name, &sbuf) < 0) if (!check_dir (dir_name, &sbuf, &stat_subdirs))
{ return NULL;
cmpl_errno = errno;
return NULL;
}
cdsl = cmpl_state->directory_sent_storage; cdsl = cmpl_state->directory_sent_storage;
...@@ -2011,7 +2071,7 @@ open_dir(gchar* dir_name, CompletionState* cmpl_state) ...@@ -2011,7 +2071,7 @@ open_dir(gchar* dir_name, CompletionState* cmpl_state)
cdsl = cdsl->next; cdsl = cdsl->next;
} }
sent = open_new_dir(dir_name, &sbuf); sent = open_new_dir(dir_name, &sbuf, stat_subdirs);
if (sent) { if (sent) {
cmpl_state->directory_sent_storage = cmpl_state->directory_sent_storage =
...@@ -2317,13 +2377,14 @@ find_completion_dir(gchar* text_to_complete, ...@@ -2317,13 +2377,14 @@ find_completion_dir(gchar* text_to_complete,
{ {
gchar* first_slash = strchr(text_to_complete, '/'); gchar* first_slash = strchr(text_to_complete, '/');
CompletionDir* dir = cmpl_state->reference_dir; CompletionDir* dir = cmpl_state->reference_dir;
CompletionDir* next;
*remaining_text = text_to_complete; *remaining_text = text_to_complete;
while(first_slash) while(first_slash)
{ {
gint len = first_slash - *remaining_text; gint len = first_slash - *remaining_text;
gint found = 0; gint found = 0;
gint found_index = -1; gchar *found_name = NULL; /* Quiet gcc */
gint i; gint i;
gchar* pat_buf = g_new (gchar, len + 1); gchar* pat_buf = g_new (gchar, len + 1);
...@@ -2344,40 +2405,37 @@ find_completion_dir(gchar* text_to_complete, ...@@ -2344,40 +2405,37 @@ find_completion_dir(gchar* text_to_complete,
else else
{ {
found = 1; 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, /* Perhaps we are trying to open an automount directory */
dir, cmpl_state); found_name = pat_buf;
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, '/');
} }
else
next = open_relative_dir(found_name, dir, cmpl_state);
if(!next)
{ {
g_free (pat_buf); g_free (pat_buf);
return NULL; 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); g_free (pat_buf);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment