blob: 7858cbe9d14ee4cde85636a4c1f911cfa57d9dfd [file] [log] [blame]
// Copyright (c) 2012 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 "posix_translation/dev_urandom.h"
#include <string.h>
#include "posix_translation/dir.h"
#include "posix_translation/virtual_file_system.h"
namespace posix_translation {
namespace {
int DoStatLocked(const std::string& pathname, struct stat* out) {
memset(out, 0, sizeof(struct stat));
out->st_ino =
VirtualFileSystem::GetVirtualFileSystem()->GetInodeLocked(pathname);
out->st_mode = S_IFCHR | 0666;
out->st_nlink = 1;
out->st_blksize = 4096;
// st_uid, st_gid, st_size, st_blocks should be zero.
// TODO(crbug.com/242337): Fill st_dev if needed.
out->st_rdev = DeviceHandler::GetDeviceId(pathname);
return 0;
}
} // namespace
DevUrandomHandler::DevUrandomHandler()
: DeviceHandler("DevUrandomHandler") {
}
DevUrandomHandler::~DevUrandomHandler() {
}
scoped_refptr<FileStream> DevUrandomHandler::open(
int fd, const std::string& pathname, int oflag, mode_t cmode) {
if (oflag & O_DIRECTORY) {
errno = ENOTDIR;
return NULL;
}
return new DevUrandom(pathname, oflag);
}
int DevUrandomHandler::stat(const std::string& pathname, struct stat* out) {
return DoStatLocked(pathname, out);
}
//------------------------------------------------------------------------------
DevUrandom::DevUrandom(const std::string& pathname, int oflag)
: DeviceStream(oflag, pathname) {
nacl_interface_query(NACL_IRT_RANDOM_v0_1, &random_, sizeof(random_));
}
DevUrandom::~DevUrandom() {
}
int DevUrandom::fstat(struct stat* out) {
return DoStatLocked(pathname(), out);
}
ssize_t DevUrandom::read(void* buf, size_t count) {
size_t nread = 0;
if (!GetRandomBytes(buf, count, &nread)) {
errno = EIO;
return -1;
}
return nread;
}
ssize_t DevUrandom::write(const void* buf, size_t count) {
errno = EPERM;
return -1;
}
bool DevUrandom::GetRandomBytes(void* buf, size_t count, size_t* nread) {
return random_.get_random_bytes(
reinterpret_cast<unsigned char*>(buf), count, nread) == 0;
}
const char* DevUrandom::GetStreamType() const {
return "dev_urandom";
}
} // namespace posix_translation