{
int input_index, output_index, escaped;
- *data = xmalloc (p_len);
+ *data = (char *) xmalloc (p_len);
output_index = 0;
escaped = 0;
return input_index;
}
+/* Process ID of inferior whose filesystem hostio functions
+ that take FILENAME arguments will use. Zero means to use
+ our own filesystem. */
+
+static int hostio_fs_pid;
+
+/* See hostio.h. */
+
+void
+hostio_handle_new_gdb_connection (void)
+{
+ hostio_fs_pid = 0;
+}
+
+/* Handle a "vFile:setfs:" packet. */
+
+static void
+handle_setfs (char *own_buf)
+{
+ char *p;
+ int pid;
+
+ /* If the target doesn't have any of the in-filesystem-of methods
+ then there's no point in GDB sending "vFile:setfs:" packets. We
+ reply with an empty packet (i.e. we pretend we don't understand
+ "vFile:setfs:") and that should stop GDB sending any more. */
+ if (the_target->multifs_open == NULL
+ && the_target->multifs_unlink == NULL
+ && the_target->multifs_readlink == NULL)
+ {
+ own_buf[0] = '\0';
+ return;
+ }
+
+ p = own_buf + strlen ("vFile:setfs:");
+
+ if (require_int (&p, &pid)
+ || pid < 0
+ || require_end (p))
+ {
+ hostio_packet_error (own_buf);
+ return;
+ }
+
+ hostio_fs_pid = pid;
+
+ hostio_reply (own_buf, 0);
+}
+
static void
handle_open (char *own_buf)
{
char filename[HOSTIO_PATH_MAX];
char *p;
- int fileio_flags, mode, flags, fd;
+ int fileio_flags, fileio_mode, flags, fd;
+ mode_t mode;
struct fd_list *new_fd;
p = own_buf + strlen ("vFile:open:");
|| require_comma (&p)
|| require_int (&p, &fileio_flags)
|| require_comma (&p)
- || require_int (&p, &mode)
+ || require_int (&p, &fileio_mode)
|| require_end (p)
- || fileio_to_host_openflags (fileio_flags, &flags))
+ || fileio_to_host_openflags (fileio_flags, &flags)
+ || fileio_to_host_mode (fileio_mode, &mode))
{
hostio_packet_error (own_buf);
return;
/* We do not need to convert MODE, since the fileio protocol
uses the standard values. */
- fd = open (filename, flags, mode);
+ if (hostio_fs_pid != 0 && the_target->multifs_open != NULL)
+ fd = the_target->multifs_open (hostio_fs_pid, filename,
+ flags, mode);
+ else
+ fd = open (filename, flags, mode);
if (fd == -1)
{
}
/* Record the new file descriptor. */
- new_fd = xmalloc (sizeof (struct fd_list));
+ new_fd = XNEW (struct fd_list);
new_fd->fd = fd;
new_fd->next = open_fds;
open_fds = new_fd;
{
int fd, ret, len, offset, bytes_sent;
char *p, *data;
+ static int max_reply_size = -1;
p = own_buf + strlen ("vFile:pread:");
return;
}
- data = xmalloc (len);
+ /* Do not attempt to read more than the maximum number of bytes
+ hostio_reply_with_data can fit in a packet. We may still read
+ too much because of escaping, but this is handled below. */
+ if (max_reply_size == -1)
+ {
+ sprintf (own_buf, "F%x;", PBUFSIZ);
+ max_reply_size = PBUFSIZ - strlen (own_buf);
+ }
+ if (len > max_reply_size)
+ len = max_reply_size;
+
+ data = (char *) xmalloc (len);
#ifdef HAVE_PREAD
ret = pread (fd, data, len, offset);
#else
return;
}
- ret = unlink (filename);
+ if (hostio_fs_pid != 0 && the_target->multifs_unlink != NULL)
+ ret = the_target->multifs_unlink (hostio_fs_pid, filename);
+ else
+ ret = unlink (filename);
if (ret == -1)
{
return;
}
- ret = readlink (filename, linkname, sizeof (linkname) - 1);
+ if (hostio_fs_pid != 0 && the_target->multifs_readlink != NULL)
+ ret = the_target->multifs_readlink (hostio_fs_pid, filename,
+ linkname,
+ sizeof (linkname) - 1);
+ else
+ ret = readlink (filename, linkname, sizeof (linkname) - 1);
+
if (ret == -1)
{
hostio_error (own_buf);
handle_unlink (own_buf);
else if (startswith (own_buf, "vFile:readlink:"))
handle_readlink (own_buf, new_packet_len);
+ else if (startswith (own_buf, "vFile:setfs:"))
+ handle_setfs (own_buf);
else
return 0;