source: projects/initscripts/tags/initscripts-8.91.3/src/console_check.c @ 1108

Revision 1108, 3.4 KB checked in by daisuke, 14 years ago (diff)

import initscripts-8.90.6 from internal cvs repository

Line 
1
2#include <fcntl.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <termios.h>
7#include <unistd.h>
8
9#include <sys/ioctl.h>
10
11#include <linux/serial.h>
12#include <linux/serial_core.h>
13
14struct speeds
15{
16        speed_t speed;
17        unsigned long value;
18};
19
20struct speeds speed_map[] =
21{
22        {B50, 50},
23        {B75, 75},
24        {B110, 110},
25        {B134, 134},
26        {B150, 150},
27        {B200, 200},
28        {B300, 300},
29        {B600, 600},
30        {B1200, 1200},
31        {B1800, 1800},
32        {B2400, 2400},
33        {B4800, 4800},
34        {B9600, 9600},
35        {B19200, 19200},
36        {B38400, 38400},
37#ifdef B57600
38        {B57600, 57600},
39#endif
40#ifdef B115200
41        {B115200, 115200},
42#endif
43#ifdef B230400
44        {B230400, 230400},
45#endif
46#ifdef B460800
47        {B460800, 460800},
48#endif
49        {0, 0}
50};
51
52int termcmp(struct termios *a, struct termios *b) {
53        if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
54            a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag ||
55            cfgetispeed(a) != cfgetispeed(b) || cfgetospeed(a) != cfgetospeed(b))
56                return 1;
57        return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
58}       
59
60int get_serial_speed(int fd) {
61        struct termios mode;
62       
63        if (!tcgetattr(fd, &mode)) {
64                int i;
65                speed_t speed;
66               
67                speed = cfgetospeed(&mode);
68                for (i = 0; speed_map[i].value != 0; i++)
69                        if (speed_map[i].speed == speed)
70                                return speed_map[i].value;
71        }
72        return 0;
73}
74
75int compare_termios_to_console(char *dev, int *speed) {
76        struct termios cmode, mode;
77        int fd, cfd;
78
79        cfd = open ("/dev/console", O_RDONLY);
80        tcgetattr(cfd, &cmode);
81        close(cfd);
82
83        fd = open(dev, O_RDONLY|O_NONBLOCK);
84        tcgetattr(fd, &mode);
85
86        if (!termcmp(&cmode, &mode)) {
87                *speed = get_serial_speed(fd);
88                close(fd);
89                return 1;
90        }
91        close(fd);
92        return 0;
93}
94
95char *serial_tty_name(int type) {
96        switch (type) {
97                case PORT_8250...PORT_MAX_8250:
98                        return "ttyS";
99                case PORT_PMAC_ZILOG:
100                        return "ttyPZ";
101                case PORT_MPSC:
102                        return "ttyMM";
103                case PORT_CPM:
104                        return "ttyCPM";
105                case PORT_MPC52xx:
106                        return "ttyPSC";
107                default:
108                        return NULL;
109        }
110}
111
112char *check_serial_console(int *speed) {
113        int fd;
114        char *ret = NULL, *device;
115        char twelve = 12;
116        struct serial_struct si, si2;
117        char *tty_name;
118
119        memset(&si, 0, sizeof(si));
120        memset(&si2, 0, sizeof(si));
121
122        fd = open("/dev/console", O_RDWR);
123        if (ioctl (fd, TIOCLINUX, &twelve) >= 0)
124                goto out;
125
126        if (ioctl(fd, TIOCGSERIAL, &si) < 0)
127                goto out;
128        close(fd);
129
130        tty_name = serial_tty_name(si.type);
131        if (!tty_name)
132                goto out;
133
134        asprintf(&device, "%s%d", tty_name, si.line);
135        fd = open(device, O_RDWR|O_NONBLOCK);
136        if (fd == -1)
137                goto out;
138
139        if (ioctl(fd, TIOCGSERIAL, &si2) < 0)
140                goto out;
141
142        if (memcmp(&si,&si2, sizeof(si)))
143                goto out;
144
145        *speed = get_serial_speed(fd);
146        ret = device;
147out:
148        close(fd);
149        return ret;
150}
151
152int emit_console_event(char *dev, int speed) {
153        char *args[] = { "initctl", "emit", "--no-wait", "fedora.serial-console-available", NULL, NULL, NULL };
154       
155        args[4] = dev;
156        if (speed)
157                asprintf(&args[5],"%d",speed);
158        execv("/sbin/initctl", args);
159        return 1;       
160}
161
162int main(int argc, char **argv) {
163        char *device;
164        int speed;
165       
166        if (argc < 2) {
167                printf("usage: console_check <device>\n");
168                exit(1);
169        }
170        chdir("/dev");
171        device = argv[1];
172        if (!strcmp(device, "console")) {
173                device = check_serial_console(&speed);
174                if (device)
175                        return emit_console_event(device, speed);
176        } else if (compare_termios_to_console(device, &speed)) {
177                return emit_console_event(device, speed);
178        }
179        return 0;
180}
Note: See TracBrowser for help on using the repository browser.