# Bug 753046 - Add support for DragonFly/NetBSD $NetBSD: patch-dom_plugins_ipc_PluginModuleChild.cpp,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- dom/plugins/ipc/PluginModuleChild.cpp.orig 2011-12-20 23:28:14.000000000 +0000 +++ dom/plugins/ipc/PluginModuleChild.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifdef MOZ_WIDGET_QT +#include // for _exit() #include #include "nsQAppInstance.h" #include "NestedLoopTimer.h" @@ -228,7 +228,7 @@ PluginModuleChild::Init(const std::strin // TODO: use PluginPRLibrary here -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_BSD) mShutdownFunc = (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown"); @@ -1790,7 +1790,7 @@ PluginModuleChild::AnswerNP_GetEntryPoin PLUGIN_LOG_DEBUG_METHOD; AssertPluginThread(); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_BSD) return true; #elif defined(OS_WIN) || defined(OS_MACOSX) *_retval = mGetEntryPointsFunc(&mFunctions); @@ -1823,7 +1823,7 @@ PluginModuleChild::AnswerNP_Initialize(N SendBackUpXResources(FileDescriptor(xSocketFd, false/*don't close*/)); #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_BSD) *_retval = mInitializeFunc(&sBrowserFuncs, &mFunctions); return true; #elif defined(OS_WIN) || defined(OS_MACOSX) $NetBSD: patch-dom_plugins_ipc_PluginModuleChild.h,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- dom/plugins/ipc/PluginModuleChild.h.orig 2011-12-20 23:28:14.000000000 +0000 +++ dom/plugins/ipc/PluginModuleChild.h @@ -340,7 +340,7 @@ private: // we get this from the plugin NP_PLUGINSHUTDOWN mShutdownFunc; -#ifdef OS_LINUX +#if defined(OS_LINUX) || defined(OS_BSD) NP_PLUGINUNIXINIT mInitializeFunc; #elif defined(OS_WIN) || defined(OS_MACOSX) NP_PLUGININIT mInitializeFunc; $NetBSD: patch-ipc_chromium_Makefile.in,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/Makefile.in.orig 2012-02-16 06:40:33.000000000 +0000 +++ ipc/chromium/Makefile.in @@ -278,6 +278,33 @@ endif endif # } OS_LINUX +ifdef OS_BSD # { + +CPPSRCS += \ + atomicops_internals_x86_gcc.cc \ + process_util_bsd.cc \ + time_posix.cc \ + $(NULL) + +ifdef MOZ_ENABLE_GTK2 +CPPSRCS += \ + message_pump_glib.cc \ + $(NULL) +endif + +ifdef MOZ_ENABLE_QT +MOCSRCS = \ + moc_message_pump_qt.cc \ + $(NULL) + +CPPSRCS += \ + $(MOCSRCS) \ + message_pump_qt.cc \ + $(NULL) +endif + +endif # } OS_BSD + # libevent ifndef MOZ_NATIVE_LIBEVENT # { $NetBSD: patch-ipc_chromium_chromium-config.mk,v 1.2 2012/03/15 08:30:06 ryoon Exp $ --- ipc/chromium/chromium-config.mk.orig 2012-02-16 07:40:33.000000000 +0100 +++ ipc/chromium/chromium-config.mk 2012-03-11 11:05:40.397182000 +0100 @@ -56,17 +56,6 @@ -I$(DEPTH)/ipc/ipdl/_ipdlheaders \ $(NULL) -ifeq ($(OS_ARCH),Darwin) # { - -OS_MACOSX = 1 -OS_POSIX = 1 - -DEFINES += \ - -DOS_MACOSX=1 \ - -DOS_POSIX=1 \ - $(NULL) - -else # } { ifeq ($(OS_ARCH),WINNT) # { OS_LIBS += $(call EXPAND_LIBNAME,psapi shell32 dbghelp) @@ -93,13 +82,65 @@ endif else # } { - -OS_LINUX = 1 OS_POSIX = 1 +DEFINES += -DOS_POSIX=1 + +ifeq ($(OS_ARCH),Darwin) # { + +OS_MACOSX = 1 +DEFINES += \ + -DOS_MACOSX=1 \ + $(NULL) + +else # } { +ifeq ($(OS_ARCH),DragonFly) # { + +OS_DRAGONFLY = 1 +OS_BSD = 1 +OS_LIBS += $(call EXPAND_LIBNAME,kvm) +DEFINES += \ + -DOS_DRAGONFLY=1 \ + -DOS_BSD=1 \ + $(NULL) + +else # } { +ifeq ($(OS_ARCH),FreeBSD) # { + +OS_FREEBSD = 1 +OS_BSD = 1 +OS_LIBS += $(call EXPAND_LIBNAME,kvm) +DEFINES += \ + -DOS_FREEBSD=1 \ + -DOS_BSD=1 \ + $(NULL) +else # } { +ifeq ($(OS_ARCH),NetBSD) # { + +OS_NETBSD = 1 +OS_BSD = 1 +OS_LIBS += $(call EXPAND_LIBNAME,kvm) +DEFINES += \ + -DOS_NETBSD=1 \ + -DOS_BSD=1 \ + $(NULL) + +else # } { +ifeq ($(OS_ARCH),OpenBSD) # { + +OS_OPENBSD = 1 +OS_BSD = 1 +OS_LIBS += $(call EXPAND_LIBNAME,kvm) +DEFINES += \ + -DOS_OPENBSD=1 \ + -DOS_BSD=1 \ + $(NULL) + +else # } { + +OS_LINUX = 1 DEFINES += \ -DOS_LINUX=1 \ - -DOS_POSIX=1 \ $(NULL) # NB: to stop gcc warnings about exporting template instantiation @@ -107,4 +147,8 @@ endif # } endif # } +endif # } +endif # } +endif # } +endif # } $NetBSD: patch-ipc_chromium_src_base_base__paths.h,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/src/base/base_paths.h.orig 2011-12-20 23:28:19.000000000 +0000 +++ ipc/chromium/src/base/base_paths.h @@ -13,7 +13,7 @@ #include "base/base_paths_win.h" #elif defined(OS_MACOSX) #include "base/base_paths_mac.h" -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || defined(OS_BSD) #include "base/base_paths_linux.h" #endif #include "base/path_service.h" $NetBSD: patch-ipc_chromium_src_base_debug__util__posic.cc,v 1.3 2012/04/01 15:18:45 ryoon Exp $ --- ipc/chromium/src/base/debug_util_posix.cc.orig 2012-03-13 01:36:53.000000000 +0000 +++ ipc/chromium/src/base/debug_util_posix.cc @@ -5,7 +5,7 @@ #include "build/build_config.h" #include "base/debug_util.h" -#define MOZ_HAVE_EXECINFO_H (!defined(ANDROID) && !defined(__OpenBSD__)) +#define MOZ_HAVE_EXECINFO_H (defined(OS_LINUX) && !defined(ANDROID)) #include #include @@ -17,9 +17,16 @@ #include #if MOZ_HAVE_EXECINFO_H #include +#endif + +#if defined(OS_MACOSX) || defined(OS_BSD) #include #endif +#if defined(OS_DRAGONFLY) || defined(OS_FREEBSD) +#include +#endif + #include "base/basictypes.h" #include "base/eintr_wrapper.h" #include "base/logging.h" @@ -32,7 +37,7 @@ bool DebugUtil::SpawnDebuggerOnProcess(u return false; } -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_BSD) // Based on Apple's recommended method as described in // http://developer.apple.com/qa/qa2004/qa1361.html @@ -71,7 +76,15 @@ bool DebugUtil::BeingDebugged() { // This process is being debugged if the P_TRACED flag is set. is_set = true; +#if defined(OS_DRAGONFLY) + being_debugged = (info.kp_flags & P_TRACED) != 0; +#elif defined(OS_FREEBSD) + being_debugged = (info.ki_flag & P_TRACED) != 0; +#elif defined(OS_OPENBSD) + being_debugged = (info.p_flag & P_TRACED) != 0; +#else being_debugged = (info.kp_proc.p_flag & P_TRACED) != 0; +#endif return being_debugged; } diff --git ipc/chromium/src/base/dir_reader_bsd.h ipc/chromium/src/base/dir_reader_bsd.h new file mode 100644 index 0000000..3fc1a87 --- /dev/null +++ ipc/chromium/src/base/dir_reader_bsd.h @@ -0,0 +1,112 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// derived from dir_reader_linux.h + +#ifndef BASE_DIR_READER_BSD_H_ +#define BASE_DIR_READER_BSD_H_ +#pragma once + +#include +#include +#include +#include +#include + +#include "base/logging.h" +#include "base/eintr_wrapper.h" + +// See the comments in dir_reader_posix.h about this. + +namespace base { + +class DirReaderBSD { + public: + explicit DirReaderBSD(const char* directory_path) +#ifdef O_DIRECTORY + : fd_(open(directory_path, O_RDONLY | O_DIRECTORY)), +#else + : fd_(open(directory_path, O_RDONLY)), +#endif + offset_(0), + size_(0) { + memset(buf_, 0, sizeof(buf_)); + } + + ~DirReaderBSD() { + if (fd_ >= 0) { + if (HANDLE_EINTR(close(fd_))) + DLOG(ERROR) << "Failed to close directory handle"; + } + } + + bool IsValid() const { + return fd_ >= 0; + } + + // Move to the next entry returning false if the iteration is complete. + bool Next() { + if (size_) { + struct dirent* dirent = reinterpret_cast(&buf_[offset_]); +#ifdef OS_DRAGONFLY + offset_ += _DIRENT_DIRSIZ(dirent); +#else + offset_ += dirent->d_reclen; +#endif + } + + if (offset_ != size_) + return true; + +#ifdef OS_OPENBSD + const int r = getdirentries(fd_, buf_, sizeof(buf_), basep_); +#else + const int r = getdents(fd_, buf_, sizeof(buf_)); +#endif + if (r == 0) + return false; + if (r == -1) { +#ifdef OS_OPENBSD + DLOG(ERROR) << "getdirentries returned an error: " << errno; +#else + DLOG(ERROR) << "getdents returned an error: " << errno; +#endif + return false; + } + size_ = r; + offset_ = 0; + return true; + } + + const char* name() const { + if (!size_) + return NULL; + + const struct dirent* dirent = + reinterpret_cast(&buf_[offset_]); + return dirent->d_name; + } + + int fd() const { + return fd_; + } + + static bool IsFallback() { + return false; + } + + private: + const int fd_; + char buf_[512]; +#ifdef OS_OPENBSD + off_t *basep_; +#endif + size_t offset_, size_; + + DISALLOW_COPY_AND_ASSIGN(DirReaderBSD); +}; + +} // namespace base + +#endif // BASE_DIR_READER_BSD_H_ diff --git ipc/chromium/src/base/dir_reader_posix.h ipc/chromium/src/base/dir_reader_posix.h index 9a34492..62b280c 100644 --- ipc/chromium/src/base/dir_reader_posix.h +++ ipc/chromium/src/base/dir_reader_posix.h @@ -18,16 +18,20 @@ // seems worse than falling back to enumerating all file descriptors so we will // probably never implement this on the Mac. -#if defined(OS_LINUX) && !defined(OS_OPENBSD) +#if defined(OS_LINUX) #include "base/dir_reader_linux.h" +#elif defined(OS_BSD) +#include "base/dir_reader_bsd.h" #else #include "base/dir_reader_fallback.h" #endif namespace base { -#if defined(OS_LINUX) && !defined(OS_OPENBSD) +#if defined(OS_LINUX) typedef DirReaderLinux DirReaderPosix; +#elif defined(OS_BSD) +typedef DirReaderBSD DirReaderPosix; #else typedef DirReaderFallback DirReaderPosix; #endif $NetBSD: patch-ipc_chromium_src_base_file__util__posix.cc,v 1.2 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/src/base/file_util_posix.cc.orig 2011-12-20 23:28:19.000000000 +0000 +++ ipc/chromium/src/base/file_util_posix.cc @@ -31,7 +31,7 @@ #include "base/time.h" // FreeBSD/OpenBSD lacks stat64, but its stat handles files >2GB just fine -#if defined(OS_FREEBSD) || defined(OS_OPENBSD) +#ifndef HAVE_STAT64 #define stat64 stat #endif $NetBSD: patch-ipc_chromium_src_base_message__loop.cc,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/src/base/message_loop.cc.orig 2012-02-16 07:40:33.000000000 +0100 +++ ipc/chromium/src/base/message_loop.cc 2012-02-21 21:24:41.000000000 +0100 @@ -19,7 +19,7 @@ #if defined(OS_POSIX) #include "base/message_pump_libevent.h" #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_BSD) #ifdef MOZ_WIDGET_GTK2 #include "base/message_pump_glib.h" #endif @@ -119,7 +119,7 @@ if (type_ == TYPE_UI) { #if defined(OS_MACOSX) pump_ = base::MessagePumpMac::Create(); -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || defined(OS_BSD) pump_ = new base::MessagePumpForUI(); #endif // OS_LINUX } else if (type_ == TYPE_IO) { $NetBSD: patch-ipc_chromium_src_base_platform__thread.h,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/src/base/platform_thread.h.orig 2011-12-20 23:28:19.000000000 +0000 +++ ipc/chromium/src/base/platform_thread.h @@ -22,9 +22,12 @@ typedef void* PlatformThreadHandle; // HANDLE #elif defined(OS_POSIX) #include typedef pthread_t PlatformThreadHandle; -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_OPENBSD) #include typedef pid_t PlatformThreadId; +#elif defined(OS_BSD) +#include +typedef lwpid_t PlatformThreadId; #elif defined(OS_MACOSX) #include typedef mach_port_t PlatformThreadId; $NetBSD: patch-ipc_chromium_src_base_platform__thread__posix.cc,v 1.4 2012/04/01 15:18:45 ryoon Exp $ --- ipc/chromium/src/base/platform_thread_posix.cc.orig 2012-03-13 01:36:53.000000000 +0000 +++ ipc/chromium/src/base/platform_thread_posix.cc @@ -9,16 +9,24 @@ #if defined(OS_MACOSX) #include +#elif defined(OS_NETBSD) +#include #elif defined(OS_LINUX) #include -#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) #include -#elif !defined(__NetBSD__) -#include +#elif defined(OS_FREEBSD) +#include +#include #endif + +#if !defined(OS_MACOSX) #include #endif +#if defined(OS_BSD) && !defined(OS_NETBSD) +#include +#endif + #if defined(OS_MACOSX) namespace base { void InitThreading(); @@ -38,9 +45,20 @@ PlatformThreadId PlatformThread::CurrentId() { // into the kernel. #if defined(OS_MACOSX) return mach_thread_self(); -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#elif defined(OS_NETBSD) + return _lwp_self(); +#elif defined(OS_DRAGONFLY) + return lwp_gettid(); +#elif defined(OS_FREEBSD) +# if __FreeBSD_version > 900030 + return pthread_getthreadid_np(); +# else + long lwpid; + thr_self(&lwpid); + return lwpid; +# endif +#elif defined(OS_OPENBSD) - // TODO(BSD): find a better thread ID - return (intptr_t)(pthread_self()); + return (intptr_t) (pthread_self()); #elif defined(OS_LINUX) return syscall(__NR_gettid); #endif @@ -102,9 +102,9 @@ void PlatformThread::SetName(const char* name) { // Note that glibc also has a 'pthread_setname_np' api, but it may not be // available everywhere and it's only benefit over using prctl directly is // that it can set the name of threads other than the current thread. -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#if defined(OS_BSD) && !defined(OS_NETBSD) pthread_set_name_np(pthread_self(), name); -#elif defined(__NetBSD__) +#elif defined(OS_NETBSD) pthread_setname_np(pthread_self(), "%s", (void *)name); #else prctl(PR_SET_NAME, reinterpret_cast(name), 0, 0, 0); $NetBSD: patch-ipc_chromium_src_base_process__util.h,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/src/base/process_util.h.orig 2011-12-21 00:28:19.000000000 +0100 +++ ipc/chromium/src/base/process_util.h 2012-01-31 13:14:54.000000000 +0100 @@ -280,6 +280,7 @@ class NamedProcessIterator { const ProcessEntry* NextProcessEntry(); private: +#if !defined(OS_BSD) // Determines whether there's another process (regardless of executable) // left in the list of all processes. Returns true and sets entry_ to // that process's info if there is one, false otherwise. @@ -292,18 +292,24 @@ void InitProcessEntry(ProcessEntry* entry); std::wstring executable_name_; +#endif #if defined(OS_WIN) HANDLE snapshot_; bool started_iteration_; #elif defined(OS_LINUX) DIR *procfs_dir_; +#elif defined(OS_BSD) + std::vector content; + size_t nextEntry; #elif defined(OS_MACOSX) std::vector kinfo_procs_; size_t index_of_kinfo_proc_; #endif +#if !defined(OS_BSD) ProcessEntry entry_; const ProcessFilter* filter_; +#endif DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator); }; $NetBSD: patch-ipc_chromium_src_base_process__util__bsd.cc,v 1.4 2012/04/01 15:18:45 ryoon Exp $ --- ipc/chromium/src/base/process_util_bsd.cc.orig 2012-04-01 00:04:28.000000000 +0000 +++ ipc/chromium/src/base/process_util_bsd.cc @@ -0,0 +1,367 @@ +// Copyright (c) 2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// derived from process_util_linux.cc and process_util_mac.cc + +#include "base/process_util.h" + +#include +#include +#include +#if defined(OS_DRAGONFLY) || defined(OS_FREEBSD) +#include +#endif + +#include +#include +#include +#include + +#include + +#include "base/debug_util.h" +#include "base/eintr_wrapper.h" +#include "base/file_util.h" +#include "base/logging.h" +#include "base/string_tokenizer.h" +#include "base/string_util.h" + +#if (defined(_POSIX_SPAWN) && _POSIX_SPAWN > 0) \ + || (defined(OS_NETBSD) && __NetBSD_Version__ >= 599006500) +#define HAVE_POSIX_SPAWN 1 +#endif + +/* + * On platforms that are not gonk based, we fall back to an arbitrary + * UID. This is generally the UID for user `nobody', albeit it is not + * always the case. + */ + +#if defined(OS_NETBSD) || defined(OS_OPENBSD) +# define CHILD_UNPRIVILEGED_UID 32767 +# define CHILD_UNPRIVILEGED_GID 32767 +#else +# define CHILD_UNPRIVILEGED_UID 65534 +# define CHILD_UNPRIVILEGED_GID 65534 +#endif + +#ifndef __dso_public +# ifdef __exported +# define __dso_public __exported +# else +# define __dso_public __attribute__((__visibility__("default"))) +# endif +#endif + +#ifdef HAVE_POSIX_SPAWN +#include +extern "C" char **environ __dso_public; +#endif + +namespace { + +enum ParsingState { + KEY_NAME, + KEY_VALUE +}; + +static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG"); + +} // namespace + +namespace base { + +#ifdef HAVE_POSIX_SPAWN + +void FreeEnvVarsArray(char* array[], int length) +{ + for (int i = 0; i < length; i++) { + free(array[i]); + } + delete[] array; +} + +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + bool wait, ProcessHandle* process_handle) { + return LaunchApp(argv, fds_to_remap, environment_map(), + wait, process_handle); +} + +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + const environment_map& env_vars_to_set, + bool wait, ProcessHandle* process_handle, + ProcessArchitecture arch) { + return LaunchApp(argv, fds_to_remap, env_vars_to_set, + SAME_PRIVILEGES_AS_PARENT, + wait, process_handle); +} + +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + const environment_map& env_vars_to_set, + ChildPrivileges privs, + bool wait, ProcessHandle* process_handle, + ProcessArchitecture arch) { + bool retval = true; + + char* argv_copy[argv.size() + 1]; + for (size_t i = 0; i < argv.size(); i++) { + argv_copy[i] = const_cast(argv[i].c_str()); + } + argv_copy[argv.size()] = NULL; + + // Make sure we don't leak any FDs to the child process by marking all FDs + // as close-on-exec. + SetAllFDsToCloseOnExec(); + + // Copy environment to a new char array and add the variables + // in env_vars_to_set. + // Existing variables are overwritten by env_vars_to_set. + int pos = 0; + environment_map combined_env_vars = env_vars_to_set; + while(environ[pos] != NULL) { + std::string varString = environ[pos]; + std::string varName = varString.substr(0, varString.find_first_of('=')); + std::string varValue = varString.substr(varString.find_first_of('=') + 1); + if (combined_env_vars.find(varName) == combined_env_vars.end()) { + combined_env_vars[varName] = varValue; + } + pos++; + } + int varsLen = combined_env_vars.size() + 1; + + char** vars = new char*[varsLen]; + int i = 0; + for (environment_map::const_iterator it = combined_env_vars.begin(); + it != combined_env_vars.end(); ++it) { + std::string entry(it->first); + entry += "="; + entry += it->second; + vars[i] = strdup(entry.c_str()); + i++; + } + vars[i] = NULL; + + posix_spawn_file_actions_t file_actions; + if (posix_spawn_file_actions_init(&file_actions) != 0) { + FreeEnvVarsArray(vars, varsLen); + return false; + } + + // Turn fds_to_remap array into a set of dup2 calls. + for (file_handle_mapping_vector::const_iterator it = fds_to_remap.begin(); + it != fds_to_remap.end(); + ++it) { + int src_fd = it->first; + int dest_fd = it->second; + + if (src_fd == dest_fd) { + int flags = fcntl(src_fd, F_GETFD); + if (flags != -1) { + fcntl(src_fd, F_SETFD, flags & ~FD_CLOEXEC); + } + } else { + if (posix_spawn_file_actions_adddup2(&file_actions, src_fd, dest_fd) != 0) { + posix_spawn_file_actions_destroy(&file_actions); + FreeEnvVarsArray(vars, varsLen); + return false; + } + } + } + + pid_t pid = 0; + int spawn_succeeded = (posix_spawnp(&pid, + argv_copy[0], + &file_actions, + NULL, + argv_copy, + vars) == 0); + + FreeEnvVarsArray(vars, varsLen); + + posix_spawn_file_actions_destroy(&file_actions); + + bool process_handle_valid = pid > 0; + if (!spawn_succeeded || !process_handle_valid) { + retval = false; + } else { + if (wait) + HANDLE_EINTR(waitpid(pid, 0, 0)); + + if (process_handle) + *process_handle = pid; + } + + return retval; +} + +bool LaunchApp(const CommandLine& cl, + bool wait, bool start_hidden, ProcessHandle* process_handle) { + // TODO(playmobil): Do we need to respect the start_hidden flag? + file_handle_mapping_vector no_files; + return LaunchApp(cl.argv(), no_files, wait, process_handle); +} + +#else // no posix_spawn, use fork/exec + +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + bool wait, ProcessHandle* process_handle) { + return LaunchApp(argv, fds_to_remap, environment_map(), + wait, process_handle); +} + +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + const environment_map& env_vars_to_set, + bool wait, ProcessHandle* process_handle, + ProcessArchitecture arch) { + return LaunchApp(argv, fds_to_remap, env_vars_to_set, + SAME_PRIVILEGES_AS_PARENT, + wait, process_handle); +} + +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + const environment_map& env_vars_to_set, + ChildPrivileges privs, + bool wait, ProcessHandle* process_handle, + ProcessArchitecture arch) { + scoped_array argv_cstr(new char*[argv.size() + 1]); + // Illegal to allocate memory after fork and before execvp + InjectiveMultimap fd_shuffle1, fd_shuffle2; + fd_shuffle1.reserve(fds_to_remap.size()); + fd_shuffle2.reserve(fds_to_remap.size()); + + pid_t pid = fork(); + if (pid < 0) + return false; + + if (pid == 0) { + for (file_handle_mapping_vector::const_iterator + it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) { + fd_shuffle1.push_back(InjectionArc(it->first, it->second, false)); + fd_shuffle2.push_back(InjectionArc(it->first, it->second, false)); + } + + if (!ShuffleFileDescriptors(&fd_shuffle1)) + _exit(127); + + CloseSuperfluousFds(fd_shuffle2); + + for (size_t i = 0; i < argv.size(); i++) + argv_cstr[i] = const_cast(argv[i].c_str()); + argv_cstr[argv.size()] = NULL; + + if (privs == UNPRIVILEGED) { + if (setgid(CHILD_UNPRIVILEGED_GID) != 0) { + DLOG(ERROR) << "FAILED TO setgid() CHILD PROCESS, path: " << argv_cstr[0]; + _exit(127); + } + if (setuid(CHILD_UNPRIVILEGED_UID) != 0) { + DLOG(ERROR) << "FAILED TO setuid() CHILD PROCESS, path: " << argv_cstr[0]; + _exit(127); + } + if (chdir("/") != 0) + gProcessLog.print("==> could not chdir()\n"); + } + + for (environment_map::const_iterator it = env_vars_to_set.begin(); + it != env_vars_to_set.end(); ++it) { + if (setenv(it->first.c_str(), it->second.c_str(), 1/*overwrite*/)) + _exit(127); + } + execv(argv_cstr[0], argv_cstr.get()); + // if we get here, we're in serious trouble and should complain loudly + DLOG(ERROR) << "FAILED TO exec() CHILD PROCESS, path: " << argv_cstr[0]; + _exit(127); + } else { + gProcessLog.print("==> process %d launched child process %d\n", + GetCurrentProcId(), pid); + if (wait) + HANDLE_EINTR(waitpid(pid, 0, 0)); + + if (process_handle) + *process_handle = pid; + } + + return true; +} + +bool LaunchApp(const CommandLine& cl, + bool wait, bool start_hidden, + ProcessHandle* process_handle) { + file_handle_mapping_vector no_files; + return LaunchApp(cl.argv(), no_files, wait, process_handle); +} + +#endif + +NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name, + const ProcessFilter* filter) +{ + int numEntries; + kvm_t *kvm; + std::string exe(WideToASCII(executable_name)); + +#if defined(OS_DRAGONFLY) || defined(OS_FREEBSD) + kvm = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL); + struct kinfo_proc* procs = kvm_getprocs(kvm, KERN_PROC_UID, getuid(), &numEntries); + if (procs != NULL && numEntries > 0) { + for (int i = 0; i < numEntries; i++) { +# if defined(OS_DRAGONFLY) + if (exe != procs[i].kp_comm) continue; + if (filter && !filter->Includes(procs[i].kp_pid, procs[i].kp_ppid)) continue; + ProcessEntry e; + e.pid = procs[i].kp_pid; + e.ppid = procs[i].kp_ppid; + strlcpy(e.szExeFile, procs[i].kp_comm, sizeof e.szExeFile); + content.push_back(e); +# elif defined(OS_FREEBSD) + if (exe != procs[i].ki_comm) continue; + if (filter && !filter->Includes(procs[i].ki_pid, procs[i].ki_ppid)) continue; + ProcessEntry e; + e.pid = procs[i].ki_pid; + e.ppid = procs[i].ki_ppid; + strlcpy(e.szExeFile, procs[i].ki_comm, sizeof e.szExeFile); + content.push_back(e); +# endif +#else + kvm = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL); +#if defined(OS_OPENBSD) + struct kinfo_proc* procs = kvm_getprocs(kvm, KERN_PROC_UID, getuid(), sizeof(struct kinfo_proc), &numEntries); +#else + struct kinfo_proc2* procs = kvm_getproc2(kvm, KERN_PROC_UID, getuid(), sizeof(struct kinfo_proc2), &numEntries); +#endif + if (procs != NULL && numEntries > 0) { + for (int i = 0; i < numEntries; i++) { + if (exe != procs[i].p_comm) continue; + if (filter && !filter->Includes(procs[i].p_pid, procs[i].p_ppid)) continue; + ProcessEntry e; + e.pid = procs[i].p_pid; + e.ppid = procs[i].p_ppid; + strlcpy(e.szExeFile, procs[i].p_comm, sizeof e.szExeFile); + content.push_back(e); +#endif + } + } + nextEntry = 0; + kvm_close(kvm); +} + +NamedProcessIterator::~NamedProcessIterator() { +} + +const ProcessEntry* NamedProcessIterator::NextProcessEntry() { + if (nextEntry >= content.size()) return NULL; + return &content[nextEntry++]; +} + +bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { + return false; +} + +} // namespace base $NetBSD: patch-ipc_chromium_src_base_process__util__posix.cc,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/src/base/process_util_posix.cc.orig 2011-12-20 23:28:19.000000000 +0000 +++ ipc/chromium/src/base/process_util_posix.cc @@ -116,6 +116,11 @@ void CloseSuperfluousFds(const base::Inj #elif defined(OS_MACOSX) static const rlim_t kSystemDefaultMaxFds = 256; static const char kFDDir[] = "/dev/fd"; +#elif defined(OS_BSD) + // the getrlimit below should never fail, so whatever .. + static const rlim_t kSystemDefaultMaxFds = 1024; + // at least /dev/fd will exist + static const char kFDDir[] = "/dev/fd"; #endif // Get the maximum number of FDs possible. @@ -199,7 +204,7 @@ void CloseSuperfluousFds(const base::Inj void SetAllFDsToCloseOnExec() { #if defined(OS_LINUX) const char fd_dir[] = "/proc/self/fd"; -#elif defined(OS_MACOSX) +#elif defined(OS_MACOSX) || defined(OS_BSD) const char fd_dir[] = "/dev/fd"; #endif ScopedDIR dir_closer(opendir(fd_dir)); $NetBSD: patch-ipc_chromium_src_base_sys__info__posix.cc,v 1.2 2011/11/27 13:09:00 tnn Exp $ --- ipc/chromium/src/base/sys_info_posix.cc.orig 2011-11-04 21:34:00.000000000 +0000 +++ ipc/chromium/src/base/sys_info_posix.cc @@ -18,6 +18,11 @@ #include #endif +#if defined(OS_NETBSD) +#include +#include +#endif + #include "base/logging.h" #include "base/string_util.h" @@ -26,7 +31,11 @@ namespace base { int SysInfo::NumberOfProcessors() { // It seems that sysconf returns the number of "logical" processors on both // mac and linux. So we get the number of "online logical" processors. +#ifdef _SC_NPROCESSORS_ONLN static long res = sysconf(_SC_NPROCESSORS_ONLN); +#else + static long res = 1; +#endif if (res == -1) { NOTREACHED(); return 1; @@ -52,6 +61,20 @@ int64 SysInfo::AmountOfPhysicalMemory() } return static_cast(hostinfo.max_mem); +#elif defined(OS_NETBSD) + int mib[2]; + int rc; + int64_t memSize; + size_t len = sizeof(memSize); + + mib[0] = CTL_HW; + mib[1] = HW_PHYSMEM64; + rc = sysctl( mib, 2, &memSize, &len, NULL, 0 ); + if (-1 != rc) { + return memSize; + } + return 0; + #else long pages = sysconf(_SC_PHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); diff --git ipc/chromium/src/base/time_posix.cc ipc/chromium/src/base/time_posix.cc index abf2a56..48791f6 100644 --- ipc/chromium/src/base/time_posix.cc +++ ipc/chromium/src/base/time_posix.cc @@ -167,7 +167,7 @@ TimeTicks TimeTicks::Now() { // With numer and denom = 1 (the expected case), the 64-bit absolute time // reported in nanoseconds is enough to last nearly 585 years. -#elif defined(__OpenBSD__) || defined(OS_POSIX) && \ +#elif defined(OS_OPENBSD) || defined(OS_POSIX) && \ defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 struct timespec ts; $NetBSD: patch-ipc_chromium_src_build_build__config.h,v 1.4 2012/04/01 15:18:45 ryoon Exp $ --- ipc/chromium/src/build/build_config.h.orig 2012-03-13 01:36:53.000000000 +0000 +++ ipc/chromium/src/build/build_config.h @@ -19,6 +19,12 @@ #define OS_MACOSX 1 #elif defined(__linux__) || defined(ANDROID) #define OS_LINUX 1 +#elif defined(__DragonFly__) +#define OS_DRAGONFLY 1 +#elif defined(__FreeBSD__) +#define OS_FREEBSD 1 +#elif defined(__NetBSD__) +#define OS_NETBSD 1 #elif defined(__OpenBSD__) #define OS_OPENBSD 1 #elif defined(_WIN32) @@ -27,9 +33,16 @@ #error Please add support for your platform in build/build_config.h #endif +// For access to standard BSD features, use OS_BSD instead of a +// more specific macro. +#if defined(OS_DRAGONFLY) || defined(OS_FREEBSD) \ + || defined(OS_NETBSD) || defined(OS_OPENBSD) +#define OS_BSD 1 +#endif + // For access to standard POSIX features, use OS_POSIX instead of a more // specific macro. -#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_OPENBSD) +#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_BSD) #define OS_POSIX 1 #endif diff --git ipc/chromium/src/chrome/common/ipc_channel_posix.cc ipc/chromium/src/chrome/common/ipc_channel_posix.cc index bd866ee..2ea5b19 100644 --- ipc/chromium/src/chrome/common/ipc_channel_posix.cc +++ ipc/chromium/src/chrome/common/ipc_channel_posix.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include $NetBSD: patch-ipc_chromium_src_chrome_common_ipc__channel__posix.h,v 1.1 2011/07/11 12:46:14 tnn Exp $ --- ipc/chromium/src/chrome/common/ipc_channel_posix.h.orig 2011-06-15 21:57:27.000000000 +0000 +++ ipc/chromium/src/chrome/common/ipc_channel_posix.h @@ -92,7 +92,7 @@ class Channel::ChannelImpl : public Mess }; // This is a control message buffer large enough to hold kMaxReadFDs -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_NETBSD) // TODO(agl): OSX appears to have non-constant CMSG macros! char input_cmsg_buf_[1024]; #else $NetBSD: patch-ipc_chromium_src_chrome_common_ipc__message__utils.h,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/src/chrome/common/ipc_message_utils.h.orig 2011-12-20 23:28:19.000000000 +0000 +++ ipc/chromium/src/chrome/common/ipc_message_utils.h @@ -195,7 +195,7 @@ }; #endif -#if !(defined(OS_MACOSX) || defined(OS_OPENBSD) || defined(OS_WIN) || (defined(OS_LINUX) && defined(ARCH_CPU_64_BITS)) || defined(ARCH_CPU_S390)) +#if !(defined(OS_MACOSX) || defined(OS_OPENBSD) || defined(OS_WIN) || ((defined(OS_BSD) || defined(OS_LINUX)) && defined(ARCH_CPU_64_BITS)) || defined(ARCH_CPU_S390)) // There size_t is a synonym for |unsigned long| ... template <> struct ParamTraits { @@ -248,7 +248,7 @@ }; #endif // defined(OS_MACOSX) -#if !(defined(OS_LINUX) && defined(ARCH_CPU_64_BITS)) +#if !((defined(OS_BSD) || defined(OS_LINUX)) && defined(ARCH_CPU_64_BITS)) // int64 is |long int| on 64-bit systems, uint64 is |unsigned long| template <> struct ParamTraits { $NetBSD: patch-ipc_chromium_src_chrome_common_transport__dib.h,v 1.1 2012/03/06 12:34:09 ryoon Exp $ --- ipc/chromium/src/chrome/common/transport_dib.h.orig 2011-12-20 23:28:19.000000000 +0000 +++ ipc/chromium/src/chrome/common/transport_dib.h @@ -7,7 +7,7 @@ #include "base/basictypes.h" -#if defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_BSD) #include "base/shared_memory.h" #endif @@ -66,7 +66,7 @@ class TransportDIB { uint32 sequence_num; }; typedef HandleAndSequenceNum Id; -#elif defined(OS_MACOSX) +#elif defined(OS_MACOSX) || defined(OS_BSD) typedef base::SharedMemoryHandle Handle; // On Mac, the inode number of the backing file is used as an id. typedef base::SharedMemoryId Id; @@ -108,7 +108,7 @@ class TransportDIB { private: TransportDIB(); -#if defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_BSD) explicit TransportDIB(base::SharedMemoryHandle dib); base::SharedMemory shared_memory_; uint32 sequence_num_; $NetBSD: patch-ipc_glue_GeckoChildProcessHost.cpp,v 1.2 2012/03/15 08:30:06 ryoon Exp $ --- ipc/glue/GeckoChildProcessHost.cpp.orig 2011-12-20 23:28:19.000000000 +0000 +++ ipc/glue/GeckoChildProcessHost.cpp @@ -430,7 +430,7 @@ // and passing wstrings from one config to the other is unsafe. So // we split the logic here. -#if defined(OS_LINUX) || defined(OS_MACOSX) +#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) base::environment_map newEnvVars; // XPCOM may not be initialized in some subprocesses. We don't want // to initialize XPCOM just for the directory service, especially @@ -445,8 +445,8 @@ if (NS_SUCCEEDED(rv)) { nsCString path; greDir->GetNativePath(path); -# ifdef OS_LINUX -# ifdef MOZ_WIDGET_ANDROID +# if defined(OS_LINUX) || defined(OS_BSD) +# if defined(MOZ_WIDGET_ANDROID) || defined(OS_BSD) path += "/lib"; # endif // MOZ_WIDGET_ANDROID const char *ld_library_path = PR_GetEnv("LD_LIBRARY_PATH"); @@ -557,7 +557,7 @@ childArgv.push_back(pidstring); #if defined(MOZ_CRASHREPORTER) -# if defined(OS_LINUX) +# if defined(OS_LINUX) || defined(OS_BSD) int childCrashFd, childCrashRemapFd; if (!CrashReporter::CreateNotificationPipeForChild( &childCrashFd, &childCrashRemapFd)) @@ -594,7 +594,7 @@ #endif base::LaunchApp(childArgv, mFileMap, -#if defined(OS_LINUX) || defined(OS_MACOSX) +#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) newEnvVars, privs, #endif false, &process, arch); diff --git ipc/glue/SharedMemorySysV.h ipc/glue/SharedMemorySysV.h index f37998d..b05dc7b 100644 --- ipc/glue/SharedMemorySysV.h +++ ipc/glue/SharedMemorySysV.h @@ -8,7 +8,7 @@ #ifndef mozilla_ipc_SharedMemorySysV_h #define mozilla_ipc_SharedMemorySysV_h -#if defined(OS_LINUX) && !defined(ANDROID) +#if (defined(OS_LINUX) && !defined(ANDROID)) || defined(OS_BSD) // SysV shared memory isn't available on Windows, but we define the // following macro so that #ifdefs are clearer (compared to #ifdef $NetBSD: patch-mm,v 1.13 2012/06/05 18:09:21 ryoon Exp $ --- toolkit/library/Makefile.in.orig 2012-05-23 18:57:09.000000000 +0000 +++ toolkit/library/Makefile.in @@ -534,6 +538,12 @@ EXTRA_DSO_LDOPTS += -lelf -ldemangle endif endif +ifneq (,$(filter DragonFly FreeBSD NetBSD OpenBSD,$(OS_ARCH))) +OS_LIBS += $(call EXPAND_LIBNAME,kvm) +# keep `environ' unresolved, see bug 14426 for binutils +EXTRA_DSO_LDOPTS += -Wl,--warn-unresolved-symbols +endif + ifeq ($(OS_ARCH),WINNT) OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 version winspool comdlg32 imm32 msimg32 shlwapi psapi ws2_32 dbghelp rasapi32 rasdlg iphlpapi uxtheme setupapi secur32 sensorsapi portabledeviceguids windowscodecs wininet) ifdef ACCESSIBILITY