Untested attempt to get rid of SIGIO pain
[gnokii.git] / common / devices / device.c
index 6a28122..826eee4 100644 (file)
@@ -42,7 +42,7 @@ static bool duringwrite;
   pthread_t selThread;
 #endif
 
-static int device_portfd = -1;
+int device_portfd = -1;
 
 /*
  * Structure to store the filedescriptor we use.
@@ -126,7 +126,10 @@ size_t device_write(__const __ptr_t __buf, size_t __n) {
   u8 buffer[300];
   size_t mysize;
   
-  while (duringwrite) {}
+  while (duringwrite) {
+    fprintf(stderr,"device_write: reentrance violation!\n");
+    _exit(1);
+  }
 
   memcpy(buffer,__buf,__n);
   AppendLog(buffer,__n,true);
@@ -136,6 +139,8 @@ size_t device_write(__const __ptr_t __buf, size_t __n) {
     default        : mysize = serial_write(device_portfd, __buf, __n); break;
   }
   duringwrite=false;
+  if (mysize!=__n)
+    fprintf(stderr,"WARNING: device_write(__n=%ld)=%ld\n",(long)__n,(long)mysize);
   return mysize;
 }
 
@@ -159,7 +164,7 @@ static void device_dumpserial(void)
 
 static char SigHandler_buffer[255];
 
-static void SigHandler(int status)
+void SigHandler(int status)
 {
   int count, res;
 
@@ -174,6 +179,49 @@ static void SigHandler(int status)
   LIVE_ENABLE;
 }
 
+#ifdef UCLINUX
+void usleep_watchdevice(unsigned long usecs)
+{
+int err;
+fd_set readfds;
+struct timeval target,timeout;
+
+  if (gettimeofday(&target/*tv*/,NULL/*tz*/))
+    perror("usleep_watchdevice()/gettimeofday(2) init");
+  target.tv_usec+=usecs%1000000;
+  target.tv_sec +=usecs/1000000 + (target.tv_usec/1000000);
+  target.tv_usec%=1000000;
+
+  for (;;)
+    FD_ZERO(&readfds);
+    if (device_portfd>=0)
+      FD_SET(device_portfd,&readfds);
+
+    if (gettimeofday(&timeout/*tv*/,NULL/*tz*/))
+      perror("usleep_watchdevice()/gettimeofday(2) loop");
+    if (target.tv_sec  < timeout.tv_sec)
+      return;
+    timeout.tv_sec =target.tv_sec - timeout.tv_sec;
+    if (target.tv_usec < timeout.tv_usec) {
+      target.tv_usec+=1000000;
+      if (target.tv_sec <= 0)
+       return;
+      target.tv_sec--;
+    }
+    timeout.tv_usec=target.tv_usec - timeout.tv_usec;
+
+    err=select((device_portfd<0 ? 0 : device_portfd+1),&readfds,NULL,NULL,&timeout);
+    if ( err > 0 ) {
+      if (device_portfd>=0 && FD_ISSET(device_portfd,&readfds)) {
+       /* call singal handler to process incoming data */
+       SigHandler(0);
+      }
+    } else {
+      if (err == -1)
+      perror("Error in SelectLoop");
+    }
+}
+#endif
 
 #if defined(__svr4__) || defined(__FreeBSD__)
 /* thread for handling incoming data */
@@ -209,11 +257,13 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp
 
   char text[100];
 
+#ifndef UCLINUX
 #if defined(__svr4__) || defined(__FreeBSD__)
   int rtn;
 #else
   struct sigaction sig_io;
 #endif
+#endif /* UCLINUX */
 
 #ifndef UCLINUX
 #ifdef DEBUG
@@ -270,6 +320,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp
 //    return false;
 //  }
 
+#ifndef UCLINUX
 #if defined(__svr4__) || defined(__FreeBSD__)
 #else
         /* Set up and install handler before enabling async IO on port. */
@@ -277,6 +328,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp
         sig_io.sa_flags = 0;
         sigaction (SIGIO, &sig_io, NULL);
 #endif
+#endif /* UCLINUX */
 
     /* Open device. */
     result = device_open(PortDevice, with_odd_parity);
@@ -286,6 +338,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp
       return false;
     }
 
+#ifndef UCLINUX
 #if defined(__svr4__) || defined(__FreeBSD__)
     /* create a thread to handle incoming data from mobile phone */
     rtn=pthread_create(&selThread,NULL,(void*)SelectLoop,(void*)NULL);
@@ -294,6 +347,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp
       return false;
     }
 #endif
+#endif /* UCLINUX */
 
   return true;
 }