Reinstate double logging if f_err != stderr
[fio.git] / client.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <limits.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <sys/poll.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/wait.h>
11 #include <sys/mman.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <netdb.h>
15
16 #include "fio.h"
17 #include "server.h"
18 #include "crc/crc32.h"
19
20 int fio_client_fd = -1;
21
22 int fio_client_connect(const char *host)
23 {
24         struct sockaddr_in addr;
25         int fd;
26
27         memset(&addr, 0, sizeof(addr));
28         addr.sin_family = AF_INET;
29         addr.sin_port = htons(fio_net_port);
30
31         if (inet_aton(host, &addr.sin_addr) != 1) {
32                 struct hostent *hent;
33
34                 hent = gethostbyname(host);
35                 if (!hent) {
36                         log_err("fio: gethostbyname: %s\n", strerror(errno));
37                         return 1;
38                 }
39
40                 memcpy(&addr.sin_addr, hent->h_addr, 4);
41         }
42
43         fd = socket(AF_INET, SOCK_STREAM, 0);
44         if (fd < 0) {
45                 log_err("fio: socket: %s\n", strerror(errno));
46                 return 1;
47         }
48
49         if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
50                 log_err("fio: connect: %s\n", strerror(errno));
51                 return 1;
52         }
53
54         fio_client_fd = fd;
55         return 0;
56 }
57
58 static int send_file_buf(char *buf, off_t size)
59 {
60         struct fio_net_cmd *cmd;
61         int ret;
62
63         cmd = malloc(sizeof(*cmd) + size);
64
65         fio_init_net_cmd(cmd, FIO_NET_CMD_JOB_END, buf, size);
66         fio_net_cmd_crc(cmd);
67
68         ret = fio_send_data(fio_client_fd, cmd, sizeof(*cmd) + size);
69         free(cmd);
70         return ret;
71 }
72
73 /*
74  * Send file contents to server backend. We could use sendfile(), but to remain
75  * more portable lets just read/write the darn thing.
76  */
77 int fio_client_send_ini(const char *filename)
78 {
79         struct stat sb;
80         char *p, *buf;
81         off_t len;
82         int fd, ret;
83
84         fd = open(filename, O_RDONLY);
85         if (fd < 0) {
86                 log_err("fio: job file open: %s\n", strerror(errno));
87                 return 1;
88         }
89
90         if (fstat(fd, &sb) < 0) {
91                 log_err("fio: job file stat: %s\n", strerror(errno));
92                 return 1;
93         }
94
95         buf = malloc(sb.st_size);
96
97         len = sb.st_size;
98         p = buf;
99         do {
100                 ret = read(fd, p, len);
101                 if (ret > 0) {
102                         len -= ret;
103                         if (!len)
104                                 break;
105                         p += ret;
106                         continue;
107                 } else if (!ret)
108                         break;
109                 else if (errno == EAGAIN || errno == EINTR)
110                         continue;
111         } while (1);
112
113         ret = send_file_buf(buf, sb.st_size);
114         free(buf);
115         return ret;
116 }
117
118 int fio_handle_clients(void)
119 {
120         struct fio_net_cmd *cmd;
121
122         while (!exit_backend) {
123                 cmd = fio_net_cmd_read(fio_client_fd);
124                 if (!cmd)
125                         continue;
126
127                 if (cmd->opcode == FIO_NET_CMD_ACK) {
128                         free(cmd);
129                         continue;
130                 }
131                 if (cmd->opcode != FIO_NET_CMD_TEXT) {
132                         printf("non text: %d\n", cmd->opcode);
133                         free(cmd);
134                         continue;
135                 }
136                 printf("%s", cmd->payload);
137                 fflush(stdout);
138                 free(cmd);
139         }
140
141         return 0;
142 }