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