| /* |
| * Copyright 2017 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include <fcntl.h> |
| #include <sys/resource.h> |
| #include <sys/socket.h> |
| #include <sys/wait.h> |
| |
| #include <base/at_exit.h> |
| #include <base/command_line.h> |
| #include <base/files/file_path.h> |
| #include <base/files/file_util.h> |
| #include <base/files/scoped_file.h> |
| #include <base/logging.h> |
| #include <mojo/edk/embedder/platform_channel_utils_posix.h> |
| |
| #include "common/camera_algorithm_adapter.h" |
| #include "cros-camera/common.h" |
| #include "cros-camera/constants.h" |
| #include "cros-camera/ipc_util.h" |
| |
| int main(int argc, char** argv) { |
| static base::AtExitManager exit_manager; |
| int kCameraProcessPriority = -20; |
| |
| // Set up logging so we can enable VLOGs with -v / --vmodule. |
| base::CommandLine::Init(argc, argv); |
| logging::LoggingSettings settings; |
| settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; |
| LOG_ASSERT(logging::InitLogging(settings)); |
| |
| int ret = setpriority(PRIO_PROCESS, 0, kCameraProcessPriority); |
| if (ret) { |
| LOGF(WARNING) << "Failed to set process priority"; |
| } |
| |
| base::FilePath socket_path(cros::constants::kCrosCameraAlgoSocketPathString); |
| // Creat unix socket to receive the adapter token and connection handle |
| int fd = -1; |
| if (!cros::CreateServerUnixDomainSocket(socket_path, &fd)) { |
| LOGF(ERROR) << "CreateSreverUnixDomainSocket failed"; |
| return EXIT_FAILURE; |
| } |
| base::ScopedFD socket_fd(fd); |
| int flags = HANDLE_EINTR(fcntl(socket_fd.get(), F_GETFL)); |
| if (flags == -1) { |
| PLOGF(ERROR) << "fcntl(F_GETFL) : " << strerror(errno); |
| return EXIT_FAILURE; |
| } |
| if (HANDLE_EINTR(fcntl(socket_fd.get(), F_SETFL, flags & ~O_NONBLOCK)) == |
| -1) { |
| PLOGF(ERROR) << "fcntl(F_SETFL) failed to disable O_NONBLOCK"; |
| return EXIT_FAILURE; |
| } |
| |
| VLOGF(1) << "Waiting for incoming connection for " << socket_path.value(); |
| base::ScopedFD connection_fd(accept(socket_fd.get(), NULL, 0)); |
| if (!connection_fd.is_valid()) { |
| LOGF(ERROR) << "Failed to accept client connect request"; |
| return EXIT_FAILURE; |
| } |
| const size_t kTokenLength = 33; |
| char recv_buf[kTokenLength] = {0}; |
| std::deque<mojo::edk::PlatformHandle> platform_handles; |
| if (PlatformChannelRecvmsg(mojo::edk::PlatformHandle(connection_fd.get()), |
| recv_buf, sizeof(recv_buf), &platform_handles, |
| true) == 0) { |
| LOGF(ERROR) << "Failed to receive message"; |
| return EXIT_FAILURE; |
| } |
| if (platform_handles.size() != 1 || !platform_handles.front().is_valid()) { |
| LOGF(ERROR) << "Received connection handle is invalid"; |
| return EXIT_FAILURE; |
| } |
| |
| VLOGF(1) << "Message from client " << std::string(recv_buf); |
| int pid = fork(); |
| if (pid == 0) { |
| cros::CameraAlgorithmAdapter adapter; |
| adapter.Run(std::string(recv_buf), |
| mojo::edk::ScopedPlatformHandle(platform_handles.front())); |
| exit(0); |
| } else if (pid > 0) { |
| wait(NULL); |
| } else { |
| LOGF(ERROR) << "Fork failed"; |
| } |
| |
| return 0; |
| } |