Add method/format information to =record-started
[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
bb7c96de
PA
301/* The quit handler originally installed. */
302static quit_handler_ftype *remote_fileio_o_quit_handler;
449092f6 303
bb7c96de
PA
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. */
449092f6
CV
307
308static void
bb7c96de 309remote_fileio_quit_handler (void)
449092f6 310{
bb7c96de 311 quit ();
449092f6
CV
312}
313
314static void
315remote_fileio_reply (int retcode, int error)
316{
317 char buf[32];
bb7c96de 318 int ctrl_c = check_quit_flag ();
449092f6 319
449092f6
CV
320 strcpy (buf, "F");
321 if (retcode < 0)
322 {
323 strcat (buf, "-");
324 retcode = -retcode;
325 }
326 sprintf (buf + strlen (buf), "%x", retcode);
bb7c96de 327 if (error || ctrl_c)
449092f6 328 {
bb7c96de 329 if (error && ctrl_c)
449092f6
CV
330 error = FILEIO_EINTR;
331 if (error < 0)
332 {
333 strcat (buf, "-");
334 error = -error;
335 }
336 sprintf (buf + strlen (buf), ",%x", error);
bb7c96de 337 if (ctrl_c)
449092f6
CV
338 strcat (buf, ",C");
339 }
bb7c96de 340 quit_handler = remote_fileio_o_quit_handler;
449092f6
CV
341 putpkt (buf);
342}
343
344static void
cbcdb1f5 345remote_fileio_ioerror (void)
449092f6
CV
346{
347 remote_fileio_reply (-1, FILEIO_EIO);
348}
349
350static void
cbcdb1f5 351remote_fileio_badfd (void)
449092f6
CV
352{
353 remote_fileio_reply (-1, FILEIO_EBADF);
354}
355
356static void
357remote_fileio_return_errno (int retcode)
358{
3e43a32a 359 remote_fileio_reply (retcode, retcode < 0
7823a941 360 ? host_to_fileio_error (errno) : 0);
449092f6
CV
361}
362
363static void
364remote_fileio_return_success (int retcode)
365{
366 remote_fileio_reply (retcode, 0);
367}
368
449092f6
CV
369static void
370remote_fileio_func_open (char *buf)
371{
372 CORE_ADDR ptrval;
f7605bc2 373 int length;
449092f6
CV
374 long num;
375 int flags, fd;
376 mode_t mode;
377 char *pathname;
378 struct stat st;
379
0df8b418 380 /* 1. Parameter: Ptr to pathname / length incl. trailing zero. */
449092f6
CV
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
f7605bc2 401 /* Request pathname. */
224c3ddb 402 pathname = (char *) alloca (length);
f7605bc2 403 if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
449092f6
CV
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
0df8b418 411 for writing. */
449092f6
CV
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
614c279d 427 fd = gdb_open_cloexec (pathname, flags, mode);
449092f6
CV
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
438static void
439remote_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 }
cbcdb1f5
CV
450 fd = remote_fileio_map_fd ((int) num);
451 if (fd == FIO_FD_INVALID)
449092f6
CV
452 {
453 remote_fileio_badfd ();
454 return;
455 }
456
449092f6
CV
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
463static void
464remote_fileio_func_read (char *buf)
465{
466 long target_fd, num;
cbcdb1f5 467 LONGEST lnum;
449092f6 468 CORE_ADDR ptrval;
22e048c9 469 int fd, ret;
cfd77fa1 470 gdb_byte *buffer;
449092f6
CV
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 }
cbcdb1f5
CV
480 fd = remote_fileio_map_fd ((int) target_fd);
481 if (fd == FIO_FD_INVALID)
449092f6
CV
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
b86ab4ff 511 buffer = (gdb_byte *) xmalloc (16384);
449092f6
CV
512 if (remaining_buf)
513 {
449092f6
CV
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 {
b86ab4ff
DJ
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);
449092f6
CV
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:
cfd77fa1 555 buffer = (gdb_byte *) xmalloc (length);
449092f6
CV
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);
449092f6
CV
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.
0df8b418 567 The Ctrl-C flag is set in remote_fileio_reply() anyway. */
449092f6
CV
568 if (old_offset != new_offset)
569 ret = new_offset - old_offset;
570 }
571 break;
572 }
573
574 if (ret > 0)
575 {
f7605bc2
PA
576 errno = target_write_memory (ptrval, buffer, ret);
577 if (errno != 0)
578 ret = -1;
449092f6
CV
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
589static void
590remote_fileio_func_write (char *buf)
591{
592 long target_fd, num;
cbcdb1f5 593 LONGEST lnum;
449092f6 594 CORE_ADDR ptrval;
f7605bc2 595 int fd, ret;
cfd77fa1 596 gdb_byte *buffer;
449092f6
CV
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 }
cbcdb1f5
CV
605 fd = remote_fileio_map_fd ((int) target_fd);
606 if (fd == FIO_FD_INVALID)
449092f6
CV
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
cfd77fa1 626 buffer = (gdb_byte *) xmalloc (length);
f7605bc2 627 if (target_read_memory (ptrval, buffer, length) != 0)
449092f6
CV
628 {
629 xfree (buffer);
630 remote_fileio_ioerror ();
631 return;
632 }
633
449092f6
CV
634 switch (fd)
635 {
636 case FIO_FD_CONSOLE_IN:
637 remote_fileio_badfd ();
1ed489bd 638 xfree (buffer);
449092f6
CV
639 return;
640 case FIO_FD_CONSOLE_OUT:
cfd77fa1
DJ
641 ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
642 (char *) buffer, length);
449092f6
CV
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)
3e43a32a 649 errno = EBADF; /* Cygwin returns EACCESS when writing to a
0df8b418 650 R/O file. */
449092f6
CV
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
662static void
663remote_fileio_func_lseek (char *buf)
664{
665 long num;
cbcdb1f5 666 LONGEST lnum;
449092f6
CV
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 }
cbcdb1f5
CV
676 fd = remote_fileio_map_fd ((int) num);
677 if (fd == FIO_FD_INVALID)
449092f6
CV
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
449092f6
CV
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
715static void
716remote_fileio_func_rename (char *buf)
717{
86cc68a8 718 CORE_ADDR old_ptr, new_ptr;
f7605bc2 719 int old_len, new_len;
449092f6
CV
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 */
86cc68a8 725 if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
449092f6
CV
726 {
727 remote_fileio_ioerror ();
728 return;
729 }
86cc68a8
NS
730
731 /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
732 if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
449092f6
CV
733 {
734 remote_fileio_ioerror ();
735 return;
736 }
86cc68a8
NS
737
738 /* Request oldpath using 'm' packet */
224c3ddb 739 oldpath = (char *) alloca (old_len);
f7605bc2 740 if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
449092f6
CV
741 {
742 remote_fileio_ioerror ();
743 return;
744 }
86cc68a8 745
449092f6 746 /* Request newpath using 'm' packet */
224c3ddb 747 newpath = (char *) alloca (new_len);
f7605bc2 748 if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
449092f6
CV
749 {
750 remote_fileio_ioerror ();
751 return;
752 }
753
0df8b418 754 /* Only operate on regular files and directories. */
cbcdb1f5
CV
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)))
449092f6
CV
759 {
760 remote_fileio_reply (-1, FILEIO_EACCES);
761 return;
762 }
763
449092f6
CV
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
0df8b418 770 always EEXIST. */
449092f6
CV
771 if (errno == ENOTEMPTY)
772 errno = EEXIST;
773#ifdef __CYGWIN__
0df8b418 774 /* Workaround some Cygwin problems with correct errnos. */
449092f6
CV
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 {
d0d0ab16
CV
783 char oldfullpath[PATH_MAX];
784 char newfullpath[PATH_MAX];
449092f6
CV
785 int len;
786
d0d0ab16
CV
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);
449092f6 791 len = strlen (oldfullpath);
0ba1096a
KT
792 if (IS_DIR_SEPARATOR (newfullpath[len])
793 && !filename_ncmp (oldfullpath, newfullpath, len))
449092f6
CV
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
808static void
809remote_fileio_func_unlink (char *buf)
810{
811 CORE_ADDR ptrval;
f7605bc2 812 int length;
449092f6
CV
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 */
224c3ddb 824 pathname = (char *) alloca (length);
f7605bc2 825 if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
449092f6
CV
826 {
827 remote_fileio_ioerror ();
828 return;
829 }
830
831 /* Only operate on regular files (and directories, which allows to return
0df8b418 832 the correct return code). */
449092f6
CV
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
449092f6
CV
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
847static void
848remote_fileio_func_stat (char *buf)
849{
86cc68a8 850 CORE_ADDR statptr, nameptr;
f7605bc2 851 int ret, namelength;
449092f6 852 char *pathname;
cbcdb1f5 853 LONGEST lnum;
449092f6
CV
854 struct stat st;
855 struct fio_stat fst;
856
857 /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
86cc68a8 858 if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
449092f6
CV
859 {
860 remote_fileio_ioerror ();
861 return;
862 }
86cc68a8
NS
863
864 /* 2. Parameter: Ptr to struct stat */
865 if (remote_fileio_extract_long (&buf, &lnum))
449092f6
CV
866 {
867 remote_fileio_ioerror ();
868 return;
869 }
86cc68a8
NS
870 statptr = (CORE_ADDR) lnum;
871
872 /* Request pathname using 'm' packet */
224c3ddb 873 pathname = (char *) alloca (namelength);
f7605bc2 874 if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
449092f6
CV
875 {
876 remote_fileio_ioerror ();
877 return;
878 }
449092f6 879
449092f6
CV
880 ret = stat (pathname, &st);
881
882 if (ret == -1)
883 {
884 remote_fileio_return_errno (-1);
885 return;
886 }
0df8b418 887 /* Only operate on regular files and directories. */
449092f6
CV
888 if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
889 {
890 remote_fileio_reply (-1, FILEIO_EACCES);
891 return;
892 }
86cc68a8 893 if (statptr)
449092f6 894 {
7823a941
GB
895 host_to_fileio_stat (&st, &fst);
896 host_to_fileio_uint (0, fst.fst_dev);
f7605bc2
PA
897
898 errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
899 if (errno != 0)
449092f6
CV
900 {
901 remote_fileio_return_errno (-1);
902 return;
903 }
904 }
905 remote_fileio_return_success (ret);
906}
907
908static void
909remote_fileio_func_fstat (char *buf)
910{
911 CORE_ADDR ptrval;
22e048c9 912 int fd, ret;
449092f6 913 long target_fd;
cbcdb1f5 914 LONGEST lnum;
449092f6
CV
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 }
cbcdb1f5
CV
925 fd = remote_fileio_map_fd ((int) target_fd);
926 if (fd == FIO_FD_INVALID)
449092f6
CV
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
449092f6
CV
939 if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
940 {
7823a941 941 host_to_fileio_uint (1, fst.fst_dev);
2e3fd767 942 memset (&st, 0, sizeof (st));
449092f6
CV
943 st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
944 st.st_nlink = 1;
d3ea6809 945#ifdef HAVE_GETUID
449092f6 946 st.st_uid = getuid ();
d3ea6809
MM
947#endif
948#ifdef HAVE_GETGID
449092f6 949 st.st_gid = getgid ();
d3ea6809 950#endif
d3ea6809 951#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
449092f6 952 st.st_blksize = 512;
d3ea6809 953#endif
1dd727e9 954#if HAVE_STRUCT_STAT_ST_BLOCKS
449092f6 955 st.st_blocks = 0;
1dd727e9 956#endif
449092f6
CV
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 {
7823a941 973 host_to_fileio_stat (&st, &fst);
449092f6 974
f7605bc2
PA
975 errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
976 if (errno != 0)
449092f6
CV
977 {
978 remote_fileio_return_errno (-1);
979 return;
980 }
981 }
982 remote_fileio_return_success (ret);
983}
984
985static void
986remote_fileio_func_gettimeofday (char *buf)
987{
cbcdb1f5 988 LONGEST lnum;
449092f6 989 CORE_ADDR ptrval;
22e048c9 990 int ret;
449092f6
CV
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;
0df8b418 1001 /* 2. Parameter: some pointer value... */
449092f6
CV
1002 if (remote_fileio_extract_long (&buf, &lnum))
1003 {
1004 remote_fileio_ioerror ();
1005 return;
1006 }
0df8b418 1007 /* ...which has to be NULL. */
449092f6
CV
1008 if (lnum)
1009 {
1010 remote_fileio_reply (-1, FILEIO_EINVAL);
1011 return;
1012 }
1013
449092f6
CV
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
f7605bc2
PA
1026 errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1027 if (errno != 0)
449092f6
CV
1028 {
1029 remote_fileio_return_errno (-1);
1030 return;
1031 }
1032 }
1033 remote_fileio_return_success (ret);
1034}
1035
1036static void
1037remote_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 }
449092f6
CV
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
1053static void
1054remote_fileio_func_system (char *buf)
1055{
1056 CORE_ADDR ptrval;
22e048c9 1057 int ret, length;
5600ea19 1058 char *cmdline = NULL;
449092f6
CV
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 }
5600ea19
NS
1066
1067 if (length)
449092f6 1068 {
5600ea19 1069 /* Request commandline using 'm' packet */
224c3ddb 1070 cmdline = (char *) alloca (length);
f7605bc2 1071 if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
5600ea19
NS
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);
449092f6
CV
1088 return;
1089 }
1090
449092f6
CV
1091 ret = system (cmdline);
1092
5600ea19
NS
1093 if (!length)
1094 remote_fileio_return_success (ret);
1095 else if (ret == -1)
449092f6
CV
1096 remote_fileio_return_errno (-1);
1097 else
1098 remote_fileio_return_success (WEXITSTATUS (ret));
1099}
1100
1101static struct {
1102 char *name;
1103 void (*func)(char *);
1104} remote_fio_func_map[] = {
d5d6fca5
DJ
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 }
449092f6
CV
1118};
1119
1120static int
1121do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
1122{
19ba03f4 1123 char *buf = (char *) buf_arg;
449092f6
CV
1124 char *c;
1125 int idx;
1126
bb7c96de 1127 quit_handler = remote_fileio_quit_handler;
449092f6
CV
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;
0df8b418 1137 if (!remote_fio_func_map[idx].name) /* ERROR: No such function. */
449092f6
CV
1138 return RETURN_ERROR;
1139 remote_fio_func_map[idx].func (c);
1140 return 0;
1141}
1142
ad9a8f3f
NS
1143/* Close any open descriptors, and reinitialize the file mapping. */
1144
1145void
1146remote_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 {
6c761d9c 1159 xfree (remote_fio_data.fd_map);
ad9a8f3f
NS
1160 remote_fio_data.fd_map = NULL;
1161 remote_fio_data.fd_map_size = 0;
1162 }
1163}
1164
0df8b418
MS
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
3a29589a
DJ
1167 acknowledged the Ctrl-C sent asynchronously earlier. */
1168
449092f6 1169void
3a29589a 1170remote_fileio_request (char *buf, int ctrlc_pending_p)
449092f6
CV
1171{
1172 int ex;
1173
bb7c96de
PA
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;
449092f6 1179
3a29589a 1180 if (ctrlc_pending_p)
449092f6 1181 {
3a29589a
DJ
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. */
bb7c96de 1185 set_quit_flag ();
3a29589a
DJ
1186 remote_fileio_reply (-1, FILEIO_EINTR);
1187 }
1188 else
1189 {
79a45e25
PA
1190 ex = catch_exceptions (current_uiout,
1191 do_remote_fileio_request, (void *)buf,
3a29589a
DJ
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 }
449092f6
CV
1204 }
1205
bb7c96de 1206 quit_handler = remote_fileio_o_quit_handler;
449092f6 1207}
0a93529c
GB
1208\f
1209
1210/* Unpack an fio_uint_t. */
1211
1212static unsigned int
1213remote_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
1221static ULONGEST
1222remote_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
1230static mode_t
1231remote_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
1239static time_t
1240remote_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
1248void
1249remote_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
449092f6
CV
1272
1273static void
1274set_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);
123f5f96 1280
449092f6
CV
1281 if (*args && *arg_end == '\0')
1282 {
1283 remote_fio_system_call_allowed = !!val;
1284 return;
1285 }
1286 }
8a3fe4f8 1287 error (_("Illegal argument for \"set remote system-call-allowed\" command"));
449092f6
CV
1288}
1289
1290static void
1291show_system_call_allowed (char *args, int from_tty)
1292{
1293 if (args)
3e43a32a
MS
1294 error (_("Garbage after \"show remote "
1295 "system-call-allowed\" command: `%s'"), args);
449092f6
CV
1296 printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1297 remote_fio_system_call_allowed ? "" : "not ");
1298}
1299
1300void
1301initialize_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,
1a966eab 1306 _("Set if the host system(3) call is allowed for the target."),
449092f6
CV
1307 &remote_set_cmdlist);
1308 add_cmd ("system-call-allowed", no_class,
1309 show_system_call_allowed,
1a966eab 1310 _("Show if the host system(3) call is allowed for the target."),
449092f6
CV
1311 &remote_show_cmdlist);
1312}
This page took 1.262467 seconds and 4 git commands to generate.