From cae29b3717dc08899faaa0adff818fe63a2c88b7 Mon Sep 17 00:00:00 2001 From: Werner Fink Date: Tue, 18 Dec 2012 15:02:35 +0100 Subject: sulogin: use the linked lists from list.h for consoles list with this the double linked list feature from util-linux is used instead of the single linked list. [kzak@redhat.com: use list_last_entry() and list INIT macros] Signed-off-by: Werner Fink Signed-off-by: Karel Zak --- lib/consoles.c | 78 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 30 deletions(-) (limited to 'lib/consoles.c') diff --git a/lib/consoles.c b/lib/consoles.c index 7bc21b61c..21c5a249a 100644 --- a/lib/consoles.c +++ b/lib/consoles.c @@ -3,6 +3,7 @@ * * Copyright (c) 2011 SuSE LINUX Products GmbH, All rights reserved. * Copyright (C) 2012 Karel Zak + * Copyright (C) 2012 Werner Fink * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,6 +57,7 @@ #endif #define alignof(type) ((sizeof(type)+(sizeof(void*)-1)) & ~(sizeof(void*)-1)) +#define strsize(string) (strlen((string))+1) static int consoles_debug; #define DBG(x) do { \ @@ -200,7 +202,7 @@ static #ifdef __GNUC__ __attribute__((__nonnull__,__hot__)) #endif -int append_console(struct console **list, char * name) +int append_console(struct list_head *consoles, const char *name) { static const struct chardata initcp = { .erase = CERASE, @@ -209,17 +211,22 @@ int append_console(struct console **list, char * name) .parity = 0 }; struct console *restrict tail; - struct console *last; + struct console *last = NULL; DBG(dbgprint("appenging %s", name)); - if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0) + if (!list_empty(consoles)) + last = list_last_entry(consoles, struct console, entry); + + if (posix_memalign((void *) &tail, sizeof(void *), + alignof(struct console) + strsize(name)) != 0) return -ENOMEM; - for (last = *list; last && last->next; last = last->next); + INIT_LIST_HEAD(&tail->entry); - tail->next = NULL; - tail->tty = name; + list_add_tail(&tail->entry, consoles); + tail->tty = ((char *) tail) + alignof(struct console); + strcpy(tail->tty, name); tail->file = (FILE*)0; tail->flags = 0; @@ -229,11 +236,6 @@ int append_console(struct console **list, char * name) memset(&tail->tio, 0, sizeof(tail->tio)); memcpy(&tail->cp, &initcp, sizeof(struct chardata)); - if (!last) - *list = tail; - else - last->next = tail; - return 0; } @@ -245,7 +247,7 @@ int append_console(struct console **list, char * name) * 1 - recoverable error * 2 - detection not available */ -static int detect_consoles_from_proc(struct console **consoles) +static int detect_consoles_from_proc(struct list_head *consoles) { char fbuf[16 + 1]; DIR *dir = NULL; @@ -274,11 +276,12 @@ static int detect_consoles_from_proc(struct console **consoles) if (!name) continue; rc = append_console(consoles, name); + free(name); if (rc < 0) goto done; } - rc = *consoles ? 0 : 1; + rc = list_empty(consoles) ? 1 : 0; done: if (dir) closedir(dir); @@ -295,7 +298,7 @@ done: * 1 - recoverable error * 2 - detection not available */ -static int detect_consoles_from_sysfs(struct console **consoles) +static int detect_consoles_from_sysfs(struct list_head *consoles) { char *attrib = NULL, *words, *token; DIR *dir = NULL; @@ -335,11 +338,12 @@ static int detect_consoles_from_sysfs(struct console **consoles) if (!name) continue; rc = append_console(consoles, name); + free(name); if (rc < 0) goto done; } - rc = *consoles ? 0 : 1; + rc = list_empty(consoles) ? 1 : 0; done: free(attrib); if (dir) @@ -349,7 +353,7 @@ done: } -static int detect_consoles_from_cmdline(struct console **consoles) +static int detect_consoles_from_cmdline(struct list_head *consoles) { char *cmdline, *words, *token; dev_t comparedev; @@ -422,11 +426,12 @@ static int detect_consoles_from_cmdline(struct console **consoles) if (!name) continue; rc = append_console(consoles, name); + free(name); if (rc < 0) goto done; } - rc = *consoles ? 0 : 1; + rc = list_empty(consoles) ? 1 : 0; done: if (dir) closedir(dir); @@ -435,7 +440,7 @@ done: return rc; } -static int detect_consoles_from_tiocgdev(struct console **consoles, +static int detect_consoles_from_tiocgdev(struct list_head *consoles, int fallback, const char *device) { @@ -445,6 +450,7 @@ static int detect_consoles_from_tiocgdev(struct console **consoles, int rc = 1, fd = -1; dev_t comparedev; DIR *dir = NULL; + struct console *console; DBG(dbgprint("trying tiocgdev")); @@ -478,12 +484,16 @@ static int detect_consoles_from_tiocgdev(struct console **consoles, } } rc = append_console(consoles, name); + free(name); if (rc < 0) goto done; - if (*consoles && (!device || !*device)) - (*consoles)->fd = fallback; - - rc = *consoles ? 0 : 1; + if (list_empty(consoles)) { + rc = 1; + goto done; + } + console = list_last_entry(consoles, struct console, entry); + if (console && (!device || !*device)) + console->fd = fallback; done: if (fd >= 0) close(fd); @@ -503,7 +513,7 @@ done: * Returns 1 if stdout and stderr should be reconnected and 0 * otherwise or less than zero on error. */ -int detect_consoles(const char *device, int fallback, struct console **consoles) +int detect_consoles(const char *device, int fallback, struct list_head *consoles) { int fd, reconnect = 0, rc; dev_t comparedev = 0; @@ -581,10 +591,11 @@ int detect_consoles(const char *device, int fallback, struct console **consoles) if (name) { rc = append_console(consoles, name); + free(name); if (rc < 0) return rc; } - if (!*consoles) + if (list_empty(consoles)) goto fallback; DBG(dbgprint("detection success [rc=%d]", reconnect)); @@ -632,7 +643,7 @@ console: if (rc < 0) return rc; /* fatal error */ - if (*consoles) { + if (!list_empty(consoles)) { DBG(dbgprint("detection success [rc=%d]", reconnect)); return reconnect; } @@ -642,6 +653,7 @@ console: fallback: if (fallback >= 0) { const char *name; + struct console *console; if (device && *device != '\0') name = device; @@ -653,8 +665,11 @@ fallback: rc = append_console(consoles, strdup(name)); if (rc < 0) return rc; - if (*consoles) - (*consoles)->fd = fallback; + if (list_empty(consoles)) + return 1; + console = list_last_entry(consoles, struct console, entry); + if (console) + console->fd = fallback; } DBG(dbgprint("detection done by fallback [rc=%d]", reconnect)); @@ -667,7 +682,8 @@ int main(int argc, char *argv[]) { char *name = NULL; int fd, re; - struct console *p, *consoles = NULL; + LIST_HEAD(consoles); + struct list_head *p; if (argc == 2) { name = argv[1]; @@ -682,8 +698,10 @@ int main(int argc, char *argv[]) re = detect_consoles(name, fd, &consoles); - for (p = consoles; p; p = p->next) - printf("%s: id=%d %s\n", p->tty, p->id, re ? "(reconnect) " : ""); + list_for_each(p, &consoles) { + struct console *c = list_entry(p, struct console, entry); + printf("%s: id=%d %s\n", c->tty, c->id, re ? "(reconnect) " : ""); + } return 0; } -- cgit v1.2.3-55-g7522