1
0
mirror of https://gitlab.gnome.org/GNOME/glib.git synced 2025-08-11 03:34:05 +02:00
Files
.gitlab-ci
docs
fuzzing
gio
completion
fam
gdbus-2.0
gvdb
inotify
kqueue
tests
win32
xdgmime
data-to-c.py
dbus-daemon.xml
gaction.c
gaction.h
gactiongroup.c
gactiongroup.h
gactiongroupexporter.c
gactiongroupexporter.h
gactionmap.c
gactionmap.h
gappinfo.c
gappinfo.h
gappinfoprivate.h
gapplication-tool.c
gapplication.c
gapplication.h
gapplicationcommandline.c
gapplicationcommandline.h
gapplicationimpl-dbus.c
gapplicationimpl.h
gasynchelper.c
gasynchelper.h
gasyncinitable.c
gasyncinitable.h
gasyncresult.c
gasyncresult.h
gbufferedinputstream.c
gbufferedinputstream.h
gbufferedoutputstream.c
gbufferedoutputstream.h
gbytesicon.c
gbytesicon.h
gcancellable.c
gcancellable.h
gcharsetconverter.c
gcharsetconverter.h
gcocoanotificationbackend.m
gcontenttype-win32.c
gcontenttype.c
gcontenttype.h
gcontenttypeprivate.h
gcontextspecificgroup.c
gcontextspecificgroup.h
gconverter.c
gconverter.h
gconverterinputstream.c
gconverterinputstream.h
gconverteroutputstream.c
gconverteroutputstream.h
gcredentials.c
gcredentials.h
gcredentialsprivate.h
gdatagrambased.c
gdatagrambased.h
gdatainputstream.c
gdatainputstream.h
gdataoutputstream.c
gdataoutputstream.h
gdbus-tool.c
gdbusactiongroup-private.h
gdbusactiongroup.c
gdbusactiongroup.h
gdbusaddress.c
gdbusaddress.h
gdbusauth.c
gdbusauth.h
gdbusauthmechanism.c
gdbusauthmechanism.h
gdbusauthmechanismanon.c
gdbusauthmechanismanon.h
gdbusauthmechanismexternal.c
gdbusauthmechanismexternal.h
gdbusauthmechanismsha1.c
gdbusauthmechanismsha1.h
gdbusauthobserver.c
gdbusauthobserver.h
gdbusconnection.c
gdbusconnection.h
gdbusdaemon.c
gdbusdaemon.h
gdbuserror.c
gdbuserror.h
gdbusinterface.c
gdbusinterface.h
gdbusinterfaceskeleton.c
gdbusinterfaceskeleton.h
gdbusintrospection.c
gdbusintrospection.h
gdbusmenumodel.c
gdbusmenumodel.h
gdbusmessage.c
gdbusmessage.h
gdbusmethodinvocation.c
gdbusmethodinvocation.h
gdbusnameowning.c
gdbusnameowning.h
gdbusnamewatching.c
gdbusnamewatching.h
gdbusobject.c
gdbusobject.h
gdbusobjectmanager.c
gdbusobjectmanager.h
gdbusobjectmanagerclient.c
gdbusobjectmanagerclient.h
gdbusobjectmanagerserver.c
gdbusobjectmanagerserver.h
gdbusobjectproxy.c
gdbusobjectproxy.h
gdbusobjectskeleton.c
gdbusobjectskeleton.h
gdbusprivate.c
gdbusprivate.h
gdbusproxy.c
gdbusproxy.h
gdbusserver.c
gdbusserver.h
gdbusutils.c
gdbusutils.h
gdelayedsettingsbackend.c
gdelayedsettingsbackend.h
gdesktopappinfo.c
gdesktopappinfo.h
gdocumentportal.c
gdocumentportal.h
gdrive.c
gdrive.h
gdtlsclientconnection.c
gdtlsclientconnection.h
gdtlsconnection.c
gdtlsconnection.h
gdtlsserverconnection.c
gdtlsserverconnection.h
gdummyfile.c
gdummyfile.h
gdummyproxyresolver.c
gdummyproxyresolver.h
gdummytlsbackend.c
gdummytlsbackend.h
gemblem.c
gemblem.h
gemblemedicon.c
gemblemedicon.h
gfdonotificationbackend.c
gfile.c
gfile.h
gfileattribute-priv.h
gfileattribute.c
gfileattribute.h
gfiledescriptorbased.c
gfiledescriptorbased.h
gfileenumerator.c
gfileenumerator.h
gfileicon.c
gfileicon.h
gfileinfo-priv.h
gfileinfo.c
gfileinfo.h
gfileinputstream.c
gfileinputstream.h
gfileiostream.c
gfileiostream.h
gfilemonitor.c
gfilemonitor.h
gfilenamecompleter.c
gfilenamecompleter.h
gfileoutputstream.c
gfileoutputstream.h
gfilterinputstream.c
gfilterinputstream.h
gfilteroutputstream.c
gfilteroutputstream.h
ggtknotificationbackend.c
ghttpproxy.c
ghttpproxy.h
gicon.c
gicon.h
ginetaddress.c
ginetaddress.h
ginetaddressmask.c
ginetaddressmask.h
ginetsocketaddress.c
ginetsocketaddress.h
ginitable.c
ginitable.h
ginputstream.c
ginputstream.h
gio-autocleanups.h
gio-querymodules-wrapper.py
gio-querymodules.c
gio-tool-cat.c
gio-tool-copy.c
gio-tool-info.c
gio-tool-list.c
gio-tool-mime.c
gio-tool-mkdir.c
gio-tool-monitor.c
gio-tool-mount.c
gio-tool-move.c
gio-tool-open.c
gio-tool-remove.c
gio-tool-rename.c
gio-tool-save.c
gio-tool-set.c
gio-tool-trash.c
gio-tool-tree.c
gio-tool.c
gio-tool.h
gio.h
gio.rc.in
gio.stp.in
gio_probes.d
gio_trace.h
gioenums.h
gioenumtypes.c.template
gioenumtypes.h.template
gioerror.c
gioerror.h
giomodule-priv.c
giomodule-priv.h
giomodule.c
giomodule.h
gioprivate.h
gioscheduler.c
gioscheduler.h
giostream.c
giostream.h
giotypes.h
giowin32-priv.h
giowin32-private.c
gkeyfilesettingsbackend.c
glib-compile-resources.c
glib-compile-schemas.c
glistmodel.c
glistmodel.h
gliststore.c
gliststore.h
gloadableicon.c
gloadableicon.h
glocalfile.c
glocalfile.h
glocalfileenumerator.c
glocalfileenumerator.h
glocalfileinfo.c
glocalfileinfo.h
glocalfileinputstream.c
glocalfileinputstream.h
glocalfileiostream.c
glocalfileiostream.h
glocalfilemonitor.c
glocalfilemonitor.h
glocalfileoutputstream.c
glocalfileoutputstream.h
glocalvfs.c
glocalvfs.h
gmarshal-internal.c
gmarshal-internal.h
gmarshal-internal.list
gmemoryinputstream.c
gmemoryinputstream.h
gmemorymonitor.c
gmemorymonitor.h
gmemorymonitordbus.c
gmemorymonitordbus.h
gmemorymonitorportal.c
gmemorymonitorportal.h
gmemoryoutputstream.c
gmemoryoutputstream.h
gmemorysettingsbackend.c
gmenu.c
gmenu.h
gmenuexporter.c
gmenuexporter.h
gmenumodel.c
gmenumodel.h
gmount.c
gmount.h
gmountoperation.c
gmountoperation.h
gmountprivate.h
gnativesocketaddress.c
gnativesocketaddress.h
gnativevolumemonitor.c
gnativevolumemonitor.h
gnetworkaddress.c
gnetworkaddress.h
gnetworking.c
gnetworking.h.in
gnetworkingprivate.h
gnetworkmonitor.c
gnetworkmonitor.h
gnetworkmonitorbase.c
gnetworkmonitorbase.h
gnetworkmonitornetlink.c
gnetworkmonitornetlink.h
gnetworkmonitornm.c
gnetworkmonitornm.h
gnetworkmonitorportal.c
gnetworkmonitorportal.h
gnetworkservice.c
gnetworkservice.h
gnextstepsettingsbackend.m
gnotification-private.h
gnotification.c
gnotification.h
gnotificationbackend.c
gnotificationbackend.h
gnullsettingsbackend.c
gopenuriportal.c
gopenuriportal.h
gosxappinfo.h
gosxappinfo.m
gosxcontenttype.m
goutputstream.c
goutputstream.h
gpermission.c
gpermission.h
gpollableinputstream.c
gpollableinputstream.h
gpollableoutputstream.c
gpollableoutputstream.h
gpollableutils.c
gpollableutils.h
gpollfilemonitor.c
gpollfilemonitor.h
gportalnotificationbackend.c
gportalsupport.c
gportalsupport.h
gpropertyaction.c
gpropertyaction.h
gproxy.c
gproxy.h
gproxyaddress.c
gproxyaddress.h
gproxyaddressenumerator.c
gproxyaddressenumerator.h
gproxyresolver.c
gproxyresolver.h
gproxyresolverportal.c
gproxyresolverportal.h
gregistrysettingsbackend.c
gregistrysettingsbackend.h
gremoteactiongroup.c
gremoteactiongroup.h
gresolver.c
gresolver.h
gresource-tool.c
gresource.c
gresource.h
gresourcefile.c
gresourcefile.h
gschema.dtd
gschema.its
gschema.loc
gseekable.c
gseekable.h
gsettings-mapping.c
gsettings-mapping.h
gsettings-tool.c
gsettings.c
gsettings.h
gsettingsbackend.c
gsettingsbackend.h
gsettingsbackendinternal.h
gsettingsschema-internal.h
gsettingsschema.c
gsettingsschema.h
gsimpleaction.c
gsimpleaction.h
gsimpleactiongroup.c
gsimpleactiongroup.h
gsimpleasyncresult.c
gsimpleasyncresult.h
gsimpleiostream.c
gsimpleiostream.h
gsimplepermission.c
gsimplepermission.h
gsimpleproxyresolver.c
gsimpleproxyresolver.h
gsocket.c
gsocket.h
gsocketaddress.c
gsocketaddress.h
gsocketaddressenumerator.c
gsocketaddressenumerator.h
gsocketclient.c
gsocketclient.h
gsocketconnectable.c
gsocketconnectable.h
gsocketconnection.c
gsocketconnection.h
gsocketcontrolmessage.c
gsocketcontrolmessage.h
gsocketinputstream.c
gsocketinputstream.h
gsocketlistener.c
gsocketlistener.h
gsocketoutputstream.c
gsocketoutputstream.h
gsocketservice.c
gsocketservice.h
gsocks4aproxy.c
gsocks4aproxy.h
gsocks4proxy.c
gsocks4proxy.h
gsocks5proxy.c
gsocks5proxy.h
gsrvtarget.c
gsrvtarget.h
gsubprocess.c
gsubprocess.h
gsubprocesslauncher-private.h
gsubprocesslauncher.c
gsubprocesslauncher.h
gtask.c
gtask.h
gtcpconnection.c
gtcpconnection.h
gtcpwrapperconnection.c
gtcpwrapperconnection.h
gtestdbus.c
gtestdbus.h
gthemedicon.c
gthemedicon.h
gthreadedresolver.c
gthreadedresolver.h
gthreadedsocketservice.c
gthreadedsocketservice.h
gtlsbackend.c
gtlsbackend.h
gtlscertificate.c
gtlscertificate.h
gtlsclientconnection.c
gtlsclientconnection.h
gtlsconnection.c
gtlsconnection.h
gtlsdatabase.c
gtlsdatabase.h
gtlsfiledatabase.c
gtlsfiledatabase.h
gtlsinteraction.c
gtlsinteraction.h
gtlspassword.c
gtlspassword.h
gtlsserverconnection.c
gtlsserverconnection.h
gtrashportal.c
gtrashportal.h
gunionvolumemonitor.c
gunionvolumemonitor.h
gunixconnection.c
gunixconnection.h
gunixcredentialsmessage.c
gunixcredentialsmessage.h
gunixfdlist.c
gunixfdlist.h
gunixfdmessage.c
gunixfdmessage.h
gunixinputstream.c
gunixinputstream.h
gunixmount.c
gunixmount.h
gunixmounts.c
gunixmounts.h
gunixoutputstream.c
gunixoutputstream.h
gunixsocketaddress.c
gunixsocketaddress.h
gunixvolume.c
gunixvolume.h
gunixvolumemonitor.c
gunixvolumemonitor.h
gvfs.c
gvfs.h
gvolume.c
gvolume.h
gvolumemonitor.c
gvolumemonitor.h
gwin32appinfo.c
gwin32appinfo.h
gwin32inputstream.c
gwin32inputstream.h
gwin32mount.c
gwin32mount.h
gwin32networking.h
gwin32networkmonitor.c
gwin32networkmonitor.h
gwin32notificationbackend.c
gwin32outputstream.c
gwin32outputstream.h
gwin32registrykey.c
gwin32registrykey.h
gwin32volumemonitor.c
gwin32volumemonitor.h
gzlibcompressor.c
gzlibcompressor.h
gzlibdecompressor.c
gzlibdecompressor.h
meson.build
org.freedesktop.portal.Documents.xml
org.freedesktop.portal.OpenURI.xml
org.freedesktop.portal.ProxyResolver.xml
org.freedesktop.portal.Trash.xml
strinfo.c
thumbnail-verify.c
thumbnail-verify.h
glib
gmodule
gobject
gthread
m4macros
po
subprojects
tests
.clang-format
.dir-locals.el
.gitattributes
.gitignore
.gitlab-ci.yml
AUTHORS
CONTRIBUTING.md
COPYING
HACKING
INSTALL.in
NEWS
NEWS.pre-1-3
README
README.md
README.rationale
README.win32
README.win32.md
check-abis.sh
clang-format-diff.py
glib-gettextize.in
glib.doap
glib.supp
meson.build
meson_options.txt
msvc_recommended_pragmas.h
sanity_check
template-tap.test.in
template.test.in
glib/gio/glocalfileenumerator.c

