diff --git a/gdb/target.c b/gdb/target.c
index af94f48..7e04679 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2684,10 +2684,20 @@ default_fileio_target (void)
     return find_default_run_target ("file I/O");
 }
 
-/* Open FILENAME on the target, using FLAGS and MODE.  Return a
-   target file descriptor, or -1 if an error occurs (and set
-   *TARGET_ERRNO).  */
-int
+/* File handle for target file operations.  */
+
+struct target_fileio_handle
+{
+  /* The target on which this file is open.  */
+  struct target_ops *t;
+
+  /* The file's descriptor on the target.  */
+  int fd;
+};
+
+/* See target.h.  */
+
+target_fileio_t
 target_fileio_open (const char *filename, int flags, int mode,
 		    int *target_errno)
 {
@@ -2698,107 +2708,86 @@ target_fileio_open (const char *filename, int flags, int mode,
       if (t->to_fileio_open != NULL)
 	{
 	  int fd = t->to_fileio_open (t, filename, flags, mode, target_errno);
+	  target_fileio_t fh = NULL;
 
 	  if (targetdebug)
 	    fprintf_unfiltered (gdb_stdlog,
-				"target_fileio_open (%s,0x%x,0%o) = %d (%d)\n",
-				filename, flags, mode,
+				"target_fileio_open (%s,0x%x,0%o)"
+				" = %s:%d (%d)\n",
+				filename, flags, mode, t->to_shortname,
 				fd, fd != -1 ? 0 : *target_errno);
-	  return fd;
+	  if (fd >= 0)
+	    {
+	      fh = XCNEW (struct target_fileio_handle);
+	      fh->t = t;
+	      fh->fd = fd;
+	    }
+
+	  return fh;
 	}
     }
 
   *target_errno = FILEIO_ENOSYS;
-  return -1;
+  return NULL;
 }
 
-/* Write up to LEN bytes from WRITE_BUF to FD on the target.
-   Return the number of bytes written, or -1 if an error occurs
-   (and set *TARGET_ERRNO).  */
+/* See target.h.  */
+
 int
-target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
-		      ULONGEST offset, int *target_errno)
+target_fileio_pwrite (target_fileio_t fh, const gdb_byte *write_buf,
+		      int len, ULONGEST offset, int *target_errno)
 {
-  struct target_ops *t;
+  int ret = fh->t->to_fileio_pwrite (fh->t, fh->fd, write_buf, len,
+				     offset, target_errno);
 
-  for (t = default_fileio_target (); t != NULL; t = t->beneath)
-    {
-      if (t->to_fileio_pwrite != NULL)
-	{
-	  int ret = t->to_fileio_pwrite (t, fd, write_buf, len, offset,
-					 target_errno);
-
-	  if (targetdebug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"target_fileio_pwrite (%d,...,%d,%s) "
-				"= %d (%d)\n",
-				fd, len, pulongest (offset),
-				ret, ret != -1 ? 0 : *target_errno);
-	  return ret;
-	}
-    }
-
-  *target_errno = FILEIO_ENOSYS;
-  return -1;
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog,
+			"target_fileio_pwrite (%s:%d,...,%d,%s)"
+			" = %d (%d)\n",
+			fh->t->to_shortname, fh->fd, len,
+			pulongest (offset), ret,
+			ret != -1 ? 0 : *target_errno);
+  return ret;
 }
 
-/* Read up to LEN bytes FD on the target into READ_BUF.
-   Return the number of bytes read, or -1 if an error occurs
-   (and set *TARGET_ERRNO).  */
+/* See target.h.  */
+
 int
-target_fileio_pread (int fd, gdb_byte *read_buf, int len,
+target_fileio_pread (target_fileio_t fh, gdb_byte *read_buf, int len,
 		     ULONGEST offset, int *target_errno)
 {
-  struct target_ops *t;
+  int ret = fh->t->to_fileio_pread (fh->t, fh->fd, read_buf, len,
+				    offset, target_errno);
 
-  for (t = default_fileio_target (); t != NULL; t = t->beneath)
-    {
-      if (t->to_fileio_pread != NULL)
-	{
-	  int ret = t->to_fileio_pread (t, fd, read_buf, len, offset,
-					target_errno);
-
-	  if (targetdebug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"target_fileio_pread (%d,...,%d,%s) "
-				"= %d (%d)\n",
-				fd, len, pulongest (offset),
-				ret, ret != -1 ? 0 : *target_errno);
-	  return ret;
-	}
-    }
-
-  *target_errno = FILEIO_ENOSYS;
-  return -1;
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog,
+			"target_fileio_pread (%s:%d,...,%d,%s)"
+			" = %d (%d)\n",
+			fh->t->to_shortname, fh->fd, len,
+			pulongest (offset), ret,
+			ret != -1 ? 0 : *target_errno);
+  return ret;
 }
 
-/* Close FD on the target.  Return 0, or -1 if an error occurs
-   (and set *TARGET_ERRNO).  */
+/* See target.h.  */
+
 int
