Hi,

this is fallout from my "freeze userspace before s2ram" research.
While investigating the segfaults, i tried the console code from suspend.c
to rule out my old vt.[ch] code. It did not help, but it might be saner
to use the same console code in both s2disk and s2ram, so here it is.

vt.c and vt.h go away after that, console.c and console.h are mainly stuff
taken out from suspend.c.
Maybe we can remove some includes from suspend.c now, i did not check all
of them.


Index: Makefile
===================================================================
RCS file: /cvsroot/suspend/suspend/Makefile,v
retrieving revision 1.38
diff -u -p -r1.38 Makefile
--- Makefile    20 Sep 2006 12:51:32 -0000      1.38
+++ Makefile    7 Oct 2006 14:51:31 -0000
@@ -41,10 +41,10 @@ else
 all: $(S2DISK) $(S2BOTH) resume s2ram
 endif
 
-S2RAMOBJ=vt.o vbetool/lrmi.o vbetool/x86-common.o vbetool/vbetool.o 
radeontool.o dmidecode.o
+S2RAMOBJ=vbetool/lrmi.o vbetool/x86-common.o vbetool/vbetool.o radeontool.o 
dmidecode.o console.o
 
 ifeq ($(ARCH), x86_64)
-S2RAMOBJ=vt.o vbetool/thunk.o vbetool/x86-common.o vbetool/vbetool.o 
vbetool/x86emu/libx86emu.a radeontool.o dmidecode.o
+S2RAMOBJ=vbetool/thunk.o vbetool/x86-common.o vbetool/vbetool.o 
vbetool/x86emu/libx86emu.a radeontool.o dmidecode.o console.o
 endif
 
 SPLASHOBJ = splash.o bootsplash.o 
@@ -98,26 +98,26 @@ encrypt.o:  encrypt.c encrypt.h md5.h
 config.o:      config.c config.h
        $(CC) $(CFLAGS) $(CC_FLAGS) -c config.c -o config.o
 
-vt.o:  vt.c vt.h
-       $(CC) $(CFLAGS) -c vt.c -o vt.o
+console.o:     console.c console.h
+       $(CC) $(CFLAGS) -c console.c -o console.o
 
 bootsplash.o: bootsplash.h bootsplash.c
        $(CC) -g $(CFLAGS) $(CC_FLAGS) -c bootsplash.c -o bootsplash.o
 
-splash.o: splash.h splash.c bootsplash.o vt.o splashy_funcs.o
+splash.o: splash.h splash.c bootsplash.o console.o splashy_funcs.o
        $(CC) -g $(CFLAGS) $(CC_FLAGS) -c splash.c -o splash.o
 
 splashy_funcs.o: splashy_funcs.c splashy_funcs.h
        $(CC) -g $(CFLAGS) $(CC_FLAGS) -c $< -o $@
 
-$(S2DISK):     vt.o md5.o encrypt.o config.o suspend.c swsusp.h config.h 
encrypt.h md5.h $(SPLASHOBJ)
-       $(CC) -g $(CFLAGS) $(CC_FLAGS) vt.o md5.o encrypt.o config.o suspend.c 
-o $@ $(SPLASHOBJ) $(LD_FLAGS)
+$(S2DISK):     console.o md5.o encrypt.o config.o suspend.c swsusp.h config.h 
encrypt.h md5.h $(SPLASHOBJ)
+       $(CC) -g $(CFLAGS) $(CC_FLAGS) console.o md5.o encrypt.o config.o 
suspend.c -o $@ $(SPLASHOBJ) $(LD_FLAGS)
 
 $(S2BOTH):     md5.o encrypt.o config.o suspend.c swsusp.h config.h encrypt.h 
md5.h s2ram.c dmidecode.c whitelist.c radeontool.c $(S2RAMOBJ) $(SPLASHOBJ)
        $(CC) -g $(CFLAGS) -DCONFIG_BOTH $(CC_FLAGS) md5.o encrypt.o config.o 
suspend.c s2ram.c -o $@ $(S2RAMOBJ) $(SPLASHOBJ) $(LD_FLAGS) -lpci
 
 resume:        md5.o encrypt.o config.o resume.c swsusp.h config.h encrypt.h 
