gdb/remote-fileio.c - gdb

Global variables defined

Functions defined

Macros defined

Source code

  1. /* Remote File-I/O communications

  2.    Copyright (C) 2003-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. /* See the GDB User Guide for details of the GDB remote protocol.  */

  15. #include "defs.h"
  16. #include "gdbcmd.h"
  17. #include "remote.h"
  18. #include "gdb/fileio.h"
  19. #include "gdb_wait.h"
  20. #include <sys/stat.h>
  21. #include "remote-fileio.h"
  22. #include "event-loop.h"
  23. #include "target.h"
  24. #include "filenames.h"
  25. #include "filestuff.h"

  26. #include <fcntl.h>
  27. #include <sys/time.h>
  28. #ifdef __CYGWIN__
  29. #include <sys/cygwin.h>                /* For cygwin_conv_path.  */
  30. #endif
  31. #include <signal.h>

  32. static struct {
  33.   int *fd_map;
  34.   int fd_map_size;
  35. } remote_fio_data;

  36. #define FIO_FD_INVALID                -1
  37. #define FIO_FD_CONSOLE_IN        -2
  38. #define FIO_FD_CONSOLE_OUT        -3

  39. static int remote_fio_system_call_allowed = 0;

  40. static struct async_signal_handler *sigint_fileio_token;

  41. static int
  42. remote_fileio_init_fd_map (void)
  43. {
  44.   int i;

  45.   if (!remote_fio_data.fd_map)
  46.     {
  47.       remote_fio_data.fd_map = (int *) xmalloc (10 * sizeof (int));
  48.       remote_fio_data.fd_map_size = 10;
  49.       remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
  50.       remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
  51.       remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
  52.       for (i = 3; i < 10; ++i)
  53.         remote_fio_data.fd_map[i] = FIO_FD_INVALID;
  54.     }
  55.   return 3;
  56. }

  57. static int
  58. remote_fileio_resize_fd_map (void)
  59. {
  60.   int i = remote_fio_data.fd_map_size;

  61.   if (!remote_fio_data.fd_map)
  62.     return remote_fileio_init_fd_map ();
  63.   remote_fio_data.fd_map_size += 10;
  64.   remote_fio_data.fd_map =
  65.     (int *) xrealloc (remote_fio_data.fd_map,
  66.                       remote_fio_data.fd_map_size * sizeof (int));
  67.   for (; i < remote_fio_data.fd_map_size; i++)
  68.     remote_fio_data.fd_map[i] = FIO_FD_INVALID;
  69.   return remote_fio_data.fd_map_size - 10;
  70. }

  71. static int
  72. remote_fileio_next_free_fd (void)
  73. {
  74.   int i;

  75.   for (i = 0; i < remote_fio_data.fd_map_size; ++i)
  76.     if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
  77.       return i;
  78.   return remote_fileio_resize_fd_map ();
  79. }

  80. static int
  81. remote_fileio_fd_to_targetfd (int fd)
  82. {
  83.   int target_fd = remote_fileio_next_free_fd ();

  84.   remote_fio_data.fd_map[target_fd] = fd;
  85.   return target_fd;
  86. }

  87. static int
  88. remote_fileio_map_fd (int target_fd)
  89. {
  90.   remote_fileio_init_fd_map ();
  91.   if (target_fd < 0 || target_fd >= remote_fio_data.fd_map_size)
  92.     return FIO_FD_INVALID;
  93.   return remote_fio_data.fd_map[target_fd];
  94. }

  95. static void
  96. remote_fileio_close_target_fd (int target_fd)
  97. {
  98.   remote_fileio_init_fd_map ();
  99.   if (target_fd >= 0 && target_fd < remote_fio_data.fd_map_size)
  100.     remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID;
  101. }

  102. static int
  103. remote_fileio_oflags_to_host (long flags)
  104. {
  105.   int hflags = 0;

  106.   if (flags & FILEIO_O_CREAT)
  107.     hflags |= O_CREAT;
  108.   if (flags & FILEIO_O_EXCL)
  109.     hflags |= O_EXCL;
  110.   if (flags & FILEIO_O_TRUNC)
  111.     hflags |= O_TRUNC;
  112.   if (flags & FILEIO_O_APPEND)
  113.     hflags |= O_APPEND;
  114.   if (flags & FILEIO_O_RDONLY)
  115.     hflags |= O_RDONLY;
  116.   if (flags & FILEIO_O_WRONLY)
  117.     hflags |= O_WRONLY;
  118.   if (flags & FILEIO_O_RDWR)
  119.     hflags |= O_RDWR;
  120. /* On systems supporting binary and text mode, always open files in
  121.    binary mode.  */
  122. #ifdef O_BINARY
  123.   hflags |= O_BINARY;
  124. #endif
  125.   return hflags;
  126. }

  127. static mode_t
  128. remote_fileio_mode_to_host (long mode, int open_call)
  129. {
  130.   mode_t hmode = 0;

  131.   if (!open_call)
  132.     {
  133.       if (mode & FILEIO_S_IFREG)
  134.         hmode |= S_IFREG;
  135.       if (mode & FILEIO_S_IFDIR)
  136.         hmode |= S_IFDIR;
  137.       if (mode & FILEIO_S_IFCHR)
  138.         hmode |= S_IFCHR;
  139.     }
  140.   if (mode & FILEIO_S_IRUSR)
  141.     hmode |= S_IRUSR;
  142.   if (mode & FILEIO_S_IWUSR)
  143.     hmode |= S_IWUSR;
  144.   if (mode & FILEIO_S_IXUSR)
  145.     hmode |= S_IXUSR;
  146. #ifdef S_IRGRP
  147.   if (mode & FILEIO_S_IRGRP)
  148.     hmode |= S_IRGRP;
  149. #endif
  150. #ifdef S_IWGRP
  151.   if (mode & FILEIO_S_IWGRP)
  152.     hmode |= S_IWGRP;
  153. #endif
  154. #ifdef S_IXGRP
  155.   if (mode & FILEIO_S_IXGRP)
  156.     hmode |= S_IXGRP;
  157. #endif
  158.   if (mode & FILEIO_S_IROTH)
  159.     hmode |= S_IROTH;
  160. #ifdef S_IWOTH
  161.   if (mode & FILEIO_S_IWOTH)
  162.     hmode |= S_IWOTH;
  163. #endif
  164. #ifdef S_IXOTH
  165.   if (mode & FILEIO_S_IXOTH)
  166.     hmode |= S_IXOTH;
  167. #endif
  168.   return hmode;
  169. }

  170. static LONGEST
  171. remote_fileio_mode_to_target (mode_t mode)
  172. {
  173.   mode_t tmode = 0;

  174.   if (S_ISREG(mode))
  175.     tmode |= FILEIO_S_IFREG;
  176.   if (S_ISDIR(mode))
  177.     tmode |= FILEIO_S_IFDIR;
  178.   if (S_ISCHR(mode))
  179.     tmode |= FILEIO_S_IFCHR;
  180.   if (mode & S_IRUSR)
  181.     tmode |= FILEIO_S_IRUSR;
  182.   if (mode & S_IWUSR)
  183.     tmode |= FILEIO_S_IWUSR;
  184.   if (mode & S_IXUSR)
  185.     tmode |= FILEIO_S_IXUSR;
  186. #ifdef S_IRGRP
  187.   if (mode & S_IRGRP)
  188.     tmode |= FILEIO_S_IRGRP;
  189. #endif
  190. #ifdef S_IWRGRP
  191.   if (mode & S_IWGRP)
  192.     tmode |= FILEIO_S_IWGRP;
  193. #endif
  194. #ifdef S_IXGRP
  195.   if (mode & S_IXGRP)
  196.     tmode |= FILEIO_S_IXGRP;
  197. #endif
  198.   if (mode & S_IROTH)
  199.     tmode |= FILEIO_S_IROTH;
  200. #ifdef S_IWOTH
  201.   if (mode & S_IWOTH)
  202.     tmode |= FILEIO_S_IWOTH;
  203. #endif
  204. #ifdef S_IXOTH
  205.   if (mode & S_IXOTH)
  206.     tmode |= FILEIO_S_IXOTH;
  207. #endif
  208.   return tmode;
  209. }

  210. static int
  211. remote_fileio_errno_to_target (int error)
  212. {
  213.   switch (error)
  214.     {
  215.       case EPERM:
  216.         return FILEIO_EPERM;
  217.       case ENOENT:
  218.         return FILEIO_ENOENT;
  219.       case EINTR:
  220.         return FILEIO_EINTR;
  221.       case EIO:
  222.         return FILEIO_EIO;
  223.       case EBADF:
  224.         return FILEIO_EBADF;
  225.       case EACCES:
  226.         return FILEIO_EACCES;
  227.       case EFAULT:
  228.         return FILEIO_EFAULT;
  229.       case EBUSY:
  230.         return FILEIO_EBUSY;
  231.       case EEXIST:
  232.         return FILEIO_EEXIST;
  233.       case ENODEV:
  234.         return FILEIO_ENODEV;
  235.       case ENOTDIR:
  236.         return FILEIO_ENOTDIR;
  237.       case EISDIR:
  238.         return FILEIO_EISDIR;
  239.       case EINVAL:
  240.         return FILEIO_EINVAL;
  241.       case ENFILE:
  242.         return FILEIO_ENFILE;
  243.       case EMFILE:
  244.         return FILEIO_EMFILE;
  245.       case EFBIG:
  246.         return FILEIO_EFBIG;
  247.       case ENOSPC:
  248.         return FILEIO_ENOSPC;
  249.       case ESPIPE:
  250.         return FILEIO_ESPIPE;
  251.       case EROFS:
  252.         return FILEIO_EROFS;
  253.       case ENOSYS:
  254.         return FILEIO_ENOSYS;
  255.       case ENAMETOOLONG:
  256.         return FILEIO_ENAMETOOLONG;
  257.     }
  258.   return FILEIO_EUNKNOWN;
  259. }

  260. static int
  261. remote_fileio_seek_flag_to_host (long num, int *flag)
  262. {
  263.   if (!flag)
  264.     return 0;
  265.   switch (num)
  266.     {
  267.       case FILEIO_SEEK_SET:
  268.         *flag = SEEK_SET;
  269.         break;
  270.       case FILEIO_SEEK_CUR:
  271.         *flagSEEK_CUR;
  272.         break;
  273.       case FILEIO_SEEK_END:
  274.         *flagSEEK_END;
  275.         break;
  276.       default:
  277.         return -1;
  278.     }
  279.   return 0;
  280. }

  281. static int
  282. remote_fileio_extract_long (char **buf, LONGEST *retlong)
  283. {
  284.   char *c;
  285.   int sign = 1;

  286.   if (!buf || !*buf || !**buf || !retlong)
  287.     return -1;
  288.   c = strchr (*buf, ',');
  289.   if (c)
  290.     *c++ = '\0';
  291.   else
  292.     c = strchr (*buf, '\0');
  293.   while (strchr ("+-", **buf))
  294.     {
  295.       if (**buf == '-')
  296.         sign = -sign;
  297.       ++*buf;
  298.     }
  299.   for (*retlong = 0; **buf; ++*buf)
  300.     {
  301.       *retlong <<= 4;
  302.       if (**buf >= '0' && **buf <= '9')
  303.         *retlong += **buf - '0';
  304.       else if (**buf >= 'a' && **buf <= 'f')
  305.         *retlong += **buf - 'a' + 10;
  306.       else if (**buf >= 'A' && **buf <= 'F')
  307.         *retlong += **buf - 'A' + 10;
  308.       else
  309.         return -1;
  310.     }
  311.   *retlong *= sign;
  312.   *buf = c;
  313.   return 0;
  314. }

  315. static int
  316. remote_fileio_extract_int (char **buf, long *retint)
  317. {
  318.   int ret;
  319.   LONGEST retlong;

  320.   if (!retint)
  321.     return -1;
  322.   ret = remote_fileio_extract_long (buf, &retlong);
  323.   if (!ret)
  324.     *retint = (long) retlong;
  325.   return ret;
  326. }

  327. static int
  328. remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
  329. {
  330.   char *c;
  331.   LONGEST retlong;

  332.   if (!buf || !*buf || !**buf || !ptrval || !length)
  333.     return -1;
  334.   c = strchr (*buf, '/');
  335.   if (!c)
  336.     return -1;
  337.   *c++ = '\0';
  338.   if (remote_fileio_extract_long (buf, &retlong))
  339.     return -1;
  340.   *ptrval = (CORE_ADDR) retlong;
  341.   *buf = c;
  342.   if (remote_fileio_extract_long (buf, &retlong))
  343.     return -1;
  344.   *length = (int) retlong;
  345.   return 0;
  346. }

  347. /* Convert to big endian.  */
  348. static void
  349. remote_fileio_to_be (LONGEST num, char *buf, int bytes)
  350. {
  351.   int i;

  352.   for (i = 0; i < bytes; ++i)
  353.     buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff;
  354. }

  355. static void
  356. remote_fileio_to_fio_uint (long num, fio_uint_t fnum)
  357. {
  358.   remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
  359. }

  360. static void
  361. remote_fileio_to_fio_mode (mode_t num, fio_mode_t fnum)
  362. {
  363.   remote_fileio_to_be (remote_fileio_mode_to_target(num), (char *) fnum, 4);
  364. }

  365. static void
  366. remote_fileio_to_fio_time (time_t num, fio_time_t fnum)
  367. {
  368.   remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
  369. }

  370. static void
  371. remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
  372. {
  373.   remote_fileio_to_be (num, (char *) fnum, 8);
  374. }

  375. static void
  376. remote_fileio_to_fio_ulong (LONGEST num, fio_ulong_t fnum)
  377. {
  378.   remote_fileio_to_be (num, (char *) fnum, 8);
  379. }

  380. static void
  381. remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst)
  382. {
  383.   LONGEST blksize;

  384.   /* `st_dev' is set in the calling function.  */
  385.   remote_fileio_to_fio_uint ((long) st->st_ino, fst->fst_ino);
  386.   remote_fileio_to_fio_mode (st->st_mode, fst->fst_mode);
  387.   remote_fileio_to_fio_uint ((long) st->st_nlink, fst->fst_nlink);
  388.   remote_fileio_to_fio_uint ((long) st->st_uid, fst->fst_uid);
  389.   remote_fileio_to_fio_uint ((long) st->st_gid, fst->fst_gid);
  390.   remote_fileio_to_fio_uint ((long) st->st_rdev, fst->fst_rdev);
  391.   remote_fileio_to_fio_ulong ((LONGEST) st->st_size, fst->fst_size);
  392. #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
  393.   blksize = st->st_blksize;
  394. #else
  395.   blksize = 512;
  396. #endif
  397.   remote_fileio_to_fio_ulong (blksize, fst->fst_blksize);
  398. #if HAVE_STRUCT_STAT_ST_BLOCKS
  399.   remote_fileio_to_fio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
  400. #else
  401.   /* FIXME: This is correct for DJGPP, but other systems that don't
  402.      have st_blocks, if any, might prefer 512 instead of st_blksize.
  403.      (eliz, 30-12-2003)  */
  404.   remote_fileio_to_fio_ulong (((LONGEST) st->st_size + blksize - 1)
  405.                               / blksize,
  406.                               fst->fst_blocks);
  407. #endif
  408.   remote_fileio_to_fio_time (st->st_atime, fst->fst_atime);
  409.   remote_fileio_to_fio_time (st->st_mtime, fst->fst_mtime);
  410.   remote_fileio_to_fio_time (st->st_ctime, fst->fst_ctime);
  411. }

  412. static void
  413. remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
  414. {
  415.   remote_fileio_to_fio_time (tv->tv_sec, ftv->ftv_sec);
  416.   remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
  417. }

  418. static int remote_fio_ctrl_c_flag = 0;
  419. static int remote_fio_no_longjmp = 0;

  420. #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
  421. static struct sigaction remote_fio_sa;
  422. static struct sigaction remote_fio_osa;
  423. #else
  424. static void (*remote_fio_ofunc)(int);
  425. #endif

  426. static void
  427. remote_fileio_sig_init (void)
  428. {
  429. #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
  430.   remote_fio_sa.sa_handler = SIG_IGN;
  431.   sigemptyset (&remote_fio_sa.sa_mask);
  432.   remote_fio_sa.sa_flags = 0;
  433.   sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa);
  434. #else
  435.   remote_fio_ofunc = signal (SIGINT, SIG_IGN);
  436. #endif
  437. }

  438. static void
  439. remote_fileio_sig_set (void (*sigint_func)(int))
  440. {
  441. #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
  442.   remote_fio_sa.sa_handler = sigint_func;
  443.   sigemptyset (&remote_fio_sa.sa_mask);
  444.   remote_fio_sa.sa_flags = 0;
  445.   sigaction (SIGINT, &remote_fio_sa, NULL);
  446. #else
  447.   signal (SIGINT, sigint_func);
  448. #endif
  449. }

  450. static void
  451. remote_fileio_sig_exit (void)
  452. {
  453. #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
  454.   sigaction (SIGINT, &remote_fio_osa, NULL);
  455. #else
  456.   signal (SIGINT, remote_fio_ofunc);
  457. #endif
  458. }

  459. static void
  460. async_remote_fileio_interrupt (gdb_client_data arg)
  461. {
  462.   quit ();
  463. }

  464. static void
  465. remote_fileio_ctrl_c_signal_handler (int signo)
  466. {
  467.   remote_fileio_sig_set (SIG_IGN);
  468.   remote_fio_ctrl_c_flag = 1;
  469.   if (!remote_fio_no_longjmp)
  470.     gdb_call_async_signal_handler (sigint_fileio_token, 1);
  471.   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
  472. }

  473. static void
  474. remote_fileio_reply (int retcode, int error)
  475. {
  476.   char buf[32];

  477.   remote_fileio_sig_set (SIG_IGN);
  478.   strcpy (buf, "F");
  479.   if (retcode < 0)
  480.     {
  481.       strcat (buf, "-");
  482.       retcode = -retcode;
  483.     }
  484.   sprintf (buf + strlen (buf), "%x", retcode);
  485.   if (error || remote_fio_ctrl_c_flag)
  486.     {
  487.       if (error && remote_fio_ctrl_c_flag)
  488.         error = FILEIO_EINTR;
  489.       if (error < 0)
  490.         {
  491.           strcat (buf, "-");
  492.           error = -error;
  493.         }
  494.       sprintf (buf + strlen (buf), ",%x", error);
  495.       if (remote_fio_ctrl_c_flag)
  496.         strcat (buf, ",C");
  497.     }
  498.   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
  499.   putpkt (buf);
  500. }

  501. static void
  502. remote_fileio_ioerror (void)
  503. {
  504.   remote_fileio_reply (-1, FILEIO_EIO);
  505. }

  506. static void
  507. remote_fileio_badfd (void)
  508. {
  509.   remote_fileio_reply (-1, FILEIO_EBADF);
  510. }

  511. static void
  512. remote_fileio_return_errno (int retcode)
  513. {
  514.   remote_fileio_reply (retcode, retcode < 0
  515.                        ? remote_fileio_errno_to_target (errno) : 0);
  516. }

  517. static void
  518. remote_fileio_return_success (int retcode)
  519. {
  520.   remote_fileio_reply (retcode, 0);
  521. }

  522. static void
  523. remote_fileio_func_open (char *buf)
  524. {
  525.   CORE_ADDR ptrval;
  526.   int length;
  527.   long num;
  528.   int flags, fd;
  529.   mode_t mode;
  530.   char *pathname;
  531.   struct stat st;

  532.   /* 1. Parameter: Ptr to pathname / length incl. trailing zero.  */
  533.   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
  534.     {
  535.       remote_fileio_ioerror ();
  536.       return;
  537.     }
  538.   /* 2. Parameter: open flags */
  539.   if (remote_fileio_extract_int (&buf, &num))
  540.     {
  541.       remote_fileio_ioerror ();
  542.       return;
  543.     }
  544.   flags = remote_fileio_oflags_to_host (num);
  545.   /* 3. Parameter: open mode */
  546.   if (remote_fileio_extract_int (&buf, &num))
  547.     {
  548.       remote_fileio_ioerror ();
  549.       return;
  550.     }
  551.   mode = remote_fileio_mode_to_host (num, 1);

  552.   /* Request pathname.  */
  553.   pathname = alloca (length);
  554.   if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
  555.     {
  556.       remote_fileio_ioerror ();
  557.       return;
  558.     }

  559.   /* Check if pathname exists and is not a regular file or directory.  If so,
  560.      return an appropriate error code.  Same for trying to open directories
  561.      for writing.  */
  562.   if (!stat (pathname, &st))
  563.     {
  564.       if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
  565.         {
  566.           remote_fileio_reply (-1, FILEIO_ENODEV);
  567.           return;
  568.         }
  569.       if (S_ISDIR (st.st_mode)
  570.           && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
  571.         {
  572.           remote_fileio_reply (-1, FILEIO_EISDIR);
  573.           return;
  574.         }
  575.     }

  576.   remote_fio_no_longjmp = 1;
  577.   fd = gdb_open_cloexec (pathname, flags, mode);
  578.   if (fd < 0)
  579.     {
  580.       remote_fileio_return_errno (-1);
  581.       return;
  582.     }

  583.   fd = remote_fileio_fd_to_targetfd (fd);
  584.   remote_fileio_return_success (fd);
  585. }

  586. static void
  587. remote_fileio_func_close (char *buf)
  588. {
  589.   long num;
  590.   int fd;

  591.   /* Parameter: file descriptor */
  592.   if (remote_fileio_extract_int (&buf, &num))
  593.     {
  594.       remote_fileio_ioerror ();
  595.       return;
  596.     }
  597.   fd = remote_fileio_map_fd ((int) num);
  598.   if (fd == FIO_FD_INVALID)
  599.     {
  600.       remote_fileio_badfd ();
  601.       return;
  602.     }

  603.   remote_fio_no_longjmp = 1;
  604.   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
  605.     remote_fileio_return_errno (-1);
  606.   remote_fileio_close_target_fd ((int) num);
  607.   remote_fileio_return_success (0);
  608. }

  609. static void
  610. remote_fileio_func_read (char *buf)
  611. {
  612.   long target_fd, num;
  613.   LONGEST lnum;
  614.   CORE_ADDR ptrval;
  615.   int fd, ret;
  616.   gdb_byte *buffer;
  617.   size_t length;
  618.   off_t old_offset, new_offset;

  619.   /* 1. Parameter: file descriptor */
  620.   if (remote_fileio_extract_int (&buf, &target_fd))
  621.     {
  622.       remote_fileio_ioerror ();
  623.       return;
  624.     }
  625.   fd = remote_fileio_map_fd ((int) target_fd);
  626.   if (fd == FIO_FD_INVALID)
  627.     {
  628.       remote_fileio_badfd ();
  629.       return;
  630.     }
  631.   /* 2. Parameter: buffer pointer */
  632.   if (remote_fileio_extract_long (&buf, &lnum))
  633.     {
  634.       remote_fileio_ioerror ();
  635.       return;
  636.     }
  637.   ptrval = (CORE_ADDR) lnum;
  638.   /* 3. Parameter: buffer length */
  639.   if (remote_fileio_extract_int (&buf, &num))
  640.     {
  641.       remote_fileio_ioerror ();
  642.       return;
  643.     }
  644.   length = (size_t) num;

  645.   switch (fd)
  646.     {
  647.       case FIO_FD_CONSOLE_OUT:
  648.         remote_fileio_badfd ();
  649.         return;
  650.       case FIO_FD_CONSOLE_IN:
  651.         {
  652.           static char *remaining_buf = NULL;
  653.           static int remaining_length = 0;

  654.           buffer = (gdb_byte *) xmalloc (16384);
  655.           if (remaining_buf)
  656.             {
  657.               remote_fio_no_longjmp = 1;
  658.               if (remaining_length > length)
  659.                 {
  660.                   memcpy (buffer, remaining_buf, length);
  661.                   memmove (remaining_buf, remaining_buf + length,
  662.                            remaining_length - length);
  663.                   remaining_length -= length;
  664.                   ret = length;
  665.                 }
  666.               else
  667.                 {
  668.                   memcpy (buffer, remaining_buf, remaining_length);
  669.                   xfree (remaining_buf);
  670.                   remaining_buf = NULL;
  671.                   ret = remaining_length;
  672.                 }
  673.             }
  674.           else
  675.             {
  676.               /* Windows (at least XP and Server 2003) has difficulty
  677.                  with large reads from consoles.  If a handle is
  678.                  backed by a real console device, overly large reads
  679.                  from the handle will fail and set errno == ENOMEM.
  680.                  On a Windows Server 2003 system where I tested,
  681.                  reading 26608 bytes from the console was OK, but
  682.                  anything above 26609 bytes would fail.  The limit has
  683.                  been observed to vary on different systems.  So, we
  684.                  limit this read to something smaller than that - by a
  685.                  safe margin, in case the limit depends on system
  686.                  resources or version.  */
  687.               ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
  688.               remote_fio_no_longjmp = 1;
  689.               if (ret > 0 && (size_t)ret > length)
  690.                 {
  691.                   remaining_buf = (char *) xmalloc (ret - length);
  692.                   remaining_length = ret - length;
  693.                   memcpy (remaining_buf, buffer + length, remaining_length);
  694.                   ret = length;
  695.                 }
  696.             }
  697.         }
  698.         break;
  699.       default:
  700.         buffer = (gdb_byte *) xmalloc (length);
  701.         /* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
  702.            for read() to return -1 even if "some" bytes have been read.  It
  703.            has been corrected in SUSv2 but that doesn't help us much...
  704.            Therefore a complete solution must check how many bytes have been
  705.            read on EINTR to return a more reliable value to the target */
  706.         old_offset = lseek (fd, 0, SEEK_CUR);
  707.         remote_fio_no_longjmp = 1;
  708.         ret = read (fd, buffer, length);
  709.         if (ret < 0 && errno == EINTR)
  710.           {
  711.             new_offset = lseek (fd, 0, SEEK_CUR);
  712.             /* If some data has been read, return the number of bytes read.
  713.                The Ctrl-C flag is set in remote_fileio_reply() anyway.  */
  714.             if (old_offset != new_offset)
  715.               ret = new_offset - old_offset;
  716.           }
  717.         break;
  718.     }

  719.   if (ret > 0)
  720.     {
  721.       errno = target_write_memory (ptrval, buffer, ret);
  722.       if (errno != 0)
  723.         ret = -1;
  724.     }

  725.   if (ret < 0)
  726.     remote_fileio_return_errno (-1);
  727.   else
  728.     remote_fileio_return_success (ret);

  729.   xfree (buffer);
  730. }

  731. static void
  732. remote_fileio_func_write (char *buf)
  733. {
  734.   long target_fd, num;
  735.   LONGEST lnum;
  736.   CORE_ADDR ptrval;
  737.   int fd, ret;
  738.   gdb_byte *buffer;
  739.   size_t length;

  740.   /* 1. Parameter: file descriptor */
  741.   if (remote_fileio_extract_int (&buf, &target_fd))
  742.     {
  743.       remote_fileio_ioerror ();
  744.       return;
  745.     }
  746.   fd = remote_fileio_map_fd ((int) target_fd);
  747.   if (fd == FIO_FD_INVALID)
  748.     {
  749.       remote_fileio_badfd ();
  750.       return;
  751.     }
  752.   /* 2. Parameter: buffer pointer */
  753.   if (remote_fileio_extract_long (&buf, &lnum))
  754.     {
  755.       remote_fileio_ioerror ();
  756.       return;
  757.     }
  758.   ptrval = (CORE_ADDR) lnum;
  759.   /* 3. Parameter: buffer length */
  760.   if (remote_fileio_extract_int (&buf, &num))
  761.     {
  762.       remote_fileio_ioerror ();
  763.       return;
  764.     }
  765.   length = (size_t) num;

  766.   buffer = (gdb_byte *) xmalloc (length);
  767.   if (target_read_memory (ptrval, buffer, length) != 0)
  768.     {
  769.       xfree (buffer);
  770.       remote_fileio_ioerror ();
  771.       return;
  772.     }

  773.   remote_fio_no_longjmp = 1;
  774.   switch (fd)
  775.     {
  776.       case FIO_FD_CONSOLE_IN:
  777.         remote_fileio_badfd ();
  778.         xfree (buffer);
  779.         return;
  780.       case FIO_FD_CONSOLE_OUT:
  781.         ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
  782.                        (char *) buffer, length);
  783.         gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
  784.         ret = length;
  785.         break;
  786.       default:
  787.         ret = write (fd, buffer, length);
  788.         if (ret < 0 && errno == EACCES)
  789.           errno = EBADF; /* Cygwin returns EACCESS when writing to a
  790.                             R/O file.  */
  791.         break;
  792.     }

  793.   if (ret < 0)
  794.     remote_fileio_return_errno (-1);
  795.   else
  796.     remote_fileio_return_success (ret);

  797.   xfree (buffer);
  798. }

  799. static void
  800. remote_fileio_func_lseek (char *buf)
  801. {
  802.   long num;
  803.   LONGEST lnum;
  804.   int fd, flag;
  805.   off_t offset, ret;

  806.   /* 1. Parameter: file descriptor */
  807.   if (remote_fileio_extract_int (&buf, &num))
  808.     {
  809.       remote_fileio_ioerror ();
  810.       return;
  811.     }
  812.   fd = remote_fileio_map_fd ((int) num);
  813.   if (fd == FIO_FD_INVALID)
  814.     {
  815.       remote_fileio_badfd ();
  816.       return;
  817.     }
  818.   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
  819.     {
  820.       remote_fileio_reply (-1, FILEIO_ESPIPE);
  821.       return;
  822.     }

  823.   /* 2. Parameter: offset */
  824.   if (remote_fileio_extract_long (&buf, &lnum))
  825.     {
  826.       remote_fileio_ioerror ();
  827.       return;
  828.     }
  829.   offset = (off_t) lnum;
  830.   /* 3. Parameter: flag */
  831.   if (remote_fileio_extract_int (&buf, &num))
  832.     {
  833.       remote_fileio_ioerror ();
  834.       return;
  835.     }
  836.   if (remote_fileio_seek_flag_to_host (num, &flag))
  837.     {
  838.       remote_fileio_reply (-1, FILEIO_EINVAL);
  839.       return;
  840.     }

  841.   remote_fio_no_longjmp = 1;
  842.   ret = lseek (fd, offset, flag);

  843.   if (ret == (off_t) -1)
  844.     remote_fileio_return_errno (-1);
  845.   else
  846.     remote_fileio_return_success (ret);
  847. }

  848. static void
  849. remote_fileio_func_rename (char *buf)
  850. {
  851.   CORE_ADDR old_ptr, new_ptr;
  852.   int old_len, new_len;
  853.   char *oldpath, *newpath;
  854.   int ret, of, nf;
  855.   struct stat ost, nst;

  856.   /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
  857.   if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
  858.     {
  859.       remote_fileio_ioerror ();
  860.       return;
  861.     }

  862.   /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
  863.   if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
  864.     {
  865.       remote_fileio_ioerror ();
  866.       return;
  867.     }

  868.   /* Request oldpath using 'm' packet */
  869.   oldpath = alloca (old_len);
  870.   if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
  871.     {
  872.       remote_fileio_ioerror ();
  873.       return;
  874.     }

  875.   /* Request newpath using 'm' packet */
  876.   newpath = alloca (new_len);
  877.   if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
  878.     {
  879.       remote_fileio_ioerror ();
  880.       return;
  881.     }

  882.   /* Only operate on regular files and directories.  */
  883.   of = stat (oldpath, &ost);
  884.   nf = stat (newpath, &nst);
  885.   if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
  886.       || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
  887.     {
  888.       remote_fileio_reply (-1, FILEIO_EACCES);
  889.       return;
  890.     }

  891.   remote_fio_no_longjmp = 1;
  892.   ret = rename (oldpath, newpath);

  893.   if (ret == -1)
  894.     {
  895.       /* Special case: newpath is a non-empty directory.  Some systems
  896.          return ENOTEMPTY, some return EEXIST.  We coerce that to be
  897.          always EEXIST.  */
  898.       if (errno == ENOTEMPTY)
  899.         errno = EEXIST;
  900. #ifdef __CYGWIN__
  901.       /* Workaround some Cygwin problems with correct errnos.  */
  902.       if (errno == EACCES)
  903.         {
  904.           if (!of && !nf && S_ISDIR (nst.st_mode))
  905.             {
  906.               if (S_ISREG (ost.st_mode))
  907.                 errno = EISDIR;
  908.               else
  909.                 {
  910.                   char oldfullpath[PATH_MAX];
  911.                   char newfullpath[PATH_MAX];
  912.                   int len;

  913.                   cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
  914.                                     PATH_MAX);
  915.                   cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
  916.                                     PATH_MAX);
  917.                   len = strlen (oldfullpath);
  918.                   if (IS_DIR_SEPARATOR (newfullpath[len])
  919.                       && !filename_ncmp (oldfullpath, newfullpath, len))
  920.                     errno = EINVAL;
  921.                   else
  922.                     errno = EEXIST;
  923.                 }
  924.             }
  925.         }
  926. #endif

  927.       remote_fileio_return_errno (-1);
  928.     }
  929.   else
  930.     remote_fileio_return_success (ret);
  931. }

  932. static void
  933. remote_fileio_func_unlink (char *buf)
  934. {
  935.   CORE_ADDR ptrval;
  936.   int length;
  937.   char *pathname;
  938.   int ret;
  939.   struct stat st;

  940.   /* Parameter: Ptr to pathname / length incl. trailing zero */
  941.   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
  942.     {
  943.       remote_fileio_ioerror ();
  944.       return;
  945.     }
  946.   /* Request pathname using 'm' packet */
  947.   pathname = alloca (length);
  948.   if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
  949.     {
  950.       remote_fileio_ioerror ();
  951.       return;
  952.     }

  953.   /* Only operate on regular files (and directories, which allows to return
  954.      the correct return code).  */
  955.   if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
  956.     {
  957.       remote_fileio_reply (-1, FILEIO_ENODEV);
  958.       return;
  959.     }

  960.   remote_fio_no_longjmp = 1;
  961.   ret = unlink (pathname);

  962.   if (ret == -1)
  963.     remote_fileio_return_errno (-1);
  964.   else
  965.     remote_fileio_return_success (ret);
  966. }

  967. static void
  968. remote_fileio_func_stat (char *buf)
  969. {
  970.   CORE_ADDR statptr, nameptr;
  971.   int ret, namelength;
  972.   char *pathname;
  973.   LONGEST lnum;
  974.   struct stat st;
  975.   struct fio_stat fst;

  976.   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
  977.   if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
  978.     {
  979.       remote_fileio_ioerror ();
  980.       return;
  981.     }

  982.   /* 2. Parameter: Ptr to struct stat */
  983.   if (remote_fileio_extract_long (&buf, &lnum))
  984.     {
  985.       remote_fileio_ioerror ();
  986.       return;
  987.     }
  988.   statptr = (CORE_ADDR) lnum;

  989.   /* Request pathname using 'm' packet */
  990.   pathname = alloca (namelength);
  991.   if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
  992.     {
  993.       remote_fileio_ioerror ();
  994.       return;
  995.     }

  996.   remote_fio_no_longjmp = 1;
  997.   ret = stat (pathname, &st);

  998.   if (ret == -1)
  999.     {
  1000.       remote_fileio_return_errno (-1);
  1001.       return;
  1002.     }
  1003.   /* Only operate on regular files and directories.  */
  1004.   if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
  1005.     {
  1006.       remote_fileio_reply (-1, FILEIO_EACCES);
  1007.       return;
  1008.     }
  1009.   if (statptr)
  1010.     {
  1011.       remote_fileio_to_fio_stat (&st, &fst);
  1012.       remote_fileio_to_fio_uint (0, fst.fst_dev);

  1013.       errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
  1014.       if (errno != 0)
  1015.         {
  1016.           remote_fileio_return_errno (-1);
  1017.           return;
  1018.         }
  1019.     }
  1020.   remote_fileio_return_success (ret);
  1021. }

  1022. static void
  1023. remote_fileio_func_fstat (char *buf)
  1024. {
  1025.   CORE_ADDR ptrval;
  1026.   int fd, ret;
  1027.   long target_fd;
  1028.   LONGEST lnum;
  1029.   struct stat st;
  1030.   struct fio_stat fst;
  1031.   struct timeval tv;

  1032.   /* 1. Parameter: file descriptor */
  1033.   if (remote_fileio_extract_int (&buf, &target_fd))
  1034.     {
  1035.       remote_fileio_ioerror ();
  1036.       return;
  1037.     }
  1038.   fd = remote_fileio_map_fd ((int) target_fd);
  1039.   if (fd == FIO_FD_INVALID)
  1040.     {
  1041.       remote_fileio_badfd ();
  1042.       return;
  1043.     }
  1044.   /* 2. Parameter: Ptr to struct stat */
  1045.   if (remote_fileio_extract_long (&buf, &lnum))
  1046.     {
  1047.       remote_fileio_ioerror ();
  1048.       return;
  1049.     }
  1050.   ptrval = (CORE_ADDR) lnum;

  1051.   remote_fio_no_longjmp = 1;
  1052.   if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
  1053.     {
  1054.       remote_fileio_to_fio_uint (1, fst.fst_dev);
  1055.       memset (&st, 0, sizeof (st));
  1056.       st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
  1057.       st.st_nlink = 1;
  1058. #ifdef HAVE_GETUID
  1059.       st.st_uid = getuid ();
  1060. #endif
  1061. #ifdef HAVE_GETGID
  1062.       st.st_gid = getgid ();
  1063. #endif
  1064. #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
  1065.       st.st_blksize = 512;
  1066. #endif
  1067. #if HAVE_STRUCT_STAT_ST_BLOCKS
  1068.       st.st_blocks = 0;
  1069. #endif
  1070.       if (!gettimeofday (&tv, NULL))
  1071.         st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
  1072.       else
  1073.         st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
  1074.       ret = 0;
  1075.     }
  1076.   else
  1077.     ret = fstat (fd, &st);

  1078.   if (ret == -1)
  1079.     {
  1080.       remote_fileio_return_errno (-1);
  1081.       return;
  1082.     }
  1083.   if (ptrval)
  1084.     {
  1085.       remote_fileio_to_fio_stat (&st, &fst);

  1086.       errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
  1087.       if (errno != 0)
  1088.         {
  1089.           remote_fileio_return_errno (-1);
  1090.           return;
  1091.         }
  1092.     }
  1093.   remote_fileio_return_success (ret);
  1094. }

  1095. static void
  1096. remote_fileio_func_gettimeofday (char *buf)
  1097. {
  1098.   LONGEST lnum;
  1099.   CORE_ADDR ptrval;
  1100.   int ret;
  1101.   struct timeval tv;
  1102.   struct fio_timeval ftv;

  1103.   /* 1. Parameter: struct timeval pointer */
  1104.   if (remote_fileio_extract_long (&buf, &lnum))
  1105.     {
  1106.       remote_fileio_ioerror ();
  1107.       return;
  1108.     }
  1109.   ptrval = (CORE_ADDR) lnum;
  1110.   /* 2. Parameter: some pointer value...  */
  1111.   if (remote_fileio_extract_long (&buf, &lnum))
  1112.     {
  1113.       remote_fileio_ioerror ();
  1114.       return;
  1115.     }
  1116.   /* ...which has to be NULL.  */
  1117.   if (lnum)
  1118.     {
  1119.       remote_fileio_reply (-1, FILEIO_EINVAL);
  1120.       return;
  1121.     }

  1122.   remote_fio_no_longjmp = 1;
  1123.   ret = gettimeofday (&tv, NULL);

  1124.   if (ret == -1)
  1125.     {
  1126.       remote_fileio_return_errno (-1);
  1127.       return;
  1128.     }

  1129.   if (ptrval)
  1130.     {
  1131.       remote_fileio_to_fio_timeval (&tv, &ftv);

  1132.       errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
  1133.       if (errno != 0)
  1134.         {
  1135.           remote_fileio_return_errno (-1);
  1136.           return;
  1137.         }
  1138.     }
  1139.   remote_fileio_return_success (ret);
  1140. }

  1141. static void
  1142. remote_fileio_func_isatty (char *buf)
  1143. {
  1144.   long target_fd;
  1145.   int fd;

  1146.   /* Parameter: file descriptor */
  1147.   if (remote_fileio_extract_int (&buf, &target_fd))
  1148.     {
  1149.       remote_fileio_ioerror ();
  1150.       return;
  1151.     }
  1152.   remote_fio_no_longjmp = 1;
  1153.   fd = remote_fileio_map_fd ((int) target_fd);
  1154.   remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
  1155.                                   fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
  1156. }

  1157. static void
  1158. remote_fileio_func_system (char *buf)
  1159. {
  1160.   CORE_ADDR ptrval;
  1161.   int ret, length;
  1162.   char *cmdline = NULL;

  1163.   /* Parameter: Ptr to commandline / length incl. trailing zero */
  1164.   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
  1165.     {
  1166.       remote_fileio_ioerror ();
  1167.       return;
  1168.     }

  1169.   if (length)
  1170.     {
  1171.       /* Request commandline using 'm' packet */
  1172.       cmdline = alloca (length);
  1173.       if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
  1174.         {
  1175.           remote_fileio_ioerror ();
  1176.           return;
  1177.         }
  1178.     }

  1179.   /* Check if system(3) has been explicitely allowed using the
  1180.      `set remote system-call-allowed 1' command.  If length is 0,
  1181.      indicating a NULL parameter to the system call, return zero to
  1182.      indicate a shell is not available.  Otherwise fail with EPERM.  */
  1183.   if (!remote_fio_system_call_allowed)
  1184.     {
  1185.       if (!length)
  1186.         remote_fileio_return_success (0);
  1187.       else
  1188.         remote_fileio_reply (-1, FILEIO_EPERM);
  1189.       return;
  1190.     }

  1191.   remote_fio_no_longjmp = 1;
  1192.   ret = system (cmdline);

  1193.   if (!length)
  1194.     remote_fileio_return_success (ret);
  1195.   else if (ret == -1)
  1196.     remote_fileio_return_errno (-1);
  1197.   else
  1198.     remote_fileio_return_success (WEXITSTATUS (ret));
  1199. }

  1200. static struct {
  1201.   char *name;
  1202.   void (*func)(char *);
  1203. } remote_fio_func_map[] = {
  1204.   { "open", remote_fileio_func_open },
  1205.   { "close", remote_fileio_func_close },
  1206.   { "read", remote_fileio_func_read },
  1207.   { "write", remote_fileio_func_write },
  1208.   { "lseek", remote_fileio_func_lseek },
  1209.   { "rename", remote_fileio_func_rename },
  1210.   { "unlink", remote_fileio_func_unlink },
  1211.   { "stat", remote_fileio_func_stat },
  1212.   { "fstat", remote_fileio_func_fstat },
  1213.   { "gettimeofday", remote_fileio_func_gettimeofday },
  1214.   { "isatty", remote_fileio_func_isatty },
  1215.   { "system", remote_fileio_func_system },
  1216.   { NULL, NULL }
  1217. };

  1218. static int
  1219. do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
  1220. {
  1221.   char *buf = buf_arg;
  1222.   char *c;
  1223.   int idx;

  1224.   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);

  1225.   c = strchr (++buf, ',');
  1226.   if (c)
  1227.     *c++ = '\0';
  1228.   else
  1229.     c = strchr (buf, '\0');
  1230.   for (idx = 0; remote_fio_func_map[idx].name; ++idx)
  1231.     if (!strcmp (remote_fio_func_map[idx].name, buf))
  1232.       break;
  1233.   if (!remote_fio_func_map[idx].name)        /* ERROR: No such function.  */
  1234.     return RETURN_ERROR;
  1235.   remote_fio_func_map[idx].func (c);
  1236.   return 0;
  1237. }

  1238. /* Close any open descriptors, and reinitialize the file mapping.  */

  1239. void
  1240. remote_fileio_reset (void)
  1241. {
  1242.   int ix;

  1243.   for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
  1244.     {
  1245.       int fd = remote_fio_data.fd_map[ix];

  1246.       if (fd >= 0)
  1247.         close (fd);
  1248.     }
  1249.   if (remote_fio_data.fd_map)
  1250.     {
  1251.       xfree (remote_fio_data.fd_map);
  1252.       remote_fio_data.fd_map = NULL;
  1253.       remote_fio_data.fd_map_size = 0;
  1254.     }
  1255. }

  1256. /* Handle a file I/O request.  BUF points to the packet containing the
  1257.    request.  CTRLC_PENDING_P should be nonzero if the target has not
  1258.    acknowledged the Ctrl-C sent asynchronously earlier.  */

  1259. void
  1260. remote_fileio_request (char *buf, int ctrlc_pending_p)
  1261. {
  1262.   int ex;

  1263.   remote_fileio_sig_init ();

  1264.   if (ctrlc_pending_p)
  1265.     {
  1266.       /* If the target hasn't responded to the Ctrl-C sent
  1267.          asynchronously earlier, take this opportunity to send the
  1268.          Ctrl-C synchronously.  */
  1269.       remote_fio_ctrl_c_flag = 1;
  1270.       remote_fio_no_longjmp = 0;
  1271.       remote_fileio_reply (-1, FILEIO_EINTR);
  1272.     }
  1273.   else
  1274.     {
  1275.       remote_fio_ctrl_c_flag = 0;
  1276.       remote_fio_no_longjmp = 0;

  1277.       ex = catch_exceptions (current_uiout,
  1278.                              do_remote_fileio_request, (void *)buf,
  1279.                              RETURN_MASK_ALL);
  1280.       switch (ex)
  1281.         {
  1282.         case RETURN_ERROR:
  1283.           remote_fileio_reply (-1, FILEIO_ENOSYS);
  1284.           break;
  1285.         case RETURN_QUIT:
  1286.           remote_fileio_reply (-1, FILEIO_EINTR);
  1287.           break;
  1288.         default:
  1289.           break;
  1290.         }
  1291.     }

  1292.   remote_fileio_sig_exit ();
  1293. }

  1294. static void
  1295. set_system_call_allowed (char *args, int from_tty)
  1296. {
  1297.   if (args)
  1298.     {
  1299.       char *arg_end;
  1300.       int val = strtoul (args, &arg_end, 10);

  1301.       if (*args && *arg_end == '\0')
  1302.         {
  1303.           remote_fio_system_call_allowed = !!val;
  1304.           return;
  1305.         }
  1306.     }
  1307.   error (_("Illegal argument for \"set remote system-call-allowed\" command"));
  1308. }

  1309. static void
  1310. show_system_call_allowed (char *args, int from_tty)
  1311. {
  1312.   if (args)
  1313.     error (_("Garbage after \"show remote "
  1314.              "system-call-allowed\" command: `%s'"), args);
  1315.   printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
  1316.                      remote_fio_system_call_allowed ? "" : "not ");
  1317. }

  1318. void
  1319. initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
  1320.                           struct cmd_list_element *remote_show_cmdlist)
  1321. {
  1322.   sigint_fileio_token =
  1323.     create_async_signal_handler (async_remote_fileio_interrupt, NULL);

  1324.   add_cmd ("system-call-allowed", no_class,
  1325.            set_system_call_allowed,
  1326.            _("Set if the host system(3) call is allowed for the target."),
  1327.            &remote_set_cmdlist);
  1328.   add_cmd ("system-call-allowed", no_class,
  1329.            show_system_call_allowed,
  1330.            _("Show if the host system(3) call is allowed for the target."),
  1331.            &remote_show_cmdlist);
  1332. }