GDB (API)
/home/stan/gdb/src/gdb/remote-fileio.c
Go to the documentation of this file.
00001 /* Remote File-I/O communications
00002 
00003    Copyright (C) 2003-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 /* See the GDB User Guide for details of the GDB remote protocol.  */
00021 
00022 #include "defs.h"
00023 #include "gdb_string.h"
00024 #include "gdbcmd.h"
00025 #include "remote.h"
00026 #include "gdb/fileio.h"
00027 #include "gdb_wait.h"
00028 #include "gdb_stat.h"
00029 #include "exceptions.h"
00030 #include "remote-fileio.h"
00031 #include "event-loop.h"
00032 #include "target.h"
00033 #include "filenames.h"
00034 #include "filestuff.h"
00035 
00036 #include <fcntl.h>
00037 #include <sys/time.h>
00038 #ifdef __CYGWIN__
00039 #include <sys/cygwin.h>         /* For cygwin_conv_path.  */
00040 #endif
00041 #include <signal.h>
00042 
00043 static struct {
00044   int *fd_map;
00045   int fd_map_size;
00046 } remote_fio_data;
00047 
00048 #define FIO_FD_INVALID          -1
00049 #define FIO_FD_CONSOLE_IN       -2
00050 #define FIO_FD_CONSOLE_OUT      -3
00051 
00052 static int remote_fio_system_call_allowed = 0;
00053 
00054 static struct async_signal_handler *sigint_fileio_token;
00055 
00056 static int
00057 remote_fileio_init_fd_map (void)
00058 {
00059   int i;
00060 
00061   if (!remote_fio_data.fd_map)
00062     {
00063       remote_fio_data.fd_map = (int *) xmalloc (10 * sizeof (int));
00064       remote_fio_data.fd_map_size = 10;
00065       remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
00066       remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
00067       remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
00068       for (i = 3; i < 10; ++i)
00069         remote_fio_data.fd_map[i] = FIO_FD_INVALID;
00070     }
00071   return 3;
00072 }
00073 
00074 static int
00075 remote_fileio_resize_fd_map (void)
00076 {
00077   int i = remote_fio_data.fd_map_size;
00078 
00079   if (!remote_fio_data.fd_map)
00080     return remote_fileio_init_fd_map ();
00081   remote_fio_data.fd_map_size += 10;
00082   remote_fio_data.fd_map =
00083     (int *) xrealloc (remote_fio_data.fd_map,
00084                       remote_fio_data.fd_map_size * sizeof (int));
00085   for (; i < remote_fio_data.fd_map_size; i++)
00086     remote_fio_data.fd_map[i] = FIO_FD_INVALID;
00087   return remote_fio_data.fd_map_size - 10;
00088 }
00089 
00090 static int
00091 remote_fileio_next_free_fd (void)
00092 {
00093   int i;
00094 
00095   for (i = 0; i < remote_fio_data.fd_map_size; ++i)
00096     if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
00097       return i;
00098   return remote_fileio_resize_fd_map ();
00099 }
00100 
00101 static int
00102 remote_fileio_fd_to_targetfd (int fd)
00103 {
00104   int target_fd = remote_fileio_next_free_fd ();
00105 
00106   remote_fio_data.fd_map[target_fd] = fd;
00107   return target_fd;
00108 }
00109 
00110 static int
00111 remote_fileio_map_fd (int target_fd)
00112 {
00113   remote_fileio_init_fd_map ();
00114   if (target_fd < 0 || target_fd >= remote_fio_data.fd_map_size)
00115     return FIO_FD_INVALID;
00116   return remote_fio_data.fd_map[target_fd];
00117 }
00118 
00119 static void
00120 remote_fileio_close_target_fd (int target_fd)
00121 {
00122   remote_fileio_init_fd_map ();
00123   if (target_fd >= 0 && target_fd < remote_fio_data.fd_map_size)
00124     remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID;
00125 }
00126 
00127 static int
00128 remote_fileio_oflags_to_host (long flags)
00129 {
00130   int hflags = 0;
00131 
00132   if (flags & FILEIO_O_CREAT)
00133     hflags |= O_CREAT;
00134   if (flags & FILEIO_O_EXCL)
00135     hflags |= O_EXCL;
00136   if (flags & FILEIO_O_TRUNC)
00137     hflags |= O_TRUNC;
00138   if (flags & FILEIO_O_APPEND)
00139     hflags |= O_APPEND;
00140   if (flags & FILEIO_O_RDONLY)
00141     hflags |= O_RDONLY;
00142   if (flags & FILEIO_O_WRONLY)
00143     hflags |= O_WRONLY;
00144   if (flags & FILEIO_O_RDWR)
00145     hflags |= O_RDWR;
00146 /* On systems supporting binary and text mode, always open files in
00147    binary mode.  */
00148 #ifdef O_BINARY
00149   hflags |= O_BINARY;
00150 #endif
00151   return hflags;
00152 }
00153 
00154 static mode_t
00155 remote_fileio_mode_to_host (long mode, int open_call)
00156 {
00157   mode_t hmode = 0;
00158 
00159   if (!open_call)
00160     {
00161       if (mode & FILEIO_S_IFREG)
00162         hmode |= S_IFREG;
00163       if (mode & FILEIO_S_IFDIR)
00164         hmode |= S_IFDIR;
00165       if (mode & FILEIO_S_IFCHR)
00166         hmode |= S_IFCHR;
00167     }
00168   if (mode & FILEIO_S_IRUSR)
00169     hmode |= S_IRUSR;
00170   if (mode & FILEIO_S_IWUSR)
00171     hmode |= S_IWUSR;
00172   if (mode & FILEIO_S_IXUSR)
00173     hmode |= S_IXUSR;
00174 #ifdef S_IRGRP
00175   if (mode & FILEIO_S_IRGRP)
00176     hmode |= S_IRGRP;
00177 #endif
00178 #ifdef S_IWGRP
00179   if (mode & FILEIO_S_IWGRP)
00180     hmode |= S_IWGRP;
00181 #endif
00182 #ifdef S_IXGRP
00183   if (mode & FILEIO_S_IXGRP)
00184     hmode |= S_IXGRP;
00185 #endif
00186   if (mode & FILEIO_S_IROTH)
00187     hmode |= S_IROTH;
00188 #ifdef S_IWOTH
00189   if (mode & FILEIO_S_IWOTH)
00190     hmode |= S_IWOTH;
00191 #endif
00192 #ifdef S_IXOTH
00193   if (mode & FILEIO_S_IXOTH)
00194     hmode |= S_IXOTH;
00195 #endif
00196   return hmode;
00197 }
00198 
00199 static LONGEST
00200 remote_fileio_mode_to_target (mode_t mode)
00201 {
00202   mode_t tmode = 0;
00203 
00204   if (S_ISREG(mode))
00205     tmode |= FILEIO_S_IFREG;
00206   if (S_ISDIR(mode))
00207     tmode |= FILEIO_S_IFDIR;
00208   if (S_ISCHR(mode))
00209     tmode |= FILEIO_S_IFCHR;
00210   if (mode & S_IRUSR)
00211     tmode |= FILEIO_S_IRUSR;
00212   if (mode & S_IWUSR)
00213     tmode |= FILEIO_S_IWUSR;
00214   if (mode & S_IXUSR)
00215     tmode |= FILEIO_S_IXUSR;
00216 #ifdef S_IRGRP
00217   if (mode & S_IRGRP)
00218     tmode |= FILEIO_S_IRGRP;
00219 #endif
00220 #ifdef S_IWRGRP
00221   if (mode & S_IWGRP)
00222     tmode |= FILEIO_S_IWGRP;
00223 #endif
00224 #ifdef S_IXGRP
00225   if (mode & S_IXGRP)
00226     tmode |= FILEIO_S_IXGRP;
00227 #endif
00228   if (mode & S_IROTH)
00229     tmode |= FILEIO_S_IROTH;
00230 #ifdef S_IWOTH
00231   if (mode & S_IWOTH)
00232     tmode |= FILEIO_S_IWOTH;
00233 #endif
00234 #ifdef S_IXOTH
00235   if (mode & S_IXOTH)
00236     tmode |= FILEIO_S_IXOTH;
00237 #endif
00238   return tmode;
00239 }
00240 
00241 static int
00242 remote_fileio_errno_to_target (int error)
00243 {
00244   switch (error)
00245     {
00246       case EPERM:
00247         return FILEIO_EPERM;
00248       case ENOENT:
00249         return FILEIO_ENOENT;
00250       case EINTR:
00251         return FILEIO_EINTR;
00252       case EIO:
00253         return FILEIO_EIO;
00254       case EBADF:
00255         return FILEIO_EBADF;
00256       case EACCES:
00257         return FILEIO_EACCES;
00258       case EFAULT:
00259         return FILEIO_EFAULT;
00260       case EBUSY:
00261         return FILEIO_EBUSY;
00262       case EEXIST:
00263         return FILEIO_EEXIST;
00264       case ENODEV:
00265         return FILEIO_ENODEV;
00266       case ENOTDIR:
00267         return FILEIO_ENOTDIR;
00268       case EISDIR:
00269         return FILEIO_EISDIR;
00270       case EINVAL:
00271         return FILEIO_EINVAL;
00272       case ENFILE:
00273         return FILEIO_ENFILE;
00274       case EMFILE:
00275         return FILEIO_EMFILE;
00276       case EFBIG:
00277         return FILEIO_EFBIG;
00278       case ENOSPC:
00279         return FILEIO_ENOSPC;
00280       case ESPIPE:
00281         return FILEIO_ESPIPE;
00282       case EROFS:
00283         return FILEIO_EROFS;
00284       case ENOSYS:
00285         return FILEIO_ENOSYS;
00286       case ENAMETOOLONG:
00287         return FILEIO_ENAMETOOLONG;
00288     }
00289   return FILEIO_EUNKNOWN;
00290 }
00291 
00292 static int
00293 remote_fileio_seek_flag_to_host (long num, int *flag)
00294 {
00295   if (!flag)
00296     return 0;
00297   switch (num)
00298     {
00299       case FILEIO_SEEK_SET:
00300         *flag = SEEK_SET;
00301         break;
00302       case FILEIO_SEEK_CUR:
00303         *flag =  SEEK_CUR;
00304         break;
00305       case FILEIO_SEEK_END:
00306         *flag =  SEEK_END;
00307         break;
00308       default:
00309         return -1;
00310     }
00311   return 0;
00312 }
00313 
00314 static int
00315 remote_fileio_extract_long (char **buf, LONGEST *retlong)
00316 {
00317   char *c;
00318   int sign = 1;
00319 
00320   if (!buf || !*buf || !**buf || !retlong)
00321     return -1;
00322   c = strchr (*buf, ',');
00323   if (c)
00324     *c++ = '\0';
00325   else
00326     c = strchr (*buf, '\0');
00327   while (strchr ("+-", **buf))
00328     {
00329       if (**buf == '-')
00330         sign = -sign;
00331       ++*buf;
00332     }
00333   for (*retlong = 0; **buf; ++*buf)
00334     {
00335       *retlong <<= 4;
00336       if (**buf >= '0' && **buf <= '9')
00337         *retlong += **buf - '0';
00338       else if (**buf >= 'a' && **buf <= 'f')
00339         *retlong += **buf - 'a' + 10;
00340       else if (**buf >= 'A' && **buf <= 'F')
00341         *retlong += **buf - 'A' + 10;
00342       else
00343         return -1;
00344     }
00345   *retlong *= sign;
00346   *buf = c;
00347   return 0;
00348 }
00349 
00350 static int
00351 remote_fileio_extract_int (char **buf, long *retint)
00352 {
00353   int ret;
00354   LONGEST retlong;
00355 
00356   if (!retint)
00357     return -1;
00358   ret = remote_fileio_extract_long (buf, &retlong);
00359   if (!ret)
00360     *retint = (long) retlong;
00361   return ret;
00362 }
00363 
00364 static int
00365 remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
00366 {
00367   char *c;
00368   LONGEST retlong;
00369 
00370   if (!buf || !*buf || !**buf || !ptrval || !length)
00371     return -1;
00372   c = strchr (*buf, '/');
00373   if (!c)
00374     return -1;
00375   *c++ = '\0';
00376   if (remote_fileio_extract_long (buf, &retlong))
00377     return -1;
00378   *ptrval = (CORE_ADDR) retlong;
00379   *buf = c;
00380   if (remote_fileio_extract_long (buf, &retlong))
00381     return -1;
00382   *length = (int) retlong;
00383   return 0;
00384 }
00385 
00386 /* Convert to big endian.  */
00387 static void
00388 remote_fileio_to_be (LONGEST num, char *buf, int bytes)
00389 {
00390   int i;
00391 
00392   for (i = 0; i < bytes; ++i)
00393     buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff;
00394 }
00395 
00396 static void
00397 remote_fileio_to_fio_uint (long num, fio_uint_t fnum)
00398 {
00399   remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
00400 }
00401 
00402 static void
00403 remote_fileio_to_fio_mode (mode_t num, fio_mode_t fnum)
00404 {
00405   remote_fileio_to_be (remote_fileio_mode_to_target(num), (char *) fnum, 4);
00406 }
00407 
00408 static void
00409 remote_fileio_to_fio_time (time_t num, fio_time_t fnum)
00410 {
00411   remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
00412 }
00413 
00414 static void
00415 remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
00416 {
00417   remote_fileio_to_be (num, (char *) fnum, 8);
00418 }
00419 
00420 static void
00421 remote_fileio_to_fio_ulong (LONGEST num, fio_ulong_t fnum)
00422 {
00423   remote_fileio_to_be (num, (char *) fnum, 8);
00424 }
00425 
00426 static void
00427 remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst)
00428 {
00429   LONGEST blksize;
00430 
00431   /* `st_dev' is set in the calling function.  */
00432   remote_fileio_to_fio_uint ((long) st->st_ino, fst->fst_ino);
00433   remote_fileio_to_fio_mode (st->st_mode, fst->fst_mode);
00434   remote_fileio_to_fio_uint ((long) st->st_nlink, fst->fst_nlink);
00435   remote_fileio_to_fio_uint ((long) st->st_uid, fst->fst_uid);
00436   remote_fileio_to_fio_uint ((long) st->st_gid, fst->fst_gid);
00437   remote_fileio_to_fio_uint ((long) st->st_rdev, fst->fst_rdev);
00438   remote_fileio_to_fio_ulong ((LONGEST) st->st_size, fst->fst_size);
00439 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
00440   blksize = st->st_blksize;
00441 #else
00442   blksize = 512;
00443 #endif
00444   remote_fileio_to_fio_ulong (blksize, fst->fst_blksize);
00445 #if HAVE_STRUCT_STAT_ST_BLOCKS
00446   remote_fileio_to_fio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
00447 #else
00448   /* FIXME: This is correct for DJGPP, but other systems that don't
00449      have st_blocks, if any, might prefer 512 instead of st_blksize.
00450      (eliz, 30-12-2003)  */
00451   remote_fileio_to_fio_ulong (((LONGEST) st->st_size + blksize - 1)
00452                               / blksize,
00453                               fst->fst_blocks);
00454 #endif
00455   remote_fileio_to_fio_time (st->st_atime, fst->fst_atime);
00456   remote_fileio_to_fio_time (st->st_mtime, fst->fst_mtime);
00457   remote_fileio_to_fio_time (st->st_ctime, fst->fst_ctime);
00458 }
00459 
00460 static void
00461 remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
00462 {
00463   remote_fileio_to_fio_time (tv->tv_sec, ftv->ftv_sec);
00464   remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
00465 }
00466 
00467 static int remote_fio_ctrl_c_flag = 0;
00468 static int remote_fio_no_longjmp = 0;
00469 
00470 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
00471 static struct sigaction remote_fio_sa;
00472 static struct sigaction remote_fio_osa;
00473 #else
00474 static void (*remote_fio_ofunc)(int);
00475 #endif
00476 
00477 static void
00478 remote_fileio_sig_init (void)
00479 {
00480 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
00481   remote_fio_sa.sa_handler = SIG_IGN;
00482   sigemptyset (&remote_fio_sa.sa_mask);
00483   remote_fio_sa.sa_flags = 0;
00484   sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa);
00485 #else
00486   remote_fio_ofunc = signal (SIGINT, SIG_IGN);
00487 #endif
00488 }
00489 
00490 static void
00491 remote_fileio_sig_set (void (*sigint_func)(int))
00492 {
00493 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
00494   remote_fio_sa.sa_handler = sigint_func;
00495   sigemptyset (&remote_fio_sa.sa_mask);
00496   remote_fio_sa.sa_flags = 0;
00497   sigaction (SIGINT, &remote_fio_sa, NULL);
00498 #else
00499   signal (SIGINT, sigint_func);
00500 #endif
00501 }
00502 
00503 static void
00504 remote_fileio_sig_exit (void)
00505 {
00506 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
00507   sigaction (SIGINT, &remote_fio_osa, NULL);
00508 #else
00509   signal (SIGINT, remote_fio_ofunc);
00510 #endif
00511 }
00512 
00513 static void
00514 async_remote_fileio_interrupt (gdb_client_data arg)
00515 {
00516   quit ();
00517 }
00518 
00519 static void
00520 remote_fileio_ctrl_c_signal_handler (int signo)
00521 {
00522   remote_fileio_sig_set (SIG_IGN);
00523   remote_fio_ctrl_c_flag = 1;
00524   if (!remote_fio_no_longjmp)
00525     gdb_call_async_signal_handler (sigint_fileio_token, 1);
00526   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
00527 }
00528 
00529 static void
00530 remote_fileio_reply (int retcode, int error)
00531 {
00532   char buf[32];
00533 
00534   remote_fileio_sig_set (SIG_IGN);
00535   strcpy (buf, "F");
00536   if (retcode < 0)
00537     {
00538       strcat (buf, "-");
00539       retcode = -retcode;
00540     }
00541   sprintf (buf + strlen (buf), "%x", retcode);
00542   if (error || remote_fio_ctrl_c_flag)
00543     {
00544       if (error && remote_fio_ctrl_c_flag)
00545         error = FILEIO_EINTR;
00546       if (error < 0)
00547         {
00548           strcat (buf, "-");
00549           error = -error;
00550         }
00551       sprintf (buf + strlen (buf), ",%x", error);
00552       if (remote_fio_ctrl_c_flag)
00553         strcat (buf, ",C");
00554     }
00555   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
00556   putpkt (buf);
00557 }
00558 
00559 static void
00560 remote_fileio_ioerror (void)
00561 {
00562   remote_fileio_reply (-1, FILEIO_EIO);
00563 }
00564 
00565 static void
00566 remote_fileio_badfd (void)
00567 {
00568   remote_fileio_reply (-1, FILEIO_EBADF);
00569 }
00570 
00571 static void
00572 remote_fileio_return_errno (int retcode)
00573 {
00574   remote_fileio_reply (retcode, retcode < 0
00575                        ? remote_fileio_errno_to_target (errno) : 0);
00576 }
00577 
00578 static void
00579 remote_fileio_return_success (int retcode)
00580 {
00581   remote_fileio_reply (retcode, 0);
00582 }
00583 
00584 static void
00585 remote_fileio_func_open (char *buf)
00586 {
00587   CORE_ADDR ptrval;
00588   int length;
00589   long num;
00590   int flags, fd;
00591   mode_t mode;
00592   char *pathname;
00593   struct stat st;
00594 
00595   /* 1. Parameter: Ptr to pathname / length incl. trailing zero.  */
00596   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
00597     {
00598       remote_fileio_ioerror ();
00599       return;
00600     }
00601   /* 2. Parameter: open flags */
00602   if (remote_fileio_extract_int (&buf, &num))
00603     {
00604       remote_fileio_ioerror ();
00605       return;
00606     }
00607   flags = remote_fileio_oflags_to_host (num);
00608   /* 3. Parameter: open mode */
00609   if (remote_fileio_extract_int (&buf, &num))
00610     {
00611       remote_fileio_ioerror ();
00612       return;
00613     }
00614   mode = remote_fileio_mode_to_host (num, 1);
00615 
00616   /* Request pathname.  */
00617   pathname = alloca (length);
00618   if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
00619     {
00620       remote_fileio_ioerror ();
00621       return;
00622     }
00623 
00624   /* Check if pathname exists and is not a regular file or directory.  If so,
00625      return an appropriate error code.  Same for trying to open directories
00626      for writing.  */
00627   if (!stat (pathname, &st))
00628     {
00629       if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
00630         {
00631           remote_fileio_reply (-1, FILEIO_ENODEV);
00632           return;
00633         }
00634       if (S_ISDIR (st.st_mode)
00635           && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
00636         {
00637           remote_fileio_reply (-1, FILEIO_EISDIR);
00638           return;
00639         }
00640     }
00641 
00642   remote_fio_no_longjmp = 1;
00643   fd = gdb_open_cloexec (pathname, flags, mode);
00644   if (fd < 0)
00645     {
00646       remote_fileio_return_errno (-1);
00647       return;
00648     }
00649 
00650   fd = remote_fileio_fd_to_targetfd (fd);
00651   remote_fileio_return_success (fd);
00652 }
00653 
00654 static void
00655 remote_fileio_func_close (char *buf)
00656 {
00657   long num;
00658   int fd;
00659 
00660   /* Parameter: file descriptor */
00661   if (remote_fileio_extract_int (&buf, &num))
00662     {
00663       remote_fileio_ioerror ();
00664       return;
00665     }
00666   fd = remote_fileio_map_fd ((int) num);
00667   if (fd == FIO_FD_INVALID)
00668     {
00669       remote_fileio_badfd ();
00670       return;
00671     }
00672 
00673   remote_fio_no_longjmp = 1;
00674   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
00675     remote_fileio_return_errno (-1);
00676   remote_fileio_close_target_fd ((int) num);
00677   remote_fileio_return_success (0);
00678 }
00679 
00680 static void
00681 remote_fileio_func_read (char *buf)
00682 {
00683   long target_fd, num;
00684   LONGEST lnum;
00685   CORE_ADDR ptrval;
00686   int fd, ret;
00687   gdb_byte *buffer;
00688   size_t length;
00689   off_t old_offset, new_offset;
00690 
00691   /* 1. Parameter: file descriptor */
00692   if (remote_fileio_extract_int (&buf, &target_fd))
00693     {
00694       remote_fileio_ioerror ();
00695       return;
00696     }
00697   fd = remote_fileio_map_fd ((int) target_fd);
00698   if (fd == FIO_FD_INVALID)
00699     {
00700       remote_fileio_badfd ();
00701       return;
00702     }
00703   /* 2. Parameter: buffer pointer */
00704   if (remote_fileio_extract_long (&buf, &lnum))
00705     {
00706       remote_fileio_ioerror ();
00707       return;
00708     }
00709   ptrval = (CORE_ADDR) lnum;
00710   /* 3. Parameter: buffer length */
00711   if (remote_fileio_extract_int (&buf, &num))
00712     {
00713       remote_fileio_ioerror ();
00714       return;
00715     }
00716   length = (size_t) num;
00717 
00718   switch (fd)
00719     {
00720       case FIO_FD_CONSOLE_OUT:
00721         remote_fileio_badfd ();
00722         return;
00723       case FIO_FD_CONSOLE_IN:
00724         {
00725           static char *remaining_buf = NULL;
00726           static int remaining_length = 0;
00727 
00728           buffer = (gdb_byte *) xmalloc (16384);
00729           if (remaining_buf)
00730             {
00731               remote_fio_no_longjmp = 1;
00732               if (remaining_length > length)
00733                 {
00734                   memcpy (buffer, remaining_buf, length);
00735                   memmove (remaining_buf, remaining_buf + length,
00736                            remaining_length - length);
00737                   remaining_length -= length;
00738                   ret = length;
00739                 }
00740               else
00741                 {
00742                   memcpy (buffer, remaining_buf, remaining_length);
00743                   xfree (remaining_buf);
00744                   remaining_buf = NULL;
00745                   ret = remaining_length;
00746                 }
00747             }
00748           else
00749             {
00750               /* Windows (at least XP and Server 2003) has difficulty
00751                  with large reads from consoles.  If a handle is
00752                  backed by a real console device, overly large reads
00753                  from the handle will fail and set errno == ENOMEM.
00754                  On a Windows Server 2003 system where I tested,
00755                  reading 26608 bytes from the console was OK, but
00756                  anything above 26609 bytes would fail.  The limit has
00757                  been observed to vary on different systems.  So, we
00758                  limit this read to something smaller than that - by a
00759                  safe margin, in case the limit depends on system
00760                  resources or version.  */
00761               ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
00762               remote_fio_no_longjmp = 1;
00763               if (ret > 0 && (size_t)ret > length)
00764                 {
00765                   remaining_buf = (char *) xmalloc (ret - length);
00766                   remaining_length = ret - length;
00767                   memcpy (remaining_buf, buffer + length, remaining_length);
00768                   ret = length;
00769                 }
00770             }
00771         }
00772         break;
00773       default:
00774         buffer = (gdb_byte *) xmalloc (length);
00775         /* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
00776            for read() to return -1 even if "some" bytes have been read.  It
00777            has been corrected in SUSv2 but that doesn't help us much...
00778            Therefore a complete solution must check how many bytes have been
00779            read on EINTR to return a more reliable value to the target */
00780         old_offset = lseek (fd, 0, SEEK_CUR);
00781         remote_fio_no_longjmp = 1;
00782         ret = read (fd, buffer, length);
00783         if (ret < 0 && errno == EINTR)
00784           {
00785             new_offset = lseek (fd, 0, SEEK_CUR);
00786             /* If some data has been read, return the number of bytes read.
00787                The Ctrl-C flag is set in remote_fileio_reply() anyway.  */
00788             if (old_offset != new_offset)
00789               ret = new_offset - old_offset;
00790           }
00791         break;
00792     }
00793 
00794   if (ret > 0)
00795     {
00796       errno = target_write_memory (ptrval, buffer, ret);
00797       if (errno != 0)
00798         ret = -1;
00799     }
00800 
00801   if (ret < 0)
00802     remote_fileio_return_errno (-1);
00803   else
00804     remote_fileio_return_success (ret);
00805 
00806   xfree (buffer);
00807 }
00808 
00809 static void
00810 remote_fileio_func_write (char *buf)
00811 {
00812   long target_fd, num;
00813   LONGEST lnum;
00814   CORE_ADDR ptrval;
00815   int fd, ret;
00816   gdb_byte *buffer;
00817   size_t length;
00818 
00819   /* 1. Parameter: file descriptor */
00820   if (remote_fileio_extract_int (&buf, &target_fd))
00821     {
00822       remote_fileio_ioerror ();
00823       return;
00824     }
00825   fd = remote_fileio_map_fd ((int) target_fd);
00826   if (fd == FIO_FD_INVALID)
00827     {
00828       remote_fileio_badfd ();
00829       return;
00830     }
00831   /* 2. Parameter: buffer pointer */
00832   if (remote_fileio_extract_long (&buf, &lnum))
00833     {
00834       remote_fileio_ioerror ();
00835       return;
00836     }
00837   ptrval = (CORE_ADDR) lnum;
00838   /* 3. Parameter: buffer length */
00839   if (remote_fileio_extract_int (&buf, &num))
00840     {
00841       remote_fileio_ioerror ();
00842       return;
00843     }
00844   length = (size_t) num;
00845     
00846   buffer = (gdb_byte *) xmalloc (length);
00847   if (target_read_memory (ptrval, buffer, length) != 0)
00848     {
00849       xfree (buffer);
00850       remote_fileio_ioerror ();
00851       return;
00852     }
00853 
00854   remote_fio_no_longjmp = 1;
00855   switch (fd)
00856     {
00857       case FIO_FD_CONSOLE_IN:
00858         remote_fileio_badfd ();
00859         xfree (buffer);
00860         return;
00861       case FIO_FD_CONSOLE_OUT:
00862         ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
00863                        (char *) buffer, length);
00864         gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
00865         ret = length;
00866         break;
00867       default:
00868         ret = write (fd, buffer, length);
00869         if (ret < 0 && errno == EACCES)
00870           errno = EBADF; /* Cygwin returns EACCESS when writing to a
00871                             R/O file.  */
00872         break;
00873     }
00874 
00875   if (ret < 0)
00876     remote_fileio_return_errno (-1);
00877   else
00878     remote_fileio_return_success (ret);
00879 
00880   xfree (buffer);
00881 }
00882 
00883 static void
00884 remote_fileio_func_lseek (char *buf)
00885 {
00886   long num;
00887   LONGEST lnum;
00888   int fd, flag;
00889   off_t offset, ret;
00890 
00891   /* 1. Parameter: file descriptor */
00892   if (remote_fileio_extract_int (&buf, &num))
00893     {
00894       remote_fileio_ioerror ();
00895       return;
00896     }
00897   fd = remote_fileio_map_fd ((int) num);
00898   if (fd == FIO_FD_INVALID)
00899     {
00900       remote_fileio_badfd ();
00901       return;
00902     }
00903   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
00904     {
00905       remote_fileio_reply (-1, FILEIO_ESPIPE);
00906       return;
00907     }
00908 
00909   /* 2. Parameter: offset */
00910   if (remote_fileio_extract_long (&buf, &lnum))
00911     {
00912       remote_fileio_ioerror ();
00913       return;
00914     }
00915   offset = (off_t) lnum;
00916   /* 3. Parameter: flag */
00917   if (remote_fileio_extract_int (&buf, &num))
00918     {
00919       remote_fileio_ioerror ();
00920       return;
00921     }
00922   if (remote_fileio_seek_flag_to_host (num, &flag))
00923     {
00924       remote_fileio_reply (-1, FILEIO_EINVAL);
00925       return;
00926     }
00927   
00928   remote_fio_no_longjmp = 1;
00929   ret = lseek (fd, offset, flag);
00930 
00931   if (ret == (off_t) -1)
00932     remote_fileio_return_errno (-1);
00933   else
00934     remote_fileio_return_success (ret);
00935 }
00936 
00937 static void
00938 remote_fileio_func_rename (char *buf)
00939 {
00940   CORE_ADDR old_ptr, new_ptr;
00941   int old_len, new_len;
00942   char *oldpath, *newpath;
00943   int ret, of, nf;
00944   struct stat ost, nst;
00945 
00946   /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
00947   if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
00948     {
00949       remote_fileio_ioerror ();
00950       return;
00951     }
00952   
00953   /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
00954   if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
00955     {
00956       remote_fileio_ioerror ();
00957       return;
00958     }
00959   
00960   /* Request oldpath using 'm' packet */
00961   oldpath = alloca (old_len);
00962   if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
00963     {
00964       remote_fileio_ioerror ();
00965       return;
00966     }
00967   
00968   /* Request newpath using 'm' packet */
00969   newpath = alloca (new_len);
00970   if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
00971     {
00972       remote_fileio_ioerror ();
00973       return;
00974     }
00975   
00976   /* Only operate on regular files and directories.  */
00977   of = stat (oldpath, &ost);
00978   nf = stat (newpath, &nst);
00979   if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
00980       || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
00981     {
00982       remote_fileio_reply (-1, FILEIO_EACCES);
00983       return;
00984     }
00985 
00986   remote_fio_no_longjmp = 1;
00987   ret = rename (oldpath, newpath);
00988 
00989   if (ret == -1)
00990     {
00991       /* Special case: newpath is a non-empty directory.  Some systems
00992          return ENOTEMPTY, some return EEXIST.  We coerce that to be
00993          always EEXIST.  */
00994       if (errno == ENOTEMPTY)
00995         errno = EEXIST;
00996 #ifdef __CYGWIN__
00997       /* Workaround some Cygwin problems with correct errnos.  */
00998       if (errno == EACCES)
00999         {
01000           if (!of && !nf && S_ISDIR (nst.st_mode))
01001             {
01002               if (S_ISREG (ost.st_mode))
01003                 errno = EISDIR;
01004               else
01005                 {
01006                   char oldfullpath[PATH_MAX];
01007                   char newfullpath[PATH_MAX];
01008                   int len;
01009 
01010                   cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
01011                                     PATH_MAX);
01012                   cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
01013                                     PATH_MAX);
01014                   len = strlen (oldfullpath);
01015                   if (IS_DIR_SEPARATOR (newfullpath[len])
01016                       && !filename_ncmp (oldfullpath, newfullpath, len))
01017                     errno = EINVAL;
01018                   else
01019                     errno = EEXIST;
01020                 }
01021             }
01022         }
01023 #endif
01024 
01025       remote_fileio_return_errno (-1);
01026     }
01027   else
01028     remote_fileio_return_success (ret);
01029 }
01030 
01031 static void
01032 remote_fileio_func_unlink (char *buf)
01033 {
01034   CORE_ADDR ptrval;
01035   int length;
01036   char *pathname;
01037   int ret;
01038   struct stat st;
01039 
01040   /* Parameter: Ptr to pathname / length incl. trailing zero */
01041   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
01042     {
01043       remote_fileio_ioerror ();
01044       return;
01045     }
01046   /* Request pathname using 'm' packet */
01047   pathname = alloca (length);
01048   if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
01049     {
01050       remote_fileio_ioerror ();
01051       return;
01052     }
01053 
01054   /* Only operate on regular files (and directories, which allows to return
01055      the correct return code).  */
01056   if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
01057     {
01058       remote_fileio_reply (-1, FILEIO_ENODEV);
01059       return;
01060     }
01061 
01062   remote_fio_no_longjmp = 1;
01063   ret = unlink (pathname);
01064 
01065   if (ret == -1)
01066     remote_fileio_return_errno (-1);
01067   else
01068     remote_fileio_return_success (ret);
01069 }
01070 
01071 static void
01072 remote_fileio_func_stat (char *buf)
01073 {
01074   CORE_ADDR statptr, nameptr;
01075   int ret, namelength;
01076   char *pathname;
01077   LONGEST lnum;
01078   struct stat st;
01079   struct fio_stat fst;
01080 
01081   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
01082   if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
01083     {
01084       remote_fileio_ioerror ();
01085       return;
01086     }
01087 
01088   /* 2. Parameter: Ptr to struct stat */
01089   if (remote_fileio_extract_long (&buf, &lnum))
01090     {
01091       remote_fileio_ioerror ();
01092       return;
01093     }
01094   statptr = (CORE_ADDR) lnum;
01095   
01096   /* Request pathname using 'm' packet */
01097   pathname = alloca (namelength);
01098   if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
01099     {
01100       remote_fileio_ioerror ();
01101       return;
01102     }
01103 
01104   remote_fio_no_longjmp = 1;
01105   ret = stat (pathname, &st);
01106 
01107   if (ret == -1)
01108     {
01109       remote_fileio_return_errno (-1);
01110       return;
01111     }
01112   /* Only operate on regular files and directories.  */
01113   if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
01114     {
01115       remote_fileio_reply (-1, FILEIO_EACCES);
01116       return;
01117     }
01118   if (statptr)
01119     {
01120       remote_fileio_to_fio_stat (&st, &fst);
01121       remote_fileio_to_fio_uint (0, fst.fst_dev);
01122 
01123       errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
01124       if (errno != 0)
01125         {
01126           remote_fileio_return_errno (-1);
01127           return;
01128         }
01129     }
01130   remote_fileio_return_success (ret);
01131 }
01132 
01133 static void
01134 remote_fileio_func_fstat (char *buf)
01135 {
01136   CORE_ADDR ptrval;
01137   int fd, ret;
01138   long target_fd;
01139   LONGEST lnum;
01140   struct stat st;
01141   struct fio_stat fst;
01142   struct timeval tv;
01143 
01144   /* 1. Parameter: file descriptor */
01145   if (remote_fileio_extract_int (&buf, &target_fd))
01146     {
01147       remote_fileio_ioerror ();
01148       return;
01149     }
01150   fd = remote_fileio_map_fd ((int) target_fd);
01151   if (fd == FIO_FD_INVALID)
01152     {
01153       remote_fileio_badfd ();
01154       return;
01155     }
01156   /* 2. Parameter: Ptr to struct stat */
01157   if (remote_fileio_extract_long (&buf, &lnum))
01158     {
01159       remote_fileio_ioerror ();
01160       return;
01161     }
01162   ptrval = (CORE_ADDR) lnum;
01163 
01164   remote_fio_no_longjmp = 1;
01165   if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
01166     {
01167       remote_fileio_to_fio_uint (1, fst.fst_dev);
01168       memset (&st, 0, sizeof (st));
01169       st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
01170       st.st_nlink = 1;
01171 #ifdef HAVE_GETUID
01172       st.st_uid = getuid ();
01173 #endif
01174 #ifdef HAVE_GETGID
01175       st.st_gid = getgid ();
01176 #endif
01177 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
01178       st.st_blksize = 512;
01179 #endif
01180 #if HAVE_STRUCT_STAT_ST_BLOCKS
01181       st.st_blocks = 0;
01182 #endif
01183       if (!gettimeofday (&tv, NULL))
01184         st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
01185       else
01186         st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
01187       ret = 0;
01188     }
01189   else
01190     ret = fstat (fd, &st);
01191 
01192   if (ret == -1)
01193     {
01194       remote_fileio_return_errno (-1);
01195       return;
01196     }
01197   if (ptrval)
01198     {
01199       remote_fileio_to_fio_stat (&st, &fst);
01200 
01201       errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
01202       if (errno != 0)
01203         {
01204           remote_fileio_return_errno (-1);
01205           return;
01206         }
01207     }
01208   remote_fileio_return_success (ret);
01209 }
01210 
01211 static void
01212 remote_fileio_func_gettimeofday (char *buf)
01213 {
01214   LONGEST lnum;
01215   CORE_ADDR ptrval;
01216   int ret;
01217   struct timeval tv;
01218   struct fio_timeval ftv;
01219 
01220   /* 1. Parameter: struct timeval pointer */
01221   if (remote_fileio_extract_long (&buf, &lnum))
01222     {
01223       remote_fileio_ioerror ();
01224       return;
01225     }
01226   ptrval = (CORE_ADDR) lnum;
01227   /* 2. Parameter: some pointer value...  */
01228   if (remote_fileio_extract_long (&buf, &lnum))
01229     {
01230       remote_fileio_ioerror ();
01231       return;
01232     }
01233   /* ...which has to be NULL.  */
01234   if (lnum)
01235     {
01236       remote_fileio_reply (-1, FILEIO_EINVAL);
01237       return;
01238     }
01239 
01240   remote_fio_no_longjmp = 1;
01241   ret = gettimeofday (&tv, NULL);
01242 
01243   if (ret == -1)
01244     {
01245       remote_fileio_return_errno (-1);
01246       return;
01247     }
01248 
01249   if (ptrval)
01250     {
01251       remote_fileio_to_fio_timeval (&tv, &ftv);
01252 
01253       errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
01254       if (errno != 0)
01255         {
01256           remote_fileio_return_errno (-1);
01257           return;
01258         }
01259     }
01260   remote_fileio_return_success (ret);
01261 }
01262 
01263 static void
01264 remote_fileio_func_isatty (char *buf)
01265 {
01266   long target_fd;
01267   int fd;
01268 
01269   /* Parameter: file descriptor */
01270   if (remote_fileio_extract_int (&buf, &target_fd))
01271     {
01272       remote_fileio_ioerror ();
01273       return;
01274     }
01275   remote_fio_no_longjmp = 1;
01276   fd = remote_fileio_map_fd ((int) target_fd);
01277   remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
01278                                 fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
01279 }
01280 
01281 static void
01282 remote_fileio_func_system (char *buf)
01283 {
01284   CORE_ADDR ptrval;
01285   int ret, length;
01286   char *cmdline = NULL;
01287 
01288   /* Parameter: Ptr to commandline / length incl. trailing zero */
01289   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
01290     {
01291       remote_fileio_ioerror ();
01292       return;
01293     }
01294 
01295   if (length)
01296     {
01297       /* Request commandline using 'm' packet */
01298       cmdline = alloca (length);
01299       if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
01300         {
01301           remote_fileio_ioerror ();
01302           return;
01303         }
01304     }
01305   
01306   /* Check if system(3) has been explicitely allowed using the
01307      `set remote system-call-allowed 1' command.  If length is 0,
01308      indicating a NULL parameter to the system call, return zero to
01309      indicate a shell is not available.  Otherwise fail with EPERM.  */
01310   if (!remote_fio_system_call_allowed)
01311     {
01312       if (!length)
01313         remote_fileio_return_success (0);
01314       else
01315         remote_fileio_reply (-1, FILEIO_EPERM);
01316       return;
01317     }
01318 
01319   remote_fio_no_longjmp = 1;
01320   ret = system (cmdline);
01321 
01322   if (!length)
01323     remote_fileio_return_success (ret);
01324   else if (ret == -1)
01325     remote_fileio_return_errno (-1);
01326   else
01327     remote_fileio_return_success (WEXITSTATUS (ret));
01328 }
01329 
01330 static struct {
01331   char *name;
01332   void (*func)(char *);
01333 } remote_fio_func_map[] = {
01334   { "open", remote_fileio_func_open },
01335   { "close", remote_fileio_func_close },
01336   { "read", remote_fileio_func_read },
01337   { "write", remote_fileio_func_write },
01338   { "lseek", remote_fileio_func_lseek },
01339   { "rename", remote_fileio_func_rename },
01340   { "unlink", remote_fileio_func_unlink },
01341   { "stat", remote_fileio_func_stat },
01342   { "fstat", remote_fileio_func_fstat },
01343   { "gettimeofday", remote_fileio_func_gettimeofday },
01344   { "isatty", remote_fileio_func_isatty },
01345   { "system", remote_fileio_func_system },
01346   { NULL, NULL }
01347 };
01348 
01349 static int
01350 do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
01351 {
01352   char *buf = buf_arg;
01353   char *c;
01354   int idx;
01355 
01356   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
01357 
01358   c = strchr (++buf, ',');
01359   if (c)
01360     *c++ = '\0';
01361   else
01362     c = strchr (buf, '\0');
01363   for (idx = 0; remote_fio_func_map[idx].name; ++idx)
01364     if (!strcmp (remote_fio_func_map[idx].name, buf))
01365       break;
01366   if (!remote_fio_func_map[idx].name)   /* ERROR: No such function.  */
01367     return RETURN_ERROR;
01368   remote_fio_func_map[idx].func (c);
01369   return 0;
01370 }
01371 
01372 /* Close any open descriptors, and reinitialize the file mapping.  */
01373 
01374 void
01375 remote_fileio_reset (void)
01376 {
01377   int ix;
01378 
01379   for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
01380     {
01381       int fd = remote_fio_data.fd_map[ix];
01382 
01383       if (fd >= 0)
01384         close (fd);
01385     }
01386   if (remote_fio_data.fd_map)
01387     {
01388       xfree (remote_fio_data.fd_map);
01389       remote_fio_data.fd_map = NULL;
01390       remote_fio_data.fd_map_size = 0;
01391     }
01392 }
01393 
01394 /* Handle a file I/O request.  BUF points to the packet containing the
01395    request.  CTRLC_PENDING_P should be nonzero if the target has not
01396    acknowledged the Ctrl-C sent asynchronously earlier.  */
01397 
01398 void
01399 remote_fileio_request (char *buf, int ctrlc_pending_p)
01400 {
01401   int ex;
01402 
01403   remote_fileio_sig_init ();
01404 
01405   if (ctrlc_pending_p)
01406     {
01407       /* If the target hasn't responded to the Ctrl-C sent
01408          asynchronously earlier, take this opportunity to send the
01409          Ctrl-C synchronously.  */
01410       remote_fio_ctrl_c_flag = 1;
01411       remote_fio_no_longjmp = 0;
01412       remote_fileio_reply (-1, FILEIO_EINTR);
01413     }
01414   else
01415     {
01416       remote_fio_ctrl_c_flag = 0;
01417       remote_fio_no_longjmp = 0;
01418 
01419       ex = catch_exceptions (current_uiout,
01420                              do_remote_fileio_request, (void *)buf,
01421                              RETURN_MASK_ALL);
01422       switch (ex)
01423         {
01424         case RETURN_ERROR:
01425           remote_fileio_reply (-1, FILEIO_ENOSYS);
01426           break;
01427         case RETURN_QUIT:
01428           remote_fileio_reply (-1, FILEIO_EINTR);
01429           break;
01430         default:
01431           break;
01432         }
01433     }
01434 
01435   remote_fileio_sig_exit ();
01436 }
01437 
01438 static void
01439 set_system_call_allowed (char *args, int from_tty)
01440 {
01441   if (args)
01442     {
01443       char *arg_end;
01444       int val = strtoul (args, &arg_end, 10);
01445 
01446       if (*args && *arg_end == '\0')
01447         {
01448           remote_fio_system_call_allowed = !!val;
01449           return;
01450         }
01451     }
01452   error (_("Illegal argument for \"set remote system-call-allowed\" command"));
01453 }
01454 
01455 static void
01456 show_system_call_allowed (char *args, int from_tty)
01457 {
01458   if (args)
01459     error (_("Garbage after \"show remote "
01460              "system-call-allowed\" command: `%s'"), args);
01461   printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
01462                      remote_fio_system_call_allowed ? "" : "not ");
01463 }
01464 
01465 void
01466 initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
01467                           struct cmd_list_element *remote_show_cmdlist)
01468 {
01469   sigint_fileio_token =
01470     create_async_signal_handler (async_remote_fileio_interrupt, NULL);
01471 
01472   add_cmd ("system-call-allowed", no_class,
01473            set_system_call_allowed,
01474            _("Set if the host system(3) call is allowed for the target."),
01475            &remote_set_cmdlist);
01476   add_cmd ("system-call-allowed", no_class,
01477            show_system_call_allowed,
01478            _("Show if the host system(3) call is allowed for the target."),
01479            &remote_show_cmdlist);
01480 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines