Automatic date update in version.in
[binutils-gdb.git] / gdb / remote-fileio.c
blobeaa0d8f619a6986334211ba2f899e807cf685971
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 "gdbcmd.h"
23 #include "remote.h"
24 #include "gdbsupport/gdb_wait.h"
25 #include <sys/stat.h>
26 #include "remote-fileio.h"
27 #include "gdbsupport/event-loop.h"
28 #include "target.h"
29 #include "filenames.h"
30 #include "gdbsupport/filestuff.h"
32 #include <fcntl.h>
33 #include "gdbsupport/gdb_sys_time.h"
34 #ifdef __CYGWIN__
35 #include <sys/cygwin.h>
36 #endif
37 #include <signal.h>
39 static struct {
40 int *fd_map;
41 int fd_map_size;
42 } remote_fio_data;
44 #define FIO_FD_INVALID -1
45 #define FIO_FD_CONSOLE_IN -2
46 #define FIO_FD_CONSOLE_OUT -3
48 static int remote_fio_system_call_allowed = 0;
50 static int
51 remote_fileio_init_fd_map (void)
53 int i;
55 if (!remote_fio_data.fd_map)
57 remote_fio_data.fd_map = XNEWVEC (int, 10);
58 remote_fio_data.fd_map_size = 10;
59 remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
60 remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
61 remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
62 for (i = 3; i < 10; ++i)
63 remote_fio_data.fd_map[i] = FIO_FD_INVALID;
65 return 3;
68 static int
69 remote_fileio_resize_fd_map (void)
71 int i = remote_fio_data.fd_map_size;
73 if (!remote_fio_data.fd_map)
74 return remote_fileio_init_fd_map ();
75 remote_fio_data.fd_map_size += 10;
76 remote_fio_data.fd_map =
77 (int *) xrealloc (remote_fio_data.fd_map,
78 remote_fio_data.fd_map_size * sizeof (int));
79 for (; i < remote_fio_data.fd_map_size; i++)
80 remote_fio_data.fd_map[i] = FIO_FD_INVALID;
81 return remote_fio_data.fd_map_size - 10;
84 static int
85 remote_fileio_next_free_fd (void)
87 int i;
89 for (i = 0; i < remote_fio_data.fd_map_size; ++i)
90 if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
91 return i;
92 return remote_fileio_resize_fd_map ();
95 static int
96 remote_fileio_fd_to_targetfd (int fd)
98 int target_fd = remote_fileio_next_free_fd ();
100 remote_fio_data.fd_map[target_fd] = fd;
101 return target_fd;
104 static int
105 remote_fileio_map_fd (int target_fd)
107 remote_fileio_init_fd_map ();
108 if (target_fd < 0 || target_fd >= remote_fio_data.fd_map_size)
109 return FIO_FD_INVALID;
110 return remote_fio_data.fd_map[target_fd];
113 static void
114 remote_fileio_close_target_fd (int target_fd)
116 remote_fileio_init_fd_map ();
117 if (target_fd >= 0 && target_fd < remote_fio_data.fd_map_size)
118 remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID;
121 static int
122 remote_fileio_oflags_to_host (long flags)
124 int hflags = 0;
126 if (flags & FILEIO_O_CREAT)
127 hflags |= O_CREAT;
128 if (flags & FILEIO_O_EXCL)
129 hflags |= O_EXCL;
130 if (flags & FILEIO_O_TRUNC)
131 hflags |= O_TRUNC;
132 if (flags & FILEIO_O_APPEND)
133 hflags |= O_APPEND;
134 if (flags & FILEIO_O_RDONLY)
135 hflags |= O_RDONLY;
136 if (flags & FILEIO_O_WRONLY)
137 hflags |= O_WRONLY;
138 if (flags & FILEIO_O_RDWR)
139 hflags |= O_RDWR;
140 /* On systems supporting binary and text mode, always open files in
141 binary mode. */
142 #ifdef O_BINARY
143 hflags |= O_BINARY;
144 #endif
145 return hflags;
148 static mode_t
149 remote_fileio_mode_to_host (long mode, int open_call)
151 mode_t hmode = 0;
153 if (!open_call)
155 if (mode & FILEIO_S_IFREG)
156 hmode |= S_IFREG;
157 if (mode & FILEIO_S_IFDIR)
158 hmode |= S_IFDIR;
159 if (mode & FILEIO_S_IFCHR)
160 hmode |= S_IFCHR;
162 if (mode & FILEIO_S_IRUSR)
163 hmode |= S_IRUSR;
164 if (mode & FILEIO_S_IWUSR)
165 hmode |= S_IWUSR;
166 if (mode & FILEIO_S_IXUSR)
167 hmode |= S_IXUSR;
168 #ifdef S_IRGRP
169 if (mode & FILEIO_S_IRGRP)
170 hmode |= S_IRGRP;
171 #endif
172 #ifdef S_IWGRP
173 if (mode & FILEIO_S_IWGRP)
174 hmode |= S_IWGRP;
175 #endif
176 #ifdef S_IXGRP
177 if (mode & FILEIO_S_IXGRP)
178 hmode |= S_IXGRP;
179 #endif
180 if (mode & FILEIO_S_IROTH)
181 hmode |= S_IROTH;
182 #ifdef S_IWOTH
183 if (mode & FILEIO_S_IWOTH)
184 hmode |= S_IWOTH;
185 #endif
186 #ifdef S_IXOTH
187 if (mode & FILEIO_S_IXOTH)
188 hmode |= S_IXOTH;
189 #endif
190 return hmode;
193 static int
194 remote_fileio_seek_flag_to_host (long num, int *flag)
196 if (!flag)
197 return 0;
198 switch (num)
200 case FILEIO_SEEK_SET:
201 *flag = SEEK_SET;
202 break;
203 case FILEIO_SEEK_CUR:
204 *flag = SEEK_CUR;
205 break;
206 case FILEIO_SEEK_END:
207 *flag = SEEK_END;
208 break;
209 default:
210 return -1;
212 return 0;
215 static int
216 remote_fileio_extract_long (char **buf, LONGEST *retlong)
218 char *c;
219 int sign = 1;
221 if (!buf || !*buf || !**buf || !retlong)
222 return -1;
223 c = strchr (*buf, ',');
224 if (c)
225 *c++ = '\0';
226 else
227 c = strchr (*buf, '\0');
228 while (strchr ("+-", **buf))
230 if (**buf == '-')
231 sign = -sign;
232 ++*buf;
234 for (*retlong = 0; **buf; ++*buf)
236 *retlong <<= 4;
237 if (**buf >= '0' && **buf <= '9')
238 *retlong += **buf - '0';
239 else if (**buf >= 'a' && **buf <= 'f')
240 *retlong += **buf - 'a' + 10;
241 else if (**buf >= 'A' && **buf <= 'F')
242 *retlong += **buf - 'A' + 10;
243 else
244 return -1;
246 *retlong *= sign;
247 *buf = c;
248 return 0;
251 static int
252 remote_fileio_extract_int (char **buf, long *retint)
254 int ret;
255 LONGEST retlong;
257 if (!retint)
258 return -1;
259 ret = remote_fileio_extract_long (buf, &retlong);
260 if (!ret)
261 *retint = (long) retlong;
262 return ret;
265 static int
266 remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
268 char *c;
269 LONGEST retlong;
271 if (!buf || !*buf || !**buf || !ptrval || !length)
272 return -1;
273 c = strchr (*buf, '/');
274 if (!c)
275 return -1;
276 *c++ = '\0';
277 if (remote_fileio_extract_long (buf, &retlong))
278 return -1;
279 *ptrval = (CORE_ADDR) retlong;
280 *buf = c;
281 if (remote_fileio_extract_long (buf, &retlong))
282 return -1;
283 *length = (int) retlong;
284 return 0;
287 static void
288 remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
290 host_to_bigendian (num, (char *) fnum, 8);
293 static void
294 remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
296 host_to_fileio_time (tv->tv_sec, ftv->ftv_sec);
297 remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
300 /* The quit handler originally installed. */
301 static quit_handler_ftype *remote_fileio_o_quit_handler;
303 /* What to do on a QUIT call while handling a file I/O request. We
304 throw a quit exception, which is caught by remote_fileio_request
305 and translated to an EINTR reply back to the target. */
307 static void
308 remote_fileio_quit_handler (void)
310 if (check_quit_flag ())
311 quit ();
314 static void
315 remote_fileio_reply (remote_target *remote, int retcode, int error)
317 char buf[32];
318 int ctrl_c = check_quit_flag ();
320 strcpy (buf, "F");
321 if (retcode < 0)
323 strcat (buf, "-");
324 retcode = -retcode;
326 sprintf (buf + strlen (buf), "%x", retcode);
327 if (error || ctrl_c)
329 if (error && ctrl_c)
330 error = FILEIO_EINTR;
331 if (error < 0)
333 strcat (buf, "-");
334 error = -error;
336 sprintf (buf + strlen (buf), ",%x", error);
337 if (ctrl_c)
338 strcat (buf, ",C");
340 quit_handler = remote_fileio_o_quit_handler;
341 putpkt (remote, buf);
344 static void
345 remote_fileio_ioerror (remote_target *remote)
347 remote_fileio_reply (remote, -1, FILEIO_EIO);
350 static void
351 remote_fileio_badfd (remote_target *remote)
353 remote_fileio_reply (remote, -1, FILEIO_EBADF);
356 static void
357 remote_fileio_return_errno (remote_target *remote, int retcode)
359 remote_fileio_reply (remote, retcode, retcode < 0
360 ? host_to_fileio_error (errno) : 0);
363 static void
364 remote_fileio_return_success (remote_target *remote, int retcode)
366 remote_fileio_reply (remote, retcode, 0);
369 static void
370 remote_fileio_func_open (remote_target *remote, char *buf)
372 CORE_ADDR ptrval;
373 int length;
374 long num;
375 int flags, fd;
376 mode_t mode;
377 char *pathname;
378 struct stat st;
380 /* 1. Parameter: Ptr to pathname / length incl. trailing zero. */
381 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
383 remote_fileio_ioerror (remote);
384 return;
386 /* 2. Parameter: open flags */
387 if (remote_fileio_extract_int (&buf, &num))
389 remote_fileio_ioerror (remote);
390 return;
392 flags = remote_fileio_oflags_to_host (num);
393 /* 3. Parameter: open mode */
394 if (remote_fileio_extract_int (&buf, &num))
396 remote_fileio_ioerror (remote);
397 return;
399 mode = remote_fileio_mode_to_host (num, 1);
401 /* Request pathname. */
402 pathname = (char *) alloca (length);
403 if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
405 remote_fileio_ioerror (remote);
406 return;
409 /* Check if pathname exists and is not a regular file or directory. If so,
410 return an appropriate error code. Same for trying to open directories
411 for writing. */
412 if (!stat (pathname, &st))
414 if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
416 remote_fileio_reply (remote, -1, FILEIO_ENODEV);
417 return;
419 if (S_ISDIR (st.st_mode)
420 && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
422 remote_fileio_reply (remote, -1, FILEIO_EISDIR);
423 return;
427 fd = gdb_open_cloexec (pathname, flags, mode).release ();
428 if (fd < 0)
430 remote_fileio_return_errno (remote, -1);
431 return;
434 fd = remote_fileio_fd_to_targetfd (fd);
435 remote_fileio_return_success (remote, fd);
438 static void
439 remote_fileio_func_close (remote_target *remote, char *buf)
441 long num;
442 int fd;
444 /* Parameter: file descriptor */
445 if (remote_fileio_extract_int (&buf, &num))
447 remote_fileio_ioerror (remote);
448 return;
450 fd = remote_fileio_map_fd ((int) num);
451 if (fd == FIO_FD_INVALID)
453 remote_fileio_badfd (remote);
454 return;
457 if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
458 remote_fileio_return_errno (remote, -1);
459 remote_fileio_close_target_fd ((int) num);
460 remote_fileio_return_success (remote, 0);
463 static void
464 remote_fileio_func_read (remote_target *remote, char *buf)
466 long target_fd, num;
467 LONGEST lnum;
468 CORE_ADDR ptrval;
469 int fd, ret;
470 gdb_byte *buffer;
471 size_t length;
472 off_t old_offset, new_offset;
474 /* 1. Parameter: file descriptor */
475 if (remote_fileio_extract_int (&buf, &target_fd))
477 remote_fileio_ioerror (remote);
478 return;
480 fd = remote_fileio_map_fd ((int) target_fd);
481 if (fd == FIO_FD_INVALID)
483 remote_fileio_badfd (remote);
484 return;
486 /* 2. Parameter: buffer pointer */
487 if (remote_fileio_extract_long (&buf, &lnum))
489 remote_fileio_ioerror (remote);
490 return;
492 ptrval = (CORE_ADDR) lnum;
493 /* 3. Parameter: buffer length */
494 if (remote_fileio_extract_int (&buf, &num))
496 remote_fileio_ioerror (remote);
497 return;
499 length = (size_t) num;
501 switch (fd)
503 case FIO_FD_CONSOLE_OUT:
504 remote_fileio_badfd (remote);
505 return;
506 case FIO_FD_CONSOLE_IN:
508 static char *remaining_buf = NULL;
509 static int remaining_length = 0;
511 buffer = (gdb_byte *) xmalloc (16384);
512 if (remaining_buf)
514 if (remaining_length > length)
516 memcpy (buffer, remaining_buf, length);
517 memmove (remaining_buf, remaining_buf + length,
518 remaining_length - length);
519 remaining_length -= length;
520 ret = length;
522 else
524 memcpy (buffer, remaining_buf, remaining_length);
525 xfree (remaining_buf);
526 remaining_buf = NULL;
527 ret = remaining_length;
530 else
532 /* Windows (at least XP and Server 2003) has difficulty
533 with large reads from consoles. If a handle is
534 backed by a real console device, overly large reads
535 from the handle will fail and set errno == ENOMEM.
536 On a Windows Server 2003 system where I tested,
537 reading 26608 bytes from the console was OK, but
538 anything above 26609 bytes would fail. The limit has
539 been observed to vary on different systems. So, we
540 limit this read to something smaller than that - by a
541 safe margin, in case the limit depends on system
542 resources or version. */
543 ret = gdb_stdtargin->read ((char *) buffer, 16383);
544 if (ret > 0 && (size_t)ret > length)
546 remaining_buf = (char *) xmalloc (ret - length);
547 remaining_length = ret - length;
548 memcpy (remaining_buf, buffer + length, remaining_length);
549 ret = length;
553 break;
554 default:
555 buffer = (gdb_byte *) xmalloc (length);
556 /* POSIX defines EINTR behaviour of read in a weird way. It's allowed
557 for read() to return -1 even if "some" bytes have been read. It
558 has been corrected in SUSv2 but that doesn't help us much...
559 Therefore a complete solution must check how many bytes have been
560 read on EINTR to return a more reliable value to the target */
561 old_offset = lseek (fd, 0, SEEK_CUR);
562 ret = read (fd, buffer, length);
563 if (ret < 0 && errno == EINTR)
565 new_offset = lseek (fd, 0, SEEK_CUR);
566 /* If some data has been read, return the number of bytes read.
567 The Ctrl-C flag is set in remote_fileio_reply() anyway. */
568 if (old_offset != new_offset)
569 ret = new_offset - old_offset;
571 break;
574 if (ret > 0)
576 errno = target_write_memory (ptrval, buffer, ret);
577 if (errno != 0)
578 ret = -1;
581 if (ret < 0)
582 remote_fileio_return_errno (remote, -1);
583 else
584 remote_fileio_return_success (remote, ret);
586 xfree (buffer);
589 static void
590 remote_fileio_func_write (remote_target *remote, char *buf)
592 long target_fd, num;
593 LONGEST lnum;
594 CORE_ADDR ptrval;
595 int fd, ret;
596 gdb_byte *buffer;
597 size_t length;
599 /* 1. Parameter: file descriptor */
600 if (remote_fileio_extract_int (&buf, &target_fd))
602 remote_fileio_ioerror (remote);
603 return;
605 fd = remote_fileio_map_fd ((int) target_fd);
606 if (fd == FIO_FD_INVALID)
608 remote_fileio_badfd (remote);
609 return;
611 /* 2. Parameter: buffer pointer */
612 if (remote_fileio_extract_long (&buf, &lnum))
614 remote_fileio_ioerror (remote);
615 return;
617 ptrval = (CORE_ADDR) lnum;
618 /* 3. Parameter: buffer length */
619 if (remote_fileio_extract_int (&buf, &num))
621 remote_fileio_ioerror (remote);
622 return;
624 length = (size_t) num;
626 buffer = (gdb_byte *) xmalloc (length);
627 if (target_read_memory (ptrval, buffer, length) != 0)
629 xfree (buffer);
630 remote_fileio_ioerror (remote);
631 return;
634 switch (fd)
636 case FIO_FD_CONSOLE_IN:
637 remote_fileio_badfd (remote);
638 xfree (buffer);
639 return;
640 case FIO_FD_CONSOLE_OUT:
642 ui_file *file = target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr;
643 file->write ((char *) buffer, length);
644 file->flush ();
645 ret = length;
647 break;
648 default:
649 ret = write (fd, buffer, length);
650 if (ret < 0 && errno == EACCES)
651 errno = EBADF; /* Cygwin returns EACCESS when writing to a
652 R/O file. */
653 break;
656 if (ret < 0)
657 remote_fileio_return_errno (remote, -1);
658 else
659 remote_fileio_return_success (remote, ret);
661 xfree (buffer);
664 static void
665 remote_fileio_func_lseek (remote_target *remote, char *buf)
667 long num;
668 LONGEST lnum;
669 int fd, flag;
670 off_t offset, ret;
672 /* 1. Parameter: file descriptor */
673 if (remote_fileio_extract_int (&buf, &num))
675 remote_fileio_ioerror (remote);
676 return;
678 fd = remote_fileio_map_fd ((int) num);
679 if (fd == FIO_FD_INVALID)
681 remote_fileio_badfd (remote);
682 return;
684 else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
686 remote_fileio_reply (remote, -1, FILEIO_ESPIPE);
687 return;
690 /* 2. Parameter: offset */
691 if (remote_fileio_extract_long (&buf, &lnum))
693 remote_fileio_ioerror (remote);
694 return;
696 offset = (off_t) lnum;
697 /* 3. Parameter: flag */
698 if (remote_fileio_extract_int (&buf, &num))
700 remote_fileio_ioerror (remote);
701 return;
703 if (remote_fileio_seek_flag_to_host (num, &flag))
705 remote_fileio_reply (remote, -1, FILEIO_EINVAL);
706 return;
709 ret = lseek (fd, offset, flag);
711 if (ret == (off_t) -1)
712 remote_fileio_return_errno (remote, -1);
713 else
714 remote_fileio_return_success (remote, ret);
717 static void
718 remote_fileio_func_rename (remote_target *remote, char *buf)
720 CORE_ADDR old_ptr, new_ptr;
721 int old_len, new_len;
722 char *oldpath, *newpath;
723 int ret, of, nf;
724 struct stat ost, nst;
726 /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
727 if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
729 remote_fileio_ioerror (remote);
730 return;
733 /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
734 if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
736 remote_fileio_ioerror (remote);
737 return;
740 /* Request oldpath using 'm' packet */
741 oldpath = (char *) alloca (old_len);
742 if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
744 remote_fileio_ioerror (remote);
745 return;
748 /* Request newpath using 'm' packet */
749 newpath = (char *) alloca (new_len);
750 if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
752 remote_fileio_ioerror (remote);
753 return;
756 /* Only operate on regular files and directories. */
757 of = stat (oldpath, &ost);
758 nf = stat (newpath, &nst);
759 if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
760 || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
762 remote_fileio_reply (remote, -1, FILEIO_EACCES);
763 return;
766 ret = rename (oldpath, newpath);
768 if (ret == -1)
770 /* Special case: newpath is a non-empty directory. Some systems
771 return ENOTEMPTY, some return EEXIST. We coerce that to be
772 always EEXIST. */
773 if (errno == ENOTEMPTY)
774 errno = EEXIST;
775 #ifdef __CYGWIN__
776 /* Workaround some Cygwin problems with correct errnos. */
777 if (errno == EACCES)
779 if (!of && !nf && S_ISDIR (nst.st_mode))
781 if (S_ISREG (ost.st_mode))
782 errno = EISDIR;
783 else
785 char oldfullpath[PATH_MAX];
786 char newfullpath[PATH_MAX];
787 int len;
789 cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
790 PATH_MAX);
791 cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
792 PATH_MAX);
793 len = strlen (oldfullpath);
794 if (IS_DIR_SEPARATOR (newfullpath[len])
795 && !filename_ncmp (oldfullpath, newfullpath, len))
796 errno = EINVAL;
797 else
798 errno = EEXIST;
802 #endif
804 remote_fileio_return_errno (remote, -1);
806 else
807 remote_fileio_return_success (remote, ret);
810 static void
811 remote_fileio_func_unlink (remote_target *remote, char *buf)
813 CORE_ADDR ptrval;
814 int length;
815 char *pathname;
816 int ret;
817 struct stat st;
819 /* Parameter: Ptr to pathname / length incl. trailing zero */
820 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
822 remote_fileio_ioerror (remote);
823 return;
825 /* Request pathname using 'm' packet */
826 pathname = (char *) alloca (length);
827 if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
829 remote_fileio_ioerror (remote);
830 return;
833 /* Only operate on regular files (and directories, which allows to return
834 the correct return code). */
835 if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
837 remote_fileio_reply (remote, -1, FILEIO_ENODEV);
838 return;
841 ret = unlink (pathname);
843 if (ret == -1)
844 remote_fileio_return_errno (remote, -1);
845 else
846 remote_fileio_return_success (remote, ret);
849 static void
850 remote_fileio_func_stat (remote_target *remote, char *buf)
852 CORE_ADDR statptr, nameptr;
853 int ret, namelength;
854 char *pathname;
855 LONGEST lnum;
856 struct stat st;
857 struct fio_stat fst;
859 /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
860 if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
862 remote_fileio_ioerror (remote);
863 return;
866 /* 2. Parameter: Ptr to struct stat */
867 if (remote_fileio_extract_long (&buf, &lnum))
869 remote_fileio_ioerror (remote);
870 return;
872 statptr = (CORE_ADDR) lnum;
874 /* Request pathname using 'm' packet */
875 pathname = (char *) alloca (namelength);
876 if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
878 remote_fileio_ioerror (remote);
879 return;
882 ret = stat (pathname, &st);
884 if (ret == -1)
886 remote_fileio_return_errno (remote, -1);
887 return;
889 /* Only operate on regular files and directories. */
890 if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
892 remote_fileio_reply (remote, -1, FILEIO_EACCES);
893 return;
895 if (statptr)
897 host_to_fileio_stat (&st, &fst);
898 host_to_fileio_uint (0, fst.fst_dev);
900 errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
901 if (errno != 0)
903 remote_fileio_return_errno (remote, -1);
904 return;
907 remote_fileio_return_success (remote, ret);
910 static void
911 remote_fileio_func_fstat (remote_target *remote, char *buf)
913 CORE_ADDR ptrval;
914 int fd, ret;
915 long target_fd;
916 LONGEST lnum;
917 struct stat st;
918 struct fio_stat fst;
919 struct timeval tv;
921 /* 1. Parameter: file descriptor */
922 if (remote_fileio_extract_int (&buf, &target_fd))
924 remote_fileio_ioerror (remote);
925 return;
927 fd = remote_fileio_map_fd ((int) target_fd);
928 if (fd == FIO_FD_INVALID)
930 remote_fileio_badfd (remote);
931 return;
933 /* 2. Parameter: Ptr to struct stat */
934 if (remote_fileio_extract_long (&buf, &lnum))
936 remote_fileio_ioerror (remote);
937 return;
939 ptrval = (CORE_ADDR) lnum;
941 if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
943 host_to_fileio_uint (1, fst.fst_dev);
944 memset (&st, 0, sizeof (st));
945 st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
946 st.st_nlink = 1;
947 #ifdef HAVE_GETUID
948 st.st_uid = getuid ();
949 #endif
950 #ifdef HAVE_GETGID
951 st.st_gid = getgid ();
952 #endif
953 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
954 st.st_blksize = 512;
955 #endif
956 #if HAVE_STRUCT_STAT_ST_BLOCKS
957 st.st_blocks = 0;
958 #endif
959 if (!gettimeofday (&tv, NULL))
960 st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
961 else
962 st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
963 ret = 0;
965 else
966 ret = fstat (fd, &st);
968 if (ret == -1)
970 remote_fileio_return_errno (remote, -1);
971 return;
973 if (ptrval)
975 host_to_fileio_stat (&st, &fst);
977 errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
978 if (errno != 0)
980 remote_fileio_return_errno (remote, -1);
981 return;
984 remote_fileio_return_success (remote, ret);
987 static void
988 remote_fileio_func_gettimeofday (remote_target *remote, char *buf)
990 LONGEST lnum;
991 CORE_ADDR ptrval;
992 int ret;
993 struct timeval tv;
994 struct fio_timeval ftv;
996 /* 1. Parameter: struct timeval pointer */
997 if (remote_fileio_extract_long (&buf, &lnum))
999 remote_fileio_ioerror (remote);
1000 return;
1002 ptrval = (CORE_ADDR) lnum;
1003 /* 2. Parameter: some pointer value... */
1004 if (remote_fileio_extract_long (&buf, &lnum))
1006 remote_fileio_ioerror (remote);
1007 return;
1009 /* ...which has to be NULL. */
1010 if (lnum)
1012 remote_fileio_reply (remote, -1, FILEIO_EINVAL);
1013 return;
1016 ret = gettimeofday (&tv, NULL);
1018 if (ret == -1)
1020 remote_fileio_return_errno (remote, -1);
1021 return;
1024 if (ptrval)
1026 remote_fileio_to_fio_timeval (&tv, &ftv);
1028 errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1029 if (errno != 0)
1031 remote_fileio_return_errno (remote, -1);
1032 return;
1035 remote_fileio_return_success (remote, ret);
1038 static void
1039 remote_fileio_func_isatty (remote_target *remote, char *buf)
1041 long target_fd;
1042 int fd;
1044 /* Parameter: file descriptor */
1045 if (remote_fileio_extract_int (&buf, &target_fd))
1047 remote_fileio_ioerror (remote);
1048 return;
1050 fd = remote_fileio_map_fd ((int) target_fd);
1051 int ret = fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT ? 1 : 0;
1052 remote_fileio_return_success (remote, ret);
1055 static void
1056 remote_fileio_func_system (remote_target *remote, char *buf)
1058 CORE_ADDR ptrval;
1059 int ret, length;
1060 char *cmdline = NULL;
1062 /* Parameter: Ptr to commandline / length incl. trailing zero */
1063 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1065 remote_fileio_ioerror (remote);
1066 return;
1069 if (length)
1071 /* Request commandline using 'm' packet */
1072 cmdline = (char *) alloca (length);
1073 if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
1075 remote_fileio_ioerror (remote);
1076 return;
1080 /* Check if system(3) has been explicitly allowed using the
1081 `set remote system-call-allowed 1' command. If length is 0,
1082 indicating a NULL parameter to the system call, return zero to
1083 indicate a shell is not available. Otherwise fail with EPERM. */
1084 if (!remote_fio_system_call_allowed)
1086 if (!length)
1087 remote_fileio_return_success (remote, 0);
1088 else
1089 remote_fileio_reply (remote, -1, FILEIO_EPERM);
1090 return;
1093 ret = system (cmdline);
1095 if (!length)
1096 remote_fileio_return_success (remote, ret);
1097 else if (ret == -1)
1098 remote_fileio_return_errno (remote, -1);
1099 else
1100 remote_fileio_return_success (remote, WEXITSTATUS (ret));
1103 static struct {
1104 const char *name;
1105 void (*func)(remote_target *remote, char *);
1106 } remote_fio_func_map[] = {
1107 { "open", remote_fileio_func_open },
1108 { "close", remote_fileio_func_close },
1109 { "read", remote_fileio_func_read },
1110 { "write", remote_fileio_func_write },
1111 { "lseek", remote_fileio_func_lseek },
1112 { "rename", remote_fileio_func_rename },
1113 { "unlink", remote_fileio_func_unlink },
1114 { "stat", remote_fileio_func_stat },
1115 { "fstat", remote_fileio_func_fstat },
1116 { "gettimeofday", remote_fileio_func_gettimeofday },
1117 { "isatty", remote_fileio_func_isatty },
1118 { "system", remote_fileio_func_system },
1119 { NULL, NULL }
1122 static void
1123 do_remote_fileio_request (remote_target *remote, char *buf)
1125 char *c;
1126 int idx;
1128 quit_handler = remote_fileio_quit_handler;
1130 c = strchr (++buf, ',');
1131 if (c)
1132 *c++ = '\0';
1133 else
1134 c = strchr (buf, '\0');
1135 for (idx = 0; remote_fio_func_map[idx].name; ++idx)
1136 if (!strcmp (remote_fio_func_map[idx].name, buf))
1137 break;
1138 if (!remote_fio_func_map[idx].name)
1139 remote_fileio_reply (remote, -1, FILEIO_ENOSYS);
1140 else
1141 remote_fio_func_map[idx].func (remote, c);
1144 /* Close any open descriptors, and reinitialize the file mapping. */
1146 void
1147 remote_fileio_reset (void)
1149 int ix;
1151 for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1153 int fd = remote_fio_data.fd_map[ix];
1155 if (fd >= 0)
1156 close (fd);
1158 if (remote_fio_data.fd_map)
1160 xfree (remote_fio_data.fd_map);
1161 remote_fio_data.fd_map = NULL;
1162 remote_fio_data.fd_map_size = 0;
1166 /* Handle a file I/O request. BUF points to the packet containing the
1167 request. CTRLC_PENDING_P should be nonzero if the target has not
1168 acknowledged the Ctrl-C sent asynchronously earlier. */
1170 void
1171 remote_fileio_request (remote_target *remote, char *buf, int ctrlc_pending_p)
1173 /* Save the previous quit handler, so we can restore it. No need
1174 for a cleanup since we catch all exceptions below. Note that the
1175 quit handler is also restored by remote_fileio_reply just before
1176 pushing a packet. */
1177 remote_fileio_o_quit_handler = quit_handler;
1179 if (ctrlc_pending_p)
1181 /* If the target hasn't responded to the Ctrl-C sent
1182 asynchronously earlier, take this opportunity to send the
1183 Ctrl-C synchronously. */
1184 set_quit_flag ();
1185 remote_fileio_reply (remote, -1, FILEIO_EINTR);
1187 else
1191 do_remote_fileio_request (remote, buf);
1193 catch (const gdb_exception_forced_quit &ex)
1195 throw;
1197 catch (const gdb_exception_quit &ex)
1199 remote_fileio_reply (remote, -1, FILEIO_EINTR);
1201 catch (const gdb_exception &ex)
1203 remote_fileio_reply (remote, -1, FILEIO_EIO);
1207 quit_handler = remote_fileio_o_quit_handler;
1211 /* Unpack an fio_uint_t. */
1213 static unsigned int
1214 remote_fileio_to_host_uint (fio_uint_t fnum)
1216 return extract_unsigned_integer ((gdb_byte *) fnum, 4,
1217 BFD_ENDIAN_BIG);
1220 /* Unpack an fio_ulong_t. */
1222 static ULONGEST
1223 remote_fileio_to_host_ulong (fio_ulong_t fnum)
1225 return extract_unsigned_integer ((gdb_byte *) fnum, 8,
1226 BFD_ENDIAN_BIG);
1229 /* Unpack an fio_mode_t. */
1231 static mode_t
1232 remote_fileio_to_host_mode (fio_mode_t fnum)
1234 return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
1238 /* Unpack an fio_time_t. */
1240 static time_t
1241 remote_fileio_to_host_time (fio_time_t fnum)
1243 return remote_fileio_to_host_uint (fnum);
1247 /* See remote-fileio.h. */
1249 void
1250 remote_fileio_to_host_stat (struct fio_stat *fst, struct stat *st)
1252 memset (st, 0, sizeof (struct stat));
1254 st->st_dev = remote_fileio_to_host_uint (fst->fst_dev);
1255 st->st_ino = remote_fileio_to_host_uint (fst->fst_ino);
1256 st->st_mode = remote_fileio_to_host_mode (fst->fst_mode);
1257 st->st_nlink = remote_fileio_to_host_uint (fst->fst_nlink);
1258 st->st_uid = remote_fileio_to_host_uint (fst->fst_uid);
1259 st->st_gid = remote_fileio_to_host_uint (fst->fst_gid);
1260 st->st_rdev = remote_fileio_to_host_uint (fst->fst_rdev);
1261 st->st_size = remote_fileio_to_host_ulong (fst->fst_size);
1262 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1263 st->st_blksize = remote_fileio_to_host_ulong (fst->fst_blksize);
1264 #endif
1265 #if HAVE_STRUCT_STAT_ST_BLOCKS
1266 st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
1267 #endif
1268 st->st_atime = remote_fileio_to_host_time (fst->fst_atime);
1269 st->st_mtime = remote_fileio_to_host_time (fst->fst_mtime);
1270 st->st_ctime = remote_fileio_to_host_time (fst->fst_ctime);
1274 static void
1275 set_system_call_allowed (const char *args, int from_tty)
1277 if (args)
1279 char *arg_end;
1280 int val = strtoul (args, &arg_end, 10);
1282 if (*args && *arg_end == '\0')
1284 remote_fio_system_call_allowed = !!val;
1285 return;
1288 error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1291 static void
1292 show_system_call_allowed (const char *args, int from_tty)
1294 if (args)
1295 error (_("Garbage after \"show remote "
1296 "system-call-allowed\" command: `%s'"), args);
1297 gdb_printf ("Calling host system(3) call from target is %sallowed\n",
1298 remote_fio_system_call_allowed ? "" : "not ");
1301 void
1302 initialize_remote_fileio (struct cmd_list_element **remote_set_cmdlist,
1303 struct cmd_list_element **remote_show_cmdlist)
1305 add_cmd ("system-call-allowed", no_class,
1306 set_system_call_allowed,
1307 _("Set if the host system(3) call is allowed for the target."),
1308 remote_set_cmdlist);
1309 add_cmd ("system-call-allowed", no_class,
1310 show_system_call_allowed,
1311 _("Show if the host system(3) call is allowed for the target."),
1312 remote_show_cmdlist);