30 #include <sys/param.h>
31 #include <crt_externs.h>
32 #include <mach-o/dyld.h>
34 #include <CoreFoundation/CFBundle.h>
35 #include <CoreFoundation/CFString.h>
36 #include <CoreFoundation/CFURL.h>
37 #include <QtCore/QFile>
38 #include <QtCore/QProcess>
39 #include <QtCore/QStringList>
40 #include <QtCore/qvarlengtharray.h>
55 CFIndex length = CFStringGetLength(str);
56 const UniChar *chars = CFStringGetCharactersPtr(str);
58 return QString(reinterpret_cast<const QChar *>(chars), length);
60 QVarLengthArray<UniChar> buffer(length);
61 CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
62 return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
77 int argc = *_NSGetArgc();
78 char ** argv = *_NSGetArgv();
79 char * newargv[argc+2];
80 char progname[PATH_MAX];
81 uint32_t buflen = PATH_MAX;
82 _NSGetExecutablePath(progname, &buflen);
83 bool found_psn =
false;
85 for (
int i = 0; i < argc; i++) {
89 newargv[argc] =
"--nofork";
90 newargv[argc+1] = NULL;
92 int x_fork_result = fork();
93 switch(x_fork_result) {
97 fprintf(stderr,
"Mac OS X workaround fork() failed!\n");
104 execvp(progname, newargv);
121 if (!value.isEmpty() && QFile::exists(value) && (QFile::permissions(value) & QFile::WriteUser)) {
122 value = QLatin1String(
"unix:path=") + value;
123 ::setenv(
"DBUS_SESSION_BUS_ADDRESS", value.toLocal8Bit(), 1);
124 kDebug() <<
"set session bus address to" << value;
136 if (dbus_initialized)
139 QString dbusVar = QString::fromLocal8Bit(qgetenv(
"DBUS_SESSION_BUS_ADDRESS"));
140 if (!dbusVar.isEmpty()) {
141 dbus_initialized =
true;
145 dbusVar = QFile::decodeName(qgetenv(
"DBUS_LAUNCHD_SESSION_BUS_SOCKET"));
147 dbus_initialized =
true;
152 QStringList path = QFile::decodeName(qgetenv(
"KDEDIRS")).split(QLatin1Char(
':')).replaceInStrings(QRegExp(QLatin1String(
"$")), QLatin1String(
"/bin"));
153 path << QFile::decodeName(qgetenv(
"PATH")).split(QLatin1Char(
':')) << QLatin1String(
"/usr/local/bin");
155 for (
int i = 0; i < path.size(); ++i) {
156 QString testLaunchctl =
QString(path.at(i)).append(QLatin1String(
"/launchctl"));
157 if (QFile(testLaunchctl).exists()) {
158 externalProc = testLaunchctl;
163 if (!externalProc.isEmpty()) {
165 qp.setTextModeEnabled(
true);
167 qp.start(externalProc,
QStringList() << QLatin1String(
"getenv") << QLatin1String(
"DBUS_LAUNCHD_SESSION_BUS_SOCKET"));
168 if (!qp.waitForFinished(
timeout)) {
169 kDebug() <<
"error running" << externalProc << qp.errorString();
172 if (qp.exitCode() != 0) {
173 kDebug() << externalProc <<
"unsuccessful:" << qp.readAllStandardError();
177 QString line = QString::fromLatin1(qp.readLine()).trimmed();
179 dbus_initialized =
true;
182 if (dbus_initialized ==
false) {
183 kDebug() <<
"warning: unable to initialize D-Bus environment!";
190 if (appFileName.isEmpty()) {
191 CFURLRef bundleURL = NULL;
192 CFBundleRef bundle = NULL;
193 CFStringRef bundlePath = NULL;
195 bundle = CFBundleGetMainBundle();
197 bundleURL = CFBundleCopyBundleURL(bundle);
198 bundlePath = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
201 CFRelease(bundleURL);
206 CFRelease(bundlePath);
void mac_fork_and_reexec_self()
Calling CoreFoundation APIs (which is unavoidable in Qt/Mac) has always had issues on Mac OS X...
QString mac_app_filename()
Get the application name.
bool mac_set_dbus_address(QString value)
Set the D-Bus environment based on session bus socket.
void mac_initialize_dbus()
Make sure D-Bus is initialized, by any means necessary.
QString convert_CFString_to_QString(CFStringRef str)
qAppFileName() is not public in qt4/mac, so we need to redo it here