diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-10-29 10:32:52 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-10-29 10:32:52 +0900 |
commit | 88bd743b4dd50e84d9c2970ff30393474af3f7bf (patch) | |
tree | a218eddccce99e5e0c70ff29a17a461d7b6e9fe2 /gio | |
parent | dede7e78ca86551aa696e2b3c7bf14f242c103d8 (diff) | |
download | glib-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.c | 10 | ||||
-rw-r--r-- | gio/gfile.c | 10 | ||||
-rw-r--r-- | gio/gfileinfo.c | 6 | ||||
-rw-r--r-- | gio/gkeyfilesettingsbackend.c | 48 | ||||
-rw-r--r-- | gio/gsubprocesslauncher-private.h | 4 | ||||
-rw-r--r-- | gio/gsubprocesslauncher.c | 16 | ||||
-rw-r--r-- | gio/tests/gsubprocess.c | 27 | ||||
-rw-r--r-- | gio/tests/pollable.c | 16 |
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 |