GDB: S12Z: new function s12z_extract_return_value
[external/binutils.git] / gdb / remote-fileio.c
1 /* Remote File-I/O communications
2
3    Copyright (C) 2003-2018 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 (remote_target *remote, 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 (remote, buf);
343 }
344
345 static void
346 remote_fileio_ioerror (remote_target *remote)
347 {
348   remote_fileio_reply (remote, -1, FILEIO_EIO);
349 }
350
351 static void
352 remote_fileio_badfd (remote_target *remote)
353 {
354   remote_fileio_reply (remote, -1, FILEIO_EBADF);
355 }
356
357 static void
358 remote_fileio_return_errno (remote_target *remote, int retcode)
359 {
360   remote_fileio_reply (remote, retcode, retcode < 0
361                        ? host_to_fileio_error (errno) : 0);
362 }
363
364 static void
365 remote_fileio_return_success (remote_target *remote, int retcode)
366 {
367   remote_fileio_reply (remote, retcode, 0);
368 }
369
370 static void
371 remote_fileio_func_open (remote_target *remote, 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 (remote);
385       return;
386     }
387   /* 2. Parameter: open flags */
388   if (remote_fileio_extract_int (&buf, &num))
389     {
390       remote_fileio_ioerror (remote);
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 (remote);
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 (remote);
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 (remote, -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 (remote, -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 (remote, -1);
432       return;
433     }
434
435   fd = remote_fileio_fd_to_targetfd (fd);
436   remote_fileio_return_success (remote, fd);
437 }
438
439 static void
440 remote_fileio_func_close (remote_target *remote, 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 (remote);
449       return;
450     }
451   fd = remote_fileio_map_fd ((int) num);
452   if (fd == FIO_FD_INVALID)
453     {
454       remote_fileio_badfd (remote);
455       return;
456     }
457
458   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
459     remote_fileio_return_errno (remote, -1);
460   remote_fileio_close_target_fd ((int) num);
461   remote_fileio_return_success (remote, 0);
462 }
463
464 static void
465 remote_fileio_func_read (remote_target *remote, 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 (remote);
479       return;
480     }
481   fd = remote_fileio_map_fd ((int) target_fd);
482   if (fd == FIO_FD_INVALID)
483     {
484       remote_fileio_badfd (remote);
485       return;
486     }
487   /* 2. Parameter: buffer pointer */
488   if (remote_fileio_extract_long (&buf, &lnum))
489     {
490       remote_fileio_ioerror (remote);
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 (remote);
498       return;
499     }
500   length = (size_t) num;
501
502   switch (fd)
503     {
504       case FIO_FD_CONSOLE_OUT:
505         remote_fileio_badfd (remote);
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 (remote, -1);
584   else
585     remote_fileio_return_success (remote, ret);
586
587   xfree (buffer);
588 }
589
590 static void
591 remote_fileio_func_write (remote_target *remote, 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 (remote);
604       return;
605     }
606   fd = remote_fileio_map_fd ((int) target_fd);
607   if (fd == FIO_FD_INVALID)
608     {
609       remote_fileio_badfd (remote);
610       return;
611     }
612   /* 2. Parameter: buffer pointer */
613   if (remote_fileio_extract_long (&buf, &lnum))
614     {
615       remote_fileio_ioerror (remote);
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 (remote);
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 (remote);
632       return;
633     }
634
635   switch (fd)
636     {
637       case FIO_FD_CONSOLE_IN:
638         remote_fileio_badfd (remote);
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 (remote, -1);
657   else
658     remote_fileio_return_success (remote, ret);
659
660   xfree (buffer);
661 }
662
663 static void
664 remote_fileio_func_lseek (remote_target *remote, 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 (remote);
675       return;
676     }
677   fd = remote_fileio_map_fd ((int) num);
678   if (fd == FIO_FD_INVALID)
679     {
680       remote_fileio_badfd (remote);
681       return;
682     }
683   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
684     {
685       remote_fileio_reply (remote, -1, FILEIO_ESPIPE);
686       return;
687     }
688
689   /* 2. Parameter: offset */
690   if (remote_fileio_extract_long (&buf, &lnum))
691     {
692       remote_fileio_ioerror (remote);
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 (remote);
700       return;
701     }
702   if (remote_fileio_seek_flag_to_host (num, &flag))
703     {
704       remote_fileio_reply (remote, -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 (remote, -1);
712   else
713     remote_fileio_return_success (remote, ret);
714 }
715
716 static void
717 remote_fileio_func_rename (remote_target *remote, 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 (remote);
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 (remote);
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 (remote);
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 (remote);
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 (remote, -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 (remote, -1);
804     }
805   else
806     remote_fileio_return_success (remote, ret);
807 }
808
809 static void
810 remote_fileio_func_unlink (remote_target *remote, 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 (remote);
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 (remote);
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 (remote, -1, FILEIO_ENODEV);
837       return;
838     }
839
840   ret = unlink (pathname);
841
842   if (ret == -1)
843     remote_fileio_return_errno (remote, -1);
844   else
845     remote_fileio_return_success (remote, ret);
846 }
847
848 static void
849 remote_fileio_func_stat (remote_target *remote, 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 (remote);
862       return;
863     }
864
865   /* 2. Parameter: Ptr to struct stat */
866   if (remote_fileio_extract_long (&buf, &lnum))
867     {
868       remote_fileio_ioerror (remote);
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 (remote);
878       return;
879     }
880
881   ret = stat (pathname, &st);
882
883   if (ret == -1)
884     {
885       remote_fileio_return_errno (remote, -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 (remote, -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 (remote, -1);
903           return;
904         }
905     }
906   remote_fileio_return_success (remote, ret);
907 }
908
909 static void
910 remote_fileio_func_fstat (remote_target *remote, 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 (remote);
924       return;
925     }
926   fd = remote_fileio_map_fd ((int) target_fd);
927   if (fd == FIO_FD_INVALID)
928     {
929       remote_fileio_badfd (remote);
930       return;
931     }
932   /* 2. Parameter: Ptr to struct stat */
933   if (remote_fileio_extract_long (&buf, &lnum))
934     {
935       remote_fileio_ioerror (remote);
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 (remote, -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 (remote, -1);
980           return;
981         }
982     }
983   remote_fileio_return_success (remote, ret);
984 }
985
986 static void
987 remote_fileio_func_gettimeofday (remote_target *remote, 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 (remote);
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 (remote);
1006       return;
1007     }
1008   /* ...which has to be NULL.  */
1009   if (lnum)
1010     {
1011       remote_fileio_reply (remote, -1, FILEIO_EINVAL);
1012       return;
1013     }
1014
1015   ret = gettimeofday (&tv, NULL);
1016
1017   if (ret == -1)
1018     {
1019       remote_fileio_return_errno (remote, -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 (remote, -1);
1031           return;
1032         }
1033     }
1034   remote_fileio_return_success (remote, ret);
1035 }
1036
1037 static void
1038 remote_fileio_func_isatty (remote_target *remote, 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 (remote);
1047       return;
1048     }
1049   fd = remote_fileio_map_fd ((int) target_fd);
1050   int ret = fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT ? 1 : 0;
1051   remote_fileio_return_success (remote, ret);
1052 }
1053
1054 static void
1055 remote_fileio_func_system (remote_target *remote, 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 (remote);
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 (remote);
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 (remote, 0);
1087       else
1088         remote_fileio_reply (remote, -1, FILEIO_EPERM);
1089       return;
1090     }
1091
1092   ret = system (cmdline);
1093
1094   if (!length)
1095     remote_fileio_return_success (remote, ret);
1096   else if (ret == -1)
1097     remote_fileio_return_errno (remote, -1);
1098   else
1099     remote_fileio_return_success (remote, WEXITSTATUS (ret));
1100 }
1101
1102 static struct {
1103   const char *name;
1104   void (*func)(remote_target *remote, 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 void
1122 do_remote_fileio_request (remote_target *remote, char *buf)
1123 {
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)
1138     remote_fileio_reply (remote, -1, FILEIO_ENOSYS);
1139   else
1140     remote_fio_func_map[idx].func (remote, c);
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 (remote_target *remote, char *buf, int ctrlc_pending_p)
1171 {
1172   /* Save the previous quit handler, so we can restore it.  No need
1173      for a cleanup since we catch all exceptions below.  Note that the
1174      quit handler is also restored by remote_fileio_reply just before
1175      pushing a packet.  */
1176   remote_fileio_o_quit_handler = quit_handler;
1177
1178   if (ctrlc_pending_p)
1179     {
1180       /* If the target hasn't responded to the Ctrl-C sent
1181          asynchronously earlier, take this opportunity to send the
1182          Ctrl-C synchronously.  */
1183       set_quit_flag ();
1184       remote_fileio_reply (remote, -1, FILEIO_EINTR);
1185     }
1186   else
1187     {
1188       TRY
1189         {
1190           do_remote_fileio_request (remote, buf);
1191         }
1192       CATCH (ex, RETURN_MASK_ALL)
1193         {
1194           if (ex.reason == RETURN_QUIT)
1195             remote_fileio_reply (remote, -1, FILEIO_EINTR);
1196           else
1197             remote_fileio_reply (remote, -1, FILEIO_EIO);
1198         }
1199       END_CATCH
1200     }
1201
1202   quit_handler = remote_fileio_o_quit_handler;
1203 }
1204 \f
1205
1206 /* Unpack an fio_uint_t.  */
1207
1208 static unsigned int
1209 remote_fileio_to_host_uint (fio_uint_t fnum)
1210 {
1211   return extract_unsigned_integer ((gdb_byte *) fnum, 4,
1212                                    BFD_ENDIAN_BIG);
1213 }
1214
1215 /* Unpack an fio_ulong_t.  */
1216
1217 static ULONGEST
1218 remote_fileio_to_host_ulong (fio_ulong_t fnum)
1219 {
1220   return extract_unsigned_integer ((gdb_byte *) fnum, 8,
1221                                    BFD_ENDIAN_BIG);
1222 }
1223
1224 /* Unpack an fio_mode_t.  */
1225
1226 static mode_t
1227 remote_fileio_to_host_mode (fio_mode_t fnum)
1228 {
1229   return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
1230                                      0);
1231 }
1232
1233 /* Unpack an fio_time_t.  */
1234
1235 static time_t
1236 remote_fileio_to_host_time (fio_time_t fnum)
1237 {
1238   return remote_fileio_to_host_uint (fnum);
1239 }
1240
1241
1242 /* See remote-fileio.h.  */
1243
1244 void
1245 remote_fileio_to_host_stat (struct fio_stat *fst, struct stat *st)
1246 {
1247   memset (st, 0, sizeof (struct stat));
1248
1249   st->st_dev = remote_fileio_to_host_uint (fst->fst_dev);
1250   st->st_ino = remote_fileio_to_host_uint (fst->fst_ino);
1251   st->st_mode = remote_fileio_to_host_mode (fst->fst_mode);
1252   st->st_nlink = remote_fileio_to_host_uint (fst->fst_nlink);
1253   st->st_uid = remote_fileio_to_host_uint (fst->fst_uid);
1254   st->st_gid = remote_fileio_to_host_uint (fst->fst_gid);
1255   st->st_rdev = remote_fileio_to_host_uint (fst->fst_rdev);
1256   st->st_size = remote_fileio_to_host_ulong (fst->fst_size);
1257 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1258   st->st_blksize = remote_fileio_to_host_ulong (fst->fst_blksize);
1259 #endif
1260 #if HAVE_STRUCT_STAT_ST_BLOCKS
1261   st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
1262 #endif
1263   st->st_atime = remote_fileio_to_host_time (fst->fst_atime);
1264   st->st_mtime = remote_fileio_to_host_time (fst->fst_mtime);
1265   st->st_ctime = remote_fileio_to_host_time (fst->fst_ctime);
1266 }
1267 \f
1268
1269 static void
1270 set_system_call_allowed (const char *args, int from_tty)
1271 {
1272   if (args)
1273     {
1274       char *arg_end;
1275       int val = strtoul (args, &arg_end, 10);
1276
1277       if (*args && *arg_end == '\0')
1278         {
1279           remote_fio_system_call_allowed = !!val;
1280           return;
1281         }
1282     }
1283   error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1284 }
1285
1286 static void
1287 show_system_call_allowed (const char *args, int from_tty)
1288 {
1289   if (args)
1290     error (_("Garbage after \"show remote "
1291              "system-call-allowed\" command: `%s'"), args);
1292   printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1293                      remote_fio_system_call_allowed ? "" : "not ");
1294 }
1295
1296 void
1297 initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
1298                           struct cmd_list_element *remote_show_cmdlist)
1299 {
1300   add_cmd ("system-call-allowed", no_class,
1301            set_system_call_allowed,
1302            _("Set if the host system(3) call is allowed for the target."),
1303            &remote_set_cmdlist);
1304   add_cmd ("system-call-allowed", no_class,
1305            show_system_call_allowed,
1306            _("Show if the host system(3) call is allowed for the target."),
1307            &remote_show_cmdlist);
1308 }