Home | History | Annotate | Line # | Download | only in uvtee
      1 #include <stdio.h>
      2 #include <fcntl.h>
      3 #include <string.h>
      4 #include <stdlib.h>
      5 
      6 #include <uv.h>
      7 
      8 typedef struct {
      9     uv_write_t req;
     10     uv_buf_t buf;
     11 } write_req_t;
     12 
     13 uv_loop_t *loop;
     14 uv_pipe_t stdin_pipe;
     15 uv_pipe_t stdout_pipe;
     16 uv_pipe_t file_pipe;
     17 
     18 void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
     19     *buf = uv_buf_init((char*) malloc(suggested_size), suggested_size);
     20 }
     21 
     22 void free_write_req(uv_write_t *req) {
     23     write_req_t *wr = (write_req_t*) req;
     24     free(wr->buf.base);
     25     free(wr);
     26 }
     27 
     28 void on_stdout_write(uv_write_t *req, int status) {
     29     free_write_req(req);
     30 }
     31 
     32 void on_file_write(uv_write_t *req, int status) {
     33     free_write_req(req);
     34 }
     35 
     36 void write_data(uv_stream_t *dest, size_t size, uv_buf_t buf, uv_write_cb cb) {
     37     write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
     38     req->buf = uv_buf_init((char*) malloc(size), size);
     39     memcpy(req->buf.base, buf.base, size);
     40     uv_write((uv_write_t*) req, (uv_stream_t*)dest, &req->buf, 1, cb);
     41 }
     42 
     43 void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
     44     if (nread < 0){
     45         if (nread == UV_EOF){
     46             // end of file
     47             uv_close((uv_handle_t *)&stdin_pipe, NULL);
     48             uv_close((uv_handle_t *)&stdout_pipe, NULL);
     49             uv_close((uv_handle_t *)&file_pipe, NULL);
     50         }
     51     } else if (nread > 0) {
     52         write_data((uv_stream_t *)&stdout_pipe, nread, *buf, on_stdout_write);
     53         write_data((uv_stream_t *)&file_pipe, nread, *buf, on_file_write);
     54     }
     55 
     56     // OK to free buffer as write_data copies it.
     57     if (buf->base)
     58         free(buf->base);
     59 }
     60 
     61 int main(int argc, char **argv) {
     62     loop = uv_default_loop();
     63 
     64     uv_pipe_init(loop, &stdin_pipe, 0);
     65     uv_pipe_open(&stdin_pipe, 0);
     66 
     67     uv_pipe_init(loop, &stdout_pipe, 0);
     68     uv_pipe_open(&stdout_pipe, 1);
     69 
     70     uv_fs_t file_req;
     71     int fd = uv_fs_open(loop, &file_req, argv[1], O_CREAT | O_RDWR, 0644, NULL);
     72     uv_pipe_init(loop, &file_pipe, 0);
     73     uv_pipe_open(&file_pipe, fd);
     74 
     75     uv_read_start((uv_stream_t*)&stdin_pipe, alloc_buffer, read_stdin);
     76 
     77     uv_run(loop, UV_RUN_DEFAULT);
     78     return 0;
     79 }
     80