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