md5.h $(SPLASHOBJ)
-       $(CC) $(CFLAGS) $(CC_FLAGS) $(STATIC_CC_FLAGS) md5.o encrypt.o config.o 
vt.o resume.c $(SPLASHOBJ) -static -o resume $(LD_FLAGS) $(STATIC_LD_FLAGS)
+       $(CC) $(CFLAGS) $(CC_FLAGS) $(STATIC_CC_FLAGS) md5.o encrypt.o config.o 
console.o resume.c $(SPLASHOBJ) -static -o resume $(LD_FLAGS) $(STATIC_LD_FLAGS)
 
 ifdef CONFIG_ENCRYPT
 suspend-keygen:        md5.o keygen.c encrypt.h md5.h
Index: bootsplash.c
===================================================================
RCS file: /cvsroot/suspend/suspend/bootsplash.c,v
retrieving revision 1.3
diff -u -p -r1.3 bootsplash.c
--- bootsplash.c        18 Sep 2006 12:00:09 -0000      1.3
+++ bootsplash.c        7 Oct 2006 14:51:31 -0000
@@ -15,7 +15,7 @@
 #include <errno.h>
 #include <string.h>
 
-#include "vt.h"
+#include "console.h"
 #include "encrypt.h"
 
 #define BOOTSPLASH_PROC "/proc/splash"
@@ -83,12 +83,12 @@ close:
        return -1;
 }
 
-void bootsplash_switch_to(void)
+void bootsplash_switch_to(int vt_fd)
 {
        if (splash_file) {
                /* assume that bootsplash is on console 1, there's no way
                 * to figure this out AFAIK */
-               chvt(1);
+               chvt(vt_fd, 1);
        }
 }
 
Index: bootsplash.h
===================================================================
RCS file: /cvsroot/suspend/suspend/bootsplash.h,v
retrieving revision 1.3
diff -u -p -r1.3 bootsplash.h
--- bootsplash.h        18 Sep 2006 12:00:09 -0000      1.3
+++ bootsplash.h        7 Oct 2006 14:51:31 -0000
@@ -16,7 +16,7 @@ int bootsplash_open(void);
 int bootsplash_prepare(void);
 int bootsplash_finish(void);
 int bootsplash_progress(int p);
-void bootsplash_switch_to(void);
+void bootsplash_switch_to(int vt_fd);
 void bootsplash_read_password(char *, int);
 int bootsplash_dialog(const char *);
 
Index: s2ram.c
===================================================================
RCS file: /cvsroot/suspend/suspend/s2ram.c,v
retrieving revision 1.45
diff -u -p -r1.45 s2ram.c
--- s2ram.c     20 Sep 2006 16:23:51 -0000      1.45
+++ s2ram.c     7 Oct 2006 14:51:31 -0000
@@ -10,10 +10,15 @@
 #include <getopt.h>
 #include <errno.h>
 #include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <syscall.h>
+#include <unistd.h>
+#include <fcntl.h>
 
 #define S2RAM
 #include "vbetool/vbetool.h"
-#include "vt.h"
+#include "console.h"
 #include "s2ram.h"
 
 static void *vbe_buffer;
