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