From d60ef5265063914ca1502e56f77fd7d70e975da3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 29 Jul 2011 03:08:49 +0200 Subject: [PATCH] sd-login: return size of arrays as return value in functions that generate an array --- src/sd-login.c | 76 ++++++++++++++++++++++++------------------------ src/sd-login.h | 24 ++++++++++----- src/test-login.c | 55 +++++++++++++++++++++++++---------- src/util.c | 49 ++++++++++++++++++------------- 4 files changed, 121 insertions(+), 83 deletions(-) diff --git a/src/sd-login.c b/src/sd-login.c index d44a1fcf..2489d78c 100644 --- a/src/sd-login.c +++ b/src/sd-login.c @@ -251,9 +251,6 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { char **a; int r; - if (!array) - return -EINVAL; - if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0) return -ENOMEM; @@ -266,7 +263,8 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { free(s); if (r == -ENOENT) { - *array = NULL; + if (array) + *array = NULL; return 0; } @@ -274,7 +272,8 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { } if (!s) { - *array = NULL; + if (array) + *array = NULL; return 0; } @@ -284,8 +283,15 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { if (!a) return -ENOMEM; - *array = a; - return 0; + strv_uniq(a); + r = strv_length(a); + + if (array) + *array = a; + else + strv_free(a); + + return r; } _public_ int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions) { @@ -445,9 +451,6 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui if (!seat) return -EINVAL; - if (!sessions && !uids) - return -EINVAL; - p = strappend("/run/systemd/seats/", seat); if (!p) return -ENOMEM; @@ -464,7 +467,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui return r; } - if (sessions && s) { + if (s) { a = strv_split(s, " "); if (!a) { free(s); @@ -510,8 +513,12 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui free(t); + r = strv_length(a); + if (sessions) *sessions = a; + else + strv_free(a); if (uids) *uids = b; @@ -519,7 +526,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui if (n_uids) *n_uids = n; - return 0; + return r; } _public_ int sd_seat_can_multi_session(const char *seat) { @@ -553,18 +560,10 @@ _public_ int sd_seat_can_multi_session(const char *seat) { } _public_ int sd_get_seats(char ***seats) { - - if (!seats) - return -EINVAL; - return get_files_in_directory("/run/systemd/seats/", seats); } _public_ int sd_get_sessions(char ***sessions) { - - if (!sessions) - return -EINVAL; - return get_files_in_directory("/run/systemd/sessions/", sessions); } @@ -574,9 +573,6 @@ _public_ int sd_get_uids(uid_t **users) { unsigned n = 0; uid_t *l = NULL; - if (!users) - return -EINVAL; - d = opendir("/run/systemd/users/"); for (;;) { struct dirent buffer, *de; @@ -601,30 +597,34 @@ _public_ int sd_get_uids(uid_t **users) { if (k < 0) continue; - if ((unsigned) r >= n) { - uid_t *t; + if (users) { + if ((unsigned) r >= n) { + uid_t *t; - n = MAX(16, 2*r); - t = realloc(l, sizeof(uid_t) * n); - if (!t) { - r = -ENOMEM; - goto finish; - } + n = MAX(16, 2*r); + t = realloc(l, sizeof(uid_t) * n); + if (!t) { + r = -ENOMEM; + goto finish; + } - l = t; - } + l = t; + } - assert((unsigned) r < n); - l[r++] = uid; + assert((unsigned) r < n); + l[r++] = uid; + } else + r++; } finish: if (d) closedir(d); - if (r >= 0) - *users = l; - else + if (r >= 0) { + if (users) + *users = l; + } else free(l); return r; diff --git a/src/sd-login.h b/src/sd-login.h index 1623a7db..7102eb88 100644 --- a/src/sd-login.h +++ b/src/sd-login.h @@ -32,7 +32,8 @@ * * Free the data we return with libc free(). * - * We return error codes as negative errno, kernel-style. + * We return error codes as negative errno, kernel-style. 0 or + * positive on success. * * These functions access data in /proc, /sys/fs/cgroup and /run. All * of these are virtual file systems, hence the accesses are @@ -59,12 +60,14 @@ int sd_uid_get_state(uid_t uid, char**state); * look for active sessions only. */ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat); -/* Return sessions of user. If require_active is true will look - * for active sessions only. */ +/* Return sessions of user. If require_active is true will look for + * active sessions only. Returns number of sessions as return + * value. If sessions is NULL will just return number of sessions. */ int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions); /* Return seats of user is on. If require_active is true will look for - * active seats only. */ + * active seats only. Returns number of seats. If seats is NULL will + * just return number of seats.*/ int sd_uid_get_seats(uid_t uid, int require_active, char ***seats); /* Return 1 if the session is a active */ @@ -79,19 +82,24 @@ int sd_session_get_seat(const char *session, char **seat); /* Return active session and user of seat */ int sd_seat_get_active(const char *seat, char **session, uid_t *uid); -/* Return sessions and users on seat */ +/* Return sessions and users on seat. Returns number of sessions as + * return value. If sessions is NULL returs only the number of + * sessions. */ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uid, unsigned *n_uids); /* Return whether the seat is multi-session capable */ int sd_seat_can_multi_session(const char *seat); -/* Get all seats */ +/* Get all seats, store in *seats. Returns the number of seats. If + * seats is NULL only returns number of seats. */ int sd_get_seats(char ***seats); -/* Get all sessions */ +/* Get all sessions, store in *seessions. Returns the number of + * sessions. If sessions is NULL only returns number of sessions. */ int sd_get_sessions(char ***sessions); -/* Get all logged in users */ +/* Get all logged in users, store in *users. Returns the number of + * users. If users is NULL only returns the number of users. */ int sd_get_uids(uid_t **users); /* Monitor object */ diff --git a/src/test-login.c b/src/test-login.c index 9cd9c27a..59b46a14 100644 --- a/src/test-login.c +++ b/src/test-login.c @@ -48,18 +48,24 @@ int main(int argc, char* argv[]) { r = sd_uid_get_sessions(u2, false, &sessions); assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("sessions = %s\n", t); free(t); + assert_se(r == sd_uid_get_sessions(u2, false, NULL)); + r = sd_uid_get_seats(u2, false, &seats); assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); printf("seats = %s\n", t); free(t); + assert_se(r == sd_uid_get_seats(u2, false, NULL)); + r = sd_session_is_active(session); assert_se(r >= 0); printf("active = %s\n", yes_no(r)); @@ -88,7 +94,10 @@ int main(int argc, char* argv[]) { printf("session2 = %s\n", session2); printf("uid2 = %lu\n", (unsigned long) u2); - assert_se(sd_seat_get_sessions(seat, &sessions, &uids, &n) >= 0); + r = sd_seat_get_sessions(seat, &sessions, &uids, &n); + assert_se(r >= 0); + printf("n_sessions = %i\n", r); + assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("sessions = %s\n", t); @@ -99,23 +108,35 @@ int main(int argc, char* argv[]) { printf("\n"); free(uids); + assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); + free(session); free(state); free(session2); free(seat); - assert_se(sd_get_seats(&seats) >= 0); + r = sd_get_seats(&seats); + assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); + printf("n_seats = %i\n", r); printf("seats = %s\n", t); free(t); - assert_se(sd_get_sessions(&sessions) >= 0); + assert_se(sd_get_seats(NULL) == r); + + r = sd_get_sessions(&sessions); + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); + printf("n_sessions = %i\n", r); printf("sessions = %s\n", t); free(t); + assert_se(sd_get_sessions(NULL) == r); + r = sd_get_uids(&uids); assert_se(r >= 0); @@ -123,25 +144,27 @@ int main(int argc, char* argv[]) { for (k = 0; k < r; k++) printf(" %lu", (unsigned long) uids[k]); printf("\n"); - free(uids); - r = sd_login_monitor_new("session", &m); - assert_se(r >= 0); + printf("n_uids = %i\n", r); + assert_se(sd_get_uids(NULL) == r); + + /* r = sd_login_monitor_new("session", &m); */ + /* assert_se(r >= 0); */ - zero(pollfd); - pollfd.fd = sd_login_monitor_get_fd(m); - pollfd.events = POLLIN; + /* zero(pollfd); */ + /* pollfd.fd = sd_login_monitor_get_fd(m); */ + /* pollfd.events = POLLIN; */ - for (n = 0; n < 5; n++) { - r = poll(&pollfd, 1, -1); - assert_se(r >= 0); + /* for (n = 0; n < 5; n++) { */ + /* r = poll(&pollfd, 1, -1); */ + /* assert_se(r >= 0); */ - sd_login_monitor_flush(m); - printf("Wake!\n"); - } + /* sd_login_monitor_flush(m); */ + /* printf("Wake!\n"); */ + /* } */ - sd_login_monitor_unref(m); + /* sd_login_monitor_unref(m); */ return 0; } diff --git a/src/util.c b/src/util.c index 45b578bd..cbfac6ec 100644 --- a/src/util.c +++ b/src/util.c @@ -5432,7 +5432,10 @@ int get_files_in_directory(const char *path, char ***list) { char **l = NULL; assert(path); - assert(list); + + /* Returns all files in a directory in *list, and the number + * of files as return value. If list is NULL returns only the + * number */ d = opendir(path); for (;;) { @@ -5453,37 +5456,41 @@ int get_files_in_directory(const char *path, char ***list) { if (!dirent_is_file(de)) continue; - if ((unsigned) r >= n) { - char **t; + if (list) { + if ((unsigned) r >= n) { + char **t; - n = MAX(16, 2*r); - t = realloc(l, sizeof(char*) * n); - if (!t) { - r = -ENOMEM; - goto finish; - } + n = MAX(16, 2*r); + t = realloc(l, sizeof(char*) * n); + if (!t) { + r = -ENOMEM; + goto finish; + } - l = t; - } + l = t; + } - assert((unsigned) r < n); + assert((unsigned) r < n); - l[r] = strdup(de->d_name); - if (!l[r]) { - r = -ENOMEM; - goto finish; - } + l[r] = strdup(de->d_name); + if (!l[r]) { + r = -ENOMEM; + goto finish; + } - l[++r] = NULL; + l[++r] = NULL; + } else + r++; } finish: if (d) closedir(d); - if (r >= 0) - *list = l; - else + if (r >= 0) { + if (list) + *list = l; + } else strv_free(l); return r; -- 2.39.5