summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-10-29 10:32:52 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-10-29 10:32:52 +0900
commit88bd743b4dd50e84d9c2970ff30393474af3f7bf (patch)
treea218eddccce99e5e0c70ff29a17a461d7b6e9fe2 /gio
parentdede7e78ca86551aa696e2b3c7bf14f242c103d8 (diff)
downloadglib-88bd743b4dd50e84d9c2970ff30393474af3f7bf.tar.gz
glib-88bd743b4dd50e84d9c2970ff30393474af3f7bf.tar.bz2
glib-88bd743b4dd50e84d9c2970ff30393474af3f7bf.zip
Imported Upstream version 2.67.5upstream/2.67.5
Diffstat (limited to 'gio')
-rw-r--r--gio/gbufferedinputstream.c10
-rw-r--r--gio/gfile.c10
-rw-r--r--gio/gfileinfo.c6
-rw-r--r--gio/gkeyfilesettingsbackend.c48
-rw-r--r--gio/gsubprocesslauncher-private.h4
-rw-r--r--gio/gsubprocesslauncher.c16
-rw-r--r--gio/tests/gsubprocess.c27
-rw-r--r--gio/tests/pollable.c16
8 files changed, 98 insertions, 39 deletions
diff --git a/gio/gbufferedinputstream.c b/gio/gbufferedinputstream.c
index 14495c4a0..d9f150d33 100644
--- a/gio/gbufferedinputstream.c
+++ b/gio/gbufferedinputstream.c
@@ -1104,8 +1104,8 @@ g_buffered_input_stream_real_fill_finish (GBufferedInputStream *stream,
typedef struct
{
- gssize bytes_skipped;
- gssize count;
+ gsize bytes_skipped;
+ gsize count;
} SkipAsyncData;
static void
@@ -1186,6 +1186,7 @@ skip_fill_buffer_callback (GObject *source_object,
priv->pos += data->count;
}
+ g_assert (data->bytes_skipped <= G_MAXSSIZE);
g_task_return_int (task, data->bytes_skipped);
}
@@ -1243,9 +1244,12 @@ g_buffered_input_stream_skip_async (GInputStream *stream,
if (count > priv->len)
{
/* Large request, shortcut buffer */
-
base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
+ /* If 'count > G_MAXSSIZE then 'g_input_stream_skip_async()'
+ * will return an error anyway before calling this.
+ * Assert that this is never called for too big `count` for clarity. */
+ g_assert ((gssize) count >= 0);
g_input_stream_skip_async (base_stream,
count,
io_priority, cancellable,
diff --git a/gio/gfile.c b/gio/gfile.c
index 1f2a3e850..d7feca6b9 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -7057,7 +7057,7 @@ g_file_query_default_handler_finish (GFile *file,
* @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
* @length: (out) (optional): a location to place the length of the contents of the file,
* or %NULL if the length is not needed
- * @etag_out: (out) (optional): a location to place the current entity tag for the file,
+ * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
* or %NULL if the entity tag is not needed
* @error: a #GError, or %NULL
*
@@ -7345,7 +7345,7 @@ g_file_load_partial_contents_async (GFile *file,
* @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
* @length: (out) (optional): a location to place the length of the contents of the file,
* or %NULL if the length is not needed
- * @etag_out: (out) (optional): a location to place the current entity tag for the file,
+ * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
* or %NULL if the entity tag is not needed
* @error: a #GError, or %NULL
*
@@ -7443,7 +7443,7 @@ g_file_load_contents_async (GFile *file,
* @contents: (out) (transfer full) (element-type guint8) (array length=length): a location to place the contents of the file
* @length: (out) (optional): a location to place the length of the contents of the file,
* or %NULL if the length is not needed
- * @etag_out: (out) (optional): a location to place the current entity tag for the file,
+ * @etag_out: (out) (optional) (nullable): a location to place the current entity tag for the file,
* or %NULL if the entity tag is not needed
* @error: a #GError, or %NULL
*
@@ -7481,7 +7481,7 @@ g_file_load_contents_finish (GFile *file,
* or %NULL
* @make_backup: %TRUE if a backup should be created
* @flags: a set of #GFileCreateFlags
- * @new_etag: (out) (optional): a location to a new [entity tag][gfile-etag]
+ * @new_etag: (out) (optional) (nullable): a location to a new [entity tag][gfile-etag]
* for the document. This should be freed with g_free() when no longer
* needed, or %NULL
* @cancellable: optional #GCancellable object, %NULL to ignore
@@ -7789,7 +7789,7 @@ g_file_replace_contents_bytes_async (GFile *file,
* g_file_replace_contents_finish:
* @file: input #GFile
* @res: a #GAsyncResult
- * @new_etag: (out) (optional): a location of a new [entity tag][gfile-etag]
+ * @new_etag: (out) (optional) (nullable): a location of a new [entity tag][gfile-etag]
* for the document. This should be freed with g_free() when it is no
* longer needed, or %NULL
* @error: a #GError, or %NULL
diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c
index 42cdc7a5d..2a97758b2 100644
--- a/gio/gfileinfo.c
+++ b/gio/gfileinfo.c
@@ -1733,9 +1733,11 @@ g_file_info_get_content_type (GFileInfo *info)
* g_file_info_get_size:
* @info: a #GFileInfo.
*
- * Gets the file's size.
+ * Gets the file's size (in bytes). The size is retrieved through the value of
+ * the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute and is converted
+ * from #guint64 to #goffset before returning the result.
*
- * Returns: a #goffset containing the file's size.
+ * Returns: a #goffset containing the file's size (in bytes).
**/
goffset
g_file_info_get_size (GFileInfo *info)
diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
index 485a25a14..094be3f91 100644
--- a/gio/gkeyfilesettingsbackend.c
+++ b/gio/gkeyfilesettingsbackend.c
@@ -605,19 +605,24 @@ g_keyfile_settings_backend_finalize (GObject *object)
g_hash_table_unref (kfsb->system_locks);
g_free (kfsb->defaults_dir);
- g_file_monitor_cancel (kfsb->file_monitor);
- g_object_unref (kfsb->file_monitor);
+ if (kfsb->file_monitor)
+ {
+ g_file_monitor_cancel (kfsb->file_monitor);
+ g_object_unref (kfsb->file_monitor);
+ }
g_object_unref (kfsb->file);
- g_file_monitor_cancel (kfsb->dir_monitor);
- g_object_unref (kfsb->dir_monitor);
+ if (kfsb->dir_monitor)
+ {
+ g_file_monitor_cancel (kfsb->dir_monitor);
+ g_object_unref (kfsb->dir_monitor);
+ }
g_object_unref (kfsb->dir);
g_free (kfsb->root_group);
g_free (kfsb->prefix);
- G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)
- ->finalize (object);
+ G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)->finalize (object);
}
static void
@@ -724,6 +729,7 @@ static void
g_keyfile_settings_backend_constructed (GObject *object)
{
GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object);
+ GError *error = NULL;
const char *path;
if (kfsb->file == NULL)
@@ -749,15 +755,31 @@ g_keyfile_settings_backend_constructed (GObject *object)
if (g_mkdir_with_parents (path, 0700) == -1)
g_warning ("Failed to create %s: %s", path, g_strerror (errno));
- kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, NULL);
- kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, NULL);
+ kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, &error);
+ if (!kfsb->file_monitor)
+ {
+ g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ g_signal_connect (kfsb->file_monitor, "changed",
+ G_CALLBACK (file_changed), kfsb);
+ }
- compute_checksum (kfsb->digest, NULL, 0);
+ kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, &error);
+ if (!kfsb->dir_monitor)
+ {
+ g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ g_signal_connect (kfsb->dir_monitor, "changed",
+ G_CALLBACK (dir_changed), kfsb);
+ }
- g_signal_connect (kfsb->file_monitor, "changed",
- G_CALLBACK (file_changed), kfsb);
- g_signal_connect (kfsb->dir_monitor, "changed",
- G_CALLBACK (dir_changed), kfsb);
+ compute_checksum (kfsb->digest, NULL, 0);
g_keyfile_settings_backend_keyfile_writable (kfsb);
g_keyfile_settings_backend_keyfile_reload (kfsb);
diff --git a/gio/gsubprocesslauncher-private.h b/gio/gsubprocesslauncher-private.h
index f8a6516c5..d6fe0d784 100644
--- a/gio/gsubprocesslauncher-private.h
+++ b/gio/gsubprocesslauncher-private.h
@@ -42,8 +42,8 @@ struct _GSubprocessLauncher
gint stderr_fd;
gchar *stderr_path;
- GArray *source_fds;
- GArray *target_fds; /* always the same length as source_fds */
+ GArray *source_fds; /* GSubprocessLauncher has ownership of the FD elements */
+ GArray *target_fds; /* always the same length as source_fds; elements are just integers and not FDs in this process */
gboolean closed_fd;
GSpawnChildSetupFunc child_setup_func;
diff --git a/gio/gsubprocesslauncher.c b/gio/gsubprocesslauncher.c
index b7257f453..a1c65e947 100644
--- a/gio/gsubprocesslauncher.c
+++ b/gio/gsubprocesslauncher.c
@@ -596,16 +596,16 @@ g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher *self,
* @target_fd: Target descriptor for child process
*
* Transfer an arbitrary file descriptor from parent process to the
- * child. This function takes "ownership" of the fd; it will be closed
+ * child. This function takes ownership of the @source_fd; it will be closed
* in the parent when @self is freed.
*
* By default, all file descriptors from the parent will be closed.
- * This function allows you to create (for example) a custom pipe() or
- * socketpair() before launching the process, and choose the target
+ * This function allows you to create (for example) a custom `pipe()` or
+ * `socketpair()` before launching the process, and choose the target
* descriptor in the child.
*
* An example use case is GNUPG, which has a command line argument
- * --passphrase-fd providing a file descriptor number where it expects
+ * `--passphrase-fd` providing a file descriptor number where it expects
* the passphrase to be written.
*/
void
@@ -661,11 +661,11 @@ g_subprocess_launcher_close (GSubprocessLauncher *self)
g_assert (self->target_fds != NULL);
g_assert (self->source_fds->len == self->target_fds->len);
+ /* Note: Don’t close the target_fds, as they’re only valid FDs in the
+ * child process. This code never executes in the child process. */
for (i = 0; i < self->source_fds->len; i++)
- {
- (void) close (g_array_index (self->source_fds, int, i));
- (void) close (g_array_index (self->target_fds, int, i));
- }
+ (void) close (g_array_index (self->source_fds, int, i));
+
g_clear_pointer (&self->source_fds, g_array_unref);
g_clear_pointer (&self->target_fds, g_array_unref);
}
diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c
index 3c248e610..7e22678ec 100644
--- a/gio/tests/gsubprocess.c
+++ b/gio/tests/gsubprocess.c
@@ -1494,23 +1494,44 @@ test_subprocess_launcher_close (void)
GSubprocessLauncher *launcher;
GSubprocess *proc;
GPtrArray *args;
- int fd;
+ int fd, fd2;
gboolean is_open;
- fd = dup(0);
+ /* Open two arbitrary FDs. One of them, @fd, will be transferred to the
+ * launcher, and the other’s FD integer will be used as its target FD, giving
+ * the mapping `fd → fd2` if a child process were to be spawned.
+ *
+ * The launcher will then be closed, which should close @fd but *not* @fd2,
+ * as the value of @fd2 is only valid as an FD in a child process. (A child
+ * process is not actually spawned in this test.)
+ */
+ fd = dup (0);
+ fd2 = dup (0);
launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
- g_subprocess_launcher_take_fd (launcher, fd, fd);
+ g_subprocess_launcher_take_fd (launcher, fd, fd2);
+
is_open = fcntl (fd, F_GETFD) != -1;
g_assert_true (is_open);
+ is_open = fcntl (fd2, F_GETFD) != -1;
+ g_assert_true (is_open);
+
g_subprocess_launcher_close (launcher);
+
is_open = fcntl (fd, F_GETFD) != -1;
g_assert_false (is_open);
+ is_open = fcntl (fd2, F_GETFD) != -1;
+ g_assert_true (is_open);
+
+ /* Now test that actually trying to spawn the child gives %G_IO_ERROR_CLOSED,
+ * as g_subprocess_launcher_close() has been called. */
args = get_test_subprocess_args ("cat", NULL);
proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
g_ptr_array_free (args, TRUE);
g_assert_null (proc);
g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_CLOSED);
g_clear_error (error);
+
+ close (fd2);
g_object_unref (launcher);
}
diff --git a/gio/tests/pollable.c b/gio/tests/pollable.c
index 9a2a3cc8c..d57c4733a 100644
--- a/gio/tests/pollable.c
+++ b/gio/tests/pollable.c
@@ -187,25 +187,28 @@ test_pollable_unix_pty (void)
{
int (*openpty_impl) (int *, int *, char *, void *, void *);
int a, b, status;
+#ifdef __linux__
+ void *handle;
+#endif
g_test_summary ("Test that PTYs are considered pollable");
#ifdef __linux__
- dlopen ("libutil.so", RTLD_GLOBAL | RTLD_LAZY);
+ handle = dlopen ("libutil.so", RTLD_GLOBAL | RTLD_LAZY);
#endif
openpty_impl = dlsym (RTLD_DEFAULT, "openpty");
if (openpty_impl == NULL)
{
g_test_skip ("System does not support openpty()");
- return;
+ goto close_libutil;
}
status = openpty_impl (&a, &b, NULL, NULL, NULL);
if (status == -1)
{
g_test_skip ("Unable to open PTY");
- return;
+ goto close_libutil;
}
in = G_POLLABLE_INPUT_STREAM (g_unix_input_stream_new (a, TRUE));
@@ -218,6 +221,13 @@ test_pollable_unix_pty (void)
close (a);
close (b);
+
+close_libutil:
+#ifdef __linux__
+ dlclose (handle);
+#else
+ return;
+#endif
}
static void