• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • kernel
kkernel_mac.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDE libraries
3 Copyright (C) 2008 Benjamin Reed <rangerrick@befunk.com>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "kkernel_mac.h"
21
22#include <config.h>
23
24#ifdef Q_OS_MACX
25
26#include <unistd.h>
27#include <string.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <sys/param.h>
31#include <crt_externs.h>
32#include <mach-o/dyld.h>
33
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>
41#include <kstandarddirs.h>
42#include <ksharedconfig.h>
43#include <kconfig.h>
44#include <kdebug.h>
45
46int timeout = 3000; // msec
47
48bool dbus_initialized = false;
49
54QString convert_CFString_to_QString(CFStringRef str) {
55 CFIndex length = CFStringGetLength(str);
56 const UniChar *chars = CFStringGetCharactersPtr(str);
57 if (chars)
58 return QString(reinterpret_cast<const QChar *>(chars), length);
59
60 QVarLengthArray<UniChar> buffer(length);
61 CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
62 return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
63}
64
74void
75mac_fork_and_reexec_self()
76{
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;
84
85 for (int i = 0; i < argc; i++) {
86 newargv[i] = argv[i];
87 }
88
89 newargv[argc] = "--nofork";
90 newargv[argc+1] = NULL;
91
92 int x_fork_result = fork();
93 switch(x_fork_result) {
94
95 case -1:
96#ifndef NDEBUG
97 fprintf(stderr, "Mac OS X workaround fork() failed!\n");
98#endif
99 ::_exit(255);
100 break;
101
102 case 0:
103 // Child
104 execvp(progname, newargv);
105 break;
106
107 default:
108 // Parent
109 _exit(0);
110 break;
111
112 }
113}
114
119bool mac_set_dbus_address(QString value)
120{
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;
125 return true;
126 }
127 return false;
128}
129
134void mac_initialize_dbus()
135{
136 if (dbus_initialized)
137 return;
138
139 QString dbusVar = QString::fromLocal8Bit(qgetenv("DBUS_SESSION_BUS_ADDRESS"));
140 if (!dbusVar.isEmpty()) {
141 dbus_initialized = true;
142 return;
143 }
144
145 dbusVar = QFile::decodeName(qgetenv("DBUS_LAUNCHD_SESSION_BUS_SOCKET"));
146 if (mac_set_dbus_address(dbusVar)) {
147 dbus_initialized = true;
148 return;
149 }
150
151 QString externalProc;
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");
154
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;
159 break;
160 }
161 }
162
163 if (!externalProc.isEmpty()) {
164 QProcess qp;
165 qp.setTextModeEnabled(true);
166
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();
170 return;
171 }
172 if (qp.exitCode() != 0) {
173 kDebug() << externalProc << "unsuccessful:" << qp.readAllStandardError();
174 return;
175 }
176
177 QString line = QString::fromLatin1(qp.readLine()).trimmed(); // read the first line
178 if (mac_set_dbus_address(line))
179 dbus_initialized = true; // hooray
180 }
181
182 if (dbus_initialized == false) {
183 kDebug() << "warning: unable to initialize D-Bus environment!";
184 }
185
186}
187
188QString mac_app_filename() {
189 static QString appFileName;
190 if (appFileName.isEmpty()) {
191 CFURLRef bundleURL = NULL;
192 CFBundleRef bundle = NULL;
193 CFStringRef bundlePath = NULL;
194
195 bundle = CFBundleGetMainBundle();
196 if (bundle) {
197 bundleURL = CFBundleCopyBundleURL(bundle);
198 bundlePath = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
199
200 if (bundleURL) {
201 CFRelease(bundleURL);
202 }
203
204 if (bundlePath) {
205 appFileName = convert_CFString_to_QString(bundlePath);
206 CFRelease(bundlePath);
207 }
208 }
209 }
210 return appFileName;
211}
212
213#endif
QProcess
QStringList
QString
kDebug
#define kDebug
Definition: kdebug.h:316
kconfig.h
kdebug.h
mac_app_filename
QString mac_app_filename()
Get the application name.
Definition: kkernel_mac.cpp:188
mac_set_dbus_address
bool mac_set_dbus_address(QString value)
Set the D-Bus environment based on session bus socket.
Definition: kkernel_mac.cpp:119
timeout
int timeout
Definition: kkernel_mac.cpp:46
mac_initialize_dbus
void mac_initialize_dbus()
Make sure D-Bus is initialized, by any means necessary.
Definition: kkernel_mac.cpp:134
mac_fork_and_reexec_self
void mac_fork_and_reexec_self()
Calling CoreFoundation APIs (which is unavoidable in Qt/Mac) has always had issues on Mac OS X,...
Definition: kkernel_mac.cpp:75
convert_CFString_to_QString
QString convert_CFString_to_QString(CFStringRef str)
qAppFileName() is not public in qt4/mac, so we need to redo it here
Definition: kkernel_mac.cpp:54
dbus_initialized
bool dbus_initialized
Definition: kkernel_mac.cpp:48
kkernel_mac.h
ksharedconfig.h
kstandarddirs.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal