gfile: Implement interface API to make symbolic links asynchronously

The interface was ready for this API but it was not provided.

So implement this, using a thread that calls the sync API for now.

Add tests.

Helps with: GNOME/glib#157
This commit is contained in:
Marco Trevisan (Treviño)
2022-06-01 18:07:35 +02:00
parent fe9e35624a
commit 04718a9692
4 changed files with 286 additions and 4 deletions

View File

@@ -269,6 +269,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 +408,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 +4165,123 @@ 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));
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