node_main.c
changeset 12 43297144f196
child 19 d18606bb6f20
equal deleted inserted replaced
11:082bfaf38cf0 12:43297144f196
       
     1 #include <stdio.h>
       
     2 #include <sys/types.h>
       
     3 #include <arpa/inet.h>
       
     4 #include <sys/socket.h>
       
     5 #include <stdlib.h>
       
     6 #include <signal.h>
       
     7 #include <string.h>
       
     8 #include <unistd.h>
       
     9 
       
    10 #include "common.h"
       
    11 #include "render.h"
       
    12 #include "render_remote.h"  // for RENDER_PORT_NAME
       
    13 #include "render_local.h"
       
    14 
       
    15 void sigpipe_handler (int signal) {
       
    16     /* ignore */
       
    17     fprintf(stderr, "SIGPIPE\n");
       
    18 }
       
    19 
       
    20 void sigpipe_ignore () {
       
    21     struct sigaction sigpipe_action;
       
    22 
       
    23     memset(&sigpipe_action, 0, sizeof(sigpipe_action));
       
    24     sigpipe_action.sa_handler = SIG_IGN;
       
    25 
       
    26     if (sigaction(SIGPIPE, &sigpipe_action, NULL))
       
    27         perr_exit("sigaction");
       
    28 }
       
    29 
       
    30 int my_fread(FILE *fh, void *ptr, size_t size) {
       
    31     int ret = fread(ptr, size, 1, fh);
       
    32     
       
    33     if (ret == 0) {
       
    34         error("EOF");
       
    35         return 0;
       
    36 
       
    37     } else if (ret != 1) {
       
    38         perror("fread");
       
    39         return 0;
       
    40     }
       
    41 
       
    42     return 1;
       
    43 }
       
    44 
       
    45 int read_byte (FILE *fh, u_int8_t *byte) {
       
    46     return my_fread(fh, byte, sizeof(*byte));
       
    47 }
       
    48 
       
    49 int read_int (FILE *fh, u_int32_t *i) {
       
    50     if (!my_fread(fh, i, sizeof(*i)))
       
    51         return 0;
       
    52 
       
    53     *i = ntohl(*i);
       
    54 
       
    55     return 1;
       
    56 }
       
    57 
       
    58 int read_double (FILE *fh, double *dbl) {
       
    59     if (!my_fread(fh, dbl, sizeof(*dbl)))
       
    60         return 0;
       
    61 
       
    62     return 1;
       
    63 }
       
    64 
       
    65 void handle_client (int sock) {
       
    66     double duration;
       
    67     struct render *ctx;
       
    68     FILE *fh;
       
    69     u_int8_t mode;
       
    70     u_int32_t img_w, img_h;
       
    71     double x1, y1, x2, y2;
       
    72 
       
    73     
       
    74     // open it as a FILE*
       
    75     if (!(fh = fdopen(sock, "r+")))
       
    76         ERROR("fdopen");
       
    77     
       
    78     // read the parameters
       
    79     if (
       
    80             !read_byte(fh, &mode)
       
    81          || !read_int(fh, &img_w)
       
    82          || !read_int(fh, &img_h)
       
    83          || !read_double(fh, &x1)
       
    84          || !read_double(fh, &y1)
       
    85          || !read_double(fh, &x2)
       
    86          || !read_double(fh, &y2)
       
    87     )
       
    88         ERROR("read_{byte,int,double}");
       
    89 
       
    90     printf("RENDER: [%ux%u] (%f, %f) -> (%f, %f): ... ", img_w, img_h, x1, y1, x2, y2);
       
    91     fflush(stdout);
       
    92 
       
    93     // set up the render_ctx
       
    94     if (!(ctx = render_alloc()))
       
    95         ERROR("render_alloc");
       
    96 
       
    97     if (render_set_mode(ctx, mode))
       
    98         ERROR("render_set_mode");
       
    99 
       
   100     if (render_set_size(ctx, img_w, img_h))
       
   101         ERROR("render_set_size");
       
   102 
       
   103     if (render_region_raw(ctx, x1, y1, x2, y2))
       
   104         ERROR("render_region_raw");
       
   105 
       
   106     if (render_io_stream(ctx, fh))
       
   107         ERROR("render_io_stream");
       
   108   
       
   109     
       
   110     // render!
       
   111     if (render_local(ctx, &duration))
       
   112         ERROR("render_local");
       
   113 
       
   114     printf("time=%fs\n", duration);
       
   115 
       
   116 error:
       
   117     // close the FILE* and socket
       
   118     fclose(fh);
       
   119     
       
   120     return;
       
   121 }
       
   122 
       
   123 
       
   124 int main (int argc, char** argv) {
       
   125     int ssock, sock;
       
   126     struct sockaddr_in addr;
       
   127     socklen_t addr_len;
       
   128     
       
   129     // parse arguments
       
   130     int opt;
       
   131     const char *port_name = NULL;
       
   132     unsigned short port;
       
   133 
       
   134     while ((opt = getopt(argc, argv, "l:")) != -1) {
       
   135         switch (opt) {
       
   136             case 'l':
       
   137                 if (port_name)
       
   138                     ERROR("only specify -l once");
       
   139 
       
   140                 port_name = optarg;
       
   141                 break;
       
   142 
       
   143             default:
       
   144                 err_exit("Usage: %s [-l port]", argv[0]);
       
   145         }
       
   146     }
       
   147     
       
   148     // post-process arguments
       
   149     if (!port_name)
       
   150         port_name = RENDER_PORT_NAME;
       
   151 
       
   152     if (!(port = atoi(port_name)))
       
   153         ERROR("invalid port: %s", port_name);
       
   154 
       
   155     // create the socket
       
   156     if ((ssock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
       
   157         PERROR("socket");
       
   158 
       
   159     addr.sin_family = AF_INET;
       
   160     addr.sin_port = htons(port);
       
   161     addr.sin_addr.s_addr = INADDR_ANY;
       
   162 
       
   163     if (bind(ssock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == -1)
       
   164         PERROR("bind");
       
   165     
       
   166     if (listen(ssock, 1) == -1)
       
   167         PERROR("listen");
       
   168     
       
   169     // ignore sigpipe
       
   170     sigpipe_ignore();
       
   171     
       
   172     // main accept loop
       
   173     printf("RUN: %s:%hu\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
       
   174 
       
   175     while (1) {
       
   176         addr_len = sizeof(struct sockaddr_in);
       
   177 
       
   178         // accept a new client
       
   179         if ((sock = accept(ssock, (struct sockaddr *) &addr, &addr_len)) == -1)
       
   180             PERROR("accept");
       
   181         
       
   182         printf("ACCEPT: %s:%hu\n", inet_ntoa(addr.sin_addr), addr.sin_port);
       
   183         
       
   184         // handle their resquest
       
   185         handle_client(sock);
       
   186     }
       
   187 
       
   188 error:
       
   189     return 1;
       
   190 }
       
   191