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