eqemu
changeset 2:48dce4ee4850
the fake device is working
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 15 Jul 2014 14:37:51 +0300 |
parents | 374d91dd2996 |
children | f9274bebe55e |
files | Makefile README src/dev.cc src/dev.h src/main.cc src/timer.cc src/timer.h |
diffstat | 7 files changed, 261 insertions(+), 5 deletions(-) [+] |
line diff
1.1 --- a/Makefile Tue Jul 15 05:44:26 2014 +0300 1.2 +++ b/Makefile Tue Jul 15 14:37:51 2014 +0300 1.3 @@ -5,7 +5,7 @@ 1.4 1.5 CFLAGS = -pedantic -Wall -g 1.6 CXXFLAGS = $(CFLAGS) 1.7 -LDFLAGS = -lGL -lGLU -lglut -lGLEW -lX11 -lm 1.8 +LDFLAGS = -lGL -lGLU -lglut -lGLEW -lX11 -lm -lpthread 1.9 1.10 $(bin): $(obj) 1.11 $(CXX) -o $@ $(obj) $(LDFLAGS)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/README Tue Jul 15 14:37:51 2014 +0300 2.3 @@ -0,0 +1,4 @@ 2.4 +1. Create 2 pseudoterminals: socat -d -d PTY PTY 2.5 +2. start ./equeue_dummy /dev/pts/one 2.6 +3. set the php script to use /dev/pts/theother (make sure apache has permission 2.7 + to rw it).
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/dev.cc Tue Jul 15 14:37:51 2014 +0300 3.3 @@ -0,0 +1,177 @@ 3.4 +#include <stdio.h> 3.5 +#include <string.h> 3.6 +#include <errno.h> 3.7 +#include <signal.h> 3.8 +#include <limits.h> 3.9 +#include <string> 3.10 +#include <unistd.h> 3.11 +#include <sys/stat.h> 3.12 +#include <sys/wait.h> 3.13 +#include <fcntl.h> 3.14 +#include <termios.h> 3.15 +#include "dev.h" 3.16 +#include "timer.h" 3.17 + 3.18 +int customer, ticket; 3.19 +static int report_inputs, cmd_echo; 3.20 +static long last_ticket_msec = LONG_MIN; 3.21 + 3.22 +static void runcmd(const char *cmd); 3.23 + 3.24 +static int fd = -1; 3.25 +static FILE *fp; 3.26 +static std::string cur_line; 3.27 + 3.28 +int start_dev(const char *devpath) 3.29 +{ 3.30 + if((fd = open(devpath, O_RDWR | O_NONBLOCK)) == -1) { 3.31 + fprintf(stderr, "failed to open device: %s: %s\n", devpath, strerror(errno)); 3.32 + return -1; 3.33 + } 3.34 + if(isatty(fd)) { 3.35 + struct termios term; 3.36 + 3.37 + if(tcgetattr(fd, &term) == -1) { 3.38 + perror("failed to retrieve terminal attributes"); 3.39 + stop_dev(); 3.40 + return -1; 3.41 + } 3.42 + term.c_cflag = CS8 | CLOCAL; 3.43 + term.c_iflag &= ~(IXON | IXOFF); 3.44 + term.c_lflag = 0; 3.45 + 3.46 + cfsetispeed(&term, B38400); 3.47 + cfsetospeed(&term, B38400); 3.48 + 3.49 + if(tcsetattr(fd, TCSANOW, &term) == -1) { 3.50 + perror("failed to set terminal attributes"); 3.51 + stop_dev(); 3.52 + return -1; 3.53 + } 3.54 + } 3.55 + 3.56 + if(!(fp = fdopen(fd, "r+"))) { 3.57 + perror("failed to attach an I/O stream to the device file\n"); 3.58 + stop_dev(); 3.59 + return -1; 3.60 + } 3.61 + setvbuf(fp, 0, _IONBF, 0); 3.62 + 3.63 + return fd; 3.64 +} 3.65 + 3.66 +void stop_dev() 3.67 +{ 3.68 + if(fp) 3.69 + fclose(fp); 3.70 + else if(fd >= 0) 3.71 + close(fd); 3.72 +} 3.73 + 3.74 + 3.75 +void proc_dev_input() 3.76 +{ 3.77 + int rdbytes; 3.78 + char buf[256]; 3.79 + static bool skip_line; 3.80 + 3.81 + while((rdbytes = read(fd, buf, sizeof buf - 1)) > 0) { 3.82 + buf[rdbytes] = 0; 3.83 + 3.84 + /* ignore our own crap */ 3.85 + if(memcmp(buf, "OK,", 3) == 0 || memcmp(buf, "ERR,", 4) == 0) { 3.86 + skip_line = true; 3.87 + } 3.88 + 3.89 + for(int i=0; i<rdbytes; i++) { 3.90 + if(buf[i] == '\n' || buf[i] == '\r') { 3.91 + if(!cur_line.empty()) { 3.92 + runcmd(cur_line.c_str()); 3.93 + cur_line.clear(); 3.94 + } 3.95 + skip_line = false; 3.96 + } else { 3.97 + if(!skip_line) { 3.98 + cur_line.push_back(buf[i]); 3.99 + } 3.100 + } 3.101 + } 3.102 + } 3.103 +} 3.104 + 3.105 +void issue_ticket() 3.106 +{ 3.107 + ticket++; 3.108 + last_ticket_msec = get_msec(); 3.109 + if(report_inputs) { 3.110 + fprintf(fp, "ticket: %d\n", ticket); 3.111 + } 3.112 +} 3.113 + 3.114 +void next_customer() 3.115 +{ 3.116 + if(customer < ticket) { 3.117 + customer++; 3.118 + last_ticket_msec = LONG_MIN; 3.119 + if(report_inputs) { 3.120 + fprintf(fp, "customer: %d\n", customer); 3.121 + } 3.122 + } 3.123 +} 3.124 + 3.125 +#define VERSTR \ 3.126 + "Queue system emulator v0.1 by John Tsiombikas <nuclear@member.fsf.org>" 3.127 + 3.128 +static void runcmd(const char *cmd) 3.129 +{ 3.130 + printf("DBG: runcmd(\"%s\")\n", cmd); 3.131 + 3.132 + switch(cmd[0]) { 3.133 + case 'e': 3.134 + cmd_echo = !cmd_echo; 3.135 + fprintf(fp, "OK,turning echo %s\n", cmd_echo ? "on" : "off"); 3.136 + break; 3.137 + 3.138 + case 'i': 3.139 + report_inputs = !report_inputs; 3.140 + fprintf(fp, "OK,turning input reports %s\n", report_inputs ? "on" : "off"); 3.141 + break; 3.142 + 3.143 + case 'v': 3.144 + fprintf(fp, "OK,%s\n", VERSTR); 3.145 + break; 3.146 + 3.147 + case 'r': 3.148 + fprintf(fp, "OK,reseting queues\n"); 3.149 + customer = 0; 3.150 + ticket = 0; 3.151 + last_ticket_msec = LONG_MIN; 3.152 + break; 3.153 + 3.154 + case 't': 3.155 + fprintf(fp, "OK,ticket: %d\r\n", ticket); 3.156 + break; 3.157 + 3.158 + case 'c': 3.159 + fprintf(fp, "OK,customer: %d\r\n", customer); 3.160 + break; 3.161 + 3.162 + case 'q': 3.163 + fprintf(fp, "OK,issuing queue ticket\n"); 3.164 + issue_ticket(); 3.165 + break; 3.166 + 3.167 + case 'n': 3.168 + fprintf(fp, "OK,next customer\n"); 3.169 + next_customer(); 3.170 + break; 3.171 + 3.172 + case 'h': 3.173 + fprintf(fp, "OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, " 3.174 + "(n)ext, (q)ueue, (r)eset, (i)nput-reports, (h)elp.\n"); 3.175 + break; 3.176 + 3.177 + default: 3.178 + fprintf(fp, "ERR,unknown command: %s\n", cmd); 3.179 + } 3.180 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/dev.h Tue Jul 15 14:37:51 2014 +0300 4.3 @@ -0,0 +1,16 @@ 4.4 +#ifndef DEV_H_ 4.5 +#define DEV_H_ 4.6 + 4.7 +extern int customer, ticket; 4.8 + 4.9 +int start_dev(const char *devpath); 4.10 +void stop_dev(); 4.11 +void proc_dev_input(); 4.12 + 4.13 +void next_customer(); 4.14 +void issue_ticket(); 4.15 + 4.16 +int get_display_number(); 4.17 +int get_led_state(int led); 4.18 + 4.19 +#endif /* DEV_H_ */
5.1 --- a/src/main.cc Tue Jul 15 05:44:26 2014 +0300 5.2 +++ b/src/main.cc Tue Jul 15 14:37:51 2014 +0300 5.3 @@ -20,6 +20,8 @@ 5.4 static void process_events(); 5.5 static int translate_keysym(KeySym sym); 5.6 5.7 +static int proc_args(int argc, char **argv); 5.8 + 5.9 static Display *dpy; 5.10 static Window win; 5.11 static GLXContext ctx; 5.12 @@ -30,10 +32,15 @@ 5.13 static bool redisplay_pending; 5.14 static bool win_mapped; 5.15 5.16 -int main() 5.17 +static int fakefd = -1; 5.18 +static char *fake_devpath; 5.19 + 5.20 +int main(int argc, char **argv) 5.21 { 5.22 + if(proc_args(argc, argv) == -1) { 5.23 + return 1; 5.24 + } 5.25 if(!init()) { 5.26 - fprintf(stderr, "X11/OpenGL initialization failed\n"); 5.27 return 1; 5.28 } 5.29 atexit(cleanup); 5.30 @@ -45,12 +52,18 @@ 5.31 FD_ZERO(&rd); 5.32 5.33 FD_SET(xfd, &rd); 5.34 + FD_SET(fakefd, &rd); 5.35 5.36 - while(select(xfd + 1, &rd, 0, 0, 0) == -1 && errno == EINTR); 5.37 + int maxfd = xfd > fakefd ? xfd : fakefd; 5.38 + 5.39 + while(select(maxfd + 1, &rd, 0, 0, 0) == -1 && errno == EINTR); 5.40 5.41 if(FD_ISSET(xfd, &rd)) { 5.42 process_events(); 5.43 } 5.44 + if(FD_ISSET(fakefd, &rd)) { 5.45 + proc_dev_input(); 5.46 + } 5.47 5.48 if(redisplay_pending) { 5.49 display(); 5.50 @@ -62,7 +75,11 @@ 5.51 5.52 static bool init() 5.53 { 5.54 - start_dev(); 5.55 + if(fake_devpath) { 5.56 + if((fakefd = start_dev(fake_devpath)) == -1) { 5.57 + return false; 5.58 + } 5.59 + } 5.60 5.61 if(!(dpy = XOpenDisplay(0))) { 5.62 fprintf(stderr, "failed to connect to the X server!\n"); 5.63 @@ -290,3 +307,24 @@ 5.64 } 5.65 return (int)sym; 5.66 } 5.67 + 5.68 +static int proc_args(int argc, char **argv) 5.69 +{ 5.70 + for(int i=1; i<argc; i++) { 5.71 + if(argv[i][0] == '-') { 5.72 + fprintf(stderr, "unexpected option: %s\n", argv[i]); 5.73 + return -1; 5.74 + 5.75 + } else { 5.76 + if(fake_devpath) { 5.77 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 5.78 + return -1; 5.79 + } 5.80 + fake_devpath = argv[i]; 5.81 + } 5.82 + } 5.83 + if(!fake_devpath) { 5.84 + fprintf(stderr, "no device path specified, running standalone\n"); 5.85 + } 5.86 + return 0; 5.87 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/timer.cc Tue Jul 15 14:37:51 2014 +0300 6.3 @@ -0,0 +1,15 @@ 6.4 +#include <unistd.h> 6.5 +#include <sys/time.h> 6.6 + 6.7 +unsigned long get_msec() 6.8 +{ 6.9 + static struct timeval tv0; 6.10 + struct timeval tv; 6.11 + 6.12 + gettimeofday(&tv, 0); 6.13 + if(tv0.tv_sec == 0 && tv0.tv_usec == 0) { 6.14 + tv0 = tv; 6.15 + return 0; 6.16 + } 6.17 + return (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000; 6.18 +}