Compare commits
22 Commits
415f8a5bfe
...
2a407487b2
Author | SHA1 | Date |
---|---|---|
Lennart Poettering | 2a407487b2 | |
Zbigniew Jędrzejewski-Szmek | 094c6fc338 | |
Zbigniew Jędrzejewski-Szmek | bc2ed3bbf0 | |
Lennart Poettering | 60bcb45927 | |
Lennart Poettering | 2a03b9ed21 | |
Lennart Poettering | ad0b610b0c | |
Lennart Poettering | 0c94a31464 | |
Frantisek Sumsal | 05827831a6 | |
Frantisek Sumsal | 8d16f29b23 | |
Frantisek Sumsal | 890ea05ac2 | |
Frantisek Sumsal | 60d7a2029a | |
Frantisek Sumsal | 973bc32ab6 | |
Frantisek Sumsal | 69e3234db7 | |
Lennart Poettering | 22f401b269 | |
Lennart Poettering | 47ab8f73e3 | |
Lennart Poettering | 0377cd2936 | |
Lennart Poettering | df8b14b591 | |
Lennart Poettering | 55f99c26c6 | |
Lennart Poettering | de008e537d | |
Lennart Poettering | 6fe3196350 | |
Lennart Poettering | a7f49f0b7c | |
Lennart Poettering | 31d74c66e2 |
6
NEWS
6
NEWS
|
@ -90,7 +90,7 @@ CHANGES WITH 247 in spe:
|
|||
latter it takes precedence over the former, similar to how most of
|
||||
systemd's own configuration is handled. Given that PAM stack
|
||||
definitions are primarily put together by OS vendors/distributions
|
||||
(though possibly overriden by users), this systemd release moves its
|
||||
(though possibly overridden by users), this systemd release moves its
|
||||
own PAM stack configuration for the "systemd-user" PAM service (i.e.
|
||||
for the PAM session invoked by the per-user user@.service instance)
|
||||
from /etc/pam.d/ to /usr/lib/pam.d/. We recommend moving all
|
||||
|
@ -98,7 +98,7 @@ CHANGES WITH 247 in spe:
|
|||
/etc/pam.d/ to /usr/lib/pam.d/, but if such OS-wide migration is not
|
||||
desired the location to which systemd installs its PAM stack
|
||||
configuration file may be changed via the "pamconfdir" meson variable
|
||||
at build time, optionally undoing ths change of default paths
|
||||
at build time, optionally undoing this change of default paths
|
||||
introduced with systemd 247.
|
||||
|
||||
CHANGES WITH 246:
|
||||
|
@ -260,7 +260,7 @@ CHANGES WITH 246:
|
|||
generation for collection with systemd-pstore.
|
||||
|
||||
* We provide a set of udev rules to enable auto-suspend on PCI and USB
|
||||
devices that were tested to currectly support it. Previously, this
|
||||
devices that were tested to correctly support it. Previously, this
|
||||
was distributed as a set of udev rules, but has now been replaced by
|
||||
by a set of hwdb entries (and a much shorter udev rule to take action
|
||||
if the device modalias matches one of the new hwdb entries).
|
||||
|
|
|
@ -301,7 +301,7 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
|
|||
</term>
|
||||
<listitem><para>Reconfigure network interfaces. Takes interface name or index number. Note that
|
||||
this does not reload <filename>.netdev</filename> or <filename>.network</filename>
|
||||
corresponding to the the specifed interface. So, if you edit config files, it is necessary to
|
||||
corresponding to the the specified interface. So, if you edit config files, it is necessary to
|
||||
call <command>networkctl reload</command> first to apply new settings.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@
|
|||
specifies the initial size of the loopback file to create.</para>
|
||||
|
||||
<para>The <option>--size=auto</option> option takes the sizes of pre-existing partitions into
|
||||
account. However, it does not accomodate for partition tables that are not tightly packed: the
|
||||
account. However, it does not accommodate for partition tables that are not tightly packed: the
|
||||
configured partitions might still not fit into the backing device if empty space exists between
|
||||
pre-existing partitions (or before the first partition) that cannot be fully filled by partitions to
|
||||
grow or create.</para>
|
||||
|
|
|
@ -863,12 +863,17 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
|||
|
||||
<listitem><para>Controls the file mode creation mask. Takes an access mode in octal notation. See
|
||||
<citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||
details. Defaults to 0022 for system units. For units of the user service manager the default value
|
||||
is inherited from the user instance (whose default is inherited from the system service manager, and
|
||||
thus also is 0022). Hence changing the default value of a user instance, either via
|
||||
<varname>UMask=</varname> or via a PAM module, will affect the user instance itself and all user
|
||||
units started by the user instance unless a user unit has specified its own
|
||||
<varname>UMask=</varname>.</para></listitem>
|
||||
details. Defaults to 0022 for system units. For user units the default value is inherited from the
|
||||
per-user service manager (whose default is in turn inherited from the system service manager, and
|
||||
thus typically also is 0022 — unless overriden by a PAM module). In order to change the per-user mask
|
||||
for all user services, consider setting the <varname>UMask=</varname> setting of the user's
|
||||
<filename>user@.service</filename> system service instance. The per-user umask may also be set via
|
||||
the <varname>umask</varname> field of a user's <ulink url="https://systemd.io/USER_RECORD">JSON User
|
||||
Record</ulink> (for users managed by
|
||||
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
this field may be controlled via <command>homectl --umask=</command>). It may also be set via a PAM
|
||||
module, such as <citerefentry
|
||||
project='man-pages'><refentrytitle>pam_umask</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
|
|
@ -200,13 +200,13 @@
|
|||
</para>
|
||||
|
||||
<para>If the address string is a string in the format
|
||||
<literal><replaceable>v.w.x.y</replaceable>:<replaceable>z</replaceable></literal>, it is interpeted
|
||||
<literal><replaceable>v.w.x.y</replaceable>:<replaceable>z</replaceable></literal>, it is interpreted
|
||||
as IPv4 address <replaceable>v.w.x.y</replaceable> and port <replaceable>z</replaceable>.</para>
|
||||
|
||||
<para>If the address string is a string in the format
|
||||
<literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable></literal>, it is interpreted as
|
||||
IPv6 address <replaceable>x</replaceable> and port <replaceable>y</replaceable>. An optional
|
||||
interface scope (interface name or number) may be specifed after a <literal>%</literal> symbol:
|
||||
interface scope (interface name or number) may be specified after a <literal>%</literal> symbol:
|
||||
<literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable>%<replaceable>dev</replaceable></literal>.
|
||||
Interface scopes are only useful with link-local addresses, because the kernel ignores them in other
|
||||
cases. Note that if an address is specified as IPv6, it might still make the service available via
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
<varlistentry id='tclass-classid'>
|
||||
<term><varname>ClassId=</varname></term>
|
||||
<listitem>
|
||||
<para>Configues the unique identifier of the class. It is specified as the major and minor numbers in
|
||||
<para>Configures the unique identifier of the class. It is specified as the major and minor numbers in
|
||||
hexadecimal in the range 0x1–Oxffff separated with a colon (<literal>major:minor</literal>).
|
||||
Defaults to unset.</para>
|
||||
</listitem>
|
||||
|
|
|
@ -432,7 +432,7 @@ static int hardlink_context_setup(
|
|||
* bottleneck we can certainly place an in-memory hash table in front of this, but for the beginning,
|
||||
* let's keep things simple, and just use the disk as lookup table for inodes.
|
||||
*
|
||||
* Note that this should have zero performace impact as long as .n_link of all files copied remains
|
||||
* Note that this should have zero performance impact as long as .n_link of all files copied remains
|
||||
* <= 0, because in that case we will not actually allocate the hardlink inode lookup table directory
|
||||
* on disk (we do so lazily, when the first candidate with .n_link > 1 is seen). This means, in the
|
||||
* common case where hardlinks are not used at all or only for few files the fact that we store the
|
||||
|
|
|
@ -209,17 +209,21 @@ static int parse_env_file_internal(
|
|||
case DOUBLE_QUOTE_VALUE_ESCAPE:
|
||||
state = DOUBLE_QUOTE_VALUE;
|
||||
|
||||
if (c == '"') {
|
||||
if (strchr(SHELL_NEED_ESCAPE, c)) {
|
||||
/* If this is a char that needs escaping, just unescape it. */
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
value[n_value++] = '"';
|
||||
} else if (!strchr(NEWLINE, c)) {
|
||||
value[n_value++] = c;
|
||||
} else if (c != '\n') {
|
||||
/* If other char than what needs escaping, keep the "\" in place, like the
|
||||
* real shell does. */
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+3))
|
||||
return -ENOMEM;
|
||||
value[n_value++] = '\\';
|
||||
value[n_value++] = c;
|
||||
}
|
||||
|
||||
/* Escaped newlines (aka "continuation lines") are eaten up entirely */
|
||||
break;
|
||||
|
||||
case COMMENT:
|
||||
|
|
|
@ -153,10 +153,8 @@ int pipe_eof(int fd) {
|
|||
int r;
|
||||
|
||||
r = fd_wait_for_event(fd, POLLIN, 0);
|
||||
if (r < 0)
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
return !!(r & POLLHUP);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* when other criteria (cpu weight, nice level) are identical.
|
||||
* In this case service units have the highest priority. */
|
||||
typedef enum UnitType {
|
||||
UNIT_SERVICE = 0,
|
||||
UNIT_SERVICE,
|
||||
UNIT_MOUNT,
|
||||
UNIT_SWAP,
|
||||
UNIT_SOCKET,
|
||||
|
@ -25,7 +25,7 @@ typedef enum UnitType {
|
|||
} UnitType;
|
||||
|
||||
typedef enum UnitLoadState {
|
||||
UNIT_STUB = 0,
|
||||
UNIT_STUB,
|
||||
UNIT_LOADED,
|
||||
UNIT_NOT_FOUND, /* error condition #1: unit file not found */
|
||||
UNIT_BAD_SETTING, /* error condition #2: we couldn't parse some essential unit file setting */
|
||||
|
|
|
@ -1454,7 +1454,9 @@ static int install_random_seed(const char *esp) {
|
|||
}
|
||||
|
||||
r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderSystemToken", NULL, NULL, &token_size);
|
||||
if (r < 0) {
|
||||
if (r == -ENODATA)
|
||||
log_debug_errno(r, "LoaderSystemToken EFI variable is invalid (too short?), replacing.");
|
||||
else if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
return log_error_errno(r, "Failed to test system token validity: %m");
|
||||
} else {
|
||||
|
|
|
@ -507,8 +507,8 @@ static void automount_trigger_notify(Unit *u, Unit *other) {
|
|||
assert(other);
|
||||
|
||||
/* Filter out invocations with bogus state */
|
||||
if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT)
|
||||
return;
|
||||
assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
|
||||
assert(other->type == UNIT_MOUNT);
|
||||
|
||||
/* Don't propagate state changes from the mount if we are already down */
|
||||
if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING))
|
||||
|
|
|
@ -2484,7 +2484,7 @@ static int acquire_credentials(
|
|||
if (dfd < 0)
|
||||
return -errno;
|
||||
|
||||
/* First we use the literally specified credentials. Note that they might be overriden again below,
|
||||
/* First we use the literally specified credentials. Note that they might be overridden again below,
|
||||
* and thus act as a "default" if the same credential is specified multiple times */
|
||||
HASHMAP_FOREACH(sc, context->set_credentials) {
|
||||
size_t add;
|
||||
|
@ -4340,7 +4340,7 @@ static int exec_child(
|
|||
* we'll try not to call PR_SET_SECUREBITS unless necessary. Setting securebits requires
|
||||
* CAP_SETPCAP. */
|
||||
if (prctl(PR_GET_SECUREBITS) != secure_bits) {
|
||||
/* CAP_SETPCAP is required to set securebits. This capabilitiy is raised into the
|
||||
/* CAP_SETPCAP is required to set securebits. This capability is raised into the
|
||||
* effective set here.
|
||||
* The effective set is overwritten during execve with the following values:
|
||||
* - ambient set (for non-root processes)
|
||||
|
|
|
@ -542,7 +542,7 @@ int mount_setup(bool loaded_policy, bool leave_propagation) {
|
|||
|
||||
/* Also create /run/systemd/inaccessible nodes, so that we always have something to mount
|
||||
* inaccessible nodes from. If we run in a container the host might have created these for us already
|
||||
* in /run/host/inaccessible/. Use those if we can, since tht way we likely get access to block/char
|
||||
* in /run/host/inaccessible/. Use those if we can, since that way we likely get access to block/char
|
||||
* device nodes that are inaccessible, and if userns is used to nodes that are on mounts owned by a
|
||||
* userns outside the container and thus nicely read-only and not remountable. */
|
||||
if (access("/run/host/inaccessible/", F_OK) < 0) {
|
||||
|
|
|
@ -748,10 +748,23 @@ static void path_trigger_notify(Unit *u, Unit *other) {
|
|||
assert(u);
|
||||
assert(other);
|
||||
|
||||
/* Invoked whenever the unit we trigger changes state or gains
|
||||
* or loses a job */
|
||||
/* Invoked whenever the unit we trigger changes state or gains or loses a job */
|
||||
|
||||
if (other->load_state != UNIT_LOADED)
|
||||
/* Filter out invocations with bogus state */
|
||||
assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
|
||||
|
||||
/* Don't propagate state changes from the triggered unit if we are already down */
|
||||
if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
|
||||
return;
|
||||
|
||||
/* Propagate start limit hit state */
|
||||
if (other->start_limit_hit) {
|
||||
path_enter_dead(p, PATH_FAILURE_UNIT_START_LIMIT_HIT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't propagate anything if there's still a job queued */
|
||||
if (other->job)
|
||||
return;
|
||||
|
||||
if (p->state == PATH_RUNNING &&
|
||||
|
@ -790,6 +803,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = {
|
|||
[PATH_SUCCESS] = "success",
|
||||
[PATH_FAILURE_RESOURCES] = "resources",
|
||||
[PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
|
||||
[PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult);
|
||||
|
|
|
@ -45,6 +45,7 @@ typedef enum PathResult {
|
|||
PATH_SUCCESS,
|
||||
PATH_FAILURE_RESOURCES,
|
||||
PATH_FAILURE_START_LIMIT_HIT,
|
||||
PATH_FAILURE_UNIT_START_LIMIT_HIT,
|
||||
_PATH_RESULT_MAX,
|
||||
_PATH_RESULT_INVALID = -1
|
||||
} PathResult;
|
||||
|
|
|
@ -589,9 +589,6 @@ static int service_verify(Service *s) {
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (s->bus_name && s->type != SERVICE_DBUS)
|
||||
log_unit_warning(UNIT(s), "Service has a D-Bus service name specified, but is not of type dbus. Ignoring.");
|
||||
|
||||
if (s->exec_context.pam_name && !IN_SET(s->kill_context.kill_mode, KILL_CONTROL_GROUP, KILL_MIXED)) {
|
||||
log_unit_error(UNIT(s), "Service has PAM enabled. Kill mode must be set to 'control-group' or 'mixed'. Refusing.");
|
||||
return -ENOEXEC;
|
||||
|
@ -687,7 +684,7 @@ static int service_setup_bus_name(Service *s) {
|
|||
|
||||
assert(s);
|
||||
|
||||
if (!s->bus_name)
|
||||
if (s->type != SERVICE_DBUS)
|
||||
return 0;
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, true, UNIT_DEPENDENCY_FILE);
|
||||
|
@ -2313,7 +2310,7 @@ static void service_enter_restart(Service *s) {
|
|||
return;
|
||||
|
||||
fail:
|
||||
log_unit_warning(UNIT(s), "Failed to schedule restart job: %s", bus_error_message(&error, -r));
|
||||
log_unit_warning(UNIT(s), "Failed to schedule restart job: %s", bus_error_message(&error, r));
|
||||
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false);
|
||||
}
|
||||
|
||||
|
@ -2329,7 +2326,7 @@ static void service_enter_reload_by_notify(Service *s) {
|
|||
/* service_enter_reload_by_notify is never called during a reload, thus no loops are possible. */
|
||||
r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error);
|
||||
if (r < 0)
|
||||
log_unit_warning(UNIT(s), "Failed to schedule propagation of reload: %s", bus_error_message(&error, -r));
|
||||
log_unit_warning(UNIT(s), "Failed to schedule propagation of reload: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
static void service_enter_reload(Service *s) {
|
||||
|
|
|
@ -3265,13 +3265,8 @@ static void socket_trigger_notify(Unit *u, Unit *other) {
|
|||
assert(other);
|
||||
|
||||
/* Filter out invocations with bogus state */
|
||||
if (!IN_SET(other->load_state,
|
||||
UNIT_LOADED,
|
||||
UNIT_NOT_FOUND,
|
||||
UNIT_BAD_SETTING,
|
||||
UNIT_ERROR,
|
||||
UNIT_MASKED) || other->type != UNIT_SERVICE)
|
||||
return;
|
||||
assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
|
||||
assert(other->type == UNIT_SERVICE);
|
||||
|
||||
/* Don't propagate state changes from the service if we are already down */
|
||||
if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING))
|
||||
|
|
|
@ -746,8 +746,8 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
|
|||
assert(u);
|
||||
assert(other);
|
||||
|
||||
if (other->load_state != UNIT_LOADED)
|
||||
return;
|
||||
/* Filter out invocations with bogus state */
|
||||
assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
|
||||
|
||||
/* Reenable all timers that depend on unit state */
|
||||
LIST_FOREACH(value, v, t->values)
|
||||
|
|
|
@ -938,7 +938,7 @@ int transaction_add_job_and_dependencies(
|
|||
|
||||
/* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set
|
||||
* temporarily. */
|
||||
if (!IN_SET(unit->load_state, UNIT_LOADED, UNIT_ERROR, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_MASKED))
|
||||
if (!UNIT_IS_LOAD_COMPLETE(unit->load_state))
|
||||
return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
|
||||
|
||||
if (type != JOB_STOP) {
|
||||
|
|
|
@ -209,11 +209,7 @@ static int unit_add_alias(Unit *u, char *donated_name) {
|
|||
|
||||
/* Make sure that u->names is allocated. We may leave u->names
|
||||
* empty if we fail later, but this is not a problem. */
|
||||
r = set_ensure_allocated(&u->aliases, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = set_put(u->aliases, donated_name);
|
||||
r = set_ensure_put(&u->aliases, &string_hash_ops, donated_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(r > 0);
|
||||
|
|
|
@ -49,6 +49,10 @@ static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
|
|||
return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED);
|
||||
}
|
||||
|
||||
static inline bool UNIT_IS_LOAD_COMPLETE(UnitLoadState t) {
|
||||
return t >= 0 && t < _UNIT_LOAD_STATE_MAX && t != UNIT_STUB && t != UNIT_MERGED;
|
||||
}
|
||||
|
||||
/* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We
|
||||
* use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be
|
||||
* created as a result of multiple "reasons", hence the bitmask. */
|
||||
|
|
|
@ -534,6 +534,7 @@ finish:
|
|||
fido_dev_info_free(&di, di_size);
|
||||
return r;
|
||||
#else
|
||||
return log_error_errno(EOPNOTSUPP, "FIDO2 tokens not supported on this build.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"FIDO2 tokens not supported on this build.");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -475,6 +475,7 @@ int find_pkcs11_token_auto(char **ret) {
|
|||
|
||||
return 0;
|
||||
#else
|
||||
return log_error_errno(EOPNOTSUPP, "PKCS#11 tokens not supported on this build.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"PKCS#11 tokens not supported on this build.");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2183,7 +2183,7 @@ int home_create_luks(
|
|||
if (disk_uuid_path)
|
||||
(void) ioctl(image_fd, BLKRRPART, 0);
|
||||
else {
|
||||
/* If we operate on a file, sync the contaning directory too. */
|
||||
/* If we operate on a file, sync the containing directory too. */
|
||||
r = fsync_directory_of_file(image_fd);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to synchronize directory of image file to disk: %m");
|
||||
|
|
|
@ -229,7 +229,7 @@ static int set_simple_string(sd_bus *bus, const char *method, const char *value)
|
|||
&error, NULL,
|
||||
"sb", value, arg_ask_password);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not set property: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not set property: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ static int change_runlevel(Server *s, int runlevel) {
|
|||
NULL,
|
||||
"ss", target, mode);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to change runlevel: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to change runlevel: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -581,10 +581,7 @@ const char *bus_error_message(const sd_bus_error *e, int error) {
|
|||
return e->message;
|
||||
}
|
||||
|
||||
if (error < 0)
|
||||
error = -error;
|
||||
|
||||
return strerror_safe(error);
|
||||
return strerror_safe(abs(error));
|
||||
}
|
||||
|
||||
static bool map_ok(const sd_bus_error_map *map) {
|
||||
|
|
|
@ -373,7 +373,7 @@ static void* client2(void *p) {
|
|||
|
||||
r = sd_bus_send(bus, m, NULL);
|
||||
if (r < 0) {
|
||||
log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
|
||||
log_error("Failed to issue method call: %s", bus_error_message(&error, r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ static void* client2(void *p) {
|
|||
|
||||
r = sd_bus_send(bus, m, NULL);
|
||||
if (r < 0) {
|
||||
log_error("Failed to issue signal: %s", bus_error_message(&error, -r));
|
||||
log_error("Failed to issue signal: %s", bus_error_message(&error, r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,7 @@ static void* client2(void *p) {
|
|||
|
||||
r = sd_bus_call(bus, m, 0, &error, &reply);
|
||||
if (r < 0) {
|
||||
log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
|
||||
log_error("Failed to issue method call: %s", bus_error_message(&error, r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -442,7 +442,7 @@ static void* client2(void *p) {
|
|||
|
||||
r = sd_bus_call(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
|
||||
if (r < 0)
|
||||
log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
|
||||
log_info("Failed to issue method call: %s", bus_error_message(&error, r));
|
||||
else
|
||||
log_info("Slow call succeed.");
|
||||
|
||||
|
@ -462,7 +462,7 @@ static void* client2(void *p) {
|
|||
|
||||
r = sd_bus_call_async(bus, NULL, m, quit_callback, &quit, 200 * USEC_PER_MSEC);
|
||||
if (r < 0) {
|
||||
log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
|
||||
log_info("Failed to issue method call: %s", bus_error_message(&error, r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ static int client(struct context *c) {
|
|||
|
||||
r = sd_bus_call(bus, m, 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -495,10 +495,8 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
|
|||
m = timeout_usec;
|
||||
|
||||
r = fd_wait_for_event(rtnl->fd, e, m);
|
||||
if (r < 0)
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ static int set_locale(int argc, char **argv, void *userdata) {
|
|||
|
||||
r = sd_bus_call(bus, m, 0, &error, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ static int set_vconsole_keymap(int argc, char **argv, void *userdata) {
|
|||
NULL,
|
||||
"ssbb", map, toggle_map, arg_convert, arg_ask_password);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ static int set_x11_keymap(int argc, char **argv, void *userdata) {
|
|||
"ssssbb", layout, model, variant, options,
|
||||
arg_convert, arg_ask_password);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to set keymap: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1022,7 +1022,7 @@ static int kill_session(int argc, char *argv[], void *userdata) {
|
|||
&error, NULL,
|
||||
"ssi", argv[i], arg_kill_who, arg_signal);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not kill session: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not kill session: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1071,7 +1071,7 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
|
|||
&error, NULL,
|
||||
"ubb", (uint32_t) uid, b, true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not enable linger: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not enable linger: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1096,7 +1096,7 @@ static int terminate_user(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_login_mgr, "TerminateUser", &error, NULL, "u", (uint32_t) uid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not terminate user: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not terminate user: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1129,7 +1129,7 @@ static int kill_user(int argc, char *argv[], void *userdata) {
|
|||
&error, NULL,
|
||||
"ui", (uint32_t) uid, arg_signal);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not kill user: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not kill user: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1154,7 +1154,7 @@ static int attach(int argc, char *argv[], void *userdata) {
|
|||
&error, NULL,
|
||||
"ssb", argv[1], argv[i], true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not attach device: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not attach device: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1172,7 +1172,7 @@ static int flush_devices(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_login_mgr, "FlushDevices", &error, NULL, "b", true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not flush devices: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not flush devices: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1194,7 +1194,7 @@ static int lock_sessions(int argc, char *argv[], void *userdata) {
|
|||
&error, NULL,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not lock sessions: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not lock sessions: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1213,7 +1213,7 @@ static int terminate_seat(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_login_mgr, "TerminateSeat", &error, NULL, "s", argv[i]);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not terminate seat: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not terminate seat: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -720,7 +720,7 @@ static int show_machine(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_machine_mgr, "GetMachine", &error, &reply, "s", argv[i]);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not get path to machine: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not get path to machine: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "o", &path);
|
||||
if (r < 0)
|
||||
|
@ -1037,7 +1037,7 @@ static int show_image(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_machine_mgr, "GetImage", &error, &reply, "s", argv[i]);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not get path to image: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not get path to image: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "o", &path);
|
||||
if (r < 0)
|
||||
|
@ -1073,7 +1073,7 @@ static int kill_machine(int argc, char *argv[], void *userdata) {
|
|||
NULL,
|
||||
"ssi", argv[i], arg_kill_who, arg_signal);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not kill machine: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not kill machine: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1105,7 +1105,7 @@ static int terminate_machine(int argc, char *argv[], void *userdata) {
|
|||
for (int i = 1; i < argc; i++) {
|
||||
r = bus_call_method(bus, bus_machine_mgr, "TerminateMachine", &error, NULL, "s", argv[i]);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not terminate machine: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not terminate machine: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1184,7 +1184,7 @@ static int bind_mount(int argc, char *argv[], void *userdata) {
|
|||
arg_read_only,
|
||||
arg_mkdir);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind mount: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to bind mount: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1347,7 +1347,7 @@ static int login_machine(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_machine_mgr, "OpenMachineLogin", &error, &reply, "s", machine);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get login PTY: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to get login PTY: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "hs", &master, NULL);
|
||||
if (r < 0)
|
||||
|
@ -1430,7 +1430,7 @@ static int shell_machine(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = sd_bus_call(bus, m, 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get shell PTY: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to get shell PTY: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "hs", &master, NULL);
|
||||
if (r < 0)
|
||||
|
@ -1485,7 +1485,7 @@ static int rename_image(int argc, char *argv[], void *userdata) {
|
|||
NULL,
|
||||
"ss", argv[1], argv[2]);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not rename image: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not rename image: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1535,7 +1535,7 @@ static int read_only_image(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_machine_mgr, "MarkImageReadOnly", &error, NULL, "sb", argv[1], b);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not mark image read-only: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not mark image read-only: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1552,7 +1552,7 @@ static int image_exists(sd_bus *bus, const char *name) {
|
|||
if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_IMAGE))
|
||||
return 0;
|
||||
|
||||
return log_error_errno(r, "Failed to check whether image %s exists: %s", name, bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to check whether image %s exists: %s", name, bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -1617,7 +1617,7 @@ static int start_machine(int argc, char *argv[], void *userdata) {
|
|||
&reply,
|
||||
"ss", unit, "fail");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to start unit: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to start unit: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "o", &object);
|
||||
if (r < 0)
|
||||
|
@ -1697,7 +1697,7 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = sd_bus_call(bus, m, 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enable or disable unit: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to enable or disable unit: %s", bus_error_message(&error, r));
|
||||
|
||||
if (streq(argv[0], "enable")) {
|
||||
r = sd_bus_message_read(reply, "b", NULL);
|
||||
|
@ -1719,7 +1719,7 @@ static int enable_machine(int argc, char *argv[], void *userdata) {
|
|||
NULL,
|
||||
NULL);
|
||||
if (r < 0) {
|
||||
log_error("Failed to reload daemon: %s", bus_error_message(&error, -r));
|
||||
log_error("Failed to reload daemon: %s", bus_error_message(&error, r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -1831,7 +1831,7 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) {
|
|||
|
||||
r = sd_bus_call(bus, m, 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to transfer image: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to transfer image: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "uo", &id, &path);
|
||||
if (r < 0)
|
||||
|
@ -2272,7 +2272,7 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_import_mgr, "ListTransfers", &error, &reply, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not get transfers: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not get transfers: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'a', "(usssdo)");
|
||||
if (r < 0)
|
||||
|
@ -2369,7 +2369,7 @@ static int cancel_transfer(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = bus_call_method(bus, bus_import_mgr, "CancelTransfer", &error, NULL, "u", id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not cancel transfer: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Could not cancel transfer: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -704,7 +704,7 @@ static int dhcp4_address_ready_callback(Address *address) {
|
|||
|
||||
r = dhcp4_start_acd(link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCP4 adddress: %m");
|
||||
return log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCP4 address: %m");
|
||||
|
||||
dhcp4_check_ready(link);
|
||||
return 0;
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
/* Hard lower limit for new partition sizes */
|
||||
#define HARD_MIN_SIZE 4096
|
||||
|
||||
/* libfdisk takes off sightly more than 1M of the disk size when creating a GPT disk label */
|
||||
/* libfdisk takes off slightly more than 1M of the disk size when creating a GPT disk label */
|
||||
#define GPT_METADATA_SIZE (1044*1024)
|
||||
|
||||
/* LUKS2 takes off 16M of the partition size with its metadata by default */
|
||||
|
|
|
@ -648,7 +648,7 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
|
|||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
/* Do not set IP_TTL for extra DNS stub listners, as the address may not be local and in that case
|
||||
/* Do not set IP_TTL for extra DNS stub listeners, as the address may not be local and in that case
|
||||
* people may want ttl > 1. */
|
||||
|
||||
r = socket_set_freebind(fd, l->family, true);
|
||||
|
|
|
@ -1146,7 +1146,7 @@ static int start_transient_service(
|
|||
&pty_reply,
|
||||
"s", arg_host);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get machine PTY: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to get machine PTY: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(pty_reply, "hs", &master, &s);
|
||||
if (r < 0)
|
||||
|
@ -1468,7 +1468,7 @@ static int start_transient_scope(sd_bus *bus) {
|
|||
|
||||
r = sd_bus_call(bus, m, 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to start transient scope unit: %s", bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to start transient scope unit: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "o", &object);
|
||||
if (r < 0)
|
||||
|
@ -1688,7 +1688,7 @@ static int start_transient_trigger(
|
|||
|
||||
r = sd_bus_call(bus, m, 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to start transient %s unit: %s", suffix + 1, bus_error_message(&error, -r));
|
||||
return log_error_errno(r, "Failed to start transient %s unit: %s", suffix + 1, bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "o", &object);
|
||||
if (r < 0)
|
||||
|
|
|
@ -36,7 +36,7 @@ static int populate_uid_cache(const char *root, Hashmap **ret) {
|
|||
if (!cache)
|
||||
return -ENOMEM;
|
||||
|
||||
/* The directory list is harcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This
|
||||
/* The directory list is hardcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This
|
||||
* could be made configurable, but I don't see the point right now. */
|
||||
|
||||
const char *fname;
|
||||
|
|
|
@ -210,7 +210,7 @@ typedef struct RecoveryKey {
|
|||
/* The type of recovery key, must be "modhex64" right now */
|
||||
char *type;
|
||||
|
||||
/* A UNIX pasword hash of the normalized form of modhex64 */
|
||||
/* A UNIX password hash of the normalized form of modhex64 */
|
||||
char *hashed_password;
|
||||
} RecoveryKey;
|
||||
|
||||
|
|
|
@ -1045,10 +1045,8 @@ int varlink_wait(Varlink *v, usec_t timeout) {
|
|||
return events;
|
||||
|
||||
r = fd_wait_for_event(fd, events, t);
|
||||
if (r < 0)
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
handle_revents(v, r);
|
||||
return 1;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "env-file.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "macro.h"
|
||||
#include "strv.h"
|
||||
|
@ -132,6 +133,46 @@ static void test_load_env_file_5(void) {
|
|||
assert_se(data[2] == NULL);
|
||||
}
|
||||
|
||||
static void test_write_and_load_env_file(void) {
|
||||
const char *v;
|
||||
|
||||
/* Make sure that our writer, parser and the shell agree on what our env var files mean */
|
||||
|
||||
FOREACH_STRING(v,
|
||||
"obbardc-laptop",
|
||||
"obbardc\\-laptop",
|
||||
"obbardc-lap\\top",
|
||||
"obbardc-lap\\top",
|
||||
"obbardc-lap\\\\top",
|
||||
"double\"quote",
|
||||
"single\'quote",
|
||||
"dollar$dollar",
|
||||
"newline\nnewline") {
|
||||
_cleanup_(unlink_and_freep) char *p = NULL;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
_cleanup_free_ char *j = NULL, *w = NULL, *cmd = NULL, *from_shell = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
size_t sz;
|
||||
|
||||
assert_se(tempfn_random_child(NULL, NULL, &p) >= 0);
|
||||
|
||||
assert_se(j = strjoin("TEST=", v));
|
||||
assert_se(write_env_file(p, STRV_MAKE(j)) >= 0);
|
||||
|
||||
assert_se(cmd = strjoin(". ", p, " && /bin/echo -n \"$TEST\""));
|
||||
assert_se(f = popen(cmd, "re"));
|
||||
assert_se(read_full_stream(f, &from_shell, &sz) >= 0);
|
||||
assert_se(sz == strlen(v));
|
||||
assert_se(streq(from_shell, v));
|
||||
|
||||
assert_se(load_env_file(NULL, p, &l) >= 0);
|
||||
assert_se(strv_equal(l, STRV_MAKE(j)));
|
||||
|
||||
assert_se(parse_env_file(NULL, p, "TEST", &w) >= 0);
|
||||
assert_se(streq_ptr(w, v));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_INFO);
|
||||
|
||||
|
@ -140,4 +181,8 @@ int main(int argc, char *argv[]) {
|
|||
test_load_env_file_3();
|
||||
test_load_env_file_4();
|
||||
test_load_env_file_5();
|
||||
|
||||
test_write_and_load_env_file();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,18 @@ static void test_parse_env_file(void) {
|
|||
assert_se(r >= 0);
|
||||
}
|
||||
|
||||
static void test_one_shell_var(const char *file, const char *variable, const char *value) {
|
||||
_cleanup_free_ char *cmd = NULL, *from_shell = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
size_t sz;
|
||||
|
||||
assert_se(cmd = strjoin(". ", file, " && /bin/echo -n \"$", variable, "\""));
|
||||
assert_se(f = popen(cmd, "re"));
|
||||
assert_se(read_full_stream(f, &from_shell, &sz) >= 0);
|
||||
assert_se(sz == strlen(value));
|
||||
assert_se(streq(from_shell, value));
|
||||
}
|
||||
|
||||
static void test_parse_multiline_env_file(void) {
|
||||
_cleanup_(unlink_tempfilep) char
|
||||
t[] = "/tmp/test-fileio-in-XXXXXX",
|
||||
|
@ -162,8 +174,8 @@ static void test_parse_multiline_env_file(void) {
|
|||
|
||||
assert_se(fmkostemp_safe(t, "w", &f) == 0);
|
||||
fputs("one=BAR\\\n"
|
||||
" VAR\\\n"
|
||||
"\tGAR\n"
|
||||
"\\ \\ \\ \\ VAR\\\n"
|
||||
"\\\tGAR\n"
|
||||
"#comment\n"
|
||||
"two=\"bar\\\n"
|
||||
" var\\\n"
|
||||
|
@ -173,9 +185,13 @@ static void test_parse_multiline_env_file(void) {
|
|||
" var \\\n"
|
||||
"\tgar \"\n", f);
|
||||
|
||||
fflush(f);
|
||||
assert_se(fflush_and_check(f) >= 0);
|
||||
fclose(f);
|
||||
|
||||
test_one_shell_var(t, "one", "BAR VAR\tGAR");
|
||||
test_one_shell_var(t, "two", "bar var\tgar");
|
||||
test_one_shell_var(t, "tri", "bar var \tgar ");
|
||||
|
||||
r = load_env_file(NULL, t, &a);
|
||||
assert_se(r >= 0);
|
||||
|
||||
|
|
|
@ -528,7 +528,7 @@ static int dir_cleanup(
|
|||
continue;
|
||||
|
||||
/* If statx() is supported, use it. It's preferable over fstatat() since it tells us
|
||||
* explicitly where we are looking at a mount point, for free as side information. Determing
|
||||
* explicitly where we are looking at a mount point, for free as side information. Determining
|
||||
* the same information without statx() is hard, see the complexity of path_is_mount_point(),
|
||||
* and also much slower as it requires a number of syscalls instead of just one. Hence, when
|
||||
* we have modern statx() we use it instead of fstat() and do proper mount point checks,
|
||||
|
|
Loading…
Reference in New Issue