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