server: fix for non zero appended strings
[fio.git] / server.c
index 938f58bb3d4e39c9d308dd5aacf5dbb58e6e1f29..a8b8258bc89bb897e9226ac9d6eb59f673b1d86a 100644 (file)
--- a/server.c
+++ b/server.c
@@ -111,7 +111,7 @@ static int verify_convert_cmd(struct fio_net_cmd *cmd)
 /*
  * Read (and defragment, if necessary) incoming commands
  */
-struct fio_net_cmd *fio_net_recv_cmd(int sk)
+struct fio_net_cmd *fio_net_recv_cmd(int sk, int block)
 {
        struct fio_net_cmd cmd, *cmdret = NULL;
        size_t cmd_size = 0, pdu_offset = 0;
@@ -126,14 +126,19 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk)
                pfd.events = POLLIN;
                ret = 0;
                do {
-                       ret = poll(&pfd, 1, 100);
+                       int timeo = block ? 100 : 10;
+
+                       ret = poll(&pfd, 1, timeo);
                        if (ret < 0) {
                                if (errno == EINTR)
                                        break;
                                log_err("fio: poll: %s\n", strerror(errno));
                                break;
-                       } else if (!ret)
+                       } else if (!ret) {
+                               if (!block)
+                                       return NULL;
                                continue;
+                       }
 
                        if (pfd.revents & POLLIN)
                                break;
@@ -141,7 +146,7 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk)
                                ret = 1;
                                break;
                        }
-               } while (ret >= 0);
+               } while (ret >= 0 && block);
 
                if (ret < 0)
                        break;
@@ -155,9 +160,11 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk)
                if (ret)
                        break;
 
-               if (first)
-                       cmd_size = sizeof(cmd) + cmd.pdu_len;
-               else
+               if (first) {
+                       /* if this is text, add room for \0 at the end */
+                       cmd_size = sizeof(cmd) + cmd.pdu_len + 1;
+                       assert(!cmdret);
+               } else
                        cmd_size += cmd.pdu_len;
 
                cmdret = realloc(cmdret, cmd_size);
@@ -194,8 +201,17 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk)
        if (ret) {
                free(cmdret);
                cmdret = NULL;
-       } else if (cmdret)
+       } else if (cmdret) {
+               /* zero-terminate text input */
+               if (cmdret->pdu_len && (cmdret->opcode == FIO_NET_CMD_TEXT ||
+                   cmdret->opcode == FIO_NET_CMD_JOB)) {
+                       char *buf = (char *) cmdret->payload;
+
+                       buf[cmdret->pdu_len ] = '\0';
+               }
+               /* frag flag is internal */
                cmdret->flags &= ~FIO_NET_CMD_F_MORE;
+       }
 
        return cmdret;
 }
@@ -259,9 +275,9 @@ static int send_quit_command(void)
        return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0);
 }
 
-static int handle_cur_job(struct fio_net_cmd *cmd)
+static int handle_job_cmd(struct fio_net_cmd *cmd)
 {
-       void *buf = cmd->payload;
+       char *buf = (char *) cmd->payload;
        int ret;
 
        parse_jobs_ini(buf, 1, 0);
@@ -298,7 +314,7 @@ static int handle_command(struct fio_net_cmd *cmd)
                exit_backend = 1;
                return -1;
        case FIO_NET_CMD_JOB:
-               ret = handle_cur_job(cmd);
+               ret = handle_job_cmd(cmd);
                break;
        case FIO_NET_CMD_PROBE:
                ret = handle_probe_cmd(cmd);
@@ -311,14 +327,14 @@ static int handle_command(struct fio_net_cmd *cmd)
        return ret;
 }
 
-static int handle_connection(int sk)
+static int handle_connection(int sk, int block)
 {
        struct fio_net_cmd *cmd = NULL;
        int ret = 0;
 
        /* read forever */
        while (!exit_backend) {
-               cmd = fio_net_recv_cmd(sk);
+               cmd = fio_net_recv_cmd(sk, block);
                if (!cmd) {
                        ret = -1;
                        break;
@@ -341,7 +357,7 @@ static int handle_connection(int sk)
 void fio_server_idle_loop(void)
 {
        if (server_fd != -1)
-               handle_connection(server_fd);
+               handle_connection(server_fd, 0);
 }
 
 static int accept_loop(int listen_sk)
@@ -384,7 +400,7 @@ again:
 
        server_fd = sk;
 
-       exitval = handle_connection(sk);
+       exitval = handle_connection(sk, 1);
 
        server_fd = -1;
        close(sk);