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