if (!Prepare()) return;
- try {
- sigchld_channel_.reset(new IOChannel(sigchld_socket_->GetFd(),
- IOChannel::IOCondition::IO_IN, this));
- } catch (const Exception& e) {
- _E("Exception occurs. error=%s", e.what());
- return;
- }
-
disposed_ = false;
}
if (disposed_) return;
Kill();
- sigchld_channel_.reset();
- sigchld_socket_.reset();
- read_socket_.reset();
- write_socket_.reset();
+ IgnoreEvents();
+ ClosePipeFds();
disposed_ = true;
}
-bool LuxManager::Prepare() {
- if (pid_ > 0) return false;
+bool LuxManager::PreparePipeFds() {
+ read_fd_ = -1;
+ write_fd_ = -1;
+ sigchld_fd_ = -1;
+ label_monitor_fd_ = -1;
int pipe_fd[2];
if (CreatePipe(&pipe_fd) != 0) return false;
read_socket_.reset(new Socket(pipe_fd[0]));
- int write_fd = pipe_fd[1];
+ write_fd_ = pipe_fd[1];
if (CreatePipe(&pipe_fd) != 0) {
- close(write_fd);
+ ClosePipeFds();
return false;
}
- int read_fd = pipe_fd[0];
+ read_fd_ = pipe_fd[0];
write_socket_.reset(new Socket(pipe_fd[1]));
if (CreatePipe(&pipe_fd) != 0) {
- close(read_fd);
- close(write_fd);
+ ClosePipeFds();
return false;
}
- int sigchld_fd = pipe_fd[0];
+ sigchld_fd_ = pipe_fd[0];
sigchld_socket_.reset(new Socket(pipe_fd[1]));
- _W("read_socket=%d, write_socket=%d, sigchld_socket=%d",
- read_socket_->GetFd(), write_socket_->GetFd(), sigchld_socket_->GetFd());
+ if (CreatePipe(&pipe_fd) != 0) {
+ ClosePipeFds();
+ return false;
+ }
+
+ label_monitor_fd_ = pipe_fd[0];
+ label_monitor_socket_.reset(new Socket(pipe_fd[1]));
+ return true;
+}
+
+void LuxManager::ClosePipeFds() {
+ if (label_monitor_fd_ > -1) {
+ close(label_monitor_fd_);
+ label_monitor_fd_ = -1;
+ }
+
+ if (sigchld_fd_ > -1) {
+ close(sigchld_fd_);
+ sigchld_fd_ = -1;
+ }
+
+ if (read_fd_ > -1) {
+ close(read_fd_);
+ read_fd_ = -1;
+ }
+
+ if (write_fd_ > -1) {
+ close(write_fd_);
+ write_fd_ = -1;
+ }
+
+ label_monitor_socket_.reset();
+ sigchld_socket_.reset();
+ read_socket_.reset();
+ write_socket_.reset();
+}
+
+bool LuxManager::ListenEvents() {
+ try {
+ sigchld_channel_.reset(new IOChannel(sigchld_socket_->GetFd(),
+ IOChannel::IOCondition::IO_IN, this));
+ label_monitor_channel_.reset(new IOChannel(
+ label_monitor_socket_->GetFd(), IOChannel::IOCondition::IO_IN, this));
+ } catch (const Exception& e) {
+ _E("Exception occurs. error=%s", e.what());
+ return false;
+ }
+
+ return true;
+}
+
+void LuxManager::IgnoreEvents() {
+ sigchld_channel_.reset();
+ label_monitor_channel_.reset();
+}
+
+bool LuxManager::Prepare() {
+ if (pid_ > 0) return false;
+
+ if (!PreparePipeFds()) return false;
+
+ _W("read_socket=%d, write_socket=%d, sigchld_socket=%d, "
+ "label_monitor_socket=%d",
+ read_socket_->GetFd(), write_socket_->GetFd(), sigchld_socket_->GetFd(),
+ label_monitor_socket_->GetFd());
pid_ = Executor::Execute();
if (pid_ < 0) {
_E("Failed to execute lux. errno(%d)", errno);
- close(sigchld_fd);
- close(read_fd);
- close(write_fd);
+ ClosePipeFds();
return false;
}
_W("Lux process=%d", pid_);
- sigchld_socket_.reset(new Socket(sigchld_fd));
- read_socket_.reset(new Socket(read_fd));
- write_socket_.reset(new Socket(write_fd));
- return true;
+ label_monitor_socket_.reset(new Socket(label_monitor_fd_));
+ label_monitor_fd_ = -1;
+ sigchld_socket_.reset(new Socket(sigchld_fd_));
+ sigchld_fd_ = -1;
+ read_socket_.reset(new Socket(read_fd_));
+ read_fd_ = -1;
+ write_socket_.reset(new Socket(write_fd_));
+ write_fd_ = -1;
+ return ListenEvents();
}
bool LuxManager::IsPrepared() const {
void LuxManager::HandleSigchld(pid_t pid) {
if (pid_ != pid) return;
- sigchld_channel_.reset();
- sigchld_socket_.reset();
- read_socket_.reset();
- write_socket_.reset();
+ IgnoreEvents();
+ ClosePipeFds();
pid_ = -1;
Prepare();
}
pid_ = -1;
}
-void LuxManager::OnIOEventReceived(int fd, int condition) {
- _D("fd=%d, condition=%d", fd, condition);
+
+void LuxManager::HandleSigChldEvent() {
size_t data_size = 0;
int ret =
sigchld_socket_->Read(static_cast<void*>(&data_size), sizeof(data_size));
if (listener_) listener_->OnLuxSigchld(pid, status);
}
+void LuxManager::HandleAppLabelsChangedEvent() {
+ size_t data_size = 0;
+ int ret = label_monitor_socket_->Read(static_cast<void*>(&data_size),
+ sizeof(data_size));
+ if (ret != 0) {
+ _E("Failed to receive the data. error=%d", ret);
+ return;
+ }
+
+ std::vector<uint8_t> data(data_size);
+ ret = label_monitor_socket_->Read(data.data(), data_size);
+ if (ret != 0) {
+ _E("Failed to receive the data. error=%d", ret);
+ return;
+ }
+
+ tizen_base::Parcel parcel(data.data(), data.size());
+ parcel.ReadInt32(&ret);
+ _W("[AppLabelsChanged] ret=%d", ret);
+ if (listener_) listener_->OnLuxAppLabelsChanged();
+}
+
+void LuxManager::OnIOEventReceived(int fd, int condition) {
+ _D("fd=%d, condition=%d", fd, condition);
+ if (fd == sigchld_socket_->GetFd()) HandleSigChldEvent();
+ else if (fd == label_monitor_socket_->GetFd()) HandleAppLabelsChangedEvent();
+}
+
void LuxManager::OnExecution() {
CPUBoostController::DoBoost(getpid(), CPUBoostController::Level::Strong, -1,
true);
std::vector<int> except_fds{read_socket_->GetFd(), write_socket_->GetFd(),
- sigchld_socket_->GetFd()};
+ sigchld_socket_->GetFd(),
+ label_monitor_socket_->GetFd()};
Util::CloseAllFds(except_fds);
std::string rfd = std::to_string(read_socket_->RemoveFd());
std::string wfd = std::to_string(write_socket_->RemoveFd());
std::string sfd = std::to_string(sigchld_socket_->RemoveFd());
+ std::string lfd = std::to_string(label_monitor_socket_->RemoveFd());
setenv("LUX_READ_FD", rfd.c_str(), 1);
setenv("LUX_WRITE_FD", wfd.c_str(), 1);
setenv("LUX_SIGCHLD_FD", sfd.c_str(), 1);
+ setenv("LUX_LABEL_MONITOR_FD", lfd.c_str(), 1);
std::vector<char*> args;
args.push_back(const_cast<char*>(kPathLux));
pub struct AppLabelsMonitor {
handle: *mut c_void,
source_id: c_uint,
+ write_fd: i32,
disposed: bool,
}
data: *mut c_void,
) -> glib_sys::gboolean {
unsafe {
+ debug!("BEGIN");
let handle: &mut AppLabelsMonitor = &mut *(data as *mut AppLabelsMonitor);
handle.process();
+ debug!("END");
G_SOURCE_CONTINUE
}
}
impl AppLabelsMonitor {
pub fn new() -> Self {
- AppLabelsMonitor { handle: ptr::null_mut(), source_id: 0, disposed: true }
+ AppLabelsMonitor { handle: ptr::null_mut(), source_id: 0, write_fd: -1, disposed: true }
}
- pub fn init(&mut self) -> Result<(), ()> {
+ pub fn init(&mut self, write_fd: i32) -> Result<(), ()> {
if !self.disposed {
return Ok(());
}
+ self.write_fd = write_fd;
let mut fd: i32 = -1;
let ret = unsafe { security_manager_app_labels_monitor_init(&mut self.handle) };
if ret != SECURITY_MANAGER_SUCCESS {
self.handle = ptr::null_mut();
}
}
+
+ if self.write_fd > -1 {
+ unsafe {
+ close(self.write_fd);
+ self.write_fd = -1;
+ }
+ }
+
self.disposed = true;
}
fn process(&mut self) {
- unsafe { security_manager_app_labels_monitor_process(self.handle) };
+ let ret = unsafe { security_manager_app_labels_monitor_process(self.handle) };
+ let mut parcel = Parcel::new();
+ parcel.write_i32(ret as i32);
+ self.write_parcel(&mut parcel);
+ }
+
+ fn write_parcel(&mut self, parcel: &mut Parcel) -> Result<(), ()> {
+ let mut data = parcel.get_raw_data().unwrap();
+ let mut data_size: c_ulong = (data.len() as usize).try_into().unwrap();
+ let nbytes = unsafe {
+ write(
+ self.write_fd,
+ (&mut data_size as *mut c_ulong).cast::<u8>() as *mut c_void,
+ mem::size_of::<c_ulong>(),
+ )
+ };
+ if nbytes < 0 {
+ error!("Failed to write data size");
+ return Err(());
+ }
+
+ let nbytes = unsafe { write(self.write_fd, data.as_mut_ptr() as *mut _, data.len()) };
+ if nbytes < 0 {
+ error!("Failed to write data");
+ return Err(());
+ }
+
+ Ok(())
}
}