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