xref: /aosp_15_r20/external/grpc-grpc/test/core/event_engine/posix/posix_engine_test_utils.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2022 gRPC Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "test/core/event_engine/posix/posix_engine_test_utils.h"
16 
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <poll.h>
20 #include <stdlib.h>
21 #include <sys/socket.h>
22 
23 #include "absl/strings/str_format.h"
24 
25 #include <grpc/support/log.h>
26 
27 #include "src/core/lib/gprpp/crash.h"
28 
29 namespace grpc_event_engine {
30 namespace experimental {
31 
32 using ResolvedAddress =
33     grpc_event_engine::experimental::EventEngine::ResolvedAddress;
34 
35 // Creates a client socket and blocks until it connects to the specified
36 // server address. The function abort fails upon encountering errors.
ConnectToServerOrDie(const ResolvedAddress & server_address)37 int ConnectToServerOrDie(const ResolvedAddress& server_address) {
38   int client_fd;
39   int one = 1;
40   int flags;
41 
42   client_fd = socket(AF_INET6, SOCK_STREAM, 0);
43   setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
44   // Make fd non-blocking.
45   flags = fcntl(client_fd, F_GETFL, 0);
46   fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
47 
48   if (connect(client_fd, const_cast<struct sockaddr*>(server_address.address()),
49               server_address.size()) == -1) {
50     if (errno == EINPROGRESS) {
51       struct pollfd pfd;
52       pfd.fd = client_fd;
53       pfd.events = POLLOUT;
54       pfd.revents = 0;
55       if (poll(&pfd, 1, -1) == -1) {
56         gpr_log(GPR_ERROR, "poll() failed during connect; errno=%d", errno);
57         abort();
58       }
59     } else {
60       grpc_core::Crash(
61           absl::StrFormat("Failed to connect to the server (errno=%d)", errno));
62     }
63   }
64   return client_fd;
65 }
66 
67 }  // namespace experimental
68 }  // namespace grpc_event_engine
69