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