static void handle_unlink (char *own_buf) { char filename[PATH_MAX]; char *p; int ret; p = own_buf + strlen ("vFile:unlink:"); if (require_filename (&p, filename) || require_end (p)) { hostio_packet_error (own_buf); return; } ret = unlink (filename); if (ret == -1) { hostio_error (own_buf); return; } hostio_reply (own_buf, ret); }
static void handle_readlink (char *own_buf, int *new_packet_len) { #if defined (HAVE_READLINK) char filename[PATH_MAX], linkname[PATH_MAX]; char *p; int ret, bytes_sent; p = own_buf + strlen ("vFile:readlink:"); if (require_filename (&p, filename) || require_end (p)) { hostio_packet_error (own_buf); return; } ret = readlink (filename, linkname, sizeof linkname); if (ret == -1) { hostio_error (own_buf); return; } bytes_sent = hostio_reply_with_data (own_buf, linkname, ret, new_packet_len); /* If the response does not fit into a single packet, do not attempt to return a partial response, but simply fail. */ if (bytes_sent < ret) sprintf (own_buf, "F-1,%x", FILEIO_ENAMETOOLONG); #else /* ! HAVE_READLINK */ sprintf (own_buf, "F-1,%x", FILEIO_ENOSYS); #endif }
static void handle_unlink (char *own_buf) { char filename[HOSTIO_PATH_MAX]; char *p; int ret; p = own_buf + strlen ("vFile:unlink:"); if (require_filename (&p, filename) || require_end (p)) { hostio_packet_error (own_buf); return; } 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) { hostio_error (own_buf); return; } hostio_reply (own_buf, ret); }
static void handle_fstat (char *own_buf, int *new_packet_len) { int fd, bytes_sent; char *p; struct stat st; struct fio_stat fst; p = own_buf + strlen ("vFile:fstat:"); if (require_int (&p, &fd) || require_valid_fd (fd) || require_end (p)) { hostio_packet_error (own_buf); return; } if (fstat (fd, &st) == -1) { hostio_error (own_buf); return; } host_to_fileio_stat (&st, &fst); bytes_sent = hostio_reply_with_data (own_buf, (char *) &fst, sizeof (fst), new_packet_len); /* If the response does not fit into a single packet, do not attempt to return a partial response, but simply fail. */ if (bytes_sent < sizeof (fst)) write_enn (own_buf); }
static void handle_close (char *own_buf) { int fd, ret; char *p; struct fd_list **open_fd_p, *old_fd; p = own_buf + strlen ("vFile:close:"); if (require_int (&p, &fd) || require_valid_fd (fd) || require_end (p)) { hostio_packet_error (own_buf); return; } ret = close (fd); if (ret == -1) { hostio_error (own_buf); return; } open_fd_p = &open_fds; while (*open_fd_p && (*open_fd_p)->fd != fd) open_fd_p = &(*open_fd_p)->next; old_fd = *open_fd_p; *open_fd_p = (*open_fd_p)->next; free (old_fd); hostio_reply (own_buf, ret); }
static void handle_pread (char *own_buf, int *new_packet_len) { int fd, ret, len, offset, bytes_sent; char *p, *data; p = own_buf + strlen ("vFile:pread:"); if (require_int (&p, &fd) || require_comma (&p) || require_valid_fd (fd) || require_int (&p, &len) || require_comma (&p) || require_int (&p, &offset) || require_end (p)) { hostio_packet_error (own_buf); return; } data = xmalloc (len); #ifdef HAVE_PREAD ret = pread (fd, data, len, offset); #else ret = -1; #endif /* If we have no pread or it failed for this file, use lseek/read. */ if (ret == -1) { ret = lseek (fd, offset, SEEK_SET); if (ret != -1) ret = read (fd, data, len); } if (ret == -1) { hostio_error (own_buf); free (data); return; } bytes_sent = hostio_reply_with_data (own_buf, data, ret, new_packet_len); /* If we were using read, and the data did not all fit in the reply, we would have to back up using lseek here. With pread it does not matter. But we still have a problem; the return value in the packet might be wrong, so we must fix it. This time it will definitely fit. */ if (bytes_sent < ret) bytes_sent = hostio_reply_with_data (own_buf, data, bytes_sent, new_packet_len); free (data); }
static void handle_open (char *own_buf) { char filename[HOSTIO_PATH_MAX]; char *p; int fileio_flags, fileio_mode, flags, fd; mode_t mode; struct fd_list *new_fd; p = own_buf + strlen ("vFile:open:"); if (require_filename (&p, filename) || require_comma (&p) || require_int (&p, &fileio_flags) || require_comma (&p) || require_int (&p, &fileio_mode) || require_end (p) || 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. */ 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) { hostio_error (own_buf); return; } /* Record the new file descriptor. */ new_fd = xmalloc (sizeof (struct fd_list)); new_fd->fd = fd; new_fd->next = open_fds; open_fds = new_fd; hostio_reply (own_buf, fd); }
static void handle_pwrite (char *own_buf, int packet_len) { int fd, ret, len, offset; char *p, *data; p = own_buf + strlen ("vFile:pwrite:"); if (require_int (&p, &fd) || require_comma (&p) || require_valid_fd (fd) || require_int (&p, &offset) || require_comma (&p) || require_data (p, packet_len - (p - own_buf), &data, &len)) { hostio_packet_error (own_buf); return; } #ifdef HAVE_PWRITE ret = pwrite (fd, data, len, offset); #else ret = -1; #endif /* If we have no pwrite or it failed for this file, use lseek/write. */ if (ret == -1) { ret = lseek (fd, offset, SEEK_SET); if (ret != -1) ret = write (fd, data, len); } if (ret == -1) { hostio_error (own_buf); free (data); return; } hostio_reply (own_buf, ret); free (data); }
static void handle_open (char *own_buf) { char filename[PATH_MAX]; char *p; int fileio_flags, mode, flags, fd; struct fd_list *new_fd; p = own_buf + strlen ("vFile:open:"); if (require_filename (&p, filename) || require_comma (&p) || require_int (&p, &fileio_flags) || require_comma (&p) || require_int (&p, &mode) || require_end (p) || fileio_open_flags_to_host (fileio_flags, &flags)) { 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 (fd == -1) { hostio_error (own_buf); return; } /* Record the new file descriptor. */ new_fd = xmalloc (sizeof (struct fd_list)); new_fd->fd = fd; new_fd->next = open_fds; open_fds = new_fd; hostio_reply (own_buf, fd); }
static void handle_readlink (char *own_buf, int *new_packet_len) { char filename[HOSTIO_PATH_MAX], linkname[HOSTIO_PATH_MAX]; char *p; int ret, bytes_sent; p = own_buf + strlen ("vFile:readlink:"); if (require_filename (&p, filename) || require_end (p)) { hostio_packet_error (own_buf); return; } 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); return; } bytes_sent = hostio_reply_with_data (own_buf, linkname, ret, new_packet_len); /* If the response does not fit into a single packet, do not attempt to return a partial response, but simply fail. */ if (bytes_sent < ret) sprintf (own_buf, "F-1,%x", FILEIO_ENAMETOOLONG); }
static void handle_pread (char *own_buf, int *new_packet_len) { int fd, ret, len, offset, bytes_sent; char *p, *data; static int max_reply_size = -1; p = own_buf + strlen ("vFile:pread:"); if (require_int (&p, &fd) || require_comma (&p) || require_valid_fd (fd) || require_int (&p, &len) || require_comma (&p) || require_int (&p, &offset) || require_end (p)) { hostio_packet_error (own_buf); return; } /* 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 = xmalloc (len); #ifdef HAVE_PREAD ret = pread (fd, data, len, offset); #else ret = -1; #endif /* If we have no pread or it failed for this file, use lseek/read. */ if (ret == -1) { ret = lseek (fd, offset, SEEK_SET); if (ret != -1) ret = read (fd, data, len); } if (ret == -1) { hostio_error (own_buf); free (data); return; } bytes_sent = hostio_reply_with_data (own_buf, data, ret, new_packet_len); /* If we were using read, and the data did not all fit in the reply, we would have to back up using lseek here. With pread it does not matter. But we still have a problem; the return value in the packet might be wrong, so we must fix it. This time it will definitely fit. */ if (bytes_sent < ret) bytes_sent = hostio_reply_with_data (own_buf, data, bytes_sent, new_packet_len); free (data); }