EINTR-protect a bunch of calls, and warn on close() failing.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 7 Apr 2013 16:51:27 +0000 (18:51 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 7 Apr 2013 16:51:27 +0000 (18:51 +0200)
server.cpp

index e26a85b3361f257da8756b78b5ef03783148c1d3..3e639cf7455a470d45072992cb7efd20eeaf30f9 100644 (file)
@@ -102,7 +102,14 @@ Server::Server()
 
 Server::~Server()
 {
-       close(epoll_fd);
+       int ret;
+       do {
+               ret = close(epoll_fd);
+       } while (ret == -1 && errno == EINTR);
+
+       if (ret == -1) {
+               perror("close(epoll_fd)");
+       }
 }
 
 void Server::run()
@@ -282,7 +289,10 @@ void Server::process_client(Client *client)
        case Client::READING_REQUEST: {
                // Try to read more of the request.
                char buf[1024];
-               int ret = read(client->sock, buf, sizeof(buf));
+               int ret;
+               do {
+                       ret = read(client->sock, buf, sizeof(buf));
+               } while (ret == -1 && errno == EINTR);
                if (ret == -1) {
                        perror("read");
                        close_client(client);
@@ -333,9 +343,12 @@ void Server::process_client(Client *client)
        }
        case Client::SENDING_ERROR:
        case Client::SENDING_HEADER: {
-               int ret = write(client->sock,
-                               client->header_or_error.data() + client->header_or_error_bytes_sent,
-                               client->header_or_error.size() - client->header_or_error_bytes_sent);
+               int ret;
+               do {
+                       ret = write(client->sock,
+                                   client->header_or_error.data() + client->header_or_error_bytes_sent,
+                                   client->header_or_error.size() - client->header_or_error_bytes_sent);
+               } while (ret == -1 && errno == EINTR);
                if (ret == -1) {
                        perror("write");
                        close_client(client);
@@ -388,11 +401,15 @@ void Server::process_client(Client *client)
                        iov[1].iov_base = const_cast<char *>(stream.data);
                        iov[1].iov_len = bytes_to_send - bytes_first_part;
 
-                       ret = writev(client->sock, iov, 2);
+                       do {
+                               ret = writev(client->sock, iov, 2);
+                       } while (ret == -1 && errno == EINTR);
                } else {
-                       ret = write(client->sock,
-                                   stream.data + (client->bytes_sent % BACKLOG_SIZE),
-                                   bytes_to_send);
+                       do {
+                               ret = write(client->sock,
+                                           stream.data + (client->bytes_sent % BACKLOG_SIZE),
+                                           bytes_to_send);
+                       } while (ret == -1 && errno == EINTR);
                }
                if (ret == -1) {
                        perror("write/writev");
@@ -489,7 +506,15 @@ void Server::close_client(Client *client)
        sleeping_clients.erase(new_end, sleeping_clients.end());
        
        // Bye-bye!
-       close(client->sock);
+       int ret;
+       do {
+               ret = close(client->sock);
+       } while (ret == -1 && errno == EINTR);
+
+       if (ret == -1) {
+               perror("close");
+       }
+
        clients.erase(client->sock);
 }