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