From 7e20e7571fd9e4d46f58ef132e5b39725bdc1bdc Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Mon, 11 Dec 2006 12:47:35 +0000
Subject: [PATCH] Make the code compile warning-free:

- declare a dummy "struct timezone" for some Win32 systems (MinGW)
- fix a few printf() argument types
- get rid off the prevailing "all filedescriptors are of type int"
  attitude

The last item required a large sweep across the code, in order to
replace all "int fd"s by "struct filedescriptor *fd"s, and pass
pointers (as we cannot pass a union directly).  In return, the
code is now supposed to be fully 64-bit safe, rather than relying
on a 64-bit pointer being converted to a (32-bit) int and back
to a pointer as we did previously.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@694 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog     | 31 ++++++++++++++++++++++++++++
 avr910.c      | 12 +++++------
 butterfly.c   | 12 +++++------
 jtagmkI.c     | 30 +++++++++++++--------------
 jtagmkII.c    | 24 +++++++++++-----------
 lists.c       |  4 ++--
 par.c         | 30 +++++++++++++--------------
 pgm.h         |  5 +++--
 ppi.c         | 55 +++++++++++++++++++++++++------------------------
 ppi.h         | 16 +++++++--------
 ppiwin.c      | 44 +++++++++++++++++++++------------------
 ser_posix.c   | 57 ++++++++++++++++++++++++++-------------------------
 ser_win32.c   | 32 ++++++++++++++---------------
 serbb_posix.c | 26 +++++++++++------------
 serbb_win32.c |  8 ++++----
 serial.h      | 17 +++++++++------
 stk500.c      | 15 ++++++--------
 stk500v2.c    | 22 ++++++++++----------
 usb_libusb.c  | 27 ++++++++++++------------
 19 files changed, 253 insertions(+), 214 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4f1a1558..cfa6e9af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2006-12-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+	* avr910.c: Make the code compile warning-free:  
+	- declare a dummy "struct timezone" for some Win32 systems (MinGW)
+	- fix a few printf() argument types
+	- get rid off the prevailing "all filedescriptors are of type int"
+	  attitude
+	The last item required a large sweep across the code, in order to
+	replace all "int fd"s by "struct filedescriptor *fd"s, and pass
+	pointers (as we cannot pass a union directly).  In return, the
+	code is now supposed to be fully 64-bit safe, rather than relying
+	on a 64-bit pointer being converted to a (32-bit) int and back
+	to a pointer as we did previously.
+	* butterfly.c: (Ditto.)
+	* jtagmkI.c: (Ditto.)
+	* jtagmkII.c: (Ditto.)
+	* lists.c: (Ditto.)
+	* par.c: (Ditto.)
+	* pgm.h: (Ditto.)
+	* ppi.c: (Ditto.)
+	* ppi.h: (Ditto.)
+	* ppiwin.c: (Ditto.)
+	* ser_posix.c: (Ditto.)
+	* ser_win32.c: (Ditto.)
+	* serbb_posix.c: (Ditto.)
+	* serbb_win32.c: (Ditto.)
+	* serial.h: (Ditto.)
+	* stk500.c: (Ditto.)
+	* stk500v2.c: (Ditto.)
+	* usb_libusb.c: (Ditto.)
+
 2006-11-23 Joerg Wunsch <j@uriah.heep.sax.de>
 
 	Implement EEPROM access through debugWire.
diff --git a/avr910.c b/avr910.c
index 6a6421ff..1d0f4b75 100644
--- a/avr910.c
+++ b/avr910.c
@@ -47,7 +47,7 @@ static char has_auto_incr_addr;
 
 static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
 {
-  return serial_send(pgm->fd, (unsigned char *)buf, len);
+  return serial_send(&pgm->fd, (unsigned char *)buf, len);
 }
 
 
