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