gecko/security/sandbox/linux/SandboxLogging.cpp
Jed Davis 8c643f1407 Bug 1181704 - Use chromium SafeSPrintf for sandbox logging. r=gdestuynder r=glandium
This gives us a logging macro that's safe to use in async signal context
(cf. bug 1046210, where we needed this and didn't have it).

This patch also changes one of the format strings to work with
SafeSPrintf's format string dialect; upstream would probably take a
patch to handle those letters, but this is easier.
2015-07-09 12:09:00 +02:00

64 lines
1.7 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SandboxLogging.h"
#ifdef ANDROID
#include <android/log.h>
#else
#include <algorithm>
#include <stdio.h>
#include <sys/uio.h>
#include <unistd.h>
#endif
#include "base/posix/eintr_wrapper.h"
namespace mozilla {
#ifndef ANDROID
// Alters an iovec array to remove the first `toDrop` bytes. This
// complexity is necessary because writev can return a short write
// (e.g., if stderr is a pipe and the buffer is almost full).
static void
IOVecDrop(struct iovec* iov, int iovcnt, size_t toDrop)
{
while (toDrop > 0 && iovcnt > 0) {
size_t toDropHere = std::min(toDrop, iov->iov_len);
iov->iov_base = static_cast<char*>(iov->iov_base) + toDropHere;
iov->iov_len -= toDropHere;
toDrop -= toDropHere;
++iov;
--iovcnt;
}
}
#endif
void
SandboxLogError(const char* message)
{
#ifdef ANDROID
// This uses writev internally and appears to be async signal safe.
__android_log_write(ANDROID_LOG_ERROR, "Sandbox", message);
#else
static const char logPrefix[] = "Sandbox: ", logSuffix[] = "\n";
struct iovec iovs[3] = {
{ const_cast<char*>(logPrefix), sizeof(logPrefix) - 1 },
{ const_cast<char*>(message), strlen(message) },
{ const_cast<char*>(logSuffix), sizeof(logSuffix) - 1 },
};
while (iovs[2].iov_len > 0) {
ssize_t written = HANDLE_EINTR(writev(STDERR_FILENO, iovs, 3));
if (written <= 0) {
break;
}
IOVecDrop(iovs, 3, static_cast<size_t>(written));
}
#endif
}
}