Add initial support for the LRMI v86 backend.
[v86d.git] / main.c
blob4402d99047b487331d70520ac188dff119d6e9e9
1 #include <sys/socket.h>
2 #include <sys/poll.h>
4 #include <linux/netlink.h>
5 #include <linux/rtnetlink.h>
7 #include <arpa/inet.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <time.h>
15 #include <fcntl.h>
17 #include "v86.h"
19 static int need_exit;
20 static __u32 seq;
22 static int netlink_send(int s, struct cn_msg *msg)
24 struct nlmsghdr *nlh;
25 unsigned int size;
26 int err;
27 char buf[1024];
28 struct cn_msg *m;
30 size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
32 nlh = (struct nlmsghdr *)buf;
33 nlh->nlmsg_seq = seq++;
34 nlh->nlmsg_pid = getpid();
35 nlh->nlmsg_type = NLMSG_DONE;
36 nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
37 nlh->nlmsg_flags = 0;
39 m = NLMSG_DATA(nlh);
40 memcpy(m, msg, sizeof(*m) + msg->len);
42 err = send(s, nlh, size, 0);
43 if (err == -1)
44 ulog("Failed to send: %s [%d].\n", strerror(errno), errno);
46 return err;
49 int req_exec(int s, struct cn_msg *msg)
51 struct uvesafb_task *tsk = (struct uvesafb_task*)(msg + 1);
52 u8 *buf = (u8*)tsk + sizeof(struct uvesafb_task);
53 int i;
55 ulog("performing request\n");
56 v86_task(tsk, buf);
57 ulog("request done\n");
58 netlink_send(s, msg);
60 return 0;
64 int main(int argc, char *argv[])
66 int s;
67 char buf[1024];
68 int len, i;
69 struct nlmsghdr *reply;
70 struct sockaddr_nl l_local;
71 struct cn_msg *data;
72 time_t tm;
73 struct pollfd pfd;
75 i = open("/dev/tty1", O_RDWR);
76 dup2(i, 0);
77 dup2(i, 1);
78 dup2(i, 2);
80 s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
81 if (s == -1) {
82 perror("socket");
83 return -1;
86 l_local.nl_family = AF_NETLINK;
87 l_local.nl_groups = 1 << (CN_IDX_UVESAFB-1); /* bitmask of requested groups */
88 l_local.nl_pid = 0;
90 if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
91 perror("bind");
92 close(s);
93 return -1;
96 i = fork();
97 if (i) {
98 exit(0);
101 setsid();
102 chdir("/");
104 if (v86_init())
105 return -1;
107 ulog("it's alive %d!\n", s);
108 memset(buf, 0, sizeof(buf));
110 /* data = (struct cn_msg *)buf;
111 data->id.idx = CN_IDX_UVESAFB;
112 data->id.val = CN_VAL_UVESAFB;
113 data->seq = seq++;
114 data->ack = 0;
115 data->len = 0;
116 netlink_send(s, data);
118 pfd.fd = s;
120 while (!need_exit) {
121 pfd.events = POLLIN;
122 pfd.revents = 0;
123 switch (poll(&pfd, 1, -1)) {
124 case 0:
125 need_exit = 1;
126 continue;
127 case -1:
128 if (errno != EINTR) {
129 need_exit = 1;
130 break;
132 continue;
135 memset(buf, 0, sizeof(buf));
136 len = recv(s, buf, sizeof(buf), 0);
137 if (len == -1) {
138 perror("recv buf");
139 close(s);
140 return -1;
143 reply = (struct nlmsghdr *)buf;
145 switch (reply->nlmsg_type) {
146 case NLMSG_ERROR:
147 ulog("Error message received.\n");
148 break;
150 case NLMSG_DONE:
151 data = (struct cn_msg *)NLMSG_DATA(reply);
152 req_exec(s, data);
153 break;
154 default:
155 break;
159 close(s);
160 return 0;