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 "socket.h"
17
18#include <cerrno>
19#include <cstdint>
20#include <sys/socket.h>
21#include <sys/uio.h>
22#include <unistd.h>
23
24namespace OHOS {
25namespace HiviewDFX {
26Socket::Socket(int socketType) : socketType(socketType) {}
27
28void Socket::SetType(uint32_t socketOption)
29{
30    socketType = socketOption;
31}
32
33void Socket::SetCredential(struct ucred& cred)
34{
35    socketCred = cred;
36}
37
38uid_t Socket::GetUid()
39{
40    return socketCred.uid;
41}
42
43pid_t Socket::GetPid()
44{
45    return socketCred.pid;
46}
47
48int Socket::GenerateFD()
49{
50    int tmpFd = TEMP_FAILURE_RETRY(socket(AF_UNIX, socketType, 0));
51    int res = tmpFd;
52    if (tmpFd == 0) {
53        res = TEMP_FAILURE_RETRY(socket(AF_UNIX, socketType, 0));
54        close(tmpFd);
55    }
56    return res;
57}
58
59int Socket::Create()
60{
61    if (socketHandler != 0) {
62        return socketHandler;
63    }
64
65    int fd = TEMP_FAILURE_RETRY(socket(AF_UNIX, socketType, 0));
66    if (fd < 0) {
67#ifdef DEBUG
68        std::cout << "Create socket failed: " <<  fd << std::endl;
69#endif
70        return fd;
71    }
72
73    socketHandler = fd;
74    return socketHandler;
75}
76
77int Socket::Poll()
78{
79    return -1;
80}
81
82int Socket::Write(const char *data, unsigned int len)
83{
84    if (data == nullptr) {
85        return -1;
86    }
87
88    return TEMP_FAILURE_RETRY(write(socketHandler, data, len));
89}
90
91int Socket::WriteAll(const char *data, unsigned int len)
92{
93    const char *ptr = data;
94    int sizeLeft = static_cast<int>(len);
95    int midRes = 0;
96
97    if (data == nullptr) {
98        return -1;
99    }
100
101    while (sizeLeft > 0) {
102        midRes = Write(ptr, sizeLeft);
103        if (midRes < 0) {
104            break;
105        }
106        sizeLeft -= midRes;
107        ptr += midRes;
108    }
109
110    return (midRes < 0) ? midRes : static_cast<int>(len);
111}
112
113
114int Socket::WriteV(const iovec *vec, unsigned int len)
115{
116    return TEMP_FAILURE_RETRY(writev(socketHandler, vec, len));
117}
118
119int Socket::Read(char *buffer, unsigned int len)
120{
121    return TEMP_FAILURE_RETRY(read(socketHandler, buffer, len));
122}
123
124int Socket::Recv(void *buffer, unsigned int bufferLen, int flags)
125{
126    return TEMP_FAILURE_RETRY(recv(socketHandler, buffer, bufferLen, flags));
127}
128
129bool Socket::SetHandler(int handler)
130{
131    if (socketHandler > 0) {
132        return false;
133    }
134    socketHandler = handler;
135    return true;
136}
137
138bool Socket::CloseHandler()
139{
140    if (socketHandler > 0) {
141        close(socketHandler);
142        socketHandler = -1;
143        return true;
144    }
145    return false;
146}
147
148Socket::~Socket()
149{
150    close(socketHandler);
151    socketHandler = -1;
152}
153} // namespace HiviewDFX
154} // namespace OHOS
155