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