* Add code to detect the system consoles with the help of the
authorDr. Werner Fink <werner@suse.de>
Fri, 11 Mar 2011 17:29:36 +0000 (17:29 +0000)
committerDr. Werner Fink <werner@suse.de>
Fri, 11 Mar 2011 17:29:36 +0000 (17:29 +0000)
  new /proc/consoles files of linux kernel 2.6.38+

git-svn-id: svn://svn.sv.gnu.org/sysvinit/sysvinit/trunk@100 456724a4-4300-0410-8514-c89748c515a2

doc/Changelog
src/Makefile
src/consoles.c [new file with mode: 0644]
src/consoles.h [new file with mode: 0644]

index bb68e111147d867c4122cddc030f80399ecb4cad..50e67e7f846ef35ad0f35d8230d30887c617c63d 100644 (file)
@@ -1,6 +1,8 @@
 sysvinit (2.89dsf) UNRELEASED; urgency=low
 
   [ Werner Fink ]
+  * Add code to detect the system consoles with the help of the
+    new /proc/consoles files of linux kernel 2.6.38+
   * Try to make utmpdump IPv6 valid, change based on suggestion from
     Navdeep Bhatia (see local bug #32429)
   * Fix signal and alarm handling based on the patch from Florent Viard.
index 19675c5293c2d697583aaed95312dd462131a99a..6c04f55bb9282c5ca0ad025fb451e3869c4856fa 100644 (file)
@@ -134,6 +134,8 @@ halt.o:             halt.c reboot.h
 
 last.o:                last.c oldutmp.h
 
+consoles.o:    consoles.c consoles.h
+
 cleanobjs:
                rm -f *.o *.bak
 
diff --git a/src/consoles.c b/src/consoles.c
new file mode 100644 (file)
index 0000000..30d8a8f
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * consoles.c      Routines to detect the system consoles
+ *
+ * Copyright (c) 2011 SuSE LINUX Products GmbH, All rights reserved.
+ *
+ * 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
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: Werner Fink <werner@suse.de>
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include "consoles.h"
+
+#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
+# ifndef  typeof
+#  define typeof               __typeof__
+# endif
+# ifndef  restrict
+#  define restrict             __restrict__
+# endif
+#endif
+
+#define alignof(type)          ((sizeof(type)+(sizeof(void*)-1)) & ~(sizeof(void*)-1))
+
+struct console *consoles;
+
+static dev_t comparedev;
+static char* scandev(DIR *dir)
+{
+       char *name = (char*)0;
+       struct dirent *dent;
+       int fd;
+
+       fd = dirfd(dir);
+       rewinddir(dir);
+       while ((dent = readdir(dir))) {
+               char path[PATH_MAX];
+               struct stat st;
+               if (fstatat(fd, dent->d_name, &st, 0) < 0)
+                       continue;
+               if (!S_ISCHR(st.st_mode))
+                       continue;
+               if (comparedev != st.st_rdev)
+                       continue;
+               if ((size_t)snprintf(path, sizeof(path), "/dev/%s", dent->d_name) >= sizeof(path))
+                       continue;
+               name = realpath(path, NULL);
+               break;
+       }
+       return name;
+}
+
+void detect_consoles(void)
+{
+       FILE *fc;
+       if ((fc = fopen("/proc/consoles", "r"))) {
+               char fbuf[16];
+               int maj, min;
+               DIR *dir;
+               dir = opendir("/dev");
+               if (!dir)
+                       goto out;
+               while ((fscanf(fc, "%*s %*s (%[^)]) %d:%d", &fbuf[0], &maj, &min) == 3)) {
+                       struct console *restrict tail;
+                       char * name;
+
+                       if (!strchr(fbuf, 'E'))
+                               continue;
+                       comparedev = makedev(maj, min);
+                       name = scandev(dir);
+
+                       if (!name)
+                               continue;
+
+                       if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0)
+                               perror("memory allocation");
+
+                       tail->next = (struct console*)0;
+                       tail->tty = name;
+
+                       if (!consoles)
+                               consoles = tail;
+                       else
+                               consoles->next = tail;
+               }
+               closedir(dir);
+out:
+               fclose(fc);
+       }
+}
diff --git a/src/consoles.h b/src/consoles.h
new file mode 100644 (file)
index 0000000..2bf8e12
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * consoles.h      Header file for routines to detect the system consoles
+ *
+ * Copyright (c) 2011 SuSE LINUX Products GmbH, All rights reserved.
+ *
+ * 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
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Author: Werner Fink <werner@suse.de>
+ */
+
+#include <termios.h>
+
+struct console {
+       char * tty;
+       int tlock;
+       struct termios ltio, otio;
+       struct console *next;
+};
+extern struct console *consoles;
+extern void detect_consoles(void);