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 #include <cerrno>
16 #include <functional>
17 #include <iosfwd>
18 #include <iostream>
19 #include <memory>
20 #include <ostream>
21 #include <type_traits>
22 #include <sys/socket.h>
23 #include <poll.h>
24
25 #include "log_utils.h"
26 #include "socket.h"
27 #include "seq_packet_socket_server.h"
28
29 namespace OHOS {
30 namespace HiviewDFX {
StartAcceptingConnection(AcceptingHandler onAccepted,milliseconds ms,TimtoutHandler timeOutFunc)31 int SeqPacketSocketServer::StartAcceptingConnection(AcceptingHandler onAccepted,
32 milliseconds ms, TimtoutHandler timeOutFunc)
33 {
34 int listeningStatus = Listen(maxListenNumber);
35 if (listeningStatus < 0) {
36 std::cerr << "Socket listen failed: ";
37 PrintErrorno(listeningStatus);
38 return listeningStatus;
39 }
40 return AcceptingLoop(onAccepted, ms, timeOutFunc);
41 }
42
AcceptingLoop(AcceptingHandler func,milliseconds ms,TimtoutHandler timeOutFunc)43 int SeqPacketSocketServer::AcceptingLoop(AcceptingHandler func, milliseconds ms, TimtoutHandler timeOutFunc)
44 {
45 for (;;) {
46 short outEvent = 0;
47 auto pollResult = Poll(POLLIN, outEvent, ms);
48 if (pollResult == 0) { // poll == 0 means timeout
49 timeOutFunc();
50 continue;
51 } else if (pollResult < 0) {
52 std::cerr << "Socket polling error: ";
53 PrintErrorno(errno);
54 break;
55 } else if (pollResult != 1 || outEvent != POLLIN) {
56 std::cerr << "Wrong poll result data. Result: " << pollResult << " OutEvent: " << outEvent << "\n";
57 break;
58 }
59
60 int acceptResult = Accept();
61 if (acceptResult > 0) {
62 struct ucred cred = { 0 };
63 socklen_t len = sizeof(struct ucred);
64 (void)getsockopt(acceptResult, SOL_SOCKET, SO_PEERCRED, &cred, &len);
65 std::cout << "Ucred: pid:" << cred.pid << ", uid: " << cred.uid << ", gid: " << cred.gid << std::endl;
66 std::unique_ptr<Socket> handler = std::make_unique<Socket>(SOCK_SEQPACKET);
67 if (handler != nullptr) {
68 handler->SetHandler(acceptResult);
69 handler->SetCredential(cred);
70 func(std::move(handler));
71 }
72 } else {
73 std::cerr << "Socket accept failed: ";
74 PrintErrorno(errno);
75 break;
76 }
77 }
78 int acceptError = errno;
79 return acceptError;
80 }
81 } // namespace HiviewDFX
82 } // namespace OHOS
83