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 */ 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 36 void delete_control_file(single_instance_struct* str) 37 { 38 remove(str->filename); 39 } 40 41 void close_control_file(single_instance_struct* str) 42 { 43 close(str->fd); 44 } 45 46 typedef void (*event_dispatcher)(char* message); 47 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 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 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 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 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 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