$ cat main.cc
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/vt.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <ncurses/curses.h>
#define VTNAME "/dev/tty%d"
static int vtno;
static int fd;
static void finish(int sig);
static int newvtno;
int main(void)
{
// used to store the device name
char vtname[sizeof VTNAME+2];
// current vt number
vtno=-1;
// new vt number for the Blue Screen of DEATH!!
newvtno=-1;
if ((fd = open("/dev/console",O_RDWR,0)) < 0) {
perror("switchto: Can't open /dev/console\n");
return(1);
}
if ((ioctl(fd, VT_OPENQRY, &newvtno) < 0) || (newvtno == -1)) {
perror("open: Cannot find a free VT\n");
close(fd);
return(1);
}
if (ioctl(fd, VT_GETSTATE, &vtno) < 0) {
perror("open: can't get VTstate\n");
close(fd);
return(1);
}
/*
vtno appears to get returned as the 16-bit negative value of what
it should be...
*/
if (vtno<0) vtno+= 65536;
sprintf(vtname,VTNAME,newvtno);
if (!geteuid()) {
uid_t uid=getuid();
chown(vtname,uid,getgid());
setuid(uid);
}
int pid;
if ((pid=fork())==0) {
setsid();
close(0);
close(1);
close(2);
close(fd);
fd=open(vtname,O_RDWR);
dup(fd); dup(fd);
(void) ioctl(fd, VT_ACTIVATE, newvtno);
/* wait to be really sure we have switched */
(void) ioctl(fd, VT_WAITACTIVE, newvtno);
signal(SIGINT,finish);
initscr();
start_color();
cbreak();
init_pair(1,COLOR_WHITE,COLOR_BLUE);
wattrset(stdscr,COLOR_PAIR(1));
for (int i=0;i<LINES;i++) {
wmove(stdscr,i,0);
whline(stdscr,' ',COLS);
}
wmove(stdscr,8,25);
wprintw(stdscr,"Linux has become unstable");
wmove(stdscr,10,15);
wprintw(stdscr,"Press <CTRL-ALT-DEL> to restart your computer");
wmove(stdscr,17,16);
wprintw(stdscr,"** HINT ** <CTRL-ALT-DEL> really reboots!!!");
wmove(stdscr,18,7);
wprintw(stdscr,"Since you're in Linux, not Windows, you can just do a <ctrl-c>");
wmove(stdscr,19,18);
wprintw(stdscr,"to continue what you were doing... :-)");
wrefresh(stdscr);
while (1);
} else {
exit(0);
}
}
static void finish(int sig)
{
endwin();
if (ioctl(fd, VT_ACTIVATE, vtno) < 0) {
fprintf(stderr, "switcho: Failed to select VT %i (%s)\n", vtno,
strerror(errno));
exit(1);
}
/* wait to be really sure we have switched */
(void) ioctl(fd, VT_WAITACTIVE, vtno);
exit(0);
}
$ cat Makefile
CC=g++
LIBS=-lncurses
SRCS=main.cc
bsod: $(SRCS)
$(CC) -o bsod $(SRCS) $(LIBS)
clean:
rm bsod
$ make
$ ./bsod
$ make
g++ -o bsod main.cc -lncurses
main.cc: In function `void finish(int)':
main.cc:108: error: `errno' undeclared (first use this function)
main.cc:108: error: (Each undeclared identifier is reported only once for each function it appears in.)
main.cc:108: error: `strerror' undeclared (first use this function)
make: *** [bsod] Ошибка 1