2007-08-10 Maxim Grigoriev <maxim2405@gmail.com>
[platform/upstream/binutils.git] / gdb / remote-fileio.c
1 /* Remote File-I/O communications
2
3    Copyright (C) 2003, 2005, 2006, 2007 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 2 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, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21
22 /* See the GDB User Guide for details of the GDB remote protocol. */
23
24 #include "defs.h"
25 #include "gdb_string.h"
26 #include "gdbcmd.h"
27 #include "remote.h"
28 #include "gdb/fileio.h"
29 #include "gdb_wait.h"
30 #include "gdb_stat.h"
31 #include "exceptions.h"
32 #include "remote-fileio.h"
33
34 #include <fcntl.h>
35 #include <sys/time.h>
36 #ifdef __CYGWIN__
37 #include <sys/cygwin.h>         /* For cygwin_conv_to_full_posix_path.  */
38 #endif
39 #include <signal.h>
40
41 static struct {
42   int *fd_map;
43   int fd_map_size;
44 } remote_fio_data;
45
46 #define FIO_FD_INVALID          -1
47 #define FIO_FD_CONSOLE_IN       -2
48 #define FIO_FD_CONSOLE_OUT      -3
49
50 static int remote_fio_system_call_allowed = 0;
51
52 static int
53 remote_fileio_init_fd_map (void)
54 {
55   int i;
56
57   if (!remote_fio_data.fd_map)
58     {
59       remote_fio_data.fd_map = (int *) xmalloc (10 * sizeof (int));
60       remote_fio_data.fd_map_size = 10;
61       remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
62       remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
63       remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
64       for (i = 3; i < 10; ++i)
65         remote_fio_data.fd_map[i] = FIO_FD_INVALID;
66     }
67   return 3;
68 }
69
70 static int
71 remote_fileio_resize_fd_map (void)
72 {
73   int i = remote_fio_data.fd_map_size;
74
75   if (!remote_fio_data.fd_map)
76     return remote_fileio_init_fd_map ();
77   remote_fio_data.fd_map_size += 10;
78   remote_fio_data.fd_map =
79     (int *) xrealloc (remote_fio_data.fd_map,
80                       remote_fio_data.fd_map_size * sizeof (int));
81   for (; i < remote_fio_data.fd_map_size; i++)
82     remote_fio_data.fd_map[i] = FIO_FD_INVALID;
83   return remote_fio_data.fd_map_size - 10;
84 }
85
86 static int
87 remote_fileio_next_free_fd (void)
88 {
89   int i;
90
91   for (i = 0; i < remote_fio_data.fd_map_size; ++i)
92     if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
93       return i;
94   return remote_fileio_resize_fd_map ();
95 }
96
97 static int
98 remote_fileio_fd_to_targetfd (int fd)
99 {
100   int target_fd = remote_fileio_next_free_fd ();
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 LONGEST
195 remote_fileio_mode_to_target (mode_t mode)
196 {
197   mode_t tmode = 0;
198
199   if (S_ISREG(mode))
200     tmode |= FILEIO_S_IFREG;
201   if (S_ISDIR(mode))
202     tmode |= FILEIO_S_IFDIR;
203   if (S_ISCHR(mode))
204     tmode |= FILEIO_S_IFCHR;
205   if (mode & S_IRUSR)
206     tmode |= FILEIO_S_IRUSR;
207   if (mode & S_IWUSR)
208     tmode |= FILEIO_S_IWUSR;
209   if (mode & S_IXUSR)
210     tmode |= FILEIO_S_IXUSR;
211 #ifdef S_IRGRP
212   if (mode & S_IRGRP)
213     tmode |= FILEIO_S_IRGRP;
214 #endif
215 #ifdef S_IWRGRP
216   if (mode & S_IWGRP)
217     tmode |= FILEIO_S_IWGRP;
218 #endif
219 #ifdef S_IXGRP
220   if (mode & S_IXGRP)
221     tmode |= FILEIO_S_IXGRP;
222 #endif
223   if (mode & S_IROTH)
224     tmode |= FILEIO_S_IROTH;
225 #ifdef S_IWOTH
226   if (mode & S_IWOTH)
227     tmode |= FILEIO_S_IWOTH;
228 #endif
229 #ifdef S_IXOTH
230   if (mode & S_IXOTH)
231     tmode |= FILEIO_S_IXOTH;
232 #endif
233   return tmode;
234 }
235
236 static int
237 remote_fileio_errno_to_target (int error)
238 {
239   switch (error)
240     {
241       case EPERM:
242         return FILEIO_EPERM;
243       case ENOENT:
244         return FILEIO_ENOENT;
245       case EINTR:
246         return FILEIO_EINTR;
247       case EIO:
248         return FILEIO_EIO;
249       case EBADF:
250         return FILEIO_EBADF;
251       case EACCES:
252         return FILEIO_EACCES;
253       case EFAULT:
254         return FILEIO_EFAULT;
255       case EBUSY:
256         return FILEIO_EBUSY;
257       case EEXIST:
258         return FILEIO_EEXIST;
259       case ENODEV:
260         return FILEIO_ENODEV;
261       case ENOTDIR:
262         return FILEIO_ENOTDIR;
263       case EISDIR:
264         return FILEIO_EISDIR;
265       case EINVAL:
266         return FILEIO_EINVAL;
267       case ENFILE:
268         return FILEIO_ENFILE;
269       case EMFILE:
270         return FILEIO_EMFILE;
271       case EFBIG:
272         return FILEIO_EFBIG;
273       case ENOSPC:
274         return FILEIO_ENOSPC;
275       case ESPIPE:
276         return FILEIO_ESPIPE;
277       case EROFS:
278         return FILEIO_EROFS;
279       case ENOSYS:
280         return FILEIO_ENOSYS;
281       case ENAMETOOLONG:
282         return FILEIO_ENAMETOOLONG;
283     }
284   return FILEIO_EUNKNOWN;
285 }
286
287 static int
288 remote_fileio_seek_flag_to_host (long num, int *flag)
289 {
290   if (!flag)
291     return 0;
292   switch (num)
293     {
294       case FILEIO_SEEK_SET:
295         *flag = SEEK_SET;
296         break;
297       case FILEIO_SEEK_CUR:
298         *flag =  SEEK_CUR;
299         break;
300       case FILEIO_SEEK_END:
301         *flag =  SEEK_END;
302         break;
303       default:
304         return -1;
305     }
306   return 0;
307 }
308
309 static int
310 remote_fileio_extract_long (char **buf, LONGEST *retlong)
311 {
312   char *c;
313   int sign = 1;
314
315   if (!buf || !*buf || !**buf || !retlong)
316     return -1;
317   c = strchr (*buf, ',');
318   if (c)
319     *c++ = '\0';
320   else
321     c = strchr (*buf, '\0');
322   while (strchr ("+-", **buf))
323     {
324       if (**buf == '-')
325         sign = -sign;
326       ++*buf;
327     }
328   for (*retlong = 0; **buf; ++*buf)
329     {
330       *retlong <<= 4;
331       if (**buf >= '0' && **buf <= '9')
332         *retlong += **buf - '0';
333       else if (**buf >= 'a' && **buf <= 'f')
334         *retlong += **buf - 'a' + 10;
335       else if (**buf >= 'A' && **buf <= 'F')
336         *retlong += **buf - 'A' + 10;
337       else
338         return -1;
339     }
340   *retlong *= sign;
341   *buf = c;
342   return 0;
343 }
344
345 static int
346 remote_fileio_extract_int (char **buf, long *retint)
347 {
348   int ret;
349   LONGEST retlong;
350
351   if (!retint)
352     return -1;
353   ret = remote_fileio_extract_long (buf, &retlong);
354   if (!ret)
355     *retint = (long) retlong;
356   return ret;
357 }
358
359 static int
360 remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
361 {
362   char *c;
363   LONGEST retlong;
364
365   if (!buf || !*buf || !**buf || !ptrval || !length)
366     return -1;
367   c = strchr (*buf, '/');
368   if (!c)
369     return -1;
370   *c++ = '\0';
371   if (remote_fileio_extract_long (buf, &retlong))
372     return -1;
373   *ptrval = (CORE_ADDR) retlong;
374   *buf = c;
375   if (remote_fileio_extract_long (buf, &retlong))
376     return -1;
377   *length = (int) retlong;
378   return 0;
379 }
380
381 /* Convert to big endian */
382 static void
383 remote_fileio_to_be (LONGEST num, char *buf, int bytes)
384 {
385   int i;
386
387   for (i = 0; i < bytes; ++i)
388     buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff;
389 }
390
391 static void
392 remote_fileio_to_fio_uint (long num, fio_uint_t fnum)
393 {
394   remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
395 }
396
397 static void
398 remote_fileio_to_fio_mode (mode_t num, fio_mode_t fnum)
399 {
400   remote_fileio_to_be (remote_fileio_mode_to_target(num), (char *) fnum, 4);
401 }
402
403 static void
404 remote_fileio_to_fio_time (time_t num, fio_time_t fnum)
405 {
406   remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
407 }
408
409 static void
410 remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
411 {
412   remote_fileio_to_be (num, (char *) fnum, 8);
413 }
414
415 static void
416 remote_fileio_to_fio_ulong (LONGEST num, fio_ulong_t fnum)
417 {
418   remote_fileio_to_be (num, (char *) fnum, 8);
419 }
420
421 static void
422 remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst)
423 {
424   LONGEST blksize;
425
426   /* `st_dev' is set in the calling function */
427   remote_fileio_to_fio_uint ((long) st->st_ino, fst->fst_ino);
428   remote_fileio_to_fio_mode (st->st_mode, fst->fst_mode);
429   remote_fileio_to_fio_uint ((long) st->st_nlink, fst->fst_nlink);
430   remote_fileio_to_fio_uint ((long) st->st_uid, fst->fst_uid);
431   remote_fileio_to_fio_uint ((long) st->st_gid, fst->fst_gid);
432   remote_fileio_to_fio_uint ((long) st->st_rdev, fst->fst_rdev);
433   remote_fileio_to_fio_ulong ((LONGEST) st->st_size, fst->fst_size);
434 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
435   blksize = st->st_blksize;
436 #else
437   blksize = 512;
438 #endif
439   remote_fileio_to_fio_ulong (blksize, fst->fst_blksize);
440 #if HAVE_STRUCT_STAT_ST_BLOCKS
441   remote_fileio_to_fio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
442 #else
443   /* FIXME: This is correct for DJGPP, but other systems that don't
444      have st_blocks, if any, might prefer 512 instead of st_blksize.
445      (eliz, 30-12-2003)  */
446   remote_fileio_to_fio_ulong (((LONGEST) st->st_size + blksize - 1)
447                               / blksize,
448                               fst->fst_blocks);
449 #endif
450   remote_fileio_to_fio_time (st->st_atime, fst->fst_atime);
451   remote_fileio_to_fio_time (st->st_mtime, fst->fst_mtime);
452   remote_fileio_to_fio_time (st->st_ctime, fst->fst_ctime);
453 }
454
455 static void
456 remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
457 {
458   remote_fileio_to_fio_time (tv->tv_sec, ftv->ftv_sec);
459   remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
460 }
461
462 static int remote_fio_ctrl_c_flag = 0;
463 static int remote_fio_no_longjmp = 0;
464
465 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
466 static struct sigaction remote_fio_sa;
467 static struct sigaction remote_fio_osa;
468 #else
469 static void (*remote_fio_ofunc)(int);
470 #endif
471
472 static void
473 remote_fileio_sig_init (void)
474 {
475 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
476   remote_fio_sa.sa_handler = SIG_IGN;
477   sigemptyset (&remote_fio_sa.sa_mask);
478   remote_fio_sa.sa_flags = 0;
479   sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa);
480 #else
481   remote_fio_ofunc = signal (SIGINT, SIG_IGN);
482 #endif
483 }
484
485 static void
486 remote_fileio_sig_set (void (*sigint_func)(int))
487 {
488 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
489   remote_fio_sa.sa_handler = sigint_func;
490   sigemptyset (&remote_fio_sa.sa_mask);
491   remote_fio_sa.sa_flags = 0;
492   sigaction (SIGINT, &remote_fio_sa, NULL);
493 #else
494   signal (SIGINT, sigint_func);
495 #endif
496 }
497
498 static void
499 remote_fileio_sig_exit (void)
500 {
501 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
502   sigaction (SIGINT, &remote_fio_osa, NULL);
503 #else
504   signal (SIGINT, remote_fio_ofunc);
505 #endif
506 }
507
508 static void
509 remote_fileio_ctrl_c_signal_handler (int signo)
510 {
511   remote_fileio_sig_set (SIG_IGN);
512   remote_fio_ctrl_c_flag = 1;
513   if (!remote_fio_no_longjmp)
514     deprecated_throw_reason (RETURN_QUIT);
515   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
516 }
517
518 static void
519 remote_fileio_reply (int retcode, int error)
520 {
521   char buf[32];
522
523   remote_fileio_sig_set (SIG_IGN);
524   strcpy (buf, "F");
525   if (retcode < 0)
526     {
527       strcat (buf, "-");
528       retcode = -retcode;
529     }
530   sprintf (buf + strlen (buf), "%x", retcode);
531   if (error || remote_fio_ctrl_c_flag)
532     {
533       if (error && remote_fio_ctrl_c_flag)
534         error = FILEIO_EINTR;
535       if (error < 0)
536         {
537           strcat (buf, "-");
538           error = -error;
539         }
540       sprintf (buf + strlen (buf), ",%x", error);
541       if (remote_fio_ctrl_c_flag)
542         strcat (buf, ",C");
543     }
544   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
545   putpkt (buf);
546 }
547
548 static void
549 remote_fileio_ioerror (void)
550 {
551   remote_fileio_reply (-1, FILEIO_EIO);
552 }
553
554 static void
555 remote_fileio_badfd (void)
556 {
557   remote_fileio_reply (-1, FILEIO_EBADF);
558 }
559
560 static void
561 remote_fileio_return_errno (int retcode)
562 {
563   remote_fileio_reply (retcode,
564                        retcode < 0 ? remote_fileio_errno_to_target (errno) : 0);
565 }
566
567 static void
568 remote_fileio_return_success (int retcode)
569 {
570   remote_fileio_reply (retcode, 0);
571 }
572
573 /* Wrapper function for remote_write_bytes() which has the disadvantage to
574    write only one packet, regardless of the requested number of bytes to
575    transfer.  This wrapper calls remote_write_bytes() as often as needed. */
576 static int
577 remote_fileio_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
578 {
579   int ret = 0, written;
580
581   while (len > 0 && (written = remote_write_bytes (memaddr, myaddr, len)) > 0)
582     {
583       len -= written;
584       memaddr += written;
585       myaddr += written;
586       ret += written;
587     }
588   return ret;
589 }
590
591 static void
592 remote_fileio_func_open (char *buf)
593 {
594   CORE_ADDR ptrval;
595   int length, retlength;
596   long num;
597   int flags, fd;
598   mode_t mode;
599   char *pathname;
600   struct stat st;
601
602   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
603   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
604     {
605       remote_fileio_ioerror ();
606       return;
607     }
608   /* 2. Parameter: open flags */
609   if (remote_fileio_extract_int (&buf, &num))
610     {
611       remote_fileio_ioerror ();
612       return;
613     }
614   flags = remote_fileio_oflags_to_host (num);
615   /* 3. Parameter: open mode */
616   if (remote_fileio_extract_int (&buf, &num))
617     {
618       remote_fileio_ioerror ();
619       return;
620     }
621   mode = remote_fileio_mode_to_host (num, 1);
622
623   /* Request pathname using 'm' packet */
624   pathname = alloca (length);
625   retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
626   if (retlength != length)
627     {
628       remote_fileio_ioerror ();
629       return;
630     }
631
632   /* Check if pathname exists and is not a regular file or directory.  If so,
633      return an appropriate error code.  Same for trying to open directories
634      for writing. */
635   if (!stat (pathname, &st))
636     {
637       if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
638         {
639           remote_fileio_reply (-1, FILEIO_ENODEV);
640           return;
641         }
642       if (S_ISDIR (st.st_mode)
643           && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
644         {
645           remote_fileio_reply (-1, FILEIO_EISDIR);
646           return;
647         }
648     }
649
650   remote_fio_no_longjmp = 1;
651   fd = open (pathname, flags, mode);
652   if (fd < 0)
653     {
654       remote_fileio_return_errno (-1);
655       return;
656     }
657
658   fd = remote_fileio_fd_to_targetfd (fd);
659   remote_fileio_return_success (fd);
660 }
661
662 static void
663 remote_fileio_func_close (char *buf)
664 {
665   long num;
666   int fd;
667
668   /* Parameter: file descriptor */
669   if (remote_fileio_extract_int (&buf, &num))
670     {
671       remote_fileio_ioerror ();
672       return;
673     }
674   fd = remote_fileio_map_fd ((int) num);
675   if (fd == FIO_FD_INVALID)
676     {
677       remote_fileio_badfd ();
678       return;
679     }
680
681   remote_fio_no_longjmp = 1;
682   if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
683     remote_fileio_return_errno (-1);
684   remote_fileio_close_target_fd ((int) num);
685   remote_fileio_return_success (0);
686 }
687
688 static void
689 remote_fileio_func_read (char *buf)
690 {
691   long target_fd, num;
692   LONGEST lnum;
693   CORE_ADDR ptrval;
694   int fd, ret, retlength;
695   gdb_byte *buffer;
696   size_t length;
697   off_t old_offset, new_offset;
698
699   /* 1. Parameter: file descriptor */
700   if (remote_fileio_extract_int (&buf, &target_fd))
701     {
702       remote_fileio_ioerror ();
703       return;
704     }
705   fd = remote_fileio_map_fd ((int) target_fd);
706   if (fd == FIO_FD_INVALID)
707     {
708       remote_fileio_badfd ();
709       return;
710     }
711   /* 2. Parameter: buffer pointer */
712   if (remote_fileio_extract_long (&buf, &lnum))
713     {
714       remote_fileio_ioerror ();
715       return;
716     }
717   ptrval = (CORE_ADDR) lnum;
718   /* 3. Parameter: buffer length */
719   if (remote_fileio_extract_int (&buf, &num))
720     {
721       remote_fileio_ioerror ();
722       return;
723     }
724   length = (size_t) num;
725
726   switch (fd)
727     {
728       case FIO_FD_CONSOLE_OUT:
729         remote_fileio_badfd ();
730         return;
731       case FIO_FD_CONSOLE_IN:
732         {
733           static char *remaining_buf = NULL;
734           static int remaining_length = 0;
735
736           buffer = (gdb_byte *) xmalloc (32768);
737           if (remaining_buf)
738             {
739               remote_fio_no_longjmp = 1;
740               if (remaining_length > length)
741                 {
742                   memcpy (buffer, remaining_buf, length);
743                   memmove (remaining_buf, remaining_buf + length,
744                            remaining_length - length);
745                   remaining_length -= length;
746                   ret = length;
747                 }
748               else
749                 {
750                   memcpy (buffer, remaining_buf, remaining_length);
751                   xfree (remaining_buf);
752                   remaining_buf = NULL;
753                   ret = remaining_length;
754                 }
755             }
756           else
757             {
758               ret = ui_file_read (gdb_stdtargin, (char *) buffer, 32767);
759               remote_fio_no_longjmp = 1;
760               if (ret > 0 && (size_t)ret > length)
761                 {
762                   remaining_buf = (char *) xmalloc (ret - length);
763                   remaining_length = ret - length;
764                   memcpy (remaining_buf, buffer + length, remaining_length);
765                   ret = length;
766                 }
767             }
768         }
769         break;
770       default:
771         buffer = (gdb_byte *) xmalloc (length);
772         /* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
773            for read() to return -1 even if "some" bytes have been read.  It
774            has been corrected in SUSv2 but that doesn't help us much...
775            Therefore a complete solution must check how many bytes have been
776            read on EINTR to return a more reliable value to the target */
777         old_offset = lseek (fd, 0, SEEK_CUR);
778         remote_fio_no_longjmp = 1;
779         ret = read (fd, buffer, length);
780         if (ret < 0 && errno == EINTR)
781           {
782             new_offset = lseek (fd, 0, SEEK_CUR);
783             /* If some data has been read, return the number of bytes read.
784                The Ctrl-C flag is set in remote_fileio_reply() anyway */
785             if (old_offset != new_offset)
786               ret = new_offset - old_offset;
787           }
788         break;
789     }
790
791   if (ret > 0)
792     {
793       retlength = remote_fileio_write_bytes (ptrval, buffer, ret);
794       if (retlength != ret)
795         ret = -1; /* errno has been set to EIO in remote_fileio_write_bytes() */
796     }
797
798   if (ret < 0)
799     remote_fileio_return_errno (-1);
800   else
801     remote_fileio_return_success (ret);
802
803   xfree (buffer);
804 }
805
806 static void
807 remote_fileio_func_write (char *buf)
808 {
809   long target_fd, num;
810   LONGEST lnum;
811   CORE_ADDR ptrval;
812   int fd, ret, retlength;
813   gdb_byte *buffer;
814   size_t length;
815
816   /* 1. Parameter: file descriptor */
817   if (remote_fileio_extract_int (&buf, &target_fd))
818     {
819       remote_fileio_ioerror ();
820       return;
821     }
822   fd = remote_fileio_map_fd ((int) target_fd);
823   if (fd == FIO_FD_INVALID)
824     {
825       remote_fileio_badfd ();
826       return;
827     }
828   /* 2. Parameter: buffer pointer */
829   if (remote_fileio_extract_long (&buf, &lnum))
830     {
831       remote_fileio_ioerror ();
832       return;
833     }
834   ptrval = (CORE_ADDR) lnum;
835   /* 3. Parameter: buffer length */
836   if (remote_fileio_extract_int (&buf, &num))
837     {
838       remote_fileio_ioerror ();
839       return;
840     }
841   length = (size_t) num;
842     
843   buffer = (gdb_byte *) xmalloc (length);
844   retlength = remote_read_bytes (ptrval, buffer, length);
845   if (retlength != length)
846     {
847       xfree (buffer);
848       remote_fileio_ioerror ();
849       return;
850     }
851
852   remote_fio_no_longjmp = 1;
853   switch (fd)
854     {
855       case FIO_FD_CONSOLE_IN:
856         remote_fileio_badfd ();
857         xfree (buffer);
858         return;
859       case FIO_FD_CONSOLE_OUT:
860         ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
861                        (char *) buffer, length);
862         gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
863         ret = length;
864         break;
865       default:
866         ret = write (fd, buffer, length);
867         if (ret < 0 && errno == EACCES)
868           errno = EBADF; /* Cygwin returns EACCESS when writing to a R/O file.*/
869         break;
870     }
871
872   if (ret < 0)
873     remote_fileio_return_errno (-1);
874   else
875     remote_fileio_return_success (ret);
876
877   xfree (buffer);
878 }
879
880 static void
881 remote_fileio_func_lseek (char *buf)
882 {
883   long num;
884   LONGEST lnum;
885   int fd, flag;
886   off_t offset, ret;
887
888   /* 1. Parameter: file descriptor */
889   if (remote_fileio_extract_int (&buf, &num))
890     {
891       remote_fileio_ioerror ();
892       return;
893     }
894   fd = remote_fileio_map_fd ((int) num);
895   if (fd == FIO_FD_INVALID)
896     {
897       remote_fileio_badfd ();
898       return;
899     }
900   else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
901     {
902       remote_fileio_reply (-1, FILEIO_ESPIPE);
903       return;
904     }
905
906   /* 2. Parameter: offset */
907   if (remote_fileio_extract_long (&buf, &lnum))
908     {
909       remote_fileio_ioerror ();
910       return;
911     }
912   offset = (off_t) lnum;
913   /* 3. Parameter: flag */
914   if (remote_fileio_extract_int (&buf, &num))
915     {
916       remote_fileio_ioerror ();
917       return;
918     }
919   if (remote_fileio_seek_flag_to_host (num, &flag))
920     {
921       remote_fileio_reply (-1, FILEIO_EINVAL);
922       return;
923     }
924   
925   remote_fio_no_longjmp = 1;
926   ret = lseek (fd, offset, flag);
927
928   if (ret == (off_t) -1)
929     remote_fileio_return_errno (-1);
930   else
931     remote_fileio_return_success (ret);
932 }
933
934 static void
935 remote_fileio_func_rename (char *buf)
936 {
937   CORE_ADDR old_ptr, new_ptr;
938   int old_len, new_len, retlength;
939   char *oldpath, *newpath;
940   int ret, of, nf;
941   struct stat ost, nst;
942
943   /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
944   if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
945     {
946       remote_fileio_ioerror ();
947       return;
948     }
949   
950   /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
951   if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
952     {
953       remote_fileio_ioerror ();
954       return;
955     }
956   
957   /* Request oldpath using 'm' packet */
958   oldpath = alloca (old_len);
959   retlength = remote_read_bytes (old_ptr, (gdb_byte *) oldpath, old_len);
960   if (retlength != old_len)
961     {
962       remote_fileio_ioerror ();
963       return;
964     }
965   
966   /* Request newpath using 'm' packet */
967   newpath = alloca (new_len);
968   retlength = remote_read_bytes (new_ptr, (gdb_byte *) newpath, new_len);
969   if (retlength != new_len)
970     {
971       remote_fileio_ioerror ();
972       return;
973     }
974   
975   /* Only operate on regular files and directories */
976   of = stat (oldpath, &ost);
977   nf = stat (newpath, &nst);
978   if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
979       || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
980     {
981       remote_fileio_reply (-1, FILEIO_EACCES);
982       return;
983     }
984
985   remote_fio_no_longjmp = 1;
986   ret = rename (oldpath, newpath);
987
988   if (ret == -1)
989     {
990       /* Special case: newpath is a non-empty directory.  Some systems
991          return ENOTEMPTY, some return EEXIST.  We coerce that to be
992          always EEXIST. */
993       if (errno == ENOTEMPTY)
994         errno = EEXIST;
995 #ifdef __CYGWIN__
996       /* Workaround some Cygwin problems with correct errnos. */
997       if (errno == EACCES)
998         {
999           if (!of && !nf && S_ISDIR (nst.st_mode))
1000             {
1001               if (S_ISREG (ost.st_mode))
1002                 errno = EISDIR;
1003               else
1004                 {
1005                   char oldfullpath[PATH_MAX + 1];
1006                   char newfullpath[PATH_MAX + 1];
1007                   int len;
1008
1009                   cygwin_conv_to_full_posix_path (oldpath, oldfullpath);
1010                   cygwin_conv_to_full_posix_path (newpath, newfullpath);
1011                   len = strlen (oldfullpath);
1012                   if (newfullpath[len] == '/'
1013                       && !strncmp (oldfullpath, newfullpath, len))
1014                     errno = EINVAL;
1015                   else
1016                     errno = EEXIST;
1017                 }
1018             }
1019         }
1020 #endif
1021
1022       remote_fileio_return_errno (-1);
1023     }
1024   else
1025     remote_fileio_return_success (ret);
1026 }
1027
1028 static void
1029 remote_fileio_func_unlink (char *buf)
1030 {
1031   CORE_ADDR ptrval;
1032   int length, retlength;
1033   char *pathname;
1034   int ret;
1035   struct stat st;
1036
1037   /* Parameter: Ptr to pathname / length incl. trailing zero */
1038   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1039     {
1040       remote_fileio_ioerror ();
1041       return;
1042     }
1043   /* Request pathname using 'm' packet */
1044   pathname = alloca (length);
1045   retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
1046   if (retlength != length)
1047     {
1048       remote_fileio_ioerror ();
1049       return;
1050     }
1051
1052   /* Only operate on regular files (and directories, which allows to return
1053      the correct return code) */
1054   if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
1055     {
1056       remote_fileio_reply (-1, FILEIO_ENODEV);
1057       return;
1058     }
1059
1060   remote_fio_no_longjmp = 1;
1061   ret = unlink (pathname);
1062
1063   if (ret == -1)
1064     remote_fileio_return_errno (-1);
1065   else
1066     remote_fileio_return_success (ret);
1067 }
1068
1069 static void
1070 remote_fileio_func_stat (char *buf)
1071 {
1072   CORE_ADDR statptr, nameptr;
1073   int ret, namelength, retlength;
1074   char *pathname;
1075   LONGEST lnum;
1076   struct stat st;
1077   struct fio_stat fst;
1078
1079   /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
1080   if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
1081     {
1082       remote_fileio_ioerror ();
1083       return;
1084     }
1085
1086   /* 2. Parameter: Ptr to struct stat */
1087   if (remote_fileio_extract_long (&buf, &lnum))
1088     {
1089       remote_fileio_ioerror ();
1090       return;
1091     }
1092   statptr = (CORE_ADDR) lnum;
1093   
1094   /* Request pathname using 'm' packet */
1095   pathname = alloca (namelength);
1096   retlength = remote_read_bytes (nameptr, (gdb_byte *) pathname, namelength);
1097   if (retlength != namelength)
1098     {
1099       remote_fileio_ioerror ();
1100       return;
1101     }
1102
1103   remote_fio_no_longjmp = 1;
1104   ret = stat (pathname, &st);
1105
1106   if (ret == -1)
1107     {
1108       remote_fileio_return_errno (-1);
1109       return;
1110     }
1111   /* Only operate on regular files and directories */
1112   if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
1113     {
1114       remote_fileio_reply (-1, FILEIO_EACCES);
1115       return;
1116     }
1117   if (statptr)
1118     {
1119       remote_fileio_to_fio_stat (&st, &fst);
1120       remote_fileio_to_fio_uint (0, fst.fst_dev);
1121       
1122       retlength = remote_fileio_write_bytes (statptr,
1123                                              (gdb_byte *) &fst, sizeof fst);
1124       if (retlength != sizeof fst)
1125         {
1126           remote_fileio_return_errno (-1);
1127           return;
1128         }
1129     }
1130   remote_fileio_return_success (ret);
1131 }
1132
1133 static void
1134 remote_fileio_func_fstat (char *buf)
1135 {
1136   CORE_ADDR ptrval;
1137   int fd, ret, retlength;
1138   long target_fd;
1139   LONGEST lnum;
1140   struct stat st;
1141   struct fio_stat fst;
1142   struct timeval tv;
1143
1144   /* 1. Parameter: file descriptor */
1145   if (remote_fileio_extract_int (&buf, &target_fd))
1146     {
1147       remote_fileio_ioerror ();
1148       return;
1149     }
1150   fd = remote_fileio_map_fd ((int) target_fd);
1151   if (fd == FIO_FD_INVALID)
1152     {
1153       remote_fileio_badfd ();
1154       return;
1155     }
1156   /* 2. Parameter: Ptr to struct stat */
1157   if (remote_fileio_extract_long (&buf, &lnum))
1158     {
1159       remote_fileio_ioerror ();
1160       return;
1161     }
1162   ptrval = (CORE_ADDR) lnum;
1163
1164   remote_fio_no_longjmp = 1;
1165   if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
1166     {
1167       remote_fileio_to_fio_uint (1, fst.fst_dev);
1168       st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
1169       st.st_nlink = 1;
1170 #ifdef HAVE_GETUID
1171       st.st_uid = getuid ();
1172 #else
1173       st.st_uid = 0;
1174 #endif
1175 #ifdef HAVE_GETGID
1176       st.st_gid = getgid ();
1177 #else
1178       st.st_gid = 0;
1179 #endif
1180       st.st_rdev = 0;
1181       st.st_size = 0;
1182 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1183       st.st_blksize = 512;
1184 #endif
1185 #if HAVE_STRUCT_STAT_ST_BLOCKS
1186       st.st_blocks = 0;
1187 #endif
1188       if (!gettimeofday (&tv, NULL))
1189         st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
1190       else
1191         st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
1192       ret = 0;
1193     }
1194   else
1195     ret = fstat (fd, &st);
1196
1197   if (ret == -1)
1198     {
1199       remote_fileio_return_errno (-1);
1200       return;
1201     }
1202   if (ptrval)
1203     {
1204       remote_fileio_to_fio_stat (&st, &fst);
1205
1206       retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &fst, sizeof fst);
1207       if (retlength != sizeof fst)
1208         {
1209           remote_fileio_return_errno (-1);
1210           return;
1211         }
1212     }
1213   remote_fileio_return_success (ret);
1214 }
1215
1216 static void
1217 remote_fileio_func_gettimeofday (char *buf)
1218 {
1219   LONGEST lnum;
1220   CORE_ADDR ptrval;
1221   int ret, retlength;
1222   struct timeval tv;
1223   struct fio_timeval ftv;
1224
1225   /* 1. Parameter: struct timeval pointer */
1226   if (remote_fileio_extract_long (&buf, &lnum))
1227     {
1228       remote_fileio_ioerror ();
1229       return;
1230     }
1231   ptrval = (CORE_ADDR) lnum;
1232   /* 2. Parameter: some pointer value... */
1233   if (remote_fileio_extract_long (&buf, &lnum))
1234     {
1235       remote_fileio_ioerror ();
1236       return;
1237     }
1238   /* ...which has to be NULL */
1239   if (lnum)
1240     {
1241       remote_fileio_reply (-1, FILEIO_EINVAL);
1242       return;
1243     }
1244
1245   remote_fio_no_longjmp = 1;
1246   ret = gettimeofday (&tv, NULL);
1247
1248   if (ret == -1)
1249     {
1250       remote_fileio_return_errno (-1);
1251       return;
1252     }
1253
1254   if (ptrval)
1255     {
1256       remote_fileio_to_fio_timeval (&tv, &ftv);
1257
1258       retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1259       if (retlength != sizeof ftv)
1260         {
1261           remote_fileio_return_errno (-1);
1262           return;
1263         }
1264     }
1265   remote_fileio_return_success (ret);
1266 }
1267
1268 static void
1269 remote_fileio_func_isatty (char *buf)
1270 {
1271   long target_fd;
1272   int fd;
1273
1274   /* Parameter: file descriptor */
1275   if (remote_fileio_extract_int (&buf, &target_fd))
1276     {
1277       remote_fileio_ioerror ();
1278       return;
1279     }
1280   remote_fio_no_longjmp = 1;
1281   fd = remote_fileio_map_fd ((int) target_fd);
1282   remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
1283                                 fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
1284 }
1285
1286 static void
1287 remote_fileio_func_system (char *buf)
1288 {
1289   CORE_ADDR ptrval;
1290   int ret, length, retlength;
1291   char *cmdline = NULL;
1292
1293   /* Parameter: Ptr to commandline / length incl. trailing zero */
1294   if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1295     {
1296       remote_fileio_ioerror ();
1297       return;
1298     }
1299
1300   if (length)
1301     {
1302       /* Request commandline using 'm' packet */
1303       cmdline = alloca (length);
1304       retlength = remote_read_bytes (ptrval, (gdb_byte *) cmdline, length);
1305       if (retlength != length)
1306         {
1307           remote_fileio_ioerror ();
1308           return;
1309         }
1310     }
1311   
1312   /* Check if system(3) has been explicitely allowed using the
1313      `set remote system-call-allowed 1' command.  If length is 0,
1314      indicating a NULL parameter to the system call, return zero to
1315      indicate a shell is not available.  Otherwise fail with EPERM.  */
1316   if (!remote_fio_system_call_allowed)
1317     {
1318       if (!length)
1319         remote_fileio_return_success (0);
1320       else
1321         remote_fileio_reply (-1, FILEIO_EPERM);
1322       return;
1323     }
1324
1325   remote_fio_no_longjmp = 1;
1326   ret = system (cmdline);
1327
1328   if (!length)
1329     remote_fileio_return_success (ret);
1330   else if (ret == -1)
1331     remote_fileio_return_errno (-1);
1332   else
1333     remote_fileio_return_success (WEXITSTATUS (ret));
1334 }
1335
1336 static struct {
1337   char *name;
1338   void (*func)(char *);
1339 } remote_fio_func_map[] = {
1340   { "open", remote_fileio_func_open },
1341   { "close", remote_fileio_func_close },
1342   { "read", remote_fileio_func_read },
1343   { "write", remote_fileio_func_write },
1344   { "lseek", remote_fileio_func_lseek },
1345   { "rename", remote_fileio_func_rename },
1346   { "unlink", remote_fileio_func_unlink },
1347   { "stat", remote_fileio_func_stat },
1348   { "fstat", remote_fileio_func_fstat },
1349   { "gettimeofday", remote_fileio_func_gettimeofday },
1350   { "isatty", remote_fileio_func_isatty },
1351   { "system", remote_fileio_func_system },
1352   { NULL, NULL }
1353 };
1354
1355 static int
1356 do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
1357 {
1358   char *buf = buf_arg;
1359   char *c;
1360   int idx;
1361
1362   remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
1363
1364   c = strchr (++buf, ',');
1365   if (c)
1366     *c++ = '\0';
1367   else
1368     c = strchr (buf, '\0');
1369   for (idx = 0; remote_fio_func_map[idx].name; ++idx)
1370     if (!strcmp (remote_fio_func_map[idx].name, buf))
1371       break;
1372   if (!remote_fio_func_map[idx].name)   /* ERROR: No such function. */
1373     return RETURN_ERROR;
1374   remote_fio_func_map[idx].func (c);
1375   return 0;
1376 }
1377
1378 /* Close any open descriptors, and reinitialize the file mapping.  */
1379
1380 void
1381 remote_fileio_reset (void)
1382 {
1383   int ix;
1384
1385   for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1386     {
1387       int fd = remote_fio_data.fd_map[ix];
1388
1389       if (fd >= 0)
1390         close (fd);
1391     }
1392   if (remote_fio_data.fd_map)
1393     {
1394       free (remote_fio_data.fd_map);
1395       remote_fio_data.fd_map = NULL;
1396       remote_fio_data.fd_map_size = 0;
1397     }
1398 }
1399
1400 void
1401 remote_fileio_request (char *buf)
1402 {
1403   int ex;
1404
1405   remote_fileio_sig_init ();
1406
1407   remote_fio_ctrl_c_flag = 0;
1408   remote_fio_no_longjmp = 0;
1409
1410   ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
1411                          RETURN_MASK_ALL);
1412   switch (ex)
1413     {
1414       case RETURN_ERROR:
1415         remote_fileio_reply (-1, FILEIO_ENOSYS);
1416         break;
1417       case RETURN_QUIT:
1418         remote_fileio_reply (-1, FILEIO_EINTR);
1419         break;
1420       default:
1421         break;
1422     }
1423
1424   remote_fileio_sig_exit ();
1425 }
1426
1427 static void
1428 set_system_call_allowed (char *args, int from_tty)
1429 {
1430   if (args)
1431     {
1432       char *arg_end;
1433       int val = strtoul (args, &arg_end, 10);
1434       if (*args && *arg_end == '\0')
1435         {
1436           remote_fio_system_call_allowed = !!val;
1437           return;
1438         }
1439     }
1440   error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1441 }
1442
1443 static void
1444 show_system_call_allowed (char *args, int from_tty)
1445 {
1446   if (args)
1447     error (_("Garbage after \"show remote system-call-allowed\" command: `%s'"), args);
1448   printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1449                      remote_fio_system_call_allowed ? "" : "not ");
1450 }
1451
1452 void
1453 initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
1454                           struct cmd_list_element *remote_show_cmdlist)
1455 {
1456   add_cmd ("system-call-allowed", no_class,
1457            set_system_call_allowed,
1458            _("Set if the host system(3) call is allowed for the target."),
1459            &remote_set_cmdlist);
1460   add_cmd ("system-call-allowed", no_class,
1461            show_system_call_allowed,
1462            _("Show if the host system(3) call is allowed for the target."),
1463            &remote_show_cmdlist);
1464 }