@@ -267,7 +272,8 @@ static void usage(void)
 int main(int argc, char *argv[])
 {
        int i, id = -1, ret = 0, test_mode = 0, force = 0;
-       int active_console = -1;
+       int orig_vc = -1, suspend_vc = -1, vt_fd = -1;
+       char *mem_pool;
        struct option options[] = {
                { "test",       no_argument,            NULL, 'n'},
                { "help",       no_argument,            NULL, 'h'},
@@ -349,10 +355,33 @@ int main(int argc, char *argv[])
        if (ret)
                goto out;
 
+       /* Make sure the 0, 1, 2 descriptors are open before opening the
+        * snapshot and resume devices
+        */
+       do {
+               ret = open("/dev/null", O_RDWR);
+               if (ret < 0) {
+                       ret = errno;
+                       fprintf(stderr, "s2ram: Could not open /dev/null\n");
+                       return ret;
+               }
+       } while (ret < 3);
+       close(ret);
+
+       mem_pool = malloc(16);
+       if (!mem_pool) {
+               fprintf(stderr, "s2ram: could not allocate 16 bytes\n");
+               return 99;
+       }
+               
        /* switch to console 1 first, since we might be in X */
-       active_console = fgconsole();
-       printf("Switching from vt%d to vt1\n", active_console);
-       chvt(1);
+
+       vt_fd = prepare_console(&orig_vc, &suspend_vc, mem_pool);
+       if (vt_fd < 0) {
+               ret = errno;
+               fprintf(stderr, "s2ram: Could not open a virtual terminal\n");
+               goto out;
+       }
 
        ret = s2ram_hacks();
        if (ret)
@@ -362,10 +391,8 @@ int main(int argc, char *argv[])
 
  out:
        /* if we switched consoles before suspend, switch back */
-       if (active_console > 0) {
-               printf("switching back to vt%d\n", active_console);
-               chvt(active_console);
-       }
+       if (vt_fd > 0)
+               restore_console(vt_fd, orig_vc);
        return ret;
 }
 #endif
Index: splash.c
===================================================================
RCS file: /cvsroot/suspend/suspend/splash.c,v
retrieving revision 1.4
diff -u -p -r1.4 splash.c
--- splash.c    18 Sep 2006 12:00:09 -0000      1.4
+++ splash.c    7 Oct 2006 14:51:31 -0000
@@ -23,7 +23,7 @@
  */
 static int splash_dummy_int_void(void) { return 0; }
 static int splash_dummy_int_int(int p) { return 0; }
-static void splash_dummy_void_void(void) { return; }
+static void splash_dummy_void_int(int p) { return; }
 #ifndef CONFIG_ENCRYPT
 static void splash_dummy_readpass(char *a, int b) { }
 #endif
@@ -40,7 +40,7 @@ void splash_prepare(struct splash *splas
 
        splash->finish      = splash_dummy_int_void;
        splash->progress    = splash_dummy_int_int;
-       splash->switch_to   = splash_dummy_void_void;
+       splash->switch_to   = splash_dummy_void_int;
        splash->dialog      = splash_dialog;
 #ifdef CONFIG_ENCRYPT
        splash->read_password   = read_password;
Index: splash.h
===================================================================
RCS file: /cvsroot/suspend/suspend/splash.h,v
retrieving revision 1.3
diff -u -p -r1.3 splash.h
--- splash.h    18 Sep 2006 12:00:09 -0000      1.3
+++ splash.h    7 Oct 2006 14:51:31 -0000
@@ -16,7 +16,7 @@
 struct splash {
        int (*finish) (void);
        int (*progress) (int p);
-       void (*switch_to) (void);
+       void (*switch_to) (int vt_fd);
        void (*read_password) (char *, int);
        int (*dialog) (const char *);
 };
Index: suspend.c
===================================================================
RCS file: /cvsroot/suspend/suspend/suspend.c,v
retrieving revision 1.59
diff -u -p -r1.59 suspend.c
--- suspend.c   6 Oct 2006 14:28:31 -0000       1.59
+++ suspend.c   7 Oct 2006 14:51:32 -0000
@@ -14,7 +14,6 @@
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/mount.h>
-#include <sys/vt.h>
 #include <sys/wait.h>
 #include <sys/time.h>
 #include <time.h>
@@ -38,7 +37,7 @@
 #include "config.h"
 #include "md5.h"
 #include "splash.h"
-#include "vt.h"
+#include "console.h"
 #ifdef CONFIG_BOTH
 #include "s2ram.h"
 #endif
@@ -72,8 +71,7 @@ static int use_platform_suspend;
 
 static int suspend_swappiness = SUSPEND_SWAPPINESS;
 static struct splash splash;
-static struct vt_mode orig_vtm;
-static int vfd;
+static int vt_fd;
 
 static struct config_par parameters[PARAM_NO] = {
        {
@@ -698,7 +696,7 @@ int suspend_system(int snapshot_fd, int 
        /* This a hack for a bug in bootsplash. Apparently it will
         * drop to 'verbose mode' after the freeze() call.
         */
-       splash.switch_to();
+       splash.switch_to(vt_fd);
        splash.progress(15);
 
        if (error)
@@ -766,179 +764,6 @@ Unfreeze:
        return error;
 }
 
-/**
- *     console_fd - get file descriptor for given file name and verify
- *     if that's a console descriptor (based on the code of openvt)
- */
-
-static inline int console_fd(const char *fname)
-{
-       int fd;
-       char arg;
-
-       fd = open(fname, O_RDONLY);
-       if (fd < 0 && errno == EACCES)
-               fd = open(fname, O_WRONLY);
-       if (fd >= 0 && (ioctl(fd, KDGKBTYPE, &arg) || (arg != KB_101 && arg != 
KB_84))) {
-               close(fd);
-               return -ENOTTY;
-       }
-       return fd;
-}
-
-#ifndef TIOCL_GETKMSGREDIRECT
-#define TIOCL_GETKMSGREDIRECT  17
-#endif
-
-static int set_kmsg_redirect;
-
-/**
- *     prepare_console - find a spare virtual terminal, open it and attach
- *     the standard streams to it.  The number of the currently active
- *     virtual terminal is saved via @orig_vc
- */
-
-static int prepare_console(int *orig_vc, int *new_vc)
-{
-       int fd, error, vt = -1;
-       char *vt_name = mem_pool;
-       struct vt_stat vtstat;
-       char clear_vt, tiocl[2];
-
-       fd = console_fd("/dev/console");
-       if (fd < 0)
-               return fd;
-
-       tiocl[0] = TIOCL_GETKMSGREDIRECT;
-       if (!ioctl(fd, TIOCLINUX, tiocl)) {
-               if (tiocl[0] > 0)
-                       vt = tiocl[0];
-       }
-
-       clear_vt = 0;
-       error = ioctl(fd, VT_GETSTATE, &vtstat);
-       if (!error) {
-               *orig_vc = vtstat.v_active;
-               if (vt < 0) {
-                       clear_vt = 1;
-                       error = ioctl(fd, VT_OPENQRY, &vt);
-               }
-       }
-
-       close(fd);
-
-       if (error || vt < 0)
-               return -1;
-
-       sprintf(vt_name, "/dev/tty%d", vt);
-       fd = open(vt_name, O_RDWR);
-       if (fd < 0)
-               return fd;
-       error = ioctl(fd, VT_ACTIVATE, vt);
-       if (error) {
-               fprintf(stderr, "Could not activate the VT %d\n", vt);
-               fflush(stderr);
-               goto Close_fd;
-       }
-       error = ioctl(fd, VT_WAITACTIVE, vt);
-       if (error) {
-               fprintf(stderr, "VT %d activation failed\n", vt);
-               fflush(stderr);
-               goto Close_fd;
-       }
-
-       if (clear_vt) {
-               char *msg = "\33[H\33[J";
-               write(fd, msg, strlen(msg));
-       }
-
-       dup2(fd, 0);
-       dup2(fd, 1);
-       dup2(fd, 2);
-       *new_vc = vt;
-
-       set_kmsg_redirect = !tiocl[0];
-       if (set_kmsg_redirect) {
-               tiocl[0] = TIOCL_SETKMSGREDIRECT;
-               tiocl[1] = vt;
-               if (ioctl(fd, TIOCLINUX, tiocl)) {
-                       fprintf(stderr, "Failed to redirect kernel messages to 
VT %d\n"
-                                       "Reason: %s\n", vt, strerror(errno));
-                       fflush(stderr);
-                       set_kmsg_redirect = 0;
-               }
-       }
-
-       return fd;
-Close_fd:
-       close(fd);
-       return error;
-}
-
-/**
- *     restore_console - switch to the virtual console that was active before
- *     suspend
- */
-
-static void restore_console(int fd, int orig_vc)
-{
-       int error;
-
-       error = ioctl(fd, VT_ACTIVATE, orig_vc);
-       if (error) {
-               fprintf(stderr, "Could not activate the VT %d\n", orig_vc);
-               fflush(stderr);
-               goto Close_fd;
-       }
-       error = ioctl(fd, VT_WAITACTIVE, orig_vc);
-       if (error) {
-               fprintf(stderr, "VT %d activation failed\n", orig_vc);
-               fflush(stderr);
-       }
-       if (set_kmsg_redirect) {
-               char tiocl[2];
-
-               tiocl[0] = TIOCL_SETKMSGREDIRECT;
-               tiocl[1] = 0;
-               ioctl(fd, TIOCLINUX, tiocl);
-       }
-Close_fd:
-       close(fd);
-}
-
-static FILE *printk_file;
-
-static inline void open_printk(void)
-{
-       printk_file = fopen("/proc/sys/kernel/printk", "r+");
-}
-
-static inline int get_kernel_console_loglevel(void)
-{
-       int level = -1;
-
-       if (printk_file) {
-               rewind(printk_file);
-               fscanf(printk_file, "%d", &level);
-       }
-       return level;
-}
-
-static inline void set_kernel_console_loglevel(int level)
-{
-       if (printk_file) {
-               rewind(printk_file);
-               fprintf(printk_file, "%d\n", level);
-               fflush(printk_file);
-       }
-}
-
-static inline void close_printk(void)
-{
-       if (printk_file)
-               fclose(printk_file);
-}
-
 static FILE *swappiness_file;
 
 static inline void open_swappiness(void)
@@ -1069,59 +894,6 @@ Close:
 }
 #endif
 
-static void unlock_vt(void)
-{
-       ioctl(vfd, VT_SETMODE, &orig_vtm);
-       close(vfd);
-}
-
-static int lock_vt(void)
-{
-       struct sigaction sa;
-       struct vt_mode vtm;
-       struct vt_stat vtstat;
-       char *vt_name = mem_pool;
-       int fd, error;
-
-       fd = console_fd("/dev/console");
-       if (fd < 0)
-               return fd;
-
-       error = ioctl(fd, VT_GETSTATE, &vtstat);
-       close(fd);
-       
-       if (error < 0)
-               return error;
-
-       sprintf(vt_name, "/dev/tty%d", vtstat.v_active);
-       vfd = open(vt_name, O_RDWR);
-       if (vfd < 0)
-               return vfd;
-
-       error = ioctl(vfd, VT_GETMODE, &vtm);
-       if (error < 0) 
-               return error;
-
-       /* Setting vt mode to VT_PROCESS means this process
-        * will handle vt switching requests.
-        * We just ignore all request by installing SIG_IGN.
-        */
-       sigemptyset(&(sa.sa_mask));
-       sa.sa_flags = SA_RESTART;
-       sa.sa_handler = SIG_IGN;
-       sigaction(SIGUSR1, &sa, NULL);
-
-       orig_vtm = vtm;
-       vtm.mode = VT_PROCESS;
-       vtm.relsig = SIGUSR1;
-       vtm.acqsig = SIGUSR1;
-       error = ioctl(vfd, VT_SETMODE, &vtm);
-       if (error < 0)
-               return error;
-
-       return 0;
-}
-
 
 
 int main(int argc, char *argv[])
@@ -1129,7 +901,7 @@ int main(int argc, char *argv[])
        unsigned int mem_size;
        char *chroot_path;
        struct stat stat_buf;
-       int resume_fd, snapshot_fd, vt_fd, orig_vc = -1, suspend_vc = -1;
+       int resume_fd, snapshot_fd, orig_vc = -1, suspend_vc = -1;
        dev_t resume_dev;
        int orig_loglevel, orig_swappiness, ret;
 
@@ -1251,7 +1023,7 @@ int main(int argc, char *argv[])
                goto Close_snapshot_fd;
        }
 
-       vt_fd = prepare_console(&orig_vc, &suspend_vc);
+       vt_fd = prepare_console(&orig_vc, &suspend_vc, mem_pool);
        if (vt_fd < 0) {
                ret = errno;
                fprintf(stderr, "suspend: Could not open a virtual terminal\n");
@@ -1260,7 +1032,7 @@ int main(int argc, char *argv[])
 
        splash_prepare(&splash, splash_param);
 
-       if (lock_vt() < 0)
+       if (lock_vt(mem_pool) < 0)
                goto Restore_console;
 
        splash.progress(5);
 
--- /dev/null   2006-09-27 23:40:31.000000000 +0200
+++ console.c   2006-10-07 16:43:10.000000000 +0200
@@ -0,0 +1,240 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/vt.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <linux/kd.h>
+#include <linux/tiocl.h>
+
+#include "console.h"
+
+struct vt_mode orig_vtm;
+int vfd;
+int set_kmsg_redirect;
+
+/**
+ *     console_fd - get file descriptor for given file name and verify
+ *     if that's a console descriptor (based on the code of openvt)
+ */
+
+int console_fd(const char *fname)
+{
+       int fd;
+       char arg;
+
+       fd = open(fname, O_RDONLY);
+       if (fd < 0 && errno == EACCES)
+               fd = open(fname, O_WRONLY);
+       if (fd >= 0 && (ioctl(fd, KDGKBTYPE, &arg) || (arg != KB_101 && arg != 
KB_84))) {
+               close(fd);
+               return -ENOTTY;
+       }
+       return fd;
+}
+
+#ifndef TIOCL_GETKMSGREDIRECT
+#define TIOCL_GETKMSGREDIRECT  17
+#endif
+
+/**
+ *     prepare_console - find a spare virtual terminal, open it and attach
+ *     the standard streams to it.  The number of the currently active
+ *     virtual terminal is saved via @orig_vc
+ */
+
+int prepare_console(int *orig_vc, int *new_vc, char *vt_name)
+{
+       int fd, error, vt = -1;
+       struct vt_stat vtstat;
+       char clear_vt, tiocl[2];
+
+       fd = console_fd("/dev/console");
+       if (fd < 0)
+               return fd;
+
+       tiocl[0] = TIOCL_GETKMSGREDIRECT;
+       if (!ioctl(fd, TIOCLINUX, tiocl)) {
+               if (tiocl[0] > 0)
+                       vt = tiocl[0];
+       }
+
+       clear_vt = 0;
+       error = ioctl(fd, VT_GETSTATE, &vtstat);
+       if (!error) {
+               *orig_vc = vtstat.v_active;
+               if (vt < 0) {
+                       clear_vt = 1;
+                       error = ioctl(fd, VT_OPENQRY, &vt);
+               }
+       }
+
+       close(fd);
+
+       if (error || vt < 0)
+               return -1;
+
+       sprintf(vt_name, "/dev/tty%d", vt);
+       fd = open(vt_name, O_RDWR);
+       free(vt_name);
+       if (fd < 0)
+               return fd;
+       error = ioctl(fd, VT_ACTIVATE, vt);
+       if (error) {
+               fprintf(stderr, "Could not activate the VT %d\n", vt);
+               fflush(stderr);
+               goto Close_fd;
+       }
+       error = ioctl(fd, VT_WAITACTIVE, vt);
+       if (error) {
+               fprintf(stderr, "VT %d activation failed\n", vt);
+               fflush(stderr);
+               goto Close_fd;
+       }
+
+       if (clear_vt) {
+               char *msg = "\33[H\33[J";
+               write(fd, msg, strlen(msg));
+       }
+
+       dup2(fd, 0);
+       dup2(fd, 1);
+       dup2(fd, 2);
+       *new_vc = vt;
+
+       set_kmsg_redirect = !tiocl[0];
+       if (set_kmsg_redirect) {
+               tiocl[0] = TIOCL_SETKMSGREDIRECT;
+               tiocl[1] = vt;
+               if (ioctl(fd, TIOCLINUX, tiocl)) {
+                       fprintf(stderr, "Failed to redirect kernel messages to 
VT %d\n"
+                                       "Reason: %s\n", vt, strerror(errno));
+                       fflush(stderr);
+                       set_kmsg_redirect = 0;
+               }
+       }
+
+       return fd;
+Close_fd:
+       close(fd);
+       return error;
+}
+
+/**
+ *     restore_console - switch to the virtual console that was active before
+ *     suspend
+ */
+
+void restore_console(int fd, int orig_vc)
+{
+       int error;
+
+       error = ioctl(fd, VT_ACTIVATE, orig_vc);
+       if (error) {
+               fprintf(stderr, "Could not activate the VT %d\n", orig_vc);
+               fflush(stderr);
+               goto Close_fd;
+       }
+       error = ioctl(fd, VT_WAITACTIVE, orig_vc);
+       if (error) {
+               fprintf(stderr, "VT %d activation failed\n", orig_vc);
+               fflush(stderr);
+       }
+       if (set_kmsg_redirect) {
+               char tiocl[2];
+
+               tiocl[0] = TIOCL_SETKMSGREDIRECT;
+               tiocl[1] = 0;
+               ioctl(fd, TIOCLINUX, tiocl);
+       }
+Close_fd:
+       close(fd);
+}
+
+void chvt(int fd, int num)
+{
+       if (ioctl(fd, VT_ACTIVATE, num)) {
+               perror("chvt: VT_ACTIVATE");
+       }
+       if (ioctl(fd, VT_WAITACTIVE, num)) {
+               perror("VT_WAITACTIVE");
+       }
+}
+
+void unlock_vt(void)
+{
+       ioctl(vfd, VT_SETMODE, &orig_vtm);
+       close(vfd);
+}
+
+int lock_vt(char *vt_name)
+{
+       struct sigaction sa;
+       struct vt_mode vtm;
+       struct vt_stat vtstat;
+       int fd, error;
+
+       fd = console_fd("/dev/console");
+       if (fd < 0)
+               return fd;
+
+       error = ioctl(fd, VT_GETSTATE, &vtstat);
+       close(fd);
+       
+       if (error < 0)
+               return error;
+
+       sprintf(vt_name, "/dev/tty%d", vtstat.v_active);
+       vfd = open(vt_name, O_RDWR);
+       if (vfd < 0)
+               return vfd;
+
+       error = ioctl(vfd, VT_GETMODE, &vtm);
+       if (error < 0) 
+               return error;
+
+       /* Setting vt mode to VT_PROCESS means this process
+        * will handle vt switching requests.
+        * We just ignore all request by installing SIG_IGN.
+        */
+       sigemptyset(&(sa.sa_mask));
+       sa.sa_flags = SA_RESTART;
+       sa.sa_handler = SIG_IGN;
+       sigaction(SIGUSR1, &sa, NULL);
+
+       orig_vtm = vtm;
+       vtm.mode = VT_PROCESS;
+       vtm.relsig = SIGUSR1;
+       vtm.acqsig = SIGUSR1;
+       error = ioctl(vfd, VT_SETMODE, &vtm);
+       if (error < 0)
+               return error;
+
+       return 0;
+}
+
+int get_kernel_console_loglevel(void)
+{
+       int level = -1;
+
+       if (printk_file) {
+               rewind(printk_file);
+               fscanf(printk_file, "%d", &level);
+       }
+       return level;
+}
+
+void set_kernel_console_loglevel(int level)
+{
+       if (printk_file) {
+               rewind(printk_file);
+               fprintf(printk_file, "%d\n", level);
+               fflush(printk_file);
+       }
+}
+
--- /dev/null   2006-09-27 23:40:31.000000000 +0200
+++ console.h   2006-10-07 16:43:10.000000000 +0200
@@ -0,0 +1,30 @@
+#ifndef TIOCL_GETKMSGREDIRECT
+#define TIOCL_GETKMSGREDIRECT  17
+#endif
+
+static FILE *printk_file;
+
+int console_fd(const char *fname);
+int prepare_console(int *orig_vc, int *new_vc, char *vt_name);
+void restore_console(int fd, int orig_vc);
+void unlock_vt(void);
+int lock_vt(char *vt_name);
+int get_kernel_console_loglevel(void);
+void set_kernel_console_loglevel(int level);
+void chvt(int vt_fd, int num);
+
+static inline void open_printk(void)
+{
+       printk_file = fopen("/proc/sys/kernel/printk", "r+");
+}
+
+static inline void close_printk(void)
+{
+       if (printk_file)
+               fclose(printk_file);
+}
+
+static inline int is_framebuffer(void)
+{
+       return !access("/sys/class/graphics/fb0", F_OK);
+}
-- 
Stefan Seyfried                  \ "I didn't want to write for pay. I
QA / R&D Team Mobile Devices      \ wanted to be paid for what I write."
SUSE LINUX Products GmbH, Nürnberg \                    -- Leonard Cohen

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Suspend-devel mailing list
Suspend-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/suspend-devel

Reply via email to