<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2016 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd-bus" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_creds_get_pid" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_creds_new_from_pid" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_default" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_error" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_message_append"
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_message_append_array"
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_message_append_basic" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_message_append_string_memfd"
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_message_append_strv"
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_new" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_bus_path_encode">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_event_add_child" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_event_add_defer" xmlns:xi="http://www.w3.org/2001/XInclude">
</refsect1>
<xi:include href="libelogind-pkgconfig.xml" />
+ <refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>A simple program that uses inotify to monitor one or two directories</title>
+
+ <programlisting><xi:include href="inotify-watch-tmp.c" parse="text" /></programlisting>
+ </example>
+ </refsect1>
+
<refsect1>
<title>See Also</title>
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_event_add_signal" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_event_get_fd" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2015 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_event_run" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2014 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_event_source_set_description" xmlns:xi="http://www.w3.org/2001/XInclude">
<!--
SPDX-License-Identifier: LGPL-2.1+
-
- Copyright © 2015 Zbigniew Jędrzejewski-Szmek
-->
<refentry id="sd_event_wait" xmlns:xi="http://www.w3.org/2001/XInclude">
#else
p = strappend("/run/systemd/sessions/", slice);
- r = parse_env_file(p, NEWLINE, "UID", &s, NULL);
+ r = parse_env_file(NULL, p, NEWLINE, "UID", &s, NULL);
if (r == -ENOENT)
return -ENXIO;
if (r < 0)
}
int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags) {
- _cleanup_free_ char *t = NULL;
+ _cleanup_(unlink_and_freep) char *t = NULL;
+ _cleanup_close_ int fdt = -1;
int r;
assert(from);
assert(to);
- r = tempfn_random(to, NULL, &t);
- if (r < 0)
- return r;
+ /* We try to use O_TMPFILE here to create the file if we can. Note that that only works if COPY_REPLACE is not
+ * set though as we need to use linkat() for linking the O_TMPFILE file into the file system but that system
+ * call can't replace existing files. Hence, if COPY_REPLACE is set we create a temporary name in the file
+ * system right-away and unconditionally which we then can renameat() to the right name after we completed
+ * writing it. */
+
+ if (copy_flags & COPY_REPLACE) {
+ r = tempfn_random(to, NULL, &t);
+ if (r < 0)
+ return r;
+
+ fdt = open(t, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
+ if (fdt < 0) {
+ t = mfree(t);
+ return -errno;
+ }
+ } else {
+ fdt = open_tmpfile_linkable(to, O_WRONLY|O_CLOEXEC, &t);
+ if (fdt < 0)
+ return fdt;
+ }
- r = copy_file(from, t, O_NOFOLLOW|O_EXCL, mode, chattr_flags, copy_flags);
+ if (chattr_flags != 0)
+ (void) chattr_fd(fdt, chattr_flags, (unsigned) -1);
+
+ r = copy_file_fd(from, fdt, copy_flags);
if (r < 0)
return r;
+ if (fchmod(fdt, mode) < 0)
+ return -errno;
+
if (copy_flags & COPY_REPLACE) {
- r = renameat(AT_FDCWD, t, AT_FDCWD, to);
+ if (renameat(AT_FDCWD, t, AT_FDCWD, to) < 0)
+ return -errno;
+ } else {
+ r = link_tmpfile(fdt, t, to);
if (r < 0)
- r = -errno;
- } else
- r = rename_noreplace(AT_FDCWD, t, AT_FDCWD, to);
- if (r < 0) {
- (void) unlink(t);
- return r;
+ return r;
}
+ t = mfree(t);
return 0;
}
}
int mkdtemp_malloc(const char *template, char **ret) {
- char *p;
+ _cleanup_free_ char *p = NULL;
+ int r;
- assert(template);
assert(ret);
- p = strdup(template);
+ if (template)
+ p = strdup(template);
+ else {
+ const char *tmp;
+
+ r = tmp_dir(&tmp);
+ if (r < 0)
+ return r;
+
+ p = strjoin(tmp, "/XXXXXX");
+ }
if (!p)
return -ENOMEM;
- if (!mkdtemp(p)) {
- free(p);
+ if (!mkdtemp(p))
return -errno;
- }
- *ret = p;
+ *ret = TAKE_PTR(p);
return 0;
}
#endif // 0
return 0;
}
+int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) {
+ /* Under the assumption that we are running privileged we
+ * first change the access mode and only then hand out
+ * ownership to avoid a window where access is too open. */
+
+ if (mode != MODE_INVALID)
+ if (fchmod(fd, mode) < 0)
+ return -errno;
+
+ if (uid != UID_INVALID || gid != GID_INVALID)
+ if (fchown(fd, uid, gid) < 0)
+ return -errno;
+
+ return 0;
+}
+
int fchmod_umask(int fd, mode_t m) {
mode_t u;
int r;
#endif // 0
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
+int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid);
int fchmod_umask(int fd, mode_t mode);
int fchmod_opath(int fd, mode_t m);
/* Structured logging */
#define log_struct_errno(level, error, ...) \
log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
- error, __FILE__, __LINE__, __func__, __VA_ARGS__)
error, __FILE__, __LINE__, __func__, __VA_ARGS__, NULL)
#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
#include <sys/types.h>
#include "macro.h"
-//#include "label.h"
+#include "label.h"
bool mac_selinux_use(void);
void mac_selinux_retest(void);
#endif
}
+#if 0 /// UNNEEDED by elogind
int putpwent_sane(const struct passwd *pw, FILE *stream) {
assert(pw);
assert(stream);
return !!s;
}
#endif
+#endif // 0
bool synthesize_nobody(void);
+#if 0 /// UNNEEDED by elogind
int fgetpwent_sane(FILE *stream, struct passwd **pw);
int fgetspent_sane(FILE *stream, struct spwd **sp);
int fgetgrent_sane(FILE *stream, struct group **gr);
int fgetsgent_sane(FILE *stream, struct sgrp **sg);
int putsgent_sane(const struct sgrp *sg, FILE *stream);
#endif
+#endif // 0
-# This file is part of elogind.
# SPDX-License-Identifier: LGPL-2.1+
#
-# elogind is free software; you can redistribute it and/or modify it
+# This file is part of elogind.
#
+# elogind is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
const char *target;
target = manager_target_for_action(handle);
+#if 0 /// elogind does not support systemd units units. A valid handle is enough
if (target) {
_cleanup_free_ char *load_state = NULL;
return r;
if (!streq(load_state, "loaded")) {
+#else
+ if (NULL == target) {
+#endif // 0
result = "no";
goto finish;
+#if 0 /// one less with elogind...
}
+#endif // 0
}
}
%struct-type
%includes
%%
-#if 0 /// UNNEEDED by elogind
-#endif // 0
#if 1 /// Additions for elogind
Sleep.SuspendMode, config_parse_strv, 0, offsetof(Manager, suspend_mode)
Sleep.SuspendState, config_parse_strv, 0, offsetof(Manager, suspend_state)
Sleep.HybridSleepMode, config_parse_strv, 0, offsetof(Manager, hybrid_sleep_mode)
Sleep.HybridSleepState, config_parse_strv, 0, offsetof(Manager, hybrid_sleep_state)
#endif // 1
-Login.NAutoVTs, config_parse_n_autovts, 0, offsetof(Manager, n_autovts)
-Login.ReserveVT, config_parse_unsigned, 0, offsetof(Manager, reserve_vt)
+#if 0 /// UNNEEDED by elogind
+# Login.NAutoVTs, config_parse_n_autovts, 0, offsetof(Manager, n_autovts)
+# Login.ReserveVT, config_parse_unsigned, 0, offsetof(Manager, reserve_vt)
+#endif // 0
Login.KillUserProcesses, config_parse_bool, 0, offsetof(Manager, kill_user_processes)
Login.KillOnlyUsers, config_parse_strv, 0, offsetof(Manager, kill_only_users)
Login.KillExcludeUsers, config_parse_strv, 0, offsetof(Manager, kill_exclude_users)
}
-#if 0 /// elogind can not ask systemd via dbus to start user services
-#else
- assert(u);
-
- hashmap_put(u->manager->user_units, u->slice, u);
-#endif // 0
static int user_start_service(User *u) {
#if 0 /// elogind can not ask systemd via dbus to start user services
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
#include <inttypes.h>
#include <signal.h>
#include <sys/epoll.h>
-//#include <sys/inotify.h>
+#include <sys/inotify.h>
#include <sys/signalfd.h>
#include <sys/types.h>
/*#include <time.h>*/
}
}
+static int callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+ return 1;
+}
+
+static void destroy_callback(void *userdata) {
+ int *n_called = userdata;
+
+ (*n_called) ++;
+}
+
+static void test_destroy_callback(void) {
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ sd_bus_slot *slot = NULL;
+ sd_bus_destroy_t t;
+
+ int r, n_called = 0;
+
+ log_info("/* %s */", __func__);
+
+ r = bus_open_system_watch_bind_with_description(&bus, "test-bus");
+ if (r < 0) {
+ log_error_errno(r, "Failed to connect to bus: %m");
+ return;
+ }
+
+ r = sd_bus_request_name_async(bus, &slot, "org.freedesktop.elogind.test-bus-util", 0, callback, &n_called);
+ assert(r == 1);
+
+ assert_se(sd_bus_slot_get_destroy_callback(slot, NULL) == 0);
+ assert_se(sd_bus_slot_get_destroy_callback(slot, &t) == 0);
+
+ assert_se(sd_bus_slot_set_destroy_callback(slot, destroy_callback) == 0);
+ assert_se(sd_bus_slot_get_destroy_callback(slot, NULL) == 1);
+ assert_se(sd_bus_slot_get_destroy_callback(slot, &t) == 1);
+ assert_se(t == destroy_callback);
+
+ /* Force cleanup so we can look at n_called */
+ assert(n_called == 0);
+ sd_bus_slot_unref(slot);
+ assert(n_called == 1);
+}
+
int main(int argc, char **argv) {
log_set_max_level(LOG_DEBUG);
log_parse_environment();
test_name_async(0);
test_name_async(20);
+ test_destroy_callback();
return 0;
}
}
}
+#if 0 /// UNNEEDED by elogind
static void test_fd_duplicate_data_fd(void) {
_cleanup_close_ int fd1 = -1, fd2 = -1;
_cleanup_(close_pairp) int sfd[2] = { -1, -1 };
assert_se(read(fd2, &j, sizeof(j)) == 0);
}
+#endif // 0
static void test_read_nr_open(void) {
log_info("nr-open: %i", read_nr_open());
test_acquire_data_fd();
test_fd_move_above_stdio();
test_rearrange_stdio();
+#if 0 /// UNNEEDED by elogind
test_fd_duplicate_data_fd();
+#endif // 0
test_read_nr_open();
return 0;
assert_se(streq(delete_trailing_chars(s4, "/"), ""));
}
-#if 0 /// UNNEEDED by elogind
static void test_skip_leading_chars(void) {
char input1[] = " \n \r k \n \r ",
input2[] = "kkkkthiskkkiskkkaktestkkk",
assert_se(streq(skip_leading_chars(input3, WHITESPACE), "abcdef"));
assert_se(streq(skip_leading_chars(input3, "bcaef"), "def"));
}
-#endif // 0
static void test_in_charset(void) {
assert_se(in_charset("dddaaabbbcccc", "abcd"));
#endif // 0
test_delete_trailing_chars();
test_delete_trailing_slashes();
-#if 0 /// UNNEEDED by elogind
test_skip_leading_chars();
-#endif // 0
test_in_charset();
test_split_pair();
test_first_word();
#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
# SPDX-License-Identifier: LGPL-2.1+
-#
-# Copyright © 2012-2013 Zbigniew Jędrzejewski-Szmek
import sys
import collections
#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
# SPDX-License-Identifier: LGPL-2.1+
-#
-# Copyright © 2013 Zbigniew Jędrzejewski-Szmek
import collections
import sys