X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogin%2Fsd-login.c;h=71d8c2942e192ef3b3e8ec6c52a280daf629afc5;hp=45e3bb8dcd07c03451f106d235bfe8ee96f64b45;hb=4b549144d82ea0f368321d149215f577049fffa6;hpb=7d5e9c0f60cddf01ec803012cbdc02d2f55b78c1 diff --git a/src/login/sd-login.c b/src/login/sd-login.c index 45e3bb8dc..71d8c2942 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -23,114 +23,75 @@ #include #include #include +#include #include "util.h" #include "cgroup-util.h" #include "macro.h" #include "sd-login.h" #include "strv.h" +#include "fileio.h" +#include "login-shared.h" _public_ int sd_pid_get_session(pid_t pid, char **session) { - int r; - char *cgroup, *p; - if (pid < 0) return -EINVAL; if (!session) return -EINVAL; - r = cg_pid_get_cgroup(pid, NULL, &cgroup); - if (r < 0) - return r; - - if (!startswith(cgroup, "/user/")) { - free(cgroup); - return -ENOENT; - } - - p = strchr(cgroup + 6, '/'); - if (!p) { - free(cgroup); - return -ENOENT; - } - - p++; - if (startswith(p, "shared/") || streq(p, "shared")) { - free(cgroup); - return -ENOENT; - } - - p = strndup(p, strcspn(p, "/")); - free(cgroup); - - if (!p) - return -ENOMEM; - - *session = p; - return 0; + return cg_pid_get_session(pid, session); } _public_ int sd_pid_get_unit(pid_t pid, char **unit) { if (pid < 0) return -EINVAL; - if (!unit) return -EINVAL; return cg_pid_get_unit(pid, unit); } -_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { - int r; - char *root, *cgroup, *p, *cc; - struct stat st; +_public_ int sd_pid_get_user_unit(pid_t pid, char **unit) { if (pid < 0) return -EINVAL; - - if (!uid) + if (!unit) return -EINVAL; - r = cg_pid_get_cgroup(pid, &root, &cgroup); - if (r < 0) - return r; + return cg_pid_get_user_unit(pid, unit); +} - if (!startswith(cgroup, "/user/")) { - free(cgroup); - free(root); - return -ENOENT; - } +_public_ int sd_pid_get_machine_name(pid_t pid, char **name) { - p = strchr(cgroup + 6, '/'); - if (!p) { - free(cgroup); - return -ENOENT; - } + if (pid < 0) + return -EINVAL; + if (!name) + return -EINVAL; - p++; - p += strcspn(p, "/"); - *p = 0; + return cg_pid_get_machine_name(pid, name); +} - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, cgroup, &cc); - free(root); - free(cgroup); +_public_ int sd_pid_get_slice(pid_t pid, char **slice) { - if (r < 0) - return -ENOMEM; + if (pid < 0) + return -EINVAL; + if (!slice) + return -EINVAL; - r = lstat(cc, &st); - free(cc); + return cg_pid_get_slice(pid, slice); +} - if (r < 0) - return -errno; +_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { - if (!S_ISDIR(st.st_mode)) - return -ENOTDIR; + if (pid < 0) + return -EINVAL; - *uid = st.st_uid; - return 0; + if (!uid) + return -EINVAL; + + return cg_pid_get_owner_uid(pid, uid); } _public_ int sd_uid_get_state(uid_t uid, char**state) { @@ -165,7 +126,8 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) { } _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) { - char *p, *w, *t, *state, *s = NULL; + char *w, *state; + _cleanup_free_ char *t = NULL, *s = NULL, *p = NULL; size_t l; int r; const char *variable; @@ -180,38 +142,26 @@ _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) return -ENOMEM; r = parse_env_file(p, NEWLINE, variable, &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } if (!s) return -EIO; - if (asprintf(&t, "%lu", (unsigned long) uid) < 0) { - free(s); + if (asprintf(&t, "%lu", (unsigned long) uid) < 0) return -ENOMEM; - } FOREACH_WORD(w, l, s, state) { - if (strncmp(t, w, l) == 0) { - free(s); - free(t); - + if (strneq(t, w, l)) return 1; - } } - free(s); - free(t); - return 0; } static int uid_get_array(uid_t uid, const char *variable, char ***array) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; char **a; int r; @@ -221,11 +171,7 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { r = parse_env_file(p, NEWLINE, variable, &s, NULL); - free(p); - if (r < 0) { - free(s); - if (r == -ENOENT) { if (array) *array = NULL; @@ -242,7 +188,6 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { } a = strv_split(s, " "); - free(s); if (!a) return -ENOMEM; @@ -282,17 +227,19 @@ static int file_of_session(const char *session, char **_p) { assert(_p); - if (session) + if (session) { + if (!session_id_valid(session)) + return -EINVAL; + p = strappend("/run/systemd/sessions/", session); - else { - char *buf; + } else { + _cleanup_free_ char *buf = NULL; r = sd_pid_get_session(0, &buf); if (r < 0) return r; p = strappend("/run/systemd/sessions/", buf); - free(buf); } if (!p) @@ -304,31 +251,26 @@ static int file_of_session(const char *session, char **_p) { _public_ int sd_session_is_active(const char *session) { int r; - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; r = file_of_session(session, &p); if (r < 0) return r; r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL); - free(p); - - if (r < 0) { - free(s); + if (r < 0) return r; - } if (!s) return -EIO; r = parse_boolean(s); - free(s); return r; } _public_ int sd_session_get_state(const char *session, char **state) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; int r; if (!state) @@ -339,21 +281,21 @@ _public_ int sd_session_get_state(const char *session, char **state) { return r; r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } else if (!s) + else if (!s) return -EIO; *state = s; + s = NULL; + return 0; } _public_ int sd_session_get_uid(const char *session, uid_t *uid) { int r; - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; if (!uid) return -EINVAL; @@ -363,24 +305,20 @@ _public_ int sd_session_get_uid(const char *session, uid_t *uid) { return r; r = parse_env_file(p, NEWLINE, "UID", &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } if (!s) return -EIO; r = parse_uid(s, uid); - free(s); return r; } static int session_get_string(const char *session, const char *field, char **value) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; int r; if (!value) @@ -391,17 +329,15 @@ static int session_get_string(const char *session, const char *field, char **val return r; r = parse_env_file(p, NEWLINE, field, &s, NULL); - free(p); - if (r < 0) { - free(s); + if (r < 0) return r; - } if (isempty(s)) return -ENOENT; *value = s; + s = NULL; return 0; } @@ -409,6 +345,27 @@ _public_ int sd_session_get_seat(const char *session, char **seat) { return session_get_string(session, "SEAT", seat); } +_public_ int sd_session_get_tty(const char *session, char **tty) { + return session_get_string(session, "TTY", tty); +} + +_public_ int sd_session_get_vt(const char *session, unsigned *vtnr) { + _cleanup_free_ char *vtnr_string; + unsigned u; + int r; + + r = session_get_string(session, "VTNr", &vtnr_string); + if (r < 0) + return r; + + r = safe_atou(vtnr_string, &u); + if (r < 0) + return r; + + *vtnr = u; + return 0; +} + _public_ int sd_session_get_service(const char *session, char **service) { return session_get_string(session, "SERVICE", service); } @@ -434,25 +391,25 @@ static int file_of_seat(const char *seat, char **_p) { if (seat) p = strappend("/run/systemd/seats/", seat); else { - char *buf; + _cleanup_free_ char *buf = NULL; r = sd_session_get_seat(NULL, &buf); if (r < 0) return r; p = strappend("/run/systemd/seats/", buf); - free(buf); } if (!p) return -ENOMEM; *_p = p; + p = NULL; return 0; } _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { - char *p, *s = NULL, *t = NULL; + _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL; int r; if (!session && !uid) @@ -466,46 +423,33 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { "ACTIVE", &s, "ACTIVE_UID", &t, NULL); - free(p); - - if (r < 0) { - free(s); - free(t); + if (r < 0) return r; - } - if (session && !s) { - free(t); + if (session && !s) return -ENOENT; - } - if (uid && !t) { - free(s); + if (uid && !t) return -ENOENT; - } if (uid && t) { r = parse_uid(t, uid); - if (r < 0) { - free(t); - free(s); + if (r < 0) return r; - } } - free(t); - - if (session && s) + if (session && s) { *session = s; - else - free(s); + s = NULL; + } return 0; } _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) { - char *p, *s = NULL, *t = NULL, **a = NULL; - uid_t *b = NULL; + _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL; + _cleanup_strv_free_ char **a = NULL; + _cleanup_free_ uid_t *b = NULL; unsigned n = 0; int r; @@ -517,25 +461,16 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui "SESSIONS", &s, "ACTIVE_SESSIONS", &t, NULL); - free(p); - if (r < 0) { - free(s); - free(t); + if (r < 0) return r; - } if (s) { a = strv_split(s, " "); - if (!a) { - free(s); - free(t); + if (!a) return -ENOMEM; - } } - free(s); - if (uids && t) { char *w, *state; size_t l; @@ -543,30 +478,22 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui FOREACH_WORD(w, l, t, state) n++; - if (n == 0) - b = NULL; - else { + if (n > 0) { unsigned i = 0; b = new(uid_t, n); - if (!b) { - strv_free(a); + if (!b) return -ENOMEM; - } FOREACH_WORD(w, l, t, state) { - char *k; + _cleanup_free_ char *k = NULL; k = strndup(w, l); - if (!k) { - free(t); - free(b); - strv_free(a); + if (!k) return -ENOMEM; - } r = parse_uid(k, b + i); - free(k); + if (r < 0) continue; @@ -575,17 +502,17 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui } } - free(t); - r = strv_length(a); - if (sessions) + if (sessions) { *sessions = a; - else - strv_free(a); + a = NULL; + } - if (uids) + if (uids) { *uids = b; + b = NULL; + } if (n_uids) *n_uids = n; @@ -594,7 +521,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui } static int seat_get_can(const char *seat, const char *variable) { - char *p, *s = NULL; + _cleanup_free_ char *p = NULL, *s = NULL; int r; r = file_of_seat(seat, &p); @@ -604,17 +531,12 @@ static int seat_get_can(const char *seat, const char *variable) { r = parse_env_file(p, NEWLINE, variable, &s, NULL); - free(p); - - if (r < 0) { - free(s); + if (r < 0) return r; - } - if (s) { + if (s) r = parse_boolean(s); - free(s); - } else + else r = 0; return r; @@ -641,10 +563,10 @@ _public_ int sd_get_sessions(char ***sessions) { } _public_ int sd_get_uids(uid_t **users) { - DIR *d; + _cleanup_closedir_ DIR *d; int r = 0; unsigned n = 0; - uid_t *l = NULL; + _cleanup_free_ uid_t *l = NULL; d = opendir("/run/systemd/users/"); if (!d) @@ -657,10 +579,8 @@ _public_ int sd_get_uids(uid_t **users) { uid_t uid; k = readdir_r(d, &buf.de, &de); - if (k != 0) { - r = -k; - goto finish; - } + if (k != 0) + return -k; if (!de) break; @@ -680,10 +600,8 @@ _public_ int sd_get_uids(uid_t **users) { n = MAX(16, 2*r); t = realloc(l, sizeof(uid_t) * n); - if (!t) { - r = -ENOMEM; - goto finish; - } + if (!t) + return -ENOMEM; l = t; } @@ -694,19 +612,18 @@ _public_ int sd_get_uids(uid_t **users) { r++; } -finish: - if (d) - closedir(d); - - if (r >= 0) { - if (users) - *users = l; - } else - free(l); + if (users) { + *users = l; + l = NULL; + } return r; } +_public_ int sd_get_machine_names(char ***machines) { + return get_files_in_directory("/run/systemd/machines/", machines); +} + static inline int MONITOR_TO_FD(sd_login_monitor *m) { return (int) (unsigned long) m - 1; } @@ -724,7 +641,7 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) { fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); if (fd < 0) - return errno; + return -errno; if (!category || streq(category, "seat")) { k = inotify_add_watch(fd, "/run/systemd/seats/", IN_MOVED_TO|IN_DELETE); @@ -756,6 +673,16 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) { good = true; } + if (!category || streq(category, "machine")) { + k = inotify_add_watch(fd, "/run/systemd/machines/", IN_MOVED_TO|IN_DELETE); + if (k < 0) { + close_nointr_nofail(fd); + return -errno; + } + + good = true; + } + if (!good) { close_nointr(fd); return -EINVAL; @@ -792,3 +719,29 @@ _public_ int sd_login_monitor_get_fd(sd_login_monitor *m) { return MONITOR_TO_FD(m); } + +_public_ int sd_login_monitor_get_events(sd_login_monitor *m) { + + if (!m) + return -EINVAL; + + /* For now we will only return POLLIN here, since we don't + * need anything else ever for inotify. However, let's have + * this API to keep our options open should we later on need + * it. */ + return POLLIN; +} + +_public_ int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec) { + + if (!m) + return -EINVAL; + if (!timeout_usec) + return -EINVAL; + + /* For now we will only return (uint64_t) -1, since we don't + * need any timeout. However, let's have this API to keep our + * options open should we later on need it. */ + *timeout_usec = (uint64_t) -1; + return 0; +}