mirror of
https://github.com/systemd/systemd
synced 2026-04-25 16:34:50 +02:00
Compare commits
No commits in common. "bc85f8b51d962597360e982811e674c126850f56" and "a008b6d771dd330ab4d8a791809cd5b822323947" have entirely different histories.
bc85f8b51d
...
a008b6d771
@ -4,9 +4,6 @@
|
|||||||
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
|
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<!-- note: units also use the following deprecated specifiers that are not documented:
|
|
||||||
%c, %r, %R. Do not reuse. -->
|
|
||||||
|
|
||||||
<row id='a'>
|
<row id='a'>
|
||||||
<entry><literal>%a</literal></entry>
|
<entry><literal>%a</literal></entry>
|
||||||
<entry>Architecture</entry>
|
<entry>Architecture</entry>
|
||||||
|
|||||||
@ -195,8 +195,8 @@ int unit_name_printf(const Unit *u, const char* format, char **ret) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int unit_full_printf_full(const Unit *u, const char *format, size_t max_length, char **ret) {
|
int unit_full_printf_full(const Unit *u, const char *format, size_t max_length, char **ret) {
|
||||||
/* This is similar to unit_name_printf() but also supports unescaping. Also, adds a couple of
|
/* This is similar to unit_name_printf() but also supports unescaping. Also, adds a couple of additional codes
|
||||||
* additional codes (which are likely not suitable for unescaped inclusion in unit names):
|
* (which are likely not suitable for unescaped inclusion in unit names):
|
||||||
*
|
*
|
||||||
* %f: the unescaped instance if set, otherwise the id unescaped as path
|
* %f: the unescaped instance if set, otherwise the id unescaped as path
|
||||||
*
|
*
|
||||||
@ -214,9 +214,9 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length,
|
|||||||
* %h: the homedir of the running user
|
* %h: the homedir of the running user
|
||||||
* %s: the shell of the running user
|
* %s: the shell of the running user
|
||||||
*
|
*
|
||||||
* NOTICE: When you add new entries here, please be careful: specifiers which depend on settings of
|
* NOTICE: When you add new entries here, please be careful: specifiers which depend on settings of the unit
|
||||||
* the unit file itself are broken by design, as they would resolve differently depending on whether
|
* file itself are broken by design, as they would resolve differently depending on whether they are used
|
||||||
* they are used before or after the relevant configuration setting. Hence: don't add them.
|
* before or after the relevant configuration setting. Hence: don't add them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -237,9 +237,9 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length,
|
|||||||
{ 'y', specifier_real_path, u->fragment_path },
|
{ 'y', specifier_real_path, u->fragment_path },
|
||||||
{ 'Y', specifier_real_directory, u->fragment_path },
|
{ 'Y', specifier_real_directory, u->fragment_path },
|
||||||
|
|
||||||
{ 'c', specifier_cgroup, NULL }, /* deprecated, see 1b89b0c499cd4bf0ff389caab4ecaae6e75f9d4e */
|
{ 'c', specifier_cgroup, NULL },
|
||||||
{ 'r', specifier_cgroup_slice, NULL }, /* deprecated, see 1b89b0c499cd4bf0ff389caab4ecaae6e75f9d4e */
|
{ 'r', specifier_cgroup_slice, NULL },
|
||||||
{ 'R', specifier_cgroup_root, NULL }, /* deprecated, see 1b89b0c499cd4bf0ff389caab4ecaae6e75f9d4e */
|
{ 'R', specifier_cgroup_root, NULL },
|
||||||
|
|
||||||
{ 'C', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
|
{ 'C', specifier_special_directory, UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
|
||||||
{ 'd', specifier_credentials_dir, NULL },
|
{ 'd', specifier_credentials_dir, NULL },
|
||||||
|
|||||||
@ -638,12 +638,7 @@ static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsys
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enumerator_scan_dir(
|
static int enumerator_scan_dir(sd_device_enumerator *enumerator, const char *basedir, const char *subdir, const char *subsystem) {
|
||||||
sd_device_enumerator *enumerator,
|
|
||||||
const char *basedir,
|
|
||||||
const char *subdir,
|
|
||||||
const char *subsystem) {
|
|
||||||
|
|
||||||
_cleanup_closedir_ DIR *dir = NULL;
|
_cleanup_closedir_ DIR *dir = NULL;
|
||||||
char *path;
|
char *path;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
@ -1002,7 +997,7 @@ _public_ sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
int device_enumerator_scan_devices_and_subsystems(sd_device_enumerator *enumerator) {
|
int device_enumerator_scan_devices_and_subsystems(sd_device_enumerator *enumerator) {
|
||||||
int r;
|
int r = 0, k;
|
||||||
|
|
||||||
assert(enumerator);
|
assert(enumerator);
|
||||||
|
|
||||||
@ -1012,14 +1007,22 @@ int device_enumerator_scan_devices_and_subsystems(sd_device_enumerator *enumerat
|
|||||||
|
|
||||||
device_enumerator_unref_devices(enumerator);
|
device_enumerator_unref_devices(enumerator);
|
||||||
|
|
||||||
if (!set_isempty(enumerator->match_tag))
|
if (!set_isempty(enumerator->match_tag)) {
|
||||||
r = enumerator_scan_devices_tags(enumerator);
|
k = enumerator_scan_devices_tags(enumerator);
|
||||||
else if (enumerator->match_parent)
|
if (k < 0)
|
||||||
r = enumerator_scan_devices_children(enumerator);
|
r = k;
|
||||||
else {
|
} else if (enumerator->match_parent) {
|
||||||
int k;
|
k = enumerator_scan_devices_children(enumerator);
|
||||||
|
if (k < 0)
|
||||||
|
r = k;
|
||||||
|
} else {
|
||||||
|
k = enumerator_scan_dir(enumerator, "class", NULL, NULL);
|
||||||
|
if (k < 0)
|
||||||
|
r = log_debug_errno(k, "sd-device-enumerator: Failed to scan /sys/class: %m");
|
||||||
|
|
||||||
r = enumerator_scan_devices_all(enumerator);
|
k = enumerator_scan_dir(enumerator, "bus", "devices", NULL);
|
||||||
|
if (k < 0)
|
||||||
|
r = log_debug_errno(k, "sd-device-enumerator: Failed to scan /sys/bus: %m");
|
||||||
|
|
||||||
if (match_subsystem(enumerator, "module")) {
|
if (match_subsystem(enumerator, "module")) {
|
||||||
k = enumerator_scan_dir_and_add_devices(enumerator, "module", NULL, NULL);
|
k = enumerator_scan_dir_and_add_devices(enumerator, "module", NULL, NULL);
|
||||||
|
|||||||
@ -207,11 +207,10 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
|
|||||||
syspath = strdup(_syspath);
|
syspath = strdup(_syspath);
|
||||||
if (!syspath)
|
if (!syspath)
|
||||||
return log_oom_debug();
|
return log_oom_debug();
|
||||||
|
|
||||||
path_simplify(syspath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_se(devpath = startswith(syspath, "/sys"));
|
devpath = syspath + STRLEN("/sys");
|
||||||
|
|
||||||
if (devpath[0] != '/')
|
if (devpath[0] != '/')
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "sd-device: \"/sys\" alone is not a valid device path.");
|
return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "sd-device: \"/sys\" alone is not a valid device path.");
|
||||||
|
|
||||||
@ -585,15 +584,11 @@ int device_set_devnum(sd_device *device, const char *major, const char *minor) {
|
|||||||
return r;
|
return r;
|
||||||
if (maj == 0)
|
if (maj == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (!DEVICE_MAJOR_VALID(maj))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (minor) {
|
if (minor) {
|
||||||
r = safe_atou(minor, &min);
|
r = safe_atou(minor, &min);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (!DEVICE_MINOR_VALID(min))
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = device_add_property_internal(device, "MAJOR", major);
|
r = device_add_property_internal(device, "MAJOR", major);
|
||||||
|
|||||||
@ -225,7 +225,7 @@ int config_parse_dnssd_service_name(
|
|||||||
{ 'a', specifier_architecture, NULL },
|
{ 'a', specifier_architecture, NULL },
|
||||||
{ 'b', specifier_boot_id, NULL },
|
{ 'b', specifier_boot_id, NULL },
|
||||||
{ 'B', specifier_os_build_id, NULL },
|
{ 'B', specifier_os_build_id, NULL },
|
||||||
{ 'H', specifier_hostname, NULL }, /* We will use specifier_dnssd_hostname(). */
|
{ 'H', specifier_host_name, NULL }, /* We will use specifier_dnssd_host_name(). */
|
||||||
{ 'm', specifier_machine_id, NULL },
|
{ 'm', specifier_machine_id, NULL },
|
||||||
{ 'o', specifier_os_id, NULL },
|
{ 'o', specifier_os_id, NULL },
|
||||||
{ 'v', specifier_kernel_release, NULL },
|
{ 'v', specifier_kernel_release, NULL },
|
||||||
|
|||||||
@ -135,7 +135,7 @@ static int dnssd_service_load(Manager *manager, const char *filename) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_dnssd_hostname(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
static int specifier_dnssd_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
DnssdService *s = (DnssdService *) userdata;
|
DnssdService *s = (DnssdService *) userdata;
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ int dnssd_render_instance_name(DnssdService *s, char **ret_name) {
|
|||||||
{ 'a', specifier_architecture, NULL },
|
{ 'a', specifier_architecture, NULL },
|
||||||
{ 'b', specifier_boot_id, NULL },
|
{ 'b', specifier_boot_id, NULL },
|
||||||
{ 'B', specifier_os_build_id, NULL },
|
{ 'B', specifier_os_build_id, NULL },
|
||||||
{ 'H', specifier_dnssd_hostname, NULL },
|
{ 'H', specifier_dnssd_host_name, NULL },
|
||||||
{ 'm', specifier_machine_id, NULL },
|
{ 'm', specifier_machine_id, NULL },
|
||||||
{ 'o', specifier_os_id, NULL },
|
{ 'o', specifier_os_id, NULL },
|
||||||
{ 'v', specifier_kernel_release, NULL },
|
{ 'v', specifier_kernel_release, NULL },
|
||||||
|
|||||||
@ -199,7 +199,7 @@ int specifier_boot_id(char specifier, const void *data, const char *root, const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_hostname(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
int specifier_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
assert(ret);
|
assert(ret);
|
||||||
@ -212,7 +212,7 @@ int specifier_hostname(char specifier, const void *data, const char *root, const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_short_hostname(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
int specifier_short_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
assert(ret);
|
assert(ret);
|
||||||
@ -225,7 +225,7 @@ int specifier_short_hostname(char specifier, const void *data, const char *root,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_pretty_hostname(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
int specifier_pretty_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *n = NULL;
|
char *n = NULL;
|
||||||
|
|
||||||
assert(ret);
|
assert(ret);
|
||||||
@ -276,18 +276,12 @@ int specifier_architecture(char specifier, const void *data, const char *root, c
|
|||||||
* installation. */
|
* installation. */
|
||||||
|
|
||||||
static int parse_os_release_specifier(const char *root, const char *id, char **ret) {
|
static int parse_os_release_specifier(const char *root, const char *id, char **ret) {
|
||||||
char *v = NULL;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
r = parse_os_release(root, id, &v);
|
|
||||||
if (r >= 0)
|
|
||||||
/* parse_os_release() calls parse_env_file() which only sets the return value for
|
|
||||||
* entries found. Let's make sure we set the return value in all cases. */
|
|
||||||
*ret = v;
|
|
||||||
|
|
||||||
/* Translate error for missing os-release file to EUNATCH. */
|
/* Translate error for missing os-release file to EUNATCH. */
|
||||||
|
r = parse_os_release(root, id, ret);
|
||||||
return r == -ENOENT ? -EUNATCH : r;
|
return r == -ENOENT ? -EUNATCH : r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,9 +19,9 @@ int specifier_real_directory(char specifier, const void *data, const char *root,
|
|||||||
|
|
||||||
int specifier_machine_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
int specifier_machine_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_boot_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
int specifier_boot_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_hostname(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
int specifier_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_short_hostname(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
int specifier_short_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_pretty_hostname(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
int specifier_pretty_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_kernel_release(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
int specifier_kernel_release(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_architecture(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
int specifier_architecture(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_os_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
int specifier_os_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
@ -75,9 +75,9 @@ int specifier_var_tmp_dir(char specifier, const void *data, const char *root, co
|
|||||||
{ 'A', specifier_os_image_version,NULL }, \
|
{ 'A', specifier_os_image_version,NULL }, \
|
||||||
{ 'b', specifier_boot_id, NULL }, \
|
{ 'b', specifier_boot_id, NULL }, \
|
||||||
{ 'B', specifier_os_build_id, NULL }, \
|
{ 'B', specifier_os_build_id, NULL }, \
|
||||||
{ 'H', specifier_hostname, NULL }, \
|
{ 'H', specifier_host_name, NULL }, \
|
||||||
{ 'l', specifier_short_hostname, NULL }, \
|
{ 'l', specifier_short_host_name, NULL }, \
|
||||||
{ 'q', specifier_pretty_hostname, NULL }, \
|
{ 'q', specifier_pretty_host_name,NULL }, \
|
||||||
{ 'm', specifier_machine_id, NULL }, \
|
{ 'm', specifier_machine_id, NULL }, \
|
||||||
{ 'M', specifier_os_image_id, NULL }, \
|
{ 'M', specifier_os_image_id, NULL }, \
|
||||||
{ 'o', specifier_os_id, NULL }, \
|
{ 'o', specifier_os_id, NULL }, \
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
#include "specifier.h"
|
#include "specifier.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "tmpfile-util.h"
|
|
||||||
#include "unit-def.h"
|
#include "unit-def.h"
|
||||||
#include "unit-name.h"
|
#include "unit-name.h"
|
||||||
#include "unit-printf.h"
|
#include "unit-printf.h"
|
||||||
@ -214,75 +213,42 @@ TEST(unit_name_mangle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_RET(unit_printf, .sd_booted = true) {
|
TEST_RET(unit_printf, .sd_booted = true) {
|
||||||
_cleanup_free_ char
|
_cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *gid = NULL, *group = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL;
|
||||||
*architecture, *os_image_version, *boot_id, *os_build_id,
|
|
||||||
*hostname, *short_hostname, *pretty_hostname,
|
|
||||||
*machine_id, *os_image_id, *os_id, *os_version_id, *os_variant_id,
|
|
||||||
*user, *group, *uid, *gid, *home, *shell,
|
|
||||||
*tmp_dir, *var_tmp_dir;
|
|
||||||
_cleanup_(manager_freep) Manager *m = NULL;
|
_cleanup_(manager_freep) Manager *m = NULL;
|
||||||
Unit *u;
|
Unit *u;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
_cleanup_(unlink_tempfilep) char filename[] = "/tmp/test-unit_printf.XXXXXX";
|
assert_se(specifier_machine_id('m', NULL, NULL, NULL, &mid) >= 0 && mid);
|
||||||
assert_se(mkostemp_safe(filename) >= 0);
|
assert_se(specifier_boot_id('b', NULL, NULL, NULL, &bid) >= 0 && bid);
|
||||||
|
assert_se(host = gethostname_malloc());
|
||||||
/* Using the specifier functions is admittedly a bit circular, but we don't want to reimplement the
|
|
||||||
* logic a second time. We're at least testing that the hookup works. */
|
|
||||||
assert_se(specifier_architecture('a', NULL, NULL, NULL, &architecture) >= 0);
|
|
||||||
assert_se(architecture);
|
|
||||||
assert_se(specifier_os_image_version('A', NULL, NULL, NULL, &os_image_version) >= 0);
|
|
||||||
assert_se(specifier_boot_id('b', NULL, NULL, NULL, &boot_id) >= 0);
|
|
||||||
assert_se(boot_id);
|
|
||||||
assert_se(specifier_os_build_id('B', NULL, NULL, NULL, &os_build_id) >= 0);
|
|
||||||
assert_se(hostname = gethostname_malloc());
|
|
||||||
assert_se(specifier_short_hostname('l', NULL, NULL, NULL, &short_hostname) == 0);
|
|
||||||
assert_se(short_hostname);
|
|
||||||
assert_se(specifier_pretty_hostname('q', NULL, NULL, NULL, &pretty_hostname) == 0);
|
|
||||||
assert_se(pretty_hostname);
|
|
||||||
assert_se(specifier_machine_id('m', NULL, NULL, NULL, &machine_id) >= 0);
|
|
||||||
assert_se(machine_id);
|
|
||||||
assert_se(specifier_os_image_id('M', NULL, NULL, NULL, &os_image_id) >= 0);
|
|
||||||
assert_se(specifier_os_id('o', NULL, NULL, NULL, &os_id) >= 0);
|
|
||||||
assert_se(specifier_os_version_id('w', NULL, NULL, NULL, &os_version_id) >= 0);
|
|
||||||
assert_se(specifier_os_variant_id('W', NULL, NULL, NULL, &os_variant_id) >= 0);
|
|
||||||
assert_se(user = uid_to_name(getuid()));
|
assert_se(user = uid_to_name(getuid()));
|
||||||
assert_se(group = gid_to_name(getgid()));
|
assert_se(group = gid_to_name(getgid()));
|
||||||
assert_se(asprintf(&uid, UID_FMT, getuid()));
|
assert_se(asprintf(&uid, UID_FMT, getuid()));
|
||||||
assert_se(asprintf(&gid, UID_FMT, getgid()));
|
assert_se(asprintf(&gid, UID_FMT, getgid()));
|
||||||
assert_se(get_home_dir(&home) >= 0);
|
assert_se(get_home_dir(&home) >= 0);
|
||||||
assert_se(get_shell(&shell) >= 0);
|
assert_se(get_shell(&shell) >= 0);
|
||||||
assert_se(specifier_tmp_dir('T', NULL, NULL, NULL, &tmp_dir) >= 0);
|
|
||||||
assert_se(tmp_dir);
|
|
||||||
assert_se(specifier_var_tmp_dir('V', NULL, NULL, NULL, &var_tmp_dir) >= 0);
|
|
||||||
assert_se(var_tmp_dir);
|
|
||||||
|
|
||||||
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
|
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
|
||||||
if (manager_errno_skip_test(r))
|
if (manager_errno_skip_test(r))
|
||||||
return log_tests_skipped_errno(r, "manager_new");
|
return log_tests_skipped_errno(r, "manager_new");
|
||||||
assert_se(r == 0);
|
assert_se(r == 0);
|
||||||
|
|
||||||
assert_se(free_and_strdup(&m->cgroup_root, "/cgroup-root") == 1);
|
#define expect(unit, pattern, expected) \
|
||||||
|
|
||||||
#define expect(unit, pattern, _expected) \
|
|
||||||
{ \
|
{ \
|
||||||
|
char *e; \
|
||||||
_cleanup_free_ char *t = NULL; \
|
_cleanup_free_ char *t = NULL; \
|
||||||
assert_se(unit_full_printf(unit, pattern, &t) >= 0); \
|
assert_se(unit_full_printf(unit, pattern, &t) >= 0); \
|
||||||
const char *expected = strempty(_expected); \
|
printf("result: %s\nexpect: %s\n", t, expected); \
|
||||||
printf("%s: result: %s\n expect: %s\n", pattern, t, expected); \
|
if ((e = endswith(expected, "*"))) \
|
||||||
assert_se(fnmatch(expected, t, FNM_NOESCAPE) == 0); \
|
assert_se(strncmp(t, e, e-expected)); \
|
||||||
|
else \
|
||||||
|
assert_se(streq(t, expected)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_se(u = unit_new(m, sizeof(Service)));
|
assert_se(u = unit_new(m, sizeof(Service)));
|
||||||
assert_se(unit_add_name(u, "blah.service") == 0);
|
assert_se(unit_add_name(u, "blah.service") == 0);
|
||||||
assert_se(unit_add_name(u, "blah.service") == 0);
|
assert_se(unit_add_name(u, "blah.service") == 0);
|
||||||
|
|
||||||
/* We need *a* file that exists, but it doesn't even need to have the right suffix. */
|
|
||||||
assert_se(free_and_strdup(&u->fragment_path, filename) == 1);
|
|
||||||
|
|
||||||
/* This sets the slice to /app.slice. */
|
|
||||||
assert_se(unit_set_default_slice(u) == 1);
|
|
||||||
|
|
||||||
/* general tests */
|
/* general tests */
|
||||||
expect(u, "%%", "%");
|
expect(u, "%%", "%");
|
||||||
expect(u, "%%s", "%s");
|
expect(u, "%%s", "%s");
|
||||||
@ -290,103 +256,62 @@ TEST_RET(unit_printf, .sd_booted = true) {
|
|||||||
expect(u, "%", "%");
|
expect(u, "%", "%");
|
||||||
|
|
||||||
/* normal unit */
|
/* normal unit */
|
||||||
expect(u, "%a", architecture);
|
expect(u, "%n", "blah.service");
|
||||||
expect(u, "%A", os_image_version);
|
expect(u, "%f", "/blah");
|
||||||
expect(u, "%b", boot_id);
|
expect(u, "%N", "blah");
|
||||||
expect(u, "%B", os_build_id);
|
expect(u, "%p", "blah");
|
||||||
expect(u, "%H", hostname);
|
expect(u, "%P", "blah");
|
||||||
expect(u, "%l", short_hostname);
|
|
||||||
expect(u, "%q", pretty_hostname);
|
|
||||||
expect(u, "%m", machine_id);
|
|
||||||
expect(u, "%M", os_image_id);
|
|
||||||
expect(u, "%o", os_id);
|
|
||||||
expect(u, "%w", os_version_id);
|
|
||||||
expect(u, "%W", os_variant_id);
|
|
||||||
expect(u, "%g", group);
|
|
||||||
expect(u, "%G", gid);
|
|
||||||
expect(u, "%u", user);
|
|
||||||
expect(u, "%U", uid);
|
|
||||||
expect(u, "%T", tmp_dir);
|
|
||||||
expect(u, "%V", var_tmp_dir);
|
|
||||||
|
|
||||||
expect(u, "%i", "");
|
expect(u, "%i", "");
|
||||||
expect(u, "%I", "");
|
expect(u, "%I", "");
|
||||||
expect(u, "%j", "blah");
|
expect(u, "%j", "blah");
|
||||||
expect(u, "%J", "blah");
|
expect(u, "%J", "blah");
|
||||||
expect(u, "%n", "blah.service");
|
expect(u, "%g", group);
|
||||||
expect(u, "%N", "blah");
|
expect(u, "%G", gid);
|
||||||
expect(u, "%p", "blah");
|
expect(u, "%u", user);
|
||||||
expect(u, "%P", "blah");
|
expect(u, "%U", uid);
|
||||||
expect(u, "%f", "/blah");
|
|
||||||
expect(u, "%y", filename);
|
|
||||||
expect(u, "%Y", "/tmp");
|
|
||||||
expect(u, "%C", m->prefix[EXEC_DIRECTORY_CACHE]);
|
|
||||||
expect(u, "%d", "*/credentials/blah.service");
|
|
||||||
expect(u, "%E", m->prefix[EXEC_DIRECTORY_CONFIGURATION]);
|
|
||||||
expect(u, "%L", m->prefix[EXEC_DIRECTORY_LOGS]);
|
|
||||||
expect(u, "%S", m->prefix[EXEC_DIRECTORY_STATE]);
|
|
||||||
expect(u, "%t", m->prefix[EXEC_DIRECTORY_RUNTIME]);
|
|
||||||
expect(u, "%h", home);
|
expect(u, "%h", home);
|
||||||
expect(u, "%s", shell);
|
expect(u, "%m", mid);
|
||||||
|
expect(u, "%b", bid);
|
||||||
/* deprecated */
|
expect(u, "%H", host);
|
||||||
expect(u, "%c", "/cgroup-root/app.slice/blah.service");
|
expect(u, "%t", "/run/user/*");
|
||||||
expect(u, "%r", "/cgroup-root/app.slice");
|
|
||||||
expect(u, "%R", "/cgroup-root");
|
|
||||||
|
|
||||||
/* templated */
|
/* templated */
|
||||||
assert_se(u = unit_new(m, sizeof(Service)));
|
assert_se(u = unit_new(m, sizeof(Service)));
|
||||||
assert_se(unit_add_name(u, "blah@foo-foo.service") == 0);
|
assert_se(unit_add_name(u, "blah@foo-foo.service") == 0);
|
||||||
assert_se(unit_add_name(u, "blah@foo-foo.service") == 0);
|
assert_se(unit_add_name(u, "blah@foo-foo.service") == 0);
|
||||||
|
|
||||||
assert_se(free_and_strdup(&u->fragment_path, filename) == 1);
|
expect(u, "%n", "blah@foo-foo.service");
|
||||||
|
expect(u, "%N", "blah@foo-foo");
|
||||||
/* This sets the slice to /app.slice/app-blah.slice. */
|
expect(u, "%f", "/foo/foo");
|
||||||
assert_se(unit_set_default_slice(u) == 1);
|
expect(u, "%p", "blah");
|
||||||
|
expect(u, "%P", "blah");
|
||||||
expect(u, "%i", "foo-foo");
|
expect(u, "%i", "foo-foo");
|
||||||
expect(u, "%I", "foo/foo");
|
expect(u, "%I", "foo/foo");
|
||||||
expect(u, "%j", "blah");
|
expect(u, "%j", "blah");
|
||||||
expect(u, "%J", "blah");
|
expect(u, "%J", "blah");
|
||||||
expect(u, "%n", "blah@foo-foo.service");
|
expect(u, "%g", group);
|
||||||
expect(u, "%N", "blah@foo-foo");
|
expect(u, "%G", gid);
|
||||||
expect(u, "%p", "blah");
|
expect(u, "%u", user);
|
||||||
expect(u, "%P", "blah");
|
expect(u, "%U", uid);
|
||||||
expect(u, "%f", "/foo/foo");
|
|
||||||
expect(u, "%y", filename);
|
|
||||||
expect(u, "%Y", "/tmp");
|
|
||||||
expect(u, "%C", m->prefix[EXEC_DIRECTORY_CACHE]);
|
|
||||||
expect(u, "%d", "*/credentials/blah@foo-foo.service");
|
|
||||||
expect(u, "%E", m->prefix[EXEC_DIRECTORY_CONFIGURATION]);
|
|
||||||
expect(u, "%L", m->prefix[EXEC_DIRECTORY_LOGS]);
|
|
||||||
expect(u, "%S", m->prefix[EXEC_DIRECTORY_STATE]);
|
|
||||||
expect(u, "%t", m->prefix[EXEC_DIRECTORY_RUNTIME]);
|
|
||||||
expect(u, "%h", home);
|
expect(u, "%h", home);
|
||||||
expect(u, "%s", shell);
|
expect(u, "%m", mid);
|
||||||
|
expect(u, "%b", bid);
|
||||||
/* deprecated */
|
expect(u, "%H", host);
|
||||||
expect(u, "%c", "/cgroup-root/app.slice/app-blah.slice/blah@foo-foo.service");
|
expect(u, "%t", "/run/user/*");
|
||||||
expect(u, "%r", "/cgroup-root/app.slice/app-blah.slice");
|
|
||||||
expect(u, "%R", "/cgroup-root");
|
|
||||||
|
|
||||||
/* templated with components */
|
/* templated with components */
|
||||||
assert_se(u = unit_new(m, sizeof(Slice)));
|
assert_se(u = unit_new(m, sizeof(Slice)));
|
||||||
assert_se(unit_add_name(u, "blah-blah\\x2d.slice") == 0);
|
assert_se(unit_add_name(u, "blah-blah\\x2d.slice") == 0);
|
||||||
|
|
||||||
|
expect(u, "%n", "blah-blah\\x2d.slice");
|
||||||
|
expect(u, "%N", "blah-blah\\x2d");
|
||||||
|
expect(u, "%f", "/blah/blah-");
|
||||||
|
expect(u, "%p", "blah-blah\\x2d");
|
||||||
|
expect(u, "%P", "blah/blah-");
|
||||||
expect(u, "%i", "");
|
expect(u, "%i", "");
|
||||||
expect(u, "%I", "");
|
expect(u, "%I", "");
|
||||||
expect(u, "%j", "blah\\x2d");
|
expect(u, "%j", "blah\\x2d");
|
||||||
expect(u, "%J", "blah-");
|
expect(u, "%J", "blah-");
|
||||||
expect(u, "%n", "blah-blah\\x2d.slice");
|
|
||||||
expect(u, "%N", "blah-blah\\x2d");
|
|
||||||
expect(u, "%p", "blah-blah\\x2d");
|
|
||||||
expect(u, "%P", "blah/blah-");
|
|
||||||
expect(u, "%f", "/blah/blah-");
|
|
||||||
|
|
||||||
/* deprecated */
|
|
||||||
expect(u, "%c", "/cgroup-root/blah-blah\\x2d.slice");
|
|
||||||
expect(u, "%r", "/cgroup-root");
|
|
||||||
expect(u, "%R", "/cgroup-root");
|
|
||||||
|
|
||||||
#undef expect
|
#undef expect
|
||||||
|
|
||||||
|
|||||||
@ -2923,8 +2923,8 @@ static int parse_line(
|
|||||||
{ 'a', specifier_architecture, NULL },
|
{ 'a', specifier_architecture, NULL },
|
||||||
{ 'b', specifier_boot_id, NULL },
|
{ 'b', specifier_boot_id, NULL },
|
||||||
{ 'B', specifier_os_build_id, NULL },
|
{ 'B', specifier_os_build_id, NULL },
|
||||||
{ 'H', specifier_hostname, NULL },
|
{ 'H', specifier_host_name, NULL },
|
||||||
{ 'l', specifier_short_hostname, NULL },
|
{ 'l', specifier_short_host_name, NULL },
|
||||||
{ 'm', specifier_machine_id_safe, NULL },
|
{ 'm', specifier_machine_id_safe, NULL },
|
||||||
{ 'o', specifier_os_id, NULL },
|
{ 'o', specifier_os_id, NULL },
|
||||||
{ 'v', specifier_kernel_release, NULL },
|
{ 'v', specifier_kernel_release, NULL },
|
||||||
|
|||||||
@ -156,8 +156,7 @@ static bool test_pointers(sd_device *dev,
|
|||||||
bool has_abs_coordinates = false;
|
bool has_abs_coordinates = false;
|
||||||
bool has_rel_coordinates = false;
|
bool has_rel_coordinates = false;
|
||||||
bool has_mt_coordinates = false;
|
bool has_mt_coordinates = false;
|
||||||
size_t num_joystick_axes = 0;
|
bool has_joystick_axes_or_buttons = false;
|
||||||
size_t num_joystick_buttons = 0;
|
|
||||||
bool has_pad_buttons = false;
|
bool has_pad_buttons = false;
|
||||||
bool is_direct = false;
|
bool is_direct = false;
|
||||||
bool has_touch = false;
|
bool has_touch = false;
|
||||||
@ -215,19 +214,15 @@ static bool test_pointers(sd_device *dev,
|
|||||||
* Catz Mad Catz M.M.O.TE). Skip those.
|
* Catz Mad Catz M.M.O.TE). Skip those.
|
||||||
*/
|
*/
|
||||||
if (!test_bit(BTN_JOYSTICK - 1, bitmask_key)) {
|
if (!test_bit(BTN_JOYSTICK - 1, bitmask_key)) {
|
||||||
for (int button = BTN_JOYSTICK; button < BTN_DIGI; button++)
|
for (int button = BTN_JOYSTICK; button < BTN_DIGI && !has_joystick_axes_or_buttons; button++)
|
||||||
if (test_bit(button, bitmask_key))
|
has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
|
||||||
num_joystick_buttons++;
|
for (int button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40 && !has_joystick_axes_or_buttons; button++)
|
||||||
for (int button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40; button++)
|
has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
|
||||||
if (test_bit(button, bitmask_key))
|
for (int button = BTN_DPAD_UP; button <= BTN_DPAD_RIGHT && !has_joystick_axes_or_buttons; button++)
|
||||||
num_joystick_buttons++;
|
has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
|
||||||
for (int button = BTN_DPAD_UP; button <= BTN_DPAD_RIGHT; button++)
|
|
||||||
if (test_bit(button, bitmask_key))
|
|
||||||
num_joystick_buttons++;
|
|
||||||
}
|
}
|
||||||
for (int axis = ABS_RX; axis < ABS_PRESSURE; axis++)
|
for (int axis = ABS_RX; axis < ABS_PRESSURE && !has_joystick_axes_or_buttons; axis++)
|
||||||
if (test_bit(axis, bitmask_abs))
|
has_joystick_axes_or_buttons = test_bit(axis, bitmask_abs);
|
||||||
num_joystick_axes++;
|
|
||||||
|
|
||||||
if (has_abs_coordinates) {
|
if (has_abs_coordinates) {
|
||||||
if (has_stylus || has_pen)
|
if (has_stylus || has_pen)
|
||||||
@ -240,9 +235,9 @@ static bool test_pointers(sd_device *dev,
|
|||||||
is_abs_mouse = true;
|
is_abs_mouse = true;
|
||||||
else if (has_touch || is_direct)
|
else if (has_touch || is_direct)
|
||||||
is_touchscreen = true;
|
is_touchscreen = true;
|
||||||
else if (num_joystick_buttons > 0 || num_joystick_axes > 0)
|
else if (has_joystick_axes_or_buttons)
|
||||||
is_joystick = true;
|
is_joystick = true;
|
||||||
} else if (num_joystick_buttons > 0 || num_joystick_axes > 0)
|
} else if (has_joystick_axes_or_buttons)
|
||||||
is_joystick = true;
|
is_joystick = true;
|
||||||
|
|
||||||
if (has_mt_coordinates) {
|
if (has_mt_coordinates) {
|
||||||
@ -267,34 +262,6 @@ static bool test_pointers(sd_device *dev,
|
|||||||
if (is_mouse && id->bustype == BUS_I2C)
|
if (is_mouse && id->bustype == BUS_I2C)
|
||||||
is_pointing_stick = true;
|
is_pointing_stick = true;
|
||||||
|
|
||||||
/* Joystick un-detection. Some keyboards have random joystick buttons
|
|
||||||
* set. Avoid those being labeled as ID_INPUT_JOYSTICK with some heuristics.
|
|
||||||
* The well-known keys represent a (randomly picked) set of key groups.
|
|
||||||
* A joystick may have one of those but probably not several. And a joystick with less than 2 buttons
|
|
||||||
* or axes is not a joystick either.
|
|
||||||
* libinput uses similar heuristics, any changes here should be added to libinput too.
|
|
||||||
*/
|
|
||||||
if (is_joystick) {
|
|
||||||
static const unsigned int well_known_keyboard_keys[] = {
|
|
||||||
KEY_LEFTCTRL, KEY_CAPSLOCK, KEY_NUMLOCK, KEY_INSERT,
|
|
||||||
KEY_MUTE, KEY_CALC, KEY_FILE, KEY_MAIL, KEY_PLAYPAUSE,
|
|
||||||
KEY_BRIGHTNESSDOWN,
|
|
||||||
};
|
|
||||||
size_t num_well_known_keys = 0;
|
|
||||||
|
|
||||||
if (has_keys)
|
|
||||||
for (size_t i = 0; i < ELEMENTSOF(well_known_keyboard_keys); i++)
|
|
||||||
if (test_bit(well_known_keyboard_keys[i], bitmask_key))
|
|
||||||
num_well_known_keys++;
|
|
||||||
|
|
||||||
if (num_well_known_keys >= 4 || num_joystick_buttons + num_joystick_axes < 2) {
|
|
||||||
log_device_debug(dev, "Input device has %zd joystick buttons and %zd axes but also %zd keyboard key sets, "
|
|
||||||
"assuming this is a keyboard, not a joystick.",
|
|
||||||
num_joystick_buttons, num_joystick_axes, num_well_known_keys);
|
|
||||||
is_joystick = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_pointing_stick)
|
if (is_pointing_stick)
|
||||||
udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "1");
|
udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "1");
|
||||||
if (is_mouse || is_abs_mouse)
|
if (is_mouse || is_abs_mouse)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user