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