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