1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <stdio.h>
8
9 typedef struct {
10 char* filename; /* this file is the pipe (set by user) */
11 char is_server; /* this is set by open_control_file */
12 int fd; /* this is set by open_control_file */
13 } single_instance_struct;
14
15 /* returns fd, is_server is set to -1 if server, 0 if client */
open_control_file(single_instance_struct * str)16 int open_control_file(single_instance_struct* str)
17 {
18 struct stat buf;
19
20 if(stat(str->filename,&buf)) {
21 mkfifo(str->filename,128|256);
22 str->is_server=-1;
23 str->fd=open(str->filename,O_NONBLOCK|O_RDONLY);
24 } else {
25 str->fd=open(str->filename,O_NONBLOCK|O_WRONLY);
26 if(errno==ENXIO) {
27 str->is_server=-1;
28 str->fd=open(str->filename,O_NONBLOCK|O_RDONLY);
29 } else
30 str->is_server=0;
31 }
32
33 return(str->fd);
34 }
35
delete_control_file(single_instance_struct * str)36 void delete_control_file(single_instance_struct* str)
37 {
38 remove(str->filename);
39 }
40
close_control_file(single_instance_struct * str)41 void close_control_file(single_instance_struct* str)
42 {
43 close(str->fd);
44 }
45
46 typedef void (*event_dispatcher)(char* message);
47
get_next_message(char * buffer,int len,single_instance_struct * str,int usecs)48 int get_next_message(char* buffer,int len,single_instance_struct* str,int usecs)
49 {
50 struct timeval tv;
51 fd_set fdset;
52 int num_fds;
53
54 FD_ZERO(&fdset);
55 FD_SET(str->fd,&fdset);
56 tv.tv_sec=0;
57 tv.tv_usec=usecs;
58
59 num_fds=select(str->fd+1,&fdset,NULL,NULL,&tv);
60 if(num_fds) {
61 int reallen;
62
63 reallen=read(str->fd,buffer,len);
64 if(reallen==0) {
65 close(str->fd);
66 str->fd=open(str->filename,O_NONBLOCK|O_RDONLY);
67 num_fds--;
68 }
69 buffer[reallen]=0;
70 #ifdef DEBUG_1INSTANCE
71 if(reallen!=0) rfbLog("message received: %s.\n",buffer);
72 #endif
73 }
74
75 return(num_fds);
76 }
77
dispatch_event(single_instance_struct * str,event_dispatcher dispatcher,int usecs)78 int dispatch_event(single_instance_struct* str,event_dispatcher dispatcher,int usecs)
79 {
80 char buffer[1024];
81 int num_fds;
82
83 if((num_fds=get_next_message(buffer,1024,str,usecs)) && buffer[0])
84 dispatcher(buffer);
85
86 return(num_fds);
87 }
88
loop_if_server(single_instance_struct * str,event_dispatcher dispatcher)89 int loop_if_server(single_instance_struct* str,event_dispatcher dispatcher)
90 {
91 open_control_file(str);
92 if(str->is_server) {
93 while(1)
94 dispatch_event(str,dispatcher,50);
95 }
96
97 return(str->fd);
98 }
99
send_message(single_instance_struct * str,char * message)100 void send_message(single_instance_struct* str,char* message)
101 {
102 #ifdef DEBUG_1INSTANCE
103 int i=
104 #endif
105 write(str->fd,message,strlen(message));
106 #ifdef DEBUG_1INSTANCE
107 rfbLog("send: %s => %d(%d)\n",message,i,strlen(message));
108 #endif
109 }
110
111 #ifdef DEBUG_MAIN
112
113 #include <stdio.h>
114 #include <stdlib.h>
115
116 single_instance_struct str1 = { "/tmp/1instance" };
117
my_dispatcher(char * message)118 void my_dispatcher(char* message)
119 {
120 #ifdef DEBUG_1INSTANCE
121 rfbLog("Message arrived: %s.\n",message);
122 #endif
123 if(!strcmp(message,"quit")) {
124 delete_control_file(str1);
125 exit(0);
126 }
127 }
128
main(int argc,char ** argv)129 int main(int argc,char** argv)
130 {
131 int i;
132
133 loop_if_server(str1,my_dispatcher);
134
135 for(i=1;i<argc;i++)
136 send_event(str1,argv[i]);
137
138 return(0);
139 }
140
141 #endif
142