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

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • 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 
46 int timeout = 3000; // msec
47 
48 bool dbus_initialized = false;
49 
54 QString 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 
74 void
75 mac_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 
119 bool 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 
134 void 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 
188 QString 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
kdebug.h
QIODevice::errorString
QString errorString() const
kkernel_mac.h
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
timeout
int timeout
Definition: kkernel_mac.cpp:46
kconfig.h
QVarLengthArray::constData
const T * constData() const
QList::at
const T & at(int i) const
QVarLengthArray
QFile::exists
bool exists() const
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
QFile
dbus_initialized
bool dbus_initialized
Definition: kkernel_mac.cpp:48
QList::size
int size() const
QRegExp
QString::fromLocal8Bit
QString fromLocal8Bit(const char *str, int size)
QProcess
QString::isEmpty
bool isEmpty() const
ksharedconfig.h
QStringList::replaceInStrings
QStringList & replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
QString
mac_app_filename
QString mac_app_filename()
Get the application name.
Definition: kkernel_mac.cpp:188
QStringList
QString::toLocal8Bit
QByteArray toLocal8Bit() const
QLatin1Char
QLatin1String
kstandarddirs.h
QVarLengthArray::data
T * data()
QIODevice::setTextModeEnabled
void setTextModeEnabled(bool enabled)
QString::fromLatin1
QString fromLatin1(const char *str, int size)
kDebug
#define kDebug
Definition: kdebug.h:316
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
QFile::permissions
Permissions permissions() const
mac_initialize_dbus
void mac_initialize_dbus()
Make sure D-Bus is initialized, by any means necessary.
Definition: kkernel_mac.cpp:134
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
QProcess::exitCode
int exitCode() const
QProcess::start
void start(const QString &program, const QStringList &arguments, QFlags< QIODevice::OpenModeFlag > mode)
QFile::decodeName
QString decodeName(const QByteArray &localFileName)
QProcess::readAllStandardError
QByteArray readAllStandardError()
QIODevice::readLine
qint64 readLine(char *data, qint64 maxSize)
QProcess::waitForFinished
bool waitForFinished(int msecs)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:11 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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