Allocate a working buffer before calling `fork()` to avoid calling
`malloc()` in the async-signal-safe context between `fork()` and
`exec()`, where it’s not safe to use.
In this case, the buffer is used to assemble a wrapper around `argv` so
it can be run under `/bin/sh`.
See `man 7 signal-safety`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2140
Allocate a working buffer before calling `fork()` to avoid calling
`malloc()` in the async-signal-safe context between `fork()` and
`exec()`, where it’s not safe to use.
In this case, the buffer is used to assemble elements from `PATH` with
the binary from `argv[0]` to try executing them.
See `man 7 signal-safety`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #2140
Query the environment before calling `fork()` so that it doesn’t have to
be called in the async-signal-safe context between `fork()` and
`exec()`.
See `man 7 signal-safety`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #2140
They’re not safe to call in an async-signal-safe context on Linux.
`sysconf()` is safe to call on FreeBSD and OpenBSD (at least), so
continue doing that.
This will reduce performance in the (already low performance) fallback
case where `/proc` is inaccessible to a forked process on Linux, while
spawning a subprocess.
See `man 7 signal-safety`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #2140
Use the error handling infrastructure which already exists for other
failures in the async-signal-safe context.
`g_assert()` is unlikely to have caused problems in practice because it
is only async-signal-unsafe when the assertion condition fails.
See `man 7 signal-safety`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #2140
While `g_ascii_isdigit()` *is* currently async-signal-safe, it’s going
to be hard to remember to keep it that way if the implementation changes
in future.
It seems more robust to just reimplement it here, given that it’s not
much code.
See `man 7 signal-safety`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #2140
Use normal `close()` instead, which is guaranteed to be
async-signal-safe.
See `man 7 signal-safety`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #2140
Functions called between `fork()` and `exec()` have to be
async-signal-safe.
Add a comment to each function which is called in that context, and
`FIXME` comments to the non-async-signal-safe functions which end up
being called as leaves of the call graph.
The following commits will fix those `FIXME`s.
See `man 7 signal-safety`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #2140
The G_VALUE_NOCOPY_CONTENTS for strings can only be used when collecting them
and not when copying them.
Instead only avoid copies for strings that are interned.
Fixes#2141
Suppress the one-time quark hash table initialisation regardless of
where `g_quark_init()` was called from.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2132
There are two variables which are used to pass state from the Unix
signal handler interrupt function to the rest of `gmain.c`. They are
currently defined as `sig_atomic_t`, which means that they are
guaranteed to be interrupt safe. However, it does not guarantee they are
thread-safe, and GLib attaches its signal handler interrupt function to
a worker thread.
Make them thread-safe using atomics. It’s not possible to use locks, as
pthread mutex functions are not signal-handler-safe. In particular, this
means we have to be careful not to end up using GLib’s fallback atomics
implementation, as that secretly uses a mutex. Better to be unsafe than
have a re-entrant call into `pthread_mutex_lock()` from a nested signal
handler.
This commit solves two problems:
1. Writes to `any_unix_signal_pending` and `unix_signal_pending` could
be delivered out of order to the worker thread which calls
`dispatch_unix_signals()`, resulting in signals not being handled
until the next iteration of that worker thread. This is a
performance problem but not a correctness problem.
2. Setting an element of `unix_signal_pending` from
`g_unix_signal_handler()` and clearing it from
`dispatch_unix_signals_unlocked()` (in the worker thread) could
race, resulting in a signal emission being cleared without being
handled. That’s a correctness problem.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1670
The G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE is set to TRUE only for NFS
filesystem types currently. Let's add also SMB filesystem types. This
also changes g_local_file_is_nfs_home function logic to handle only
NFS filesystems.
The g_local_file_is_remote function is misleading as it works only for
NFS filesystem types and only for locations in home directorly. Let's
rename it to g_local_file_is_nfs_home to make it obvious.
statfs/statvfs is called several times when querying filesystem info.
This is because the G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE attribute is set
over is_remote_fs function, which calls statfs/statvfs again. Let's use
the already known fstype instead of redundant statfs/statvfs calls.
This also changes g_local_file_is_remote implementation to use
g_local_file_query_filesystem_info to obtain fstype, which allows to
remove duplicated code from is_remote_fs function.
The G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE currently works only for locations
in the home directory. Let's make it work also for files outside the home
directory.
There are glocalfile.h and glocalfileprivate.h header files currently.
None of those header files is public, so it doesn't make sense to have
two private headers for glocalfile.c. Let's remove glocalfileprivate.h.
Suppress the cached charset from `g_get_charset()`, and widen the
suppression of the global random number `GRand` instance, since it can
be used outside test cases.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2134
We need to include the isnan*.c sources as necessary, if any of the
isnan*() functions cannot be found, so that builds on compilers that
lack these functions could be fixed.
Also, if we do have the isnan*() functions, improve the build by not
unnecessarily including the isnan*.c sources in the build.
If the isnan*() functions are found, make sure that the
HAVE_ISNAN*_IN_LIBC macros are defined in the CFLags, so that we do not
accidently require the gnulib implementations for these functions.
The implementation didn’t match the documentation. The implementation
has the right behaviour (wrt not allowing embedded nuls, validating
UTF-8, and returning a default value if an invalid string is detected),
so keep that and fix the documentation to match.
The [`GVariant`
specification](https://people.gnome.org/~desrt/gvariant-serialisation.pdf)
is incorrect on this point, and the implementation of GLib was
purposefully changed after the specification was published (but before
`GVariant` became API-stable in GLib). The behaviour in GLib
(specifically concerning all strings being in UTF-8) is consistent with
D-Bus.
Spotted by William Manley.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This was mostly machine generated with the following command:
```
codespell \
--builtin clear,rare,usage \
--skip './po/*' --skip './.git/*' --skip './NEWS*' \
--write-changes .
```
using the latest git version of `codespell` as per [these
instructions](https://github.com/codespell-project/codespell#user-content-updating).
Then I manually checked each change using `git add -p`, made a few
manual fixups and dropped a load of incorrect changes.
There are still some outdated or loaded terms used in GLib, mostly to do
with git branch terminology. They will need to be changed later as part
of a wider migration of git terminology.
If I’ve missed anything, please file an issue!
Signed-off-by: Philip Withnall <withnall@endlessm.com>