Wake up interruptible_select in remote_fileio ctrl-c 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   /* Wake up interruptible_select.  */
352   quit_serial_event_set ();
353 }
354
355 static void
356 remote_fileio_reply (int retcode, int error)
357 {
358   char buf[32];
359
360   remote_fileio_sig_set (SIG_IGN);
361   strcpy (buf, "F");
362   if (retcode < 0)
363     {
364       strcat (buf, "-");
365       retcode = -retcode;
366     }
367   sprintf (buf + strlen (buf), "%x", retcode);
368   if (error || remote_fio_ctrl_c_flag)
369     {
370       if (error && remote_fio_ctrl_c_flag)
371         error = FILEIO_EINTR;
372       if (error < 0)
373         {
374           strcat (buf, "-");
375           error = -error;
376         }
377       sprintf (buf + strlen (buf), ",%x", error);
378       if (remote_fio_ctrl_c_flag)
379         strcat (buf, ",C");
380     }
381   remote_fio_ctrl_c_flag = 0;
382   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
383   putpkt (buf);
384 }
385
386 static void
387 remote_fileio_ioerror (void)
388 {
389   remote_fileio_reply (-1, FILEIO_EIO);
390 }
391
392 static void
393 remote_fileio_badfd (void)
394 {
395   remote_fileio_reply (-1, FILEIO_EBADF);
396 }
397
398 static void
399 remote_fileio_return_errno (int retcode)
400 {
401   remote_fileio_reply (retcode, retcode < 0
402                        ? host_to_fileio_error (errno) : 0);
403 }
404
405 static void
406 remote_fileio_return_success (int retcode)
407 {
408   remote_fileio_reply (retcode, 0);
409 }
410
411 static void
412 remote_fileio_func_open (char *buf)
413 {
414   CORE_ADDR ptrval;
415   int length;
416   long num;
417   int flags, fd;
418   mode_t mode;
419   char *pathname;
420   struct stat st;
421
422   /* 1. Parameter: Ptr to pathname / length incl. trailing zero.  */
423   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
424     {
425       remote_fileio_ioerror ();
426       return;
427     }
428   /* 2. Parameter: open flags */
429   if (remote_fileio_extract_int (&buf, &num))
430     {
431       remote_fileio_ioerror ();
432       return;
433     }
434   flags = remote_fileio_oflags_to_host (num);
435   /* 3. Parameter: open mode */
436   if (remote_fileio_extract_int (&buf, &num))
437     {
438       remote_fileio_ioerror ();
439       return;
440     }
441   mode = remote_fileio_mode_to_host (num, 1);
442
443   /* Request pathname.  */
444   pathname = (char *) alloca (length);
445   if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
446     {
447       remote_fileio_ioerror ();
448       return;
449     }
450
451   /* Check if pathname exists and is not a regular file or directory.  If so,
452      return an appropriate error code.  Same for trying to open directories
453      for writing.  */
454   if (!stat (pathname, &st))
455     {
456       if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
457         {
458           remote_fileio_reply (-1, FILEIO_ENODEV);
459           return;
460         }
461       if (S_ISDIR (st.st_mode)
462           && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
463         {
464           remote_fileio_reply (-1, FILEIO_EISDIR);
465           return;
466         }
467     }
468
469   fd = gdb_open_cloexec (pathname, flags, mode);
470   if (fd < 0)
471     {
472       remote_fileio_return_errno (-1);
473       return;
474     }
475
476   fd = remote_fileio_fd_to_targetfd (fd);
477   remote_fileio_return_success (fd);
478 }
479
480 static void
481 remote_fileio_func_close (char *buf)
482 {
483   long num;
484   int fd;
485
486   /* Parameter: file descriptor */
487   if (remote_fileio_extract_int (&buf, &num))
488     {
489       remote_fileio_ioerror ();
490       return;
491     }
492   fd = remote_fileio_map_fd ((int) num);
493   if (fd == FIO_FD_INVALID)
494     {
495       remote_fileio_badfd ();
496       return;
497     }
498
499   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
500     remote_fileio_return_errno (-1);
501   remote_fileio_close_target_fd ((int) num);
502   remote_fileio_return_success (0);
503 }
504
505 static void
506 remote_fileio_func_read (char *buf)
507 {
508   long target_fd, num;
509   LONGEST lnum;
510   CORE_ADDR ptrval;
511   int fd, ret;
512   gdb_byte *buffer;
513   size_t length;
514   off_t old_offset, new_offset;
515
516   /* 1. Parameter: file descriptor */
517   if (remote_fileio_extract_int (&buf, &target_fd))
518     {
519       remote_fileio_ioerror ();
520       return;
521     }
522   fd = remote_fileio_map_fd ((int) target_fd);
523   if (fd == FIO_FD_INVALID)
524     {
525       remote_fileio_badfd ();
526       return;
527     }
528   /* 2. Parameter: buffer pointer */
529   if (remote_fileio_extract_long (&buf, &lnum))
530     {
531       remote_fileio_ioerror ();
532       return;
533     }
534   ptrval = (CORE_ADDR) lnum;
535   /* 3. Parameter: buffer length */
536   if (remote_fileio_extract_int (&buf, &num))
537     {
538       remote_fileio_ioerror ();
539       return;
540     }
541   length = (size_t) num;
542
543   switch (fd)
544     {
545       case FIO_FD_CONSOLE_OUT:
546         remote_fileio_badfd ();
547         return;
548       case FIO_FD_CONSOLE_IN:
549         {
550           static char *remaining_buf = NULL;
551           static int remaining_length = 0;
552
553           buffer = (gdb_byte *) xmalloc (16384);
554           if (remaining_buf)
555             {
556               if (remaining_length > length)
557                 {
558                   memcpy (buffer, remaining_buf, length);
559                   memmove (remaining_buf, remaining_buf + length,
560                            remaining_length - length);
561                   remaining_length -= length;
562                   ret = length;
563                 }
564               else
565                 {
566                   memcpy (buffer, remaining_buf, remaining_length);
567                   xfree (remaining_buf);
568                   remaining_buf = NULL;
569                   ret = remaining_length;
570                 }
571             }
572           else
573             {
574               /* Windows (at least XP and Server 2003) has difficulty
575                  with large reads from consoles.  If a handle is
576                  backed by a real console device, overly large reads
577                  from the handle will fail and set errno == ENOMEM.
578                  On a Windows Server 2003 system where I tested,
579                  reading 26608 bytes from the console was OK, but
580                  anything above 26609 bytes would fail.  The limit has
581                  been observed to vary on different systems.  So, we
582                  limit this read to something smaller than that - by a
583                  safe margin, in case the limit depends on system
584                  resources or version.  */
585               ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
586               if (ret > 0 && (size_t)ret > length)
587                 {
588                   remaining_buf = (char *) xmalloc (ret - length);
589                   remaining_length = ret - length;
590                   memcpy (remaining_buf, buffer + length, remaining_length);
591                   ret = length;
592                 }
593             }
594         }
595         break;
596       default:
597         buffer = (gdb_byte *) xmalloc (length);
598         /* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
599            for read() to return -1 even if "some" bytes have been read.  It
600            has been corrected in SUSv2 but that doesn't help us much...
601            Therefore a complete solution must check how many bytes have been
602            read on EINTR to return a more reliable value to the target */
603         old_offset = lseek (fd, 0, SEEK_CUR);
604         ret = read (fd, buffer, length);
605         if (ret < 0 && errno == EINTR)
606           {
607             new_offset = lseek (fd, 0, SEEK_CUR);
608             /* If some data has been read, return the number of bytes read.
609                The Ctrl-C flag is set in remote_fileio_reply() anyway.  */
610             if (old_offset != new_offset)
611               ret = new_offset - old_offset;
612           }
613         break;
614     }
615
616   if (ret > 0)
617     {
618       errno = target_write_memory (ptrval, buffer, ret);
619       if (errno != 0)
620         ret = -1;
621     }
622
623   if (ret < 0)
624     remote_fileio_return_errno (-1);
625   else
626     remote_fileio_return_success (ret);
627
628   xfree (buffer);
629 }
630
631 static void
632 remote_fileio_func_write (char *buf)
633 {
634   long target_fd, num;
635   LONGEST lnum;
636   CORE_ADDR ptrval;
637   int fd, ret;
638   gdb_byte *buffer;
639   size_t length;
640
641   /* 1. Parameter: file descriptor */
642   if (remote_fileio_extract_int (&buf, &target_fd))
643     {
644       remote_fileio_ioerror ();
645       return;
646     }
647   fd = remote_fileio_map_fd ((int) target_fd);
648   if (fd == FIO_FD_INVALID)
649     {
650       remote_fileio_badfd ();
651       return;
652     }
653   /* 2. Parameter: buffer pointer */
654   if (remote_fileio_extract_long (&buf, &lnum))
655     {
656       remote_fileio_ioerror ();
657       return;
658     }
659   ptrval = (CORE_ADDR) lnum;
660   /* 3. Parameter: buffer length */
661   if (remote_fileio_extract_int (&buf, &num))
662     {
663       remote_fileio_ioerror ();
664       return;
665     }
666   length = (size_t) num;
667     
668   buffer = (gdb_byte *) xmalloc (length);
669   if (target_read_memory (ptrval, buffer, length) != 0)
670     {
671       xfree (buffer);
672       remote_fileio_ioerror ();
673       return;
674     }
675
676   switch (fd)
677     {
678       case FIO_FD_CONSOLE_IN:
679         remote_fileio_badfd ();
680         xfree (buffer);
681         return;
682       case FIO_FD_CONSOLE_OUT:
683         ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
684                        (char *) buffer, length);
685         gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
686         ret = length;
687         break;
688       default:
689         ret = write (fd, buffer, length);
690         if (ret < 0 && errno == EACCES)
691           errno = EBADF; /* Cygwin returns EACCESS when writing to a
692                             R/O file.  */
693         break;
694     }
695
696   if (ret < 0)
697     remote_fileio_return_errno (-1);
698   else
699     remote_fileio_return_success (ret);
700
701   xfree (buffer);
702 }
703
704 static void
705 remote_fileio_func_lseek (char *buf)
706 {
707   long num;
708   LONGEST lnum;
709   int fd, flag;
710   off_t offset, ret;
711
712   /* 1. Parameter: file descriptor */
713   if (remote_fileio_extract_int (&buf, &num))
714     {
715       remote_fileio_ioerror ();
716       return;
717     }
718   fd = remote_fileio_map_fd ((int) num);
719   if (fd == FIO_FD_INVALID)
720     {
721       remote_fileio_badfd ();
722       return;
723     }
724   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
725     {
726       remote_fileio_reply (-1, FILEIO_ESPIPE);
727       return;
728     }
729
730   /* 2. Parameter: offset */
731   if (remote_fileio_extract_long (&buf, &lnum))
732     {
733       remote_fileio_ioerror ();
734       return;
735     }
736   offset = (off_t) lnum;
737   /* 3. Parameter: flag */
738   if (remote_fileio_extract_int (&buf, &num))
739     {
740       remote_fileio_ioerror ();
741       return;
742     }
743   if (remote_fileio_seek_flag_to_host (num, &flag))
744     {
745       remote_fileio_reply (-1, FILEIO_EINVAL);
746       return;
747     }
748   
749   ret = lseek (fd, offset, flag);
750
751   if (ret == (off_t) -1)
752     remote_fileio_return_errno (-1);
753   else
754     remote_fileio_return_success (ret);
755 }
756
757 static void
758 remote_fileio_func_rename (char *buf)
759 {
760   CORE_ADDR old_ptr, new_ptr;
761   int old_len, new_len;
762   char *oldpath, *newpath;
763   int ret, of, nf;
764   struct stat ost, nst;
765
766   /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
767   if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
768     {
769       remote_fileio_ioerror ();
770       return;
771     }
772   
773   /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
774   if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
775     {
776       remote_fileio_ioerror ();
777       return;
778     }
779   
780   /* Request oldpath using 'm' packet */
781   oldpath = (char *) alloca (old_len);
782   if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
783     {
784       remote_fileio_ioerror ();
785       return;
786     }
787   
788   /* Request newpath using 'm' packet */
789   newpath = (char *) alloca (new_len);
790   if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
791     {
792       remote_fileio_ioerror ();
793       return;
794     }
795   
796   /* Only operate on regular files and directories.  */
797   of = stat (oldpath, &ost);
798   nf = stat (newpath, &nst);
799   if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
800       || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
801     {
802       remote_fileio_reply (-1, FILEIO_EACCES);
803       return;
804     }
805
806   ret = rename (oldpath, newpath);
807
808   if (ret == -1)
809     {
810       /* Special case: newpath is a non-empty directory.  Some systems
811          return ENOTEMPTY, some return EEXIST.  We coerce that to be
812          always EEXIST.  */
813       if (errno == ENOTEMPTY)
814         errno = EEXIST;
815 #ifdef __CYGWIN__
816       /* Workaround some Cygwin problems with correct errnos.  */
817       if (errno == EACCES)
818         {
819           if (!of && !nf && S_ISDIR (nst.st_mode))
820             {
821               if (S_ISREG (ost.st_mode))
822                 errno = EISDIR;
823               else
824                 {
825                   char oldfullpath[PATH_MAX];
826                   char newfullpath[PATH_MAX];
827                   int len;
828
829                   cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
830                                     PATH_MAX);
831                   cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
832                                     PATH_MAX);
833                   len = strlen (oldfullpath);
834                   if (IS_DIR_SEPARATOR (newfullpath[len])
835                       && !filename_ncmp (oldfullpath, newfullpath, len))
836                     errno = EINVAL;
837                   else
838                     errno = EEXIST;
839                 }
840             }
841         }
842 #endif
843
844       remote_fileio_return_errno (-1);
845     }
846   else
847     remote_fileio_return_success (ret);
848 }
849
850 static void
851 remote_fileio_func_unlink (char *buf)
852 {
853   CORE_ADDR ptrval;
854   int length;
855   char *pathname;
856   int ret;
857   struct stat st;
858
859   /* Parameter: Ptr to pathname / length incl. trailing zero */
860   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
861     {
862       remote_fileio_ioerror ();
863       return;
864     }
865   /* Request pathname using 'm' packet */
866   pathname = (char *) alloca (length);
867   if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
868     {
869       remote_fileio_ioerror ();
870       return;
871     }
872
873   /* Only operate on regular files (and directories, which allows to return
874      the correct return code).  */
875   if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
876     {
877       remote_fileio_reply (-1, FILEIO_ENODEV);
878       return;
879     }
880
881   ret = unlink (pathname);
882
883   if (ret == -1)
884     remote_fileio_return_errno (-1);
885   else
886     remote_fileio_return_success (ret);
887 }
888
889 static void
890 remote_fileio_func_stat (char *buf)
891 {
892   CORE_ADDR statptr, nameptr;
893   int ret, namelength;
894   char *pathname;
895   LONGEST lnum;
896   struct stat st;
897   struct fio_stat fst;
898
899   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
900   if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
901     {
902       remote_fileio_ioerror ();
903       return;
904     }
905
906   /* 2. Parameter: Ptr to struct stat */
907   if (remote_fileio_extract_long (&buf, &lnum))
908     {
909       remote_fileio_ioerror ();
910       return;
911     }
912   statptr = (CORE_ADDR) lnum;
913   
914   /* Request pathname using 'm' packet */
915   pathname = (char *) alloca (namelength);
916   if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
917     {
918       remote_fileio_ioerror ();
919       return;
920     }
921
922   ret = stat (pathname, &st);
923
924   if (ret == -1)
925     {
926       remote_fileio_return_errno (-1);
927       return;
928     }
929   /* Only operate on regular files and directories.  */
930   if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
931     {
932       remote_fileio_reply (-1, FILEIO_EACCES);
933       return;
934     }
935   if (statptr)
936     {
937       host_to_fileio_stat (&st, &fst);
938       host_to_fileio_uint (0, fst.fst_dev);
939
940       errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
941       if (errno != 0)
942         {
943           remote_fileio_return_errno (-1);
944           return;
945         }
946     }
947   remote_fileio_return_success (ret);
948 }
949
950 static void
951 remote_fileio_func_fstat (char *buf)
952 {
953   CORE_ADDR ptrval;
954   int fd, ret;
955   long target_fd;
956   LONGEST lnum;
957   struct stat st;
958   struct fio_stat fst;
959   struct timeval tv;
960
961   /* 1. Parameter: file descriptor */
962   if (remote_fileio_extract_int (&buf, &target_fd))
963     {
964       remote_fileio_ioerror ();
965       return;
966     }
967   fd = remote_fileio_map_fd ((int) target_fd);
968   if (fd == FIO_FD_INVALID)
969     {
970       remote_fileio_badfd ();
971       return;
972     }
973   /* 2. Parameter: Ptr to struct stat */
974   if (remote_fileio_extract_long (&buf, &lnum))
975     {
976       remote_fileio_ioerror ();
977       return;
978     }
979   ptrval = (CORE_ADDR) lnum;
980
981   if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
982     {
983       host_to_fileio_uint (1, fst.fst_dev);
984       memset (&st, 0, sizeof (st));
985       st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
986       st.st_nlink = 1;
987 #ifdef HAVE_GETUID
988       st.st_uid = getuid ();
989 #endif
990 #ifdef HAVE_GETGID
991       st.st_gid = getgid ();
992 #endif
993 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
994       st.st_blksize = 512;
995 #endif
996 #if HAVE_STRUCT_STAT_ST_BLOCKS
997       st.st_blocks = 0;
998 #endif
999       if (!gettimeofday (&tv, NULL))
1000         st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
1001       else
1002         st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
1003       ret = 0;
1004     }
1005   else
1006     ret = fstat (fd, &st);
1007
1008   if (ret == -1)
1009     {
1010       remote_fileio_return_errno (-1);
1011       return;
1012     }
1013   if (ptrval)
1014     {
1015       host_to_fileio_stat (&st, &fst);
1016
1017       errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
1018       if (errno != 0)
1019         {
1020           remote_fileio_return_errno (-1);
1021           return;
1022         }
1023     }
1024   remote_fileio_return_success (ret);
1025 }
1026
1027 static void
1028 remote_fileio_func_gettimeofday (char *buf)
1029 {
1030   LONGEST lnum;
1031   CORE_ADDR ptrval;
1032   int ret;
1033   struct timeval tv;
1034   struct fio_timeval ftv;
1035
1036   /* 1. Parameter: struct timeval pointer */
1037   if (remote_fileio_extract_long (&buf, &lnum))
1038     {
1039       remote_fileio_ioerror ();
1040       return;
1041     }
1042   ptrval = (CORE_ADDR) lnum;
1043   /* 2. Parameter: some pointer value...  */
1044   if (remote_fileio_extract_long (&buf, &lnum))
1045     {
1046       remote_fileio_ioerror ();
1047       return;
1048     }
1049   /* ...which has to be NULL.  */
1050   if (lnum)
1051     {
1052       remote_fileio_reply (-1, FILEIO_EINVAL);
1053       return;
1054     }
1055
1056   ret = gettimeofday (&tv, NULL);
1057
1058   if (ret == -1)
1059     {
1060       remote_fileio_return_errno (-1);
1061       return;
1062     }
1063
1064   if (ptrval)
1065     {
1066       remote_fileio_to_fio_timeval (&tv, &ftv);
1067
1068       errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1069       if (errno != 0)
1070         {
1071           remote_fileio_return_errno (-1);
1072           return;
1073         }
1074     }
1075   remote_fileio_return_success (ret);
1076 }
1077
1078 static void
1079 remote_fileio_func_isatty (char *buf)
1080 {
1081   long target_fd;
1082   int fd;
1083
1084   /* Parameter: file descriptor */
1085   if (remote_fileio_extract_int (&buf, &target_fd))
1086     {
1087       remote_fileio_ioerror ();
1088       return;
1089     }
1090   fd = remote_fileio_map_fd ((int) target_fd);
1091   remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
1092                                 fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
1093 }
1094
1095 static void
1096 remote_fileio_func_system (char *buf)
1097 {
1098   CORE_ADDR ptrval;
1099   int ret, length;
1100   char *cmdline = NULL;
1101
1102   /* Parameter: Ptr to commandline / length incl. trailing zero */
1103   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1104     {
1105       remote_fileio_ioerror ();
1106       return;
1107     }
1108
1109   if (length)
1110     {
1111       /* Request commandline using 'm' packet */
1112       cmdline = (char *) alloca (length);
1113       if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
1114         {
1115           remote_fileio_ioerror ();
1116           return;
1117         }
1118     }
1119   
1120   /* Check if system(3) has been explicitely allowed using the
1121      `set remote system-call-allowed 1' command.  If length is 0,
1122      indicating a NULL parameter to the system call, return zero to
1123      indicate a shell is not available.  Otherwise fail with EPERM.  */
1124   if (!remote_fio_system_call_allowed)
1125     {
1126       if (!length)
1127         remote_fileio_return_success (0);
1128       else
1129         remote_fileio_reply (-1, FILEIO_EPERM);
1130       return;
1131     }
1132
1133   ret = system (cmdline);
1134
1135   if (!length)
1136     remote_fileio_return_success (ret);
1137   else if (ret == -1)
1138     remote_fileio_return_errno (-1);
1139   else
1140     remote_fileio_return_success (WEXITSTATUS (ret));
1141 }
1142
1143 static struct {
1144   char *name;
1145   void (*func)(char *);
1146 } remote_fio_func_map[] = {
1147   { "open", remote_fileio_func_open },
1148   { "close", remote_fileio_func_close },
1149   { "read", remote_fileio_func_read },
1150   { "write", remote_fileio_func_write },
1151   { "lseek", remote_fileio_func_lseek },
1152   { "rename", remote_fileio_func_rename },
1153   { "unlink", remote_fileio_func_unlink },
1154   { "stat", remote_fileio_func_stat },
1155   { "fstat", remote_fileio_func_fstat },
1156   { "gettimeofday", remote_fileio_func_gettimeofday },
1157   { "isatty", remote_fileio_func_isatty },
1158   { "system", remote_fileio_func_system },
1159   { NULL, NULL }
1160 };
1161
1162 static int
1163 do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
1164 {
1165   char *buf = (char *) buf_arg;
1166   char *c;
1167   int idx;
1168
1169   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
1170
1171   c = strchr (++buf, ',');
1172   if (c)
1173     *c++ = '\0';
1174   else
1175     c = strchr (buf, '\0');
1176   for (idx = 0; remote_fio_func_map[idx].name; ++idx)
1177     if (!strcmp (remote_fio_func_map[idx].name, buf))
1178       break;
1179   if (!remote_fio_func_map[idx].name)   /* ERROR: No such function.  */
1180     return RETURN_ERROR;
1181   remote_fio_func_map[idx].func (c);
1182   return 0;
1183 }
1184
1185 /* Close any open descriptors, and reinitialize the file mapping.  */
1186
1187 void
1188 remote_fileio_reset (void)
1189 {
1190   int ix;
1191
1192   for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1193     {
1194       int fd = remote_fio_data.fd_map[ix];
1195
1196       if (fd >= 0)
1197         close (fd);
1198     }
1199   if (remote_fio_data.fd_map)
1200     {
1201       xfree (remote_fio_data.fd_map);
1202       remote_fio_data.fd_map = NULL;
1203       remote_fio_data.fd_map_size = 0;
1204     }
1205 }
1206
1207 /* Handle a file I/O request.  BUF points to the packet containing the
1208    request.  CTRLC_PENDING_P should be nonzero if the target has not
1209    acknowledged the Ctrl-C sent asynchronously earlier.  */
1210
1211 void
1212 remote_fileio_request (char *buf, int ctrlc_pending_p)
1213 {
1214   int ex;
1215
1216   remote_fileio_sig_init ();
1217
1218   if (ctrlc_pending_p)
1219     {
1220       /* If the target hasn't responded to the Ctrl-C sent
1221          asynchronously earlier, take this opportunity to send the
1222          Ctrl-C synchronously.  */
1223       remote_fio_ctrl_c_flag = 1;
1224       remote_fileio_reply (-1, FILEIO_EINTR);
1225     }
1226   else
1227     {
1228       remote_fio_ctrl_c_flag = 0;
1229
1230       ex = catch_exceptions (current_uiout,
1231                              do_remote_fileio_request, (void *)buf,
1232                              RETURN_MASK_ALL);
1233       switch (ex)
1234         {
1235         case RETURN_ERROR:
1236           remote_fileio_reply (-1, FILEIO_ENOSYS);
1237           break;
1238         case RETURN_QUIT:
1239           remote_fileio_reply (-1, FILEIO_EINTR);
1240           break;
1241         default:
1242           break;
1243         }
1244     }
1245
1246   remote_fileio_sig_exit ();
1247 }
1248 \f
1249
1250 /* Unpack an fio_uint_t.  */
1251
1252 static unsigned int
1253 remote_fileio_to_host_uint (fio_uint_t fnum)
1254 {
1255   return extract_unsigned_integer ((gdb_byte *) fnum, 4,
1256                                    BFD_ENDIAN_BIG);
1257 }
1258
1259 /* Unpack an fio_ulong_t.  */
1260
1261 static ULONGEST
1262 remote_fileio_to_host_ulong (fio_ulong_t fnum)
1263 {
1264   return extract_unsigned_integer ((gdb_byte *) fnum, 8,
1265                                    BFD_ENDIAN_BIG);
1266 }
1267
1268 /* Unpack an fio_mode_t.  */
1269
1270 static mode_t
1271 remote_fileio_to_host_mode (fio_mode_t fnum)
1272 {
1273   return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
1274                                      0);
1275 }
1276
1277 /* Unpack an fio_time_t.  */
1278
1279 static time_t
1280 remote_fileio_to_host_time (fio_time_t fnum)
1281 {
1282   return remote_fileio_to_host_uint (fnum);
1283 }
1284
1285
1286 /* See remote-fileio.h.  */
1287
1288 void
1289 remote_fileio_to_host_stat (struct fio_stat *fst, struct stat *st)
1290 {
1291   memset (st, 0, sizeof (struct stat));
1292
1293   st->st_dev = remote_fileio_to_host_uint (fst->fst_dev);
1294   st->st_ino = remote_fileio_to_host_uint (fst->fst_ino);
1295   st->st_mode = remote_fileio_to_host_mode (fst->fst_mode);
1296   st->st_nlink = remote_fileio_to_host_uint (fst->fst_nlink);
1297   st->st_uid = remote_fileio_to_host_uint (fst->fst_uid);
1298   st->st_gid = remote_fileio_to_host_uint (fst->fst_gid);
1299   st->st_rdev = remote_fileio_to_host_uint (fst->fst_rdev);
1300   st->st_size = remote_fileio_to_host_ulong (fst->fst_size);
1301 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1302   st->st_blksize = remote_fileio_to_host_ulong (fst->fst_blksize);
1303 #endif
1304 #if HAVE_STRUCT_STAT_ST_BLOCKS
1305   st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
1306 #endif
1307   st->st_atime = remote_fileio_to_host_time (fst->fst_atime);
1308   st->st_mtime = remote_fileio_to_host_time (fst->fst_mtime);
1309   st->st_ctime = remote_fileio_to_host_time (fst->fst_ctime);
1310 }
1311 \f
1312
1313 static void
1314 set_system_call_allowed (char *args, int from_tty)
1315 {
1316   if (args)
1317     {
1318       char *arg_end;
1319       int val = strtoul (args, &arg_end, 10);
1320
1321       if (*args && *arg_end == '\0')
1322         {
1323           remote_fio_system_call_allowed = !!val;
1324           return;
1325         }
1326     }
1327   error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1328 }
1329
1330 static void
1331 show_system_call_allowed (char *args, int from_tty)
1332 {
1333   if (args)
1334     error (_("Garbage after \"show remote "
1335              "system-call-allowed\" command: `%s'"), args);
1336   printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1337                      remote_fio_system_call_allowed ? "" : "not ");
1338 }
1339
1340 void
1341 initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
1342                           struct cmd_list_element *remote_show_cmdlist)
1343 {
1344   add_cmd ("system-call-allowed", no_class,
1345            set_system_call_allowed,
1346            _("Set if the host system(3) call is allowed for the target."),
1347            &remote_set_cmdlist);
1348   add_cmd ("system-call-allowed", no_class,
1349            show_system_call_allowed,
1350            _("Show if the host system(3) call is allowed for the target."),
1351            &remote_show_cmdlist);
1352 }