bool FileDescriptor::CreatePipe(FileDescriptor &r, FileDescriptor &w) { int fds[2]; #ifdef __linux__ const int flags = O_CLOEXEC; #ifdef __BIONIC__ /* Bionic provides the pipe2() function only since Android 2.3, therefore we must roll our own system call here */ const int result = syscall(__NR_pipe2, fds, flags); #else const int result = pipe2(fds, flags); #endif #else const int result = pipe(fds); #endif if (result < 0) return false; r = FileDescriptor(fds[0]); w = FileDescriptor(fds[1]); return true; }
bool CreateTransport(ProcessHandle /*unused*/, ProcessHandle /*unused*/, TransportDescriptor* aOne, TransportDescriptor* aTwo) { // Gecko doesn't care about this random ID, and the argument to this // function isn't really necessary, it can be just any random // pointer value wstring id = ChildProcessInfo::GenerateRandomChannelID(aOne); // Use MODE_SERVER to force creation of the socketpair Transport t(id, Transport::MODE_SERVER, nsnull); int fd1 = t.GetServerFileDescriptor(); int fd2, dontcare; t.GetClientFileDescriptorMapping(&fd2, &dontcare); if (fd1 < 0 || fd2 < 0) { return false; } // The Transport closes these fds when it goes out of scope, so we // dup them here fd1 = dup(fd1); fd2 = dup(fd2); if (fd1 < 0 || fd2 < 0) { return false; } aOne->mFd = FileDescriptor(fd1, true/*close after sending*/); aTwo->mFd = FileDescriptor(fd2, true/*close after sending*/); return true; }
WaylandEventQueue::WaylandEventQueue(IOLoop &_io_loop, EventQueue &_queue) :io_loop(_io_loop), queue(_queue), display(wl_display_connect(nullptr)) { if (display == nullptr) { fprintf(stderr, "wl_display_connect() failed\n"); exit(EXIT_FAILURE); } auto registry = wl_display_get_registry(display); wl_registry_add_listener(registry, ®istry_listener, this); wl_display_dispatch(display); wl_display_roundtrip(display); if (compositor == nullptr) { fprintf(stderr, "No Wayland compositor found\n"); exit(EXIT_FAILURE); } if (seat == nullptr) { fprintf(stderr, "No Wayland seat found\n"); exit(EXIT_FAILURE); } if (shell == nullptr) { fprintf(stderr, "No Wayland shell found\n"); exit(EXIT_FAILURE); } io_loop.Add(FileDescriptor(wl_display_get_fd(display)), io_loop.READ, *this); }
mozilla::ipc::IPCResult TemporaryIPCBlobParent::CreateAndShareFile() { MOZ_ASSERT(mActive); MOZ_ASSERT(!mFile); nsresult rv = NS_OpenAnonymousTemporaryNsIFile(getter_AddRefs(mFile)); if (NS_WARN_IF(NS_FAILED(rv))) { return SendDeleteError(rv); } PRFileDesc* fd; rv = mFile->OpenNSPRFileDesc(PR_RDWR, PR_IRWXU, &fd); if (NS_WARN_IF(NS_FAILED(rv))) { return SendDeleteError(rv); } FileDescriptor fdd = FileDescriptor(FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(fd))); // The FileDescriptor object owns a duplicate of the file handle; we // must close the original (and clean up the NSPR descriptor). PR_Close(fd); Unused << SendFileDesc(fdd); return IPC_OK(); }
void CEmuFileWrapper::UnRegisterFileObjectByStream(FILE* stream) { if (isValidFilePtr(stream)) { return UnRegisterFileObjectByDescriptor(FileDescriptor(*stream)->_file); } }
void CEmuFileWrapper::CleanUp() { CSingleLock lock(m_criticalSection); for (int i = 0; i < MAX_EMULATED_FILES; i++) { if (m_files[i].used) { m_files[i].file_xbmc->Close(); delete m_files[i].file_xbmc; if (m_files[i].file_lock) { delete m_files[i].file_lock; m_files[i].file_lock = nullptr; } #if !defined(TARGET_WINDOWS) //Don't memset on Windows as it overwrites our pointer memset(&m_files[i], 0, sizeof(EmuFileObject)); #endif m_files[i].used = false; FileDescriptor(m_files[i].file_emu)->_file = -1; } #if defined(TARGET_WINDOWS) && (_MSC_VER >= 1900) delete static_cast<kodi_iobuf*>(m_files[i].file_emu._Placeholder); m_files[i].file_emu._Placeholder = nullptr; #endif } }
bool CEmuFileWrapper::StreamIsEmulatedFile(FILE* stream) { if (isValidFilePtr(stream)) { return DescriptorIsEmulatedFile(FileDescriptor(*stream)->_file); } return false; }
EmuFileObject* CEmuFileWrapper::GetFileObjectByStream(FILE* stream) { if (isValidFilePtr(stream)) { return GetFileObjectByDescriptor(FileDescriptor(*stream)->_file); } return nullptr; }
Pipe::Pipe() { #ifdef _WIN32 HANDLE readPipe; HANDLE writePipe; SECURITY_ATTRIBUTES sec; memset(&sec, 0, sizeof(sec)); sec.nLength = sizeof(sec); sec.bInheritHandle = FALSE; // O_CLOEXEC equivalent constexpr DWORD kPipeSize = 64 * 1024; if (!CreatePipe(&readPipe, &writePipe, &sec, kPipeSize)) { throw std::system_error( GetLastError(), std::system_category(), "CreatePipe failed"); } read = FileDescriptor(intptr_t(readPipe)); write = FileDescriptor(intptr_t(writePipe)); #else int fds[2]; int res; #if HAVE_PIPE2 res = pipe2(fds, O_NONBLOCK | O_CLOEXEC); #else res = pipe(fds); #endif if (res) { throw std::system_error( errno, std::system_category(), std::string("pipe error: ") + strerror(errno)); } read = FileDescriptor(fds[0]); write = FileDescriptor(fds[1]); #if !HAVE_PIPE2 read.setCloExec(); read.setNonBlock(); write.setCloExec(); write.setNonBlock(); #endif #endif }
int CEmuFileWrapper::GetDescriptorByStream(FILE* stream) { if (isValidFilePtr(stream)) { int i = FileDescriptor(*stream)->_file - FILE_WRAPPER_OFFSET; if (i >= 0 && i < MAX_EMULATED_FILES) { return i + FILE_WRAPPER_OFFSET; } } return -1; }
XFILE::CFile* CEmuFileWrapper::GetFileXbmcByStream(FILE* stream) { if (isValidFilePtr(stream)) { auto object = GetFileObjectByDescriptor(FileDescriptor(*stream)->_file); if (object != nullptr && object->used) { return object->file_xbmc; } } return nullptr; }
Result<Ok, nsresult> MemMapSnapshot::Freeze(AutoMemMap& aMem) { auto orig = mFile.ref().ClonePlatformHandle(); mFile.reset(); HANDLE handle; if (!::DuplicateHandle( GetCurrentProcess(), orig.release(), GetCurrentProcess(), &handle, GENERIC_READ | FILE_MAP_READ, false, DUPLICATE_CLOSE_SOURCE)) { return Err(NS_ERROR_FAILURE); } return aMem.initWithHandle(FileDescriptor(handle), mMem.size()); }
X11EventQueue::X11EventQueue(IOLoop &_io_loop, EventQueue &_queue) :io_loop(_io_loop), queue(_queue), display(XOpenDisplay(nullptr)) { if (display == nullptr) { fprintf(stderr, "XOpenDisplay() failed\n"); exit(EXIT_FAILURE); } wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", false); io_loop.Add(FileDescriptor(ConnectionNumber(display)), io_loop.READ, *this); }
CEmuFileWrapper::CEmuFileWrapper() { // since we always use dlls we might just initialize it directly for (int i = 0; i < MAX_EMULATED_FILES; i++) { memset(&m_files[i], 0, sizeof(EmuFileObject)); m_files[i].used = false; #if defined(TARGET_WINDOWS) && (_MSC_VER >= 1900) m_files[i].file_emu._Placeholder = new kodi_iobuf(); #endif FileDescriptor(m_files[i].file_emu)->_file = -1; } }
void ParamTraits<MagicGrallocBufferHandle>::Write(Message* aMsg, const paramType& aParam) { #if ANDROID_VERSION >= 19 sp<GraphicBuffer> flattenable = aParam.mGraphicBuffer; #else Flattenable *flattenable = aParam.mGraphicBuffer.get(); #endif size_t nbytes = flattenable->getFlattenedSize(); size_t nfds = flattenable->getFdCount(); char data[nbytes]; int fds[nfds]; #if ANDROID_VERSION >= 19 // Make a copy of "data" and "fds" for flatten() to avoid casting problem void *pdata = (void *)data; int *pfds = fds; flattenable->flatten(pdata, nbytes, pfds, nfds); // In Kitkat, flatten() will change the value of nbytes and nfds, which dues // to multiple parcelable object consumption. The actual size and fd count // which returned by getFlattenedSize() and getFdCount() are not changed. // So we change nbytes and nfds back by call corresponding calls. nbytes = flattenable->getFlattenedSize(); nfds = flattenable->getFdCount(); #else flattenable->flatten(data, nbytes, fds, nfds); #endif aMsg->WriteInt(aParam.mRef.mOwner); aMsg->WriteInt64(aParam.mRef.mKey); aMsg->WriteSize(nbytes); aMsg->WriteSize(nfds); aMsg->WriteBytes(data, nbytes); for (size_t n = 0; n < nfds; ++n) { // These buffers can't die in transit because they're created // synchonously and the parent-side buffer can only be dropped if // there's a crash. aMsg->WriteFileDescriptor(FileDescriptor(fds[n], false)); } }
EmuFileObject* CEmuFileWrapper::RegisterFileObject(XFILE::CFile* pFile) { EmuFileObject* object = nullptr; CSingleLock lock(m_criticalSection); for (int i = 0; i < MAX_EMULATED_FILES; i++) { if (!m_files[i].used) { // found a free location object = &m_files[i]; object->used = true; object->file_xbmc = pFile; FileDescriptor(object->file_emu)->_file = (i + FILE_WRAPPER_OFFSET); object->file_lock = new CCriticalSection(); break; } } return object; }
void ParamTraits<MagicGrallocBufferHandle>::Write(Message* aMsg, const paramType& aParam) { Flattenable *flattenable = aParam.mGraphicBuffer.get(); size_t nbytes = flattenable->getFlattenedSize(); size_t nfds = flattenable->getFdCount(); char data[nbytes]; int fds[nfds]; flattenable->flatten(data, nbytes, fds, nfds); aMsg->WriteSize(nbytes); aMsg->WriteSize(nfds); aMsg->WriteBytes(data, nbytes); for (size_t n = 0; n < nfds; ++n) { // These buffers can't die in transit because they're created // synchonously and the parent-side buffer can only be dropped if // there's a crash. aMsg->WriteFileDescriptor(FileDescriptor(fds[n], false)); } }
void CEmuFileWrapper::UnRegisterFileObjectByDescriptor(int fd) { int i = fd - FILE_WRAPPER_OFFSET; if (! (i >= 0 && i < MAX_EMULATED_FILES)) return; if (!m_files[i].used) return; CSingleLock lock(m_criticalSection); // we assume the emulated function already deleted the CFile object if (m_files[i].file_lock) { delete m_files[i].file_lock; m_files[i].file_lock = nullptr; } #if !defined(TARGET_WINDOWS) //Don't memset on Windows as it overwrites our pointer memset(&m_files[i], 0, sizeof(EmuFileObject)); #endif m_files[i].used = false; FileDescriptor(m_files[i].file_emu)->_file = -1; }
WaylandEventQueue::~WaylandEventQueue() { io_loop.Remove(FileDescriptor(wl_display_get_fd(display))); wl_display_disconnect(display); }
static constexpr FileDescriptor Undefined() { return FileDescriptor(-1); }
X11EventQueue::~X11EventQueue() { io_loop.Remove(FileDescriptor(ConnectionNumber(display))); XCloseDisplay(display); }
MumuFile::MumuFile(QByteArray fdBlock) { this->descriptor = FileDescriptor(fdBlock); }