Package: digitemp
Version: 3.6.0+dfsg1-2
Severity: normal
Tags: patch

Digitemp in daemon mode do not handle disappearing devices (e.g. DS9097
via usb to serial adapter).
It closes the fd, but tries to access that descriptor forever afterwards.

I suggest a workaround that works on my system for a long time.
It contains two patches.

The first patch (close.patch) helps to forget fd after close, overwriting fd 
value
with -1.
The second patch (assert.patch) calls assert when digitemp tries to access 
closed descriptor.

This is not real solution since error is handled by assert in library,
but it works fine, when digitemp daemon is running under an external
supervisor, that restarts failing processes.


-- System Information:
Debian Release: jessie/sid
  APT prefers testing
  APT policy: (990, 'testing'), (192, 'unstable')
Architecture: i386 (x86_64)

Kernel: Linux 3.11-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=ru_RU.UTF-8, LC_CTYPE=ru_RU.UTF-8 (charmap=UTF-8) (ignored: LC_ALL 
set to ru_RU.UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages digitemp depends on:
ii  libc6         2.17-93
ii  libusb-0.1-4  2:0.1.12-23.2

digitemp recommends no packages.

Versions of packages digitemp suggests:
pn  mysql-server  <none>
ii  python        2.7.5-5
ii  rrdtool       1.4.7-2+b1

-- no debconf information
--- a/userial/ds9097/linuxlnk.c
+++ b/userial/ds9097/linuxlnk.c
@@ -135,6 +135,7 @@
 	OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
 	perror("owTouchReset: Error with tcsetattr 1");
 	close(fd[portnum]);
+	fd[portnum] = -1;
 	return FALSE;
      }
    
@@ -193,6 +194,7 @@
 	OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
 	perror("Reset: Error with tcsetattr 2");
 	close(fd[portnum]);
+	fd[portnum] = -1;
 	return FALSE;
      }
 
--- a/userial/ds9097/linuxses.c
+++ b/userial/ds9097/linuxses.c
@@ -77,6 +77,7 @@
 	OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
 	perror("owAcquire: failed to set attributes");
 	close(fd[portnum]);
+	fd[portnum] = -1;
 	return FALSE;
      }
    
@@ -106,6 +107,7 @@
 	OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
 	perror("owAcquire: failed to set attributes");	
 	close(fd[portnum]);
+	fd[portnum] = -1;
 	return FALSE;
      }
       
@@ -124,7 +126,6 @@
 	/* We failed doing that */
 	OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
 	perror("owAcquire: failed to set attributes");
-	close(fd[portnum]);
      }
    
    /* Close the port */
@@ -134,6 +135,7 @@
 	OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
 	perror("owAcquire: failed to close port");
      }
+   fd[portnum] = -1;
 
    /* we should return an error condition here but MAXIMS API is 
     * badly designed */
--- a/userial/ds9097/linuxlnk.c
+++ b/userial/ds9097/linuxlnk.c
@@ -73,6 +73,8 @@
 
 #include <ownet.h>
 
+#include <assert.h>
+
 /* The UART_FIFO_SIZE defines the amount of bytes that are written before
  * reading the reply. Any positive value should work and 16 is probably low
  * enough to avoid losing bytes in even most extreme situations on all modern
@@ -111,6 +113,7 @@
  * the reset has failed and it returns FALSE. */
 SMALLINT owTouchReset(int portnum)
 {
+   assert(fd[portnum] != -1);
    fd_set readset;
    struct timeval timeout_tv;
    
@@ -206,6 +209,7 @@
 
 void owTouchBlock( int portnum, int timeout, int nbits, uchar *transfer_buf)
 {
+   assert(fd[portnum] != -1);
    fd_set readset;
    char *buf;
    struct timeval timeout_tv;
@@ -325,6 +329,7 @@
 //
 SMALLINT owTouchBit(int portnum, SMALLINT sbit)
 {
+   assert(fd[portnum] != -1);
    //unsigned char c = 0;
   unsigned char sendbit;
    unsigned char inbit = 0;
--- a/userial/ds9097/linuxses.c
+++ b/userial/ds9097/linuxses.c
@@ -41,6 +41,8 @@
 #include <ownet.h>
 #include <sys/file.h>
 
+#include <assert.h>
+
 /* local function prototypes */
 SMALLINT owAcquire(int,char *);
 void     owRelease(int);
@@ -120,6 +122,7 @@
 /* Release port 'portnum' */
 void owRelease(int portnum)
 {
+   assert(fd[portnum] != -1);
    /* Restore original settings */
    if(tcsetattr(fd[portnum], TCSANOW, &term_orig[portnum]) < 0 )
      {

Reply via email to