blob: 81a9c888ada988fbd9cdc2396d99a01d4f53c6f0 [file] [log] [blame]
// Copyright 2014 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 "chromeos/ui/util.h"
#include <fcntl.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <vector>
#include <base/check.h>
#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/process/launch.h>
namespace chromeos {
namespace ui {
namespace util {
base::FilePath GetReparentedPath(const std::string& path,
const base::FilePath& parent) {
if (parent.empty())
return base::FilePath(path);
CHECK(!path.empty() && path[0] == '/');
base::FilePath relative_path(path.substr(1));
CHECK(!relative_path.IsAbsolute());
return parent.Append(relative_path);
}
bool SetPermissions(const base::FilePath& path,
uid_t uid,
gid_t gid,
mode_t mode) {
base::ScopedFD fd(
open(path.value().c_str(), O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC));
if (!fd.is_valid()) {
PLOG(ERROR) << "Couldn't open " << path.value();
return false;
}
if (getuid() == 0) {
if (fchown(fd.get(), uid, gid) != 0) {
PLOG(ERROR) << "Couldn't chown " << path.value() << " to " << uid << ":"
<< gid;
return false;
}
}
if (fchmod(fd.get(), mode) != 0) {
PLOG(ERROR) << "Unable to chmod " << path.value() << " to " << std::oct
<< mode;
return false;
}
return true;
}
bool EnsureDirectoryExists(const base::FilePath& path,
uid_t uid,
gid_t gid,
mode_t mode) {
if (!base::DirectoryExists(path)) {
// Remove the existing file or link if any.
if (!base::DeleteFile(path)) {
PLOG(ERROR) << "Unable to delete " << path.value();
return false;
}
if (!base::CreateDirectory(path)) {
PLOG(ERROR) << "Unable to create " << path.value();
return false;
}
}
return SetPermissions(path, uid, gid, mode);
}
bool Run(const char* command, const char* arg, ...) {
// Extra parentheses because yay C++ most vexing parse.
base::CommandLine cl((base::FilePath(command)));
va_list list;
va_start(list, arg);
while (arg) {
cl.AppendArg(const_cast<char*>(arg));
arg = va_arg(list, char*);
}
va_end(list);
std::string output;
int exit_code = 0;
if (!base::GetAppOutputWithExitCode(cl, &output, &exit_code)) {
LOG(WARNING) << "\"" << cl.GetCommandLineString() << "\" failed with "
<< exit_code << ": " << output;
return false;
}
return true;
}
} // namespace util
} // namespace ui
} // namespace chromeos