From 8c54d8d932878ee007bede8146ffb7253fcb499d Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 19 Jun 2012 12:30:00 +0400 Subject: [PATCH] pipes: Add dump_one_pipe_data helpers Will need it for fifo data dumping. At moment the helper is pushed out of compilation procedure for easier review, and will be real used in next patch. Signed-off-by: Cyrill Gorcunov Signed-off-by: Pavel Emelyanov --- pipes.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/pipes.c b/pipes.c index 51869e399..30e43694e 100644 --- a/pipes.c +++ b/pipes.c @@ -304,6 +304,98 @@ static int open_pipe(struct file_desc *d) static u32 *pipes_with_data; /* pipes for which data already dumped */ static int nr_pipes = 0; +#if 0 +static int dump_one_pipe_data(int lfd, u32 id, const struct fd_parms *p) +{ + int pipe_size, i, bytes; + int steal_pipe[2]; + int ret = -1; + + if (p->flags & O_WRONLY) + return 0; + + /* Maybe we've dumped it already */ + for (i = 0; i < nr_pipes; i++) { + if (pipes_with_data[i] == p->id) + return 0; + } + + pr_info("Dumping data from pipe %#x fd %d\n", id, lfd); + + if (PIPES_SIZE < nr_pipes + 1) { + pr_err("OOM storing pipe\n"); + return -1; + } + + pipes_with_data[nr_pipes] = p->id; + nr_pipes++; + + pipe_size = fcntl(lfd, F_GETPIPE_SZ); + if (pipe_size < 0) { + pr_err("Can't obtain piped data size\n"); + goto err; + } + + if (pipe(steal_pipe) < 0) { + pr_perror("Can't create pipe for stealing data"); + goto err; + } + + bytes = tee(lfd, steal_pipe[1], pipe_size, SPLICE_F_NONBLOCK); + if (bytes > 0) { + int fd_pipes_data = fdset_fd(glob_fdset, CR_FD_PIPES_DATA); + struct pipe_data_entry pde; + int wrote; + + pde.pipe_id = p->id; + pde.bytes = bytes; + pde.off = 0; + + if (bytes > PIPE_MAX_NONALIG_SIZE) { + off_t off; + + off = lseek(fd_pipes_data, 0, SEEK_CUR); + off += sizeof(pde); + off &= ~PAGE_MASK; + + if (off) + pde.off = PAGE_SIZE - off; + + pr_info("\toff %#lx %#x bytes %#x\n", off, pde.off, bytes); + } + + if (write_img(fd_pipes_data, &pde)) + goto err_close; + + /* Don't forget to advance position if a hole needed */ + if (pde.off) + lseek(fd_pipes_data, pde.off, SEEK_CUR); + + wrote = splice(steal_pipe[0], NULL, fd_pipes_data, NULL, bytes, 0); + if (wrote < 0) { + pr_perror("Can't push pipe data"); + goto err_close; + } else if (wrote != bytes) { + pr_err("%#x: Wanted to write %d bytes, but wrote %d\n", id, bytes, wrote); + goto err_close; + } + } else if (bytes < 0) { + if (errno != EAGAIN) { + pr_perror("Can't pick pipe data"); + goto err_close; + } + } + + ret = 0; + +err_close: + close(steal_pipe[0]); + close(steal_pipe[1]); +err: + return ret; +} +#endif + static int dump_one_pipe(int lfd, u32 id, const struct fd_parms *p) { struct pipe_entry pe;