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