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