]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/remote-fileio.c
gdb: change return type of check_quit_flag to bool
[thirdparty/binutils-gdb.git] / gdb / remote-fileio.c
CommitLineData
449092f6
CV
1/* Remote File-I/O communications
2
1d506c26 3 Copyright (C) 2003-2024 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 21
ec452525 22#include "extract-store-integer.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"
400b5eca 28#include "gdbsupport/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__
ef0f16cc 36#include <sys/cygwin.h>
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)
dda83cd7 64 remote_fio_data.fd_map[i] = FIO_FD_INVALID;
449092f6
CV
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:
dda83cd7 202 *flag = SEEK_SET;
449092f6
CV
203 break;
204 case FILEIO_SEEK_CUR:
dda83cd7 205 *flag = SEEK_CUR;
449092f6
CV
206 break;
207 case FILEIO_SEEK_END:
dda83cd7 208 *flag = SEEK_END;
449092f6
CV
209 break;
210 default:
dda83cd7 211 return -1;
449092f6
CV
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')
dda83cd7 239 *retlong += **buf - '0';
449092f6 240 else if (**buf >= 'a' && **buf <= 'f')
dda83cd7 241 *retlong += **buf - 'a' + 10;
449092f6 242 else if (**buf >= 'A' && **buf <= 'F')
dda83cd7 243 *retlong += **buf - 'A' + 10;
449092f6 244 else
dda83cd7 245 return -1;
449092f6
CV
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];
14872939 319 bool 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)
dda83cd7 331 error = FILEIO_EINTR;
449092f6 332 if (error < 0)
dda83cd7 333 {
449092f6
CV
334 strcat (buf, "-");
335 error = -error;
336 }
337 sprintf (buf + strlen (buf), ",%x", error);
bb7c96de 338 if (ctrl_c)
dda83cd7 339 strcat (buf, ",C");
449092f6 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
13084383 428 fd = gdb_open_cloexec (pathname, flags, mode).release ();
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. */
da5bd37e 544 ret = gdb_stdtargin->read ((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:
da5bd37e
TT
642 {
643 ui_file *file = target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr;
644 file->write ((char *) buffer, length);
645 file->flush ();
646 ret = length;
647 }
449092f6
CV
648 break;
649 default:
650 ret = write (fd, buffer, length);
651 if (ret < 0 && errno == EACCES)
3e43a32a 652 errno = EBADF; /* Cygwin returns EACCESS when writing to a
0df8b418 653 R/O file. */
449092f6
CV
654 break;
655 }
656
657 if (ret < 0)
6b8edb51 658 remote_fileio_return_errno (remote, -1);
449092f6 659 else
6b8edb51 660 remote_fileio_return_success (remote, ret);
449092f6
CV
661
662 xfree (buffer);
663}
664
665static void
6b8edb51 666remote_fileio_func_lseek (remote_target *remote, char *buf)
449092f6
CV
667{
668 long num;
cbcdb1f5 669 LONGEST lnum;
449092f6
CV
670 int fd, flag;
671 off_t offset, ret;
672
673 /* 1. Parameter: file descriptor */
674 if (remote_fileio_extract_int (&buf, &num))
675 {
6b8edb51 676 remote_fileio_ioerror (remote);
449092f6
CV
677 return;
678 }
cbcdb1f5
CV
679 fd = remote_fileio_map_fd ((int) num);
680 if (fd == FIO_FD_INVALID)
449092f6 681 {
6b8edb51 682 remote_fileio_badfd (remote);
449092f6
CV
683 return;
684 }
685 else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
686 {
6b8edb51 687 remote_fileio_reply (remote, -1, FILEIO_ESPIPE);
449092f6
CV
688 return;
689 }
690
691 /* 2. Parameter: offset */
692 if (remote_fileio_extract_long (&buf, &lnum))
693 {
6b8edb51 694 remote_fileio_ioerror (remote);
449092f6
CV
695 return;
696 }
697 offset = (off_t) lnum;
698 /* 3. Parameter: flag */
699 if (remote_fileio_extract_int (&buf, &num))
700 {
6b8edb51 701 remote_fileio_ioerror (remote);
449092f6
CV
702 return;
703 }
704 if (remote_fileio_seek_flag_to_host (num, &flag))
705 {
6b8edb51 706 remote_fileio_reply (remote, -1, FILEIO_EINVAL);
449092f6
CV
707 return;
708 }
709
449092f6
CV
710 ret = lseek (fd, offset, flag);
711
712 if (ret == (off_t) -1)
6b8edb51 713 remote_fileio_return_errno (remote, -1);
449092f6 714 else
6b8edb51 715 remote_fileio_return_success (remote, ret);
449092f6
CV
716}
717
718static void
6b8edb51 719remote_fileio_func_rename (remote_target *remote, char *buf)
449092f6 720{
86cc68a8 721 CORE_ADDR old_ptr, new_ptr;
f7605bc2 722 int old_len, new_len;
449092f6
CV
723 char *oldpath, *newpath;
724 int ret, of, nf;
725 struct stat ost, nst;
726
727 /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
86cc68a8 728 if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
449092f6 729 {
6b8edb51 730 remote_fileio_ioerror (remote);
449092f6
CV
731 return;
732 }
86cc68a8
NS
733
734 /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
735 if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
449092f6 736 {
6b8edb51 737 remote_fileio_ioerror (remote);
449092f6
CV
738 return;
739 }
86cc68a8
NS
740
741 /* Request oldpath using 'm' packet */
224c3ddb 742 oldpath = (char *) alloca (old_len);
f7605bc2 743 if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
449092f6 744 {
6b8edb51 745 remote_fileio_ioerror (remote);
449092f6
CV
746 return;
747 }
86cc68a8 748
449092f6 749 /* Request newpath using 'm' packet */
224c3ddb 750 newpath = (char *) alloca (new_len);
f7605bc2 751 if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
449092f6 752 {
6b8edb51 753 remote_fileio_ioerror (remote);
449092f6
CV
754 return;
755 }
756
0df8b418 757 /* Only operate on regular files and directories. */
cbcdb1f5
CV
758 of = stat (oldpath, &ost);
759 nf = stat (newpath, &nst);
760 if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
761 || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
449092f6 762 {
6b8edb51 763 remote_fileio_reply (remote, -1, FILEIO_EACCES);
449092f6
CV
764 return;
765 }
766
449092f6
CV
767 ret = rename (oldpath, newpath);
768
769 if (ret == -1)
770 {
771 /* Special case: newpath is a non-empty directory. Some systems
dda83cd7 772 return ENOTEMPTY, some return EEXIST. We coerce that to be
0df8b418 773 always EEXIST. */
449092f6 774 if (errno == ENOTEMPTY)
dda83cd7 775 errno = EEXIST;
449092f6 776#ifdef __CYGWIN__
0df8b418 777 /* Workaround some Cygwin problems with correct errnos. */
449092f6 778 if (errno == EACCES)
dda83cd7 779 {
449092f6
CV
780 if (!of && !nf && S_ISDIR (nst.st_mode))
781 {
782 if (S_ISREG (ost.st_mode))
783 errno = EISDIR;
784 else
785 {
d0d0ab16
CV
786 char oldfullpath[PATH_MAX];
787 char newfullpath[PATH_MAX];
449092f6
CV
788 int len;
789
d0d0ab16
CV
790 cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
791 PATH_MAX);
792 cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
793 PATH_MAX);
449092f6 794 len = strlen (oldfullpath);
0ba1096a
KT
795 if (IS_DIR_SEPARATOR (newfullpath[len])
796 && !filename_ncmp (oldfullpath, newfullpath, len))
449092f6
CV
797 errno = EINVAL;
798 else
799 errno = EEXIST;
800 }
801 }
802 }
803#endif
804
6b8edb51 805 remote_fileio_return_errno (remote, -1);
449092f6
CV
806 }
807 else
6b8edb51 808 remote_fileio_return_success (remote, ret);
449092f6
CV
809}
810
811static void
6b8edb51 812remote_fileio_func_unlink (remote_target *remote, char *buf)
449092f6
CV
813{
814 CORE_ADDR ptrval;
f7605bc2 815 int length;
449092f6
CV
816 char *pathname;
817 int ret;
818 struct stat st;
819
820 /* Parameter: Ptr to pathname / length incl. trailing zero */
821 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
822 {
6b8edb51 823 remote_fileio_ioerror (remote);
449092f6
CV
824 return;
825 }
826 /* Request pathname using 'm' packet */
224c3ddb 827 pathname = (char *) alloca (length);
f7605bc2 828 if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
449092f6 829 {
6b8edb51 830 remote_fileio_ioerror (remote);
449092f6
CV
831 return;
832 }
833
834 /* Only operate on regular files (and directories, which allows to return
0df8b418 835 the correct return code). */
449092f6
CV
836 if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
837 {
6b8edb51 838 remote_fileio_reply (remote, -1, FILEIO_ENODEV);
449092f6
CV
839 return;
840 }
841
449092f6
CV
842 ret = unlink (pathname);
843
844 if (ret == -1)
6b8edb51 845 remote_fileio_return_errno (remote, -1);
449092f6 846 else
6b8edb51 847 remote_fileio_return_success (remote, ret);
449092f6
CV
848}
849
850static void
6b8edb51 851remote_fileio_func_stat (remote_target *remote, char *buf)
449092f6 852{
86cc68a8 853 CORE_ADDR statptr, nameptr;
f7605bc2 854 int ret, namelength;
449092f6 855 char *pathname;
cbcdb1f5 856 LONGEST lnum;
449092f6
CV
857 struct stat st;
858 struct fio_stat fst;
859
860 /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
86cc68a8 861 if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
449092f6 862 {
6b8edb51 863 remote_fileio_ioerror (remote);
449092f6
CV
864 return;
865 }
86cc68a8
NS
866
867 /* 2. Parameter: Ptr to struct stat */
868 if (remote_fileio_extract_long (&buf, &lnum))
449092f6 869 {
6b8edb51 870 remote_fileio_ioerror (remote);
449092f6
CV
871 return;
872 }
86cc68a8
NS
873 statptr = (CORE_ADDR) lnum;
874
875 /* Request pathname using 'm' packet */
224c3ddb 876 pathname = (char *) alloca (namelength);
f7605bc2 877 if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
449092f6 878 {
6b8edb51 879 remote_fileio_ioerror (remote);
449092f6
CV
880 return;
881 }
449092f6 882
449092f6
CV
883 ret = stat (pathname, &st);
884
885 if (ret == -1)
886 {
6b8edb51 887 remote_fileio_return_errno (remote, -1);
449092f6
CV
888 return;
889 }
0df8b418 890 /* Only operate on regular files and directories. */
449092f6
CV
891 if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
892 {
6b8edb51 893 remote_fileio_reply (remote, -1, FILEIO_EACCES);
449092f6
CV
894 return;
895 }
86cc68a8 896 if (statptr)
449092f6 897 {
7823a941
GB
898 host_to_fileio_stat (&st, &fst);
899 host_to_fileio_uint (0, fst.fst_dev);
f7605bc2
PA
900
901 errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
902 if (errno != 0)
449092f6 903 {
6b8edb51 904 remote_fileio_return_errno (remote, -1);
449092f6
CV
905 return;
906 }
907 }
6b8edb51 908 remote_fileio_return_success (remote, ret);
449092f6
CV
909}
910
911static void
6b8edb51 912remote_fileio_func_fstat (remote_target *remote, char *buf)
449092f6
CV
913{
914 CORE_ADDR ptrval;
22e048c9 915 int fd, ret;
449092f6 916 long target_fd;
cbcdb1f5 917 LONGEST lnum;
449092f6
CV
918 struct stat st;
919 struct fio_stat fst;
920 struct timeval tv;
921
922 /* 1. Parameter: file descriptor */
923 if (remote_fileio_extract_int (&buf, &target_fd))
924 {
6b8edb51 925 remote_fileio_ioerror (remote);
449092f6
CV
926 return;
927 }
cbcdb1f5
CV
928 fd = remote_fileio_map_fd ((int) target_fd);
929 if (fd == FIO_FD_INVALID)
449092f6 930 {
6b8edb51 931 remote_fileio_badfd (remote);
449092f6
CV
932 return;
933 }
934 /* 2. Parameter: Ptr to struct stat */
935 if (remote_fileio_extract_long (&buf, &lnum))
936 {
6b8edb51 937 remote_fileio_ioerror (remote);
449092f6
CV
938 return;
939 }
940 ptrval = (CORE_ADDR) lnum;
941
449092f6
CV
942 if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
943 {
7823a941 944 host_to_fileio_uint (1, fst.fst_dev);
2e3fd767 945 memset (&st, 0, sizeof (st));
449092f6
CV
946 st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
947 st.st_nlink = 1;
d3ea6809 948#ifdef HAVE_GETUID
449092f6 949 st.st_uid = getuid ();
d3ea6809
MM
950#endif
951#ifdef HAVE_GETGID
449092f6 952 st.st_gid = getgid ();
d3ea6809 953#endif
d3ea6809 954#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
449092f6 955 st.st_blksize = 512;
d3ea6809 956#endif
1dd727e9 957#if HAVE_STRUCT_STAT_ST_BLOCKS
449092f6 958 st.st_blocks = 0;
1dd727e9 959#endif
449092f6
CV
960 if (!gettimeofday (&tv, NULL))
961 st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
962 else
dda83cd7 963 st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
449092f6
CV
964 ret = 0;
965 }
966 else
967 ret = fstat (fd, &st);
968
969 if (ret == -1)
970 {
6b8edb51 971 remote_fileio_return_errno (remote, -1);
449092f6
CV
972 return;
973 }
974 if (ptrval)
975 {
7823a941 976 host_to_fileio_stat (&st, &fst);
449092f6 977
f7605bc2
PA
978 errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
979 if (errno != 0)
449092f6 980 {
6b8edb51 981 remote_fileio_return_errno (remote, -1);
449092f6
CV
982 return;
983 }
984 }
6b8edb51 985 remote_fileio_return_success (remote, ret);
449092f6
CV
986}
987
988static void
6b8edb51 989remote_fileio_func_gettimeofday (remote_target *remote, char *buf)
449092f6 990{
cbcdb1f5 991 LONGEST lnum;
449092f6 992 CORE_ADDR ptrval;
22e048c9 993 int ret;
449092f6
CV
994 struct timeval tv;
995 struct fio_timeval ftv;
996
997 /* 1. Parameter: struct timeval pointer */
998 if (remote_fileio_extract_long (&buf, &lnum))
999 {
6b8edb51 1000 remote_fileio_ioerror (remote);
449092f6
CV
1001 return;
1002 }
1003 ptrval = (CORE_ADDR) lnum;
0df8b418 1004 /* 2. Parameter: some pointer value... */
449092f6
CV
1005 if (remote_fileio_extract_long (&buf, &lnum))
1006 {
6b8edb51 1007 remote_fileio_ioerror (remote);
449092f6
CV
1008 return;
1009 }
0df8b418 1010 /* ...which has to be NULL. */
449092f6
CV
1011 if (lnum)
1012 {
6b8edb51 1013 remote_fileio_reply (remote, -1, FILEIO_EINVAL);
449092f6
CV
1014 return;
1015 }
1016
449092f6
CV
1017 ret = gettimeofday (&tv, NULL);
1018
1019 if (ret == -1)
1020 {
6b8edb51 1021 remote_fileio_return_errno (remote, -1);
449092f6
CV
1022 return;
1023 }
1024
1025 if (ptrval)
1026 {
1027 remote_fileio_to_fio_timeval (&tv, &ftv);
1028
f7605bc2
PA
1029 errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
1030 if (errno != 0)
449092f6 1031 {
6b8edb51 1032 remote_fileio_return_errno (remote, -1);
449092f6
CV
1033 return;
1034 }
1035 }
6b8edb51 1036 remote_fileio_return_success (remote, ret);
449092f6
CV
1037}
1038
1039static void
6b8edb51 1040remote_fileio_func_isatty (remote_target *remote, char *buf)
449092f6
CV
1041{
1042 long target_fd;
1043 int fd;
1044
1045 /* Parameter: file descriptor */
1046 if (remote_fileio_extract_int (&buf, &target_fd))
1047 {
6b8edb51 1048 remote_fileio_ioerror (remote);
449092f6
CV
1049 return;
1050 }
449092f6 1051 fd = remote_fileio_map_fd ((int) target_fd);
6b8edb51
PA
1052 int ret = fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT ? 1 : 0;
1053 remote_fileio_return_success (remote, ret);
449092f6
CV
1054}
1055
1056static void
6b8edb51 1057remote_fileio_func_system (remote_target *remote, char *buf)
449092f6
CV
1058{
1059 CORE_ADDR ptrval;
22e048c9 1060 int ret, length;
5600ea19 1061 char *cmdline = NULL;
449092f6
CV
1062
1063 /* Parameter: Ptr to commandline / length incl. trailing zero */
1064 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1065 {
6b8edb51 1066 remote_fileio_ioerror (remote);
449092f6
CV
1067 return;
1068 }
5600ea19
NS
1069
1070 if (length)
449092f6 1071 {
5600ea19 1072 /* Request commandline using 'm' packet */
224c3ddb 1073 cmdline = (char *) alloca (length);
f7605bc2 1074 if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
5600ea19 1075 {
6b8edb51 1076 remote_fileio_ioerror (remote);
5600ea19
NS
1077 return;
1078 }
1079 }
1080
85102364 1081 /* Check if system(3) has been explicitly allowed using the
5600ea19
NS
1082 `set remote system-call-allowed 1' command. If length is 0,
1083 indicating a NULL parameter to the system call, return zero to
1084 indicate a shell is not available. Otherwise fail with EPERM. */
1085 if (!remote_fio_system_call_allowed)
1086 {
1087 if (!length)
6b8edb51 1088 remote_fileio_return_success (remote, 0);
5600ea19 1089 else
6b8edb51 1090 remote_fileio_reply (remote, -1, FILEIO_EPERM);
449092f6
CV
1091 return;
1092 }
1093
449092f6
CV
1094 ret = system (cmdline);
1095
5600ea19 1096 if (!length)
6b8edb51 1097 remote_fileio_return_success (remote, ret);
5600ea19 1098 else if (ret == -1)
6b8edb51 1099 remote_fileio_return_errno (remote, -1);
449092f6 1100 else
6b8edb51 1101 remote_fileio_return_success (remote, WEXITSTATUS (ret));
449092f6
CV
1102}
1103
1104static struct {
a121b7c1 1105 const char *name;
6b8edb51 1106 void (*func)(remote_target *remote, char *);
449092f6 1107} remote_fio_func_map[] = {
d5d6fca5
DJ
1108 { "open", remote_fileio_func_open },
1109 { "close", remote_fileio_func_close },
1110 { "read", remote_fileio_func_read },
1111 { "write", remote_fileio_func_write },
1112 { "lseek", remote_fileio_func_lseek },
1113 { "rename", remote_fileio_func_rename },
1114 { "unlink", remote_fileio_func_unlink },
1115 { "stat", remote_fileio_func_stat },
1116 { "fstat", remote_fileio_func_fstat },
1117 { "gettimeofday", remote_fileio_func_gettimeofday },
1118 { "isatty", remote_fileio_func_isatty },
1119 { "system", remote_fileio_func_system },
1120 { NULL, NULL }
449092f6
CV
1121};
1122
65630365 1123static void
6b8edb51 1124do_remote_fileio_request (remote_target *remote, char *buf)
449092f6 1125{
449092f6
CV
1126 char *c;
1127 int idx;
1128
bb7c96de 1129 quit_handler = remote_fileio_quit_handler;
449092f6
CV
1130
1131 c = strchr (++buf, ',');
1132 if (c)
1133 *c++ = '\0';
1134 else
1135 c = strchr (buf, '\0');
1136 for (idx = 0; remote_fio_func_map[idx].name; ++idx)
1137 if (!strcmp (remote_fio_func_map[idx].name, buf))
1138 break;
65630365 1139 if (!remote_fio_func_map[idx].name)
6b8edb51 1140 remote_fileio_reply (remote, -1, FILEIO_ENOSYS);
65630365 1141 else
6b8edb51 1142 remote_fio_func_map[idx].func (remote, c);
449092f6
CV
1143}
1144
ad9a8f3f
NS
1145/* Close any open descriptors, and reinitialize the file mapping. */
1146
1147void
1148remote_fileio_reset (void)
1149{
1150 int ix;
1151
1152 for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1153 {
1154 int fd = remote_fio_data.fd_map[ix];
1155
1156 if (fd >= 0)
1157 close (fd);
1158 }
1159 if (remote_fio_data.fd_map)
1160 {
6c761d9c 1161 xfree (remote_fio_data.fd_map);
ad9a8f3f
NS
1162 remote_fio_data.fd_map = NULL;
1163 remote_fio_data.fd_map_size = 0;
1164 }
1165}
1166
0df8b418
MS
1167/* Handle a file I/O request. BUF points to the packet containing the
1168 request. CTRLC_PENDING_P should be nonzero if the target has not
3a29589a
DJ
1169 acknowledged the Ctrl-C sent asynchronously earlier. */
1170
449092f6 1171void
6b8edb51 1172remote_fileio_request (remote_target *remote, char *buf, int ctrlc_pending_p)
449092f6 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 ();
6b8edb51 1186 remote_fileio_reply (remote, -1, FILEIO_EINTR);
3a29589a
DJ
1187 }
1188 else
1189 {
a70b8144 1190 try
3a29589a 1191 {
6b8edb51 1192 do_remote_fileio_request (remote, buf);
65630365 1193 }
363429d5
KB
1194 catch (const gdb_exception_forced_quit &ex)
1195 {
1196 throw;
1197 }
1198 catch (const gdb_exception_quit &ex)
1199 {
1200 remote_fileio_reply (remote, -1, FILEIO_EINTR);
1201 }
230d2906 1202 catch (const gdb_exception &ex)
65630365 1203 {
363429d5 1204 remote_fileio_reply (remote, -1, FILEIO_EIO);
3a29589a 1205 }
449092f6
CV
1206 }
1207
bb7c96de 1208 quit_handler = remote_fileio_o_quit_handler;
449092f6 1209}
0a93529c
GB
1210\f
1211
1212/* Unpack an fio_uint_t. */
1213
1214static unsigned int
1215remote_fileio_to_host_uint (fio_uint_t fnum)
1216{
1217 return extract_unsigned_integer ((gdb_byte *) fnum, 4,
1218 BFD_ENDIAN_BIG);
1219}
1220
1221/* Unpack an fio_ulong_t. */
1222
1223static ULONGEST
1224remote_fileio_to_host_ulong (fio_ulong_t fnum)
1225{
1226 return extract_unsigned_integer ((gdb_byte *) fnum, 8,
1227 BFD_ENDIAN_BIG);
1228}
1229
1230/* Unpack an fio_mode_t. */
1231
1232static mode_t
1233remote_fileio_to_host_mode (fio_mode_t fnum)
1234{
1235 return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
1236 0);
1237}
1238
1239/* Unpack an fio_time_t. */
1240
1241static time_t
1242remote_fileio_to_host_time (fio_time_t fnum)
1243{
1244 return remote_fileio_to_host_uint (fnum);
1245}
1246
1247
1248/* See remote-fileio.h. */
1249
1250void
1251remote_fileio_to_host_stat (struct fio_stat *fst, struct stat *st)
1252{
1253 memset (st, 0, sizeof (struct stat));
1254
1255 st->st_dev = remote_fileio_to_host_uint (fst->fst_dev);
1256 st->st_ino = remote_fileio_to_host_uint (fst->fst_ino);
1257 st->st_mode = remote_fileio_to_host_mode (fst->fst_mode);
1258 st->st_nlink = remote_fileio_to_host_uint (fst->fst_nlink);
1259 st->st_uid = remote_fileio_to_host_uint (fst->fst_uid);
1260 st->st_gid = remote_fileio_to_host_uint (fst->fst_gid);
1261 st->st_rdev = remote_fileio_to_host_uint (fst->fst_rdev);
1262 st->st_size = remote_fileio_to_host_ulong (fst->fst_size);
1263#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1264 st->st_blksize = remote_fileio_to_host_ulong (fst->fst_blksize);
1265#endif
1266#if HAVE_STRUCT_STAT_ST_BLOCKS
1267 st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
1268#endif
1269 st->st_atime = remote_fileio_to_host_time (fst->fst_atime);
1270 st->st_mtime = remote_fileio_to_host_time (fst->fst_mtime);
1271 st->st_ctime = remote_fileio_to_host_time (fst->fst_ctime);
1272}
1273\f
449092f6
CV
1274
1275static void
442019e1 1276set_system_call_allowed (const char *args, int from_tty)
449092f6
CV
1277{
1278 if (args)
1279 {
1280 char *arg_end;
1281 int val = strtoul (args, &arg_end, 10);
123f5f96 1282
449092f6 1283 if (*args && *arg_end == '\0')
dda83cd7 1284 {
449092f6
CV
1285 remote_fio_system_call_allowed = !!val;
1286 return;
1287 }
1288 }
8a3fe4f8 1289 error (_("Illegal argument for \"set remote system-call-allowed\" command"));
449092f6
CV
1290}
1291
1292static void
442019e1 1293show_system_call_allowed (const char *args, int from_tty)
449092f6
CV
1294{
1295 if (args)
3e43a32a
MS
1296 error (_("Garbage after \"show remote "
1297 "system-call-allowed\" command: `%s'"), args);
6cb06a8c
TT
1298 gdb_printf ("Calling host system(3) call from target is %sallowed\n",
1299 remote_fio_system_call_allowed ? "" : "not ");
449092f6
CV
1300}
1301
1302void
3f4d92eb
PW
1303initialize_remote_fileio (struct cmd_list_element **remote_set_cmdlist,
1304 struct cmd_list_element **remote_show_cmdlist)
449092f6
CV
1305{
1306 add_cmd ("system-call-allowed", no_class,
1307 set_system_call_allowed,
1a966eab 1308 _("Set if the host system(3) call is allowed for the target."),
3f4d92eb 1309 remote_set_cmdlist);
449092f6
CV
1310 add_cmd ("system-call-allowed", no_class,
1311 show_system_call_allowed,
1a966eab 1312 _("Show if the host system(3) call is allowed for the target."),
3f4d92eb 1313 remote_show_cmdlist);
449092f6 1314}