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