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