Sim-only files move, part 2/2.
Move Pipe and executablepath from libutils to the simulator, since nothing else uses them.
This commit is contained in:
parent
d0ef3d46f9
commit
69197b6020
|
@ -55,7 +55,6 @@ commonSources:= \
|
|||
#
|
||||
hostSources:= \
|
||||
InetAddress.cpp \
|
||||
Pipe.cpp \
|
||||
Socket.cpp \
|
||||
ZipEntry.cpp \
|
||||
ZipFile.cpp
|
||||
|
@ -71,12 +70,7 @@ ifeq ($(HOST_OS),linux)
|
|||
# Use the futex based mutex and condition variable
|
||||
# implementation from android-arm because it's shared mem safe
|
||||
LOCAL_SRC_FILES += \
|
||||
futex_synchro.c \
|
||||
executablepath_linux.cpp
|
||||
endif
|
||||
ifeq ($(HOST_OS),darwin)
|
||||
LOCAL_SRC_FILES += \
|
||||
executablepath_darwin.cpp
|
||||
futex_synchro.c
|
||||
endif
|
||||
|
||||
LOCAL_MODULE:= libutils
|
||||
|
|
|
@ -1,465 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Unidirectional pipe.
|
||||
//
|
||||
|
||||
#include <utils/Pipe.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace android;
|
||||
|
||||
const unsigned long kInvalidHandle = (unsigned long) -1;
|
||||
|
||||
|
||||
/*
|
||||
* Constructor. Do little.
|
||||
*/
|
||||
Pipe::Pipe(void)
|
||||
: mReadNonBlocking(false), mReadHandle(kInvalidHandle),
|
||||
mWriteHandle(kInvalidHandle)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Destructor. Use the system-appropriate close call.
|
||||
*/
|
||||
Pipe::~Pipe(void)
|
||||
{
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
if (mReadHandle != kInvalidHandle) {
|
||||
if (!CloseHandle((HANDLE)mReadHandle))
|
||||
LOG(LOG_WARN, "pipe", "failed closing read handle (%ld)\n",
|
||||
mReadHandle);
|
||||
}
|
||||
if (mWriteHandle != kInvalidHandle) {
|
||||
FlushFileBuffers((HANDLE)mWriteHandle);
|
||||
if (!CloseHandle((HANDLE)mWriteHandle))
|
||||
LOG(LOG_WARN, "pipe", "failed closing write handle (%ld)\n",
|
||||
mWriteHandle);
|
||||
}
|
||||
#else
|
||||
if (mReadHandle != kInvalidHandle) {
|
||||
if (close((int) mReadHandle) != 0)
|
||||
LOG(LOG_WARN, "pipe", "failed closing read fd (%d)\n",
|
||||
(int) mReadHandle);
|
||||
}
|
||||
if (mWriteHandle != kInvalidHandle) {
|
||||
if (close((int) mWriteHandle) != 0)
|
||||
LOG(LOG_WARN, "pipe", "failed closing write fd (%d)\n",
|
||||
(int) mWriteHandle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the pipe.
|
||||
*
|
||||
* Use the POSIX stuff for everything but Windows.
|
||||
*/
|
||||
bool Pipe::create(void)
|
||||
{
|
||||
assert(mReadHandle == kInvalidHandle);
|
||||
assert(mWriteHandle == kInvalidHandle);
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
/* we use this across processes, so they need to be inheritable */
|
||||
HANDLE handles[2];
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
if (!CreatePipe(&handles[0], &handles[1], &saAttr, 0)) {
|
||||
LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
|
||||
return false;
|
||||
}
|
||||
mReadHandle = (unsigned long) handles[0];
|
||||
mWriteHandle = (unsigned long) handles[1];
|
||||
return true;
|
||||
#else
|
||||
int fds[2];
|
||||
|
||||
if (pipe(fds) != 0) {
|
||||
LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
|
||||
return false;
|
||||
}
|
||||
mReadHandle = fds[0];
|
||||
mWriteHandle = fds[1];
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a "half pipe". Please, no Segway riding.
|
||||
*/
|
||||
bool Pipe::createReader(unsigned long handle)
|
||||
{
|
||||
mReadHandle = handle;
|
||||
assert(mWriteHandle == kInvalidHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a "half pipe" for writing.
|
||||
*/
|
||||
bool Pipe::createWriter(unsigned long handle)
|
||||
{
|
||||
mWriteHandle = handle;
|
||||
assert(mReadHandle == kInvalidHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return "true" if create() has been called successfully.
|
||||
*/
|
||||
bool Pipe::isCreated(void)
|
||||
{
|
||||
// one or the other should be open
|
||||
return (mReadHandle != kInvalidHandle || mWriteHandle != kInvalidHandle);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read data from the pipe.
|
||||
*
|
||||
* For Linux and Darwin, just call read(). For Windows, implement
|
||||
* non-blocking reads by calling PeekNamedPipe first.
|
||||
*/
|
||||
int Pipe::read(void* buf, int count)
|
||||
{
|
||||
assert(mReadHandle != kInvalidHandle);
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
DWORD totalBytesAvail = count;
|
||||
DWORD bytesRead;
|
||||
|
||||
if (mReadNonBlocking) {
|
||||
// use PeekNamedPipe to adjust read count expectations
|
||||
if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
|
||||
&totalBytesAvail, NULL))
|
||||
{
|
||||
LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (totalBytesAvail == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ReadFile((HANDLE) mReadHandle, buf, totalBytesAvail, &bytesRead,
|
||||
NULL))
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
|
||||
return 0;
|
||||
LOG(LOG_ERROR, "pipe", "ReadFile failed (err=%ld)\n", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) bytesRead;
|
||||
#else
|
||||
int cc;
|
||||
cc = ::read(mReadHandle, buf, count);
|
||||
if (cc < 0 && errno == EAGAIN)
|
||||
return 0;
|
||||
return cc;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to the pipe.
|
||||
*
|
||||
* POSIX systems are trivial, Windows uses a different call and doesn't
|
||||
* handle non-blocking writes.
|
||||
*
|
||||
* If we add non-blocking support here, we probably want to make it an
|
||||
* all-or-nothing write.
|
||||
*
|
||||
* DO NOT use LOG() here, we could be writing a log message.
|
||||
*/
|
||||
int Pipe::write(const void* buf, int count)
|
||||
{
|
||||
assert(mWriteHandle != kInvalidHandle);
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
DWORD bytesWritten;
|
||||
|
||||
if (mWriteNonBlocking) {
|
||||
// BUG: can't use PeekNamedPipe() to get the amount of space
|
||||
// left. Looks like we need to use "overlapped I/O" functions.
|
||||
// I just don't care that much.
|
||||
}
|
||||
|
||||
if (!WriteFile((HANDLE) mWriteHandle, buf, count, &bytesWritten, NULL)) {
|
||||
// can't LOG, use stderr
|
||||
fprintf(stderr, "WriteFile failed (err=%ld)\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) bytesWritten;
|
||||
#else
|
||||
int cc;
|
||||
cc = ::write(mWriteHandle, buf, count);
|
||||
if (cc < 0 && errno == EAGAIN)
|
||||
return 0;
|
||||
return cc;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out if there is data available on the read fd.
|
||||
*
|
||||
* We return "true" on error because we want the caller to try to read
|
||||
* from the pipe. They'll notice the read failure and do something
|
||||
* appropriate.
|
||||
*/
|
||||
bool Pipe::readReady(void)
|
||||
{
|
||||
assert(mReadHandle != kInvalidHandle);
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
DWORD totalBytesAvail;
|
||||
|
||||
if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
|
||||
&totalBytesAvail, NULL))
|
||||
{
|
||||
LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return (totalBytesAvail != 0);
|
||||
#else
|
||||
errno = 0;
|
||||
fd_set readfds;
|
||||
struct timeval tv = { 0, 0 };
|
||||
int cc;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(mReadHandle, &readfds);
|
||||
|
||||
cc = select(mReadHandle+1, &readfds, NULL, NULL, &tv);
|
||||
if (cc < 0) {
|
||||
LOG(LOG_ERROR, "pipe", "select() failed\n");
|
||||
return true;
|
||||
} else if (cc == 0) {
|
||||
/* timed out, nothing available */
|
||||
return false;
|
||||
} else if (cc == 1) {
|
||||
/* our fd is ready */
|
||||
return true;
|
||||
} else {
|
||||
LOG(LOG_ERROR, "pipe", "HUH? select() returned > 1\n");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable or disable non-blocking mode for the read descriptor.
|
||||
*
|
||||
* NOTE: the calls succeed under Mac OS X, but the pipe doesn't appear to
|
||||
* actually be in non-blocking mode. If this matters -- i.e. you're not
|
||||
* using a select() call -- put a call to readReady() in front of the
|
||||
* ::read() call, with a PIPE_NONBLOCK_BROKEN #ifdef in the Makefile for
|
||||
* Darwin.
|
||||
*/
|
||||
bool Pipe::setReadNonBlocking(bool val)
|
||||
{
|
||||
assert(mReadHandle != kInvalidHandle);
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
// nothing to do
|
||||
#else
|
||||
int flags;
|
||||
|
||||
if (fcntl(mReadHandle, F_GETFL, &flags) == -1) {
|
||||
LOG(LOG_ERROR, "pipe", "couldn't get flags for pipe read fd\n");
|
||||
return false;
|
||||
}
|
||||
if (val)
|
||||
flags |= O_NONBLOCK;
|
||||
else
|
||||
flags &= ~(O_NONBLOCK);
|
||||
if (fcntl(mReadHandle, F_SETFL, &flags) == -1) {
|
||||
LOG(LOG_ERROR, "pipe", "couldn't set flags for pipe read fd\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
mReadNonBlocking = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable or disable non-blocking mode for the write descriptor.
|
||||
*
|
||||
* As with setReadNonBlocking(), this does not work on the Mac.
|
||||
*/
|
||||
bool Pipe::setWriteNonBlocking(bool val)
|
||||
{
|
||||
assert(mWriteHandle != kInvalidHandle);
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
// nothing to do
|
||||
#else
|
||||
int flags;
|
||||
|
||||
if (fcntl(mWriteHandle, F_GETFL, &flags) == -1) {
|
||||
LOG(LOG_WARN, "pipe",
|
||||
"Warning: couldn't get flags for pipe write fd (errno=%d)\n",
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
if (val)
|
||||
flags |= O_NONBLOCK;
|
||||
else
|
||||
flags &= ~(O_NONBLOCK);
|
||||
if (fcntl(mWriteHandle, F_SETFL, &flags) == -1) {
|
||||
LOG(LOG_WARN, "pipe",
|
||||
"Warning: couldn't set flags for pipe write fd (errno=%d)\n",
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
mWriteNonBlocking = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify whether a file descriptor can be inherited by a child process.
|
||||
* Under Linux this means setting the close-on-exec flag, under Windows
|
||||
* this is SetHandleInformation(HANDLE_FLAG_INHERIT).
|
||||
*/
|
||||
bool Pipe::disallowReadInherit(void)
|
||||
{
|
||||
if (mReadHandle == kInvalidHandle)
|
||||
return false;
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
if (SetHandleInformation((HANDLE) mReadHandle, HANDLE_FLAG_INHERIT, 0) == 0)
|
||||
return false;
|
||||
#else
|
||||
if (fcntl((int) mReadHandle, F_SETFD, FD_CLOEXEC) != 0)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
bool Pipe::disallowWriteInherit(void)
|
||||
{
|
||||
if (mWriteHandle == kInvalidHandle)
|
||||
return false;
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
if (SetHandleInformation((HANDLE) mWriteHandle, HANDLE_FLAG_INHERIT, 0) == 0)
|
||||
return false;
|
||||
#else
|
||||
if (fcntl((int) mWriteHandle, F_SETFD, FD_CLOEXEC) != 0)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close read descriptor.
|
||||
*/
|
||||
bool Pipe::closeRead(void)
|
||||
{
|
||||
if (mReadHandle == kInvalidHandle)
|
||||
return false;
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
if (mReadHandle != kInvalidHandle) {
|
||||
if (!CloseHandle((HANDLE)mReadHandle)) {
|
||||
LOG(LOG_WARN, "pipe", "failed closing read handle\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (mReadHandle != kInvalidHandle) {
|
||||
if (close((int) mReadHandle) != 0) {
|
||||
LOG(LOG_WARN, "pipe", "failed closing read fd\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mReadHandle = kInvalidHandle;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close write descriptor.
|
||||
*/
|
||||
bool Pipe::closeWrite(void)
|
||||
{
|
||||
if (mWriteHandle == kInvalidHandle)
|
||||
return false;
|
||||
|
||||
#if defined(HAVE_WIN32_IPC)
|
||||
if (mWriteHandle != kInvalidHandle) {
|
||||
if (!CloseHandle((HANDLE)mWriteHandle)) {
|
||||
LOG(LOG_WARN, "pipe", "failed closing write handle\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (mWriteHandle != kInvalidHandle) {
|
||||
if (close((int) mWriteHandle) != 0) {
|
||||
LOG(LOG_WARN, "pipe", "failed closing write fd\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mWriteHandle = kInvalidHandle;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the read handle.
|
||||
*/
|
||||
unsigned long Pipe::getReadHandle(void)
|
||||
{
|
||||
assert(mReadHandle != kInvalidHandle);
|
||||
|
||||
return mReadHandle;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the write handle.
|
||||
*/
|
||||
unsigned long Pipe::getWriteHandle(void)
|
||||
{
|
||||
assert(mWriteHandle != kInvalidHandle);
|
||||
|
||||
return mWriteHandle;
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <utils/executablepath.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void executablepath(char s[PATH_MAX])
|
||||
{
|
||||
ProcessSerialNumber psn;
|
||||
GetCurrentProcess(&psn);
|
||||
CFDictionaryRef dict;
|
||||
dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
|
||||
CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
|
||||
CFSTR("CFBundleExecutable"));
|
||||
CFStringGetCString(value, s, PATH_MAX+1, kCFStringEncodingUTF8);
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <utils/executablepath.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void executablepath(char exe[PATH_MAX])
|
||||
{
|
||||
char proc[100];
|
||||
sprintf(proc, "/proc/%d/exe", getpid());
|
||||
|
||||
int err = readlink(proc, exe, PATH_MAX);
|
||||
}
|
||||
|
Loading…
Reference in New Issue