Updated copyright notices for most files.
[deliverable/binutils-gdb.git] / gdb / remote-fileio.c
CommitLineData
449092f6
CV
1/* Remote File-I/O communications
2
9b254dd1 3 Copyright (C) 2003, 2005, 2006, 2007, 2008 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
CV
19
20/* See the GDB User Guide for details of the GDB remote protocol. */
21
22#include "defs.h"
23#include "gdb_string.h"
24#include "gdbcmd.h"
25#include "remote.h"
26#include "gdb/fileio.h"
0ef75e11
AC
27#include "gdb_wait.h"
28#include "gdb_stat.h"
60250e8b 29#include "exceptions.h"
cd90e54f 30#include "remote-fileio.h"
449092f6 31
449092f6
CV
32#include <fcntl.h>
33#include <sys/time.h>
449092f6 34#ifdef __CYGWIN__
0ef75e11 35#include <sys/cygwin.h> /* For cygwin_conv_to_full_posix_path. */
449092f6 36#endif
449092f6
CV
37#include <signal.h>
38
39static struct {
40 int *fd_map;
41 int fd_map_size;
42} remote_fio_data;
43
44#define FIO_FD_INVALID -1
45#define FIO_FD_CONSOLE_IN -2
46#define FIO_FD_CONSOLE_OUT -3
47
48static int remote_fio_system_call_allowed = 0;
49
50static int
cbcdb1f5 51remote_fileio_init_fd_map (void)
449092f6
CV
52{
53 int i;
54
55 if (!remote_fio_data.fd_map)
56 {
57 remote_fio_data.fd_map = (int *) xmalloc (10 * sizeof (int));
58 remote_fio_data.fd_map_size = 10;
59 remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
60 remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
61 remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
62 for (i = 3; i < 10; ++i)
63 remote_fio_data.fd_map[i] = FIO_FD_INVALID;
64 }
65 return 3;
66}
67
68static int
cbcdb1f5 69remote_fileio_resize_fd_map (void)
449092f6 70{
9f8e6999
MG
71 int i = remote_fio_data.fd_map_size;
72
449092f6
CV
73 if (!remote_fio_data.fd_map)
74 return remote_fileio_init_fd_map ();
75 remote_fio_data.fd_map_size += 10;
76 remote_fio_data.fd_map =
77 (int *) xrealloc (remote_fio_data.fd_map,
78 remote_fio_data.fd_map_size * sizeof (int));
9f8e6999
MG
79 for (; i < remote_fio_data.fd_map_size; i++)
80 remote_fio_data.fd_map[i] = FIO_FD_INVALID;
449092f6
CV
81 return remote_fio_data.fd_map_size - 10;
82}
83
84static int
cbcdb1f5 85remote_fileio_next_free_fd (void)
449092f6
CV
86{
87 int i;
88
89 for (i = 0; i < remote_fio_data.fd_map_size; ++i)
90 if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
91 return i;
92 return remote_fileio_resize_fd_map ();
93}
94
95static int
96remote_fileio_fd_to_targetfd (int fd)
97{
98 int target_fd = remote_fileio_next_free_fd ();
99 remote_fio_data.fd_map[target_fd] = fd;
100 return target_fd;
101}
102
103static int
104remote_fileio_map_fd (int target_fd)
105{
106 remote_fileio_init_fd_map ();
107 if (target_fd < 0 || target_fd >= remote_fio_data.fd_map_size)
108 return FIO_FD_INVALID;
109 return remote_fio_data.fd_map[target_fd];
110}
111
112static void
113remote_fileio_close_target_fd (int target_fd)
114{
115 remote_fileio_init_fd_map ();
116 if (target_fd >= 0 && target_fd < remote_fio_data.fd_map_size)
117 remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID;
118}
119
120static int
121remote_fileio_oflags_to_host (long flags)
122{
123 int hflags = 0;
124
125 if (flags & FILEIO_O_CREAT)
126 hflags |= O_CREAT;
127 if (flags & FILEIO_O_EXCL)
128 hflags |= O_EXCL;
129 if (flags & FILEIO_O_TRUNC)
130 hflags |= O_TRUNC;
131 if (flags & FILEIO_O_APPEND)
132 hflags |= O_APPEND;
133 if (flags & FILEIO_O_RDONLY)
134 hflags |= O_RDONLY;
135 if (flags & FILEIO_O_WRONLY)
136 hflags |= O_WRONLY;
137 if (flags & FILEIO_O_RDWR)
138 hflags |= O_RDWR;
139/* On systems supporting binary and text mode, always open files in
140 binary mode. */
141#ifdef O_BINARY
142 hflags |= O_BINARY;
143#endif
144 return hflags;
145}
146
147static mode_t
148remote_fileio_mode_to_host (long mode, int open_call)
149{
150 mode_t hmode = 0;
151
152 if (!open_call)
153 {
154 if (mode & FILEIO_S_IFREG)
155 hmode |= S_IFREG;
156 if (mode & FILEIO_S_IFDIR)
157 hmode |= S_IFDIR;
158 if (mode & FILEIO_S_IFCHR)
159 hmode |= S_IFCHR;
160 }
161 if (mode & FILEIO_S_IRUSR)
162 hmode |= S_IRUSR;
163 if (mode & FILEIO_S_IWUSR)
164 hmode |= S_IWUSR;
165 if (mode & FILEIO_S_IXUSR)
166 hmode |= S_IXUSR;
9b265ec2 167#ifdef S_IRGRP
449092f6
CV
168 if (mode & FILEIO_S_IRGRP)
169 hmode |= S_IRGRP;
9b265ec2
MM
170#endif
171#ifdef S_IWGRP
449092f6
CV
172 if (mode & FILEIO_S_IWGRP)
173 hmode |= S_IWGRP;
9b265ec2
MM
174#endif
175#ifdef S_IXGRP
449092f6
CV
176 if (mode & FILEIO_S_IXGRP)
177 hmode |= S_IXGRP;
9b265ec2 178#endif
449092f6
CV
179 if (mode & FILEIO_S_IROTH)
180 hmode |= S_IROTH;
9b265ec2 181#ifdef S_IWOTH
449092f6
CV
182 if (mode & FILEIO_S_IWOTH)
183 hmode |= S_IWOTH;
9b265ec2
MM
184#endif
185#ifdef S_IXOTH
449092f6
CV
186 if (mode & FILEIO_S_IXOTH)
187 hmode |= S_IXOTH;
9b265ec2 188#endif
449092f6
CV
189 return hmode;
190}
191
cbcdb1f5 192static LONGEST
449092f6
CV
193remote_fileio_mode_to_target (mode_t mode)
194{
195 mode_t tmode = 0;
196
9c7deb13 197 if (S_ISREG(mode))
449092f6 198 tmode |= FILEIO_S_IFREG;
9c7deb13 199 if (S_ISDIR(mode))
449092f6 200 tmode |= FILEIO_S_IFDIR;
9c7deb13 201 if (S_ISCHR(mode))
449092f6
CV
202 tmode |= FILEIO_S_IFCHR;
203 if (mode & S_IRUSR)
204 tmode |= FILEIO_S_IRUSR;
205 if (mode & S_IWUSR)
206 tmode |= FILEIO_S_IWUSR;
207 if (mode & S_IXUSR)
208 tmode |= FILEIO_S_IXUSR;
9b265ec2 209#ifdef S_IRGRP
449092f6
CV
210 if (mode & S_IRGRP)
211 tmode |= FILEIO_S_IRGRP;
9b265ec2
MM
212#endif
213#ifdef S_IWRGRP
449092f6
CV
214 if (mode & S_IWGRP)
215 tmode |= FILEIO_S_IWGRP;
9b265ec2
MM
216#endif
217#ifdef S_IXGRP
449092f6
CV
218 if (mode & S_IXGRP)
219 tmode |= FILEIO_S_IXGRP;
9b265ec2 220#endif
449092f6
CV
221 if (mode & S_IROTH)
222 tmode |= FILEIO_S_IROTH;
9b265ec2 223#ifdef S_IWOTH
449092f6
CV
224 if (mode & S_IWOTH)
225 tmode |= FILEIO_S_IWOTH;
9b265ec2
MM
226#endif
227#ifdef S_IXOTH
449092f6
CV
228 if (mode & S_IXOTH)
229 tmode |= FILEIO_S_IXOTH;
9b265ec2 230#endif
449092f6
CV
231 return tmode;
232}
233
234static int
235remote_fileio_errno_to_target (int error)
236{
237 switch (error)
238 {
239 case EPERM:
240 return FILEIO_EPERM;
241 case ENOENT:
242 return FILEIO_ENOENT;
243 case EINTR:
244 return FILEIO_EINTR;
245 case EIO:
246 return FILEIO_EIO;
247 case EBADF:
248 return FILEIO_EBADF;
249 case EACCES:
250 return FILEIO_EACCES;
251 case EFAULT:
252 return FILEIO_EFAULT;
253 case EBUSY:
254 return FILEIO_EBUSY;
255 case EEXIST:
256 return FILEIO_EEXIST;
257 case ENODEV:
258 return FILEIO_ENODEV;
259 case ENOTDIR:
260 return FILEIO_ENOTDIR;
261 case EISDIR:
262 return FILEIO_EISDIR;
263 case EINVAL:
264 return FILEIO_EINVAL;
265 case ENFILE:
266 return FILEIO_ENFILE;
267 case EMFILE:
268 return FILEIO_EMFILE;
269 case EFBIG:
270 return FILEIO_EFBIG;
271 case ENOSPC:
272 return FILEIO_ENOSPC;
273 case ESPIPE:
274 return FILEIO_ESPIPE;
275 case EROFS:
276 return FILEIO_EROFS;
277 case ENOSYS:
278 return FILEIO_ENOSYS;
279 case ENAMETOOLONG:
280 return FILEIO_ENAMETOOLONG;
281 }
282 return FILEIO_EUNKNOWN;
283}
284
285static int
286remote_fileio_seek_flag_to_host (long num, int *flag)
287{
288 if (!flag)
289 return 0;
290 switch (num)
291 {
292 case FILEIO_SEEK_SET:
293 *flag = SEEK_SET;
294 break;
295 case FILEIO_SEEK_CUR:
296 *flag = SEEK_CUR;
297 break;
298 case FILEIO_SEEK_END:
299 *flag = SEEK_END;
300 break;
301 default:
302 return -1;
303 }
304 return 0;
305}
306
307static int
cbcdb1f5 308remote_fileio_extract_long (char **buf, LONGEST *retlong)
449092f6
CV
309{
310 char *c;
311 int sign = 1;
312
313 if (!buf || !*buf || !**buf || !retlong)
314 return -1;
315 c = strchr (*buf, ',');
316 if (c)
317 *c++ = '\0';
318 else
319 c = strchr (*buf, '\0');
320 while (strchr ("+-", **buf))
321 {
322 if (**buf == '-')
323 sign = -sign;
324 ++*buf;
325 }
326 for (*retlong = 0; **buf; ++*buf)
327 {
328 *retlong <<= 4;
329 if (**buf >= '0' && **buf <= '9')
330 *retlong += **buf - '0';
331 else if (**buf >= 'a' && **buf <= 'f')
332 *retlong += **buf - 'a' + 10;
333 else if (**buf >= 'A' && **buf <= 'F')
334 *retlong += **buf - 'A' + 10;
335 else
336 return -1;
337 }
338 *retlong *= sign;
339 *buf = c;
340 return 0;
341}
342
343static int
344remote_fileio_extract_int (char **buf, long *retint)
345{
346 int ret;
cbcdb1f5 347 LONGEST retlong;
449092f6
CV
348
349 if (!retint)
350 return -1;
cbcdb1f5
CV
351 ret = remote_fileio_extract_long (buf, &retlong);
352 if (!ret)
449092f6
CV
353 *retint = (long) retlong;
354 return ret;
355}
356
357static int
358remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
359{
360 char *c;
cbcdb1f5 361 LONGEST retlong;
449092f6
CV
362
363 if (!buf || !*buf || !**buf || !ptrval || !length)
364 return -1;
365 c = strchr (*buf, '/');
366 if (!c)
367 return -1;
368 *c++ = '\0';
369 if (remote_fileio_extract_long (buf, &retlong))
370 return -1;
371 *ptrval = (CORE_ADDR) retlong;
372 *buf = c;
373 if (remote_fileio_extract_long (buf, &retlong))
374 return -1;
375 *length = (int) retlong;
376 return 0;
377}
378
379/* Convert to big endian */
380static void
cbcdb1f5 381remote_fileio_to_be (LONGEST num, char *buf, int bytes)
449092f6
CV
382{
383 int i;
384
385 for (i = 0; i < bytes; ++i)
386 buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff;
387}
388
449092f6
CV
389static void
390remote_fileio_to_fio_uint (long num, fio_uint_t fnum)
391{
cbcdb1f5 392 remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
449092f6
CV
393}
394
395static void
396remote_fileio_to_fio_mode (mode_t num, fio_mode_t fnum)
397{
398 remote_fileio_to_be (remote_fileio_mode_to_target(num), (char *) fnum, 4);
399}
400
401static void
402remote_fileio_to_fio_time (time_t num, fio_time_t fnum)
403{
cbcdb1f5 404 remote_fileio_to_be ((LONGEST) num, (char *) fnum, 4);
449092f6
CV
405}
406
407static void
cbcdb1f5 408remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
449092f6
CV
409{
410 remote_fileio_to_be (num, (char *) fnum, 8);
411}
412
413static void
cbcdb1f5 414remote_fileio_to_fio_ulong (LONGEST num, fio_ulong_t fnum)
449092f6
CV
415{
416 remote_fileio_to_be (num, (char *) fnum, 8);
417}
418
419static void
420remote_fileio_to_fio_stat (struct stat *st, struct fio_stat *fst)
421{
d3ea6809
MM
422 LONGEST blksize;
423
449092f6
CV
424 /* `st_dev' is set in the calling function */
425 remote_fileio_to_fio_uint ((long) st->st_ino, fst->fst_ino);
426 remote_fileio_to_fio_mode (st->st_mode, fst->fst_mode);
427 remote_fileio_to_fio_uint ((long) st->st_nlink, fst->fst_nlink);
428 remote_fileio_to_fio_uint ((long) st->st_uid, fst->fst_uid);
429 remote_fileio_to_fio_uint ((long) st->st_gid, fst->fst_gid);
430 remote_fileio_to_fio_uint ((long) st->st_rdev, fst->fst_rdev);
cbcdb1f5 431 remote_fileio_to_fio_ulong ((LONGEST) st->st_size, fst->fst_size);
d3ea6809
MM
432#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
433 blksize = st->st_blksize;
434#else
435 blksize = 512;
436#endif
437 remote_fileio_to_fio_ulong (blksize, fst->fst_blksize);
1dd727e9 438#if HAVE_STRUCT_STAT_ST_BLOCKS
cbcdb1f5 439 remote_fileio_to_fio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
1dd727e9
EZ
440#else
441 /* FIXME: This is correct for DJGPP, but other systems that don't
442 have st_blocks, if any, might prefer 512 instead of st_blksize.
443 (eliz, 30-12-2003) */
d3ea6809
MM
444 remote_fileio_to_fio_ulong (((LONGEST) st->st_size + blksize - 1)
445 / blksize,
1dd727e9
EZ
446 fst->fst_blocks);
447#endif
449092f6
CV
448 remote_fileio_to_fio_time (st->st_atime, fst->fst_atime);
449 remote_fileio_to_fio_time (st->st_mtime, fst->fst_mtime);
450 remote_fileio_to_fio_time (st->st_ctime, fst->fst_ctime);
451}
452
453static void
454remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
455{
456 remote_fileio_to_fio_time (tv->tv_sec, ftv->ftv_sec);
457 remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
458}
459
460static int remote_fio_ctrl_c_flag = 0;
461static int remote_fio_no_longjmp = 0;
449092f6
CV
462
463#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
464static struct sigaction remote_fio_sa;
465static struct sigaction remote_fio_osa;
466#else
467static void (*remote_fio_ofunc)(int);
468#endif
469
470static void
cbcdb1f5 471remote_fileio_sig_init (void)
449092f6
CV
472{
473#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
474 remote_fio_sa.sa_handler = SIG_IGN;
475 sigemptyset (&remote_fio_sa.sa_mask);
476 remote_fio_sa.sa_flags = 0;
477 sigaction (SIGINT, &remote_fio_sa, &remote_fio_osa);
478#else
479 remote_fio_ofunc = signal (SIGINT, SIG_IGN);
480#endif
481}
482
483static void
484remote_fileio_sig_set (void (*sigint_func)(int))
485{
486#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
487 remote_fio_sa.sa_handler = sigint_func;
488 sigemptyset (&remote_fio_sa.sa_mask);
489 remote_fio_sa.sa_flags = 0;
490 sigaction (SIGINT, &remote_fio_sa, NULL);
491#else
492 signal (SIGINT, sigint_func);
493#endif
494}
495
496static void
cbcdb1f5 497remote_fileio_sig_exit (void)
449092f6
CV
498{
499#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
500 sigaction (SIGINT, &remote_fio_osa, NULL);
501#else
502 signal (SIGINT, remote_fio_ofunc);
503#endif
504}
505
506static void
507remote_fileio_ctrl_c_signal_handler (int signo)
508{
509 remote_fileio_sig_set (SIG_IGN);
510 remote_fio_ctrl_c_flag = 1;
511 if (!remote_fio_no_longjmp)
315a522e 512 deprecated_throw_reason (RETURN_QUIT);
449092f6
CV
513 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
514}
515
516static void
517remote_fileio_reply (int retcode, int error)
518{
519 char buf[32];
520
521 remote_fileio_sig_set (SIG_IGN);
522 strcpy (buf, "F");
523 if (retcode < 0)
524 {
525 strcat (buf, "-");
526 retcode = -retcode;
527 }
528 sprintf (buf + strlen (buf), "%x", retcode);
529 if (error || remote_fio_ctrl_c_flag)
530 {
531 if (error && remote_fio_ctrl_c_flag)
532 error = FILEIO_EINTR;
533 if (error < 0)
534 {
535 strcat (buf, "-");
536 error = -error;
537 }
538 sprintf (buf + strlen (buf), ",%x", error);
539 if (remote_fio_ctrl_c_flag)
540 strcat (buf, ",C");
541 }
542 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
543 putpkt (buf);
544}
545
546static void
cbcdb1f5 547remote_fileio_ioerror (void)
449092f6
CV
548{
549 remote_fileio_reply (-1, FILEIO_EIO);
550}
551
552static void
cbcdb1f5 553remote_fileio_badfd (void)
449092f6
CV
554{
555 remote_fileio_reply (-1, FILEIO_EBADF);
556}
557
558static void
559remote_fileio_return_errno (int retcode)
560{
561 remote_fileio_reply (retcode,
562 retcode < 0 ? remote_fileio_errno_to_target (errno) : 0);
563}
564
565static void
566remote_fileio_return_success (int retcode)
567{
568 remote_fileio_reply (retcode, 0);
569}
570
571/* Wrapper function for remote_write_bytes() which has the disadvantage to
572 write only one packet, regardless of the requested number of bytes to
573 transfer. This wrapper calls remote_write_bytes() as often as needed. */
574static int
cfd77fa1 575remote_fileio_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
449092f6
CV
576{
577 int ret = 0, written;
578
579 while (len > 0 && (written = remote_write_bytes (memaddr, myaddr, len)) > 0)
580 {
581 len -= written;
582 memaddr += written;
583 myaddr += written;
584 ret += written;
585 }
586 return ret;
587}
588
589static void
590remote_fileio_func_open (char *buf)
591{
592 CORE_ADDR ptrval;
593 int length, retlength;
594 long num;
595 int flags, fd;
596 mode_t mode;
597 char *pathname;
598 struct stat st;
599
600 /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
601 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
602 {
603 remote_fileio_ioerror ();
604 return;
605 }
606 /* 2. Parameter: open flags */
607 if (remote_fileio_extract_int (&buf, &num))
608 {
609 remote_fileio_ioerror ();
610 return;
611 }
612 flags = remote_fileio_oflags_to_host (num);
613 /* 3. Parameter: open mode */
614 if (remote_fileio_extract_int (&buf, &num))
615 {
616 remote_fileio_ioerror ();
617 return;
618 }
619 mode = remote_fileio_mode_to_host (num, 1);
620
621 /* Request pathname using 'm' packet */
622 pathname = alloca (length);
cfd77fa1 623 retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
449092f6
CV
624 if (retlength != length)
625 {
626 remote_fileio_ioerror ();
627 return;
628 }
629
630 /* Check if pathname exists and is not a regular file or directory. If so,
631 return an appropriate error code. Same for trying to open directories
632 for writing. */
633 if (!stat (pathname, &st))
634 {
635 if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
636 {
637 remote_fileio_reply (-1, FILEIO_ENODEV);
638 return;
639 }
640 if (S_ISDIR (st.st_mode)
641 && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
642 {
643 remote_fileio_reply (-1, FILEIO_EISDIR);
644 return;
645 }
646 }
647
648 remote_fio_no_longjmp = 1;
649 fd = open (pathname, flags, mode);
650 if (fd < 0)
651 {
652 remote_fileio_return_errno (-1);
653 return;
654 }
655
656 fd = remote_fileio_fd_to_targetfd (fd);
657 remote_fileio_return_success (fd);
658}
659
660static void
661remote_fileio_func_close (char *buf)
662{
663 long num;
664 int fd;
665
666 /* Parameter: file descriptor */
667 if (remote_fileio_extract_int (&buf, &num))
668 {
669 remote_fileio_ioerror ();
670 return;
671 }
cbcdb1f5
CV
672 fd = remote_fileio_map_fd ((int) num);
673 if (fd == FIO_FD_INVALID)
449092f6
CV
674 {
675 remote_fileio_badfd ();
676 return;
677 }
678
679 remote_fio_no_longjmp = 1;
680 if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
681 remote_fileio_return_errno (-1);
682 remote_fileio_close_target_fd ((int) num);
683 remote_fileio_return_success (0);
684}
685
686static void
687remote_fileio_func_read (char *buf)
688{
689 long target_fd, num;
cbcdb1f5 690 LONGEST lnum;
449092f6
CV
691 CORE_ADDR ptrval;
692 int fd, ret, retlength;
cfd77fa1 693 gdb_byte *buffer;
449092f6
CV
694 size_t length;
695 off_t old_offset, new_offset;
696
697 /* 1. Parameter: file descriptor */
698 if (remote_fileio_extract_int (&buf, &target_fd))
699 {
700 remote_fileio_ioerror ();
701 return;
702 }
cbcdb1f5
CV
703 fd = remote_fileio_map_fd ((int) target_fd);
704 if (fd == FIO_FD_INVALID)
449092f6
CV
705 {
706 remote_fileio_badfd ();
707 return;
708 }
709 /* 2. Parameter: buffer pointer */
710 if (remote_fileio_extract_long (&buf, &lnum))
711 {
712 remote_fileio_ioerror ();
713 return;
714 }
715 ptrval = (CORE_ADDR) lnum;
716 /* 3. Parameter: buffer length */
717 if (remote_fileio_extract_int (&buf, &num))
718 {
719 remote_fileio_ioerror ();
720 return;
721 }
722 length = (size_t) num;
723
724 switch (fd)
725 {
726 case FIO_FD_CONSOLE_OUT:
727 remote_fileio_badfd ();
728 return;
729 case FIO_FD_CONSOLE_IN:
730 {
731 static char *remaining_buf = NULL;
732 static int remaining_length = 0;
733
cfd77fa1 734 buffer = (gdb_byte *) xmalloc (32768);
449092f6
CV
735 if (remaining_buf)
736 {
737 remote_fio_no_longjmp = 1;
738 if (remaining_length > length)
739 {
740 memcpy (buffer, remaining_buf, length);
741 memmove (remaining_buf, remaining_buf + length,
742 remaining_length - length);
743 remaining_length -= length;
744 ret = length;
745 }
746 else
747 {
748 memcpy (buffer, remaining_buf, remaining_length);
749 xfree (remaining_buf);
750 remaining_buf = NULL;
751 ret = remaining_length;
752 }
753 }
754 else
755 {
cfd77fa1 756 ret = ui_file_read (gdb_stdtargin, (char *) buffer, 32767);
449092f6
CV
757 remote_fio_no_longjmp = 1;
758 if (ret > 0 && (size_t)ret > length)
759 {
760 remaining_buf = (char *) xmalloc (ret - length);
761 remaining_length = ret - length;
762 memcpy (remaining_buf, buffer + length, remaining_length);
763 ret = length;
764 }
765 }
766 }
767 break;
768 default:
cfd77fa1 769 buffer = (gdb_byte *) xmalloc (length);
449092f6
CV
770 /* POSIX defines EINTR behaviour of read in a weird way. It's allowed
771 for read() to return -1 even if "some" bytes have been read. It
772 has been corrected in SUSv2 but that doesn't help us much...
773 Therefore a complete solution must check how many bytes have been
774 read on EINTR to return a more reliable value to the target */
775 old_offset = lseek (fd, 0, SEEK_CUR);
776 remote_fio_no_longjmp = 1;
777 ret = read (fd, buffer, length);
778 if (ret < 0 && errno == EINTR)
779 {
780 new_offset = lseek (fd, 0, SEEK_CUR);
781 /* If some data has been read, return the number of bytes read.
782 The Ctrl-C flag is set in remote_fileio_reply() anyway */
783 if (old_offset != new_offset)
784 ret = new_offset - old_offset;
785 }
786 break;
787 }
788
789 if (ret > 0)
790 {
791 retlength = remote_fileio_write_bytes (ptrval, buffer, ret);
792 if (retlength != ret)
793 ret = -1; /* errno has been set to EIO in remote_fileio_write_bytes() */
794 }
795
796 if (ret < 0)
797 remote_fileio_return_errno (-1);
798 else
799 remote_fileio_return_success (ret);
800
801 xfree (buffer);
802}
803
804static void
805remote_fileio_func_write (char *buf)
806{
807 long target_fd, num;
cbcdb1f5 808 LONGEST lnum;
449092f6
CV
809 CORE_ADDR ptrval;
810 int fd, ret, retlength;
cfd77fa1 811 gdb_byte *buffer;
449092f6
CV
812 size_t length;
813
814 /* 1. Parameter: file descriptor */
815 if (remote_fileio_extract_int (&buf, &target_fd))
816 {
817 remote_fileio_ioerror ();
818 return;
819 }
cbcdb1f5
CV
820 fd = remote_fileio_map_fd ((int) target_fd);
821 if (fd == FIO_FD_INVALID)
449092f6
CV
822 {
823 remote_fileio_badfd ();
824 return;
825 }
826 /* 2. Parameter: buffer pointer */
827 if (remote_fileio_extract_long (&buf, &lnum))
828 {
829 remote_fileio_ioerror ();
830 return;
831 }
832 ptrval = (CORE_ADDR) lnum;
833 /* 3. Parameter: buffer length */
834 if (remote_fileio_extract_int (&buf, &num))
835 {
836 remote_fileio_ioerror ();
837 return;
838 }
839 length = (size_t) num;
840
cfd77fa1 841 buffer = (gdb_byte *) xmalloc (length);
449092f6
CV
842 retlength = remote_read_bytes (ptrval, buffer, length);
843 if (retlength != length)
844 {
845 xfree (buffer);
846 remote_fileio_ioerror ();
847 return;
848 }
849
850 remote_fio_no_longjmp = 1;
851 switch (fd)
852 {
853 case FIO_FD_CONSOLE_IN:
854 remote_fileio_badfd ();
1ed489bd 855 xfree (buffer);
449092f6
CV
856 return;
857 case FIO_FD_CONSOLE_OUT:
cfd77fa1
DJ
858 ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
859 (char *) buffer, length);
449092f6
CV
860 gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
861 ret = length;
862 break;
863 default:
864 ret = write (fd, buffer, length);
865 if (ret < 0 && errno == EACCES)
866 errno = EBADF; /* Cygwin returns EACCESS when writing to a R/O file.*/
867 break;
868 }
869
870 if (ret < 0)
871 remote_fileio_return_errno (-1);
872 else
873 remote_fileio_return_success (ret);
874
875 xfree (buffer);
876}
877
878static void
879remote_fileio_func_lseek (char *buf)
880{
881 long num;
cbcdb1f5 882 LONGEST lnum;
449092f6
CV
883 int fd, flag;
884 off_t offset, ret;
885
886 /* 1. Parameter: file descriptor */
887 if (remote_fileio_extract_int (&buf, &num))
888 {
889 remote_fileio_ioerror ();
890 return;
891 }
cbcdb1f5
CV
892 fd = remote_fileio_map_fd ((int) num);
893 if (fd == FIO_FD_INVALID)
449092f6
CV
894 {
895 remote_fileio_badfd ();
896 return;
897 }
898 else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
899 {
900 remote_fileio_reply (-1, FILEIO_ESPIPE);
901 return;
902 }
903
904 /* 2. Parameter: offset */
905 if (remote_fileio_extract_long (&buf, &lnum))
906 {
907 remote_fileio_ioerror ();
908 return;
909 }
910 offset = (off_t) lnum;
911 /* 3. Parameter: flag */
912 if (remote_fileio_extract_int (&buf, &num))
913 {
914 remote_fileio_ioerror ();
915 return;
916 }
917 if (remote_fileio_seek_flag_to_host (num, &flag))
918 {
919 remote_fileio_reply (-1, FILEIO_EINVAL);
920 return;
921 }
922
923 remote_fio_no_longjmp = 1;
924 ret = lseek (fd, offset, flag);
925
926 if (ret == (off_t) -1)
927 remote_fileio_return_errno (-1);
928 else
929 remote_fileio_return_success (ret);
930}
931
932static void
933remote_fileio_func_rename (char *buf)
934{
86cc68a8
NS
935 CORE_ADDR old_ptr, new_ptr;
936 int old_len, new_len, retlength;
449092f6
CV
937 char *oldpath, *newpath;
938 int ret, of, nf;
939 struct stat ost, nst;
940
941 /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
86cc68a8 942 if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
449092f6
CV
943 {
944 remote_fileio_ioerror ();
945 return;
946 }
86cc68a8
NS
947
948 /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
949 if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
449092f6
CV
950 {
951 remote_fileio_ioerror ();
952 return;
953 }
86cc68a8
NS
954
955 /* Request oldpath using 'm' packet */
956 oldpath = alloca (old_len);
957 retlength = remote_read_bytes (old_ptr, (gdb_byte *) oldpath, old_len);
958 if (retlength != old_len)
449092f6
CV
959 {
960 remote_fileio_ioerror ();
961 return;
962 }
86cc68a8 963
449092f6 964 /* Request newpath using 'm' packet */
86cc68a8
NS
965 newpath = alloca (new_len);
966 retlength = remote_read_bytes (new_ptr, (gdb_byte *) newpath, new_len);
967 if (retlength != new_len)
449092f6
CV
968 {
969 remote_fileio_ioerror ();
970 return;
971 }
972
973 /* Only operate on regular files and directories */
cbcdb1f5
CV
974 of = stat (oldpath, &ost);
975 nf = stat (newpath, &nst);
976 if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
977 || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
449092f6
CV
978 {
979 remote_fileio_reply (-1, FILEIO_EACCES);
980 return;
981 }
982
983 remote_fio_no_longjmp = 1;
984 ret = rename (oldpath, newpath);
985
986 if (ret == -1)
987 {
988 /* Special case: newpath is a non-empty directory. Some systems
989 return ENOTEMPTY, some return EEXIST. We coerce that to be
990 always EEXIST. */
991 if (errno == ENOTEMPTY)
992 errno = EEXIST;
993#ifdef __CYGWIN__
994 /* Workaround some Cygwin problems with correct errnos. */
995 if (errno == EACCES)
996 {
997 if (!of && !nf && S_ISDIR (nst.st_mode))
998 {
999 if (S_ISREG (ost.st_mode))
1000 errno = EISDIR;
1001 else
1002 {
1003 char oldfullpath[PATH_MAX + 1];
1004 char newfullpath[PATH_MAX + 1];
1005 int len;
1006
1007 cygwin_conv_to_full_posix_path (oldpath, oldfullpath);
1008 cygwin_conv_to_full_posix_path (newpath, newfullpath);
1009 len = strlen (oldfullpath);
1010 if (newfullpath[len] == '/'
1011 && !strncmp (oldfullpath, newfullpath, len))
1012 errno = EINVAL;
1013 else
1014 errno = EEXIST;
1015 }
1016 }
1017 }
1018#endif
1019
1020 remote_fileio_return_errno (-1);
1021 }
1022 else
1023 remote_fileio_return_success (ret);
1024}
1025
1026static void
1027remote_fileio_func_unlink (char *buf)
1028{
1029 CORE_ADDR ptrval;
1030 int length, retlength;
1031 char *pathname;
1032 int ret;
1033 struct stat st;
1034
1035 /* Parameter: Ptr to pathname / length incl. trailing zero */
1036 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1037 {
1038 remote_fileio_ioerror ();
1039 return;
1040 }
1041 /* Request pathname using 'm' packet */
1042 pathname = alloca (length);
cfd77fa1 1043 retlength = remote_read_bytes (ptrval, (gdb_byte *) pathname, length);
449092f6
CV
1044 if (retlength != length)
1045 {
1046 remote_fileio_ioerror ();
1047 return;
1048 }
1049
1050 /* Only operate on regular files (and directories, which allows to return
1051 the correct return code) */
1052 if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
1053 {
1054 remote_fileio_reply (-1, FILEIO_ENODEV);
1055 return;
1056 }
1057
1058 remote_fio_no_longjmp = 1;
1059 ret = unlink (pathname);
1060
1061 if (ret == -1)
1062 remote_fileio_return_errno (-1);
1063 else
1064 remote_fileio_return_success (ret);
1065}
1066
1067static void
1068remote_fileio_func_stat (char *buf)
1069{
86cc68a8
NS
1070 CORE_ADDR statptr, nameptr;
1071 int ret, namelength, retlength;
449092f6 1072 char *pathname;
cbcdb1f5 1073 LONGEST lnum;
449092f6
CV
1074 struct stat st;
1075 struct fio_stat fst;
1076
1077 /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
86cc68a8 1078 if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
449092f6
CV
1079 {
1080 remote_fileio_ioerror ();
1081 return;
1082 }
86cc68a8
NS
1083
1084 /* 2. Parameter: Ptr to struct stat */
1085 if (remote_fileio_extract_long (&buf, &lnum))
449092f6
CV
1086 {
1087 remote_fileio_ioerror ();
1088 return;
1089 }
86cc68a8
NS
1090 statptr = (CORE_ADDR) lnum;
1091
1092 /* Request pathname using 'm' packet */
1093 pathname = alloca (namelength);
1094 retlength = remote_read_bytes (nameptr, (gdb_byte *) pathname, namelength);
1095 if (retlength != namelength)
449092f6
CV
1096 {
1097 remote_fileio_ioerror ();
1098 return;
1099 }
449092f6
CV
1100
1101 remote_fio_no_longjmp = 1;
1102 ret = stat (pathname, &st);
1103
1104 if (ret == -1)
1105 {
1106 remote_fileio_return_errno (-1);
1107 return;
1108 }
1109 /* Only operate on regular files and directories */
1110 if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
1111 {
1112 remote_fileio_reply (-1, FILEIO_EACCES);
1113 return;
1114 }
86cc68a8 1115 if (statptr)
449092f6
CV
1116 {
1117 remote_fileio_to_fio_stat (&st, &fst);
1118 remote_fileio_to_fio_uint (0, fst.fst_dev);
1119
86cc68a8
NS
1120 retlength = remote_fileio_write_bytes (statptr,
1121 (gdb_byte *) &fst, sizeof fst);
449092f6
CV
1122 if (retlength != sizeof fst)
1123 {
1124 remote_fileio_return_errno (-1);
1125 return;
1126 }
1127 }
1128 remote_fileio_return_success (ret);
1129}
1130
1131static void
1132remote_fileio_func_fstat (char *buf)
1133{
1134 CORE_ADDR ptrval;
1135 int fd, ret, retlength;
1136 long target_fd;
cbcdb1f5 1137 LONGEST lnum;
449092f6
CV
1138 struct stat st;
1139 struct fio_stat fst;
1140 struct timeval tv;
1141
1142 /* 1. Parameter: file descriptor */
1143 if (remote_fileio_extract_int (&buf, &target_fd))
1144 {
1145 remote_fileio_ioerror ();
1146 return;
1147 }
cbcdb1f5
CV
1148 fd = remote_fileio_map_fd ((int) target_fd);
1149 if (fd == FIO_FD_INVALID)
449092f6
CV
1150 {
1151 remote_fileio_badfd ();
1152 return;
1153 }
1154 /* 2. Parameter: Ptr to struct stat */
1155 if (remote_fileio_extract_long (&buf, &lnum))
1156 {
1157 remote_fileio_ioerror ();
1158 return;
1159 }
1160 ptrval = (CORE_ADDR) lnum;
1161
1162 remote_fio_no_longjmp = 1;
1163 if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
1164 {
1165 remote_fileio_to_fio_uint (1, fst.fst_dev);
1166 st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
1167 st.st_nlink = 1;
d3ea6809 1168#ifdef HAVE_GETUID
449092f6 1169 st.st_uid = getuid ();
d3ea6809
MM
1170#else
1171 st.st_uid = 0;
1172#endif
1173#ifdef HAVE_GETGID
449092f6 1174 st.st_gid = getgid ();
d3ea6809
MM
1175#else
1176 st.st_gid = 0;
1177#endif
449092f6
CV
1178 st.st_rdev = 0;
1179 st.st_size = 0;
d3ea6809 1180#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
449092f6 1181 st.st_blksize = 512;
d3ea6809 1182#endif
1dd727e9 1183#if HAVE_STRUCT_STAT_ST_BLOCKS
449092f6 1184 st.st_blocks = 0;
1dd727e9 1185#endif
449092f6
CV
1186 if (!gettimeofday (&tv, NULL))
1187 st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
1188 else
1189 st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
1190 ret = 0;
1191 }
1192 else
1193 ret = fstat (fd, &st);
1194
1195 if (ret == -1)
1196 {
1197 remote_fileio_return_errno (-1);
1198 return;
1199 }
1200 if (ptrval)
1201 {
1202 remote_fileio_to_fio_stat (&st, &fst);
1203
cfd77fa1 1204 retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &fst, sizeof fst);
449092f6
CV
1205 if (retlength != sizeof fst)
1206 {
1207 remote_fileio_return_errno (-1);
1208 return;
1209 }
1210 }
1211 remote_fileio_return_success (ret);
1212}
1213
1214static void
1215remote_fileio_func_gettimeofday (char *buf)
1216{
cbcdb1f5 1217 LONGEST lnum;
449092f6
CV
1218 CORE_ADDR ptrval;
1219 int ret, retlength;
1220 struct timeval tv;
1221 struct fio_timeval ftv;
1222
1223 /* 1. Parameter: struct timeval pointer */
1224 if (remote_fileio_extract_long (&buf, &lnum))
1225 {
1226 remote_fileio_ioerror ();
1227 return;
1228 }
1229 ptrval = (CORE_ADDR) lnum;
1230 /* 2. Parameter: some pointer value... */
1231 if (remote_fileio_extract_long (&buf, &lnum))
1232 {
1233 remote_fileio_ioerror ();
1234 return;
1235 }
1236 /* ...which has to be NULL */
1237 if (lnum)
1238 {
1239 remote_fileio_reply (-1, FILEIO_EINVAL);
1240 return;
1241 }
1242
1243 remote_fio_no_longjmp = 1;
1244 ret = gettimeofday (&tv, NULL);
1245
1246 if (ret == -1)
1247 {
1248 remote_fileio_return_errno (-1);
1249 return;
1250 }
1251
1252 if (ptrval)
1253 {
1254 remote_fileio_to_fio_timeval (&tv, &ftv);
1255
cfd77fa1 1256 retlength = remote_fileio_write_bytes (ptrval, (gdb_byte *) &ftv, sizeof ftv);
449092f6
CV
1257 if (retlength != sizeof ftv)
1258 {
1259 remote_fileio_return_errno (-1);
1260 return;
1261 }
1262 }
1263 remote_fileio_return_success (ret);
1264}
1265
1266static void
1267remote_fileio_func_isatty (char *buf)
1268{
1269 long target_fd;
1270 int fd;
1271
1272 /* Parameter: file descriptor */
1273 if (remote_fileio_extract_int (&buf, &target_fd))
1274 {
1275 remote_fileio_ioerror ();
1276 return;
1277 }
1278 remote_fio_no_longjmp = 1;
1279 fd = remote_fileio_map_fd ((int) target_fd);
1280 remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
1281 fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
1282}
1283
1284static void
1285remote_fileio_func_system (char *buf)
1286{
1287 CORE_ADDR ptrval;
1288 int ret, length, retlength;
5600ea19 1289 char *cmdline = NULL;
449092f6
CV
1290
1291 /* Parameter: Ptr to commandline / length incl. trailing zero */
1292 if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
1293 {
1294 remote_fileio_ioerror ();
1295 return;
1296 }
5600ea19
NS
1297
1298 if (length)
449092f6 1299 {
5600ea19
NS
1300 /* Request commandline using 'm' packet */
1301 cmdline = alloca (length);
1302 retlength = remote_read_bytes (ptrval, (gdb_byte *) cmdline, length);
1303 if (retlength != length)
1304 {
1305 remote_fileio_ioerror ();
1306 return;
1307 }
1308 }
1309
1310 /* Check if system(3) has been explicitely allowed using the
1311 `set remote system-call-allowed 1' command. If length is 0,
1312 indicating a NULL parameter to the system call, return zero to
1313 indicate a shell is not available. Otherwise fail with EPERM. */
1314 if (!remote_fio_system_call_allowed)
1315 {
1316 if (!length)
1317 remote_fileio_return_success (0);
1318 else
1319 remote_fileio_reply (-1, FILEIO_EPERM);
449092f6
CV
1320 return;
1321 }
1322
1323 remote_fio_no_longjmp = 1;
1324 ret = system (cmdline);
1325
5600ea19
NS
1326 if (!length)
1327 remote_fileio_return_success (ret);
1328 else if (ret == -1)
449092f6
CV
1329 remote_fileio_return_errno (-1);
1330 else
1331 remote_fileio_return_success (WEXITSTATUS (ret));
1332}
1333
1334static struct {
1335 char *name;
1336 void (*func)(char *);
1337} remote_fio_func_map[] = {
d5d6fca5
DJ
1338 { "open", remote_fileio_func_open },
1339 { "close", remote_fileio_func_close },
1340 { "read", remote_fileio_func_read },
1341 { "write", remote_fileio_func_write },
1342 { "lseek", remote_fileio_func_lseek },
1343 { "rename", remote_fileio_func_rename },
1344 { "unlink", remote_fileio_func_unlink },
1345 { "stat", remote_fileio_func_stat },
1346 { "fstat", remote_fileio_func_fstat },
1347 { "gettimeofday", remote_fileio_func_gettimeofday },
1348 { "isatty", remote_fileio_func_isatty },
1349 { "system", remote_fileio_func_system },
1350 { NULL, NULL }
449092f6
CV
1351};
1352
1353static int
1354do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
1355{
1356 char *buf = buf_arg;
1357 char *c;
1358 int idx;
1359
1360 remote_fileio_sig_set (remote_fileio_ctrl_c_signal_handler);
1361
1362 c = strchr (++buf, ',');
1363 if (c)
1364 *c++ = '\0';
1365 else
1366 c = strchr (buf, '\0');
1367 for (idx = 0; remote_fio_func_map[idx].name; ++idx)
1368 if (!strcmp (remote_fio_func_map[idx].name, buf))
1369 break;
1370 if (!remote_fio_func_map[idx].name) /* ERROR: No such function. */
1371 return RETURN_ERROR;
1372 remote_fio_func_map[idx].func (c);
1373 return 0;
1374}
1375
ad9a8f3f
NS
1376/* Close any open descriptors, and reinitialize the file mapping. */
1377
1378void
1379remote_fileio_reset (void)
1380{
1381 int ix;
1382
1383 for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
1384 {
1385 int fd = remote_fio_data.fd_map[ix];
1386
1387 if (fd >= 0)
1388 close (fd);
1389 }
1390 if (remote_fio_data.fd_map)
1391 {
1392 free (remote_fio_data.fd_map);
1393 remote_fio_data.fd_map = NULL;
1394 remote_fio_data.fd_map_size = 0;
1395 }
1396}
1397
449092f6
CV
1398void
1399remote_fileio_request (char *buf)
1400{
1401 int ex;
1402
1403 remote_fileio_sig_init ();
1404
1405 remote_fio_ctrl_c_flag = 0;
1406 remote_fio_no_longjmp = 0;
1407
1408 ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
1c3c7ee7 1409 RETURN_MASK_ALL);
449092f6
CV
1410 switch (ex)
1411 {
1412 case RETURN_ERROR:
1413 remote_fileio_reply (-1, FILEIO_ENOSYS);
1414 break;
1415 case RETURN_QUIT:
1416 remote_fileio_reply (-1, FILEIO_EINTR);
1417 break;
1418 default:
1419 break;
1420 }
1421
1422 remote_fileio_sig_exit ();
1423}
1424
1425static void
1426set_system_call_allowed (char *args, int from_tty)
1427{
1428 if (args)
1429 {
1430 char *arg_end;
1431 int val = strtoul (args, &arg_end, 10);
1432 if (*args && *arg_end == '\0')
1433 {
1434 remote_fio_system_call_allowed = !!val;
1435 return;
1436 }
1437 }
8a3fe4f8 1438 error (_("Illegal argument for \"set remote system-call-allowed\" command"));
449092f6
CV
1439}
1440
1441static void
1442show_system_call_allowed (char *args, int from_tty)
1443{
1444 if (args)
8a3fe4f8 1445 error (_("Garbage after \"show remote system-call-allowed\" command: `%s'"), args);
449092f6
CV
1446 printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
1447 remote_fio_system_call_allowed ? "" : "not ");
1448}
1449
1450void
1451initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
1452 struct cmd_list_element *remote_show_cmdlist)
1453{
1454 add_cmd ("system-call-allowed", no_class,
1455 set_system_call_allowed,
1a966eab 1456 _("Set if the host system(3) call is allowed for the target."),
449092f6
CV
1457 &remote_set_cmdlist);
1458 add_cmd ("system-call-allowed", no_class,
1459 show_system_call_allowed,
1a966eab 1460 _("Show if the host system(3) call is allowed for the target."),
449092f6
CV
1461 &remote_show_cmdlist);
1462}
This page took 0.435142 seconds and 4 git commands to generate.