-target_fileio_close (int fd, int *target_errno)
+target_fileio_close (target_fileio_t fh, int *target_errno)
 {
-  struct target_ops *t;
+  int ret = fh->t->to_fileio_close (fh->t, fh->fd, target_errno);
 
-  for (t = default_fileio_target (); t != NULL; t = t->beneath)
-    {
-      if (t->to_fileio_close != NULL)
-	{
-	  int ret = t->to_fileio_close (t, fd, target_errno);
-
-	  if (targetdebug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"target_fileio_close (%d) = %d (%d)\n",
-				fd, ret, ret != -1 ? 0 : *target_errno);
-	  return ret;
-	}
-    }
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog,
+			"target_fileio_close (%s:%d) = %d (%d)\n",
+			fh->t->to_shortname, fh->fd, ret,
+			ret != -1 ? 0 : *target_errno);
+  xfree (fh);
 
-  *target_errno = FILEIO_ENOSYS;
-  return -1;
+  return ret;
 }
 
-/* Unlink FILENAME on the target.  Return 0, or -1 if an error
-   occurs (and set *TARGET_ERRNO).  */
+/* See target.h.  */
+
 int
 target_fileio_unlink (const char *filename, int *target_errno)
 {
@@ -2822,9 +2811,8 @@ target_fileio_unlink (const char *filename, int *target_errno)
   return -1;
 }
 
-/* Read value of symbolic link FILENAME on the target.  Return a
-   null-terminated string allocated via xmalloc, or NULL if an error
-   occurs (and set *TARGET_ERRNO).  */
+/* See target.h.  */
+
 char *
 target_fileio_readlink (const char *filename, int *target_errno)
 {
@@ -2852,10 +2840,10 @@ target_fileio_readlink (const char *filename, int *target_errno)
 static void
 target_fileio_close_cleanup (void *opaque)
 {
-  int fd = *(int *) opaque;
+  target_fileio_t fh = (target_fileio_t) opaque;
   int target_errno;
 
-  target_fileio_close (fd, &target_errno);
+  target_fileio_close (fh, &target_errno);
 }
 
 /* Read target file FILENAME.  Store the result in *BUF_P and
@@ -2872,14 +2860,14 @@ target_fileio_read_alloc_1 (const char *filename,
   size_t buf_alloc, buf_pos;
   gdb_byte *buf;
   LONGEST n;
-  int fd;
+  target_fileio_t fh;
   int target_errno;
 
-  fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno);
-  if (fd == -1)
+  fh = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno);
+  if (fh == NULL)
     return -1;
 
-  close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd);
+  close_cleanup = make_cleanup (target_fileio_close_cleanup, fh);
 
   /* Start by reading up to 4K at a time.  The target will throttle
      this number down if necessary.  */
@@ -2888,7 +2876,7 @@ target_fileio_read_alloc_1 (const char *filename,
   buf_pos = 0;
   while (1)
     {
-      n = target_fileio_pread (fd, &buf[buf_pos],
+      n = target_fileio_pread (fh, &buf[buf_pos],
 			       buf_alloc - buf_pos - padding, buf_pos,
 			       &target_errno);
       if (n < 0)
diff --git a/gdb/target.h b/gdb/target.h
index c95e1a4..1edee84 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1915,27 +1915,33 @@ extern int target_search_memory (CORE_ADDR start_addr,
 
 /* Target file operations.  */
 
-/* Open FILENAME on the target, using FLAGS and MODE.  Return a
-   target file descriptor, or -1 if an error occurs (and set
-   *TARGET_ERRNO).  */
-extern int target_fileio_open (const char *filename, int flags, int mode,
-			       int *target_errno);
+/* File handle for target file operations.  */
+typedef struct target_fileio_handle *target_fileio_t;
 
-/* Write up to LEN bytes from WRITE_BUF to FD on the target.
+/* Open FILENAME on the target, using FLAGS and MODE.  Return a target
+   file handle, or NULL if an error occurs (and set *TARGET_ERRNO).  */
+extern target_fileio_t target_fileio_open (const char *filename,
+					   int flags, int mode,
+					   int *target_errno);
+
+/* Write up to LEN bytes from WRITE_BUF to FH on the target.
    Return the number of bytes written, or -1 if an error occurs
    (and set *TARGET_ERRNO).  */
-extern int target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+extern int target_fileio_pwrite (target_fileio_t fh,
+				 const gdb_byte *write_buf, int len,
 				 ULONGEST offset, int *target_errno);
 
-/* Read up to LEN bytes FD on the target into READ_BUF.
+/* Read up to LEN bytes from FH on the target into READ_BUF.
    Return the number of bytes read, or -1 if an error occurs
    (and set *TARGET_ERRNO).  */
-extern int target_fileio_pread (int fd, gdb_byte *read_buf, int len,
+extern int target_fileio_pread (target_fileio_t fh,
+				gdb_byte *read_buf, int len,
 				ULONGEST offset, int *target_errno);
 
-/* Close FD on the target.  Return 0, or -1 if an error occurs
+/* Close FH on the target.  Return 0, or -1 if an error occurs
    (and set *TARGET_ERRNO).  */
-extern int target_fileio_close (int fd, int *target_errno);
+extern int target_fileio_close (target_fileio_t fh,
+				int *target_errno);
 
 /* Unlink FILENAME on the target.  Return 0, or -1 if an error
    occurs (and set *TARGET_ERRNO).  */
