with this the double linked list feature from util-linux is used instead of the single linked list. Signed-off-by: Werner Fink <werner@xxxxxxx> --- include/consoles.h | 6 ++-- lib/consoles.c | 77 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git include/consoles.h include/consoles.h index 2283d02..2544263 100644 --- include/consoles.h +++ include/consoles.h @@ -2,6 +2,7 @@ * consoles.h Header file for routines to detect the system consoles * * Copyright (c) 2011 SuSE LINUX Products GmbH, All rights reserved. + * Copyright (c) 2012 Werner Fink <werner@xxxxxxx> * * 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 @@ -25,6 +26,7 @@ #include <stdint.h> #include <stdio.h> #include <termios.h> +#include <list.h> struct chardata { uint8_t erase; @@ -33,6 +35,7 @@ struct chardata { uint8_t parity; }; struct console { + struct list_head entry; char *tty; FILE *file; uint32_t flags; @@ -42,8 +45,7 @@ struct console { pid_t pid; struct chardata cp; struct termios tio; - struct console *next; }; extern int detect_consoles(const char *device, int fallback, - struct console **consoles); + struct list_head *consoles); diff --git lib/consoles.c lib/consoles.c index 7bc21b6..38c8208 100644 --- lib/consoles.c +++ lib/consoles.c @@ -3,6 +3,7 @@ * * Copyright (c) 2011 SuSE LINUX Products GmbH, All rights reserved. * Copyright (C) 2012 Karel Zak <kzak@xxxxxxxxxx> + * Copyright (C) 2012 Werner Fink <werner@xxxxxxx> * * 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, @@ -210,16 +212,21 @@ int append_console(struct console **list, char * name) }; struct console *restrict tail; struct console *last; + + if (list_empty(consoles)) + last = NULL; + else + last = list_entry(consoles->prev, struct console, entry); DBG(dbgprint("appenging %s", name)); - if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0) + if (posix_memalign((void*)&tail, sizeof(void*), + alignof(struct console)+strsize(name)) != 0) return -ENOMEM; - for (last = *list; last && last->next; last = last->next); - - 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_entry(consoles->prev, 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_entry(consoles->prev, struct console, entry); + if (console) + console->fd = fallback; } DBG(dbgprint("detection done by fallback [rc=%d]", reconnect)); @@ -667,7 +682,7 @@ int main(int argc, char *argv[]) { char *name = NULL; int fd, re; - struct console *p, *consoles = NULL; + struct list_head *p, consoles = {&consoles, &consoles}; if (argc == 2) { name = argv[1]; @@ -682,8 +697,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; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html