mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
Merge branch 'more-async-gfile' into 'main'
gfile (and GAppInfo): Add some missing async APIs and ensure async calls always use them See merge request GNOME/glib!2717
This commit is contained in:
commit
5655af6ada
@ -84,6 +84,10 @@ g_file_new_for_uri
|
||||
g_file_new_for_commandline_arg
|
||||
g_file_new_for_commandline_arg_and_cwd
|
||||
g_file_new_tmp
|
||||
g_file_new_tmp_async
|
||||
g_file_new_tmp_finish
|
||||
g_file_new_tmp_dir_async
|
||||
g_file_new_tmp_dir_finish
|
||||
g_file_parse_name
|
||||
g_file_new_build_filename
|
||||
g_file_dup
|
||||
@ -156,6 +160,8 @@ g_file_make_directory_async
|
||||
g_file_make_directory_finish
|
||||
g_file_make_directory_with_parents
|
||||
g_file_make_symbolic_link
|
||||
g_file_make_symbolic_link_async
|
||||
g_file_make_symbolic_link_finish
|
||||
g_file_query_settable_attributes
|
||||
g_file_query_writable_namespaces
|
||||
g_file_set_attribute
|
||||
@ -1371,6 +1377,7 @@ g_io_scheduler_job_send_to_mainloop_async
|
||||
G_IO_ERROR
|
||||
GIOErrorEnum
|
||||
g_io_error_from_errno
|
||||
g_io_error_from_file_error
|
||||
g_io_error_from_win32_error
|
||||
<SUBSECTION Standard>
|
||||
G_TYPE_IO_ERROR_ENUM
|
||||
@ -1435,7 +1442,11 @@ g_app_info_get_supported_types
|
||||
g_app_info_get_all
|
||||
g_app_info_get_all_for_type
|
||||
g_app_info_get_default_for_type
|
||||
g_app_info_get_default_for_type_async
|
||||
g_app_info_get_default_for_type_finish
|
||||
g_app_info_get_default_for_uri_scheme
|
||||
g_app_info_get_default_for_uri_scheme_async
|
||||
g_app_info_get_default_for_uri_scheme_finish
|
||||
g_app_info_get_fallback_for_type
|
||||
g_app_info_get_recommended_for_type
|
||||
g_app_info_launch_default_for_uri
|
||||
|
247
gio/gappinfo.c
247
gio/gappinfo.c
@ -778,6 +778,188 @@ g_app_info_should_show (GAppInfo *appinfo)
|
||||
return (* iface->should_show) (appinfo);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *content_type;
|
||||
gboolean must_support_uris;
|
||||
} DefaultForTypeData;
|
||||
|
||||
static void
|
||||
default_for_type_data_free (DefaultForTypeData *data)
|
||||
{
|
||||
g_free (data->content_type);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
get_default_for_type_thread (GTask *task,
|
||||
gpointer object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
DefaultForTypeData *data = task_data;
|
||||
GAppInfo *info;
|
||||
|
||||
info = g_app_info_get_default_for_type (data->content_type,
|
||||
data->must_support_uris);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||
_("Failed to find default application for "
|
||||
"content type ‘%s’"), data->content_type);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_pointer (task, g_steal_pointer (&info), g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_app_info_get_default_for_type_async:
|
||||
* @content_type: the content type to find a #GAppInfo for
|
||||
* @must_support_uris: if %TRUE, the #GAppInfo is expected to
|
||||
* support URIs
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore
|
||||
* @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
|
||||
* @user_data: (nullable): data to pass to @callback
|
||||
*
|
||||
* Asynchronously gets the default #GAppInfo for a given content type.
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
void
|
||||
g_app_info_get_default_for_type_async (const char *content_type,
|
||||
gboolean must_support_uris,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
DefaultForTypeData *data;
|
||||
|
||||
g_return_if_fail (content_type != NULL && *content_type != '\0');
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
data = g_new0 (DefaultForTypeData, 1);
|
||||
data->content_type = g_strdup (content_type);
|
||||
data->must_support_uris = must_support_uris;
|
||||
|
||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, g_app_info_get_default_for_type_async);
|
||||
g_task_set_task_data (task, data, (GDestroyNotify) default_for_type_data_free);
|
||||
g_task_set_check_cancellable (task, TRUE);
|
||||
g_task_run_in_thread (task, get_default_for_type_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
get_default_for_scheme_thread (GTask *task,
|
||||
gpointer object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const char *uri_scheme = task_data;
|
||||
GAppInfo *info;
|
||||
|
||||
info = g_app_info_get_default_for_uri_scheme (uri_scheme);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||
_("Failed to find default application for "
|
||||
"URI Scheme ‘%s’"), uri_scheme);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_pointer (task, g_steal_pointer (&info), g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_app_info_get_default_for_uri_scheme_async:
|
||||
* @uri_scheme: a string containing a URI scheme.
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore
|
||||
* @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
|
||||
* @user_data: (nullable): data to pass to @callback
|
||||
*
|
||||
* Asynchronously gets the default application for handling URIs with
|
||||
* the given URI scheme. A URI scheme is the initial part
|
||||
* of the URI, up to but not including the ':', e.g. "http",
|
||||
* "ftp" or "sip".
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
void
|
||||
g_app_info_get_default_for_uri_scheme_async (const char *uri_scheme,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_return_if_fail (uri_scheme != NULL && *uri_scheme != '\0');
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, g_app_info_get_default_for_uri_scheme_async);
|
||||
g_task_set_task_data (task, g_strdup (uri_scheme), g_free);
|
||||
g_task_set_check_cancellable (task, TRUE);
|
||||
g_task_run_in_thread (task, get_default_for_scheme_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_app_info_get_default_for_uri_scheme_finish:
|
||||
* @result: a #GAsyncResult
|
||||
* @error: (nullable): a #GError
|
||||
*
|
||||
* Finishes a default #GAppInfo lookup started by
|
||||
* g_app_info_get_default_for_uri_scheme_async().
|
||||
*
|
||||
* If no #GAppInfo is found, then @error will be set to %G_IO_ERROR_NOT_FOUND.
|
||||
*
|
||||
* Returns: (transfer full): #GAppInfo for given @uri_scheme or
|
||||
* %NULL on error.
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
GAppInfo *
|
||||
g_app_info_get_default_for_uri_scheme_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
||||
g_app_info_get_default_for_uri_scheme_async, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_app_info_get_default_for_type_finish:
|
||||
* @result: a #GAsyncResult
|
||||
* @error: (nullable): a #GError
|
||||
*
|
||||
* Finishes a default #GAppInfo lookup started by
|
||||
* g_app_info_get_default_for_type_async().
|
||||
*
|
||||
* If no #GAppInfo is found, then @error will be set to %G_IO_ERROR_NOT_FOUND.
|
||||
*
|
||||
* Returns: (transfer full): #GAppInfo for given @content_type or
|
||||
* %NULL on error.
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
GAppInfo *
|
||||
g_app_info_get_default_for_type_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
||||
g_app_info_get_default_for_type_async, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_app_info_launch_default_for_uri:
|
||||
* @uri: the uri to show
|
||||
@ -966,6 +1148,46 @@ launch_default_for_uri_default_handler_cb (GObject *object,
|
||||
launch_default_for_uri_portal_open_uri (g_steal_pointer (&task), g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
static void
|
||||
launch_default_app_for_default_handler (GTask *task)
|
||||
{
|
||||
GFile *file;
|
||||
GCancellable *cancellable;
|
||||
LaunchDefaultForUriData *data;
|
||||
|
||||
data = g_task_get_task_data (task);
|
||||
cancellable = g_task_get_cancellable (task);
|
||||
file = g_file_new_for_uri (data->uri);
|
||||
|
||||
g_file_query_default_handler_async (file,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
launch_default_for_uri_default_handler_cb,
|
||||
g_steal_pointer (&task));
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
static void
|
||||
launch_default_app_for_uri_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task = G_TASK (user_data);
|
||||
GAppInfo *app_info;
|
||||
|
||||
app_info = g_app_info_get_default_for_uri_scheme_finish (result, NULL);
|
||||
|
||||
if (!app_info)
|
||||
{
|
||||
launch_default_app_for_default_handler (g_steal_pointer (&task));
|
||||
}
|
||||
else
|
||||
{
|
||||
launch_default_for_uri_launch_uris (g_steal_pointer (&task),
|
||||
g_steal_pointer (&app_info));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* g_app_info_launch_default_for_uri_async:
|
||||
* @uri: the uri to show
|
||||
@ -996,7 +1218,6 @@ g_app_info_launch_default_for_uri_async (const char *uri,
|
||||
{
|
||||
GTask *task;
|
||||
char *uri_scheme;
|
||||
GAppInfo *app_info = NULL;
|
||||
LaunchDefaultForUriData *data;
|
||||
|
||||
g_return_if_fail (uri != NULL);
|
||||
@ -1015,24 +1236,18 @@ g_app_info_launch_default_for_uri_async (const char *uri,
|
||||
*/
|
||||
uri_scheme = g_uri_parse_scheme (uri);
|
||||
if (uri_scheme && uri_scheme[0] != '\0')
|
||||
/* FIXME: The following still uses blocking calls. */
|
||||
app_info = g_app_info_get_default_for_uri_scheme (uri_scheme);
|
||||
g_free (uri_scheme);
|
||||
|
||||
if (!app_info)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
g_file_query_default_handler_async (file,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
launch_default_for_uri_default_handler_cb,
|
||||
g_steal_pointer (&task));
|
||||
g_object_unref (file);
|
||||
g_app_info_get_default_for_uri_scheme_async (uri_scheme,
|
||||
cancellable,
|
||||
launch_default_app_for_uri_cb,
|
||||
g_steal_pointer (&task));
|
||||
}
|
||||
else
|
||||
launch_default_for_uri_launch_uris (g_steal_pointer (&task), g_steal_pointer (&app_info));
|
||||
{
|
||||
launch_default_app_for_default_handler (g_steal_pointer (&task));
|
||||
}
|
||||
|
||||
g_free (uri_scheme);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,9 +246,27 @@ void g_app_info_reset_type_associations (const char *content_type);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GAppInfo *g_app_info_get_default_for_type (const char *content_type,
|
||||
gboolean must_support_uris);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
void g_app_info_get_default_for_type_async (const char *content_type,
|
||||
gboolean must_support_uris,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
GAppInfo *g_app_info_get_default_for_type_finish (GAsyncResult *result,
|
||||
GError **error);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GAppInfo *g_app_info_get_default_for_uri_scheme (const char *uri_scheme);
|
||||
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
void g_app_info_get_default_for_uri_scheme_async (const char *uri_scheme,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
GAppInfo *g_app_info_get_default_for_uri_scheme_finish (GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
gboolean g_app_info_launch_default_for_uri (const char *uri,
|
||||
GAppLaunchContext *context,
|
||||
|
@ -3349,11 +3349,16 @@ launch_uris_bus_get_cb (GObject *object,
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
g_object_unref (task);
|
||||
}
|
||||
else
|
||||
else if (session_bus)
|
||||
g_dbus_connection_flush (session_bus,
|
||||
cancellable,
|
||||
launch_uris_flush_cb,
|
||||
g_steal_pointer (&task));
|
||||
else
|
||||
{
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_clear_object (&task);
|
||||
}
|
||||
}
|
||||
|
||||
g_clear_object (&session_bus);
|
||||
@ -4626,6 +4631,8 @@ g_app_info_get_default_for_uri_scheme (const char *uri_scheme)
|
||||
GAppInfo *app_info;
|
||||
char *content_type, *scheme_down;
|
||||
|
||||
g_return_val_if_fail (uri_scheme != NULL && *uri_scheme != '\0', NULL);
|
||||
|
||||
scheme_down = g_ascii_strdown (uri_scheme, -1);
|
||||
content_type = g_strdup_printf ("x-scheme-handler/%s", scheme_down);
|
||||
g_free (scheme_down);
|
||||
|
480
gio/gfile.c
480
gio/gfile.c
@ -96,6 +96,8 @@
|
||||
* - g_file_new_for_uri() if you have a URI.
|
||||
* - g_file_new_for_commandline_arg() for a command line argument.
|
||||
* - g_file_new_tmp() to create a temporary file from a template.
|
||||
* - g_file_new_tmp_async() to asynchronously create a temporary file.
|
||||
* - g_file_new_tmp_dir_async() to asynchronously create a temporary directory.
|
||||
* - g_file_parse_name() from a UTF-8 string gotten from g_file_get_parse_name().
|
||||
* - g_file_new_build_filename() to create a file from path elements.
|
||||
*
|
||||
@ -269,6 +271,15 @@ static void g_file_real_make_directory_async (GFile
|
||||
static gboolean g_file_real_make_directory_finish (GFile *file,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
static void g_file_real_make_symbolic_link_async (GFile *file,
|
||||
const char *symlink_value,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
static gboolean g_file_real_make_symbolic_link_finish (GFile *file,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
static void g_file_real_open_readwrite_async (GFile *file,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
@ -399,6 +410,8 @@ g_file_default_init (GFileIface *iface)
|
||||
iface->move_finish = g_file_real_move_finish;
|
||||
iface->make_directory_async = g_file_real_make_directory_async;
|
||||
iface->make_directory_finish = g_file_real_make_directory_finish;
|
||||
iface->make_symbolic_link_async = g_file_real_make_symbolic_link_async;
|
||||
iface->make_symbolic_link_finish = g_file_real_make_symbolic_link_finish;
|
||||
iface->open_readwrite_async = g_file_real_open_readwrite_async;
|
||||
iface->open_readwrite_finish = g_file_real_open_readwrite_finish;
|
||||
iface->create_readwrite_async = g_file_real_create_readwrite_async;
|
||||
@ -4154,6 +4167,125 @@ g_file_make_symbolic_link (GFile *file,
|
||||
return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error);
|
||||
}
|
||||
|
||||
static void
|
||||
make_symbolic_link_async_thread (GTask *task,
|
||||
gpointer object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const char *symlink_value = task_data;
|
||||
GError *error = NULL;
|
||||
|
||||
if (g_file_make_symbolic_link (G_FILE (object), symlink_value, cancellable, &error))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
static void
|
||||
g_file_real_make_symbolic_link_async (GFile *file,
|
||||
const char *symlink_value,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
g_return_if_fail (symlink_value != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
task = g_task_new (file, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, g_file_real_make_symbolic_link_async);
|
||||
g_task_set_task_data (task, g_strdup (symlink_value), g_free);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
g_task_run_in_thread (task, make_symbolic_link_async_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_make_symbolic_link_async:
|
||||
* @file: a #GFile with the name of the symlink to create
|
||||
* @symlink_value: (type filename): a string with the path for the target
|
||||
* of the new symlink
|
||||
* @io_priority: the [I/O priority][io-priority] of the request
|
||||
* @cancellable: (nullable): optional #GCancellable object,
|
||||
* %NULL to ignore
|
||||
* @callback: a #GAsyncReadyCallback to call
|
||||
* when the request is satisfied
|
||||
* @user_data: the data to pass to callback function
|
||||
*
|
||||
* Asynchronously creates a symbolic link named @file which contains the
|
||||
* string @symlink_value.
|
||||
*
|
||||
* Virtual: make_symbolic_link_async
|
||||
* Since: 2.74
|
||||
*/
|
||||
void
|
||||
g_file_make_symbolic_link_async (GFile *file,
|
||||
const char *symlink_value,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
g_return_if_fail (symlink_value != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
|
||||
/* Default implementation should always be provided by GFileIface */
|
||||
g_assert (iface->make_symbolic_link_async != NULL);
|
||||
|
||||
(* iface->make_symbolic_link_async) (file, symlink_value, io_priority,
|
||||
cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_file_real_make_symbolic_link_finish (GFile *file,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, file), FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_make_symbolic_link_finish:
|
||||
* @file: input #GFile
|
||||
* @result: a #GAsyncResult
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Finishes an asynchronous symbolic link creation, started with
|
||||
* g_file_make_symbolic_link_async().
|
||||
*
|
||||
* Virtual: make_symbolic_link_finish
|
||||
* Returns: %TRUE on successful directory creation, %FALSE otherwise.
|
||||
* Since: 2.74
|
||||
*/
|
||||
gboolean
|
||||
g_file_make_symbolic_link_finish (GFile *file,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GFileIface *iface;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
iface = G_FILE_GET_IFACE (file);
|
||||
/* Default implementation should always be provided by GFileIface */
|
||||
g_assert (iface->make_symbolic_link_finish != NULL);
|
||||
|
||||
return (* iface->make_symbolic_link_finish) (file, result, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_delete:
|
||||
* @file: input #GFile
|
||||
@ -6814,6 +6946,252 @@ g_file_new_tmp (const char *tmpl,
|
||||
return file;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GFile *file;
|
||||
GFileIOStream *iostream;
|
||||
} NewTmpAsyncData;
|
||||
|
||||
static void
|
||||
new_tmp_data_free (NewTmpAsyncData *data)
|
||||
{
|
||||
g_clear_object (&data->file);
|
||||
g_clear_object (&data->iostream);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
new_tmp_async_thread (GTask *task,
|
||||
gpointer object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GFile *file;
|
||||
const char *tmpl = task_data;
|
||||
GFileIOStream *iostream = NULL;
|
||||
GError *error = NULL;
|
||||
NewTmpAsyncData *return_data;
|
||||
|
||||
if (g_task_return_error_if_cancelled (task))
|
||||
return;
|
||||
|
||||
file = g_file_new_tmp (tmpl, &iostream, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
int error_code = G_IO_ERROR_FAILED;
|
||||
|
||||
if (error->domain == G_IO_ERROR)
|
||||
{
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (error->domain == G_FILE_ERROR)
|
||||
error_code = g_io_error_from_file_error (error->code);
|
||||
|
||||
g_task_return_new_error (task, G_IO_ERROR, error_code,
|
||||
_("Failed to create a temporary directory for "
|
||||
"template “%s”: %s"),
|
||||
tmpl, error->message);
|
||||
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
return_data = g_new0 (NewTmpAsyncData, 1);
|
||||
return_data->file = g_steal_pointer (&file);
|
||||
return_data->iostream = g_steal_pointer (&iostream);
|
||||
|
||||
g_task_return_pointer (task, g_steal_pointer (&return_data),
|
||||
(GDestroyNotify) new_tmp_data_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_new_tmp_async:
|
||||
* @tmpl: (type filename) (nullable): Template for the file
|
||||
* name, as in g_file_open_tmp(), or %NULL for a default template
|
||||
* @io_priority: the [I/O priority][io-priority] of the request
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore
|
||||
* @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
|
||||
* @user_data: (nullable): data to pass to @callback
|
||||
*
|
||||
* Asynchronously opens a file in the preferred directory for temporary files
|
||||
* (as returned by g_get_tmp_dir()) as g_file_new_tmp().
|
||||
*
|
||||
* @tmpl should be a string in the GLib file name encoding
|
||||
* containing a sequence of six 'X' characters, and containing no
|
||||
* directory components. If it is %NULL, a default template is used.
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
void
|
||||
g_file_new_tmp_async (const char *tmpl,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, g_file_new_tmp_async);
|
||||
g_task_set_task_data (task, g_strdup (tmpl), g_free);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_check_cancellable (task, TRUE);
|
||||
g_task_run_in_thread (task, new_tmp_async_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_new_tmp_finish:
|
||||
* @result: a #GAsyncResult
|
||||
* @iostream: (out) (not optional) (not nullable) (transfer full): on return, a #GFileIOStream for the created file
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Finishes a temporary file creation started by g_file_new_tmp_async().
|
||||
*
|
||||
* Returns: (transfer full): a new #GFile.
|
||||
* Free the returned object with g_object_unref().
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
GFile *
|
||||
g_file_new_tmp_finish (GAsyncResult *result,
|
||||
GFileIOStream **iostream,
|
||||
GError **error)
|
||||
{
|
||||
GFile *file;
|
||||
NewTmpAsyncData *data;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
||||
g_file_new_tmp_async, NULL);
|
||||
g_return_val_if_fail (iostream != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
data = g_task_propagate_pointer (G_TASK (result), error);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
*iostream = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file = g_steal_pointer (&data->file);
|
||||
*iostream = g_steal_pointer (&data->iostream);
|
||||
|
||||
new_tmp_data_free (data);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static void
|
||||
new_tmp_dir_async_thread (GTask *task,
|
||||
gpointer object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
gchar *path;
|
||||
const char *tmpl = task_data;
|
||||
GError *error = NULL;
|
||||
|
||||
if (g_task_return_error_if_cancelled (task))
|
||||
return;
|
||||
|
||||
path = g_dir_make_tmp (tmpl, &error);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
int error_code = G_IO_ERROR_FAILED;
|
||||
|
||||
if (error->domain == G_IO_ERROR)
|
||||
{
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (error->domain == G_FILE_ERROR)
|
||||
error_code = g_io_error_from_file_error (error->code);
|
||||
|
||||
g_task_return_new_error (task, G_IO_ERROR, error_code,
|
||||
_("Failed to create a temporary directory for "
|
||||
"template “%s”: %s"),
|
||||
tmpl, error->message);
|
||||
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_pointer (task, g_file_new_for_path (path), g_object_unref);
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_new_tmp_dir_async:
|
||||
* @tmpl: (type filename) (nullable): Template for the file
|
||||
* name, as in g_dir_make_tmp(), or %NULL for a default template
|
||||
* @io_priority: the [I/O priority][io-priority] of the request
|
||||
* @cancellable: optional #GCancellable object, %NULL to ignore
|
||||
* @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
|
||||
* @user_data: (nullable): data to pass to @callback
|
||||
*
|
||||
* Asynchronously creates a directory in the preferred directory for
|
||||
* temporary files (as returned by g_get_tmp_dir()) as g_dir_make_tmp().
|
||||
*
|
||||
* @tmpl should be a string in the GLib file name encoding
|
||||
* containing a sequence of six 'X' characters, and containing no
|
||||
* directory components. If it is %NULL, a default template is used.
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
void
|
||||
g_file_new_tmp_dir_async (const char *tmpl,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, g_file_new_tmp_dir_async);
|
||||
g_task_set_task_data (task, g_strdup (tmpl), g_free);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_check_cancellable (task, TRUE);
|
||||
g_task_run_in_thread (task, new_tmp_dir_async_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_new_tmp_dir_finish:
|
||||
* @result: a #GAsyncResult
|
||||
* @error: a #GError, or %NULL
|
||||
*
|
||||
* Finishes a temporary directory creation started by
|
||||
* g_file_new_tmp_dir_async().
|
||||
*
|
||||
* Returns: (transfer full): a new #GFile.
|
||||
* Free the returned object with g_object_unref().
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
GFile *
|
||||
g_file_new_tmp_dir_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_is_valid (result, NULL), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
||||
g_file_new_tmp_dir_async, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_file_parse_name:
|
||||
* @parse_name: a file name or path to be parsed
|
||||
@ -7145,6 +7523,36 @@ g_file_query_default_handler (GFile *file,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
query_default_handler_query_app_info_for_type_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task = G_TASK (user_data);
|
||||
GAppInfo *appinfo;
|
||||
GError *error = NULL;
|
||||
|
||||
appinfo = g_app_info_get_default_for_type_finish (result, &error);
|
||||
|
||||
if (appinfo != NULL)
|
||||
{
|
||||
g_task_return_pointer (task, g_steal_pointer (&appinfo), g_object_unref);
|
||||
}
|
||||
else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s", error->message);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
g_clear_error (&error);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
query_default_handler_query_info_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
@ -7155,7 +7563,6 @@ query_default_handler_query_info_cb (GObject *object,
|
||||
GError *error = NULL;
|
||||
GFileInfo *info;
|
||||
const char *content_type;
|
||||
GAppInfo *appinfo = NULL;
|
||||
|
||||
info = g_file_query_info_finish (file, result, &error);
|
||||
if (info == NULL)
|
||||
@ -7170,27 +7577,58 @@ query_default_handler_query_info_cb (GObject *object,
|
||||
content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
|
||||
if (content_type)
|
||||
{
|
||||
GCancellable *cancellable = g_task_get_cancellable (task);
|
||||
char *path;
|
||||
|
||||
/* Don't use is_native(), as we want to support fuse paths if available */
|
||||
path = g_file_get_path (file);
|
||||
|
||||
/* FIXME: The following still uses blocking calls. */
|
||||
appinfo = g_app_info_get_default_for_type (content_type,
|
||||
path == NULL);
|
||||
g_app_info_get_default_for_type_async (content_type,
|
||||
path == NULL,
|
||||
cancellable,
|
||||
query_default_handler_query_app_info_for_type_cb,
|
||||
g_steal_pointer (&task));
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No application is registered as handling this file"));
|
||||
}
|
||||
|
||||
g_object_unref (info);
|
||||
g_clear_object (&task);
|
||||
}
|
||||
|
||||
if (appinfo != NULL)
|
||||
g_task_return_pointer (task, g_steal_pointer (&appinfo), g_object_unref);
|
||||
static void
|
||||
on_query_default_handler_for_uri_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task = user_data;
|
||||
GAppInfo *app_info;
|
||||
|
||||
app_info = g_app_info_get_default_for_uri_scheme_finish (result, NULL);
|
||||
|
||||
if (app_info)
|
||||
{
|
||||
g_task_return_pointer (task, g_steal_pointer (&app_info), g_object_unref);
|
||||
g_object_unref (task);
|
||||
}
|
||||
else
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
_("No application is registered as handling this file"));
|
||||
g_object_unref (task);
|
||||
{
|
||||
g_file_query_info_async (g_task_get_source_object (task),
|
||||
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
|
||||
G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
|
||||
0,
|
||||
g_task_get_priority (task),
|
||||
g_task_get_cancellable (task),
|
||||
query_default_handler_query_info_cb,
|
||||
task);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -7221,21 +7659,13 @@ g_file_query_default_handler_async (GFile *file,
|
||||
uri_scheme = g_file_get_uri_scheme (file);
|
||||
if (uri_scheme && uri_scheme[0] != '\0')
|
||||
{
|
||||
GAppInfo *appinfo;
|
||||
|
||||
/* FIXME: The following still uses blocking calls. */
|
||||
appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme);
|
||||
g_app_info_get_default_for_uri_scheme_async (uri_scheme,
|
||||
cancellable,
|
||||
on_query_default_handler_for_uri_cb,
|
||||
g_steal_pointer (&task));
|
||||
g_free (uri_scheme);
|
||||
|
||||
if (appinfo != NULL)
|
||||
{
|
||||
g_task_return_pointer (task, g_steal_pointer (&appinfo), g_object_unref);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
g_free (uri_scheme);
|
||||
|
||||
g_file_query_info_async (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
|
||||
@ -7245,6 +7675,8 @@ g_file_query_default_handler_async (GFile *file,
|
||||
cancellable,
|
||||
query_default_handler_query_info_cb,
|
||||
g_steal_pointer (&task));
|
||||
|
||||
g_free (uri_scheme);
|
||||
}
|
||||
|
||||
/**
|
||||
|
45
gio/gfile.h
45
gio/gfile.h
@ -115,8 +115,8 @@ typedef struct _GFileIface GFileIface;
|
||||
* @make_directory_finish: Finishes making a directory asynchronously.
|
||||
* @make_symbolic_link: (nullable): Makes a symbolic link. %NULL if symbolic
|
||||
* links are unsupported.
|
||||
* @_make_symbolic_link_async: Asynchronously makes a symbolic link
|
||||
* @_make_symbolic_link_finish: Finishes making a symbolic link asynchronously.
|
||||
* @make_symbolic_link_async: Asynchronously makes a symbolic link
|
||||
* @make_symbolic_link_finish: Finishes making a symbolic link asynchronously.
|
||||
* @copy: (nullable): Copies a file. %NULL if copying is unsupported, which will
|
||||
* cause `GFile` to use a fallback copy method where it reads from the
|
||||
* source and writes to the destination.
|
||||
@ -396,8 +396,15 @@ struct _GFileIface
|
||||
const char *symlink_value,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void (* _make_symbolic_link_async) (void);
|
||||
void (* _make_symbolic_link_finish) (void);
|
||||
void (* make_symbolic_link_async) (GFile *file,
|
||||
const char *symlink_value,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean (* make_symbolic_link_finish) (GFile *file,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
gboolean (* copy) (GFile *source,
|
||||
GFile *destination,
|
||||
@ -619,6 +626,25 @@ GLIB_AVAILABLE_IN_2_32
|
||||
GFile * g_file_new_tmp (const char *tmpl,
|
||||
GFileIOStream **iostream,
|
||||
GError **error);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
void g_file_new_tmp_async (const char *tmpl,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
GFile * g_file_new_tmp_finish (GAsyncResult *result,
|
||||
GFileIOStream **iostream,
|
||||
GError **error);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
void g_file_new_tmp_dir_async (const char *tmpl,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
GFile * g_file_new_tmp_dir_finish (GAsyncResult *result,
|
||||
GError **error);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GFile * g_file_parse_name (const char *parse_name);
|
||||
GLIB_AVAILABLE_IN_2_56
|
||||
@ -976,6 +1002,17 @@ gboolean g_file_make_symbolic_link (GFile
|
||||
const char *symlink_value,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
void g_file_make_symbolic_link_async (GFile *file,
|
||||
const char *symlink_value,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
gboolean g_file_make_symbolic_link_finish (GFile *file,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GFileAttributeInfoList *g_file_query_settable_attributes (GFile *file,
|
||||
GCancellable *cancellable,
|
||||
|
@ -509,6 +509,7 @@ typedef enum {
|
||||
* value, which has this more logical name. Since 2.44.
|
||||
* @G_IO_ERROR_NOT_CONNECTED: Transport endpoint is not connected. Since 2.44
|
||||
* @G_IO_ERROR_MESSAGE_TOO_LARGE: Message too large. Since 2.48.
|
||||
* @G_IO_ERROR_NO_SUCH_DEVICE: No such device found. Since 2.74
|
||||
*
|
||||
* Error codes returned by GIO functions.
|
||||
*
|
||||
@ -577,7 +578,8 @@ typedef enum {
|
||||
G_IO_ERROR_BROKEN_PIPE,
|
||||
G_IO_ERROR_CONNECTION_CLOSED = G_IO_ERROR_BROKEN_PIPE,
|
||||
G_IO_ERROR_NOT_CONNECTED,
|
||||
G_IO_ERROR_MESSAGE_TOO_LARGE
|
||||
G_IO_ERROR_MESSAGE_TOO_LARGE,
|
||||
G_IO_ERROR_NO_SUCH_DEVICE,
|
||||
} GIOErrorEnum;
|
||||
|
||||
|
||||
|
169
gio/gioerror.c
169
gio/gioerror.c
@ -1,6 +1,7 @@
|
||||
/* GIO - GLib Input, Output and Streaming Library
|
||||
*
|
||||
* Copyright (C) 2006-2007 Red Hat, Inc.
|
||||
* Copyright (C) 2022 Canonical Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
@ -18,6 +19,7 @@
|
||||
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Alexander Larsson <alexl@redhat.com>
|
||||
* Author: Marco Trevisan <marco.trevisan@canonical.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -71,83 +73,38 @@ G_DEFINE_QUARK (g-io-error-quark, g_io_error)
|
||||
GIOErrorEnum
|
||||
g_io_error_from_errno (gint err_no)
|
||||
{
|
||||
GFileError file_error;
|
||||
GIOErrorEnum io_error;
|
||||
|
||||
file_error = g_file_error_from_errno (err_no);
|
||||
io_error = g_io_error_from_file_error (file_error);
|
||||
|
||||
if (io_error != G_IO_ERROR_FAILED)
|
||||
return io_error;
|
||||
|
||||
switch (err_no)
|
||||
{
|
||||
#ifdef EEXIST
|
||||
case EEXIST:
|
||||
return G_IO_ERROR_EXISTS;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef EISDIR
|
||||
case EISDIR:
|
||||
return G_IO_ERROR_IS_DIRECTORY;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef EACCES
|
||||
case EACCES:
|
||||
return G_IO_ERROR_PERMISSION_DENIED;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENAMETOOLONG
|
||||
case ENAMETOOLONG:
|
||||
return G_IO_ERROR_FILENAME_TOO_LONG;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENOENT
|
||||
case ENOENT:
|
||||
return G_IO_ERROR_NOT_FOUND;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENOTDIR
|
||||
case ENOTDIR:
|
||||
return G_IO_ERROR_NOT_DIRECTORY;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENXIO
|
||||
case ENXIO:
|
||||
return G_IO_ERROR_NOT_REGULAR_FILE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef EROFS
|
||||
case EROFS:
|
||||
return G_IO_ERROR_READ_ONLY;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ELOOP
|
||||
case ELOOP:
|
||||
#ifdef EMLINK
|
||||
case EMLINK:
|
||||
return G_IO_ERROR_TOO_MANY_LINKS;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENOSPC
|
||||
case ENOSPC:
|
||||
return G_IO_ERROR_NO_SPACE;
|
||||
#ifdef ENOMSG
|
||||
case ENOMSG:
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ENOMEM
|
||||
case ENOMEM:
|
||||
return G_IO_ERROR_NO_SPACE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef EINVAL
|
||||
case EINVAL:
|
||||
return G_IO_ERROR_INVALID_ARGUMENT;
|
||||
#ifdef ENODATA
|
||||
case ENODATA:
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef EPERM
|
||||
case EPERM:
|
||||
return G_IO_ERROR_PERMISSION_DENIED;
|
||||
#ifdef EBADMSG
|
||||
case EBADMSG:
|
||||
return G_IO_ERROR_INVALID_DATA;
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -226,12 +183,6 @@ g_io_error_from_errno (gint err_no)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef EMFILE
|
||||
case EMFILE:
|
||||
return G_IO_ERROR_TOO_MANY_OPEN_FILES;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef EADDRINUSE
|
||||
case EADDRINUSE:
|
||||
return G_IO_ERROR_ADDRESS_IN_USE;
|
||||
@ -250,15 +201,15 @@ g_io_error_from_errno (gint err_no)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef ECONNREFUSED
|
||||
case ECONNREFUSED:
|
||||
return G_IO_ERROR_CONNECTION_REFUSED;
|
||||
#ifdef ENETDOWN
|
||||
case ENETDOWN:
|
||||
return G_IO_ERROR_NETWORK_UNREACHABLE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef EPIPE
|
||||
case EPIPE:
|
||||
return G_IO_ERROR_BROKEN_PIPE;
|
||||
#ifdef ECONNREFUSED
|
||||
case ECONNREFUSED:
|
||||
return G_IO_ERROR_CONNECTION_REFUSED;
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -292,6 +243,70 @@ g_io_error_from_errno (gint err_no)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* g_io_error_from_file_error:
|
||||
* @file_error: a #GFileError.
|
||||
*
|
||||
* Converts #GFileError error codes into GIO error codes.
|
||||
*
|
||||
* Returns: #GIOErrorEnum value for the given #GFileError error value.
|
||||
*
|
||||
* Since: 2.74
|
||||
**/
|
||||
GIOErrorEnum
|
||||
g_io_error_from_file_error (GFileError file_error)
|
||||
{
|
||||
switch (file_error)
|
||||
{
|
||||
case G_FILE_ERROR_EXIST:
|
||||
return G_IO_ERROR_EXISTS;
|
||||
case G_FILE_ERROR_ISDIR:
|
||||
return G_IO_ERROR_IS_DIRECTORY;
|
||||
case G_FILE_ERROR_ACCES:
|
||||
return G_IO_ERROR_PERMISSION_DENIED;
|
||||
case G_FILE_ERROR_NAMETOOLONG:
|
||||
return G_IO_ERROR_FILENAME_TOO_LONG;
|
||||
case G_FILE_ERROR_NOENT:
|
||||
return G_IO_ERROR_NOT_FOUND;
|
||||
case G_FILE_ERROR_NOTDIR:
|
||||
return G_IO_ERROR_NOT_DIRECTORY;
|
||||
case G_FILE_ERROR_NXIO:
|
||||
return G_IO_ERROR_NOT_REGULAR_FILE;
|
||||
case G_FILE_ERROR_NODEV:
|
||||
return G_IO_ERROR_NO_SUCH_DEVICE;
|
||||
case G_FILE_ERROR_ROFS:
|
||||
return G_IO_ERROR_READ_ONLY;
|
||||
case G_FILE_ERROR_TXTBSY:
|
||||
return G_IO_ERROR_BUSY;
|
||||
case G_FILE_ERROR_LOOP:
|
||||
return G_IO_ERROR_TOO_MANY_LINKS;
|
||||
case G_FILE_ERROR_NOSPC:
|
||||
case G_FILE_ERROR_NOMEM:
|
||||
return G_IO_ERROR_NO_SPACE;
|
||||
case G_FILE_ERROR_MFILE:
|
||||
case G_FILE_ERROR_NFILE:
|
||||
return G_IO_ERROR_TOO_MANY_OPEN_FILES;
|
||||
case G_FILE_ERROR_INVAL:
|
||||
return G_IO_ERROR_INVALID_ARGUMENT;
|
||||
case G_FILE_ERROR_PIPE:
|
||||
return G_IO_ERROR_BROKEN_PIPE;
|
||||
case G_FILE_ERROR_AGAIN:
|
||||
return G_IO_ERROR_WOULD_BLOCK;
|
||||
case G_FILE_ERROR_PERM:
|
||||
return G_IO_ERROR_PERMISSION_DENIED;
|
||||
case G_FILE_ERROR_NOSYS:
|
||||
return G_IO_ERROR_NOT_SUPPORTED;
|
||||
case G_FILE_ERROR_BADF:
|
||||
case G_FILE_ERROR_FAILED:
|
||||
case G_FILE_ERROR_FAULT:
|
||||
case G_FILE_ERROR_INTR:
|
||||
case G_FILE_ERROR_IO:
|
||||
return G_IO_ERROR_FAILED;
|
||||
default:
|
||||
g_return_val_if_reached (G_IO_ERROR_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
/**
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gioenums.h>
|
||||
#include <glib/gfileutils.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -44,6 +45,8 @@ GLIB_AVAILABLE_IN_ALL
|
||||
GQuark g_io_error_quark (void);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
GIOErrorEnum g_io_error_from_errno (gint err_no);
|
||||
GLIB_AVAILABLE_IN_2_74
|
||||
GIOErrorEnum g_io_error_from_file_error (GFileError file_error);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
|
@ -30,21 +30,34 @@
|
||||
#include <unistd.h>
|
||||
|
||||
static GAppInfo *
|
||||
create_app_info (const char *name)
|
||||
create_command_line_app_info (const char *name,
|
||||
const char *command_line,
|
||||
const char *default_for_type)
|
||||
{
|
||||
GError *error;
|
||||
GAppInfo *info;
|
||||
GError *error = NULL;
|
||||
|
||||
error = NULL;
|
||||
info = g_app_info_create_from_commandline ("true blah",
|
||||
info = g_app_info_create_from_commandline (command_line,
|
||||
name,
|
||||
G_APP_INFO_CREATE_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
/* this is necessary to ensure that the info is saved */
|
||||
g_app_info_set_as_default_for_type (info, "application/x-blah", &error);
|
||||
g_app_info_set_as_default_for_type (info, default_for_type, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
return g_steal_pointer (&info);
|
||||
}
|
||||
|
||||
static GAppInfo *
|
||||
create_app_info (const char *name)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GAppInfo *info;
|
||||
|
||||
info = create_command_line_app_info (name, "true blah", "application/x-blah");
|
||||
|
||||
/* this is necessary to ensure that the info is saved */
|
||||
g_app_info_remove_supports_type (info, "application/x-blah", &error);
|
||||
g_assert_no_error (error);
|
||||
g_app_info_reset_type_associations ("application/x-blah");
|
||||
@ -119,6 +132,23 @@ test_default (void)
|
||||
g_assert_cmpstr (g_app_info_get_id (info), ==, g_app_info_get_id (info2));
|
||||
g_object_unref (info);
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*assertion*uri_scheme*failed*");
|
||||
g_assert_null (g_app_info_get_default_for_uri_scheme (NULL));
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*assertion*uri_scheme*failed*");
|
||||
g_assert_null (g_app_info_get_default_for_uri_scheme (""));
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_app_info_set_as_default_for_type (info3, "x-scheme-handler/glib", &error);
|
||||
g_assert_no_error (error);
|
||||
info = g_app_info_get_default_for_uri_scheme ("glib");
|
||||
g_assert_nonnull (info);
|
||||
g_assert_true (g_app_info_equal (info, info3));
|
||||
g_object_unref (info);
|
||||
|
||||
/* now try adding something, but not setting as default */
|
||||
g_app_info_add_supports_type (info3, "application/x-test", &error);
|
||||
g_assert_no_error (error);
|
||||
@ -141,6 +171,170 @@ test_default (void)
|
||||
|
||||
/* now clean it all up */
|
||||
g_app_info_reset_type_associations ("application/x-test");
|
||||
g_app_info_reset_type_associations ("x-scheme-handler/glib");
|
||||
|
||||
list = g_app_info_get_all_for_type ("application/x-test");
|
||||
g_assert_null (list);
|
||||
|
||||
list = g_app_info_get_all_for_type ("x-scheme-handler/glib");
|
||||
g_assert_null (list);
|
||||
|
||||
g_app_info_delete (info1);
|
||||
g_app_info_delete (info2);
|
||||
g_app_info_delete (info3);
|
||||
|
||||
g_object_unref (info1);
|
||||
g_object_unref (info2);
|
||||
g_object_unref (info3);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GAppInfo *expected_info;
|
||||
GMainLoop *loop;
|
||||
} DefaultForTypeData;
|
||||
|
||||
static void
|
||||
ensure_default_type_result (GAppInfo *info,
|
||||
DefaultForTypeData *data,
|
||||
GError *error)
|
||||
{
|
||||
if (data->expected_info)
|
||||
{
|
||||
g_assert_nonnull (info);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (g_app_info_equal (info, data->expected_info));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_null (info);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
|
||||
}
|
||||
|
||||
g_main_loop_quit (data->loop);
|
||||
g_clear_object (&info);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static void
|
||||
on_default_for_type_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GAppInfo *info;
|
||||
GError *error = NULL;
|
||||
DefaultForTypeData *data = user_data;
|
||||
|
||||
g_assert_null (object);
|
||||
|
||||
info = g_app_info_get_default_for_type_finish (result, &error);
|
||||
|
||||
ensure_default_type_result (info, data, error);
|
||||
}
|
||||
|
||||
static void
|
||||
on_default_for_uri_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GAppInfo *info;
|
||||
GError *error = NULL;
|
||||
DefaultForTypeData *data = user_data;
|
||||
|
||||
g_assert_null (object);
|
||||
|
||||
info = g_app_info_get_default_for_uri_scheme_finish (result, &error);
|
||||
|
||||
ensure_default_type_result (info, data, error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_default_async (void)
|
||||
{
|
||||
DefaultForTypeData data;
|
||||
GAppInfo *info1, *info2, *info3;
|
||||
GList *list;
|
||||
GError *error = NULL;
|
||||
|
||||
data.loop = g_main_loop_new (NULL, TRUE);
|
||||
|
||||
info1 = create_app_info ("Blah1");
|
||||
info2 = create_app_info ("Blah2");
|
||||
info3 = create_app_info ("Blah3");
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*assertion*content_type*failed*");
|
||||
g_app_info_get_default_for_type_async (NULL, FALSE, NULL, NULL, NULL);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*assertion*content_type*failed*");
|
||||
g_app_info_get_default_for_type_async ("", FALSE, NULL, NULL, NULL);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_app_info_set_as_default_for_type (info1, "application/x-test", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_app_info_set_as_default_for_type (info2, "application/x-test", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
data.expected_info = info2;
|
||||
g_app_info_get_default_for_type_async ("application/x-test", FALSE,
|
||||
NULL, on_default_for_type_cb, &data);
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
/* now try adding something, but not setting as default */
|
||||
g_app_info_add_supports_type (info3, "application/x-test", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
/* check that info2 is still default */
|
||||
data.expected_info = info2;
|
||||
g_app_info_get_default_for_type_async ("application/x-test", FALSE,
|
||||
NULL, on_default_for_type_cb, &data);
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
/* now remove info1 again */
|
||||
g_app_info_remove_supports_type (info1, "application/x-test", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
/* and make sure info2 is still default */
|
||||
data.expected_info = info2;
|
||||
g_app_info_get_default_for_type_async ("application/x-test", FALSE,
|
||||
NULL, on_default_for_type_cb, &data);
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
g_app_info_set_as_default_for_type (info3, "x-scheme-handler/glib-async", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*assertion*uri_scheme*failed*");
|
||||
g_assert_null (g_app_info_get_default_for_uri_scheme (NULL));
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*assertion*uri_scheme*failed*");
|
||||
g_assert_null (g_app_info_get_default_for_uri_scheme (""));
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
data.expected_info = info3;
|
||||
g_app_info_get_default_for_uri_scheme_async ("glib-async", NULL,
|
||||
on_default_for_uri_cb, &data);
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
/* now clean it all up */
|
||||
g_app_info_reset_type_associations ("application/x-test");
|
||||
|
||||
data.expected_info = NULL;
|
||||
g_app_info_get_default_for_type_async ("application/x-test", FALSE,
|
||||
NULL, on_default_for_type_cb, &data);
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
g_app_info_reset_type_associations ("x-scheme-handler/glib-async");
|
||||
|
||||
data.expected_info = NULL;
|
||||
g_app_info_get_default_for_uri_scheme_async ("glib-async", NULL,
|
||||
on_default_for_uri_cb, &data);
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
list = g_app_info_get_all_for_type ("application/x-test");
|
||||
g_assert_null (list);
|
||||
@ -152,6 +346,8 @@ test_default (void)
|
||||
g_object_unref (info1);
|
||||
g_object_unref (info2);
|
||||
g_object_unref (info3);
|
||||
|
||||
g_main_loop_unref (data.loop);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -799,6 +995,164 @@ test_launch_as_manager (void)
|
||||
g_assert_finalize_object (context);
|
||||
}
|
||||
|
||||
static GAppInfo *
|
||||
create_app_info_toucher (const char *name,
|
||||
const char *touched_file_name,
|
||||
const char *handled_type,
|
||||
char **out_file_path)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GAppInfo *info;
|
||||
gchar *command_line;
|
||||
gchar *file_path;
|
||||
gchar *tmpdir;
|
||||
|
||||
g_assert_nonnull (out_file_path);
|
||||
|
||||
tmpdir = g_dir_make_tmp ("desktop-app-info-launch-XXXXXX", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
file_path = g_build_filename (tmpdir, touched_file_name, NULL);
|
||||
command_line = g_strdup_printf ("touch %s", file_path);
|
||||
|
||||
info = create_command_line_app_info (name, command_line, handled_type);
|
||||
*out_file_path = g_steal_pointer (&file_path);
|
||||
|
||||
g_free (tmpdir);
|
||||
g_free (command_line);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
test_default_uri_handler (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *file_path = NULL;
|
||||
GAppInfo *info;
|
||||
|
||||
info = create_app_info_toucher ("Touch Handled", "handled",
|
||||
"x-scheme-handler/glib-touch",
|
||||
&file_path);
|
||||
g_assert_true (G_IS_APP_INFO (info));
|
||||
g_assert_nonnull (file_path);
|
||||
|
||||
g_assert_true (g_app_info_launch_default_for_uri ("glib-touch://touch-me",
|
||||
NULL, &error));
|
||||
g_assert_no_error (error);
|
||||
|
||||
while (!g_file_test (file_path, G_FILE_TEST_IS_REGULAR));
|
||||
g_assert_true (g_file_test (file_path, G_FILE_TEST_IS_REGULAR));
|
||||
|
||||
g_assert_false (g_app_info_launch_default_for_uri ("glib-INVALID-touch://touch-me",
|
||||
NULL, &error));
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_object_unref (info);
|
||||
g_free (file_path);
|
||||
}
|
||||
|
||||
static void
|
||||
on_launch_default_for_uri_success_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gboolean *called = user_data;
|
||||
|
||||
g_assert_true (g_app_info_launch_default_for_uri_finish (result, &error));
|
||||
g_assert_no_error (error);
|
||||
|
||||
*called = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_launch_default_for_uri_not_found_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GMainLoop *loop = user_data;
|
||||
|
||||
g_assert_false (g_app_info_launch_default_for_uri_finish (result, &error));
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static void
|
||||
on_launch_default_for_uri_cancelled_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GMainLoop *loop = user_data;
|
||||
|
||||
g_assert_false (g_app_info_launch_default_for_uri_finish (result, &error));
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static void
|
||||
test_default_uri_handler_async (void)
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
gchar *file_path = NULL;
|
||||
GAppInfo *info;
|
||||
GMainLoop *loop;
|
||||
gboolean called = FALSE;
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
info = create_app_info_toucher ("Touch Handled", "handled-async",
|
||||
"x-scheme-handler/glib-async-touch",
|
||||
&file_path);
|
||||
g_assert_true (G_IS_APP_INFO (info));
|
||||
g_assert_nonnull (file_path);
|
||||
|
||||
g_app_info_launch_default_for_uri_async ("glib-async-touch://touch-me", NULL,
|
||||
NULL,
|
||||
on_launch_default_for_uri_success_cb,
|
||||
&called);
|
||||
|
||||
while (!g_file_test (file_path, G_FILE_TEST_IS_REGULAR))
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
g_assert_true (called);
|
||||
g_assert_true (g_file_test (file_path, G_FILE_TEST_IS_REGULAR));
|
||||
|
||||
g_unlink (file_path);
|
||||
g_assert_false (g_file_test (file_path, G_FILE_TEST_IS_REGULAR));
|
||||
|
||||
g_app_info_launch_default_for_uri_async ("glib-async-INVALID-touch://touch-me",
|
||||
NULL, NULL,
|
||||
on_launch_default_for_uri_not_found_cb,
|
||||
loop);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
g_app_info_launch_default_for_uri_async ("glib-async-touch://touch-me", NULL,
|
||||
cancellable,
|
||||
on_launch_default_for_uri_cancelled_cb,
|
||||
loop);
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
/* Once started our touch app may take some time before having written the
|
||||
* file, so let's wait a bit here before ensuring that the file has been
|
||||
* created as expected.
|
||||
*/
|
||||
g_usleep (G_USEC_PER_SEC / 10);
|
||||
g_assert_false (g_file_test (file_path, G_FILE_TEST_IS_REGULAR));
|
||||
|
||||
g_object_unref (info);
|
||||
g_main_loop_unref (loop);
|
||||
g_free (file_path);
|
||||
}
|
||||
|
||||
/* Test if Desktop-File Id is correctly formed */
|
||||
static void
|
||||
test_id (void)
|
||||
@ -824,6 +1178,7 @@ main (int argc,
|
||||
|
||||
g_test_add_func ("/desktop-app-info/delete", test_delete);
|
||||
g_test_add_func ("/desktop-app-info/default", test_default);
|
||||
g_test_add_func ("/desktop-app-info/default-async", test_default_async);
|
||||
g_test_add_func ("/desktop-app-info/fallback", test_fallback);
|
||||
g_test_add_func ("/desktop-app-info/lastused", test_last_used);
|
||||
g_test_add_func ("/desktop-app-info/extra-getters", test_extra_getters);
|
||||
@ -832,6 +1187,8 @@ main (int argc,
|
||||
g_test_add_func ("/desktop-app-info/implements", test_implements);
|
||||
g_test_add_func ("/desktop-app-info/show-in", test_show_in);
|
||||
g_test_add_func ("/desktop-app-info/launch-as-manager", test_launch_as_manager);
|
||||
g_test_add_func ("/desktop-app-info/launch-default-uri-handler", test_default_uri_handler);
|
||||
g_test_add_func ("/desktop-app-info/launch-default-uri-handler-async", test_default_uri_handler_async);
|
||||
g_test_add_func ("/desktop-app-info/id", test_id);
|
||||
|
||||
return g_test_run ();
|
||||
|
856
gio/tests/error.c
Normal file
856
gio/tests/error.c
Normal file
@ -0,0 +1,856 @@
|
||||
/* Unit tests for gioerror
|
||||
* GIO - GLib Input, Output and Streaming Library
|
||||
*
|
||||
* Copyright (C) 2022 Marco Trevisan
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* 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
|
||||
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Marco Trevisan <marco.trevisan@canonical.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
/* We are testing some deprecated APIs here */
|
||||
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_error_from_errno (void)
|
||||
{
|
||||
g_assert_cmpint (g_io_error_from_errno (-1), ==, G_IO_ERROR_FAILED);
|
||||
|
||||
#ifdef EEXIST
|
||||
g_assert_cmpint (g_io_error_from_errno (EEXIST), ==,
|
||||
G_IO_ERROR_EXISTS);
|
||||
#endif
|
||||
|
||||
#ifdef EISDIR
|
||||
g_assert_cmpint (g_io_error_from_errno (EISDIR), ==,
|
||||
G_IO_ERROR_IS_DIRECTORY);
|
||||
#endif
|
||||
|
||||
#ifdef EACCES
|
||||
g_assert_cmpint (g_io_error_from_errno (EACCES), ==,
|
||||
G_IO_ERROR_PERMISSION_DENIED);
|
||||
#endif
|
||||
|
||||
#ifdef ENAMETOOLONG
|
||||
g_assert_cmpint (g_io_error_from_errno (ENAMETOOLONG), ==,
|
||||
G_IO_ERROR_FILENAME_TOO_LONG);
|
||||
#endif
|
||||
|
||||
#ifdef ENOENT
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOENT), ==,
|
||||
G_IO_ERROR_NOT_FOUND);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTDIR
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOTDIR), ==,
|
||||
G_IO_ERROR_NOT_DIRECTORY);
|
||||
#endif
|
||||
|
||||
#ifdef ENXIO
|
||||
g_assert_cmpint (g_io_error_from_errno (ENXIO), ==,
|
||||
G_IO_ERROR_NOT_REGULAR_FILE);
|
||||
#endif
|
||||
|
||||
#ifdef EROFS
|
||||
g_assert_cmpint (g_io_error_from_errno (EROFS), ==,
|
||||
G_IO_ERROR_READ_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef ELOOP
|
||||
g_assert_cmpint (g_io_error_from_errno (ELOOP), ==,
|
||||
G_IO_ERROR_TOO_MANY_LINKS);
|
||||
#endif
|
||||
|
||||
#ifdef EMLINK
|
||||
g_assert_cmpint (g_io_error_from_errno (EMLINK), ==,
|
||||
G_IO_ERROR_TOO_MANY_LINKS);
|
||||
#endif
|
||||
|
||||
#ifdef ENOSPC
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOSPC), ==,
|
||||
G_IO_ERROR_NO_SPACE);
|
||||
#endif
|
||||
|
||||
#ifdef ENOMEM
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOMEM), ==,
|
||||
G_IO_ERROR_NO_SPACE);
|
||||
#endif
|
||||
|
||||
#ifdef EINVAL
|
||||
g_assert_cmpint (g_io_error_from_errno (EINVAL), ==,
|
||||
G_IO_ERROR_INVALID_ARGUMENT);
|
||||
#endif
|
||||
|
||||
#ifdef EPERM
|
||||
g_assert_cmpint (g_io_error_from_errno (EPERM), ==,
|
||||
G_IO_ERROR_PERMISSION_DENIED);
|
||||
#endif
|
||||
|
||||
#ifdef ECANCELED
|
||||
g_assert_cmpint (g_io_error_from_errno (ECANCELED), ==,
|
||||
G_IO_ERROR_CANCELLED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTEMPTY
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOTEMPTY), ==,
|
||||
G_IO_ERROR_NOT_EMPTY);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTSUP
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOTSUP), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
#endif
|
||||
|
||||
#ifdef EOPNOTSUPP
|
||||
g_assert_cmpint (g_io_error_from_errno (EOPNOTSUPP), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
#endif
|
||||
|
||||
#ifdef EPROTONOSUPPORT
|
||||
g_assert_cmpint (g_io_error_from_errno (EPROTONOSUPPORT), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
#endif
|
||||
|
||||
#ifdef ESOCKTNOSUPPORT
|
||||
g_assert_cmpint (g_io_error_from_errno (ESOCKTNOSUPPORT), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
#endif
|
||||
|
||||
#ifdef EPFNOSUPPORT
|
||||
g_assert_cmpint (g_io_error_from_errno (EPFNOSUPPORT), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
#endif
|
||||
|
||||
#ifdef EAFNOSUPPORT
|
||||
g_assert_cmpint (g_io_error_from_errno (EAFNOSUPPORT), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
#endif
|
||||
|
||||
#ifdef ETIMEDOUT
|
||||
g_assert_cmpint (g_io_error_from_errno (ETIMEDOUT), ==,
|
||||
G_IO_ERROR_TIMED_OUT);
|
||||
#endif
|
||||
|
||||
#ifdef EBUSY
|
||||
g_assert_cmpint (g_io_error_from_errno (EBUSY), ==,
|
||||
G_IO_ERROR_BUSY);
|
||||
#endif
|
||||
|
||||
#ifdef EWOULDBLOCK
|
||||
g_assert_cmpint (g_io_error_from_errno (EWOULDBLOCK), ==,
|
||||
G_IO_ERROR_WOULD_BLOCK);
|
||||
#endif
|
||||
|
||||
#ifdef EAGAIN
|
||||
g_assert_cmpint (g_io_error_from_errno (EAGAIN), ==,
|
||||
G_IO_ERROR_WOULD_BLOCK);
|
||||
#endif
|
||||
|
||||
#ifdef EMFILE
|
||||
g_assert_cmpint (g_io_error_from_errno (EMFILE), ==,
|
||||
G_IO_ERROR_TOO_MANY_OPEN_FILES);
|
||||
#endif
|
||||
|
||||
#ifdef EADDRINUSE
|
||||
g_assert_cmpint (g_io_error_from_errno (EADDRINUSE), ==,
|
||||
G_IO_ERROR_ADDRESS_IN_USE);
|
||||
#endif
|
||||
|
||||
#ifdef EHOSTUNREACH
|
||||
g_assert_cmpint (g_io_error_from_errno (EHOSTUNREACH), ==,
|
||||
G_IO_ERROR_HOST_UNREACHABLE);
|
||||
#endif
|
||||
|
||||
#ifdef ENETUNREACH
|
||||
g_assert_cmpint (g_io_error_from_errno (ENETUNREACH), ==,
|
||||
G_IO_ERROR_NETWORK_UNREACHABLE);
|
||||
#endif
|
||||
|
||||
#ifdef ECONNREFUSED
|
||||
g_assert_cmpint (g_io_error_from_errno (ECONNREFUSED), ==,
|
||||
G_IO_ERROR_CONNECTION_REFUSED);
|
||||
#endif
|
||||
|
||||
#ifdef EPIPE
|
||||
g_assert_cmpint (g_io_error_from_errno (EPIPE), ==,
|
||||
G_IO_ERROR_BROKEN_PIPE);
|
||||
#endif
|
||||
|
||||
#ifdef ECONNRESET
|
||||
g_assert_cmpint (g_io_error_from_errno (ECONNRESET), ==,
|
||||
G_IO_ERROR_CONNECTION_CLOSED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTCONN
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOTCONN), ==,
|
||||
G_IO_ERROR_NOT_CONNECTED);
|
||||
#endif
|
||||
|
||||
#ifdef EMSGSIZE
|
||||
g_assert_cmpint (g_io_error_from_errno (EMSGSIZE), ==,
|
||||
G_IO_ERROR_MESSAGE_TOO_LARGE);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTSOCK
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOTSOCK), ==,
|
||||
G_IO_ERROR_INVALID_ARGUMENT);
|
||||
#endif
|
||||
|
||||
#ifdef ESRCH
|
||||
g_assert_cmpint (g_io_error_from_errno (ESRCH), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EINTR
|
||||
g_assert_cmpint (g_io_error_from_errno (EINTR), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EIO
|
||||
g_assert_cmpint (g_io_error_from_errno (EIO), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef E2BIG
|
||||
g_assert_cmpint (g_io_error_from_errno (E2BIG), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOEXEC
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOEXEC), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EBADF
|
||||
g_assert_cmpint (g_io_error_from_errno (EBADF), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ECHILD
|
||||
g_assert_cmpint (g_io_error_from_errno (ECHILD), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EFAULT
|
||||
g_assert_cmpint (g_io_error_from_errno (EFAULT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTBLK
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOTBLK), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EXDEV
|
||||
g_assert_cmpint (g_io_error_from_errno (EXDEV), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENODEV
|
||||
g_assert_cmpint (g_io_error_from_errno (ENODEV), ==,
|
||||
G_IO_ERROR_NO_SUCH_DEVICE);
|
||||
#endif
|
||||
|
||||
#ifdef ENFILE
|
||||
g_assert_cmpint (g_io_error_from_errno (ENFILE), ==,
|
||||
G_IO_ERROR_TOO_MANY_OPEN_FILES);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTTY
|
||||
g_assert_cmpint (g_io_error_from_errno (ENOTTY), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ETXTBSY
|
||||
g_assert_cmpint (g_io_error_from_errno (ETXTBSY), ==,
|
||||
G_IO_ERROR_BUSY);
|
||||
#endif
|
||||
|
||||
#ifdef EFBIG
|
||||
g_assert_cmpint (g_io_error_from_errno (EFBIG), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ESPIPE
|
||||
g_assert_cmpint (g_io_error_from_errno (ESPIPE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EDOM
|
||||
g_assert_cmpint (g_io_error_from_errno (EDOM), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ERANGE
|
||||
g_assert_cmpint (g_io_error_from_errno (ERANGE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EDEADLK
|
||||
g_assert_cmpuint (g_io_error_from_errno (EDEADLK), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOLCK
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOLCK), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOSYS
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOSYS), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOMSG
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOMSG), ==,
|
||||
G_IO_ERROR_INVALID_DATA);
|
||||
#endif
|
||||
|
||||
#ifdef EIDRM
|
||||
g_assert_cmpuint (g_io_error_from_errno (EIDRM), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ECHRNG
|
||||
g_assert_cmpuint (g_io_error_from_errno (ECHRNG), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EL2NSYNC
|
||||
g_assert_cmpuint (g_io_error_from_errno (EL2NSYNC), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EL3HLT
|
||||
g_assert_cmpuint (g_io_error_from_errno (EL3HLT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EL3RST
|
||||
g_assert_cmpuint (g_io_error_from_errno (EL3RST), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ELNRNG
|
||||
g_assert_cmpuint (g_io_error_from_errno (ELNRNG), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EUNATCH
|
||||
g_assert_cmpuint (g_io_error_from_errno (EUNATCH), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOCSI
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOCSI), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EL2HLT
|
||||
g_assert_cmpuint (g_io_error_from_errno (EL2HLT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EBADE
|
||||
g_assert_cmpuint (g_io_error_from_errno (EBADE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EBADR
|
||||
g_assert_cmpuint (g_io_error_from_errno (EBADR), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EXFULL
|
||||
g_assert_cmpuint (g_io_error_from_errno (EXFULL), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOANO
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOANO), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EBADRQC
|
||||
g_assert_cmpuint (g_io_error_from_errno (EBADRQC), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EBADSLT
|
||||
g_assert_cmpuint (g_io_error_from_errno (EBADSLT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EDEADLOCK
|
||||
g_assert_cmpuint (g_io_error_from_errno (EDEADLOCK), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EBFONT
|
||||
g_assert_cmpuint (g_io_error_from_errno (EBFONT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOSTR
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOSTR), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENODATA
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENODATA), ==,
|
||||
G_IO_ERROR_INVALID_DATA);
|
||||
#endif
|
||||
|
||||
#ifdef ETIME
|
||||
g_assert_cmpuint (g_io_error_from_errno (ETIME), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOSR
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOSR), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENONET
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENONET), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOPKG
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOPKG), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EREMOTE
|
||||
g_assert_cmpuint (g_io_error_from_errno (EREMOTE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOLINK
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOLINK), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EADV
|
||||
g_assert_cmpuint (g_io_error_from_errno (EADV), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ESRMNT
|
||||
g_assert_cmpuint (g_io_error_from_errno (ESRMNT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ECOMM
|
||||
g_assert_cmpuint (g_io_error_from_errno (ECOMM), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EPROTO
|
||||
g_assert_cmpuint (g_io_error_from_errno (EPROTO), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EMULTIHOP
|
||||
g_assert_cmpuint (g_io_error_from_errno (EMULTIHOP), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EDOTDOT
|
||||
g_assert_cmpuint (g_io_error_from_errno (EDOTDOT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EBADMSG
|
||||
g_assert_cmpuint (g_io_error_from_errno (EBADMSG), ==,
|
||||
G_IO_ERROR_INVALID_DATA);
|
||||
#endif
|
||||
|
||||
#ifdef EOVERFLOW
|
||||
g_assert_cmpuint (g_io_error_from_errno (EOVERFLOW), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTUNIQ
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOTUNIQ), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EBADFD
|
||||
g_assert_cmpuint (g_io_error_from_errno (EBADFD), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EREMCHG
|
||||
g_assert_cmpuint (g_io_error_from_errno (EREMCHG), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ELIBACC
|
||||
g_assert_cmpuint (g_io_error_from_errno (ELIBACC), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ELIBBAD
|
||||
g_assert_cmpuint (g_io_error_from_errno (ELIBBAD), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ELIBSCN
|
||||
g_assert_cmpuint (g_io_error_from_errno (ELIBSCN), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ELIBMAX
|
||||
g_assert_cmpuint (g_io_error_from_errno (ELIBMAX), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ELIBEXEC
|
||||
g_assert_cmpuint (g_io_error_from_errno (ELIBEXEC), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EILSEQ
|
||||
g_assert_cmpuint (g_io_error_from_errno (EILSEQ), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ERESTART
|
||||
g_assert_cmpuint (g_io_error_from_errno (ERESTART), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ESTRPIPE
|
||||
g_assert_cmpuint (g_io_error_from_errno (ESTRPIPE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EUSERS
|
||||
g_assert_cmpuint (g_io_error_from_errno (EUSERS), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EDESTADDRREQ
|
||||
g_assert_cmpuint (g_io_error_from_errno (EDESTADDRREQ), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EPROTOTYPE
|
||||
g_assert_cmpuint (g_io_error_from_errno (EPROTOTYPE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOPROTOOPT
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOPROTOOPT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EADDRNOTAVAIL
|
||||
g_assert_cmpuint (g_io_error_from_errno (EADDRNOTAVAIL), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENETDOWN
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENETDOWN), ==,
|
||||
G_IO_ERROR_NETWORK_UNREACHABLE);
|
||||
#endif
|
||||
|
||||
#ifdef ECONNABORTED
|
||||
g_assert_cmpuint (g_io_error_from_errno (ECONNABORTED), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOBUFS
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOBUFS), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EISCONN
|
||||
g_assert_cmpuint (g_io_error_from_errno (EISCONN), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ESHUTDOWN
|
||||
g_assert_cmpuint (g_io_error_from_errno (ESHUTDOWN), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ETOOMANYREFS
|
||||
g_assert_cmpuint (g_io_error_from_errno (ETOOMANYREFS), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EHOSTDOWN
|
||||
g_assert_cmpuint (g_io_error_from_errno (EHOSTDOWN), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EALREADY
|
||||
g_assert_cmpuint (g_io_error_from_errno (EALREADY), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EINPROGRESS
|
||||
g_assert_cmpuint (g_io_error_from_errno (EINPROGRESS), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ESTALE
|
||||
g_assert_cmpuint (g_io_error_from_errno (ESTALE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EUCLEAN
|
||||
g_assert_cmpuint (g_io_error_from_errno (EUCLEAN), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTNAM
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOTNAM), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENAVAIL
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENAVAIL), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EISNAM
|
||||
g_assert_cmpuint (g_io_error_from_errno (EISNAM), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EREMOTEIO
|
||||
g_assert_cmpuint (g_io_error_from_errno (EREMOTEIO), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EDQUOT
|
||||
g_assert_cmpuint (g_io_error_from_errno (EDQUOT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOMEDIUM
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOMEDIUM), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EMEDIUMTYPE
|
||||
g_assert_cmpuint (g_io_error_from_errno (EMEDIUMTYPE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOKEY
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOKEY), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EKEYEXPIRED
|
||||
g_assert_cmpuint (g_io_error_from_errno (EKEYEXPIRED), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EKEYREVOKED
|
||||
g_assert_cmpuint (g_io_error_from_errno (EKEYREVOKED), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EKEYREJECTED
|
||||
g_assert_cmpuint (g_io_error_from_errno (EKEYREJECTED), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EOWNERDEAD
|
||||
g_assert_cmpuint (g_io_error_from_errno (EOWNERDEAD), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ENOTRECOVERABLE
|
||||
g_assert_cmpuint (g_io_error_from_errno (ENOTRECOVERABLE), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef ERFKILL
|
||||
g_assert_cmpuint (g_io_error_from_errno (ERFKILL), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
|
||||
#ifdef EHWPOISON
|
||||
g_assert_cmpuint (g_io_error_from_errno (EHWPOISON), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
test_error_from_file_error (void)
|
||||
{
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*should not be reached*");
|
||||
g_assert_cmpuint (g_io_error_from_file_error (-1), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_EXIST), ==,
|
||||
G_IO_ERROR_EXISTS);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_ISDIR), ==,
|
||||
G_IO_ERROR_IS_DIRECTORY);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_ACCES), ==,
|
||||
G_IO_ERROR_PERMISSION_DENIED);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NAMETOOLONG), ==,
|
||||
G_IO_ERROR_FILENAME_TOO_LONG);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NOENT), ==,
|
||||
G_IO_ERROR_NOT_FOUND);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NOTDIR), ==,
|
||||
G_IO_ERROR_NOT_DIRECTORY);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NXIO), ==,
|
||||
G_IO_ERROR_NOT_REGULAR_FILE);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NODEV), ==,
|
||||
G_IO_ERROR_NO_SUCH_DEVICE);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_ROFS), ==,
|
||||
G_IO_ERROR_READ_ONLY);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_TXTBSY), ==,
|
||||
G_IO_ERROR_BUSY);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_LOOP), ==,
|
||||
G_IO_ERROR_TOO_MANY_LINKS);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NOSPC), ==,
|
||||
G_IO_ERROR_NO_SPACE);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NOMEM), ==,
|
||||
G_IO_ERROR_NO_SPACE);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_MFILE), ==,
|
||||
G_IO_ERROR_TOO_MANY_OPEN_FILES);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NFILE), ==,
|
||||
G_IO_ERROR_TOO_MANY_OPEN_FILES);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_INVAL), ==,
|
||||
G_IO_ERROR_INVALID_ARGUMENT);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_PIPE), ==,
|
||||
G_IO_ERROR_BROKEN_PIPE);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_AGAIN), ==,
|
||||
G_IO_ERROR_WOULD_BLOCK);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_PERM), ==,
|
||||
G_IO_ERROR_PERMISSION_DENIED);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_NOSYS), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_BADF), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_FAILED), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_FAULT), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_INTR), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
g_assert_cmpuint (g_io_error_from_file_error (G_FILE_ERROR_IO), ==,
|
||||
G_IO_ERROR_FAILED);
|
||||
}
|
||||
|
||||
static void
|
||||
test_error_from_win32_error (void)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
g_assert_cmpint (g_io_error_from_win32_error (-1), ==, G_IO_ERROR_FAILED);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEADDRINUSE), ==,
|
||||
G_IO_ERROR_ADDRESS_IN_USE);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEWOULDBLOCK), ==,
|
||||
G_IO_ERROR_WOULD_BLOCK);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEACCES), ==,
|
||||
G_IO_ERROR_PERMISSION_DENIED);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSA_INVALID_HANDLE), ==,
|
||||
G_IO_ERROR_INVALID_ARGUMENT);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSA_INVALID_PARAMETER), ==,
|
||||
G_IO_ERROR_INVALID_ARGUMENT);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEINVAL), ==,
|
||||
G_IO_ERROR_INVALID_ARGUMENT);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEBADF), ==,
|
||||
G_IO_ERROR_INVALID_ARGUMENT);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAENOTSOCK), ==,
|
||||
G_IO_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEPROTONOSUPPORT), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAECANCELLED), ==,
|
||||
G_IO_ERROR_CANCELLED);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAESOCKTNOSUPPORT), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEOPNOTSUPP), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEPFNOSUPPORT), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEAFNOSUPPORT), ==,
|
||||
G_IO_ERROR_NOT_SUPPORTED);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAECONNRESET), ==,
|
||||
G_IO_ERROR_CONNECTION_CLOSED);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAENETRESET), ==,
|
||||
G_IO_ERROR_CONNECTION_CLOSED);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAESHUTDOWN), ==,
|
||||
G_IO_ERROR_CONNECTION_CLOSED);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEHOSTUNREACH), ==,
|
||||
G_IO_ERROR_HOST_UNREACHABLE);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAENETUNREACH), ==,
|
||||
G_IO_ERROR_NETWORK_UNREACHABLE);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAECONNREFUSED), ==,
|
||||
G_IO_ERROR_CONNECTION_REFUSED);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAETIMEDOUT), ==,
|
||||
G_IO_ERROR_TIMED_OUT);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAENOTCONN), ==,
|
||||
G_IO_ERROR_NOT_CONNECTED);
|
||||
g_assert_cmpint (g_io_error_from_win32_error (ERROR_PIPE_LISTENING), ==,
|
||||
G_IO_ERROR_NOT_CONNECTED);
|
||||
|
||||
g_assert_cmpint (g_io_error_from_win32_error (WSAEMSGSIZE), ==,
|
||||
G_IO_ERROR_MESSAGE_TOO_LARGE);
|
||||
#else
|
||||
g_test_skip ("Windows error codes can only be checked on Windows");
|
||||
#endif /* G_OS_WIN32 */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_setenv ("LC_ALL", "C", TRUE);
|
||||
g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
|
||||
|
||||
g_test_add_func ("/error/from-errno", test_error_from_errno);
|
||||
g_test_add_func ("/error/from-file-error", test_error_from_file_error);
|
||||
g_test_add_func ("/error/from-win32-error", test_error_from_win32_error);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
647
gio/tests/file.c
647
gio/tests/file.c
@ -8,6 +8,12 @@
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMainLoop *loop;
|
||||
GError **error;
|
||||
} AsyncErrorData;
|
||||
|
||||
static void
|
||||
test_basic_for_file (GFile *file,
|
||||
const gchar *suffix)
|
||||
@ -852,6 +858,18 @@ test_replace_symlink (void)
|
||||
g_test_message ("Using temporary directory %s", tmpdir_path);
|
||||
g_free (tmpdir_path);
|
||||
|
||||
source_file = g_file_get_child (tmpdir, "source");
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*assertion*symlink_value*failed*");
|
||||
g_assert_false (g_file_make_symbolic_link (source_file, NULL, NULL, &local_error));
|
||||
g_assert_no_error (local_error);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_assert_false (g_file_make_symbolic_link (source_file, "", NULL, &local_error));
|
||||
g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
|
||||
g_clear_object (&source_file);
|
||||
g_clear_error (&local_error);
|
||||
|
||||
/* Create symlink `source` which points to `target`. */
|
||||
source_file = g_file_get_child (tmpdir, "source");
|
||||
target_file = g_file_get_child (tmpdir, "target");
|
||||
@ -1958,6 +1976,200 @@ test_replace (gconstpointer test_data)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
on_new_tmp_done (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFile *file;
|
||||
GFile *parent;
|
||||
GFileInfo *info;
|
||||
GFileIOStream *iostream;
|
||||
GError *error = NULL;
|
||||
GMainLoop *loop = user_data;
|
||||
gchar *basename;
|
||||
gchar *parent_path;
|
||||
|
||||
g_assert_null (object);
|
||||
|
||||
file = g_file_new_tmp_finish (result, &iostream, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_true (g_file_query_exists (file, NULL));
|
||||
|
||||
basename = g_file_get_basename (file);
|
||||
g_assert_true (g_str_has_prefix (basename, "g_file_new_tmp_async_"));
|
||||
|
||||
info = g_file_io_stream_query_info (iostream, G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
||||
NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_cmpuint (g_file_info_get_file_type (info), ==, G_FILE_TYPE_REGULAR);
|
||||
g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
parent = g_file_get_parent (file);
|
||||
parent_path = g_file_get_path (parent);
|
||||
|
||||
g_assert_cmpstr (g_get_tmp_dir (), ==, parent_path);
|
||||
|
||||
g_main_loop_quit (loop);
|
||||
|
||||
g_object_unref (file);
|
||||
g_object_unref (parent);
|
||||
g_object_unref (iostream);
|
||||
g_object_unref (info);
|
||||
g_free (basename);
|
||||
g_free (parent_path);
|
||||
}
|
||||
|
||||
static void
|
||||
on_new_tmp_error (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFileIOStream *iostream = (GFileIOStream*) &on_new_tmp_error;
|
||||
AsyncErrorData *error_data = user_data;
|
||||
|
||||
g_assert_null (object);
|
||||
|
||||
g_assert_null (g_file_new_tmp_finish (result, &iostream, error_data->error));
|
||||
g_assert_nonnull (error_data->error);
|
||||
g_assert_null (iostream);
|
||||
|
||||
g_main_loop_quit (error_data->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
test_async_new_tmp (void)
|
||||
{
|
||||
GMainLoop *loop;
|
||||
GError *error = NULL;
|
||||
GCancellable *cancellable;
|
||||
AsyncErrorData error_data = { .error = &error };
|
||||
|
||||
loop = g_main_loop_new (NULL, TRUE);
|
||||
error_data.loop = loop;
|
||||
|
||||
g_file_new_tmp_async ("g_file_new_tmp_async_XXXXXX",
|
||||
G_PRIORITY_DEFAULT, NULL,
|
||||
on_new_tmp_done, loop);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_file_new_tmp_async ("g_file_new_tmp_async_invalid_template",
|
||||
G_PRIORITY_DEFAULT, NULL,
|
||||
on_new_tmp_error, &error_data);
|
||||
g_main_loop_run (loop);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
||||
g_clear_error (&error);
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
g_file_new_tmp_async ("g_file_new_tmp_async_cancelled_XXXXXX",
|
||||
G_PRIORITY_DEFAULT, cancellable,
|
||||
on_new_tmp_error, &error_data);
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_main_loop_run (loop);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||
g_clear_object (&cancellable);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_main_loop_unref (loop);
|
||||
}
|
||||
|
||||
static void
|
||||
on_new_tmp_dir_done (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFile *file;
|
||||
GFile *parent;
|
||||
GFileInfo *info;
|
||||
GError *error = NULL;
|
||||
GMainLoop *loop = user_data;
|
||||
gchar *basename;
|
||||
gchar *parent_path;
|
||||
|
||||
g_assert_null (object);
|
||||
|
||||
file = g_file_new_tmp_dir_finish (result, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_true (g_file_query_exists (file, NULL));
|
||||
|
||||
basename = g_file_get_basename (file);
|
||||
g_assert_true (g_str_has_prefix (basename, "g_file_new_tmp_dir_async_"));
|
||||
|
||||
info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE,
|
||||
G_FILE_QUERY_INFO_NONE, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_cmpuint (g_file_info_get_file_type (info), ==, G_FILE_TYPE_DIRECTORY);
|
||||
|
||||
parent = g_file_get_parent (file);
|
||||
parent_path = g_file_get_path (parent);
|
||||
|
||||
g_assert_cmpstr (g_get_tmp_dir (), ==, parent_path);
|
||||
|
||||
g_main_loop_quit (loop);
|
||||
|
||||
g_object_unref (file);
|
||||
g_object_unref (parent);
|
||||
g_object_unref (info);
|
||||
g_free (basename);
|
||||
g_free (parent_path);
|
||||
}
|
||||
|
||||
static void
|
||||
on_new_tmp_dir_error (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
AsyncErrorData *error_data = user_data;
|
||||
|
||||
g_assert_null (object);
|
||||
|
||||
g_assert_null (g_file_new_tmp_dir_finish (result, error_data->error));
|
||||
g_assert_nonnull (error_data->error);
|
||||
|
||||
g_main_loop_quit (error_data->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
test_async_new_tmp_dir (void)
|
||||
{
|
||||
GMainLoop *loop;
|
||||
GError *error = NULL;
|
||||
GCancellable *cancellable;
|
||||
AsyncErrorData error_data = { .error = &error };
|
||||
|
||||
loop = g_main_loop_new (NULL, TRUE);
|
||||
error_data.loop = loop;
|
||||
|
||||
g_file_new_tmp_dir_async ("g_file_new_tmp_dir_async_XXXXXX",
|
||||
G_PRIORITY_DEFAULT, NULL,
|
||||
on_new_tmp_dir_done, loop);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_file_new_tmp_dir_async ("g_file_new_tmp_dir_async",
|
||||
G_PRIORITY_DEFAULT, NULL,
|
||||
on_new_tmp_dir_error, &error_data);
|
||||
g_main_loop_run (loop);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
||||
g_clear_error (&error);
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
g_file_new_tmp_dir_async ("g_file_new_tmp_dir_async_cancelled_XXXXXX",
|
||||
G_PRIORITY_DEFAULT, cancellable,
|
||||
on_new_tmp_dir_error, &error_data);
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_main_loop_run (loop);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||
g_clear_object (&cancellable);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_main_loop_unref (loop);
|
||||
}
|
||||
|
||||
static void
|
||||
on_file_deleted (GObject *object,
|
||||
GAsyncResult *result,
|
||||
@ -2000,6 +2212,133 @@ test_async_delete (void)
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
static void
|
||||
on_symlink_done (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFile *file = (GFile *) object;
|
||||
GError *error = NULL;
|
||||
GMainLoop *loop = user_data;
|
||||
|
||||
g_assert_true (g_file_make_symbolic_link_finish (file, result, &error));
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static void
|
||||
on_symlink_error (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFile *file = (GFile *) object;
|
||||
GError *error = NULL;
|
||||
AsyncErrorData *data = user_data;
|
||||
|
||||
g_assert_false (g_file_make_symbolic_link_finish (file, result, &error));
|
||||
g_assert_nonnull (error);
|
||||
g_propagate_error (data->error, g_steal_pointer (&error));
|
||||
|
||||
g_main_loop_quit (data->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
test_async_make_symlink (void)
|
||||
{
|
||||
GFile *link;
|
||||
GFile *parent_dir;
|
||||
GFile *target;
|
||||
GFileInfo *link_info;
|
||||
GFileIOStream *iostream;
|
||||
GError *error = NULL;
|
||||
GCancellable *cancellable;
|
||||
GMainLoop *loop;
|
||||
AsyncErrorData error_data = {0};
|
||||
gchar *tmpdir_path;
|
||||
gchar *target_path;
|
||||
|
||||
target = g_file_new_tmp ("g_file_symlink_target_XXXXXX", &iostream, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_io_stream_close ((GIOStream *) iostream, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_object_unref (iostream);
|
||||
|
||||
g_assert_true (g_file_query_exists (target, NULL));
|
||||
|
||||
loop = g_main_loop_new (NULL, TRUE);
|
||||
error_data.loop = loop;
|
||||
error_data.error = &error;
|
||||
|
||||
tmpdir_path = g_dir_make_tmp ("g_file_symlink_XXXXXX", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
parent_dir = g_file_new_for_path (tmpdir_path);
|
||||
g_assert_true (g_file_query_exists (parent_dir, NULL));
|
||||
|
||||
link = g_file_get_child (parent_dir, "symlink");
|
||||
g_assert_false (g_file_query_exists (link, NULL));
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*assertion*symlink_value*failed*");
|
||||
g_file_make_symbolic_link_async (link, NULL,
|
||||
G_PRIORITY_DEFAULT, NULL,
|
||||
on_symlink_done, loop);
|
||||
g_test_assert_expected_messages ();
|
||||
|
||||
g_file_make_symbolic_link_async (link, "",
|
||||
G_PRIORITY_DEFAULT, NULL,
|
||||
on_symlink_error, &error_data);
|
||||
g_main_loop_run (loop);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
|
||||
g_clear_error (&error);
|
||||
|
||||
target_path = g_file_get_path (target);
|
||||
g_file_make_symbolic_link_async (link, target_path,
|
||||
G_PRIORITY_DEFAULT, NULL,
|
||||
on_symlink_done, loop);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
g_assert_true (g_file_query_exists (link, NULL));
|
||||
link_info = g_file_query_info (link,
|
||||
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
|
||||
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
NULL,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_true (g_file_info_get_is_symlink (link_info));
|
||||
g_assert_cmpstr (target_path, ==, g_file_info_get_symlink_target (link_info));
|
||||
|
||||
/* Try creating it again, it fails */
|
||||
g_file_make_symbolic_link_async (link, target_path,
|
||||
G_PRIORITY_DEFAULT, NULL,
|
||||
on_symlink_error, &error_data);
|
||||
g_main_loop_run (loop);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
|
||||
g_clear_error (&error);
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
g_file_make_symbolic_link_async (link, target_path,
|
||||
G_PRIORITY_DEFAULT, cancellable,
|
||||
on_symlink_error, &error_data);
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_main_loop_run (loop);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||
g_clear_error (&error);
|
||||
g_clear_object (&cancellable);
|
||||
|
||||
g_main_loop_unref (loop);
|
||||
g_object_unref (target);
|
||||
g_object_unref (parent_dir);
|
||||
g_object_unref (link);
|
||||
g_object_unref (link_info);
|
||||
g_free (tmpdir_path);
|
||||
g_free (target_path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_copy_preserve_mode (void)
|
||||
{
|
||||
@ -3125,6 +3464,307 @@ test_move_async (void)
|
||||
g_free (destination_path);
|
||||
}
|
||||
|
||||
static GAppInfo *
|
||||
create_command_line_app_info (const char *name,
|
||||
const char *command_line,
|
||||
const char *default_for_type)
|
||||
{
|
||||
GAppInfo *info;
|
||||
GError *error = NULL;
|
||||
|
||||
info = g_app_info_create_from_commandline (command_line,
|
||||
name,
|
||||
G_APP_INFO_CREATE_NONE,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_app_info_set_as_default_for_type (info, default_for_type, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
return g_steal_pointer (&info);
|
||||
}
|
||||
|
||||
static void
|
||||
test_query_default_handler_uri (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GAppInfo *info;
|
||||
GAppInfo *default_info;
|
||||
GFile *file;
|
||||
GFile *invalid_file;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
g_test_skip ("Default URI handlers are not currently supported on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
info = create_command_line_app_info ("Gio File Handler", "true",
|
||||
"x-scheme-handler/gio-file");
|
||||
g_assert_true (G_IS_APP_INFO (info));
|
||||
|
||||
file = g_file_new_for_uri ("gio-file://hello-gio!");
|
||||
default_info = g_file_query_default_handler (file, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (g_app_info_equal (default_info, info));
|
||||
|
||||
invalid_file = g_file_new_for_uri ("gio-file-INVALID://goodbye-gio!");
|
||||
g_assert_null (g_file_query_default_handler (invalid_file, NULL, &error));
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_app_info_remove_supports_type (info, "x-scheme-handler/gio-file", &error);
|
||||
g_assert_no_error (error);
|
||||
g_app_info_reset_type_associations ("x-scheme-handler/gio-file");
|
||||
|
||||
g_object_unref (default_info);
|
||||
g_object_unref (info);
|
||||
g_object_unref (file);
|
||||
g_object_unref (invalid_file);
|
||||
}
|
||||
|
||||
static void
|
||||
test_query_default_handler_file (void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GAppInfo *info;
|
||||
GAppInfo *default_info;
|
||||
GFile *text_file;
|
||||
GFile *binary_file;
|
||||
GFile *invalid_file;
|
||||
GFileIOStream *iostream;
|
||||
GOutputStream *output_stream;
|
||||
const char buffer[] = "Text file!\n";
|
||||
const guint8 binary_buffer[] = "\xde\xad\xbe\xff";
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
g_test_skip ("Default URI handlers are not currently supported on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
text_file = g_file_new_tmp ("query-default-handler-XXXXXX", &iostream, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
output_stream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
|
||||
g_output_stream_write_all (output_stream, buffer, G_N_ELEMENTS (buffer) - 1,
|
||||
NULL, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_output_stream_close (output_stream, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_clear_object (&iostream);
|
||||
|
||||
info = create_command_line_app_info ("Text handler", "true", "text/plain");
|
||||
g_assert_true (G_IS_APP_INFO (info));
|
||||
|
||||
default_info = g_file_query_default_handler (text_file, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (g_app_info_equal (default_info, info));
|
||||
|
||||
invalid_file = g_file_new_for_path ("/hopefully/this-does-not-exists");
|
||||
g_assert_null (g_file_query_default_handler (invalid_file, NULL, &error));
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
|
||||
g_clear_error (&error);
|
||||
|
||||
binary_file = g_file_new_tmp ("query-default-handler-bin-XXXXXX", &iostream, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
output_stream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
|
||||
g_output_stream_write_all (output_stream, binary_buffer,
|
||||
G_N_ELEMENTS (binary_buffer),
|
||||
NULL, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_output_stream_close (output_stream, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_clear_object (&iostream);
|
||||
|
||||
g_assert_null (g_file_query_default_handler (binary_file, NULL, &error));
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_app_info_remove_supports_type (info, "text/plain", &error);
|
||||
g_assert_no_error (error);
|
||||
g_app_info_reset_type_associations ("text/plain");
|
||||
|
||||
g_object_unref (default_info);
|
||||
g_object_unref (info);
|
||||
g_object_unref (text_file);
|
||||
g_object_unref (binary_file);
|
||||
g_object_unref (invalid_file);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GMainLoop *loop;
|
||||
GAppInfo *info;
|
||||
GError *error;
|
||||
} QueryDefaultHandlerData;
|
||||
|
||||
static void
|
||||
on_query_default (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
QueryDefaultHandlerData *data = user_data;
|
||||
|
||||
data->info = g_file_query_default_handler_finish (G_FILE (source), result,
|
||||
&data->error);
|
||||
g_main_loop_quit (data->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
test_query_default_handler_file_async (void)
|
||||
{
|
||||
QueryDefaultHandlerData data = {0};
|
||||
GCancellable *cancellable;
|
||||
GAppInfo *info;
|
||||
GFile *text_file;
|
||||
GFile *binary_file;
|
||||
GFile *invalid_file;
|
||||
GFileIOStream *iostream;
|
||||
GOutputStream *output_stream;
|
||||
const char buffer[] = "Text file!\n";
|
||||
const guint8 binary_buffer[] = "\xde\xad\xbe\xff";
|
||||
GError *error = NULL;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
g_test_skip ("Default URI handlers are not currently supported on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
data.loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
text_file = g_file_new_tmp ("query-default-handler-XXXXXX", &iostream, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
output_stream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
|
||||
g_output_stream_write_all (output_stream, buffer, G_N_ELEMENTS (buffer) - 1,
|
||||
NULL, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_output_stream_close (output_stream, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_clear_object (&iostream);
|
||||
|
||||
info = create_command_line_app_info ("Text handler", "true", "text/plain");
|
||||
g_assert_true (G_IS_APP_INFO (info));
|
||||
|
||||
g_file_query_default_handler_async (text_file, G_PRIORITY_DEFAULT,
|
||||
NULL, on_query_default,
|
||||
&data);
|
||||
g_main_loop_run (data.loop);
|
||||
g_assert_no_error (data.error);
|
||||
g_assert_true (g_app_info_equal (data.info, info));
|
||||
g_clear_object (&data.info);
|
||||
|
||||
invalid_file = g_file_new_for_path ("/hopefully/this/.file/does-not-exists");
|
||||
g_file_query_default_handler_async (invalid_file, G_PRIORITY_DEFAULT,
|
||||
NULL, on_query_default,
|
||||
&data);
|
||||
g_main_loop_run (data.loop);
|
||||
g_assert_null (data.info);
|
||||
g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
|
||||
g_clear_error (&data.error);
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
g_file_query_default_handler_async (text_file, G_PRIORITY_DEFAULT,
|
||||
cancellable, on_query_default,
|
||||
&data);
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_main_loop_run (data.loop);
|
||||
g_assert_null (data.info);
|
||||
g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||
g_clear_error (&data.error);
|
||||
|
||||
binary_file = g_file_new_tmp ("query-default-handler-bin-XXXXXX", &iostream, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
output_stream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
|
||||
g_output_stream_write_all (output_stream, binary_buffer,
|
||||
G_N_ELEMENTS (binary_buffer),
|
||||
NULL, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_output_stream_close (output_stream, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_clear_object (&iostream);
|
||||
|
||||
g_file_query_default_handler_async (binary_file, G_PRIORITY_DEFAULT,
|
||||
NULL, on_query_default,
|
||||
&data);
|
||||
g_main_loop_run (data.loop);
|
||||
g_assert_null (data.info);
|
||||
g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_clear_error (&data.error);
|
||||
|
||||
g_app_info_remove_supports_type (info, "text/plain", &error);
|
||||
g_assert_no_error (error);
|
||||
g_app_info_reset_type_associations ("text/plain");
|
||||
|
||||
g_main_loop_unref (data.loop);
|
||||
g_object_unref (info);
|
||||
g_object_unref (text_file);
|
||||
g_object_unref (binary_file);
|
||||
g_object_unref (invalid_file);
|
||||
}
|
||||
|
||||
static void
|
||||
test_query_default_handler_uri_async (void)
|
||||
{
|
||||
QueryDefaultHandlerData data = {0};
|
||||
GCancellable *cancellable;
|
||||
GAppInfo *info;
|
||||
GFile *file;
|
||||
GFile *invalid_file;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
g_test_skip ("Default URI handlers are not currently supported on Windows");
|
||||
return;
|
||||
#endif
|
||||
|
||||
info = create_command_line_app_info ("Gio File Handler", "true",
|
||||
"x-scheme-handler/gio-file");
|
||||
g_assert_true (G_IS_APP_INFO (info));
|
||||
|
||||
data.loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
file = g_file_new_for_uri ("gio-file://hello-gio!");
|
||||
g_file_query_default_handler_async (file, G_PRIORITY_DEFAULT,
|
||||
NULL, on_query_default,
|
||||
&data);
|
||||
g_main_loop_run (data.loop);
|
||||
g_assert_no_error (data.error);
|
||||
g_assert_true (g_app_info_equal (data.info, info));
|
||||
g_clear_object (&data.info);
|
||||
|
||||
invalid_file = g_file_new_for_uri ("gio-file-INVALID://goodbye-gio!");
|
||||
g_file_query_default_handler_async (invalid_file, G_PRIORITY_DEFAULT,
|
||||
NULL, on_query_default,
|
||||
&data);
|
||||
g_main_loop_run (data.loop);
|
||||
g_assert_null (data.info);
|
||||
g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
|
||||
g_clear_error (&data.error);
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
g_file_query_default_handler_async (file, G_PRIORITY_DEFAULT,
|
||||
cancellable, on_query_default,
|
||||
&data);
|
||||
g_cancellable_cancel (cancellable);
|
||||
g_main_loop_run (data.loop);
|
||||
g_assert_null (data.info);
|
||||
g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||
g_clear_error (&data.error);
|
||||
|
||||
g_app_info_remove_supports_type (info, "x-scheme-handler/gio-file", &data.error);
|
||||
g_assert_no_error (data.error);
|
||||
g_app_info_reset_type_associations ("x-scheme-handler/gio-file");
|
||||
|
||||
g_main_loop_unref (data.loop);
|
||||
g_object_unref (info);
|
||||
g_object_unref (file);
|
||||
g_object_unref (invalid_file);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -3150,7 +3790,10 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/file/replace-symlink/using-etag", test_replace_symlink_using_etag);
|
||||
g_test_add_data_func ("/file/replace/write-only", GUINT_TO_POINTER (FALSE), test_replace);
|
||||
g_test_add_data_func ("/file/replace/read-write", GUINT_TO_POINTER (TRUE), test_replace);
|
||||
g_test_add_func ("/file/async-new-tmp", test_async_new_tmp);
|
||||
g_test_add_func ("/file/async-new-tmp-dir", test_async_new_tmp_dir);
|
||||
g_test_add_func ("/file/async-delete", test_async_delete);
|
||||
g_test_add_func ("/file/async-make-symlink", test_async_make_symlink);
|
||||
g_test_add_func ("/file/copy-preserve-mode", test_copy_preserve_mode);
|
||||
g_test_add_func ("/file/measure", test_measure);
|
||||
g_test_add_func ("/file/measure-async", test_measure_async);
|
||||
@ -3169,6 +3812,10 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/file/writev/async_all-cancellation", test_writev_async_all_cancellation);
|
||||
g_test_add_func ("/file/build-attribute-list-for-copy", test_build_attribute_list_for_copy);
|
||||
g_test_add_func ("/file/move_async", test_move_async);
|
||||
g_test_add_func ("/file/query-default-handler-file", test_query_default_handler_file);
|
||||
g_test_add_func ("/file/query-default-handler-file-async", test_query_default_handler_file_async);
|
||||
g_test_add_func ("/file/query-default-handler-uri", test_query_default_handler_uri);
|
||||
g_test_add_func ("/file/query-default-handler-uri-async", test_query_default_handler_uri_async);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ gio_tests = {
|
||||
},
|
||||
'data-input-stream' : {},
|
||||
'data-output-stream' : {},
|
||||
'error': {},
|
||||
'fileattributematcher' : {},
|
||||
'filter-streams' : {},
|
||||
'giomodule' : {
|
||||
|
Loading…
Reference in New Issue
Block a user