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