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