29c5ca3589680f66815b48e8fa826c487fa348bd
[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 static int remote_fio_ctrl_c_flag = 0;
302
303 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
304 static struct sigaction remote_fio_sa;
305 static struct sigaction remote_fio_osa;
306 #else
307 static void (*remote_fio_ofunc)(int);
308 #endif
309
310 static void
311 remote_fileio_sig_init (void)
312 {
313 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
314 remote_fio_sa.sa_handler = SIG_IGN;
315 sigemptyset (&remote_fio_sa.sa_mask);
316 remote_fio_sa.sa_flags = 0;
317 sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa);
318 #else
319 remote_fio_ofunc = signal (SIGINT, SIG_IGN);
320 #endif
321 }
322
323 static void
324 remote_fileio_sig_set (void (*sigint_func)(int))
325 {
326 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
327 remote_fio_sa.sa_handler = sigint_func;
328 sigemptyset (&remote_fio_sa.sa_mask);
329 remote_fio_sa.sa_flags = 0;
330 sigaction (SIGINT, &remote_fio_sa, NULL);
331 #else
332 signal (SIGINT, sigint_func);
333 #endif
334 }
335
336 static void
337 remote_fileio_sig_exit (void)
338 {
339 #if defined (HAVE_SIGACTION) && defined (SA_RESTART)
340 sigaction (SIGINT, &remote_fio_osa, NULL);
341 #else
342 signal (SIGINT, remote_fio_ofunc);
343 #endif
344 }
345
346 static void
347 remote_fileio_ctrl_c_signal_handler (int signo)
348 {
349 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
350 remote_fio_ctrl_c_flag = 1;
351 /* Wake up interruptible_select. */
352 quit_serial_event_set ();
353 }
354
355 static void
356 remote_fileio_reply (int retcode, int error)
357 {
358 char buf[32];
359
360 remote_fileio_sig_set (SIG_IGN);
361 strcpy (buf, "F");
362 if (retcode < 0)
363 {
364 strcat (buf, "-");
365 retcode = -retcode;
366 }
367 sprintf (buf + strlen (buf), "%x", retcode);
368 if (error || remote_fio_ctrl_c_flag)
369 {
370 if (error && remote_fio_ctrl_c_flag)
371 error = FILEIO_EINTR;
372 if (error < 0)
373 {
374 strcat (buf, "-");
375 error = -error;
376 }
377 sprintf (buf + strlen (buf), ",%x", error);
378 if (remote_fio_ctrl_c_flag)
379 strcat (buf, ",C");
380 }
381 remote_fio_ctrl_c_flag = 0;
382 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
383 putpkt (buf);
384 }
385
386 static void
387 remote_fileio_ioerror (void)
388 {
389 remote_fileio_reply (-1, FILEIO_EIO);
390 }
391
392 static void
393 remote_fileio_badfd (void)
394 {
395 remote_fileio_reply (-1, FILEIO_EBADF);
396 }
397
398 static void
399 remote_fileio_return_errno (int retcode)
400 {
401 remote_fileio_reply (retcode, retcode < 0
402 ? host_to_fileio_error (errno) : 0);
403 }
404
405 static void
406 remote_fileio_return_success (int retcode)
407 {
408 remote_fileio_reply (retcode, 0);
409 }
410
411 static void
412 remote_fileio_func_open (char *buf)
413 {
414 CORE_ADDR ptrval;
415 int length;
416 long num;
417 int flags, fd;
418 mode_t mode;
419 char *pathname;
420 struct stat st;
421
422 /* 1. Parameter: Ptr to pathname / length incl. trailing zero. */
423 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
424 {
425 remote_fileio_ioerror ();
426 return;
427 }
428 /* 2. Parameter: open flags */
429 if (remote_fileio_extract_int (&buf, &num))
430 {
431 remote_fileio_ioerror ();
432 return;
433 }
434 flags = remote_fileio_oflags_to_host (num);
435 /* 3. Parameter: open mode */
436 if (remote_fileio_extract_int (&buf, &num))
437 {
438 remote_fileio_ioerror ();
439 return;
440 }
441 mode = remote_fileio_mode_to_host (num, 1);
442
443 /* Request pathname. */
444 pathname = (char *) alloca (length);
445 if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
446 {
447 remote_fileio_ioerror ();
448 return;
449 }
450
451 /* Check if pathname exists and is not a regular file or directory. If so,
452 return an appropriate error code. Same for trying to open directories
453 for writing. */
454 if (!stat (pathname, &st))
455 {
456 if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
457 {
458 remote_fileio_reply (-1, FILEIO_ENODEV);
459 return;
460 }
461 if (S_ISDIR (st.st_mode)
462 && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
463 {
464 remote_fileio_reply (-1, FILEIO_EISDIR);
465 return;
466 }
467 }
468
469 fd = gdb_open_cloexec (pathname, flags, mode);
470 if (fd < 0)
471 {
472 remote_fileio_return_errno (-1);
473 return;
474 }
475
476 fd = remote_fileio_fd_to_targetfd (fd);
477 remote_fileio_return_success (fd);
478 }
479
480 static void
481 remote_fileio_func_close (char *buf)
482 {
483 long num;
484 int fd;
485
486 /* Parameter: file descriptor */
487 if (remote_fileio_extract_int (&buf, &num))
488 {
489 remote_fileio_ioerror ();
490 return;
491 }
492 fd = remote_fileio_map_fd ((int) num);
493 if (fd == FIO_FD_INVALID)
494 {
495 remote_fileio_badfd ();
496 return;
497 }
498
499 if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
500 remote_fileio_return_errno (-1);
501 remote_fileio_close_target_fd ((int) num);
502 remote_fileio_return_success (0);
503 }
504
505 static void
506 remote_fileio_func_read (char *buf)
507 {
508 long target_fd, num;
509 LONGEST lnum;
510 CORE_ADDR ptrval;
511 int fd, ret;
512 gdb_byte *buffer;
513 size_t length;
514 off_t old_offset, new_offset;
515
516 /* 1. Parameter: file descriptor */
517 if (remote_fileio_extract_int (&buf, &target_fd))
518 {
519 remote_fileio_ioerror ();
520 return;
521 }
522 fd = remote_fileio_map_fd ((int) target_fd);
523 if (fd == FIO_FD_INVALID)
524 {
525 remote_fileio_badfd ();
526 return;
527 }
528 /* 2. Parameter: buffer pointer */
529 if (remote_fileio_extract_long (&buf, &lnum))
530 {
531 remote_fileio_ioerror ();
532 return;
533 }
534 ptrval = (CORE_ADDR) lnum;
535 /* 3. Parameter: buffer length */
536 if (remote_fileio_extract_int (&buf, &num))
537 {
538 remote_fileio_ioerror ();
539 return;
540 }
541 length = (size_t) num;
542
543 switch (fd)
544 {
545 case FIO_FD_CONSOLE_OUT:
546 remote_fileio_badfd ();
547 return;
548 case FIO_FD_CONSOLE_IN:
549 {
550 static char *remaining_buf = NULL;
551 static int remaining_length = 0;
552
553 buffer = (gdb_byte *) xmalloc (16384);
554 if (remaining_buf)
555 {
556 if (remaining_length > length)
557 {
558 memcpy (buffer, remaining_buf, length);
559 memmove (remaining_buf, remaining_buf + length,
560 remaining_length - length);
561 remaining_length -= length;
562 ret = length;
563 }
564 else
565 {
566 memcpy (buffer, remaining_buf, remaining_length);
567 xfree (remaining_buf);
568 remaining_buf = NULL;
569 ret = remaining_length;
570 }
571 }
572 else
573 {
574 /* Windows (at least XP and Server 2003) has difficulty
575 with large reads from consoles. If a handle is
576 backed by a real console device, overly large reads
577 from the handle will fail and set errno == ENOMEM.
578 On a Windows Server 2003 system where I tested,
579 reading 26608 bytes from the console was OK, but
580 anything above 26609 bytes would fail. The limit has
581 been observed to vary on different systems. So, we
582 limit this read to something smaller than that - by a
583 safe margin, in case the limit depends on system
584 resources or version. */
585 ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
586 if (ret > 0 && (size_t)ret > length)
587 {
588 remaining_buf = (char *) xmalloc (ret - length);
589 remaining_length = ret - length;
590 memcpy (remaining_buf, buffer + length, remaining_length);
591 ret = length;
592 }
593 }
594 }
595 break;
596 default:
597 buffer = (gdb_byte *) xmalloc (length);
598 /* POSIX defines EINTR behaviour of read in a weird way. It's allowed
599 for read() to return -1 even if "some" bytes have been read. It
600 has been corrected in SUSv2 but that doesn't help us much...
601 Therefore a complete solution must check how many bytes have been
602 read on EINTR to return a more reliable value to the target */
603 old_offset = lseek (fd, 0, SEEK_CUR);
604 ret = read (fd, buffer, length);
605 if (ret < 0 && errno == EINTR)
606 {
607 new_offset = lseek (fd, 0, SEEK_CUR);
608 /* If some data has been read, return the number of bytes read.
609 The Ctrl-C flag is set in remote_fileio_reply() anyway. */
610 if (old_offset != new_offset)
611 ret = new_offset - old_offset;
612 }
613 break;
614 }
615
616 if (ret > 0)
617 {
618 errno = target_write_memory (ptrval, buffer, ret);
619 if (errno != 0)
620 ret = -1;
621 }
622
623 if (ret < 0)
624 remote_fileio_return_errno (-1);
625 else
626 remote_fileio_return_success (ret);
627
628 xfree (buffer);
629 }
630
631 static void
632 remote_fileio_func_write (char *buf)
633 {
634 long target_fd, num;
635 LONGEST lnum;
636 CORE_ADDR ptrval;
637 int fd, ret;
638 gdb_byte *buffer;
639 size_t length;
640
641 /* 1. Parameter: file descriptor */
642 if (remote_fileio_extract_int (&buf, &target_fd))
643 {
644 remote_fileio_ioerror ();
645 return;
646 }
647 fd = remote_fileio_map_fd ((int) target_fd);
648 if (fd == FIO_FD_INVALID)
649 {
650 remote_fileio_badfd ();
651 return;
652 }
653 /* 2. Parameter: buffer pointer */
654 if (remote_fileio_extract_long (&buf, &lnum))
655 {
656 remote_fileio_ioerror ();
657 return;
658 }
659 ptrval = (CORE_ADDR) lnum;
660 /* 3. Parameter: buffer length */
661 if (remote_fileio_extract_int (&buf, &num))
662 {
663 remote_fileio_ioerror ();
664 return;
665 }
666 length = (size_t) num;
667
668 buffer = (gdb_byte *) xmalloc (length);
669 if (target_read_memory (ptrval, buffer, length) != 0)
670 {
671 xfree (buffer);
672 remote_fileio_ioerror ();
673 return;
674 }
675
676 switch (fd)
677 {
678 case FIO_FD_CONSOLE_IN:
679 remote_fileio_badfd ();
680 xfree (buffer);
681 return;
682 case FIO_FD_CONSOLE_OUT:
683 ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
684 (char *) buffer, length);
685 gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
686 ret = length;
687 break;
688 default:
689 ret = write (fd, buffer, length);
690 if (ret < 0 && errno == EACCES)
691 errno = EBADF; /* Cygwin returns EACCESS when writing to a
692 R/O file. */
693 break;
694 }
695
696 if (ret < 0)
697 remote_fileio_return_errno (-1);
698 else
699 remote_fileio_return_success (ret);
700
701 xfree (buffer);
702 }
703
704 static void
705 remote_fileio_func_lseek (char *buf)
706 {
707 long num;
708 LONGEST lnum;
709 int fd, flag;
710 off_t offset, ret;
711
712 /* 1. Parameter: file descriptor */
713 if (remote_fileio_extract_int (&buf, &num))
714 {
715 remote_fileio_ioerror ();
716 return;
717 }
718 fd = remote_fileio_map_fd ((int) num);
719 if (fd == FIO_FD_INVALID)
720 {
721 remote_fileio_badfd ();
722 return;
723 }
724 else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
725 {
726 remote_fileio_reply (-1, FILEIO_ESPIPE);
727 return;
728 }
729
730 /* 2. Parameter: offset */
731 if (remote_fileio_extract_long (&buf, &lnum))
732 {
733 remote_fileio_ioerror ();
734 return;
735 }
736 offset = (off_t) lnum;
737 /* 3. Parameter: flag */
738 if (remote_fileio_extract_int (&buf, &num))
739 {
740 remote_fileio_ioerror ();
741 return;
742 }
743 if (remote_fileio_seek_flag_to_host (num, &flag))
744 {
745 remote_fileio_reply (-1, FILEIO_EINVAL);
746 return;
747 }
748
749 ret = lseek (fd, offset, flag);
750
751 if (ret == (off_t) -1)
752 remote_fileio_return_errno (-1);
753 else
754 remote_fileio_return_success (ret);
755 }
756
757 static void
758 remote_fileio_func_rename (char *buf)
759 {
760 CORE_ADDR old_ptr, new_ptr;
761 int old_len, new_len;
762 char *oldpath, *newpath;
763 int ret, of, nf;
764 struct stat ost, nst;
765
766 /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
767 if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
768 {
769 remote_fileio_ioerror ();
770 return;
771 }
772
773 /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
774 if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
775 {
776 remote_fileio_ioerror ();
777 return;
778 }
779
780 /* Request oldpath using 'm' packet */
781 oldpath = (char *) alloca (old_len);
782 if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
783 {
784 remote_fileio_ioerror ();
785 return;
786 }
787
788 /* Request newpath using 'm' packet */
789 newpath = (char *) alloca (new_len);
790 if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
791 {
792 remote_fileio_ioerror ();
793 return;
794 }
795
796 /* Only operate on regular files and directories. */
797 of = stat (oldpath, &ost);
798 nf = stat (newpath, &nst);
799 if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
800 || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
801 {
802 remote_fileio_reply (-1, FILEIO_EACCES);
803 return;
804 }
805
806 ret = rename (oldpath, newpath);
807
808 if (ret == -1)
809 {
810 /* Special case: newpath is a non-empty directory. Some systems
811 return ENOTEMPTY, some return EEXIST. We coerce that to be
812 always EEXIST. */
813 if (errno == ENOTEMPTY)
814 errno = EEXIST;
815 #ifdef __CYGWIN__
816 /* Workaround some Cygwin problems with correct errnos. */
817 if (errno == EACCES)
818 {
819 if (!of && !nf && S_ISDIR (nst.st_mode))
820 {
821 if (S_ISREG (ost.st_mode))
822 errno = EISDIR;
823 else
824 {
825 char oldfullpath[PATH_MAX];
826 char newfullpath[PATH_MAX];
827 int len;
828
829 cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
830 PATH_MAX);
831 cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
832 PATH_MAX);
833 len = strlen (oldfullpath);
834 if (IS_DIR_SEPARATOR (newfullpath[len])
835 && !filename_ncmp (oldfullpath, newfullpath, len))
836 errno = EINVAL;
837 else
838 errno = EEXIST;
839 }
840 }
841 }
842 #endif
843
844 remote_fileio_return_errno (-1);
845 }
846 else
847 remote_fileio_return_success (ret);
848 }
849
850 static void
851 remote_fileio_func_unlink (char *buf)
852 {
853 CORE_ADDR ptrval;
854 int length;
855 char *pathname;
856 int ret;
857 struct stat st;
858
859 /* Parameter: Ptr to pathname / length incl. trailing zero */
860 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
861 {
862 remote_fileio_ioerror ();
863 return;
864 }
865 /* Request pathname using 'm' packet */
866 pathname = (char *) alloca (length);
867 if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
868 {
869 remote_fileio_ioerror ();
870 return;
871 }
872
873 /* Only operate on regular files (and directories, which allows to return
874 the correct return code). */
875 if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
876 {
877 remote_fileio_reply (-1, FILEIO_ENODEV);
878 return;
879 }
880
881 ret = unlink (pathname);
882
883 if (ret == -1)
884 remote_fileio_return_errno (-1);
885 else
886 remote_fileio_return_success (ret);
887 }
888
889 static void
890 remote_fileio_func_stat (char *buf)
891 {
892 CORE_ADDR statptr, nameptr;
893 int ret, namelength;
894 char *pathname;
895 LONGEST lnum;
896 struct stat st;
897 struct fio_stat fst;
898
899 /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
900 if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
901 {
902 remote_fileio_ioerror ();
903 return;
904 }
905
906 /* 2. Parameter: Ptr to struct stat */
907 if (remote_fileio_extract_long (&buf, &lnum))
908 {
909 remote_fileio_ioerror ();
910 return;
911 }
912 statptr = (CORE_ADDR) lnum;
913
914 /* Request pathname using 'm' packet */
915 pathname = (char *) alloca (namelength);
916 if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
917 {
918 remote_fileio_ioerror ();
919 return;
920 }
921
922 ret = stat (pathname, &st);
923
924 if (ret == -1)
925 {
926 remote_fileio_return_errno (-1);
927 return;
928 }
929 /* Only operate on regular files and directories. */
930 if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
931 {
932 remote_fileio_reply (-1, FILEIO_EACCES);
933 return;
934 }
935 if (statptr)
936 {
937 host_to_fileio_stat (&st, &fst);
938 host_to_fileio_uint (0, fst.fst_dev);
939
940 errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
941 if (errno != 0)
942 {
943 remote_fileio_return_errno (-1);
944 return;
945 }
946 }
947 remote_fileio_return_success (ret);
948 }
949
950 static void
951 remote_fileio_func_fstat (char *buf)
952 {
953 CORE_ADDR ptrval;
954 int fd, ret;
955 long target_fd;
956 LONGEST lnum;
957 struct stat st;
958 struct fio_stat fst;
959 struct timeval tv;
960
961 /* 1. Parameter: file descriptor */
962 if (remote_fileio_extract_int (&buf, &target_fd))
963 {
964 remote_fileio_ioerror ();
965 return;
966 }
967 fd = remote_fileio_map_fd ((int) target_fd);
968 if (fd == FIO_FD_INVALID)
969 {
970 remote_fileio_badfd ();
971 return;
972 }
973 /* 2. Parameter: Ptr to struct stat */
974 if (remote_fileio_extract_long (&buf, &lnum))
975 {
976 remote_fileio_ioerror ();
977 return;
978 }
979 ptrval = (CORE_ADDR) lnum;
980
981 if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
982 {
983 host_to_fileio_uint (1, fst.fst_dev);
984 memset (&st, 0, sizeof (st));
985 st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
986 st.st_nlink = 1;
987 #ifdef HAVE_GETUID
988 st.st_uid = getuid ();
989 #endif
990 #ifdef HAVE_GETGID
991 st.st_gid = getgid ();
992 #endif
993 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
994 st.st_blksize = 512;
995 #endif
996 #if HAVE_STRUCT_STAT_ST_BLOCKS
997 st.st_blocks = 0;
998 #endif
999 if (!gettimeofday (&tv, NULL))
1000 st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
1001 else
1002 st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
1003 ret = 0;
1004 }
1005 else
1006 ret = fstat (fd, &st);
1007
1008 if (ret == -1)
1009 {
1010 remote_fileio_return_errno (-1);
1011 return;
1012 }
1013 if (ptrval)
1014 {
1015 host_to_fileio_stat (&st, &fst);
1016
1017 errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
1018 if (errno != 0)
1019 {
1020 remote_fileio_return_errno (-1);
1021 return;
1022 }
1023 }
1024 remote_fileio_return_success (ret);
1025 }
1026
1027 static void
1028 remote_fileio_func_gettimeofday (char *buf)
1029 {
1030 LONGEST lnum;
1031 CORE_ADDR ptrval;
1032 int ret;
1033 struct timeval tv;
1034 struct fio_timeval ftv;
1035
1036 /* 1. Parameter: struct timeval pointer */
1037 if (remote_fileio_extract_long (&buf, &lnum))
1038 {
1039 remote_fileio_ioerror ();
1040 return;
1041 }
1042 ptrval = (CORE_ADDR) lnum;
1043 /* 2. Parameter: some pointer value... */
1044 if (remote_fileio_extract_long (&buf, &lnum))
1045 {
1046 remote_fileio_ioerror ();
1047 return;
1048 }
1049 /* ...which has to be NULL. */
1050 if (lnum)
1051 {
1052 remote_fileio_reply (-1, FILEIO_EINVAL);
1053 return;
1054 }
1055
1056 ret = gettimeofday (&tv, NULL);
1057
1058 if (ret == -1)
1059 {
1060 remote_fileio_return_errno (-1);
1061 return;
1062 }
1063
1064 if (ptrval)
1065 {
1066 remote_fileio_to_fio_timeval (&tv, &ftv);
1067
1068 errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1069 if (errno != 0)
1070 {
1071 remote_fileio_return_errno (-1);
1072 return;
1073 }
1074 }
1075 remote_fileio_return_success (ret);
1076 }
1077
1078 static void
1079 remote_fileio_func_isatty (char *buf)
1080 {
1081 long target_fd;
1082 int fd;
1083
1084 /* Parameter: file descriptor */
1085 if (remote_fileio_extract_int (&buf, &target_fd))
1086 {
1087 remote_fileio_ioerror ();
1088 return;
1089 }
1090 fd = remote_fileio_map_fd ((int) target_fd);
1091 remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
1092 fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
1093 }
1094
1095 static void
1096 remote_fileio_func_system (char *buf)
1097 {
1098 CORE_ADDR ptrval;
1099 int ret, length;
1100 char *cmdline = NULL;
1101
1102 /* Parameter: Ptr to commandline / length incl. trailing zero */
1103 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1104 {
1105 remote_fileio_ioerror ();
1106 return;
1107 }
1108
1109 if (length)
1110 {
1111 /* Request commandline using 'm' packet */
1112 cmdline = (char *) alloca (length);
1113 if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
1114 {
1115 remote_fileio_ioerror ();
1116 return;
1117 }
1118 }
1119
1120 /* Check if system(3) has been explicitely allowed using the
1121 `set remote system-call-allowed 1' command. If length is 0,
1122 indicating a NULL parameter to the system call, return zero to
1123 indicate a shell is not available. Otherwise fail with EPERM. */
1124 if (!remote_fio_system_call_allowed)
1125 {
1126 if (!length)
1127 remote_fileio_return_success (0);
1128 else
1129 remote_fileio_reply (-1, FILEIO_EPERM);
1130 return;
1131 }
1132
1133 ret = system (cmdline);
1134
1135 if (!length)
1136 remote_fileio_return_success (ret);
1137 else if (ret == -1)
1138 remote_fileio_return_errno (-1);
1139 else
1140 remote_fileio_return_success (WEXITSTATUS (ret));
1141 }
1142
1143 static struct {
1144 char *name;
1145 void (*func)(char *);
1146 } remote_fio_func_map[] = {
1147 { "open", remote_fileio_func_open },
1148 { "close", remote_fileio_func_close },
1149 { "read", remote_fileio_func_read },
1150 { "write", remote_fileio_func_write },
1151 { "lseek", remote_fileio_func_lseek },
1152 { "rename", remote_fileio_func_rename },
1153 { "unlink", remote_fileio_func_unlink },
1154 { "stat", remote_fileio_func_stat },
1155 { "fstat", remote_fileio_func_fstat },
1156 { "gettimeofday", remote_fileio_func_gettimeofday },
1157 { "isatty", remote_fileio_func_isatty },
1158 { "system", remote_fileio_func_system },
1159 { NULL, NULL }
1160 };
1161
1162 static int
1163 do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
1164 {
1165 char *buf = (char *) buf_arg;
1166 char *c;
1167 int idx;
1168
1169 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
1170
1171 c = strchr (++buf, ',');
1172 if (c)
1173 *c++ = '\0';
1174 else
1175 c = strchr (buf, '\0');
1176 for (idx = 0; remote_fio_func_map[idx].name; ++idx)
1177 if (!strcmp (remote_fio_func_map[idx].name, buf))
1178 break;
1179 if (!remote_fio_func_map[idx].name) /* ERROR: No such function. */
1180 return RETURN_ERROR;
1181 remote_fio_func_map[idx].func (c);
1182 return 0;
1183 }
1184
1185 /* Close any open descriptors, and reinitialize the file mapping. */
1186
1187 void
1188 remote_fileio_reset (void)
1189 {
1190 int ix;
1191
1192 for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1193 {
1194 int fd = remote_fio_data.fd_map[ix];
1195
1196 if (fd >= 0)
1197 close (fd);
1198 }
1199 if (remote_fio_data.fd_map)
1200 {
1201 xfree (remote_fio_data.fd_map);
1202 remote_fio_data.fd_map = NULL;
1203 remote_fio_data.fd_map_size = 0;
1204 }
1205 }
1206
1207 /* Handle a file I/O request. BUF points to the packet containing the
1208 request. CTRLC_PENDING_P should be nonzero if the target has not
1209 acknowledged the Ctrl-C sent asynchronously earlier. */
1210
1211 void
1212 remote_fileio_request (char *buf, int ctrlc_pending_p)
1213 {
1214 int ex;
1215
1216 remote_fileio_sig_init ();
1217
1218 if (ctrlc_pending_p)
1219 {
1220 /* If the target hasn't responded to the Ctrl-C sent
1221 asynchronously earlier, take this opportunity to send the
1222 Ctrl-C synchronously. */
1223 remote_fio_ctrl_c_flag = 1;
1224 remote_fileio_reply (-1, FILEIO_EINTR);
1225 }
1226 else
1227 {
1228 remote_fio_ctrl_c_flag = 0;
1229
1230 ex = catch_exceptions (current_uiout,
1231 do_remote_fileio_request, (void *)buf,
1232 RETURN_MASK_ALL);
1233 switch (ex)
1234 {
1235 case RETURN_ERROR:
1236 remote_fileio_reply (-1, FILEIO_ENOSYS);
1237 break;
1238 case RETURN_QUIT:
1239 remote_fileio_reply (-1, FILEIO_EINTR);
1240 break;
1241 default:
1242 break;
1243 }
1244 }
1245
1246 remote_fileio_sig_exit ();
1247 }
1248 \f
1249
1250 /* Unpack an fio_uint_t. */
1251
1252 static unsigned int
1253 remote_fileio_to_host_uint (fio_uint_t fnum)
1254 {
1255 return extract_unsigned_integer ((gdb_byte *) fnum, 4,
1256 BFD_ENDIAN_BIG);
1257 }
1258
1259 /* Unpack an fio_ulong_t. */
1260
1261 static ULONGEST
1262 remote_fileio_to_host_ulong (fio_ulong_t fnum)
1263 {
1264 return extract_unsigned_integer ((gdb_byte *) fnum, 8,
1265 BFD_ENDIAN_BIG);
1266 }
1267
1268 /* Unpack an fio_mode_t. */
1269
1270 static mode_t
1271 remote_fileio_to_host_mode (fio_mode_t fnum)
1272 {
1273 return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
1274 0);
1275 }
1276
1277 /* Unpack an fio_time_t. */
1278
1279 static time_t
1280 remote_fileio_to_host_time (fio_time_t fnum)
1281 {
1282 return remote_fileio_to_host_uint (fnum);
1283 }
1284
1285
1286 /* See remote-fileio.h. */
1287
1288 void
1289 remote_fileio_to_host_stat (struct fio_stat *fst, struct stat *st)
1290 {
1291 memset (st, 0, sizeof (struct stat));
1292
1293 st->st_dev = remote_fileio_to_host_uint (fst->fst_dev);
1294 st->st_ino = remote_fileio_to_host_uint (fst->fst_ino);
1295 st->st_mode = remote_fileio_to_host_mode (fst->fst_mode);
1296 st->st_nlink = remote_fileio_to_host_uint (fst->fst_nlink);
1297 st->st_uid = remote_fileio_to_host_uint (fst->fst_uid);
1298 st->st_gid = remote_fileio_to_host_uint (fst->fst_gid);
1299 st->st_rdev = remote_fileio_to_host_uint (fst->fst_rdev);
1300 st->st_size = remote_fileio_to_host_ulong (fst->fst_size);
1301 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1302 st->st_blksize = remote_fileio_to_host_ulong (fst->fst_blksize);
1303 #endif
1304 #if HAVE_STRUCT_STAT_ST_BLOCKS
1305 st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
1306 #endif
1307 st->st_atime = remote_fileio_to_host_time (fst->fst_atime);
1308 st->st_mtime = remote_fileio_to_host_time (fst->fst_mtime);
1309 st->st_ctime = remote_fileio_to_host_time (fst->fst_ctime);
1310 }
1311 \f
1312
1313 static void
1314 set_system_call_allowed (char *args, int from_tty)
1315 {
1316 if (args)
1317 {
1318 char *arg_end;
1319 int val = strtoul (args, &arg_end, 10);
1320
1321 if (*args && *arg_end == '\0')
1322 {
1323 remote_fio_system_call_allowed = !!val;
1324 return;
1325 }
1326 }
1327 error (_("Illegal argument for \"set remote system-call-allowed\" command"));
1328 }
1329
1330 static void
1331 show_system_call_allowed (char *args, int from_tty)
1332 {
1333 if (args)
1334 error (_("Garbage after \"show remote "
1335 "system-call-allowed\" command: `%s'"), args);
1336 printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1337 remote_fio_system_call_allowed ? "" : "not ");
1338 }
1339
1340 void
1341 initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
1342 struct cmd_list_element *remote_show_cmdlist)
1343 {
1344 add_cmd ("system-call-allowed", no_class,
1345 set_system_call_allowed,
1346 _("Set if the host system(3) call is allowed for the target."),
1347 &remote_set_cmdlist);
1348 add_cmd ("system-call-allowed", no_class,
1349 show_system_call_allowed,
1350 _("Show if the host system(3) call is allowed for the target."),
1351 &remote_show_cmdlist);
1352 }
This page took 0.081367 seconds and 3 git commands to generate.