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