blob: f6c431576c20aff9975e2a8375a2af27dc6b78a3 [file] [log] [blame]
San Mehata430b2b2014-09-23 08:30:51 -07001#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
9typedef 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 */
16int 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
36void delete_control_file(single_instance_struct* str)
37{
38 remove(str->filename);
39}
40
41void close_control_file(single_instance_struct* str)
42{
43 close(str->fd);
44}
45
46typedef void (*event_dispatcher)(char* message);
47
48int 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
78int 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
89int 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
100void 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
116single_instance_struct str1 = { "/tmp/1instance" };
117
118void 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
129int 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