Home | History | Annotate | Download | only in examples
      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