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