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