xref: /dflybsd-src/contrib/gdb-7/gdb/remote-fileio.c (revision c0d274d062fd959993bf623f25f7cb6a8a676c4e)
1 /* Remote File-I/O communications
2 
3    Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010
4    Free Software Foundation, Inc.
5 
6    This file is part of GDB.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 /* See the GDB User Guide for details of the GDB remote protocol. */
22 
23 #include "defs.h"
24 #include "gdb_string.h"
25 #include "gdbcmd.h"
26 #include "remote.h"
27 #include "gdb/fileio.h"
28 #include "gdb_wait.h"
29 #include "gdb_stat.h"
30 #include "exceptions.h"
31 #include "remote-fileio.h"
32 #include "event-loop.h"
33 
34 #include <fcntl.h>
35 #include <sys/time.h>
36 #ifdef __CYGWIN__
37 #include <sys/cygwin.h>		/* For cygwin_conv_to_full_posix_path.  */
38 #include <cygwin/version.h>
39 #if CYGWIN_VERSION_DLL_MAKE_COMBINED(CYGWIN_VERSION_API_MAJOR,CYGWIN_VERSION_API_MINOR) < 181
40 # define CCP_POSIX_TO_WIN_A 0
41 # define CCP_WIN_A_TO_POSIX 2
42 # define cygwin_conv_path(op, from, to, size)  \
43          (op == CCP_WIN_A_TO_POSIX) ? \
44          cygwin_conv_to_full_posix_path (from, to) : \
45          cygwin_conv_to_win32_path (from, to)
46 #endif
47 #endif
48 #include <signal.h>
49 
50 static struct {
51   int *fd_map;
52   int fd_map_size;
53 } remote_fio_data;
54 
55 #define FIO_FD_INVALID		-1
56 #define FIO_FD_CONSOLE_IN	-2
57 #define FIO_FD_CONSOLE_OUT	-3
58 
59 static int remote_fio_system_call_allowed = 0;
60 
61 static struct async_signal_handler *sigint_fileio_token;
62 
63 static int
64 remote_fileio_init_fd_map (void)
65 {
66   int i;
67 
68   if (!remote_fio_data.fd_map)
69     {
70       remote_fio_data.fd_map = (int *) xmalloc (10 * sizeof (int));
71       remote_fio_data.fd_map_size = 10;
72       remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
73       remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
74       remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
75       for (i = 3; i < 10; ++i)
76         remote_fio_data.fd_map[i] = FIO_FD_INVALID;
77     }
78   return 3;
79 }
80 
81 static int
82 remote_fileio_resize_fd_map (void)
83 {
84   int i = remote_fio_data.fd_map_size;
85 
86   if (!remote_fio_data.fd_map)
87     return remote_fileio_init_fd_map ();
88   remote_fio_data.fd_map_size += 10;
89   remote_fio_data.fd_map =
90     (int *) xrealloc (remote_fio_data.fd_map,
91 		      remote_fio_data.fd_map_size * sizeof (int));
92   for (; i < remote_fio_data.fd_map_size; i++)
93     remote_fio_data.fd_map[i] = FIO_FD_INVALID;
94   return remote_fio_data.fd_map_size - 10;
95 }
96 
97 static int
98 remote_fileio_next_free_fd (void)
99 {
100   int i;
101 
102   for (i = 0; i < remote_fio_data.fd_map_size; ++i)
103     if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
104       return i;
105   return remote_fileio_resize_fd_map ();
106 }
107 
108 static int
109 remote_fileio_fd_to_targetfd (int fd)
110 {
111   int target_fd = remote_fileio_next_free_fd ();
112 
113   remote_fio_data.fd_map[target_fd] = fd;
114   return target_fd;
115 }
116 
117 static int
118 remote_fileio_map_fd (int target_fd)
119 {
120   remote_fileio_init_fd_map ();
121   if (target_fd < 0 || target_fd >= remote_fio_data.fd_map_size)
122     return FIO_FD_INVALID;
123   return remote_fio_data.fd_map[target_fd];
124 }
125 
126 static void
127 remote_fileio_close_target_fd (int target_fd)
128 {
129   remote_fileio_init_fd_map ();
130   if (target_fd >= 0 && target_fd < remote_fio_data.fd_map_size)
131     remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID;
132 }
133 
134 static int
135 remote_fileio_oflags_to_host (long flags)
136 {
137   int hflags = 0;
138 
139   if (flags & FILEIO_O_CREAT)
140     hflags |= O_CREAT;
141   if (flags & FILEIO_O_EXCL)
142     hflags |= O_EXCL;
143   if (flags & FILEIO_O_TRUNC)
144     hflags |= O_TRUNC;
145   if (flags & FILEIO_O_APPEND)
146     hflags |= O_APPEND;
147   if (flags & FILEIO_O_RDONLY)
148     hflags |= O_RDONLY;
149   if (flags & FILEIO_O_WRONLY)
150     hflags |= O_WRONLY;
151   if (flags & FILEIO_O_RDWR)
152     hflags |= O_RDWR;
153 /* On systems supporting binary and text mode, always open files in
154    binary mode. */
155 #ifdef O_BINARY
156   hflags |= O_BINARY;
157 #endif
158   return hflags;
159 }
160 
161 static mode_t
162 remote_fileio_mode_to_host (long mode, int open_call)
163 {
164   mode_t hmode = 0;
165 
166   if (!open_call)
167     {
168       if (mode & FILEIO_S_IFREG)
169 	hmode |= S_IFREG;
170       if (mode & FILEIO_S_IFDIR)
171 	hmode |= S_IFDIR;
172       if (mode & FILEIO_S_IFCHR)
173 	hmode |= S_IFCHR;
174     }
175   if (mode & FILEIO_S_IRUSR)
176     hmode |= S_IRUSR;
177   if (mode & FILEIO_S_IWUSR)
178     hmode |= S_IWUSR;
179   if (mode & FILEIO_S_IXUSR)
180     hmode |= S_IXUSR;
181 #ifdef S_IRGRP
182   if (mode & FILEIO_S_IRGRP)
183     hmode |= S_IRGRP;
184 #endif
185 #ifdef S_IWGRP
186   if (mode & FILEIO_S_IWGRP)
187     hmode |= S_IWGRP;
188 #endif
189 #ifdef S_IXGRP
190   if (mode & FILEIO_S_IXGRP)
191     hmode |= S_IXGRP;
192 #endif
193   if (mode & FILEIO_S_IROTH)
194     hmode |= S_IROTH;
195 #ifdef S_IWOTH
196   if (mode & FILEIO_S_IWOTH)
197     hmode |= S_IWOTH;
198 #endif
199 #ifdef S_IXOTH
200   if (mode & FILEIO_S_IXOTH)
201     hmode |= S_IXOTH;
202 #endif
203   return hmode;
204 }
205 
206 static LONGEST
207 remote_fileio_mode_to_target (mode_t mode)
208 {
209   mode_t tmode = 0;
210 
211   if (S_ISREG(mode))
212     tmode |= FILEIO_S_IFREG;
213   if (S_ISDIR(mode))
214     tmode |= FILEIO_S_IFDIR;
215   if (S_ISCHR(mode))
216     tmode |= FILEIO_S_IFCHR;
217   if (mode & S_IRUSR)
218     tmode |= FILEIO_S_IRUSR;
219   if (mode & S_IWUSR)
220     tmode |= FILEIO_S_IWUSR;
221   if (mode & S_IXUSR)
222     tmode |= FILEIO_S_IXUSR;
223 #ifdef S_IRGRP
224   if (mode & S_IRGRP)
225     tmode |= FILEIO_S_IRGRP;
226 #endif
227 #ifdef S_IWRGRP
228   if (mode & S_IWGRP)
229     tmode |= FILEIO_S_IWGRP;
230 #endif
231 #ifdef S_IXGRP
232   if (mode & S_IXGRP)
233     tmode |= FILEIO_S_IXGRP;
234 #endif
235   if (mode & S_IROTH)
236     tmode |= FILEIO_S_IROTH;
237 #ifdef S_IWOTH
238   if (mode & S_IWOTH)
239     tmode |= FILEIO_S_IWOTH;
240 #endif
241 #ifdef S_IXOTH
242   if (mode & S_IXOTH)
243     tmode |= FILEIO_S_IXOTH;
244 #endif
245   return tmode;
246 }
247 
248 static int
249 remote_fileio_errno_to_target (int error)
250 {
251   switch (error)
252     {
253       case EPERM:
254         return FILEIO_EPERM;
255       case ENOENT:
256         return FILEIO_ENOENT;
257       case EINTR:
258         return FILEIO_EINTR;
259       case EIO:
260         return FILEIO_EIO;
261       case EBADF:
262         return FILEIO_EBADF;
263       case EACCES:
264         return FILEIO_EACCES;
265       case EFAULT:
266         return FILEIO_EFAULT;
267       case EBUSY:
268         return FILEIO_EBUSY;
269       case EEXIST:
270         return FILEIO_EEXIST;
271       case ENODEV:
272         return FILEIO_ENODEV;
273       case ENOTDIR:
274         return FILEIO_ENOTDIR;
275       case EISDIR:
276         return FILEIO_EISDIR;
277       case EINVAL:
278         return FILEIO_EINVAL;
279       case ENFILE:
280         return FILEIO_ENFILE;
281       case EMFILE:
282         return FILEIO_EMFILE;
283       case EFBIG:
284         return FILEIO_EFBIG;
285       case ENOSPC:
286         return FILEIO_ENOSPC;
287       case ESPIPE:
288         return FILEIO_ESPIPE;
289       case EROFS:
290         return FILEIO_EROFS;
291       case ENOSYS:
292         return FILEIO_ENOSYS;
293       case ENAMETOOLONG:
294         return FILEIO_ENAMETOOLONG;
295     }
296   return FILEIO_EUNKNOWN;
297 }
298 
299 static int
300 remote_fileio_seek_flag_to_host (long num, int *flag)
301 {
302   if (!flag)
303     return 0;
304   switch (num)
305     {
306       case FILEIO_SEEK_SET:
307         *flag = SEEK_SET;
308 	break;
309       case FILEIO_SEEK_CUR:
310         *flag =  SEEK_CUR;
311 	break;
312       case FILEIO_SEEK_END:
313         *flag =  SEEK_END;
314 	break;
315       default:
316         return -1;
317     }
318   return 0;
319 }
320 
321 static int
322 remote_fileio_extract_long (char **buf, LONGEST *retlong)
323 {
324   char *c;
325   int sign = 1;
326 
327   if (!buf || !*buf || !**buf || !retlong)
328     return -1;
329   c = strchr (*buf, ',');
330   if (c)
331     *c++ = '\0';
332   else
333     c = strchr (*buf, '\0');
334   while (strchr ("+-", **buf))
335     {
336       if (**buf == '-')
337 	sign = -sign;
338       ++*buf;
339     }
340   for (*retlong = 0; **buf; ++*buf)
341     {
342       *retlong <<= 4;
343       if (**buf >= '0' && **buf <= '9')
344         *retlong += **buf - '0';
345       else if (**buf >= 'a' && **buf <= 'f')
346         *retlong += **buf - 'a' + 10;
347       else if (**buf >= 'A' && **buf <= 'F')
348         *retlong += **buf - 'A' + 10;
349       else
350         return -1;
351     }
352   *retlong *= sign;
353   *buf = c;
354   return 0;
355 }
356 
357 static int
358 remote_fileio_extract_int (char **buf, long *retint)
359 {
360   int ret;
361   LONGEST retlong;
362 
363   if (!retint)
364     return -1;
365   ret = remote_fileio_extract_long (buf, &retlong);
366   if (!ret)
367     *retint = (long) retlong;
368   return ret;
369 }
370 
371 static int
372 remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
373 {
374   char *c;
375   LONGEST retlong;
376 
377   if (!buf || !*buf || !**buf || !ptrval || !length)
378     return -1;
379   c = strchr (*buf, '/');
380   if (!c)
381     return -1;
382   *c++ = '\0';
383   if (remote_fileio_extract_long (buf, &retlong))
384     return -1;
385   *ptrval = (CORE_ADDR) retlong;
386   *buf = c;
387   if (remote_fileio_extract_long (buf, &retlong))
388     return -1;
389   *length = (int) retlong;
390   return 0;
391 }
392 
393 /* Convert to big endian */
394 static void
395 remote_fileio_to_be (LONGEST num, char *buf, int bytes)
396 {
397   int i;
398 
399   for (i = 0; i < bytes; ++i)
400     buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff;
401 }
402 
403 static void
404 remote_fileio_to_fio_uint (long num, fio_uint_t fnum)
405 {
406   remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
407 }
408 
409 static void
410 remote_fileio_to_fio_mode (mode_t num, fio_mode_t fnum)
411 {
412   remote_fileio_to_be (remote_fileio_mode_to_target(num), (char *) fnum, 4);
413 }
414 
415 static void
416 remote_fileio_to_fio_time (time_t num, fio_time_t fnum)
417 {
418   remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
419 }
420 
421 static void
422 remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
423 {
424   remote_fileio_to_be (num, (char *) fnum, 8);
425 }
426 
427 static void
428 remote_fileio_to_fio_ulong (LONGEST num, fio_ulong_t fnum)
429 {
430   remote_fileio_to_be (num, (char *) fnum, 8);
431 }
432 
433 static void
434 remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst)
435 {
436   LONGEST blksize;
437 
438   /* `st_dev' is set in the calling function */
439   remote_fileio_to_fio_uint ((long) st->st_ino, fst->fst_ino);
440   remote_fileio_to_fio_mode (st->st_mode, fst->fst_mode);
441   remote_fileio_to_fio_uint ((long) st->st_nlink, fst->fst_nlink);
442   remote_fileio_to_fio_uint ((long) st->st_uid, fst->fst_uid);
443   remote_fileio_to_fio_uint ((long) st->st_gid, fst->fst_gid);
444   remote_fileio_to_fio_uint ((long) st->st_rdev, fst->fst_rdev);
445   remote_fileio_to_fio_ulong ((LONGEST) st->st_size, fst->fst_size);
446 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
447   blksize = st->st_blksize;
448 #else
449   blksize = 512;
450 #endif
451   remote_fileio_to_fio_ulong (blksize, fst->fst_blksize);
452 #if HAVE_STRUCT_STAT_ST_BLOCKS
453   remote_fileio_to_fio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
454 #else
455   /* FIXME: This is correct for DJGPP, but other systems that don't
456      have st_blocks, if any, might prefer 512 instead of st_blksize.
457      (eliz, 30-12-2003)  */
458   remote_fileio_to_fio_ulong (((LONGEST) st->st_size + blksize - 1)
459 			      / blksize,
460 			      fst->fst_blocks);
461 #endif
462   remote_fileio_to_fio_time (st->st_atime, fst->fst_atime);
463   remote_fileio_to_fio_time (st->st_mtime, fst->fst_mtime);
464   remote_fileio_to_fio_time (st->st_ctime, fst->fst_ctime);
465 }
466 
467 static void
468 remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
469 {
470   remote_fileio_to_fio_time (tv->tv_sec, ftv->ftv_sec);
471   remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
472 }
473 
474 static int remote_fio_ctrl_c_flag = 0;
475 static int remote_fio_no_longjmp = 0;
476 
477 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
478 static struct sigaction remote_fio_sa;
479 static struct sigaction remote_fio_osa;
480 #else
481 static void (*remote_fio_ofunc)(int);
482 #endif
483 
484 static void
485 remote_fileio_sig_init (void)
486 {
487 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
488   remote_fio_sa.sa_handler = SIG_IGN;
489   sigemptyset (&remote_fio_sa.sa_mask);
490   remote_fio_sa.sa_flags = 0;
491   sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa);
492 #else
493   remote_fio_ofunc = signal (SIGINT, SIG_IGN);
494 #endif
495 }
496 
497 static void
498 remote_fileio_sig_set (void (*sigint_func)(int))
499 {
500 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
501   remote_fio_sa.sa_handler = sigint_func;
502   sigemptyset (&remote_fio_sa.sa_mask);
503   remote_fio_sa.sa_flags = 0;
504   sigaction (SIGINT, &remote_fio_sa, NULL);
505 #else
506   signal (SIGINT, sigint_func);
507 #endif
508 }
509 
510 static void
511 remote_fileio_sig_exit (void)
512 {
513 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
514   sigaction (SIGINT, &remote_fio_osa, NULL);
515 #else
516   signal (SIGINT, remote_fio_ofunc);
517 #endif
518 }
519 
520 static void
521 async_remote_fileio_interrupt (gdb_client_data arg)
522 {
523   deprecated_throw_reason (RETURN_QUIT);
524 }
525 
526 static void
527 remote_fileio_ctrl_c_signal_handler (int signo)
528 {
529   remote_fileio_sig_set (SIG_IGN);
530   remote_fio_ctrl_c_flag = 1;
531   if (!remote_fio_no_longjmp)
532     gdb_call_async_signal_handler (sigint_fileio_token, 1);
533   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
534 }
535 
536 static void
537 remote_fileio_reply (int retcode, int error)
538 {
539   char buf[32];
540 
541   remote_fileio_sig_set (SIG_IGN);
542   strcpy (buf, "F");
543   if (retcode < 0)
544     {
545       strcat (buf, "-");
546       retcode = -retcode;
547     }
548   sprintf (buf + strlen (buf), "%x", retcode);
549   if (error || remote_fio_ctrl_c_flag)
550     {
551       if (error && remote_fio_ctrl_c_flag)
552         error = FILEIO_EINTR;
553       if (error < 0)
554         {
555 	  strcat (buf, "-");
556 	  error = -error;
557 	}
558       sprintf (buf + strlen (buf), ",%x", error);
559       if (remote_fio_ctrl_c_flag)
560         strcat (buf, ",C");
561     }
562   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
563   putpkt (buf);
564 }
565 
566 static void
567 remote_fileio_ioerror (void)
568 {
569   remote_fileio_reply (-1, FILEIO_EIO);
570 }
571 
572 static void
573 remote_fileio_badfd (void)
574 {
575   remote_fileio_reply (-1, FILEIO_EBADF);
576 }
577 
578 static void
579 remote_fileio_return_errno (int retcode)
580 {
581   remote_fileio_reply (retcode,
582 		       retcode < 0 ? remote_fileio_errno_to_target (errno) : 0);
583 }
584 
585 static void
586 remote_fileio_return_success (int retcode)
587 {
588   remote_fileio_reply (retcode, 0);
589 }
590 
591 /* Wrapper function for remote_write_bytes() which has the disadvantage to
592    write only one packet, regardless of the requested number of bytes to
593    transfer.  This wrapper calls remote_write_bytes() as often as needed. */
594 static int
595 remote_fileio_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
596 {
597   int ret = 0, written;
598 
599   while (len > 0 && (written = remote_write_bytes (memaddr, myaddr, len)) > 0)
600     {
601       len -= written;
602       memaddr += written;
603       myaddr += written;
604       ret += written;
605     }
606   return ret;
607 }
608 
609 static void
610 remote_fileio_func_open (char *buf)
611 {
612   CORE_ADDR ptrval;
613   int length, retlength;
614   long num;
615   int flags, fd;
616   mode_t mode;
617   char *pathname;
618   struct stat st;
619 
620   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
621   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
622     {
623       remote_fileio_ioerror ();
624       return;
625     }
626   /* 2. Parameter: open flags */
627   if (remote_fileio_extract_int (&buf, &num))
628     {
629       remote_fileio_ioerror ();
630       return;
631     }
632   flags = remote_fileio_oflags_to_host (num);
633   /* 3. Parameter: open mode */
634   if (remote_fileio_extract_int (&buf, &num))
635     {
636       remote_fileio_ioerror ();
637       return;
638     }
639   mode = remote_fileio_mode_to_host (num, 1);
640 
641   /* Request pathname using 'm' packet */
642   pathname = alloca (length);
643   retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
644   if (retlength != length)
645     {
646       remote_fileio_ioerror ();
647       return;
648     }
649 
650   /* Check if pathname exists and is not a regular file or directory.  If so,
651      return an appropriate error code.  Same for trying to open directories
652      for writing. */
653   if (!stat (pathname, &st))
654     {
655       if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
656 	{
657 	  remote_fileio_reply (-1, FILEIO_ENODEV);
658 	  return;
659 	}
660       if (S_ISDIR (st.st_mode)
661 	  && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
662 	{
663 	  remote_fileio_reply (-1, FILEIO_EISDIR);
664 	  return;
665 	}
666     }
667 
668   remote_fio_no_longjmp = 1;
669   fd = open (pathname, flags, mode);
670   if (fd < 0)
671     {
672       remote_fileio_return_errno (-1);
673       return;
674     }
675 
676   fd = remote_fileio_fd_to_targetfd (fd);
677   remote_fileio_return_success (fd);
678 }
679 
680 static void
681 remote_fileio_func_close (char *buf)
682 {
683   long num;
684   int fd;
685 
686   /* Parameter: file descriptor */
687   if (remote_fileio_extract_int (&buf, &num))
688     {
689       remote_fileio_ioerror ();
690       return;
691     }
692   fd = remote_fileio_map_fd ((int) num);
693   if (fd == FIO_FD_INVALID)
694     {
695       remote_fileio_badfd ();
696       return;
697     }
698 
699   remote_fio_no_longjmp = 1;
700   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
701     remote_fileio_return_errno (-1);
702   remote_fileio_close_target_fd ((int) num);
703   remote_fileio_return_success (0);
704 }
705 
706 static void
707 remote_fileio_func_read (char *buf)
708 {
709   long target_fd, num;
710   LONGEST lnum;
711   CORE_ADDR ptrval;
712   int fd, ret, retlength;
713   gdb_byte *buffer;
714   size_t length;
715   off_t old_offset, new_offset;
716 
717   /* 1. Parameter: file descriptor */
718   if (remote_fileio_extract_int (&buf, &target_fd))
719     {
720       remote_fileio_ioerror ();
721       return;
722     }
723   fd = remote_fileio_map_fd ((int) target_fd);
724   if (fd == FIO_FD_INVALID)
725     {
726       remote_fileio_badfd ();
727       return;
728     }
729   /* 2. Parameter: buffer pointer */
730   if (remote_fileio_extract_long (&buf, &lnum))
731     {
732       remote_fileio_ioerror ();
733       return;
734     }
735   ptrval = (CORE_ADDR) lnum;
736   /* 3. Parameter: buffer length */
737   if (remote_fileio_extract_int (&buf, &num))
738     {
739       remote_fileio_ioerror ();
740       return;
741     }
742   length = (size_t) num;
743 
744   switch (fd)
745     {
746       case FIO_FD_CONSOLE_OUT:
747 	remote_fileio_badfd ();
748 	return;
749       case FIO_FD_CONSOLE_IN:
750 	{
751 	  static char *remaining_buf = NULL;
752 	  static int remaining_length = 0;
753 
754 	  buffer = (gdb_byte *) xmalloc (16384);
755 	  if (remaining_buf)
756 	    {
757 	      remote_fio_no_longjmp = 1;
758 	      if (remaining_length > length)
759 		{
760 		  memcpy (buffer, remaining_buf, length);
761 		  memmove (remaining_buf, remaining_buf + length,
762 			   remaining_length - length);
763 		  remaining_length -= length;
764 		  ret = length;
765 		}
766 	      else
767 		{
768 		  memcpy (buffer, remaining_buf, remaining_length);
769 		  xfree (remaining_buf);
770 		  remaining_buf = NULL;
771 		  ret = remaining_length;
772 		}
773 	    }
774 	  else
775 	    {
776 	      /* Windows (at least XP and Server 2003) has difficulty
777 		 with large reads from consoles.  If a handle is
778 		 backed by a real console device, overly large reads
779 		 from the handle will fail and set errno == ENOMEM.
780 		 On a Windows Server 2003 system where I tested,
781 		 reading 26608 bytes from the console was OK, but
782 		 anything above 26609 bytes would fail.  The limit has
783 		 been observed to vary on different systems.  So, we
784 		 limit this read to something smaller than that - by a
785 		 safe margin, in case the limit depends on system
786 		 resources or version.  */
787 	      ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
788 	      remote_fio_no_longjmp = 1;
789 	      if (ret > 0 && (size_t)ret > length)
790 		{
791 		  remaining_buf = (char *) xmalloc (ret - length);
792 		  remaining_length = ret - length;
793 		  memcpy (remaining_buf, buffer + length, remaining_length);
794 		  ret = length;
795 		}
796 	    }
797 	}
798 	break;
799       default:
800 	buffer = (gdb_byte *) xmalloc (length);
801 	/* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
802 	   for read() to return -1 even if "some" bytes have been read.  It
803 	   has been corrected in SUSv2 but that doesn't help us much...
804 	   Therefore a complete solution must check how many bytes have been
805 	   read on EINTR to return a more reliable value to the target */
806 	old_offset = lseek (fd, 0, SEEK_CUR);
807 	remote_fio_no_longjmp = 1;
808 	ret = read (fd, buffer, length);
809 	if (ret < 0 && errno == EINTR)
810 	  {
811 	    new_offset = lseek (fd, 0, SEEK_CUR);
812 	    /* If some data has been read, return the number of bytes read.
813 	       The Ctrl-C flag is set in remote_fileio_reply() anyway */
814 	    if (old_offset != new_offset)
815 	      ret = new_offset - old_offset;
816 	  }
817 	break;
818     }
819 
820   if (ret > 0)
821     {
822       retlength = remote_fileio_write_bytes (ptrval, buffer, ret);
823       if (retlength != ret)
824 	ret = -1; /* errno has been set to EIO in remote_fileio_write_bytes() */
825     }
826 
827   if (ret < 0)
828     remote_fileio_return_errno (-1);
829   else
830     remote_fileio_return_success (ret);
831 
832   xfree (buffer);
833 }
834 
835 static void
836 remote_fileio_func_write (char *buf)
837 {
838   long target_fd, num;
839   LONGEST lnum;
840   CORE_ADDR ptrval;
841   int fd, ret, retlength;
842   gdb_byte *buffer;
843   size_t length;
844 
845   /* 1. Parameter: file descriptor */
846   if (remote_fileio_extract_int (&buf, &target_fd))
847     {
848       remote_fileio_ioerror ();
849       return;
850     }
851   fd = remote_fileio_map_fd ((int) target_fd);
852   if (fd == FIO_FD_INVALID)
853     {
854       remote_fileio_badfd ();
855       return;
856     }
857   /* 2. Parameter: buffer pointer */
858   if (remote_fileio_extract_long (&buf, &lnum))
859     {
860       remote_fileio_ioerror ();
861       return;
862     }
863   ptrval = (CORE_ADDR) lnum;
864   /* 3. Parameter: buffer length */
865   if (remote_fileio_extract_int (&buf, &num))
866     {
867       remote_fileio_ioerror ();
868       return;
869     }
870   length = (size_t) num;
871 
872   buffer = (gdb_byte *) xmalloc (length);
873   retlength = remote_read_bytes (ptrval, buffer, length);
874   if (retlength != length)
875     {
876       xfree (buffer);
877       remote_fileio_ioerror ();
878       return;
879     }
880 
881   remote_fio_no_longjmp = 1;
882   switch (fd)
883     {
884       case FIO_FD_CONSOLE_IN:
885 	remote_fileio_badfd ();
886 	xfree (buffer);
887 	return;
888       case FIO_FD_CONSOLE_OUT:
889 	ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
890 		       (char *) buffer, length);
891 	gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
892 	ret = length;
893 	break;
894       default:
895 	ret = write (fd, buffer, length);
896 	if (ret < 0 && errno == EACCES)
897 	  errno = EBADF; /* Cygwin returns EACCESS when writing to a R/O file.*/
898 	break;
899     }
900 
901   if (ret < 0)
902     remote_fileio_return_errno (-1);
903   else
904     remote_fileio_return_success (ret);
905 
906   xfree (buffer);
907 }
908 
909 static void
910 remote_fileio_func_lseek (char *buf)
911 {
912   long num;
913   LONGEST lnum;
914   int fd, flag;
915   off_t offset, ret;
916 
917   /* 1. Parameter: file descriptor */
918   if (remote_fileio_extract_int (&buf, &num))
919     {
920       remote_fileio_ioerror ();
921       return;
922     }
923   fd = remote_fileio_map_fd ((int) num);
924   if (fd == FIO_FD_INVALID)
925     {
926       remote_fileio_badfd ();
927       return;
928     }
929   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
930     {
931       remote_fileio_reply (-1, FILEIO_ESPIPE);
932       return;
933     }
934 
935   /* 2. Parameter: offset */
936   if (remote_fileio_extract_long (&buf, &lnum))
937     {
938       remote_fileio_ioerror ();
939       return;
940     }
941   offset = (off_t) lnum;
942   /* 3. Parameter: flag */
943   if (remote_fileio_extract_int (&buf, &num))
944     {
945       remote_fileio_ioerror ();
946       return;
947     }
948   if (remote_fileio_seek_flag_to_host (num, &flag))
949     {
950       remote_fileio_reply (-1, FILEIO_EINVAL);
951       return;
952     }
953 
954   remote_fio_no_longjmp = 1;
955   ret = lseek (fd, offset, flag);
956 
957   if (ret == (off_t) -1)
958     remote_fileio_return_errno (-1);
959   else
960     remote_fileio_return_success (ret);
961 }
962 
963 static void
964 remote_fileio_func_rename (char *buf)
965 {
966   CORE_ADDR old_ptr, new_ptr;
967   int old_len, new_len, retlength;
968   char *oldpath, *newpath;
969   int ret, of, nf;
970   struct stat ost, nst;
971 
972   /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
973   if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
974     {
975       remote_fileio_ioerror ();
976       return;
977     }
978 
979   /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
980   if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
981     {
982       remote_fileio_ioerror ();
983       return;
984     }
985 
986   /* Request oldpath using 'm' packet */
987   oldpath = alloca (old_len);
988   retlength = remote_read_bytes (old_ptr, (gdb_byte *) oldpath, old_len);
989   if (retlength != old_len)
990     {
991       remote_fileio_ioerror ();
992       return;
993     }
994 
995   /* Request newpath using 'm' packet */
996   newpath = alloca (new_len);
997   retlength = remote_read_bytes (new_ptr, (gdb_byte *) newpath, new_len);
998   if (retlength != new_len)
999     {
1000       remote_fileio_ioerror ();
1001       return;
1002     }
1003 
1004   /* Only operate on regular files and directories */
1005   of = stat (oldpath, &ost);
1006   nf = stat (newpath, &nst);
1007   if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
1008       || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
1009     {
1010       remote_fileio_reply (-1, FILEIO_EACCES);
1011       return;
1012     }
1013 
1014   remote_fio_no_longjmp = 1;
1015   ret = rename (oldpath, newpath);
1016 
1017   if (ret == -1)
1018     {
1019       /* Special case: newpath is a non-empty directory.  Some systems
1020          return ENOTEMPTY, some return EEXIST.  We coerce that to be
1021 	 always EEXIST. */
1022       if (errno == ENOTEMPTY)
1023         errno = EEXIST;
1024 #ifdef __CYGWIN__
1025       /* Workaround some Cygwin problems with correct errnos. */
1026       if (errno == EACCES)
1027         {
1028 	  if (!of && !nf && S_ISDIR (nst.st_mode))
1029 	    {
1030 	      if (S_ISREG (ost.st_mode))
1031 		errno = EISDIR;
1032 	      else
1033 		{
1034 		  char oldfullpath[PATH_MAX];
1035 		  char newfullpath[PATH_MAX];
1036 		  int len;
1037 
1038 		  cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
1039 				    PATH_MAX);
1040 		  cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
1041 				    PATH_MAX);
1042 		  len = strlen (oldfullpath);
1043 		  if (newfullpath[len] == '/'
1044 		      && !strncmp (oldfullpath, newfullpath, len))
1045 		    errno = EINVAL;
1046 		  else
1047 		    errno = EEXIST;
1048 		}
1049 	    }
1050 	}
1051 #endif
1052 
1053       remote_fileio_return_errno (-1);
1054     }
1055   else
1056     remote_fileio_return_success (ret);
1057 }
1058 
1059 static void
1060 remote_fileio_func_unlink (char *buf)
1061 {
1062   CORE_ADDR ptrval;
1063   int length, retlength;
1064   char *pathname;
1065   int ret;
1066   struct stat st;
1067 
1068   /* Parameter: Ptr to pathname / length incl. trailing zero */
1069   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1070     {
1071       remote_fileio_ioerror ();
1072       return;
1073     }
1074   /* Request pathname using 'm' packet */
1075   pathname = alloca (length);
1076   retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
1077   if (retlength != length)
1078     {
1079       remote_fileio_ioerror ();
1080       return;
1081     }
1082 
1083   /* Only operate on regular files (and directories, which allows to return
1084      the correct return code) */
1085   if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
1086     {
1087       remote_fileio_reply (-1, FILEIO_ENODEV);
1088       return;
1089     }
1090 
1091   remote_fio_no_longjmp = 1;
1092   ret = unlink (pathname);
1093 
1094   if (ret == -1)
1095     remote_fileio_return_errno (-1);
1096   else
1097     remote_fileio_return_success (ret);
1098 }
1099 
1100 static void
1101 remote_fileio_func_stat (char *buf)
1102 {
1103   CORE_ADDR statptr, nameptr;
1104   int ret, namelength, retlength;
1105   char *pathname;
1106   LONGEST lnum;
1107   struct stat st;
1108   struct fio_stat fst;
1109 
1110   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
1111   if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
1112     {
1113       remote_fileio_ioerror ();
1114       return;
1115     }
1116 
1117   /* 2. Parameter: Ptr to struct stat */
1118   if (remote_fileio_extract_long (&buf, &lnum))
1119     {
1120       remote_fileio_ioerror ();
1121       return;
1122     }
1123   statptr = (CORE_ADDR) lnum;
1124 
1125   /* Request pathname using 'm' packet */
1126   pathname = alloca (namelength);
1127   retlength = remote_read_bytes (nameptr, (gdb_byte *) pathname, namelength);
1128   if (retlength != namelength)
1129     {
1130       remote_fileio_ioerror ();
1131       return;
1132     }
1133 
1134   remote_fio_no_longjmp = 1;
1135   ret = stat (pathname, &st);
1136 
1137   if (ret == -1)
1138     {
1139       remote_fileio_return_errno (-1);
1140       return;
1141     }
1142   /* Only operate on regular files and directories */
1143   if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
1144     {
1145       remote_fileio_reply (-1, FILEIO_EACCES);
1146       return;
1147     }
1148   if (statptr)
1149     {
1150       remote_fileio_to_fio_stat (&st, &fst);
1151       remote_fileio_to_fio_uint (0, fst.fst_dev);
1152 
1153       retlength = remote_fileio_write_bytes (statptr,
1154 					     (gdb_byte *) &fst, sizeof fst);
1155       if (retlength != sizeof fst)
1156 	{
1157 	  remote_fileio_return_errno (-1);
1158 	  return;
1159 	}
1160     }
1161   remote_fileio_return_success (ret);
1162 }
1163 
1164 static void
1165 remote_fileio_func_fstat (char *buf)
1166 {
1167   CORE_ADDR ptrval;
1168   int fd, ret, retlength;
1169   long target_fd;
1170   LONGEST lnum;
1171   struct stat st;
1172   struct fio_stat fst;
1173   struct timeval tv;
1174 
1175   /* 1. Parameter: file descriptor */
1176   if (remote_fileio_extract_int (&buf, &target_fd))
1177     {
1178       remote_fileio_ioerror ();
1179       return;
1180     }
1181   fd = remote_fileio_map_fd ((int) target_fd);
1182   if (fd == FIO_FD_INVALID)
1183     {
1184       remote_fileio_badfd ();
1185       return;
1186     }
1187   /* 2. Parameter: Ptr to struct stat */
1188   if (remote_fileio_extract_long (&buf, &lnum))
1189     {
1190       remote_fileio_ioerror ();
1191       return;
1192     }
1193   ptrval = (CORE_ADDR) lnum;
1194 
1195   remote_fio_no_longjmp = 1;
1196   if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
1197     {
1198       remote_fileio_to_fio_uint (1, fst.fst_dev);
1199       st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
1200       st.st_nlink = 1;
1201 #ifdef HAVE_GETUID
1202       st.st_uid = getuid ();
1203 #else
1204       st.st_uid = 0;
1205 #endif
1206 #ifdef HAVE_GETGID
1207       st.st_gid = getgid ();
1208 #else
1209       st.st_gid = 0;
1210 #endif
1211       st.st_rdev = 0;
1212       st.st_size = 0;
1213 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1214       st.st_blksize = 512;
1215 #endif
1216 #if HAVE_STRUCT_STAT_ST_BLOCKS
1217       st.st_blocks = 0;
1218 #endif
1219       if (!gettimeofday (&tv, NULL))
1220 	st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
1221       else
1222         st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
1223       ret = 0;
1224     }
1225   else
1226     ret = fstat (fd, &st);
1227 
1228   if (ret == -1)
1229     {
1230       remote_fileio_return_errno (-1);
1231       return;
1232     }
1233   if (ptrval)
1234     {
1235       remote_fileio_to_fio_stat (&st, &fst);
1236 
1237       retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &fst, sizeof fst);
1238       if (retlength != sizeof fst)
1239 	{
1240 	  remote_fileio_return_errno (-1);
1241 	  return;
1242 	}
1243     }
1244   remote_fileio_return_success (ret);
1245 }
1246 
1247 static void
1248 remote_fileio_func_gettimeofday (char *buf)
1249 {
1250   LONGEST lnum;
1251   CORE_ADDR ptrval;
1252   int ret, retlength;
1253   struct timeval tv;
1254   struct fio_timeval ftv;
1255 
1256   /* 1. Parameter: struct timeval pointer */
1257   if (remote_fileio_extract_long (&buf, &lnum))
1258     {
1259       remote_fileio_ioerror ();
1260       return;
1261     }
1262   ptrval = (CORE_ADDR) lnum;
1263   /* 2. Parameter: some pointer value... */
1264   if (remote_fileio_extract_long (&buf, &lnum))
1265     {
1266       remote_fileio_ioerror ();
1267       return;
1268     }
1269   /* ...which has to be NULL */
1270   if (lnum)
1271     {
1272       remote_fileio_reply (-1, FILEIO_EINVAL);
1273       return;
1274     }
1275 
1276   remote_fio_no_longjmp = 1;
1277   ret = gettimeofday (&tv, NULL);
1278 
1279   if (ret == -1)
1280     {
1281       remote_fileio_return_errno (-1);
1282       return;
1283     }
1284 
1285   if (ptrval)
1286     {
1287       remote_fileio_to_fio_timeval (&tv, &ftv);
1288 
1289       retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1290       if (retlength != sizeof ftv)
1291 	{
1292 	  remote_fileio_return_errno (-1);
1293 	  return;
1294 	}
1295     }
1296   remote_fileio_return_success (ret);
1297 }
1298 
1299 static void
1300 remote_fileio_func_isatty (char *buf)
1301 {
1302   long target_fd;
1303   int fd;
1304 
1305   /* Parameter: file descriptor */
1306   if (remote_fileio_extract_int (&buf, &target_fd))
1307     {
1308       remote_fileio_ioerror ();
1309       return;
1310     }
1311   remote_fio_no_longjmp = 1;
1312   fd = remote_fileio_map_fd ((int) target_fd);
1313   remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
1314   				fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
1315 }
1316 
1317 static void
1318 remote_fileio_func_system (char *buf)
1319 {
1320   CORE_ADDR ptrval;
1321   int ret, length, retlength;
1322   char *cmdline = NULL;
1323 
1324   /* Parameter: Ptr to commandline / length incl. trailing zero */
1325   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1326     {
1327       remote_fileio_ioerror ();
1328       return;
1329     }
1330 
1331   if (length)
1332     {
1333       /* Request commandline using 'm' packet */
1334       cmdline = alloca (length);
1335       retlength = remote_read_bytes (ptrval, (gdb_byte *) cmdline, length);
1336       if (retlength != length)
1337 	{
1338 	  remote_fileio_ioerror ();
1339 	  return;
1340 	}
1341     }
1342 
1343   /* Check if system(3) has been explicitely allowed using the
1344      `set remote system-call-allowed 1' command.  If length is 0,
1345      indicating a NULL parameter to the system call, return zero to
1346      indicate a shell is not available.  Otherwise fail with EPERM.  */
1347   if (!remote_fio_system_call_allowed)
1348     {
1349       if (!length)
1350 	remote_fileio_return_success (0);
1351       else
1352 	remote_fileio_reply (-1, FILEIO_EPERM);
1353       return;
1354     }
1355 
1356   remote_fio_no_longjmp = 1;
1357   ret = system (cmdline);
1358 
1359   if (!length)
1360     remote_fileio_return_success (ret);
1361   else if (ret == -1)
1362     remote_fileio_return_errno (-1);
1363   else
1364     remote_fileio_return_success (WEXITSTATUS (ret));
1365 }
1366 
1367 static struct {
1368   char *name;
1369   void (*func)(char *);
1370 } remote_fio_func_map[] = {
1371   { "open", remote_fileio_func_open },
1372   { "close", remote_fileio_func_close },
1373   { "read", remote_fileio_func_read },
1374   { "write", remote_fileio_func_write },
1375   { "lseek", remote_fileio_func_lseek },
1376   { "rename", remote_fileio_func_rename },
1377   { "unlink", remote_fileio_func_unlink },
1378   { "stat", remote_fileio_func_stat },
1379   { "fstat", remote_fileio_func_fstat },
1380   { "gettimeofday", remote_fileio_func_gettimeofday },
1381   { "isatty", remote_fileio_func_isatty },
1382   { "system", remote_fileio_func_system },
1383   { NULL, NULL }
1384 };
1385 
1386 static int
1387 do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
1388 {
1389   char *buf = buf_arg;
1390   char *c;
1391   int idx;
1392 
1393   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
1394 
1395   c = strchr (++buf, ',');
1396   if (c)
1397     *c++ = '\0';
1398   else
1399     c = strchr (buf, '\0');
1400   for (idx = 0; remote_fio_func_map[idx].name; ++idx)
1401     if (!strcmp (remote_fio_func_map[idx].name, buf))
1402       break;
1403   if (!remote_fio_func_map[idx].name)	/* ERROR: No such function. */
1404     return RETURN_ERROR;
1405   remote_fio_func_map[idx].func (c);
1406   return 0;
1407 }
1408 
1409 /* Close any open descriptors, and reinitialize the file mapping.  */
1410 
1411 void
1412 remote_fileio_reset (void)
1413 {
1414   int ix;
1415 
1416   for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1417     {
1418       int fd = remote_fio_data.fd_map[ix];
1419 
1420       if (fd >= 0)
1421 	close (fd);
1422     }
1423   if (remote_fio_data.fd_map)
1424     {
1425       xfree (remote_fio_data.fd_map);
1426       remote_fio_data.fd_map = NULL;
1427       remote_fio_data.fd_map_size = 0;
1428     }
1429 }
1430 
1431 /* Handle a file I/O request. BUF points to the packet containing the
1432    request. CTRLC_PENDING_P should be nonzero if the target has not
1433    acknowledged the Ctrl-C sent asynchronously earlier.  */
1434 
1435 void
1436 remote_fileio_request (char *buf, int ctrlc_pending_p)
1437 {
1438   int ex;
1439 
1440   remote_fileio_sig_init ();
1441 
1442   if (ctrlc_pending_p)
1443     {
1444       /* If the target hasn't responded to the Ctrl-C sent
1445 	 asynchronously earlier, take this opportunity to send the
1446 	 Ctrl-C synchronously.  */
1447       remote_fio_ctrl_c_flag = 1;
1448       remote_fio_no_longjmp = 0;
1449       remote_fileio_reply (-1, FILEIO_EINTR);
1450     }
1451   else
1452     {
1453       remote_fio_ctrl_c_flag = 0;
1454       remote_fio_no_longjmp = 0;
1455 
1456       ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
1457 			     RETURN_MASK_ALL);
1458       switch (ex)
1459 	{
1460 	case RETURN_ERROR:
1461 	  remote_fileio_reply (-1, FILEIO_ENOSYS);
1462 	  break;
1463 	case RETURN_QUIT:
1464 	  remote_fileio_reply (-1, FILEIO_EINTR);
1465 	  break;
1466 	default:
1467 	  break;
1468 	}
1469     }
1470 
1471   remote_fileio_sig_exit ();
1472 }
1473 
1474 static void
1475 set_system_call_allowed (char *args, int from_tty)
1476 {
1477   if (args)
1478     {
1479       char *arg_end;
1480       int val = strtoul (args, &arg_end, 10);
1481 
1482       if (*args && *arg_end == '\0')
1483         {
1484 	  remote_fio_system_call_allowed = !!val;
1485 	  return;
1486 	}
1487     }
1488   error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1489 }
1490 
1491 static void
1492 show_system_call_allowed (char *args, int from_tty)
1493 {
1494   if (args)
1495     error (_("Garbage after \"show remote system-call-allowed\" command: `%s'"), args);
1496   printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1497 		     remote_fio_system_call_allowed ? "" : "not ");
1498 }
1499 
1500 void
1501 initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
1502 			  struct cmd_list_element *remote_show_cmdlist)
1503 {
1504   sigint_fileio_token =
1505     create_async_signal_handler (async_remote_fileio_interrupt, NULL);
1506 
1507   add_cmd ("system-call-allowed", no_class,
1508 	   set_system_call_allowed,
1509 	   _("Set if the host system(3) call is allowed for the target."),
1510 	   &remote_set_cmdlist);
1511   add_cmd ("system-call-allowed", no_class,
1512 	   show_system_call_allowed,
1513 	   _("Show if the host system(3) call is allowed for the target."),
1514 	   &remote_show_cmdlist);
1515 }
1516