1 /* Remote File-I/O communications
3 Copyright (C) 2003-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 /* See the GDB User Guide for details of the GDB remote protocol. */
22 #include "event-top.h"
23 #include "extract-store-integer.h"
24 #include "cli/cli-cmds.h"
26 #include "gdbsupport/gdb_wait.h"
28 #include "remote-fileio.h"
29 #include "gdbsupport/event-loop.h"
31 #include "filenames.h"
32 #include "gdbsupport/filestuff.h"
35 #include "gdbsupport/gdb_sys_time.h"
37 #include <sys/cygwin.h>
46 #define FIO_FD_INVALID -1
47 #define FIO_FD_CONSOLE_IN -2
48 #define FIO_FD_CONSOLE_OUT -3
50 static int remote_fio_system_call_allowed
= 0;
53 remote_fileio_init_fd_map (void)
57 if (!remote_fio_data
.fd_map
)
59 remote_fio_data
.fd_map
= XNEWVEC (int, 10);
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
;
71 remote_fileio_resize_fd_map (void)
73 int i
= remote_fio_data
.fd_map_size
;
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;
87 remote_fileio_next_free_fd (void)
91 for (i
= 0; i
< remote_fio_data
.fd_map_size
; ++i
)
92 if (remote_fio_data
.fd_map
[i
] == FIO_FD_INVALID
)
94 return remote_fileio_resize_fd_map ();
98 remote_fileio_fd_to_targetfd (int fd
)
100 int target_fd
= remote_fileio_next_free_fd ();
102 remote_fio_data
.fd_map
[target_fd
] = fd
;
107 remote_fileio_map_fd (int target_fd
)
109 remote_fileio_init_fd_map ();
110 if (target_fd
< 0 || target_fd
>= remote_fio_data
.fd_map_size
)
111 return FIO_FD_INVALID
;
112 return remote_fio_data
.fd_map
[target_fd
];
116 remote_fileio_close_target_fd (int target_fd
)
118 remote_fileio_init_fd_map ();
119 if (target_fd
>= 0 && target_fd
< remote_fio_data
.fd_map_size
)
120 remote_fio_data
.fd_map
[target_fd
] = FIO_FD_INVALID
;
124 remote_fileio_oflags_to_host (long flags
)
128 if (flags
& FILEIO_O_CREAT
)
130 if (flags
& FILEIO_O_EXCL
)
132 if (flags
& FILEIO_O_TRUNC
)
134 if (flags
& FILEIO_O_APPEND
)
136 if (flags
& FILEIO_O_RDONLY
)
138 if (flags
& FILEIO_O_WRONLY
)
140 if (flags
& FILEIO_O_RDWR
)
142 /* On systems supporting binary and text mode, always open files in
151 remote_fileio_mode_to_host (long mode
, int open_call
)
157 if (mode
& FILEIO_S_IFREG
)
159 if (mode
& FILEIO_S_IFDIR
)
161 if (mode
& FILEIO_S_IFCHR
)
164 if (mode
& FILEIO_S_IRUSR
)
166 if (mode
& FILEIO_S_IWUSR
)
168 if (mode
& FILEIO_S_IXUSR
)
171 if (mode
& FILEIO_S_IRGRP
)
175 if (mode
& FILEIO_S_IWGRP
)
179 if (mode
& FILEIO_S_IXGRP
)
182 if (mode
& FILEIO_S_IROTH
)
185 if (mode
& FILEIO_S_IWOTH
)
189 if (mode
& FILEIO_S_IXOTH
)
196 remote_fileio_seek_flag_to_host (long num
, int *flag
)
202 case FILEIO_SEEK_SET
:
205 case FILEIO_SEEK_CUR
:
208 case FILEIO_SEEK_END
:
218 remote_fileio_extract_long (char **buf
, LONGEST
*retlong
)
223 if (!buf
|| !*buf
|| !**buf
|| !retlong
)
225 c
= strchr (*buf
, ',');
229 c
= strchr (*buf
, '\0');
230 while (strchr ("+-", **buf
))
236 for (*retlong
= 0; **buf
; ++*buf
)
239 if (**buf
>= '0' && **buf
<= '9')
240 *retlong
+= **buf
- '0';
241 else if (**buf
>= 'a' && **buf
<= 'f')
242 *retlong
+= **buf
- 'a' + 10;
243 else if (**buf
>= 'A' && **buf
<= 'F')
244 *retlong
+= **buf
- 'A' + 10;
254 remote_fileio_extract_int (char **buf
, long *retint
)
261 ret
= remote_fileio_extract_long (buf
, &retlong
);
263 *retint
= (long) retlong
;
268 remote_fileio_extract_ptr_w_len (char **buf
, CORE_ADDR
*ptrval
, int *length
)
273 if (!buf
|| !*buf
|| !**buf
|| !ptrval
|| !length
)
275 c
= strchr (*buf
, '/');
279 if (remote_fileio_extract_long (buf
, &retlong
))
281 *ptrval
= (CORE_ADDR
) retlong
;
283 if (remote_fileio_extract_long (buf
, &retlong
))
285 *length
= (int) retlong
;
290 remote_fileio_to_fio_long (LONGEST num
, fio_long_t fnum
)
292 host_to_bigendian (num
, (char *) fnum
, 8);
296 remote_fileio_to_fio_timeval (struct timeval
*tv
, struct fio_timeval
*ftv
)
298 host_to_fileio_time (tv
->tv_sec
, ftv
->ftv_sec
);
299 remote_fileio_to_fio_long (tv
->tv_usec
, ftv
->ftv_usec
);
302 /* The quit handler originally installed. */
303 static quit_handler_ftype
*remote_fileio_o_quit_handler
;
305 /* What to do on a QUIT call while handling a file I/O request. We
306 throw a quit exception, which is caught by remote_fileio_request
307 and translated to an EINTR reply back to the target. */
310 remote_fileio_quit_handler (void)
312 if (check_quit_flag ())
317 remote_fileio_reply (remote_target
*remote
, int retcode
, int error
)
320 bool ctrl_c
= check_quit_flag ();
328 sprintf (buf
+ strlen (buf
), "%x", retcode
);
332 error
= FILEIO_EINTR
;
338 sprintf (buf
+ strlen (buf
), ",%x", error
);
342 quit_handler
= remote_fileio_o_quit_handler
;
343 putpkt (remote
, buf
);
347 remote_fileio_ioerror (remote_target
*remote
)
349 remote_fileio_reply (remote
, -1, FILEIO_EIO
);
353 remote_fileio_badfd (remote_target
*remote
)
355 remote_fileio_reply (remote
, -1, FILEIO_EBADF
);
359 remote_fileio_return_errno (remote_target
*remote
, int retcode
)
361 remote_fileio_reply (remote
, retcode
, retcode
< 0
362 ? host_to_fileio_error (errno
) : 0);
366 remote_fileio_return_success (remote_target
*remote
, int retcode
)
368 remote_fileio_reply (remote
, retcode
, 0);
372 remote_fileio_func_open (remote_target
*remote
, char *buf
)
382 /* 1. Parameter: Ptr to pathname / length incl. trailing zero. */
383 if (remote_fileio_extract_ptr_w_len (&buf
, &ptrval
, &length
))
385 remote_fileio_ioerror (remote
);
388 /* 2. Parameter: open flags */
389 if (remote_fileio_extract_int (&buf
, &num
))
391 remote_fileio_ioerror (remote
);
394 flags
= remote_fileio_oflags_to_host (num
);
395 /* 3. Parameter: open mode */
396 if (remote_fileio_extract_int (&buf
, &num
))
398 remote_fileio_ioerror (remote
);
401 mode
= remote_fileio_mode_to_host (num
, 1);
403 /* Request pathname. */
404 pathname
= (char *) alloca (length
);
405 if (target_read_memory (ptrval
, (gdb_byte
*) pathname
, length
) != 0)
407 remote_fileio_ioerror (remote
);
411 /* Check if pathname exists and is not a regular file or directory. If so,
412 return an appropriate error code. Same for trying to open directories
414 if (!stat (pathname
, &st
))
416 if (!S_ISREG (st
.st_mode
) && !S_ISDIR (st
.st_mode
))
418 remote_fileio_reply (remote
, -1, FILEIO_ENODEV
);
421 if (S_ISDIR (st
.st_mode
)
422 && ((flags
& O_WRONLY
) == O_WRONLY
|| (flags
& O_RDWR
) == O_RDWR
))
424 remote_fileio_reply (remote
, -1, FILEIO_EISDIR
);
429 fd
= gdb_open_cloexec (pathname
, flags
, mode
).release ();
432 remote_fileio_return_errno (remote
, -1);
436 fd
= remote_fileio_fd_to_targetfd (fd
);
437 remote_fileio_return_success (remote
, fd
);
441 remote_fileio_func_close (remote_target
*remote
, char *buf
)
446 /* Parameter: file descriptor */
447 if (remote_fileio_extract_int (&buf
, &num
))
449 remote_fileio_ioerror (remote
);
452 fd
= remote_fileio_map_fd ((int) num
);
453 if (fd
== FIO_FD_INVALID
)
455 remote_fileio_badfd (remote
);
459 if (fd
!= FIO_FD_CONSOLE_IN
&& fd
!= FIO_FD_CONSOLE_OUT
&& close (fd
))
460 remote_fileio_return_errno (remote
, -1);
461 remote_fileio_close_target_fd ((int) num
);
462 remote_fileio_return_success (remote
, 0);
466 remote_fileio_func_read (remote_target
*remote
, char *buf
)
474 off_t old_offset
, new_offset
;
476 /* 1. Parameter: file descriptor */
477 if (remote_fileio_extract_int (&buf
, &target_fd
))
479 remote_fileio_ioerror (remote
);
482 fd
= remote_fileio_map_fd ((int) target_fd
);
483 if (fd
== FIO_FD_INVALID
)
485 remote_fileio_badfd (remote
);
488 /* 2. Parameter: buffer pointer */
489 if (remote_fileio_extract_long (&buf
, &lnum
))
491 remote_fileio_ioerror (remote
);
494 ptrval
= (CORE_ADDR
) lnum
;
495 /* 3. Parameter: buffer length */
496 if (remote_fileio_extract_int (&buf
, &num
))
498 remote_fileio_ioerror (remote
);
501 length
= (size_t) num
;
505 case FIO_FD_CONSOLE_OUT
:
506 remote_fileio_badfd (remote
);
508 case FIO_FD_CONSOLE_IN
:
510 static char *remaining_buf
= NULL
;
511 static int remaining_length
= 0;
513 buffer
= (gdb_byte
*) xmalloc (16384);
516 if (remaining_length
> length
)
518 memcpy (buffer
, remaining_buf
, length
);
519 memmove (remaining_buf
, remaining_buf
+ length
,
520 remaining_length
- length
);
521 remaining_length
-= length
;
526 memcpy (buffer
, remaining_buf
, remaining_length
);
527 xfree (remaining_buf
);
528 remaining_buf
= NULL
;
529 ret
= remaining_length
;
534 /* Windows (at least XP and Server 2003) has difficulty
535 with large reads from consoles. If a handle is
536 backed by a real console device, overly large reads
537 from the handle will fail and set errno == ENOMEM.
538 On a Windows Server 2003 system where I tested,
539 reading 26608 bytes from the console was OK, but
540 anything above 26609 bytes would fail. The limit has
541 been observed to vary on different systems. So, we
542 limit this read to something smaller than that - by a
543 safe margin, in case the limit depends on system
544 resources or version. */
545 ret
= gdb_stdtargin
->read ((char *) buffer
, 16383);
546 if (ret
> 0 && (size_t)ret
> length
)
548 remaining_buf
= (char *) xmalloc (ret
- length
);
549 remaining_length
= ret
- length
;
550 memcpy (remaining_buf
, buffer
+ length
, remaining_length
);
557 buffer
= (gdb_byte
*) xmalloc (length
);
558 /* POSIX defines EINTR behavior of read in a weird way. It's allowed
559 for read() to return -1 even if "some" bytes have been read. It
560 has been corrected in SUSv2 but that doesn't help us much...
561 Therefore a complete solution must check how many bytes have been
562 read on EINTR to return a more reliable value to the target */
563 old_offset
= lseek (fd
, 0, SEEK_CUR
);
564 ret
= read (fd
, buffer
, length
);
565 if (ret
< 0 && errno
== EINTR
)
567 new_offset
= lseek (fd
, 0, SEEK_CUR
);
568 /* If some data has been read, return the number of bytes read.
569 The Ctrl-C flag is set in remote_fileio_reply() anyway. */
570 if (old_offset
!= new_offset
)
571 ret
= new_offset
- old_offset
;
578 errno
= target_write_memory (ptrval
, buffer
, ret
);
584 remote_fileio_return_errno (remote
, -1);
586 remote_fileio_return_success (remote
, ret
);
592 remote_fileio_func_write (remote_target
*remote
, char *buf
)
601 /* 1. Parameter: file descriptor */
602 if (remote_fileio_extract_int (&buf
, &target_fd
))
604 remote_fileio_ioerror (remote
);
607 fd
= remote_fileio_map_fd ((int) target_fd
);
608 if (fd
== FIO_FD_INVALID
)
610 remote_fileio_badfd (remote
);
613 /* 2. Parameter: buffer pointer */
614 if (remote_fileio_extract_long (&buf
, &lnum
))
616 remote_fileio_ioerror (remote
);
619 ptrval
= (CORE_ADDR
) lnum
;
620 /* 3. Parameter: buffer length */
621 if (remote_fileio_extract_int (&buf
, &num
))
623 remote_fileio_ioerror (remote
);
626 length
= (size_t) num
;
628 buffer
= (gdb_byte
*) xmalloc (length
);
629 if (target_read_memory (ptrval
, buffer
, length
) != 0)
632 remote_fileio_ioerror (remote
);
638 case FIO_FD_CONSOLE_IN
:
639 remote_fileio_badfd (remote
);
642 case FIO_FD_CONSOLE_OUT
:
644 ui_file
*file
= gdb_stdtarg
;
645 file
->write ((char *) buffer
, length
);
651 ret
= write (fd
, buffer
, length
);
652 if (ret
< 0 && errno
== EACCES
)
653 errno
= EBADF
; /* Cygwin returns EACCESS when writing to a
659 remote_fileio_return_errno (remote
, -1);
661 remote_fileio_return_success (remote
, ret
);
667 remote_fileio_func_lseek (remote_target
*remote
, char *buf
)
674 /* 1. Parameter: file descriptor */
675 if (remote_fileio_extract_int (&buf
, &num
))
677 remote_fileio_ioerror (remote
);
680 fd
= remote_fileio_map_fd ((int) num
);
681 if (fd
== FIO_FD_INVALID
)
683 remote_fileio_badfd (remote
);
686 else if (fd
== FIO_FD_CONSOLE_IN
|| fd
== FIO_FD_CONSOLE_OUT
)
688 remote_fileio_reply (remote
, -1, FILEIO_ESPIPE
);
692 /* 2. Parameter: offset */
693 if (remote_fileio_extract_long (&buf
, &lnum
))
695 remote_fileio_ioerror (remote
);
698 offset
= (off_t
) lnum
;
699 /* 3. Parameter: flag */
700 if (remote_fileio_extract_int (&buf
, &num
))
702 remote_fileio_ioerror (remote
);
705 if (remote_fileio_seek_flag_to_host (num
, &flag
))
707 remote_fileio_reply (remote
, -1, FILEIO_EINVAL
);
711 ret
= lseek (fd
, offset
, flag
);
713 if (ret
== (off_t
) -1)
714 remote_fileio_return_errno (remote
, -1);
716 remote_fileio_return_success (remote
, ret
);
720 remote_fileio_func_rename (remote_target
*remote
, char *buf
)
722 CORE_ADDR old_ptr
, new_ptr
;
723 int old_len
, new_len
;
724 char *oldpath
, *newpath
;
726 struct stat ost
, nst
;
728 /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
729 if (remote_fileio_extract_ptr_w_len (&buf
, &old_ptr
, &old_len
))
731 remote_fileio_ioerror (remote
);
735 /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
736 if (remote_fileio_extract_ptr_w_len (&buf
, &new_ptr
, &new_len
))
738 remote_fileio_ioerror (remote
);
742 /* Request oldpath using 'm' packet */
743 oldpath
= (char *) alloca (old_len
);
744 if (target_read_memory (old_ptr
, (gdb_byte
*) oldpath
, old_len
) != 0)
746 remote_fileio_ioerror (remote
);
750 /* Request newpath using 'm' packet */
751 newpath
= (char *) alloca (new_len
);
752 if (target_read_memory (new_ptr
, (gdb_byte
*) newpath
, new_len
) != 0)
754 remote_fileio_ioerror (remote
);
758 /* Only operate on regular files and directories. */
759 of
= stat (oldpath
, &ost
);
760 nf
= stat (newpath
, &nst
);
761 if ((!of
&& !S_ISREG (ost
.st_mode
) && !S_ISDIR (ost
.st_mode
))
762 || (!nf
&& !S_ISREG (nst
.st_mode
) && !S_ISDIR (nst
.st_mode
)))
764 remote_fileio_reply (remote
, -1, FILEIO_EACCES
);
768 ret
= rename (oldpath
, newpath
);
772 /* Special case: newpath is a non-empty directory. Some systems
773 return ENOTEMPTY, some return EEXIST. We coerce that to be
775 if (errno
== ENOTEMPTY
)
778 /* Workaround some Cygwin problems with correct errnos. */
781 if (!of
&& !nf
&& S_ISDIR (nst
.st_mode
))
783 if (S_ISREG (ost
.st_mode
))
787 char oldfullpath
[PATH_MAX
];
788 char newfullpath
[PATH_MAX
];
791 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, oldpath
, oldfullpath
,
793 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, newpath
, newfullpath
,
795 len
= strlen (oldfullpath
);
796 if (IS_DIR_SEPARATOR (newfullpath
[len
])
797 && !filename_ncmp (oldfullpath
, newfullpath
, len
))
806 remote_fileio_return_errno (remote
, -1);
809 remote_fileio_return_success (remote
, ret
);
813 remote_fileio_func_unlink (remote_target
*remote
, char *buf
)
821 /* Parameter: Ptr to pathname / length incl. trailing zero */
822 if (remote_fileio_extract_ptr_w_len (&buf
, &ptrval
, &length
))
824 remote_fileio_ioerror (remote
);
827 /* Request pathname using 'm' packet */
828 pathname
= (char *) alloca (length
);
829 if (target_read_memory (ptrval
, (gdb_byte
*) pathname
, length
) != 0)
831 remote_fileio_ioerror (remote
);
835 /* Only operate on regular files (and directories, which allows to return
836 the correct return code). */
837 if (!stat (pathname
, &st
) && !S_ISREG (st
.st_mode
) && !S_ISDIR (st
.st_mode
))
839 remote_fileio_reply (remote
, -1, FILEIO_ENODEV
);
843 ret
= unlink (pathname
);
846 remote_fileio_return_errno (remote
, -1);
848 remote_fileio_return_success (remote
, ret
);
852 remote_fileio_func_stat (remote_target
*remote
, char *buf
)
854 CORE_ADDR statptr
, nameptr
;
861 /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
862 if (remote_fileio_extract_ptr_w_len (&buf
, &nameptr
, &namelength
))
864 remote_fileio_ioerror (remote
);
868 /* 2. Parameter: Ptr to struct stat */
869 if (remote_fileio_extract_long (&buf
, &lnum
))
871 remote_fileio_ioerror (remote
);
874 statptr
= (CORE_ADDR
) lnum
;
876 /* Request pathname using 'm' packet */
877 pathname
= (char *) alloca (namelength
);
878 if (target_read_memory (nameptr
, (gdb_byte
*) pathname
, namelength
) != 0)
880 remote_fileio_ioerror (remote
);
884 ret
= stat (pathname
, &st
);
888 remote_fileio_return_errno (remote
, -1);
891 /* Only operate on regular files and directories. */
892 if (!ret
&& !S_ISREG (st
.st_mode
) && !S_ISDIR (st
.st_mode
))
894 remote_fileio_reply (remote
, -1, FILEIO_EACCES
);
899 host_to_fileio_stat (&st
, &fst
);
900 host_to_fileio_uint (0, fst
.fst_dev
);
902 errno
= target_write_memory (statptr
, (gdb_byte
*) &fst
, sizeof fst
);
905 remote_fileio_return_errno (remote
, -1);
909 remote_fileio_return_success (remote
, ret
);
913 remote_fileio_func_fstat (remote_target
*remote
, char *buf
)
923 /* 1. Parameter: file descriptor */
924 if (remote_fileio_extract_int (&buf
, &target_fd
))
926 remote_fileio_ioerror (remote
);
929 fd
= remote_fileio_map_fd ((int) target_fd
);
930 if (fd
== FIO_FD_INVALID
)
932 remote_fileio_badfd (remote
);
935 /* 2. Parameter: Ptr to struct stat */
936 if (remote_fileio_extract_long (&buf
, &lnum
))
938 remote_fileio_ioerror (remote
);
941 ptrval
= (CORE_ADDR
) lnum
;
943 if (fd
== FIO_FD_CONSOLE_IN
|| fd
== FIO_FD_CONSOLE_OUT
)
945 host_to_fileio_uint (1, fst
.fst_dev
);
946 memset (&st
, 0, sizeof (st
));
947 st
.st_mode
= S_IFCHR
| (fd
== FIO_FD_CONSOLE_IN
? S_IRUSR
: S_IWUSR
);
950 st
.st_uid
= getuid ();
953 st
.st_gid
= getgid ();
955 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
958 #if HAVE_STRUCT_STAT_ST_BLOCKS
961 if (!gettimeofday (&tv
, NULL
))
962 st
.st_atime
= st
.st_mtime
= st
.st_ctime
= tv
.tv_sec
;
964 st
.st_atime
= st
.st_mtime
= st
.st_ctime
= (time_t) 0;
968 ret
= fstat (fd
, &st
);
972 remote_fileio_return_errno (remote
, -1);
977 host_to_fileio_stat (&st
, &fst
);
979 errno
= target_write_memory (ptrval
, (gdb_byte
*) &fst
, sizeof fst
);
982 remote_fileio_return_errno (remote
, -1);
986 remote_fileio_return_success (remote
, ret
);
990 remote_fileio_func_gettimeofday (remote_target
*remote
, char *buf
)
996 struct fio_timeval ftv
;
998 /* 1. Parameter: struct timeval pointer */
999 if (remote_fileio_extract_long (&buf
, &lnum
))
1001 remote_fileio_ioerror (remote
);
1004 ptrval
= (CORE_ADDR
) lnum
;
1005 /* 2. Parameter: some pointer value... */
1006 if (remote_fileio_extract_long (&buf
, &lnum
))
1008 remote_fileio_ioerror (remote
);
1011 /* ...which has to be NULL. */
1014 remote_fileio_reply (remote
, -1, FILEIO_EINVAL
);
1018 ret
= gettimeofday (&tv
, NULL
);
1022 remote_fileio_return_errno (remote
, -1);
1028 remote_fileio_to_fio_timeval (&tv
, &ftv
);
1030 errno
= target_write_memory (ptrval
, (gdb_byte
*) &ftv
, sizeof ftv
);
1033 remote_fileio_return_errno (remote
, -1);
1037 remote_fileio_return_success (remote
, ret
);
1041 remote_fileio_func_isatty (remote_target
*remote
, char *buf
)
1046 /* Parameter: file descriptor */
1047 if (remote_fileio_extract_int (&buf
, &target_fd
))
1049 remote_fileio_ioerror (remote
);
1052 fd
= remote_fileio_map_fd ((int) target_fd
);
1053 int ret
= fd
== FIO_FD_CONSOLE_IN
|| fd
== FIO_FD_CONSOLE_OUT
? 1 : 0;
1054 remote_fileio_return_success (remote
, ret
);
1058 remote_fileio_func_system (remote_target
*remote
, char *buf
)
1062 char *cmdline
= NULL
;
1064 /* Parameter: Ptr to commandline / length incl. trailing zero */
1065 if (remote_fileio_extract_ptr_w_len (&buf
, &ptrval
, &length
))
1067 remote_fileio_ioerror (remote
);
1073 /* Request commandline using 'm' packet */
1074 cmdline
= (char *) alloca (length
);
1075 if (target_read_memory (ptrval
, (gdb_byte
*) cmdline
, length
) != 0)
1077 remote_fileio_ioerror (remote
);
1082 /* Check if system(3) has been explicitly allowed using the
1083 `set remote system-call-allowed 1' command. If length is 0,
1084 indicating a NULL parameter to the system call, return zero to
1085 indicate a shell is not available. Otherwise fail with EPERM. */
1086 if (!remote_fio_system_call_allowed
)
1089 remote_fileio_return_success (remote
, 0);
1091 remote_fileio_reply (remote
, -1, FILEIO_EPERM
);
1095 ret
= system (cmdline
);
1098 remote_fileio_return_success (remote
, ret
);
1100 remote_fileio_return_errno (remote
, -1);
1102 remote_fileio_return_success (remote
, WEXITSTATUS (ret
));
1107 void (*func
)(remote_target
*remote
, char *);
1108 } remote_fio_func_map
[] = {
1109 { "open", remote_fileio_func_open
},
1110 { "close", remote_fileio_func_close
},
1111 { "read", remote_fileio_func_read
},
1112 { "write", remote_fileio_func_write
},
1113 { "lseek", remote_fileio_func_lseek
},
1114 { "rename", remote_fileio_func_rename
},
1115 { "unlink", remote_fileio_func_unlink
},
1116 { "stat", remote_fileio_func_stat
},
1117 { "fstat", remote_fileio_func_fstat
},
1118 { "gettimeofday", remote_fileio_func_gettimeofday
},
1119 { "isatty", remote_fileio_func_isatty
},
1120 { "system", remote_fileio_func_system
},
1125 do_remote_fileio_request (remote_target
*remote
, char *buf
)
1130 quit_handler
= remote_fileio_quit_handler
;
1132 c
= strchr (++buf
, ',');
1136 c
= strchr (buf
, '\0');
1137 for (idx
= 0; remote_fio_func_map
[idx
].name
; ++idx
)
1138 if (!strcmp (remote_fio_func_map
[idx
].name
, buf
))
1140 if (!remote_fio_func_map
[idx
].name
)
1141 remote_fileio_reply (remote
, -1, FILEIO_ENOSYS
);
1143 remote_fio_func_map
[idx
].func (remote
, c
);
1146 /* Close any open descriptors, and reinitialize the file mapping. */
1149 remote_fileio_reset (void)
1153 for (ix
= 0; ix
!= remote_fio_data
.fd_map_size
; ix
++)
1155 int fd
= remote_fio_data
.fd_map
[ix
];
1160 if (remote_fio_data
.fd_map
)
1162 xfree (remote_fio_data
.fd_map
);
1163 remote_fio_data
.fd_map
= NULL
;
1164 remote_fio_data
.fd_map_size
= 0;
1168 /* Handle a file I/O request. BUF points to the packet containing the
1169 request. CTRLC_PENDING_P should be nonzero if the target has not
1170 acknowledged the Ctrl-C sent asynchronously earlier. */
1173 remote_fileio_request (remote_target
*remote
, char *buf
, int ctrlc_pending_p
)
1175 /* Save the previous quit handler, so we can restore it. No need
1176 for a cleanup since we catch all exceptions below. Note that the
1177 quit handler is also restored by remote_fileio_reply just before
1178 pushing a packet. */
1179 remote_fileio_o_quit_handler
= quit_handler
;
1181 if (ctrlc_pending_p
)
1183 /* If the target hasn't responded to the Ctrl-C sent
1184 asynchronously earlier, take this opportunity to send the
1185 Ctrl-C synchronously. */
1187 remote_fileio_reply (remote
, -1, FILEIO_EINTR
);
1193 do_remote_fileio_request (remote
, buf
);
1195 catch (const gdb_exception_forced_quit
&ex
)
1199 catch (const gdb_exception_quit
&ex
)
1201 remote_fileio_reply (remote
, -1, FILEIO_EINTR
);
1203 catch (const gdb_exception
&ex
)
1205 remote_fileio_reply (remote
, -1, FILEIO_EIO
);
1209 quit_handler
= remote_fileio_o_quit_handler
;
1213 /* Unpack an fio_uint_t. */
1216 remote_fileio_to_host_uint (fio_uint_t fnum
)
1218 return extract_unsigned_integer ((gdb_byte
*) fnum
, 4,
1222 /* Unpack an fio_ulong_t. */
1225 remote_fileio_to_host_ulong (fio_ulong_t fnum
)
1227 return extract_unsigned_integer ((gdb_byte
*) fnum
, 8,
1231 /* Unpack an fio_mode_t. */
1234 remote_fileio_to_host_mode (fio_mode_t fnum
)
1236 return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum
),
1240 /* Unpack an fio_time_t. */
1243 remote_fileio_to_host_time (fio_time_t fnum
)
1245 return remote_fileio_to_host_uint (fnum
);
1249 /* See remote-fileio.h. */
1252 remote_fileio_to_host_stat (struct fio_stat
*fst
, struct stat
*st
)
1254 memset (st
, 0, sizeof (struct stat
));
1256 st
->st_dev
= remote_fileio_to_host_uint (fst
->fst_dev
);
1257 st
->st_ino
= remote_fileio_to_host_uint (fst
->fst_ino
);
1258 st
->st_mode
= remote_fileio_to_host_mode (fst
->fst_mode
);
1259 st
->st_nlink
= remote_fileio_to_host_uint (fst
->fst_nlink
);
1260 st
->st_uid
= remote_fileio_to_host_uint (fst
->fst_uid
);
1261 st
->st_gid
= remote_fileio_to_host_uint (fst
->fst_gid
);
1262 st
->st_rdev
= remote_fileio_to_host_uint (fst
->fst_rdev
);
1263 st
->st_size
= remote_fileio_to_host_ulong (fst
->fst_size
);
1264 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1265 st
->st_blksize
= remote_fileio_to_host_ulong (fst
->fst_blksize
);
1267 #if HAVE_STRUCT_STAT_ST_BLOCKS
1268 st
->st_blocks
= remote_fileio_to_host_ulong (fst
->fst_blocks
);
1270 st
->st_atime
= remote_fileio_to_host_time (fst
->fst_atime
);
1271 st
->st_mtime
= remote_fileio_to_host_time (fst
->fst_mtime
);
1272 st
->st_ctime
= remote_fileio_to_host_time (fst
->fst_ctime
);
1277 set_system_call_allowed (const char *args
, int from_tty
)
1282 int val
= strtoul (args
, &arg_end
, 10);
1284 if (*args
&& *arg_end
== '\0')
1286 remote_fio_system_call_allowed
= !!val
;
1290 error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1294 show_system_call_allowed (const char *args
, int from_tty
)
1297 error (_("Garbage after \"show remote "
1298 "system-call-allowed\" command: `%s'"), args
);
1299 gdb_printf ("Calling host system(3) call from target is %sallowed\n",
1300 remote_fio_system_call_allowed
? "" : "not ");
1304 initialize_remote_fileio (struct cmd_list_element
**remote_set_cmdlist
,
1305 struct cmd_list_element
**remote_show_cmdlist
)
1307 add_cmd ("system-call-allowed", no_class
,
1308 set_system_call_allowed
,
1309 _("Set if the host system(3) call is allowed for the target."),
1310 remote_set_cmdlist
);
1311 add_cmd ("system-call-allowed", no_class
,
1312 show_system_call_allowed
,
1313 _("Show if the host system(3) call is allowed for the target."),
1314 remote_show_cmdlist
);