@@ -55,7 +55,7 @@ static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
 {
   int rv;
 
-  rv = serial_recv(pgm->fd, (unsigned char *)buf, len);
+  rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
   if (rv < 0) {
     fprintf(stderr,
 	    "%s: avr910_recv(): programmer is not responding\n",
@@ -68,7 +68,7 @@ static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
 
 static int avr910_drain(PROGRAMMER * pgm, int display)
 {
-  return serial_drain(pgm->fd, display);
+  return serial_drain(&pgm->fd, display);
 }
 
 
@@ -271,7 +271,7 @@ static int avr910_open(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, pgm->baudrate);
+  serial_open(port, pgm->baudrate, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -285,8 +285,8 @@ static void avr910_close(PROGRAMMER * pgm)
 {
   avr910_leave_prog_mode(pgm);
 
-  serial_close(pgm->fd);
-  pgm->fd = -1;
+  serial_close(&pgm->fd);
+  pgm->fd.ifd = -1;
 }
 
 
diff --git a/butterfly.c b/butterfly.c
index 3c3465a3..d6661ef7 100644
--- a/butterfly.c
+++ b/butterfly.c
@@ -69,7 +69,7 @@ static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
 {
   no_show_func_info();
 
-  return serial_send(pgm->fd, (unsigned char *)buf, len);
+  return serial_send(&pgm->fd, (unsigned char *)buf, len);
 }
 
 
@@ -79,7 +79,7 @@ static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
 
   no_show_func_info();
 
-  rv = serial_recv(pgm->fd, (unsigned char *)buf, len);
+  rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
   if (rv < 0) {
     fprintf(stderr,
 	    "%s: butterfly_recv(): programmer is not responding\n",
@@ -94,7 +94,7 @@ static int butterfly_drain(PROGRAMMER * pgm, int display)
 {
   no_show_func_info();
 
-  return serial_drain(pgm->fd, display);
+  return serial_drain(&pgm->fd, display);
 }
 
 
@@ -359,7 +359,7 @@ static int butterfly_open(PROGRAMMER * pgm, char * port)
   if(pgm->baudrate == 0) {
     pgm->baudrate = 19200;
   }
-  pgm->fd = serial_open(port, pgm->baudrate);
+  serial_open(port, pgm->baudrate, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -378,8 +378,8 @@ static void butterfly_close(PROGRAMMER * pgm)
   butterfly_send(pgm, "E", 1);
   butterfly_vfy_cmd_sent(pgm, "exit bootloader");
 
-  serial_close(pgm->fd);
-  pgm->fd = -1;
+  serial_close(&pgm->fd);
+  pgm->fd.ifd = -1;
 }
 
 
diff --git a/jtagmkI.c b/jtagmkI.c
index 35c0faa9..04aed441 100644
--- a/jtagmkI.c
+++ b/jtagmkI.c
@@ -194,7 +194,7 @@ static int jtagmkI_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
   buf[len] = ' ';		/* "CRC" */
   buf[len + 1] = ' ';		/* EOP */
 
-  if (serial_send(pgm->fd, buf, len + 2) != 0) {
+  if (serial_send(&pgm->fd, buf, len + 2) != 0) {
     fprintf(stderr,
 	    "%s: jtagmkI_send(): failed to send command to serial port\n",
 	    progname);
@@ -208,7 +208,7 @@ static int jtagmkI_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
 
 static void jtagmkI_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
 {
-  if (serial_recv(pgm->fd, buf, len) != 0) {
+  if (serial_recv(&pgm->fd, buf, len) != 0) {
     fprintf(stderr,
 	    "\n%s: jtagmkI_recv(): failed to send command to serial port\n",
 	    progname);
@@ -223,7 +223,7 @@ static void jtagmkI_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
 
 static int jtagmkI_drain(PROGRAMMER * pgm, int display)
 {
-  return serial_drain(pgm->fd, display);
+  return serial_drain(&pgm->fd, display);
 }
 
 
@@ -248,14 +248,14 @@ static int jtagmkI_resync(PROGRAMMER * pgm, int maxtries, int signon)
       fprintf(stderr, "%s: jtagmkI_resync(): Sending sync command: ",
 	      progname);
 
-    if (serial_send(pgm->fd, buf, 1) != 0) {
+    if (serial_send(&pgm->fd, buf, 1) != 0) {
       fprintf(stderr,
 	      "\n%s: jtagmkI_resync(): failed to send command to serial port\n",
 	      progname);
       serial_recv_timeout = otimeout;
       return -1;
     }
-    if (serial_recv(pgm->fd, resp, 1) == 0 && resp[0] == RESP_OK) {
+    if (serial_recv(&pgm->fd, resp, 1) == 0 && resp[0] == RESP_OK) {
       if (verbose >= 2)
 	fprintf(stderr, "got RESP_OK\n");
       break;
@@ -280,14 +280,14 @@ static int jtagmkI_resync(PROGRAMMER * pgm, int maxtries, int signon)
 	fprintf(stderr, "%s: jtagmkI_resync(): Sending sign-on command: ",
 		progname);
 
-      if (serial_send(pgm->fd, buf, 4) != 0) {
+      if (serial_send(&pgm->fd, buf, 4) != 0) {
 	fprintf(stderr,
 		"\n%s: jtagmkI_resync(): failed to send command to serial port\n",
 		progname);
 	serial_recv_timeout = otimeout;
 	return -1;
       }
-      if (serial_recv(pgm->fd, resp, 9) == 0 && resp[0] == RESP_OK) {
+      if (serial_recv(&pgm->fd, resp, 9) == 0 && resp[0] == RESP_OK) {
 	if (verbose >= 2)
 	  fprintf(stderr, "got RESP_OK\n");
 	break;
@@ -486,7 +486,7 @@ static int jtagmkI_program_disable(PROGRAMMER * pgm)
   if (!prog_enabled)
     return 0;
 
-  if (pgm->fd != -1) {
+  if (pgm->fd.ifd != -1) {
     buf[0] = CMD_LEAVE_PROGMODE;
     if (verbose >= 2)
       fprintf(stderr, "%s: jtagmkI_program_disable(): "
@@ -552,7 +552,7 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
                 progname, pgm->baudrate);
       if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) {
         initial_baudrate = pgm->baudrate; /* don't adjust again later */
-        serial_setspeed(pgm->fd, pgm->baudrate);
+        serial_setspeed(&pgm->fd, pgm->baudrate);
       }
     }
   }
@@ -653,7 +653,7 @@ static int jtagmkI_open(PROGRAMMER * pgm, char * port)
       fprintf(stderr,
               "%s: jtagmkI_open(): trying to sync at baud rate %ld:\n",
               progname, baudtab[i].baud);
-    pgm->fd = serial_open(port, baudtab[i].baud);
+    serial_open(port, baudtab[i].baud, &pgm->fd);
 
     /*
      * drain any extraneous input
@@ -667,13 +667,13 @@ static int jtagmkI_open(PROGRAMMER * pgm, char * port)
       return 0;
     }
 
-    serial_close(pgm->fd);
+    serial_close(&pgm->fd);
   }
 
   fprintf(stderr,
           "%s: jtagmkI_open(): failed to synchronize to ICE\n",
           progname);
-  pgm->fd = -1;
+  pgm->fd.ifd = -1;
 
   return -1;
 }
@@ -685,11 +685,11 @@ static void jtagmkI_close(PROGRAMMER * pgm)
   if (verbose >= 2)
     fprintf(stderr, "%s: jtagmkI_close()\n", progname);
 
-  if (pgm->fd != -1) {
-    serial_close(pgm->fd);
+  if (pgm->fd.ifd != -1) {
+    serial_close(&pgm->fd);
   }
 
-  pgm->fd = -1;
+  pgm->fd.ifd = -1;
 }
 
 
diff --git a/jtagmkII.c b/jtagmkII.c
index 8a42174b..b9ed4751 100644
--- a/jtagmkII.c
+++ b/jtagmkII.c
@@ -359,7 +359,7 @@ int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
 
   crcappend(buf, len + 8);
 
-  if (serial_send(pgm->fd, buf, len + 10) != 0) {
+  if (serial_send(&pgm->fd, buf, len + 10) != 0) {
     fprintf(stderr,
 	    "%s: jtagmkII_send(): failed to send command to serial port\n",
 	    progname);
@@ -374,7 +374,7 @@ int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
 
 static int jtagmkII_drain(PROGRAMMER * pgm, int display)
 {
-  return serial_drain(pgm->fd, display);
+  return serial_drain(&pgm->fd, display);
 }
 
 
@@ -423,9 +423,9 @@ static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
       if (ignorpkt) {
 	/* skip packet's contents */
 	for(l = 0; l < msglen; l++)
-	  rv += serial_recv(pgm->fd, &c, 1);
+	  rv += serial_recv(&pgm->fd, &c, 1);
       } else {
-	rv += serial_recv(pgm->fd, buf + 8, msglen);
+	rv += serial_recv(&pgm->fd, buf + 8, msglen);
       }
       if (rv != 0) {
 	timedout:
@@ -438,7 +438,7 @@ static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
 	return -1;
       }
     } else {
-      if (serial_recv(pgm->fd, &c, 1) != 0)
+      if (serial_recv(&pgm->fd, &c, 1) != 0)
 	goto timedout;
     }
     checksum ^= c;
@@ -1099,7 +1099,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
 		"trying to set baudrate to %d\n",
 		progname, pgm->baudrate);
       if (jtagmkII_setparm(pgm, PAR_BAUD_RATE, &b) == 0)
-	serial_setspeed(pgm->fd, pgm->baudrate);
+	serial_setspeed(&pgm->fd, pgm->baudrate);
     }
   }
   if (!(pgm->flag & PGM_FL_IS_DW) && pgm->bitclock != 0.0) {
@@ -1199,7 +1199,7 @@ static int jtagmkII_open(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, baud);
+  serial_open(port, baud, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -1244,7 +1244,7 @@ static int jtagmkII_open_dw(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, baud);
+  serial_open(port, baud, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -1289,7 +1289,7 @@ static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, baud);
+  serial_open(port, baud, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -1334,7 +1334,7 @@ static int jtagmkII_dragon_open_dw(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, baud);
+  serial_open(port, baud, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -1418,8 +1418,8 @@ void jtagmkII_close(PROGRAMMER * pgm)
 	    progname, jtagmkII_get_rc(c));
   }
 
-  serial_close(pgm->fd);
-  pgm->fd = -1;
+  serial_close(&pgm->fd);
+  pgm->fd.ifd = -1;
 }
 
 
diff --git a/lists.c b/lists.c
index 8705fce7..3d1cfc64 100644
--- a/lists.c
+++ b/lists.c
@@ -1290,8 +1290,8 @@ int lprint ( FILE * f, LISTID lid )
 
   l = (LIST *)lid;
 
-  fprintf ( f, "list id 0x%08x internal data structures:\n", 
-            (unsigned int)lid );
+  fprintf ( f, "list id %p internal data structures:\n", 
+            lid );
 #if CHECK_MAGIC
   if ((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) {
     fprintf ( f, "  *** WARNING: LIST MAGIC IS CORRUPT ***\n" );
diff --git a/par.c b/par.c
index ce327bf0..34b9e2a4 100644
--- a/par.c
+++ b/par.c
@@ -96,9 +96,9 @@ static int par_setpin(PROGRAMMER * pgm, int pin, int value)
     value = !value;
 
   if (value)
-    ppi_set(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+    ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
   else
-    ppi_clr(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+    ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
 
   if (pgm->ispdelay > 1)
     bitbang_delay(pgm->ispdelay);
@@ -129,7 +129,7 @@ static int par_getpin(PROGRAMMER * pgm, int pin)
 
   pin--;
 
-  value = ppi_get(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+  value = ppi_get(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
 
   if (value)
     value = 1;
@@ -160,19 +160,19 @@ static int par_highpulsepin(PROGRAMMER * pgm, int pin)
     inverted = !inverted;
 
   if (inverted) {
-    ppi_clr(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+    ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
     if (pgm->ispdelay > 1)
       bitbang_delay(pgm->ispdelay);
 
-    ppi_set(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+    ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
     if (pgm->ispdelay > 1)
       bitbang_delay(pgm->ispdelay);
   } else {
-    ppi_set(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+    ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
     if (pgm->ispdelay > 1)
       bitbang_delay(pgm->ispdelay);
 
-    ppi_clr(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+    ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
     if (pgm->ispdelay > 1)
       bitbang_delay(pgm->ispdelay);
   }
@@ -250,8 +250,8 @@ static int par_open(PROGRAMMER * pgm, char * port)
 
   bitbang_check_prerequisites(pgm);
 
-  pgm->fd = ppi_open(port);
-  if (pgm->fd < 0) {
+  ppi_open(port, &pgm->fd);
+  if (pgm->fd.ifd < 0) {
     fprintf(stderr, "%s: failed to open parallel port \"%s\"\n\n",
             progname, port);
     exit(1);
@@ -260,14 +260,14 @@ static int par_open(PROGRAMMER * pgm, char * port)
   /*
    * save pin values, so they can be restored when device is closed
    */
-  rc = ppi_getall(pgm->fd, PPIDATA);
+  rc = ppi_getall(&pgm->fd, PPIDATA);
   if (rc < 0) {
     fprintf(stderr, "%s: error reading status of ppi data port\n", progname);
     return -1;
   }
   pgm->ppidata = rc;
 
-  rc = ppi_getall(pgm->fd, PPICTRL);
+  rc = ppi_getall(&pgm->fd, PPICTRL);
   if (rc < 0) {
     fprintf(stderr, "%s: error reading status of ppi ctrl port\n", progname);
     return -1;
@@ -285,8 +285,8 @@ static void par_close(PROGRAMMER * pgm)
    * Restore pin values before closing,
    * but ensure that buffers are turned off.
    */
-  ppi_setall(pgm->fd, PPIDATA, pgm->ppidata);
-  ppi_setall(pgm->fd, PPICTRL, pgm->ppictrl);
+  ppi_setall(&pgm->fd, PPIDATA, pgm->ppidata);
+  ppi_setall(&pgm->fd, PPICTRL, pgm->ppictrl);
 
   par_setpin(pgm, pgm->pinno[PPI_AVR_BUFF], 1);
 
@@ -320,8 +320,8 @@ static void par_close(PROGRAMMER * pgm)
     break;
   }
 
-  ppi_close(pgm->fd);
-  pgm->fd = -1;
+  ppi_close(&pgm->fd);
+  pgm->fd.ifd = -1;
 }
 
 static void par_display(PROGRAMMER * pgm, char * p)
diff --git a/pgm.h b/pgm.h
index bebdf6e3..78efd350 100644
--- a/pgm.h
+++ b/pgm.h
@@ -27,7 +27,7 @@
 #include "avrpart.h"
 #include "lists.h"
 #include "pindefs.h"
-
+#include "serial.h"
 
 #define ON  1
 #define OFF 0
@@ -63,7 +63,7 @@ typedef struct programmer_t {
   int baudrate;
   double bitclock;    /* JTAG ICE clock period in microseconds */
   int ispdelay;    /* ISP clock delay */
-  int fd;
+  union filedescriptor fd;
   int  page_size;  /* page size if the programmer supports paged write/load */
   int  (*rdy_led)        (struct programmer_t * pgm, int value);
   int  (*err_led)        (struct programmer_t * pgm, int value);
@@ -124,6 +124,7 @@ PROGRAMMER * pgm_new(void);
 void usleep(unsigned long us);
 
 #if !defined(HAVE_GETTIMEOFDAY)
+struct timezone;
 int gettimeofday(struct timeval *tv, struct timezone *tz);
 #endif /* HAVE_GETTIMEOFDAY */
 
diff --git a/ppi.c b/ppi.c
index 61502949..8070d668 100644
--- a/ppi.c
+++ b/ppi.c
@@ -54,7 +54,7 @@ enum {
   PPI_SHADOWREAD
 };
 
-int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
+int ppi_shadow_access(union filedescriptor *fdp, int reg, unsigned char *v, unsigned char action)
 {
   static unsigned char shadow[3];
   int shadow_num;
@@ -81,12 +81,12 @@ int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
       *v = shadow[shadow_num];
       break;
     case PPI_READ:
-      DO_PPI_READ(fd, reg, v);
+      DO_PPI_READ(fdp->ifd, reg, v);
       shadow[shadow_num]=*v;
       break;
     case PPI_WRITE:
       shadow[shadow_num]=*v;
-      DO_PPI_WRITE(fd, reg, v);
+      DO_PPI_WRITE(fdp->ifd, reg, v);
       break;
   }
   return 0;
@@ -95,14 +95,14 @@ int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
 /*
  * set the indicated bit of the specified register.
  */
-int ppi_set(int fd, int reg, int bit)
+int ppi_set(union filedescriptor *fdp, int reg, int bit)
 {
   unsigned char v;
   int rc;
 
-  rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
+  rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
   v |= bit;
-  rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
+  rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
 
   if (rc)
     return -1;
@@ -114,14 +114,14 @@ int ppi_set(int fd, int reg, int bit)
 /*
  * clear the indicated bit of the specified register.
  */
-int ppi_clr(int fd, int reg, int bit)
+int ppi_clr(union filedescriptor *fdp, int reg, int bit)
 {
   unsigned char v;
   int rc;
 
-  rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
+  rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
   v &= ~bit;
-  rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
+  rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
 
   if (rc)
     return -1;
@@ -133,12 +133,12 @@ int ppi_clr(int fd, int reg, int bit)
 /*
  * get the indicated bit of the specified register.
  */
-int ppi_get(int fd, int reg, int bit)
+int ppi_get(union filedescriptor *fdp, int reg, int bit)
 {
   unsigned char v;
   int rc;
 
-  rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
+  rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
   v &= bit;
 
   if (rc)
@@ -150,14 +150,14 @@ int ppi_get(int fd, int reg, int bit)
 /*
  * toggle the indicated bit of the specified register.
  */
-int ppi_toggle(int fd, int reg, int bit)
+int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
 {
   unsigned char v;
   int rc;
 
-  rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
+  rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
   v ^= bit;
-  rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
+  rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
 
   if (rc)
     return -1;
@@ -169,12 +169,12 @@ int ppi_toggle(int fd, int reg, int bit)
 /*
  * get all bits of the specified register.
  */
-int ppi_getall(int fd, int reg)
+int ppi_getall(union filedescriptor *fdp, int reg)
 {
   unsigned char v;
   int rc;
 
-  rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
+  rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
 
   if (rc)
     return -1;
@@ -185,13 +185,13 @@ int ppi_getall(int fd, int reg)
 /*
  * set all bits of the specified register to val.
  */
-int ppi_setall(int fd, int reg, int val)
+int ppi_setall(union filedescriptor *fdp, int reg, int val)
 {
   unsigned char v;
   int rc;
 
   v = val;
-  rc = ppi_shadow_access(fd, reg, &v, PPI_WRITE);
+  rc = ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
 
   if (rc)
     return -1;
@@ -200,7 +200,7 @@ int ppi_setall(int fd, int reg, int val)
 }
 
 
-int ppi_open(char * port)
+void ppi_open(char * port, union filedescriptor *fdp)
 {
   int fd;
   unsigned char v;
@@ -209,7 +209,8 @@ int ppi_open(char * port)
   if (fd < 0) {
     fprintf(stderr, "%s: can't open device \"%s\": %s\n",
               progname, port, strerror(errno));
-    return -1;
+    fdp->ifd = -1;
+    return;
   }
 
   ppi_claim (fd);
@@ -218,18 +219,18 @@ int ppi_open(char * port)
    * Initialize shadow registers
    */
 
-  ppi_shadow_access (fd, PPIDATA, &v, PPI_READ);
-  ppi_shadow_access (fd, PPICTRL, &v, PPI_READ);
-  ppi_shadow_access (fd, PPISTATUS, &v, PPI_READ);
+  ppi_shadow_access (fdp, PPIDATA, &v, PPI_READ);
+  ppi_shadow_access (fdp, PPICTRL, &v, PPI_READ);
+  ppi_shadow_access (fdp, PPISTATUS, &v, PPI_READ);
 
-  return fd;
+  fdp->ifd = fd;
 }
 
 
-void ppi_close(int fd)
+void ppi_close(union filedescriptor *fdp)
 {
-  ppi_release (fd);
-  close(fd);
+  ppi_release (fdp->ifd);
+  close(fdp->ifd);
 }
 
 #endif /* HAVE_PARPORT */
diff --git a/ppi.h b/ppi.h
index 80203aec..dd031e41 100644
--- a/ppi.h
+++ b/ppi.h
@@ -33,21 +33,21 @@ enum {
 
 
 
-int ppi_get       (int fd, int reg, int bit);
+int ppi_get       (union filedescriptor *fdp, int reg, int bit);
 
-int ppi_set       (int fd, int reg, int bit);
+int ppi_set       (union filedescriptor *fdp, int reg, int bit);
 
-int ppi_clr       (int fd, int reg, int bit);
+int ppi_clr       (union filedescriptor *fdp, int reg, int bit);
 
-int ppi_getall    (int fd, int reg);
+int ppi_getall    (union filedescriptor *fdp, int reg);
 
-int ppi_setall    (int fd, int reg, int val);
+int ppi_setall    (union filedescriptor *fdp, int reg, int val);
 
-int ppi_toggle    (int fd, int reg, int bit);
+int ppi_toggle    (union filedescriptor *fdp, int reg, int bit);
 
-int ppi_open      (char * port);
+void ppi_open     (char * port, union filedescriptor *fdp);
 
-void ppi_close    (int fd);
+void ppi_close    (union filedescriptor *fdp);
 
 #endif
 
diff --git a/ppiwin.c b/ppiwin.c
index f5be6517..1f33731c 100644
--- a/ppiwin.c
+++ b/ppiwin.c
@@ -43,6 +43,7 @@ reg = register as defined in an enum in ppi.h. This must be converted
 #include <windows.h>
 #include <sys/time.h>
 #include <windows.h>
+#include "serial.h"
 #include "ppi.h"
 
 extern char *progname;
@@ -74,7 +75,7 @@ static const winpp winports[DEVICE_MAX] =
 
 /* FUNCTION PROTOTYPES */
 static int winnt_pp_open(void);
-static unsigned short port_get(int fd, int reg);
+static unsigned short port_get(union filedescriptor *fdp, int reg);
 static unsigned char reg2offset(int reg);
 static unsigned char inb(unsigned short port);
 static void outb(unsigned char value, unsigned short port);
@@ -83,7 +84,7 @@ static void outb(unsigned char value, unsigned short port);
 
 /* FUNCTION DEFINITIONS */
 
-int ppi_open(char *port)
+void ppi_open(char *port, union filedescriptor *fdp)
 {
     unsigned char i;
     int fd;
@@ -93,7 +94,8 @@ int ppi_open(char *port)
     if(fd < 0)
     {
         fprintf(stderr, "%s: can't open device \"giveio\"\n\n", progname);
-        return(-1);
+        fdp->ifd = -1;
+        return;
     }
 
     /* Search the windows port names for a match */
@@ -110,10 +112,11 @@ int ppi_open(char *port)
     if(fd < 0)
     {
         fprintf(stderr, "%s: can't open device \"%s\"\n\n", progname, port);
-        return(-1);
+        fdp->ifd = -1;
+        return;
     }
 
-    return(fd);
+    fdp->ifd = fd;
 }
 
 
@@ -158,7 +161,7 @@ static int winnt_pp_open(void)
 
 
 
-void ppi_close(int fd)
+void ppi_close(union filedescriptor *fdp)
 {
     return;
 }
@@ -168,12 +171,12 @@ void ppi_close(int fd)
 /*
  * set the indicated bit of the specified register.
  */
-int ppi_set(int fd, int reg, int bit)
+int ppi_set(union filedescriptor *fdp, int reg, int bit)
 {
     unsigned char v;
     unsigned short port;
 
-    port = port_get(fd, reg);
+    port = port_get(fdp, reg);
     v = inb(port);
     v |= bit;
     outb(v, port);
@@ -184,12 +187,12 @@ int ppi_set(int fd, int reg, int bit)
 /*
  * clear the indicated bit of the specified register.
  */
-int ppi_clr(int fd, int reg, int bit)
+int ppi_clr(union filedescriptor *fdp, int reg, int bit)
 {
     unsigned char v;
     unsigned short port;
 
-    port = port_get(fd, reg);
+    port = port_get(fdp, reg);
     v = inb(port);
     v &= ~bit;
     outb(v, port);
@@ -201,11 +204,11 @@ int ppi_clr(int fd, int reg, int bit)
 /*
  * get the indicated bit of the specified register.
  */
-int ppi_get(int fd, int reg, int bit)
+int ppi_get(union filedescriptor *fdp, int reg, int bit)
 {
     unsigned char v;
 
-    v = inb(port_get(fd, reg));
+    v = inb(port_get(fdp, reg));
     v &= bit;
 
     return(v);
@@ -217,12 +220,12 @@ int ppi_get(int fd, int reg, int bit)
 /*
  * toggle the indicated bit of the specified register.
  */
-int ppi_toggle(int fd, int reg, int bit)
+int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
 {
     unsigned char v;
     unsigned short port;
 
-    port = port_get(fd, reg);
+    port = port_get(fdp, reg);
 
     v = inb(port);
     v ^= bit;
@@ -235,11 +238,11 @@ int ppi_toggle(int fd, int reg, int bit)
 /*
  * get all bits of the specified register.
  */
-int ppi_getall(int fd, int reg)
+int ppi_getall(union filedescriptor *fdp, int reg)
 {
     unsigned char v;
 
-    v = inb(port_get(fd, reg));
+    v = inb(port_get(fdp, reg));
 
     return((int)v);
 }
@@ -250,9 +253,9 @@ int ppi_getall(int fd, int reg)
 /*
  * set all bits of the specified register to val.
  */
-int ppi_setall(int fd, int reg, int val)
+int ppi_setall(union filedescriptor *fdp, int reg, int val)
 {
-    outb((unsigned char)val, port_get(fd, reg));
+    outb((unsigned char)val, port_get(fdp, reg));
     return 0;
 }
 
@@ -260,9 +263,9 @@ int ppi_setall(int fd, int reg, int val)
 
 
 /* Calculate port address to access. */
-static unsigned short port_get(int fd, int reg)
+static unsigned short port_get(union filedescriptor *fdp, int reg)
 {
-    return((unsigned short)(fd + reg2offset(reg)));
+    return((unsigned short)(fdp->ifd + reg2offset(reg)));
 }
 
 
@@ -318,6 +321,7 @@ static void outb(unsigned char value, unsigned short port)
 }
 
 #if !defined(HAVE_GETTIMEOFDAY)
+struct timezone;
 int gettimeofday(struct timeval *tv, struct timezone *unused){
 // i've found only ms resolution, avrdude expects us
 
diff --git a/ser_posix.c b/ser_posix.c
index ab1b76e5..2c3671ab 100644
--- a/ser_posix.c
+++ b/ser_posix.c
@@ -87,19 +87,19 @@ static speed_t serial_baud_lookup(long baud)
   exit(1);
 }
 
-static int ser_setspeed(int fd, long baud)
+static int ser_setspeed(union filedescriptor *fd, long baud)
 {
   int rc;
   struct termios termios;
   speed_t speed = serial_baud_lookup (baud);
   
-  if (!isatty(fd))
+  if (!isatty(fd->ifd))
     return -ENOTTY;
   
   /*
    * initialize terminal modes
    */
-  rc = tcgetattr(fd, &termios);
+  rc = tcgetattr(fd->ifd, &termios);
   if (rc < 0) {
     fprintf(stderr, "%s: ser_setspeed(): tcgetattr() failed",
             progname);
@@ -123,7 +123,7 @@ static int ser_setspeed(int fd, long baud)
   cfsetospeed(&termios, speed);
   cfsetispeed(&termios, speed);
   
-  rc = tcsetattr(fd, TCSANOW | TCSAFLUSH, &termios);
+  rc = tcsetattr(fd->ifd, TCSANOW | TCSAFLUSH, &termios);
   if (rc < 0) {
     fprintf(stderr, "%s: ser_setspeed(): tcsetattr() failed",
             progname);
@@ -134,9 +134,9 @@ static int ser_setspeed(int fd, long baud)
    * Everything is now set up for a local line without modem control
    * or flow control, so clear O_NONBLOCK again.
    */
-  rc = fcntl(fd, F_GETFL, 0);
+  rc = fcntl(fd->ifd, F_GETFL, 0);
   if (rc != -1)
-    fcntl(fd, F_SETFL, rc & ~O_NONBLOCK);
+    fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);
 
   return 0;
 }
@@ -147,8 +147,8 @@ static int ser_setspeed(int fd, long baud)
  * terminal/console server with serial parameters configured
  * appropriately (e. g. 115200-8-N-1 for a STK500.)
  */
-static int
-net_open(const char *port)
+static void
+net_open(const char *port, union filedescriptor *fdp)
 {
   char *hstr, *pstr, *end;
   unsigned int pnum;
@@ -209,10 +209,10 @@ net_open(const char *port)
     exit(1);
   }
 
-  return fd;
+  fdp->ifd = fd;
 }
 
-static int ser_open(char * port, long baud)
+static void ser_open(char * port, long baud, union filedescriptor *fdp)
 {
   int rc;
   int fd;
@@ -222,7 +222,8 @@ static int ser_open(char * port, long baud)
    * handle it as a TCP connection to a terminal server.
    */
   if (strncmp(port, "net:", strlen("net:")) == 0) {
-    return net_open(port + strlen("net:"));
+    net_open(port + strlen("net:"), fdp);
+    return;
   }
 
   /*
@@ -238,7 +239,7 @@ static int ser_open(char * port, long baud)
   /*
    * set serial line attributes
    */
-  rc = ser_setspeed(fd, baud);
+  rc = ser_setspeed(fdp, baud);
   if (rc) {
     fprintf(stderr, 
             "%s: ser_open(): can't set attributes for device \"%s\": %s\n",
@@ -246,17 +247,17 @@ static int ser_open(char * port, long baud)
     exit(1);
   }
 
-  return fd;
+  fdp->ifd = fd;
 }
 
 
-static void ser_close(int fd)
+static void ser_close(union filedescriptor *fd)
 {
   /*
    * restore original termios settings from ser_open
    */
   if (saved_original_termios) {
-    int rc = tcsetattr(fd, TCSANOW | TCSADRAIN, &original_termios);
+    int rc = tcsetattr(fd->ifd, TCSANOW | TCSADRAIN, &original_termios);
     if (rc) {
       fprintf(stderr, 
               "%s: ser_close(): can't reset attributes for device: %s\n",
@@ -265,11 +266,11 @@ static void ser_close(int fd)
     saved_original_termios = 0;
   }
 
-  close(fd);
+  close(fd->ifd);
 }
 
 
-static int ser_send(int fd, unsigned char * buf, size_t buflen)
+static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
 {
   struct timeval timeout, to2;
   fd_set wfds;
@@ -309,9 +310,9 @@ static int ser_send(int fd, unsigned char * buf, size_t buflen)
   while (len) {
   reselect:
     FD_ZERO(&wfds);
-    FD_SET(fd, &wfds);
+    FD_SET(fd->ifd, &wfds);
 
-    nfds = select(fd+1, NULL, &wfds, NULL, &to2);
+    nfds = select(fd->ifd + 1, NULL, &wfds, NULL, &to2);
     if (nfds == 0) {
       if (verbose >= 1)
 	fprintf(stderr,
@@ -330,7 +331,7 @@ static int ser_send(int fd, unsigned char * buf, size_t buflen)
       }
     }
 
-    rc = write(fd, p, (len > 1024) ? 1024 : len);
+    rc = write(fd->ifd, p, (len > 1024) ? 1024 : len);
     if (rc < 0) {
       fprintf(stderr, "%s: ser_send(): write error: %s\n",
               progname, strerror(errno));
@@ -344,7 +345,7 @@ static int ser_send(int fd, unsigned char * buf, size_t buflen)
 }
 
 
-static int ser_recv(int fd, unsigned char * buf, size_t buflen)
+static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
 {
   struct timeval timeout, to2;
   fd_set rfds;
@@ -360,9 +361,9 @@ static int ser_recv(int fd, unsigned char * buf, size_t buflen)
   while (len < buflen) {
   reselect:
     FD_ZERO(&rfds);
-    FD_SET(fd, &rfds);
+    FD_SET(fd->ifd, &rfds);
 
-    nfds = select(fd+1, &rfds, NULL, NULL, &to2);
+    nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2);
     if (nfds == 0) {
       if (verbose > 1)
 	fprintf(stderr,
@@ -384,7 +385,7 @@ static int ser_recv(int fd, unsigned char * buf, size_t buflen)
       }
     }
 
-    rc = read(fd, p, (buflen - len > 1024) ? 1024 : buflen - len);
+    rc = read(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len);
     if (rc < 0) {
       fprintf(stderr, "%s: ser_recv(): read error: %s\n",
               progname, strerror(errno));
@@ -420,7 +421,7 @@ static int ser_recv(int fd, unsigned char * buf, size_t buflen)
 }
 
 
-static int ser_drain(int fd, int display)
+static int ser_drain(union filedescriptor *fd, int display)
 {
   struct timeval timeout;
   fd_set rfds;
@@ -437,10 +438,10 @@ static int ser_drain(int fd, int display)
 
   while (1) {
     FD_ZERO(&rfds);
-    FD_SET(fd, &rfds);
+    FD_SET(fd->ifd, &rfds);
 
   reselect:
-    nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
+    nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout);
     if (nfds == 0) {
       if (display) {
         fprintf(stderr, "<drain\n");
@@ -459,7 +460,7 @@ static int ser_drain(int fd, int display)
       }
     }
 
-    rc = read(fd, &buf, 1);
+    rc = read(fd->ifd, &buf, 1);
     if (rc < 0) {
       fprintf(stderr, "%s: ser_drain(): read error: %s\n",
               progname, strerror(errno));
diff --git a/ser_win32.c b/ser_win32.c
index 0864cbe9..861e3241 100644
--- a/ser_win32.c
+++ b/ser_win32.c
@@ -84,10 +84,10 @@ static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
 	return SetCommTimeouts(hComPort, &ctmo);
 }
 
-static int ser_setspeed(int fd, long baud)
+static int ser_setspeed(union filedescriptor *fd, long baud)
 {
 	DCB dcb;
-	HANDLE hComPort = (HANDLE)fd;
+	HANDLE hComPort = (HANDLE)fd->pfd;
 
 	ZeroMemory (&dcb, sizeof(DCB));
 	dcb.DCBlength = sizeof(DCB);
@@ -106,7 +106,7 @@ static int ser_setspeed(int fd, long baud)
 }
 
 
-static int ser_open(char * port, long baud)
+static void ser_open(char * port, long baud, union filedescriptor *fdp)
 {
 	LPVOID lpMsgBuf;
 	HANDLE hComPort=INVALID_HANDLE_VALUE;
@@ -158,8 +158,8 @@ static int ser_open(char * port, long baud)
 		exit(1);
 	}
 
-
-	if (ser_setspeed((int)hComPort, baud) != 0)
+        fdp->pfd = (void *)hComPort;
+	if (ser_setspeed(fdp, baud) != 0)
 	{
 		CloseHandle(hComPort);
 		fprintf(stderr, "%s: ser_open(): can't set com-state for \"%s\"\n",
@@ -174,14 +174,12 @@ static int ser_open(char * port, long baud)
 				progname, port);
 		exit(1);
 	}
-
-  return (int)hComPort;
 }
 
 
-static void ser_close(int fd)
+static void ser_close(union filedescriptor *fd)
 {
-	HANDLE hComPort=(HANDLE)fd;
+	HANDLE hComPort=(HANDLE)fd->pfd;
 	if (hComPort != INVALID_HANDLE_VALUE)
 		CloseHandle (hComPort);
 
@@ -189,14 +187,14 @@ static void ser_close(int fd)
 }
 
 
-static int ser_send(int fd, char * buf, size_t buflen)
+static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
 {
 	size_t len = buflen;
 	unsigned char c='\0';
 	DWORD written;
-        char * b = buf;
+        unsigned char * b = buf;
 
-	HANDLE hComPort=(HANDLE)fd;
+	HANDLE hComPort=(HANDLE)fd->pfd;
 
 	if (hComPort == INVALID_HANDLE_VALUE) {
 		fprintf(stderr, "%s: ser_send(): port not open\n",
@@ -244,14 +242,14 @@ static int ser_send(int fd, char * buf, size_t buflen)
 }
 
 
-static int ser_recv(int fd, char * buf, size_t buflen)
+static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
 {
 	unsigned char c;
-	char * p = buf;
+	unsigned char * p = buf;
 	size_t len = 0;
 	DWORD read;
 
-	HANDLE hComPort=(HANDLE)fd;
+	HANDLE hComPort=(HANDLE)fd->pfd;
 	
 	if (hComPort == INVALID_HANDLE_VALUE) {
 		fprintf(stderr, "%s: ser_read(): port not open\n",
@@ -304,14 +302,14 @@ static int ser_recv(int fd, char * buf, size_t buflen)
 }
 
 
-static int ser_drain(int fd, int display)
+static int ser_drain(union filedescriptor *fd, int display)
 {
 	// int rc;
 	unsigned char buf[10];
 	BOOL readres;
 	DWORD read;
 
-	HANDLE hComPort=(HANDLE)fd;
+	HANDLE hComPort=(HANDLE)fd->pfd;
 
   	if (hComPort == INVALID_HANDLE_VALUE) {
 		fprintf(stderr, "%s: ser_drain(): port not open\n",
diff --git a/serbb_posix.c b/serbb_posix.c
index ea188375..4aabe362 100644
--- a/serbb_posix.c
+++ b/serbb_posix.c
@@ -92,7 +92,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
   switch ( pin )
   {
     case 3:  /* txd */
-	     r = ioctl(pgm->fd, value ? TIOCSBRK : TIOCCBRK, 0);
+	     r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0);
 	     if (r < 0) {
 	       perror("ioctl(\"TIOCxBRK\")");
 	       return -1;
@@ -101,7 +101,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
 
     case 4:  /* dtr */
     case 7:  /* rts */
-             r = ioctl(pgm->fd, TIOCMGET, &ctl);
+             r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
  	     if (r < 0) {
 	       perror("ioctl(\"TIOCMGET\")");
 	       return -1;
@@ -110,7 +110,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
                ctl |= serregbits[pin];
              else
                ctl &= ~(serregbits[pin]);
-	     r = ioctl(pgm->fd, TIOCMSET, &ctl);
+	     r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl);
  	     if (r < 0) {
 	       perror("ioctl(\"TIOCMSET\")");
 	       return -1;
@@ -147,7 +147,7 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin)
     case 6:  /* dsr */
     case 8:  /* cts */
     case 9:  /* ri  */
-             r = ioctl(pgm->fd, TIOCMGET, &ctl);
+             r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
  	     if (r < 0) {
 	       perror("ioctl(\"TIOCMGET\")");
 	       return -1;
@@ -225,14 +225,14 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
 
   /* adapted from uisp code */
 
-  pgm->fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
+  pgm->fd.ifd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
 
-  if (pgm->fd < 0) {
+  if (pgm->fd.ifd < 0) {
     perror(port);
     return(-1);
   }
 
-  r = tcgetattr(pgm->fd, &mode);
+  r = tcgetattr(pgm->fd.ifd, &mode);
   if (r < 0) {
     fprintf(stderr, "%s: ", port);
     perror("tcgetattr");
@@ -246,7 +246,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
   mode.c_cc [VMIN] = 1;
   mode.c_cc [VTIME] = 0;
 
-  r = tcsetattr(pgm->fd, TCSANOW, &mode);
+  r = tcsetattr(pgm->fd.ifd, TCSANOW, &mode);
   if (r < 0) {
       fprintf(stderr, "%s: ", port);
       perror("tcsetattr");
@@ -254,7 +254,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
   }
 
   /* Clear O_NONBLOCK flag.  */
-  flags = fcntl(pgm->fd, F_GETFL, 0);
+  flags = fcntl(pgm->fd.ifd, F_GETFL, 0);
   if (flags == -1)
     {
       fprintf(stderr, "%s: Can not get flags: %s\n",
@@ -262,7 +262,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
       return(-1);
     }
   flags &= ~O_NONBLOCK;
-  if (fcntl(pgm->fd, F_SETFL, flags) == -1)
+  if (fcntl(pgm->fd.ifd, F_SETFL, flags) == -1)
     {
       fprintf(stderr, "%s: Can not clear nonblock flag: %s\n",
 	      progname, strerror(errno));
@@ -274,11 +274,11 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
 
 static void serbb_close(PROGRAMMER *pgm)
 {
-  if (pgm->fd != -1)
+  if (pgm->fd.ifd != -1)
   {
-	  (void)tcsetattr(pgm->fd, TCSANOW, &oldmode);
+	  (void)tcsetattr(pgm->fd.ifd, TCSANOW, &oldmode);
 	  pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
-	  close(pgm->fd);
+	  close(pgm->fd.ifd);
   }
   return;
 }
diff --git a/serbb_win32.c b/serbb_win32.c
index ed1e8d8a..628e73f0 100644
--- a/serbb_win32.c
+++ b/serbb_win32.c
@@ -63,7 +63,7 @@ static int dtr, rts, txd;
 
 static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
 {
-	HANDLE hComPort = (HANDLE)pgm->fd;
+	HANDLE hComPort = (HANDLE)pgm->fd.pfd;
         LPVOID lpMsgBuf;
         DWORD dwFunc;
         const char *name;
@@ -131,7 +131,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
 
 static int serbb_getpin(PROGRAMMER * pgm, int pin)
 {
-	HANDLE hComPort = (HANDLE)pgm->fd;
+	HANDLE hComPort = (HANDLE)pgm->fd.pfd;
         LPVOID lpMsgBuf;
         int invert, rv;
         const char *name;
@@ -323,7 +323,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
                         "%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
                         progname, port, (int)hComPort);
 
-        pgm->fd = (int)hComPort;
+        pgm->fd.pfd = (void *)hComPort;
 
         dtr = rts = txd = 0;
 
@@ -332,7 +332,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
 
 static void serbb_close(PROGRAMMER *pgm)
 {
-	HANDLE hComPort=(HANDLE)pgm->fd;
+	HANDLE hComPort=(HANDLE)pgm->fd.pfd;
 	if (hComPort != INVALID_HANDLE_VALUE)
 	{
 		pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
diff --git a/serial.h b/serial.h
index 359ee1e8..1b19f26a 100644
--- a/serial.h
+++ b/serial.h
@@ -31,16 +31,21 @@
 #define __serial_h__
 
 extern long serial_recv_timeout;
+union filedescriptor
+{
+  int ifd;
+  void *pfd;
+};
 
 struct serial_device
 {
-  int (*open)(char * port, long baud);
-  int (*setspeed)(int fd, long baud);
-  void (*close)(int fd);
+  void (*open)(char * port, long baud, union filedescriptor *fd);
+  int (*setspeed)(union filedescriptor *fd, long baud);
+  void (*close)(union filedescriptor *fd);
 
-  int (*send)(int fd, unsigned char * buf, size_t buflen);
-  int (*recv)(int fd, unsigned char * buf, size_t buflen);
-  int (*drain)(int fd, int display);
+  int (*send)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
+  int (*recv)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
+  int (*drain)(union filedescriptor *fd, int display);
 
   int flags;
 #define SERDEV_FL_NONE         0x0000 /* no flags */
diff --git a/stk500.c b/stk500.c
index cb839e35..7116bf2a 100644
--- a/stk500.c
+++ b/stk500.c
@@ -57,7 +57,7 @@ static int stk500_is_page_empty(unsigned int address, int page_size,
 
 static int stk500_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
 {
-  return serial_send(pgm->fd, buf, len);
+  return serial_send(&pgm->fd, buf, len);
 }
 
 
@@ -65,7 +65,7 @@ static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
 {
   int rv;
 
-  rv = serial_recv(pgm->fd, buf, len);
+  rv = serial_recv(&pgm->fd, buf, len);
   if (rv < 0) {
     fprintf(stderr,
 	    "%s: stk500_recv(): programmer is not responding\n",
@@ -78,7 +78,7 @@ static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
 
 static int stk500_drain(PROGRAMMER * pgm, int display)
 {
-  return serial_drain(pgm->fd, display);
+  return serial_drain(&pgm->fd, display);
 }
 
 
@@ -585,10 +585,7 @@ static void stk500_enable(PROGRAMMER * pgm)
 static int stk500_open(PROGRAMMER * pgm, char * port)
 {
   strcpy(pgm->port, port);
-  if (pgm->baudrate)
-    pgm->fd = serial_open(port, pgm->baudrate);
-  else
-    pgm->fd = serial_open(port, 115200);
+  serial_open(port, pgm->baudrate? pgm->baudrate: 115200, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -604,8 +601,8 @@ static int stk500_open(PROGRAMMER * pgm, char * port)
 
 static void stk500_close(PROGRAMMER * pgm)
 {
-  serial_close(pgm->fd);
-  pgm->fd = -1;
+  serial_close(&pgm->fd);
+  pgm->fd.ifd = -1;
 }
 
 
diff --git a/stk500v2.c b/stk500v2.c
index a20dcfa5..459962a1 100644
--- a/stk500v2.c
+++ b/stk500v2.c
@@ -205,7 +205,7 @@ b2_to_u16(unsigned char *b)
 
 static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
 {
-  if (serial_send(pgm->fd, data, len) != 0) {
+  if (serial_send(&pgm->fd, data, len) != 0) {
     fprintf(stderr,"%s: stk500_send_mk2(): failed to send command to serial port\n",progname);
     exit(1);
   }
@@ -298,7 +298,7 @@ static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
   for (i=0;i<len+6;i++) DEBUG("0x%02x ",buf[i]);
   DEBUG(", %d)\n",len+6);
 
-  if (serial_send(pgm->fd, buf, len+6) != 0) {
+  if (serial_send(&pgm->fd, buf, len+6) != 0) {
     fprintf(stderr,"%s: stk500_send(): failed to send command to serial port\n",progname);
     exit(1);
   }
@@ -309,7 +309,7 @@ static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
 
 static int stk500v2_drain(PROGRAMMER * pgm, int display)
 {
-  return serial_drain(pgm->fd, display);
+  return serial_drain(&pgm->fd, display);
 }
 
 static int stk500v2_recv_mk2(PROGRAMMER * pgm, unsigned char msg[],
@@ -317,7 +317,7 @@ static int stk500v2_recv_mk2(PROGRAMMER * pgm, unsigned char msg[],
 {
   int rv;
 
-  rv = serial_recv(pgm->fd, msg, maxsize);
+  rv = serial_recv(&pgm->fd, msg, maxsize);
   if (rv < 0) {
     fprintf(stderr, "%s: stk500v2_recv_mk2: error in USB receive\n", progname);
     return -1;
@@ -386,7 +386,7 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
   tstart = tv.tv_sec;
 
   while ( (state != sDONE ) && (!timeout) ) {
-    if (serial_recv(pgm->fd, &c, 1) < 0)
+    if (serial_recv(&pgm->fd, &c, 1) < 0)
       goto timedout;
     DEBUG("0x%02x ",c);
     checksum ^= c;
@@ -979,7 +979,7 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, baud);
+  serial_open(port, baud, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -1003,8 +1003,8 @@ static void stk500v2_close(PROGRAMMER * pgm)
 {
   DEBUG("STK500V2: stk500v2_close()\n");
 
-  serial_close(pgm->fd);
-  pgm->fd = -1;
+  serial_close(&pgm->fd);
+  pgm->fd.ifd = -1;
 }
 
 
@@ -2190,7 +2190,7 @@ static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, baud);
+  serial_open(port, baud, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -2257,7 +2257,7 @@ static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, baud);
+  serial_open(port, baud, &pgm->fd);
 
   /*
    * drain any extraneous input
@@ -2324,7 +2324,7 @@ static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port)
   }
 
   strcpy(pgm->port, port);
-  pgm->fd = serial_open(port, baud);
+  serial_open(port, baud, &pgm->fd);
 
   /*
    * drain any extraneous input
diff --git a/usb_libusb.c b/usb_libusb.c
index e733b077..01031c88 100644
--- a/usb_libusb.c
+++ b/usb_libusb.c
@@ -53,7 +53,7 @@ static int usb_interface;
  * The "baud" parameter is meaningless for USB devices, so we reuse it
  * to pass the desired USB device ID.
  */
-static int usbdev_open(char * port, long baud)
+static void usbdev_open(char * port, long baud, union filedescriptor *fd)
 {
   char string[256];
   char product[256];
@@ -189,7 +189,8 @@ static int usbdev_open(char * port, long baud)
 		      goto trynext;
 		    }
 
-		  return (int)udev;
+		  fd->pfd = udev;
+                  return;
 		}
 	      trynext:
 	      usb_close(udev);
@@ -202,9 +203,9 @@ static int usbdev_open(char * port, long baud)
   exit(1);
 }
 
-static void usbdev_close(int fd)
+static void usbdev_close(union filedescriptor *fd)
 {
-  usb_dev_handle *udev = (usb_dev_handle *)fd;
+  usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
 
   (void)usb_release_interface(udev, usb_interface);
 
@@ -218,10 +219,10 @@ static void usbdev_close(int fd)
 }
 
 
-static int usbdev_send(int fd, unsigned char *bp, size_t mlen)
+static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
 {
-  usb_dev_handle *udev = (usb_dev_handle *)fd;
-  size_t rv;
+  usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
+  int rv;
   int i = mlen;
   unsigned char * p = bp;
   int tx_size;
@@ -296,9 +297,9 @@ usb_fill_buf(usb_dev_handle *udev)
   return 0;
 }
 
-static int usbdev_recv(int fd, unsigned char *buf, size_t nbytes)
+static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
 {
-  usb_dev_handle *udev = (usb_dev_handle *)fd;
+  usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
   int i, amnt;
   unsigned char * p = buf;
 
@@ -348,9 +349,9 @@ static int usbdev_recv(int fd, unsigned char *buf, size_t nbytes)
  *
  * This is used for the AVRISP mkII device.
  */
-static int usbdev_recv_frame(int fd, unsigned char *buf, size_t nbytes)
+static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
 {
-  usb_dev_handle *udev = (usb_dev_handle *)fd;
+  usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
   int rv, n;
   int i;
   unsigned char * p = buf;
@@ -405,9 +406,9 @@ static int usbdev_recv_frame(int fd, unsigned char *buf, size_t nbytes)
   return n;
 }
 
-static int usbdev_drain(int fd, int display)
+static int usbdev_drain(union filedescriptor *fd, int display)
 {
-  usb_dev_handle *udev = (usb_dev_handle *)fd;
+  usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
   int rv;
 
   do {