459 lines
11 KiB
C
Raw Normal View History

/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
2014-01-23 12:58:29 +01:00
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Alexander Larsson <alexl@redhat.com>
*/
#include "config.h"
#include <glib.h>
#include <glocalfileenumerator.h>
#include <glocalfileinfo.h>
#include <glocalfile.h>
#include <gioerror.h>
#include <string.h>
#include <stdlib.h>
#include "glibintl.h"
#define CHUNK_SIZE 1000
#ifdef G_OS_WIN32
#define USE_GDIR
#endif
#ifndef USE_GDIR
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
typedef struct {
char *name;
long inode;
GFileType type;
} DirEntry;
#endif
struct _GLocalFileEnumerator
{
GFileEnumerator parent;
GFileAttributeMatcher *matcher;
GFileAttributeMatcher *reduced_matcher;
char *filename;
char *attributes;
GFileQueryInfoFlags flags;
gboolean got_parent_info;
GLocalParentFileInfo parent_info;
#ifdef USE_GDIR
GDir *dir;
#else
DIR *dir;
DirEntry *entries;
int entries_pos;
gboolean at_end;
#endif
gboolean follow_symlinks;
};
#define g_local_file_enumerator_get_type _g_local_file_enumerator_get_type
G_DEFINE_TYPE (GLocalFileEnumerator, g_local_file_enumerator, G_TYPE_FILE_ENUMERATOR)
static GFileInfo *g_local_file_enumerator_next_file (GFileEnumerator *enumerator,
GCancellable *cancellable,
GError **error);
static gboolean g_local_file_enumerator_close (GFileEnumerator *enumerator,
GCancellable *cancellable,
GError **error);
static void
free_entries (GLocalFileEnumerator *local)
{
#ifndef USE_GDIR
int i;
if (local->entries != NULL)
{
for (i = 0; local->entries[i].name != NULL; i++)
g_free (local->entries[i].name);
g_free (local->entries);
}
#endif
}
static void
g_local_file_enumerator_finalize (GObject *object)
{
GLocalFileEnumerator *local;
local = G_LOCAL_FILE_ENUMERATOR (object);
if (local->got_parent_info)
_g_local_file_info_free_parent_info (&local->parent_info);
g_free (local->filename);
g_file_attribute_matcher_unref (local->matcher);
g_file_attribute_matcher_unref (local->reduced_matcher);
if (local->dir)
{
#ifdef USE_GDIR
g_dir_close (local->dir);
#else
closedir (local->dir);
#endif
local->dir = NULL;
}
free_entries (local);
G_OBJECT_CLASS (g_local_file_enumerator_parent_class)->finalize (object);
}
static void
g_local_file_enumerator_class_init (GLocalFileEnumeratorClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GFileEnumeratorClass *enumerator_class = G_FILE_ENUMERATOR_CLASS (klass);
gobject_class->finalize = g_local_file_enumerator_finalize;
enumerator_class->next_file = g_local_file_enumerator_next_file;
enumerator_class->close_fn = g_local_file_enumerator_close;
}
static void
g_local_file_enumerator_init (GLocalFileEnumerator *local)
{
}
#ifdef USE_GDIR
static void
convert_file_to_io_error (GError **error,
GError *file_error)
{
int new_code;
if (file_error == NULL)
return;
new_code = G_IO_ERROR_FAILED;
if (file_error->domain == G_FILE_ERROR)
{
switch (file_error->code)
{
case G_FILE_ERROR_NOENT:
new_code = G_IO_ERROR_NOT_FOUND;
break;
case G_FILE_ERROR_ACCES:
new_code = G_IO_ERROR_PERMISSION_DENIED;
break;
case G_FILE_ERROR_NOTDIR:
new_code = G_IO_ERROR_NOT_DIRECTORY;
break;
case G_FILE_ERROR_MFILE:
new_code = G_IO_ERROR_TOO_MANY_OPEN_FILES;
break;
default:
break;
}
}
g_set_error_literal (error, G_IO_ERROR,
new_code,
file_error->message);
}
#else
static GFileAttributeMatcher *
g_file_attribute_matcher_subtract_attributes (GFileAttributeMatcher *matcher,
const char * attributes)
{
GFileAttributeMatcher *result, *tmp;
tmp = g_file_attribute_matcher_new (attributes);
result = g_file_attribute_matcher_subtract (matcher, tmp);
g_file_attribute_matcher_unref (tmp);
return result;
}
#endif
GFileEnumerator *
_g_local_file_enumerator_new (GLocalFile *file,
const char *attributes,
GFileQueryInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
GLocalFileEnumerator *local;
char *filename = g_file_get_path (G_FILE (file));
#ifdef USE_GDIR
GError *dir_error;
GDir *dir;
dir_error = NULL;
dir = g_dir_open (filename, 0, error != NULL ? &dir_error : NULL);
if (dir == NULL)
{
if (error != NULL)
{
convert_file_to_io_error (error, dir_error);
g_error_free (dir_error);
}
g_free (filename);
return NULL;
}
#else
DIR *dir;
int errsv;
dir = opendir (filename);
if (dir == NULL)
{
gchar *utf8_filename;
errsv = errno;
utf8_filename = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
g_set_error (error, G_IO_ERROR,
g_io_error_from_errno (errsv),
"Error opening directory '%s': %s",
utf8_filename, g_strerror (errsv));
g_free (utf8_filename);
g_free (filename);
return NULL;
}
#endif
local = g_object_new (G_TYPE_LOCAL_FILE_ENUMERATOR,
"container", file,
NULL);
local->dir = dir;
local->filename = filename;
local->matcher = g_file_attribute_matcher_new (attributes);
#ifndef USE_GDIR
local->reduced_matcher = g_file_attribute_matcher_subtract_attributes (local->matcher,
G_LOCAL_FILE_INFO_NOSTAT_ATTRIBUTES","
"standard::type");
#endif
local->flags = flags;
return G_FILE_ENUMERATOR (local);
}
#ifndef USE_GDIR
static int
sort_by_inode (const void *_a, const void *_b)
{
const DirEntry *a, *b;
a = _a;
b = _b;
return a->inode - b->inode;
}
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
static GFileType
file_type_from_dirent (char d_type)
{
switch (d_type)
{
case DT_BLK:
case DT_CHR:
case DT_FIFO:
case DT_SOCK:
return G_FILE_TYPE_SPECIAL;
case DT_DIR:
return G_FILE_TYPE_DIRECTORY;
case DT_LNK:
return G_FILE_TYPE_SYMBOLIC_LINK;
case DT_REG:
return G_FILE_TYPE_REGULAR;
case DT_UNKNOWN:
default:
return G_FILE_TYPE_UNKNOWN;
}
}
#endif
static const char *
next_file_helper (GLocalFileEnumerator *local, GFileType *file_type)
{
struct dirent *entry;
const char *filename;
int i;
if (local->at_end)
return NULL;
if (local->entries == NULL ||
(local->entries[local->entries_pos].name == NULL))
{
if (local->entries == NULL)
local->entries = g_new (DirEntry, CHUNK_SIZE + 1);
else
{
/* Restart by clearing old names */
for (i = 0; local->entries[i].name != NULL; i++)
g_free (local->entries[i].name);
}
for (i = 0; i < CHUNK_SIZE; i++)
{
entry = readdir (local->dir);
while (entry
&& (0 == strcmp (entry->d_name, ".") ||
0 == strcmp (entry->d_name, "..")))
entry = readdir (local->dir);
if (entry)
{
local->entries[i].name = g_strdup (entry->d_name);
local->entries[i].inode = entry->d_ino;
#if HAVE_STRUCT_DIRENT_D_TYPE
local->entries[i].type = file_type_from_dirent (entry->d_type);
#else
local->entries[i].type = G_FILE_TYPE_UNKNOWN;
#endif
}
else
break;
}
local->entries[i].name = NULL;
local->entries_pos = 0;
qsort (local->entries, i, sizeof (DirEntry), sort_by_inode);
}
filename = local->entries[local->entries_pos].name;
if (filename == NULL)
local->at_end = TRUE;
*file_type = local->entries[local->entries_pos].type;
local->entries_pos++;
return filename;
}
#endif
static GFileInfo *
g_local_file_enumerator_next_file (GFileEnumerator *enumerator,
GCancellable *cancellable,
GError **error)
{
GLocalFileEnumerator *local = G_LOCAL_FILE_ENUMERATOR (enumerator);
const char *filename;
char *path;
GFileInfo *info;
GError *my_error;
GFileType file_type;
if (!local->got_parent_info)
{
_g_local_file_info_get_parent_info (local->filename, local->matcher, &local->parent_info);
local->got_parent_info = TRUE;
}
2010-07-10 18:04:22 -04:00
next_file:
#ifdef USE_GDIR
filename = g_dir_read_name (local->dir);
file_type = G_FILE_TYPE_UNKNOWN;
#else
filename = next_file_helper (local, &file_type);
#endif
if (filename == NULL)
return NULL;
my_error = NULL;
path = g_build_filename (local->filename, filename, NULL);
if (file_type == G_FILE_TYPE_UNKNOWN ||
(file_type == G_FILE_TYPE_SYMBOLIC_LINK && !(local->flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS)))
{
info = _g_local_file_info_get (filename, path,
local->matcher,
local->flags,
&local->parent_info,
&my_error);
}
else
{
info = _g_local_file_info_get (filename, path,
local->reduced_matcher,
local->flags,
&local->parent_info,
&my_error);
if (info)
{
_g_local_file_info_get_nostat (info, filename, path, local->matcher);
g_file_info_set_file_type (info, file_type);
if (file_type == G_FILE_TYPE_SYMBOLIC_LINK)
g_file_info_set_is_symlink (info, TRUE);
}
}
g_free (path);
if (info == NULL)
{
/* Failed to get info */
/* If the file does not exist there might have been a race where
* the file was removed between the readdir and the stat, so we
* ignore the file. */
2010-07-10 18:04:22 -04:00
if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
g_error_free (my_error);
goto next_file;
}
else
g_propagate_error (error, my_error);
}
return info;
}
static gboolean
g_local_file_enumerator_close (GFileEnumerator *enumerator,
GCancellable *cancellable,
GError **error)
{
GLocalFileEnumerator *local = G_LOCAL_FILE_ENUMERATOR (enumerator);
if (local->dir)
{
#ifdef USE_GDIR
g_dir_close (local->dir);
#else
closedir (local->dir);
#endif
local->dir = NULL;
}
return TRUE;
}