• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
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 
16 #include "appspawn_socket.h"
17 
18 #include <sys/socket.h>
19 #include <cerrno>
20 
21 #include "appspawn_server.h"
22 #include "pubdef.h"
23 #include "securec.h"
24 
25 namespace OHOS {
26 namespace AppSpawn {
AppSpawnSocket(const std::string & name)27 AppSpawnSocket::AppSpawnSocket(const std::string &name)
28 {
29     socketName_ = name;
30 }
31 
~AppSpawnSocket()32 AppSpawnSocket::~AppSpawnSocket()
33 {
34     if (socketFd_ > 0) {
35         CloseSocket(socketFd_);
36         socketFd_ = -1;
37     }
38 }
39 
GetSocketFd() const40 int AppSpawnSocket::GetSocketFd() const
41 {
42     return socketFd_;
43 }
44 
PackSocketAddr()45 int AppSpawnSocket::PackSocketAddr()
46 {
47     APPSPAWN_CHECK(!socketName_.empty(), return -EINVAL, "Invalid socket name: empty");
48 
49     APPSPAWN_CHECK(memset_s(&socketAddr_, sizeof(socketAddr_), 0, sizeof(socketAddr_)) == EOK,
50         return -1, "Failed to memset socket addr");
51 
52     socklen_t pathLen = 0;
53     if (socketName_[0] == '/') {
54         pathLen = socketName_.length();
55     } else {
56         pathLen = socketDir_.length() + socketName_.length();
57     }
58     socklen_t pathSize = sizeof(socketAddr_.sun_path);
59     if (pathLen >= pathSize) {
60         APPSPAWN_LOGE("Invalid socket name: '%s' too long", socketName_.c_str());
61         return -1;
62     }
63 
64     int len = 0;
65     if (socketName_[0] == '/') {
66         len = snprintf_s(socketAddr_.sun_path, pathSize, (pathSize - 1), "%s", socketName_.c_str());
67     } else {
68         len = snprintf_s(socketAddr_.sun_path, pathSize, (pathSize - 1), "%s%s",
69             socketDir_.c_str(), socketName_.c_str());
70     }
71     APPSPAWN_CHECK(static_cast<int>(pathLen) == len, return -1, "Failed to copy socket path");
72 
73     socketAddr_.sun_family = AF_LOCAL;
74     socketAddrLen_ = offsetof(struct sockaddr_un, sun_path) + pathLen + 1;
75 
76     return 0;
77 }
78 
CreateSocket()79 int AppSpawnSocket::CreateSocket()
80 {
81     int socketFd = socket(AF_UNIX, SOCK_STREAM, 0); // SOCK_SEQPACKET
82     APPSPAWN_CHECK(socketFd >= 0, return -errno, "Failed to create socket: %d", errno);
83 
84     APPSPAWN_LOGV("Created socket with fd %d", socketFd);
85     return socketFd;
86 }
87 
CloseSocket(int & socketFd)88 void AppSpawnSocket::CloseSocket(int &socketFd)
89 {
90     if (socketFd >= 0) {
91         APPSPAWN_LOGV("Closed socket with fd %d", socketFd);
92         close(socketFd);
93         socketFd = -1;
94     }
95 }
96 
ReadSocketMessage(int socketFd,void * buf,int len)97 int AppSpawnSocket::ReadSocketMessage(int socketFd, void *buf, int len)
98 {
99     if (socketFd < 0 || len <= 0 || buf == nullptr) {
100         APPSPAWN_LOGE("Invalid args: socket %d, len %d, buf might be nullptr", socketFd, len);
101         return -1;
102     }
103 
104     APPSPAWN_CHECK(memset_s(buf, len, 0, len) == EOK, return -1, "Failed to memset read buf");
105 
106     ssize_t rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len));
107     while ((rLen < 0) && (errno == EAGAIN)) {
108         rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len));
109     }
110     APPSPAWN_CHECK(rLen >= 0, return -EFAULT, "Read message from fd %d error %zd: %d",
111         socketFd, rLen, errno);
112 
113     return rLen;
114 }
115 
WriteSocketMessage(int socketFd,const void * buf,int len)116 int AppSpawnSocket::WriteSocketMessage(int socketFd, const void *buf, int len)
117 {
118     if (socketFd < 0 || len <= 0 || buf == nullptr) {
119         APPSPAWN_LOGE("Invalid args: socket %d, len %d, buf might be nullptr", socketFd, len);
120         return -1;
121     }
122 
123     ssize_t written = 0;
124     ssize_t remain = static_cast<ssize_t>(len);
125     const uint8_t *offset = reinterpret_cast<const uint8_t *>(buf);
126     for (ssize_t wLen = 0; remain > 0; offset += wLen, remain -= wLen, written += wLen) {
127         wLen = write(socketFd, offset, remain);
128         APPSPAWN_LOGV("socket fd %d, wLen %zd", socketFd, wLen);
129         bool isRet = (wLen <= 0) && (errno != EINTR);
130         APPSPAWN_CHECK(!isRet, return -errno, "Failed to write message to fd %d, error %zd: %d",
131             socketFd, wLen, errno);
132     }
133 
134     return written;
135 }
136 }  // namespace AppSpawn
137 }  // namespace OHOS
138