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