Automatic date update in version.in
[binutils-gdb.git] / gdb / remote-fileio.c
blobb15824637a947ccd1a1e281ebbcf5b9d2138b420
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"
25 #include "remote.h"
26 #include "gdbsupport/gdb_wait.h"
27 #include <sys/stat.h>
28 #include "remote-fileio.h"
29 #include "gdbsupport/event-loop.h"
30 #include "target.h"
31 #include "filenames.h"
32 #include "gdbsupport/filestuff.h"
34 #include <fcntl.h>
35 #include "gdbsupport/gdb_sys_time.h"
36 #ifdef __CYGWIN__
37 #include <sys/cygwin.h>
38 #endif
39 #include <signal.h>
41 static struct {
42 int *fd_map;
43 int fd_map_size;
44 } remote_fio_data;
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;
52 static int
53 remote_fileio_init_fd_map (void)
55 int i;
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;
67 return 3;
70 static int
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;
86 static int
87 remote_fileio_next_free_fd (void)
89 int i;
91 for (i = 0; i < remote_fio_data.fd_map_size; ++i)
92 if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
93 return i;
94 return remote_fileio_resize_fd_map ();
97 static int
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;
103 return target_fd;
106 static int
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];
115 static void
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;
123 static int
124 remote_fileio_oflags_to_host (long flags)
126 int hflags = 0;
128 if (flags & FILEIO_O_CREAT)
129 hflags |= O_CREAT;
130 if (flags & FILEIO_O_EXCL)
131 hflags |= O_EXCL;
132 if (flags & FILEIO_O_TRUNC)
133 hflags |= O_TRUNC;
134 if (flags & FILEIO_O_APPEND)
135 hflags |= O_APPEND;
136 if (flags & FILEIO_O_RDONLY)
137 hflags |= O_RDONLY;
138 if (flags & FILEIO_O_WRONLY)
139 hflags |= O_WRONLY;
140 if (flags & FILEIO_O_RDWR)
141 hflags |= O_RDWR;
142 /* On systems supporting binary and text mode, always open files in
143 binary mode. */
144 #ifdef O_BINARY
145 hflags |= O_BINARY;
146 #endif
147 return hflags;
150 static mode_t
151 remote_fileio_mode_to_host (long mode, int open_call)
153 mode_t hmode = 0;
155 if (!open_call)
157 if (mode & FILEIO_S_IFREG)
158 hmode |= S_IFREG;
159 if (mode & FILEIO_S_IFDIR)
160 hmode |= S_IFDIR;
161 if (mode & FILEIO_S_IFCHR)
162 hmode |= S_IFCHR;
164 if (mode & FILEIO_S_IRUSR)
165 hmode |= S_IRUSR;
166 if (mode & FILEIO_S_IWUSR)
167 hmode |= S_IWUSR;
168 if (mode & FILEIO_S_IXUSR)
169 hmode |= S_IXUSR;
170 #ifdef S_IRGRP
171 if (mode & FILEIO_S_IRGRP)
172 hmode |= S_IRGRP;
173 #endif
174 #ifdef S_IWGRP
175 if (mode & FILEIO_S_IWGRP)
176 hmode |= S_IWGRP;
177 #endif
178 #ifdef S_IXGRP
179 if (mode & FILEIO_S_IXGRP)
180 hmode |= S_IXGRP;
181 #endif
182 if (mode & FILEIO_S_IROTH)
183 hmode |= S_IROTH;
184 #ifdef S_IWOTH
185 if (mode & FILEIO_S_IWOTH)
186 hmode |= S_IWOTH;
187 #endif
188 #ifdef S_IXOTH
189 if (mode & FILEIO_S_IXOTH)
190 hmode |= S_IXOTH;
191 #endif
192 return hmode;
195 static int
196 remote_fileio_seek_flag_to_host (long num, int *flag)
198 if (!flag)
199 return 0;
200 switch (num)
202 case FILEIO_SEEK_SET:
203 *flag = SEEK_SET;
204 break;
205 case FILEIO_SEEK_CUR:
206 *flag = SEEK_CUR;
207 break;
208 case FILEIO_SEEK_END:
209 *flag = SEEK_END;
210 break;
211 default:
212 return -1;
214 return 0;
217 static int
218 remote_fileio_extract_long (char **buf, LONGEST *retlong)
220 char *c;
221 int sign = 1;
223 if (!buf || !*buf || !**buf || !retlong)
224 return -1;
225 c = strchr (*buf, ',');
226 if (c)
227 *c++ = '\0';
228 else
229 c = strchr (*buf, '\0');
230 while (strchr ("+-", **buf))
232 if (**buf == '-')
233 sign = -sign;
234 ++*buf;
236 for (*retlong = 0; **buf; ++*buf)
238 *retlong <<= 4;
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;
245 else
246 return -1;
248 *retlong *= sign;
249 *buf = c;
250 return 0;
253 static int
254 remote_fileio_extract_int (char **buf, long *retint)
256 int ret;
257 LONGEST retlong;
259 if (!retint)
260 return -1;
261 ret = remote_fileio_extract_long (buf, &retlong);
262 if (!ret)
263 *retint = (long) retlong;
264 return ret;
267 static int
268 remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
270 char *c;
271 LONGEST retlong;
273 if (!buf || !*buf || !**buf || !ptrval || !length)
274 return -1;
275 c = strchr (*buf, '/');
276 if (!c)
277 return -1;
278 *c++ = '\0';
279 if (remote_fileio_extract_long (buf, &retlong))
280 return -1;
281 *ptrval = (CORE_ADDR) retlong;
282 *buf = c;
283 if (remote_fileio_extract_long (buf, &retlong))
284 return -1;
285 *length = (int) retlong;
286 return 0;
289 static void
290 remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
292 host_to_bigendian (num, (char *) fnum, 8);
295 static void
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. */
309 static void
310 remote_fileio_quit_handler (void)
312 if (check_quit_flag ())
313 quit ();
316 static void
317 remote_fileio_reply (remote_target *remote, int retcode, int error)
319 char buf[32];
320 bool ctrl_c = check_quit_flag ();
322 strcpy (buf, "F");
323 if (retcode < 0)
325 strcat (buf, "-");
326 retcode = -retcode;
328 sprintf (buf + strlen (buf), "%x", retcode);
329 if (error || ctrl_c)
331 if (error && ctrl_c)
332 error = FILEIO_EINTR;
333 if (error < 0)
335 strcat (buf, "-");
336 error = -error;
338 sprintf (buf + strlen (buf), ",%x", error);
339 if (ctrl_c)
340 strcat (buf, ",C");
342 quit_handler = remote_fileio_o_quit_handler;
343 putpkt (remote, buf);
346 static void
347 remote_fileio_ioerror (remote_target *remote)
349 remote_fileio_reply (remote, -1, FILEIO_EIO);
352 static void
353 remote_fileio_badfd (remote_target *remote)
355 remote_fileio_reply (remote, -1, FILEIO_EBADF);
358 static void
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);
365 static void
366 remote_fileio_return_success (remote_target *remote, int retcode)
368 remote_fileio_reply (remote, retcode, 0);
371 static void
372 remote_fileio_func_open (remote_target *remote, char *buf)
374 CORE_ADDR ptrval;
375 int length;
376 long num;
377 int flags, fd;
378 mode_t mode;
379 char *pathname;
380 struct stat st;
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);
386 return;
388 /* 2. Parameter: open flags */
389 if (remote_fileio_extract_int (&buf, &num))
391 remote_fileio_ioerror (remote);
392 return;
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);
399 return;
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);
408 return;
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
413 for writing. */
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);
419 return;
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);
425 return;
429 fd = gdb_open_cloexec (pathname, flags, mode).release ();
430 if (fd < 0)
432 remote_fileio_return_errno (remote, -1);
433 return;
436 fd = remote_fileio_fd_to_targetfd (fd);
437 remote_fileio_return_success (remote, fd);
440 static void
441 remote_fileio_func_close (remote_target *remote, char *buf)
443 long num;
444 int fd;
446 /* Parameter: file descriptor */
447 if (remote_fileio_extract_int (&buf, &num))
449 remote_fileio_ioerror (remote);
450 return;
452 fd = remote_fileio_map_fd ((int) num);
453 if (fd == FIO_FD_INVALID)
455 remote_fileio_badfd (remote);
456 return;
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);
465 static void
466 remote_fileio_func_read (remote_target *remote, char *buf)
468 long target_fd, num;
469 LONGEST lnum;
470 CORE_ADDR ptrval;
471 int fd, ret;
472 gdb_byte *buffer;
473 size_t length;
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);
480 return;
482 fd = remote_fileio_map_fd ((int) target_fd);
483 if (fd == FIO_FD_INVALID)
485 remote_fileio_badfd (remote);
486 return;
488 /* 2. Parameter: buffer pointer */
489 if (remote_fileio_extract_long (&buf, &lnum))
491 remote_fileio_ioerror (remote);
492 return;
494 ptrval = (CORE_ADDR) lnum;
495 /* 3. Parameter: buffer length */
496 if (remote_fileio_extract_int (&buf, &num))
498 remote_fileio_ioerror (remote);
499 return;
501 length = (size_t) num;
503 switch (fd)
505 case FIO_FD_CONSOLE_OUT:
506 remote_fileio_badfd (remote);
507 return;
508 case FIO_FD_CONSOLE_IN:
510 static char *remaining_buf = NULL;
511 static int remaining_length = 0;
513 buffer = (gdb_byte *) xmalloc (16384);
514 if (remaining_buf)
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;
522 ret = length;
524 else
526 memcpy (buffer, remaining_buf, remaining_length);
527 xfree (remaining_buf);
528 remaining_buf = NULL;
529 ret = remaining_length;
532 else
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);
551 ret = length;
555 break;
556 default:
557 buffer = (gdb_byte *) xmalloc (length);
558 /* POSIX defines EINTR behaviour 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;
573 break;
576 if (ret > 0)
578 errno = target_write_memory (ptrval, buffer, ret);
579 if (errno != 0)
580 ret = -1;
583 if (ret < 0)
584 remote_fileio_return_errno (remote, -1);
585 else
586 remote_fileio_return_success (remote, ret);
588 xfree (buffer);
591 static void
592 remote_fileio_func_write (remote_target *remote, char *buf)
594 long target_fd, num;
595 LONGEST lnum;
596 CORE_ADDR ptrval;
597 int fd, ret;
598 gdb_byte *buffer;
599 size_t length;
601 /* 1. Parameter: file descriptor */
602 if (remote_fileio_extract_int (&buf, &target_fd))
604 remote_fileio_ioerror (remote);
605 return;
607 fd = remote_fileio_map_fd ((int) target_fd);
608 if (fd == FIO_FD_INVALID)
610 remote_fileio_badfd (remote);
611 return;
613 /* 2. Parameter: buffer pointer */
614 if (remote_fileio_extract_long (&buf, &lnum))
616 remote_fileio_ioerror (remote);
617 return;
619 ptrval = (CORE_ADDR) lnum;
620 /* 3. Parameter: buffer length */
621 if (remote_fileio_extract_int (&buf, &num))
623 remote_fileio_ioerror (remote);
624 return;
626 length = (size_t) num;
628 buffer = (gdb_byte *) xmalloc (length);
629 if (target_read_memory (ptrval, buffer, length) != 0)
631 xfree (buffer);
632 remote_fileio_ioerror (remote);
633 return;
636 switch (fd)
638 case FIO_FD_CONSOLE_IN:
639 remote_fileio_badfd (remote);
640 xfree (buffer);
641 return;
642 case FIO_FD_CONSOLE_OUT:
644 ui_file *file = target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr;
645 file->write ((char *) buffer, length);
646 file->flush ();
647 ret = length;
649 break;
650 default:
651 ret = write (fd, buffer, length);
652 if (ret < 0 && errno == EACCES)
653 errno = EBADF; /* Cygwin returns EACCESS when writing to a
654 R/O file. */
655 break;
658 if (ret < 0)
659 remote_fileio_return_errno (remote, -1);
660 else
661 remote_fileio_return_success (remote, ret);
663 xfree (buffer);
666 static void
667 remote_fileio_func_lseek (remote_target *remote, char *buf)
669 long num;
670 LONGEST lnum;
671 int fd, flag;
672 off_t offset, ret;
674 /* 1. Parameter: file descriptor */
675 if (remote_fileio_extract_int (&buf, &num))
677 remote_fileio_ioerror (remote);
678 return;
680 fd = remote_fileio_map_fd ((int) num);
681 if (fd == FIO_FD_INVALID)
683 remote_fileio_badfd (remote);
684 return;
686 else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
688 remote_fileio_reply (remote, -1, FILEIO_ESPIPE);
689 return;
692 /* 2. Parameter: offset */
693 if (remote_fileio_extract_long (&buf, &lnum))
695 remote_fileio_ioerror (remote);
696 return;
698 offset = (off_t) lnum;
699 /* 3. Parameter: flag */
700 if (remote_fileio_extract_int (&buf, &num))
702 remote_fileio_ioerror (remote);
703 return;
705 if (remote_fileio_seek_flag_to_host (num, &flag))
707 remote_fileio_reply (remote, -1, FILEIO_EINVAL);
708 return;
711 ret = lseek (fd, offset, flag);
713 if (ret == (off_t) -1)
714 remote_fileio_return_errno (remote, -1);
715 else
716 remote_fileio_return_success (remote, ret);
719 static void
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;
725 int ret, of, nf;
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);
732 return;
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);
739 return;
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);
747 return;
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);
755 return;
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);
765 return;
768 ret = rename (oldpath, newpath);
770 if (ret == -1)
772 /* Special case: newpath is a non-empty directory. Some systems
773 return ENOTEMPTY, some return EEXIST. We coerce that to be
774 always EEXIST. */
775 if (errno == ENOTEMPTY)
776 errno = EEXIST;
777 #ifdef __CYGWIN__
778 /* Workaround some Cygwin problems with correct errnos. */
779 if (errno == EACCES)
781 if (!of && !nf && S_ISDIR (nst.st_mode))
783 if (S_ISREG (ost.st_mode))
784 errno = EISDIR;
785 else
787 char oldfullpath[PATH_MAX];
788 char newfullpath[PATH_MAX];
789 int len;
791 cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
792 PATH_MAX);
793 cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
794 PATH_MAX);
795 len = strlen (oldfullpath);
796 if (IS_DIR_SEPARATOR (newfullpath[len])
797 && !filename_ncmp (oldfullpath, newfullpath, len))
798 errno = EINVAL;
799 else
800 errno = EEXIST;
804 #endif
806 remote_fileio_return_errno (remote, -1);
808 else
809 remote_fileio_return_success (remote, ret);
812 static void
813 remote_fileio_func_unlink (remote_target *remote, char *buf)
815 CORE_ADDR ptrval;
816 int length;
817 char *pathname;
818 int ret;
819 struct stat st;
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);
825 return;
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);
832 return;
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);
840 return;
843 ret = unlink (pathname);
845 if (ret == -1)
846 remote_fileio_return_errno (remote, -1);
847 else
848 remote_fileio_return_success (remote, ret);
851 static void
852 remote_fileio_func_stat (remote_target *remote, char *buf)
854 CORE_ADDR statptr, nameptr;
855 int ret, namelength;
856 char *pathname;
857 LONGEST lnum;
858 struct stat st;
859 struct fio_stat fst;
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);
865 return;
868 /* 2. Parameter: Ptr to struct stat */
869 if (remote_fileio_extract_long (&buf, &lnum))
871 remote_fileio_ioerror (remote);
872 return;
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);
881 return;
884 ret = stat (pathname, &st);
886 if (ret == -1)
888 remote_fileio_return_errno (remote, -1);
889 return;
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);
895 return;
897 if (statptr)
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);
903 if (errno != 0)
905 remote_fileio_return_errno (remote, -1);
906 return;
909 remote_fileio_return_success (remote, ret);
912 static void
913 remote_fileio_func_fstat (remote_target *remote, char *buf)
915 CORE_ADDR ptrval;
916 int fd, ret;
917 long target_fd;
918 LONGEST lnum;
919 struct stat st;
920 struct fio_stat fst;
921 struct timeval tv;
923 /* 1. Parameter: file descriptor */
924 if (remote_fileio_extract_int (&buf, &target_fd))
926 remote_fileio_ioerror (remote);
927 return;
929 fd = remote_fileio_map_fd ((int) target_fd);
930 if (fd == FIO_FD_INVALID)
932 remote_fileio_badfd (remote);
933 return;
935 /* 2. Parameter: Ptr to struct stat */
936 if (remote_fileio_extract_long (&buf, &lnum))
938 remote_fileio_ioerror (remote);
939 return;
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);
948 st.st_nlink = 1;
949 #ifdef HAVE_GETUID
950 st.st_uid = getuid ();
951 #endif
952 #ifdef HAVE_GETGID
953 st.st_gid = getgid ();
954 #endif
955 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
956 st.st_blksize = 512;
957 #endif
958 #if HAVE_STRUCT_STAT_ST_BLOCKS
959 st.st_blocks = 0;
960 #endif
961 if (!gettimeofday (&tv, NULL))
962 st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
963 else
964 st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
965 ret = 0;
967 else
968 ret = fstat (fd, &st);
970 if (ret == -1)
972 remote_fileio_return_errno (remote, -1);
973 return;
975 if (ptrval)
977 host_to_fileio_stat (&st, &fst);
979 errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
980 if (errno != 0)
982 remote_fileio_return_errno (remote, -1);
983 return;
986 remote_fileio_return_success (remote, ret);
989 static void
990 remote_fileio_func_gettimeofday (remote_target *remote, char *buf)
992 LONGEST lnum;
993 CORE_ADDR ptrval;
994 int ret;
995 struct timeval tv;
996 struct fio_timeval ftv;
998 /* 1. Parameter: struct timeval pointer */
999 if (remote_fileio_extract_long (&buf, &lnum))
1001 remote_fileio_ioerror (remote);
1002 return;
1004 ptrval = (CORE_ADDR) lnum;
1005 /* 2. Parameter: some pointer value... */
1006 if (remote_fileio_extract_long (&buf, &lnum))
1008 remote_fileio_ioerror (remote);
1009 return;
1011 /* ...which has to be NULL. */
1012 if (lnum)
1014 remote_fileio_reply (remote, -1, FILEIO_EINVAL);
1015 return;
1018 ret = gettimeofday (&tv, NULL);
1020 if (ret == -1)
1022 remote_fileio_return_errno (remote, -1);
1023 return;
1026 if (ptrval)
1028 remote_fileio_to_fio_timeval (&tv, &ftv);
1030 errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1031 if (errno != 0)
1033 remote_fileio_return_errno (remote, -1);
1034 return;
1037 remote_fileio_return_success (remote, ret);
1040 static void
1041 remote_fileio_func_isatty (remote_target *remote, char *buf)
1043 long target_fd;
1044 int fd;
1046 /* Parameter: file descriptor */
1047 if (remote_fileio_extract_int (&buf, &target_fd))
1049 remote_fileio_ioerror (remote);
1050 return;
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);
1057 static void
1058 remote_fileio_func_system (remote_target *remote, char *buf)
1060 CORE_ADDR ptrval;
1061 int ret, length;
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);
1068 return;
1071 if (length)
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);
1078 return;
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)
1088 if (!length)
1089 remote_fileio_return_success (remote, 0);
1090 else
1091 remote_fileio_reply (remote, -1, FILEIO_EPERM);
1092 return;
1095 ret = system (cmdline);
1097 if (!length)
1098 remote_fileio_return_success (remote, ret);
1099 else if (ret == -1)
1100 remote_fileio_return_errno (remote, -1);
1101 else
1102 remote_fileio_return_success (remote, WEXITSTATUS (ret));
1105 static struct {
1106 const char *name;
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 },
1121 { NULL, NULL }
1124 static void
1125 do_remote_fileio_request (remote_target *remote, char *buf)
1127 char *c;
1128 int idx;
1130 quit_handler = remote_fileio_quit_handler;
1132 c = strchr (++buf, ',');
1133 if (c)
1134 *c++ = '\0';
1135 else
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))
1139 break;
1140 if (!remote_fio_func_map[idx].name)
1141 remote_fileio_reply (remote, -1, FILEIO_ENOSYS);
1142 else
1143 remote_fio_func_map[idx].func (remote, c);
1146 /* Close any open descriptors, and reinitialize the file mapping. */
1148 void
1149 remote_fileio_reset (void)
1151 int ix;
1153 for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1155 int fd = remote_fio_data.fd_map[ix];
1157 if (fd >= 0)
1158 close (fd);
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. */
1172 void
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. */
1186 set_quit_flag ();
1187 remote_fileio_reply (remote, -1, FILEIO_EINTR);
1189 else
1193 do_remote_fileio_request (remote, buf);
1195 catch (const gdb_exception_forced_quit &ex)
1197 throw;
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. */
1215 static unsigned int
1216 remote_fileio_to_host_uint (fio_uint_t fnum)
1218 return extract_unsigned_integer ((gdb_byte *) fnum, 4,
1219 BFD_ENDIAN_BIG);
1222 /* Unpack an fio_ulong_t. */
1224 static ULONGEST
1225 remote_fileio_to_host_ulong (fio_ulong_t fnum)
1227 return extract_unsigned_integer ((gdb_byte *) fnum, 8,
1228 BFD_ENDIAN_BIG);
1231 /* Unpack an fio_mode_t. */
1233 static 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. */
1242 static 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. */
1251 void
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);
1266 #endif
1267 #if HAVE_STRUCT_STAT_ST_BLOCKS
1268 st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
1269 #endif
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);
1276 static void
1277 set_system_call_allowed (const char *args, int from_tty)
1279 if (args)
1281 char *arg_end;
1282 int val = strtoul (args, &arg_end, 10);
1284 if (*args && *arg_end == '\0')
1286 remote_fio_system_call_allowed = !!val;
1287 return;
1290 error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1293 static void
1294 show_system_call_allowed (const char *args, int from_tty)
1296 if (args)
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 ");
1303 void
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);