diff --git a/dom/plugins/PluginProcessParent.cpp b/dom/plugins/PluginProcessParent.cpp index bd6fb75817f1..9843e8181eb4 100644 --- a/dom/plugins/PluginProcessParent.cpp +++ b/dom/plugins/PluginProcessParent.cpp @@ -61,8 +61,8 @@ PluginProcessParent::~PluginProcessParent() bool PluginProcessParent::Launch() { - std::vector args; - args.push_back(UTF8ToWide(mPluginFilePath)); + std::vector args; + args.push_back(mPluginFilePath); return SyncLaunch(args); } diff --git a/dom/plugins/PluginThreadChild.cpp b/dom/plugins/PluginThreadChild.cpp index 9407be5e7d0c..b5f16a99f5d9 100644 --- a/dom/plugins/PluginThreadChild.cpp +++ b/dom/plugins/PluginThreadChild.cpp @@ -66,15 +66,27 @@ PluginThreadChild::Init() { GeckoThread::Init(); - // FIXME/cjones: set up channel stuff, etc. - + std::string pluginFilename; + +#if defined(OS_POSIX) + // NB: need to be very careful in ensuring that the first arg + // (after the binary name) here is indeed the plugin module path. + // Keep in sync with dom/plugins/PluginModuleParent. + std::vector values = CommandLine::ForCurrentProcess()->argv(); + NS_ABORT_IF_FALSE(values.size() >= 2, "not enough args"); + + pluginFilename = values[1]; + +#elif defined(OS_WIN) std::vector values = CommandLine::ForCurrentProcess()->GetLooseValues(); + NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args"); - // XXX need to handle plugin args! - DCHECK(values.size() >= 1); + pluginFilename = WideToUTF8(values[0]); - std::string pluginFilename = WideToUTF8(values[0]); +#else +# error Sorry +#endif // FIXME owner_loop() is bad here mPlugin.Init(pluginFilename, diff --git a/ipc/glue/AsyncChannel.cpp b/ipc/glue/AsyncChannel.cpp index 08acb8e4e8a6..5b4691819aa3 100644 --- a/ipc/glue/AsyncChannel.cpp +++ b/ipc/glue/AsyncChannel.cpp @@ -250,8 +250,10 @@ AsyncChannel::OnChannelError() // Must exit the IO loop, which will then join with the UI loop. MessageLoop::current()->Quit(); #else - // Go ahead and abort here. - NS_DebugBreak(NS_DEBUG_ABORT, nsnull, nsnull, nsnull, 0); + // FIXME need to devote some thought to the most + // effective/least easily overrideable, yet quiet, way to + // exit. abort() is a little loud + _exit(0); #endif } } diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 3ab0dc241c29..fe7c453b132d 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -67,12 +67,11 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType, } bool -GeckoChildProcessHost::SyncLaunch(std::vector aExtraOpts) +GeckoChildProcessHost::SyncLaunch(std::vector aExtraOpts) { - MessageLoop* loop = MessageLoop::current(); MessageLoop* ioLoop = BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO); - NS_ASSERTION(loop != ioLoop, "sync launch from the IO thread NYI"); + NS_ASSERTION(MessageLoop::current() != ioLoop, "sync launch from the IO thread NYI"); ioLoop->PostTask(FROM_HERE, NewRunnableMethod(this, @@ -90,7 +89,7 @@ GeckoChildProcessHost::SyncLaunch(std::vector aExtraOpts) } bool -GeckoChildProcessHost::AsyncLaunch(std::vector aExtraOpts) +GeckoChildProcessHost::AsyncLaunch(std::vector aExtraOpts) { // FIXME/cjones: make this work from non-IO threads, too @@ -98,45 +97,74 @@ GeckoChildProcessHost::AsyncLaunch(std::vector aExtraOpts) return false; } - FilePath exePath = - FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program()); - exePath = exePath.DirName(); - - exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME); - - // remap the IPC socket fd to a well-known int, as the OS does for - // STDOUT_FILENO, for example -#if defined(OS_POSIX) - int srcChannelFd, dstChannelFd; - channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd); - mFileMap.push_back(std::pair(srcChannelFd, dstChannelFd)); -#endif - - CommandLine cmdLine(exePath.ToWStringHack()); - cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id()); - - for (std::vector::iterator it = aExtraOpts.begin(); - it != aExtraOpts.end(); - ++it) { - cmdLine.AppendLooseValue((*it).c_str()); - } + base::ProcessHandle process; // send the child the PID so that it can open a ProcessHandle back to us. // probably don't want to do this in the long run char pidstring[32]; PR_snprintf(pidstring, sizeof(pidstring) - 1, "%ld", base::Process::Current().pid()); + + const char* const childProcessType = + XRE_ChildProcessTypeToString(mProcessType); + +//-------------------------------------------------- +#if defined(OS_POSIX) + // For POSIX, we have to be extremely anal about *not* using + // std::wstring in code compiled with Mozilla's -fshort-wchar + // configuration, because chromium is compiled with -fno-short-wchar + // and passing wstrings from one config to the other is unsafe. So + // we split the logic here. + + FilePath exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]); + exePath = exePath.DirName(); + exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME); + + // remap the IPC socket fd to a well-known int, as the OS does for + // STDOUT_FILENO, for example + int srcChannelFd, dstChannelFd; + channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd); + mFileMap.push_back(std::pair(srcChannelFd, dstChannelFd)); + + // no need for kProcessChannelID, the child process inherits the + // other end of the socketpair() from us + + std::vector childArgv; + + childArgv.push_back(exePath.value()); + + childArgv.insert(childArgv.end(), aExtraOpts.begin(), aExtraOpts.end()); + + childArgv.push_back(pidstring); + childArgv.push_back(childProcessType); + + base::LaunchApp(childArgv, mFileMap, false, &process); + +//-------------------------------------------------- +#elif defined(OS_WIN) + + FilePath exePath = + FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program()); + exePath = exePath.DirName(); + + exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME); + + CommandLine cmdLine(exePath.ToWStringHack()); + cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id()); + + for (std::vector::iterator it = aExtraOpts.begin(); + it != aExtraOpts.end(); + ++it) { + cmdLine.AppendLooseValue(UTF8ToWide(*it)); + } + cmdLine.AppendLooseValue(UTF8ToWide(pidstring)); + cmdLine.AppendLooseValue(UTF8ToWide(childProcessType)); - cmdLine.AppendLooseValue(UTF8ToWide(XRE_ChildProcessTypeToString(mProcessType))); - - base::ProcessHandle process; -#if defined(OS_WIN) base::LaunchApp(cmdLine, false, false, &process); -#elif defined(OS_POSIX) - base::LaunchApp(cmdLine.argv(), mFileMap, false, &process); + #else -#error Bad! +# error Sorry #endif if (!process) { diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h index c27d01b575dd..dd701cf9fa5f 100644 --- a/ipc/glue/GeckoChildProcessHost.h +++ b/ipc/glue/GeckoChildProcessHost.h @@ -61,8 +61,8 @@ public: GeckoChildProcessHost(GeckoProcessType aProcessType=GeckoProcessType_Default, base::WaitableEventWatcher::Delegate* aDelegate=nsnull); - bool SyncLaunch(std::vector aExtraOpts=std::vector()); - bool AsyncLaunch(std::vector aExtraOpts=std::vector()); + bool SyncLaunch(std::vector aExtraOpts=std::vector()); + bool AsyncLaunch(std::vector aExtraOpts=std::vector()); virtual void OnChannelConnected(int32 peer_pid); virtual void OnMessageReceived(const IPC::Message& aMsg); diff --git a/ipc/glue/ScopedXREEmbed.cpp b/ipc/glue/ScopedXREEmbed.cpp index eb9be189e50d..b3af8c2eade1 100644 --- a/ipc/glue/ScopedXREEmbed.cpp +++ b/ipc/glue/ScopedXREEmbed.cpp @@ -64,7 +64,14 @@ ScopedXREEmbed::~ScopedXREEmbed() void ScopedXREEmbed::Start() { - std::string path = WideToUTF8(CommandLine::ForCurrentProcess()->program()); + std::string path; +#if defined(OS_WIN) + path = WideToUTF8(CommandLine::ForCurrentProcess()->program()); +#elif defined(OS_POSIX) + path = CommandLine::ForCurrentProcess()->argv()[0]; +#else +# error Sorry +#endif nsCOMPtr localFile; nsresult rv = XRE_GetBinaryPath(path.c_str(), getter_AddRefs(localFile)); diff --git a/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp b/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp index e88ff7c5d7e4..1d64fc3cb876 100644 --- a/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp +++ b/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp @@ -35,15 +35,17 @@ const char* const IPDLUnitTestName() { if (!gIPDLUnitTestName) { +#if defined(OS_WIN) std::vector args = CommandLine::ForCurrentProcess()->GetLooseValues(); - gIPDLUnitTestName = strdup(WideToUTF8(args[ -#ifndef OS_WIN -args.size()-1 + gIPDLUnitTestName = strdup(WideToUTF8(args[0]).c_str()); +#elif defined(OS_POSIX) + std::vector argv = + CommandLine::ForCurrentProcess()->argv(); + gIPDLUnitTestName = strdup(argv[1].c_str()); #else -args.size()-2 +# error Sorry #endif - ]).c_str()); } return gIPDLUnitTestName; } @@ -129,9 +131,8 @@ IPDLUnitTestMain(void* aData) } gIPDLUnitTestName = testString; - std::wstring testWString = UTF8ToWide(testString); - std::vector testCaseArgs; - testCaseArgs.push_back(testWString); + std::vector testCaseArgs; + testCaseArgs.push_back(testString); IPDLUnitTestSubprocess* subprocess = new IPDLUnitTestSubprocess(); if (!subprocess->SyncLaunch(testCaseArgs))