1 /* Remote File-I/O communications
3 Copyright (C) 2003-2015 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. */
27 #include "remote-fileio.h"
28 #include "event-loop.h"
30 #include "filenames.h"
31 #include "filestuff.h"
36 #include <sys/cygwin.h> /* For cygwin_conv_path. */
45 #define FIO_FD_INVALID -1
46 #define FIO_FD_CONSOLE_IN -2
47 #define FIO_FD_CONSOLE_OUT -3
49 static int remote_fio_system_call_allowed
= 0;
51 static struct async_signal_handler
*sigint_fileio_token
;
54 remote_fileio_init_fd_map (void)
58 if (!remote_fio_data
.fd_map
)
60 remote_fio_data
.fd_map
= (int *) xmalloc (10 * sizeof (int));
61 remote_fio_data
.fd_map_size
= 10;
62 remote_fio_data
.fd_map
[0] = FIO_FD_CONSOLE_IN
;
63 remote_fio_data
.fd_map
[1] = FIO_FD_CONSOLE_OUT
;
64 remote_fio_data
.fd_map
[2] = FIO_FD_CONSOLE_OUT
;
65 for (i
= 3; i
< 10; ++i
)
66 remote_fio_data
.fd_map
[i
] = FIO_FD_INVALID
;
72 remote_fileio_resize_fd_map (void)
74 int i
= remote_fio_data
.fd_map_size
;
76 if (!remote_fio_data
.fd_map
)
77 return remote_fileio_init_fd_map ();
78 remote_fio_data
.fd_map_size
+= 10;
79 remote_fio_data
.fd_map
=
80 (int *) xrealloc (remote_fio_data
.fd_map
,
81 remote_fio_data
.fd_map_size
* sizeof (int));
82 for (; i
< remote_fio_data
.fd_map_size
; i
++)
83 remote_fio_data
.fd_map
[i
] = FIO_FD_INVALID
;
84 return remote_fio_data
.fd_map_size
- 10;
88 remote_fileio_next_free_fd (void)
92 for (i
= 0; i
< remote_fio_data
.fd_map_size
; ++i
)
93 if (remote_fio_data
.fd_map
[i
] == FIO_FD_INVALID
)
95 return remote_fileio_resize_fd_map ();
99 remote_fileio_fd_to_targetfd (int fd
)
101 int target_fd
= remote_fileio_next_free_fd ();
103 remote_fio_data
.fd_map
[target_fd
] = fd
;
108 remote_fileio_map_fd (int target_fd
)
110 remote_fileio_init_fd_map ();
111 if (target_fd
< 0 || target_fd
>= remote_fio_data
.fd_map_size
)
112 return FIO_FD_INVALID
;
113 return remote_fio_data
.fd_map
[target_fd
];
117 remote_fileio_close_target_fd (int target_fd
)
119 remote_fileio_init_fd_map ();
120 if (target_fd
>= 0 && target_fd
< remote_fio_data
.fd_map_size
)
121 remote_fio_data
.fd_map
[target_fd
] = FIO_FD_INVALID
;
125 remote_fileio_oflags_to_host (long flags
)
129 if (flags
& FILEIO_O_CREAT
)
131 if (flags
& FILEIO_O_EXCL
)
133 if (flags
& FILEIO_O_TRUNC
)
135 if (flags
& FILEIO_O_APPEND
)
137 if (flags
& FILEIO_O_RDONLY
)
139 if (flags
& FILEIO_O_WRONLY
)
141 if (flags
& FILEIO_O_RDWR
)
143 /* On systems supporting binary and text mode, always open files in
152 remote_fileio_mode_to_host (long mode
, int open_call
)
158 if (mode
& FILEIO_S_IFREG
)
160 if (mode
& FILEIO_S_IFDIR
)
162 if (mode
& FILEIO_S_IFCHR
)
165 if (mode
& FILEIO_S_IRUSR
)
167 if (mode
& FILEIO_S_IWUSR
)
169 if (mode
& FILEIO_S_IXUSR
)
172 if (mode
& FILEIO_S_IRGRP
)
176 if (mode
& FILEIO_S_IWGRP
)
180 if (mode
& FILEIO_S_IXGRP
)
183 if (mode
& FILEIO_S_IROTH
)
186 if (mode
& FILEIO_S_IWOTH
)
190 if (mode
& FILEIO_S_IXOTH
)
197 remote_fileio_seek_flag_to_host (long num
, int *flag
)
203 case FILEIO_SEEK_SET
:
206 case FILEIO_SEEK_CUR
:
209 case FILEIO_SEEK_END
:
219 remote_fileio_extract_long (char **buf
, LONGEST
*retlong
)
224 if (!buf
|| !*buf
|| !**buf
|| !retlong
)
226 c
= strchr (*buf
, ',');
230 c
= strchr (*buf
, '\0');
231 while (strchr ("+-", **buf
))
237 for (*retlong
= 0; **buf
; ++*buf
)
240 if (**buf
>= '0' && **buf
<= '9')
241 *retlong
+= **buf
- '0';
242 else if (**buf
>= 'a' && **buf
<= 'f')
243 *retlong
+= **buf
- 'a' + 10;
244 else if (**buf
>= 'A' && **buf
<= 'F')
245 *retlong
+= **buf
- 'A' + 10;
255 remote_fileio_extract_int (char **buf
, long *retint
)
262 ret
= remote_fileio_extract_long (buf
, &retlong
);
264 *retint
= (long) retlong
;
269 remote_fileio_extract_ptr_w_len (char **buf
, CORE_ADDR
*ptrval
, int *length
)
274 if (!buf
|| !*buf
|| !**buf
|| !ptrval
|| !length
)
276 c
= strchr (*buf
, '/');
280 if (remote_fileio_extract_long (buf
, &retlong
))
282 *ptrval
= (CORE_ADDR
) retlong
;
284 if (remote_fileio_extract_long (buf
, &retlong
))
286 *length
= (int) retlong
;
291 remote_fileio_to_fio_long (LONGEST num
, fio_long_t fnum
)
293 host_to_bigendian (num
, (char *) fnum
, 8);
297 remote_fileio_to_fio_timeval (struct timeval
*tv
, struct fio_timeval
*ftv
)
299 host_to_fileio_time (tv
->tv_sec
, ftv
->ftv_sec
);
300 remote_fileio_to_fio_long (tv
->tv_usec
, ftv
->ftv_usec
);
303 static int remote_fio_ctrl_c_flag
= 0;
304 static int remote_fio_no_longjmp
= 0;
306 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
307 static struct sigaction remote_fio_sa
;
308 static struct sigaction remote_fio_osa
;
310 static void (*remote_fio_ofunc
)(int);
314 remote_fileio_sig_init (void)
316 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
317 remote_fio_sa
.sa_handler
= SIG_IGN
;
318 sigemptyset (&remote_fio_sa
.sa_mask
);
319 remote_fio_sa
.sa_flags
= 0;
320 sigaction (SIGINT
, &remote_fio_sa
, &remote_fio_osa
);
322 remote_fio_ofunc
= signal (SIGINT
, SIG_IGN
);
327 remote_fileio_sig_set (void (*sigint_func
)(int))
329 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
330 remote_fio_sa
.sa_handler
= sigint_func
;
331 sigemptyset (&remote_fio_sa
.sa_mask
);
332 remote_fio_sa
.sa_flags
= 0;
333 sigaction (SIGINT
, &remote_fio_sa
, NULL
);
335 signal (SIGINT
, sigint_func
);
340 remote_fileio_sig_exit (void)
342 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
343 sigaction (SIGINT
, &remote_fio_osa
, NULL
);
345 signal (SIGINT
, remote_fio_ofunc
);
350 async_remote_fileio_interrupt (gdb_client_data arg
)
356 remote_fileio_ctrl_c_signal_handler (int signo
)
358 remote_fileio_sig_set (SIG_IGN
);
359 remote_fio_ctrl_c_flag
= 1;
360 if (!remote_fio_no_longjmp
)
361 gdb_call_async_signal_handler (sigint_fileio_token
, 1);
362 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler
);
366 remote_fileio_reply (int retcode
, int error
)
370 remote_fileio_sig_set (SIG_IGN
);
377 sprintf (buf
+ strlen (buf
), "%x", retcode
);
378 if (error
|| remote_fio_ctrl_c_flag
)
380 if (error
&& remote_fio_ctrl_c_flag
)
381 error
= FILEIO_EINTR
;
387 sprintf (buf
+ strlen (buf
), ",%x", error
);
388 if (remote_fio_ctrl_c_flag
)
391 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler
);
396 remote_fileio_ioerror (void)
398 remote_fileio_reply (-1, FILEIO_EIO
);
402 remote_fileio_badfd (void)
404 remote_fileio_reply (-1, FILEIO_EBADF
);
408 remote_fileio_return_errno (int retcode
)
410 remote_fileio_reply (retcode
, retcode
< 0
411 ? host_to_fileio_error (errno
) : 0);
415 remote_fileio_return_success (int retcode
)
417 remote_fileio_reply (retcode
, 0);
421 remote_fileio_func_open (char *buf
)
431 /* 1. Parameter: Ptr to pathname / length incl. trailing zero. */
432 if (remote_fileio_extract_ptr_w_len (&buf
, &ptrval
, &length
))
434 remote_fileio_ioerror ();
437 /* 2. Parameter: open flags */
438 if (remote_fileio_extract_int (&buf
, &num
))
440 remote_fileio_ioerror ();
443 flags
= remote_fileio_oflags_to_host (num
);
444 /* 3. Parameter: open mode */
445 if (remote_fileio_extract_int (&buf
, &num
))
447 remote_fileio_ioerror ();
450 mode
= remote_fileio_mode_to_host (num
, 1);
452 /* Request pathname. */
453 pathname
= alloca (length
);
454 if (target_read_memory (ptrval
, (gdb_byte
*) pathname
, length
) != 0)
456 remote_fileio_ioerror ();
460 /* Check if pathname exists and is not a regular file or directory. If so,
461 return an appropriate error code. Same for trying to open directories
463 if (!stat (pathname
, &st
))
465 if (!S_ISREG (st
.st_mode
) && !S_ISDIR (st
.st_mode
))
467 remote_fileio_reply (-1, FILEIO_ENODEV
);
470 if (S_ISDIR (st
.st_mode
)
471 && ((flags
& O_WRONLY
) == O_WRONLY
|| (flags
& O_RDWR
) == O_RDWR
))
473 remote_fileio_reply (-1, FILEIO_EISDIR
);
478 remote_fio_no_longjmp
= 1;
479 fd
= gdb_open_cloexec (pathname
, flags
, mode
);
482 remote_fileio_return_errno (-1);
486 fd
= remote_fileio_fd_to_targetfd (fd
);
487 remote_fileio_return_success (fd
);
491 remote_fileio_func_close (char *buf
)
496 /* Parameter: file descriptor */
497 if (remote_fileio_extract_int (&buf
, &num
))
499 remote_fileio_ioerror ();
502 fd
= remote_fileio_map_fd ((int) num
);
503 if (fd
== FIO_FD_INVALID
)
505 remote_fileio_badfd ();
509 remote_fio_no_longjmp
= 1;
510 if (fd
!= FIO_FD_CONSOLE_IN
&& fd
!= FIO_FD_CONSOLE_OUT
&& close (fd
))
511 remote_fileio_return_errno (-1);
512 remote_fileio_close_target_fd ((int) num
);
513 remote_fileio_return_success (0);
517 remote_fileio_func_read (char *buf
)
525 off_t old_offset
, new_offset
;
527 /* 1. Parameter: file descriptor */
528 if (remote_fileio_extract_int (&buf
, &target_fd
))
530 remote_fileio_ioerror ();
533 fd
= remote_fileio_map_fd ((int) target_fd
);
534 if (fd
== FIO_FD_INVALID
)
536 remote_fileio_badfd ();
539 /* 2. Parameter: buffer pointer */
540 if (remote_fileio_extract_long (&buf
, &lnum
))
542 remote_fileio_ioerror ();
545 ptrval
= (CORE_ADDR
) lnum
;
546 /* 3. Parameter: buffer length */
547 if (remote_fileio_extract_int (&buf
, &num
))
549 remote_fileio_ioerror ();
552 length
= (size_t) num
;
556 case FIO_FD_CONSOLE_OUT
:
557 remote_fileio_badfd ();
559 case FIO_FD_CONSOLE_IN
:
561 static char *remaining_buf
= NULL
;
562 static int remaining_length
= 0;
564 buffer
= (gdb_byte
*) xmalloc (16384);
567 remote_fio_no_longjmp
= 1;
568 if (remaining_length
> length
)
570 memcpy (buffer
, remaining_buf
, length
);
571 memmove (remaining_buf
, remaining_buf
+ length
,
572 remaining_length
- length
);
573 remaining_length
-= length
;
578 memcpy (buffer
, remaining_buf
, remaining_length
);
579 xfree (remaining_buf
);
580 remaining_buf
= NULL
;
581 ret
= remaining_length
;
586 /* Windows (at least XP and Server 2003) has difficulty
587 with large reads from consoles. If a handle is
588 backed by a real console device, overly large reads
589 from the handle will fail and set errno == ENOMEM.
590 On a Windows Server 2003 system where I tested,
591 reading 26608 bytes from the console was OK, but
592 anything above 26609 bytes would fail. The limit has
593 been observed to vary on different systems. So, we
594 limit this read to something smaller than that - by a
595 safe margin, in case the limit depends on system
596 resources or version. */
597 ret
= ui_file_read (gdb_stdtargin
, (char *) buffer
, 16383);
598 remote_fio_no_longjmp
= 1;
599 if (ret
> 0 && (size_t)ret
> length
)
601 remaining_buf
= (char *) xmalloc (ret
- length
);
602 remaining_length
= ret
- length
;
603 memcpy (remaining_buf
, buffer
+ length
, remaining_length
);
610 buffer
= (gdb_byte
*) xmalloc (length
);
611 /* POSIX defines EINTR behaviour of read in a weird way. It's allowed
612 for read() to return -1 even if "some" bytes have been read. It
613 has been corrected in SUSv2 but that doesn't help us much...
614 Therefore a complete solution must check how many bytes have been
615 read on EINTR to return a more reliable value to the target */
616 old_offset
= lseek (fd
, 0, SEEK_CUR
);
617 remote_fio_no_longjmp
= 1;
618 ret
= read (fd
, buffer
, length
);
619 if (ret
< 0 && errno
== EINTR
)
621 new_offset
= lseek (fd
, 0, SEEK_CUR
);
622 /* If some data has been read, return the number of bytes read.
623 The Ctrl-C flag is set in remote_fileio_reply() anyway. */
624 if (old_offset
!= new_offset
)
625 ret
= new_offset
- old_offset
;
632 errno
= target_write_memory (ptrval
, buffer
, ret
);
638 remote_fileio_return_errno (-1);
640 remote_fileio_return_success (ret
);
646 remote_fileio_func_write (char *buf
)
655 /* 1. Parameter: file descriptor */
656 if (remote_fileio_extract_int (&buf
, &target_fd
))
658 remote_fileio_ioerror ();
661 fd
= remote_fileio_map_fd ((int) target_fd
);
662 if (fd
== FIO_FD_INVALID
)
664 remote_fileio_badfd ();
667 /* 2. Parameter: buffer pointer */
668 if (remote_fileio_extract_long (&buf
, &lnum
))
670 remote_fileio_ioerror ();
673 ptrval
= (CORE_ADDR
) lnum
;
674 /* 3. Parameter: buffer length */
675 if (remote_fileio_extract_int (&buf
, &num
))
677 remote_fileio_ioerror ();
680 length
= (size_t) num
;
682 buffer
= (gdb_byte
*) xmalloc (length
);
683 if (target_read_memory (ptrval
, buffer
, length
) != 0)
686 remote_fileio_ioerror ();
690 remote_fio_no_longjmp
= 1;
693 case FIO_FD_CONSOLE_IN
:
694 remote_fileio_badfd ();
697 case FIO_FD_CONSOLE_OUT
:
698 ui_file_write (target_fd
== 1 ? gdb_stdtarg
: gdb_stdtargerr
,
699 (char *) buffer
, length
);
700 gdb_flush (target_fd
== 1 ? gdb_stdtarg
: gdb_stdtargerr
);
704 ret
= write (fd
, buffer
, length
);
705 if (ret
< 0 && errno
== EACCES
)
706 errno
= EBADF
; /* Cygwin returns EACCESS when writing to a
712 remote_fileio_return_errno (-1);
714 remote_fileio_return_success (ret
);
720 remote_fileio_func_lseek (char *buf
)
727 /* 1. Parameter: file descriptor */
728 if (remote_fileio_extract_int (&buf
, &num
))
730 remote_fileio_ioerror ();
733 fd
= remote_fileio_map_fd ((int) num
);
734 if (fd
== FIO_FD_INVALID
)
736 remote_fileio_badfd ();
739 else if (fd
== FIO_FD_CONSOLE_IN
|| fd
== FIO_FD_CONSOLE_OUT
)
741 remote_fileio_reply (-1, FILEIO_ESPIPE
);
745 /* 2. Parameter: offset */
746 if (remote_fileio_extract_long (&buf
, &lnum
))
748 remote_fileio_ioerror ();
751 offset
= (off_t
) lnum
;
752 /* 3. Parameter: flag */
753 if (remote_fileio_extract_int (&buf
, &num
))
755 remote_fileio_ioerror ();
758 if (remote_fileio_seek_flag_to_host (num
, &flag
))
760 remote_fileio_reply (-1, FILEIO_EINVAL
);
764 remote_fio_no_longjmp
= 1;
765 ret
= lseek (fd
, offset
, flag
);
767 if (ret
== (off_t
) -1)
768 remote_fileio_return_errno (-1);
770 remote_fileio_return_success (ret
);
774 remote_fileio_func_rename (char *buf
)
776 CORE_ADDR old_ptr
, new_ptr
;
777 int old_len
, new_len
;
778 char *oldpath
, *newpath
;
780 struct stat ost
, nst
;
782 /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
783 if (remote_fileio_extract_ptr_w_len (&buf
, &old_ptr
, &old_len
))
785 remote_fileio_ioerror ();
789 /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
790 if (remote_fileio_extract_ptr_w_len (&buf
, &new_ptr
, &new_len
))
792 remote_fileio_ioerror ();
796 /* Request oldpath using 'm' packet */
797 oldpath
= alloca (old_len
);
798 if (target_read_memory (old_ptr
, (gdb_byte
*) oldpath
, old_len
) != 0)
800 remote_fileio_ioerror ();
804 /* Request newpath using 'm' packet */
805 newpath
= alloca (new_len
);
806 if (target_read_memory (new_ptr
, (gdb_byte
*) newpath
, new_len
) != 0)
808 remote_fileio_ioerror ();
812 /* Only operate on regular files and directories. */
813 of
= stat (oldpath
, &ost
);
814 nf
= stat (newpath
, &nst
);
815 if ((!of
&& !S_ISREG (ost
.st_mode
) && !S_ISDIR (ost
.st_mode
))
816 || (!nf
&& !S_ISREG (nst
.st_mode
) && !S_ISDIR (nst
.st_mode
)))
818 remote_fileio_reply (-1, FILEIO_EACCES
);
822 remote_fio_no_longjmp
= 1;
823 ret
= rename (oldpath
, newpath
);
827 /* Special case: newpath is a non-empty directory. Some systems
828 return ENOTEMPTY, some return EEXIST. We coerce that to be
830 if (errno
== ENOTEMPTY
)
833 /* Workaround some Cygwin problems with correct errnos. */
836 if (!of
&& !nf
&& S_ISDIR (nst
.st_mode
))
838 if (S_ISREG (ost
.st_mode
))
842 char oldfullpath
[PATH_MAX
];
843 char newfullpath
[PATH_MAX
];
846 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, oldpath
, oldfullpath
,
848 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, newpath
, newfullpath
,
850 len
= strlen (oldfullpath
);
851 if (IS_DIR_SEPARATOR (newfullpath
[len
])
852 && !filename_ncmp (oldfullpath
, newfullpath
, len
))
861 remote_fileio_return_errno (-1);
864 remote_fileio_return_success (ret
);
868 remote_fileio_func_unlink (char *buf
)
876 /* Parameter: Ptr to pathname / length incl. trailing zero */
877 if (remote_fileio_extract_ptr_w_len (&buf
, &ptrval
, &length
))
879 remote_fileio_ioerror ();
882 /* Request pathname using 'm' packet */
883 pathname
= alloca (length
);
884 if (target_read_memory (ptrval
, (gdb_byte
*) pathname
, length
) != 0)
886 remote_fileio_ioerror ();
890 /* Only operate on regular files (and directories, which allows to return
891 the correct return code). */
892 if (!stat (pathname
, &st
) && !S_ISREG (st
.st_mode
) && !S_ISDIR (st
.st_mode
))
894 remote_fileio_reply (-1, FILEIO_ENODEV
);
898 remote_fio_no_longjmp
= 1;
899 ret
= unlink (pathname
);
902 remote_fileio_return_errno (-1);
904 remote_fileio_return_success (ret
);
908 remote_fileio_func_stat (char *buf
)
910 CORE_ADDR statptr
, nameptr
;
917 /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
918 if (remote_fileio_extract_ptr_w_len (&buf
, &nameptr
, &namelength
))
920 remote_fileio_ioerror ();
924 /* 2. Parameter: Ptr to struct stat */
925 if (remote_fileio_extract_long (&buf
, &lnum
))
927 remote_fileio_ioerror ();
930 statptr
= (CORE_ADDR
) lnum
;
932 /* Request pathname using 'm' packet */
933 pathname
= alloca (namelength
);
934 if (target_read_memory (nameptr
, (gdb_byte
*) pathname
, namelength
) != 0)
936 remote_fileio_ioerror ();
940 remote_fio_no_longjmp
= 1;
941 ret
= stat (pathname
, &st
);
945 remote_fileio_return_errno (-1);
948 /* Only operate on regular files and directories. */
949 if (!ret
&& !S_ISREG (st
.st_mode
) && !S_ISDIR (st
.st_mode
))
951 remote_fileio_reply (-1, FILEIO_EACCES
);
956 host_to_fileio_stat (&st
, &fst
);
957 host_to_fileio_uint (0, fst
.fst_dev
);
959 errno
= target_write_memory (statptr
, (gdb_byte
*) &fst
, sizeof fst
);
962 remote_fileio_return_errno (-1);
966 remote_fileio_return_success (ret
);
970 remote_fileio_func_fstat (char *buf
)
980 /* 1. Parameter: file descriptor */
981 if (remote_fileio_extract_int (&buf
, &target_fd
))
983 remote_fileio_ioerror ();
986 fd
= remote_fileio_map_fd ((int) target_fd
);
987 if (fd
== FIO_FD_INVALID
)
989 remote_fileio_badfd ();
992 /* 2. Parameter: Ptr to struct stat */
993 if (remote_fileio_extract_long (&buf
, &lnum
))
995 remote_fileio_ioerror ();
998 ptrval
= (CORE_ADDR
) lnum
;
1000 remote_fio_no_longjmp
= 1;
1001 if (fd
== FIO_FD_CONSOLE_IN
|| fd
== FIO_FD_CONSOLE_OUT
)
1003 host_to_fileio_uint (1, fst
.fst_dev
);
1004 memset (&st
, 0, sizeof (st
));
1005 st
.st_mode
= S_IFCHR
| (fd
== FIO_FD_CONSOLE_IN
? S_IRUSR
: S_IWUSR
);
1008 st
.st_uid
= getuid ();
1011 st
.st_gid
= getgid ();
1013 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1014 st
.st_blksize
= 512;
1016 #if HAVE_STRUCT_STAT_ST_BLOCKS
1019 if (!gettimeofday (&tv
, NULL
))
1020 st
.st_atime
= st
.st_mtime
= st
.st_ctime
= tv
.tv_sec
;
1022 st
.st_atime
= st
.st_mtime
= st
.st_ctime
= (time_t) 0;
1026 ret
= fstat (fd
, &st
);
1030 remote_fileio_return_errno (-1);
1035 host_to_fileio_stat (&st
, &fst
);
1037 errno
= target_write_memory (ptrval
, (gdb_byte
*) &fst
, sizeof fst
);
1040 remote_fileio_return_errno (-1);
1044 remote_fileio_return_success (ret
);
1048 remote_fileio_func_gettimeofday (char *buf
)
1054 struct fio_timeval ftv
;
1056 /* 1. Parameter: struct timeval pointer */
1057 if (remote_fileio_extract_long (&buf
, &lnum
))
1059 remote_fileio_ioerror ();
1062 ptrval
= (CORE_ADDR
) lnum
;
1063 /* 2. Parameter: some pointer value... */
1064 if (remote_fileio_extract_long (&buf
, &lnum
))
1066 remote_fileio_ioerror ();
1069 /* ...which has to be NULL. */
1072 remote_fileio_reply (-1, FILEIO_EINVAL
);
1076 remote_fio_no_longjmp
= 1;
1077 ret
= gettimeofday (&tv
, NULL
);
1081 remote_fileio_return_errno (-1);
1087 remote_fileio_to_fio_timeval (&tv
, &ftv
);
1089 errno
= target_write_memory (ptrval
, (gdb_byte
*) &ftv
, sizeof ftv
);
1092 remote_fileio_return_errno (-1);
1096 remote_fileio_return_success (ret
);
1100 remote_fileio_func_isatty (char *buf
)
1105 /* Parameter: file descriptor */
1106 if (remote_fileio_extract_int (&buf
, &target_fd
))
1108 remote_fileio_ioerror ();
1111 remote_fio_no_longjmp
= 1;
1112 fd
= remote_fileio_map_fd ((int) target_fd
);
1113 remote_fileio_return_success (fd
== FIO_FD_CONSOLE_IN
||
1114 fd
== FIO_FD_CONSOLE_OUT
? 1 : 0);
1118 remote_fileio_func_system (char *buf
)
1122 char *cmdline
= NULL
;
1124 /* Parameter: Ptr to commandline / length incl. trailing zero */
1125 if (remote_fileio_extract_ptr_w_len (&buf
, &ptrval
, &length
))
1127 remote_fileio_ioerror ();
1133 /* Request commandline using 'm' packet */
1134 cmdline
= alloca (length
);
1135 if (target_read_memory (ptrval
, (gdb_byte
*) cmdline
, length
) != 0)
1137 remote_fileio_ioerror ();
1142 /* Check if system(3) has been explicitely allowed using the
1143 `set remote system-call-allowed 1' command. If length is 0,
1144 indicating a NULL parameter to the system call, return zero to
1145 indicate a shell is not available. Otherwise fail with EPERM. */
1146 if (!remote_fio_system_call_allowed
)
1149 remote_fileio_return_success (0);
1151 remote_fileio_reply (-1, FILEIO_EPERM
);
1155 remote_fio_no_longjmp
= 1;
1156 ret
= system (cmdline
);
1159 remote_fileio_return_success (ret
);
1161 remote_fileio_return_errno (-1);
1163 remote_fileio_return_success (WEXITSTATUS (ret
));
1168 void (*func
)(char *);
1169 } remote_fio_func_map
[] = {
1170 { "open", remote_fileio_func_open
},
1171 { "close", remote_fileio_func_close
},
1172 { "read", remote_fileio_func_read
},
1173 { "write", remote_fileio_func_write
},
1174 { "lseek", remote_fileio_func_lseek
},
1175 { "rename", remote_fileio_func_rename
},
1176 { "unlink", remote_fileio_func_unlink
},
1177 { "stat", remote_fileio_func_stat
},
1178 { "fstat", remote_fileio_func_fstat
},
1179 { "gettimeofday", remote_fileio_func_gettimeofday
},
1180 { "isatty", remote_fileio_func_isatty
},
1181 { "system", remote_fileio_func_system
},
1186 do_remote_fileio_request (struct ui_out
*uiout
, void *buf_arg
)
1188 char *buf
= buf_arg
;
1192 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler
);
1194 c
= strchr (++buf
, ',');
1198 c
= strchr (buf
, '\0');
1199 for (idx
= 0; remote_fio_func_map
[idx
].name
; ++idx
)
1200 if (!strcmp (remote_fio_func_map
[idx
].name
, buf
))
1202 if (!remote_fio_func_map
[idx
].name
) /* ERROR: No such function. */
1203 return RETURN_ERROR
;
1204 remote_fio_func_map
[idx
].func (c
);
1208 /* Close any open descriptors, and reinitialize the file mapping. */
1211 remote_fileio_reset (void)
1215 for (ix
= 0; ix
!= remote_fio_data
.fd_map_size
; ix
++)
1217 int fd
= remote_fio_data
.fd_map
[ix
];
1222 if (remote_fio_data
.fd_map
)
1224 xfree (remote_fio_data
.fd_map
);
1225 remote_fio_data
.fd_map
= NULL
;
1226 remote_fio_data
.fd_map_size
= 0;
1230 /* Handle a file I/O request. BUF points to the packet containing the
1231 request. CTRLC_PENDING_P should be nonzero if the target has not
1232 acknowledged the Ctrl-C sent asynchronously earlier. */
1235 remote_fileio_request (char *buf
, int ctrlc_pending_p
)
1239 remote_fileio_sig_init ();
1241 if (ctrlc_pending_p
)
1243 /* If the target hasn't responded to the Ctrl-C sent
1244 asynchronously earlier, take this opportunity to send the
1245 Ctrl-C synchronously. */
1246 remote_fio_ctrl_c_flag
= 1;
1247 remote_fio_no_longjmp
= 0;
1248 remote_fileio_reply (-1, FILEIO_EINTR
);
1252 remote_fio_ctrl_c_flag
= 0;
1253 remote_fio_no_longjmp
= 0;
1255 ex
= catch_exceptions (current_uiout
,
1256 do_remote_fileio_request
, (void *)buf
,
1261 remote_fileio_reply (-1, FILEIO_ENOSYS
);
1264 remote_fileio_reply (-1, FILEIO_EINTR
);
1271 remote_fileio_sig_exit ();
1275 /* Unpack an fio_uint_t. */
1278 remote_fileio_to_host_uint (fio_uint_t fnum
)
1280 return extract_unsigned_integer ((gdb_byte
*) fnum
, 4,
1284 /* Unpack an fio_ulong_t. */
1287 remote_fileio_to_host_ulong (fio_ulong_t fnum
)
1289 return extract_unsigned_integer ((gdb_byte
*) fnum
, 8,
1293 /* Unpack an fio_mode_t. */
1296 remote_fileio_to_host_mode (fio_mode_t fnum
)
1298 return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum
),
1302 /* Unpack an fio_time_t. */
1305 remote_fileio_to_host_time (fio_time_t fnum
)
1307 return remote_fileio_to_host_uint (fnum
);
1311 /* See remote-fileio.h. */
1314 remote_fileio_to_host_stat (struct fio_stat
*fst
, struct stat
*st
)
1316 memset (st
, 0, sizeof (struct stat
));
1318 st
->st_dev
= remote_fileio_to_host_uint (fst
->fst_dev
);
1319 st
->st_ino
= remote_fileio_to_host_uint (fst
->fst_ino
);
1320 st
->st_mode
= remote_fileio_to_host_mode (fst
->fst_mode
);
1321 st
->st_nlink
= remote_fileio_to_host_uint (fst
->fst_nlink
);
1322 st
->st_uid
= remote_fileio_to_host_uint (fst
->fst_uid
);
1323 st
->st_gid
= remote_fileio_to_host_uint (fst
->fst_gid
);
1324 st
->st_rdev
= remote_fileio_to_host_uint (fst
->fst_rdev
);
1325 st
->st_size
= remote_fileio_to_host_ulong (fst
->fst_size
);
1326 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1327 st
->st_blksize
= remote_fileio_to_host_ulong (fst
->fst_blksize
);
1329 #if HAVE_STRUCT_STAT_ST_BLOCKS
1330 st
->st_blocks
= remote_fileio_to_host_ulong (fst
->fst_blocks
);
1332 st
->st_atime
= remote_fileio_to_host_time (fst
->fst_atime
);
1333 st
->st_mtime
= remote_fileio_to_host_time (fst
->fst_mtime
);
1334 st
->st_ctime
= remote_fileio_to_host_time (fst
->fst_ctime
);
1339 set_system_call_allowed (char *args
, int from_tty
)
1344 int val
= strtoul (args
, &arg_end
, 10);
1346 if (*args
&& *arg_end
== '\0')
1348 remote_fio_system_call_allowed
= !!val
;
1352 error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1356 show_system_call_allowed (char *args
, int from_tty
)
1359 error (_("Garbage after \"show remote "
1360 "system-call-allowed\" command: `%s'"), args
);
1361 printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1362 remote_fio_system_call_allowed
? "" : "not ");
1366 initialize_remote_fileio (struct cmd_list_element
*remote_set_cmdlist
,
1367 struct cmd_list_element
*remote_show_cmdlist
)
1369 sigint_fileio_token
=
1370 create_async_signal_handler (async_remote_fileio_interrupt
, NULL
);
1372 add_cmd ("system-call-allowed", no_class
,
1373 set_system_call_allowed
,
1374 _("Set if the host system(3) call is allowed for the target."),
1375 &remote_set_cmdlist
);
1376 add_cmd ("system-call-allowed", no_class
,
1377 show_system_call_allowed
,
1378 _("Show if the host system(3) call is allowed for the target."),
1379 &remote_show_cmdlist
);