1 /* Host file transfer support for gdbserver.
2 Copyright (C) 2007-2015 Free Software Foundation, Inc.
4 Contributed by CodeSourcery.
6 This file is part of GDB.
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.
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.
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/>. */
22 #include "gdb/fileio.h"
28 #include <sys/types.h>
32 extern int remote_debug
;
40 static struct fd_list
*open_fds
;
43 safe_fromhex (char a
, int *nibble
)
45 if (a
>= '0' && a
<= '9')
47 else if (a
>= 'a' && a
<= 'f')
48 *nibble
= a
- 'a' + 10;
49 else if (a
>= 'A' && a
<= 'F')
50 *nibble
= a
- 'A' + 10;
57 /* Filenames are hex encoded, so the maximum we can handle is half the
58 packet buffer size. Cap to PATH_MAX, if it is shorter. */
59 #if !defined (PATH_MAX) || (PATH_MAX > (PBUFSIZ / 2 + 1))
60 # define HOSTIO_PATH_MAX (PBUFSIZ / 2 + 1)
62 # define HOSTIO_PATH_MAX PATH_MAX
66 require_filename (char **pp
, char *filename
)
74 while (*p
&& *p
!= ',')
78 /* Don't allow overflow. */
79 if (count
>= HOSTIO_PATH_MAX
- 1)
82 if (safe_fromhex (p
[0], &nib1
)
83 || safe_fromhex (p
[1], &nib2
))
86 filename
[count
++] = nib1
* 16 + nib2
;
90 filename
[count
] = '\0';
96 require_int (char **pp
, int *value
)
105 while (*p
&& *p
!= ',')
109 /* Don't allow overflow. */
113 if (safe_fromhex (p
[0], &nib
))
115 *value
= *value
* 16 + nib
;
125 require_data (char *p
, int p_len
, char **data
, int *data_len
)
127 int input_index
, output_index
, escaped
;
129 *data
= xmalloc (p_len
);
133 for (input_index
= 0; input_index
< p_len
; input_index
++)
135 char b
= p
[input_index
];
139 (*data
)[output_index
++] = b
^ 0x20;
145 (*data
)[output_index
++] = b
;
154 *data_len
= output_index
;
159 require_comma (char **pp
)
171 require_end (char *p
)
180 require_valid_fd (int fd
)
182 struct fd_list
*fd_ptr
;
184 for (fd_ptr
= open_fds
; fd_ptr
!= NULL
; fd_ptr
= fd_ptr
->next
)
185 if (fd_ptr
->fd
== fd
)
191 /* Fill in own_buf with the last hostio error packet, however it
192 suitable for the target. */
194 hostio_error (char *own_buf
)
196 the_target
->hostio_last_error (own_buf
);
200 hostio_packet_error (char *own_buf
)
202 sprintf (own_buf
, "F-1,%x", FILEIO_EINVAL
);
206 hostio_reply (char *own_buf
, int result
)
208 sprintf (own_buf
, "F%x", result
);
212 hostio_reply_with_data (char *own_buf
, char *buffer
, int len
,
215 int input_index
, output_index
, out_maxlen
;
217 sprintf (own_buf
, "F%x;", len
);
218 output_index
= strlen (own_buf
);
220 out_maxlen
= PBUFSIZ
;
222 for (input_index
= 0; input_index
< len
; input_index
++)
224 char b
= buffer
[input_index
];
226 if (b
== '$' || b
== '#' || b
== '}' || b
== '*')
228 /* These must be escaped. */
229 if (output_index
+ 2 > out_maxlen
)
231 own_buf
[output_index
++] = '}';
232 own_buf
[output_index
++] = b
^ 0x20;
236 if (output_index
+ 1 > out_maxlen
)
238 own_buf
[output_index
++] = b
;
242 *new_packet_len
= output_index
;
247 handle_open (char *own_buf
)
249 char filename
[HOSTIO_PATH_MAX
];
251 int fileio_flags
, fileio_mode
, flags
, fd
;
253 struct fd_list
*new_fd
;
255 p
= own_buf
+ strlen ("vFile:open:");
257 if (require_filename (&p
, filename
)
258 || require_comma (&p
)
259 || require_int (&p
, &fileio_flags
)
260 || require_comma (&p
)
261 || require_int (&p
, &fileio_mode
)
263 || fileio_to_host_openflags (fileio_flags
, &flags
)
264 || fileio_to_host_mode (fileio_mode
, &mode
))
266 hostio_packet_error (own_buf
);
270 /* We do not need to convert MODE, since the fileio protocol
271 uses the standard values. */
272 fd
= open (filename
, flags
, mode
);
276 hostio_error (own_buf
);
280 /* Record the new file descriptor. */
281 new_fd
= xmalloc (sizeof (struct fd_list
));
283 new_fd
->next
= open_fds
;
286 hostio_reply (own_buf
, fd
);
290 handle_pread (char *own_buf
, int *new_packet_len
)
292 int fd
, ret
, len
, offset
, bytes_sent
;
295 p
= own_buf
+ strlen ("vFile:pread:");
297 if (require_int (&p
, &fd
)
298 || require_comma (&p
)
299 || require_valid_fd (fd
)
300 || require_int (&p
, &len
)
301 || require_comma (&p
)
302 || require_int (&p
, &offset
)
305 hostio_packet_error (own_buf
);
309 data
= xmalloc (len
);
311 ret
= pread (fd
, data
, len
, offset
);
315 /* If we have no pread or it failed for this file, use lseek/read. */
318 ret
= lseek (fd
, offset
, SEEK_SET
);
320 ret
= read (fd
, data
, len
);
325 hostio_error (own_buf
);
330 bytes_sent
= hostio_reply_with_data (own_buf
, data
, ret
, new_packet_len
);
332 /* If we were using read, and the data did not all fit in the reply,
333 we would have to back up using lseek here. With pread it does
334 not matter. But we still have a problem; the return value in the
335 packet might be wrong, so we must fix it. This time it will
337 if (bytes_sent
< ret
)
338 bytes_sent
= hostio_reply_with_data (own_buf
, data
, bytes_sent
,
345 handle_pwrite (char *own_buf
, int packet_len
)
347 int fd
, ret
, len
, offset
;
350 p
= own_buf
+ strlen ("vFile:pwrite:");
352 if (require_int (&p
, &fd
)
353 || require_comma (&p
)
354 || require_valid_fd (fd
)
355 || require_int (&p
, &offset
)
356 || require_comma (&p
)
357 || require_data (p
, packet_len
- (p
- own_buf
), &data
, &len
))
359 hostio_packet_error (own_buf
);
364 ret
= pwrite (fd
, data
, len
, offset
);
368 /* If we have no pwrite or it failed for this file, use lseek/write. */
371 ret
= lseek (fd
, offset
, SEEK_SET
);
373 ret
= write (fd
, data
, len
);
378 hostio_error (own_buf
);
383 hostio_reply (own_buf
, ret
);
388 handle_fstat (char *own_buf
, int *new_packet_len
)
395 p
= own_buf
+ strlen ("vFile:fstat:");
397 if (require_int (&p
, &fd
)
398 || require_valid_fd (fd
)
401 hostio_packet_error (own_buf
);
405 if (fstat (fd
, &st
) == -1)
407 hostio_error (own_buf
);
411 host_to_fileio_stat (&st
, &fst
);
413 bytes_sent
= hostio_reply_with_data (own_buf
,
414 (char *) &fst
, sizeof (fst
),
417 /* If the response does not fit into a single packet, do not attempt
418 to return a partial response, but simply fail. */
419 if (bytes_sent
< sizeof (fst
))
424 handle_close (char *own_buf
)
428 struct fd_list
**open_fd_p
, *old_fd
;
430 p
= own_buf
+ strlen ("vFile:close:");
432 if (require_int (&p
, &fd
)
433 || require_valid_fd (fd
)
436 hostio_packet_error (own_buf
);
444 hostio_error (own_buf
);
448 open_fd_p
= &open_fds
;
449 /* We know that fd is in the list, thanks to require_valid_fd. */
450 while ((*open_fd_p
)->fd
!= fd
)
451 open_fd_p
= &(*open_fd_p
)->next
;
454 *open_fd_p
= (*open_fd_p
)->next
;
457 hostio_reply (own_buf
, ret
);
461 handle_unlink (char *own_buf
)
463 char filename
[HOSTIO_PATH_MAX
];
467 p
= own_buf
+ strlen ("vFile:unlink:");
469 if (require_filename (&p
, filename
)
472 hostio_packet_error (own_buf
);
476 ret
= unlink (filename
);
480 hostio_error (own_buf
);
484 hostio_reply (own_buf
, ret
);
488 handle_readlink (char *own_buf
, int *new_packet_len
)
490 char filename
[HOSTIO_PATH_MAX
], linkname
[HOSTIO_PATH_MAX
];
494 p
= own_buf
+ strlen ("vFile:readlink:");
496 if (require_filename (&p
, filename
)
499 hostio_packet_error (own_buf
);
503 ret
= readlink (filename
, linkname
, sizeof (linkname
) - 1);
506 hostio_error (own_buf
);
510 bytes_sent
= hostio_reply_with_data (own_buf
, linkname
, ret
, new_packet_len
);
512 /* If the response does not fit into a single packet, do not attempt
513 to return a partial response, but simply fail. */
514 if (bytes_sent
< ret
)
515 sprintf (own_buf
, "F-1,%x", FILEIO_ENAMETOOLONG
);
518 /* Handle all the 'F' file transfer packets. */
521 handle_vFile (char *own_buf
, int packet_len
, int *new_packet_len
)
523 if (startswith (own_buf
, "vFile:open:"))
524 handle_open (own_buf
);
525 else if (startswith (own_buf
, "vFile:pread:"))
526 handle_pread (own_buf
, new_packet_len
);
527 else if (startswith (own_buf
, "vFile:pwrite:"))
528 handle_pwrite (own_buf
, packet_len
);
529 else if (startswith (own_buf
, "vFile:fstat:"))
530 handle_fstat (own_buf
, new_packet_len
);
531 else if (startswith (own_buf
, "vFile:close:"))
532 handle_close (own_buf
);
533 else if (startswith (own_buf
, "vFile:unlink:"))
534 handle_unlink (own_buf
);
535 else if (startswith (own_buf
, "vFile:readlink:"))
536 handle_readlink (own_buf
, new_packet_len
);
This page took 0.040358 seconds and 4 git commands to generate.