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