blob: 7126ff8887a4a879a6ac21fa49adc4f2004efd48 [file] [log] [blame]
Ravi Tejace1c96f2020-10-05 23:13:01 -05001#include "utils.hpp"
2
George Liuc453e162022-12-21 17:16:23 +08003#include <libpldm/base.h>
Ravi Tejace1c96f2020-10-05 23:13:01 -05004#include <sys/socket.h>
5#include <sys/types.h>
6#include <sys/un.h>
7#include <unistd.h>
8
Riya Dixit49cfb132023-03-02 04:26:53 -06009#include <phosphor-logging/lg2.hpp>
10
Riya Dixit49cfb132023-03-02 04:26:53 -060011PHOSPHOR_LOG2_USING;
12
Ravi Tejace1c96f2020-10-05 23:13:01 -050013namespace pldm
14{
15namespace responder
16{
17namespace utils
18{
Ravi Tejace1c96f2020-10-05 23:13:01 -050019int setupUnixSocket(const std::string& socketInterface)
20{
21 int sock;
22 struct sockaddr_un addr;
23 memset(&addr, 0, sizeof(addr));
24 addr.sun_family = AF_UNIX;
25 if (strnlen(socketInterface.c_str(), sizeof(addr.sun_path)) ==
26 sizeof(addr.sun_path))
27 {
Riya Dixit49cfb132023-03-02 04:26:53 -060028 error("setupUnixSocket: UNIX socket path too long");
Ravi Tejace1c96f2020-10-05 23:13:01 -050029 return -1;
30 }
31
32 strncpy(addr.sun_path, socketInterface.c_str(), sizeof(addr.sun_path) - 1);
33
34 if ((sock = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
35 {
Riya Dixit49cfb132023-03-02 04:26:53 -060036 error("setupUnixSocket: socket() call failed");
Ravi Tejace1c96f2020-10-05 23:13:01 -050037 return -1;
38 }
39
40 if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
41 {
Riya Dixit49cfb132023-03-02 04:26:53 -060042 error("setupUnixSocket: bind() call failed with errno {ERR}", "ERR",
43 errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050044 close(sock);
45 return -1;
46 }
47
48 if (listen(sock, 1) == -1)
49 {
Riya Dixit49cfb132023-03-02 04:26:53 -060050 error("setupUnixSocket: listen() call failed");
Ravi Tejace1c96f2020-10-05 23:13:01 -050051 close(sock);
52 return -1;
53 }
54
55 fd_set rfd;
56 struct timeval tv;
57 tv.tv_sec = 1;
58 tv.tv_usec = 0;
59
60 FD_ZERO(&rfd);
61 FD_SET(sock, &rfd);
62 int nfd = sock + 1;
Andrew Geisslerefbb5942020-12-15 10:12:30 -060063 int fd = -1;
Ravi Tejace1c96f2020-10-05 23:13:01 -050064
65 int retval = select(nfd, &rfd, NULL, NULL, &tv);
66 if (retval < 0)
67 {
Riya Dixit49cfb132023-03-02 04:26:53 -060068 error("setupUnixSocket: select call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050069 close(sock);
70 return -1;
71 }
72
73 if ((retval > 0) && (FD_ISSET(sock, &rfd)))
74 {
75 fd = accept(sock, NULL, NULL);
76 if (fd < 0)
77 {
Riya Dixit49cfb132023-03-02 04:26:53 -060078 error("setupUnixSocket: accept() call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -050079 close(sock);
80 return -1;
81 }
82 close(sock);
83 }
84 return fd;
85}
86
87int writeToUnixSocket(const int sock, const char* buf, const uint64_t blockSize)
88{
89 uint64_t i;
90 int nwrite = 0;
91
92 for (i = 0; i < blockSize; i = i + nwrite)
93 {
Ravi Tejace1c96f2020-10-05 23:13:01 -050094 fd_set wfd;
95 struct timeval tv;
96 tv.tv_sec = 1;
97 tv.tv_usec = 0;
98
99 FD_ZERO(&wfd);
100 FD_SET(sock, &wfd);
101 int nfd = sock + 1;
102
103 int retval = select(nfd, NULL, &wfd, NULL, &tv);
104 if (retval < 0)
105 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600106 error("writeToUnixSocket: select call failed {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500107 close(sock);
108 return -1;
109 }
110 if (retval == 0)
111 {
112 nwrite = 0;
113 continue;
114 }
115 if ((retval > 0) && (FD_ISSET(sock, &wfd)))
116 {
117 nwrite = write(sock, buf + i, blockSize - i);
118 if (nwrite < 0)
119 {
120 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
121 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600122 error(
123 "writeToUnixSocket: Write call failed with EAGAIN or EWOULDBLOCK or EINTR");
Ravi Tejace1c96f2020-10-05 23:13:01 -0500124 nwrite = 0;
125 continue;
126 }
Riya Dixit49cfb132023-03-02 04:26:53 -0600127 error("writeToUnixSocket: Failed to write {ERR}", "ERR", errno);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500128 close(sock);
129 return -1;
130 }
131 }
132 else
133 {
134 nwrite = 0;
135 }
136 }
137 return 0;
138}
139
Ravi Tejace1c96f2020-10-05 23:13:01 -0500140} // namespace utils
141} // namespace responder
142} // namespace pldm