summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorRobert Griebl <rgriebl@trolltech.com>2008-07-30 21:14:24 (GMT)
committerRobert Griebl <rgriebl@trolltech.com>2009-07-29 08:50:20 (GMT)
commitd7b688870aead912690188b324d370b920a7a600 (patch)
treeaac6c19d222ca3bad65cfbb850483a647013c67a /src/corelib/kernel
parente5262a0c29c743f2afd4ba249e8adff984c1ca83 (diff)
downloadQt-d7b688870aead912690188b324d370b920a7a600.zip
Qt-d7b688870aead912690188b324d370b920a7a600.tar.gz
Qt-d7b688870aead912690188b324d370b920a7a600.tar.bz2
Port of Qt to VxWorks
This makes Qt work on VxWorks 6.6+ in native (kernel) mode. * compiles with the WindRiver GNU toolchain (Linux only) * works with QWS (tested with the VNC driver only) * tested on PPC hardware and the x86 VxWorks simulator * no q3support, no phonon, no webkit * no QSharedMemory, no QSystemSemaphore, no QProcess * only one QApplication instance (flat address space) * filesystem support depends heavily on the quality of the native driver * QLibrary is just a dummy to make plugins work at all * qmake transparently creates VxWorks munching rules for static ctors * made auto-test cope with missing OS features A special note regarding the Q_FOREACH patch for dcc: when calling foreach(a,c) with c being a function returning a container, the compiler would generate 5 references to some labels (.LXXXX), which are not there (so the linker complains in the end). Seems like dcc doesn't really like the 'true ? 0 : <function call to get type>' statement Reviewed-By: Harald Fernengel
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/kernel.pri7
-rw-r--r--src/corelib/kernel/qcore_unix.cpp9
-rw-r--r--src/corelib/kernel/qcore_unix_p.h11
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp8
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp66
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h10
-rw-r--r--src/corelib/kernel/qfunctions_p.h2
-rw-r--r--src/corelib/kernel/qfunctions_vxworks.cpp202
-rw-r--r--src/corelib/kernel/qfunctions_vxworks.h153
9 files changed, 455 insertions, 13 deletions
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 8759578..7177293 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -112,3 +112,10 @@ unix {
contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri)
}
+vxworks {
+ SOURCES += \
+ kernel/qfunctions_vxworks.cpp
+ HEADERS += \
+ kernel/qfunctions_vxworks.h
+}
+
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index 28c1d9c..0bc03cd 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -41,8 +41,13 @@
#include "qcore_unix_p.h"
-#include <sys/select.h>
-#include <sys/time.h>
+#ifndef Q_OS_VXWORKS
+# include <sys/select.h>
+# include <sys/time.h>
+#else
+# include <selectLib.h>
+#endif
+
#include <stdlib.h>
#include "qeventdispatcher_unix_p.h" // for the timeval operators
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index bffd670..fb0e6a5 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -67,6 +67,10 @@
#include <errno.h>
#include <fcntl.h>
+#if defined(Q_OS_VXWORKS)
+# include <ioLib.h>
+#endif
+
struct sockaddr;
#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204
@@ -129,6 +133,7 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07
#undef QT_OPEN
#define QT_OPEN qt_safe_open
+#ifndef Q_OS_VXWORKS // no POSIX pipes in VxWorks
// don't call ::pipe
// call qt_safe_pipe
static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
@@ -164,6 +169,8 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
return 0;
}
+#endif // Q_OS_VXWORKS
+
// don't call dup or fcntl(F_DUPFD)
static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC)
{
@@ -238,6 +245,8 @@ static inline int qt_safe_close(int fd)
#undef QT_CLOSE
#define QT_CLOSE qt_safe_close
+#ifndef Q_OS_VXWORKS // no processes in VxWorks
+
static inline int qt_safe_execve(const char *filename, char *const argv[],
char *const envp[])
{
@@ -267,6 +276,8 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
return ret;
}
+#endif // Q_OS_VXWORKS
+
bool qt_gettime_is_monotonic();
timeval qt_gettime();
Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 706dc54..d0a4943 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -61,6 +61,7 @@
#include <private/qthread_p.h>
#include <qlibraryinfo.h>
#include <private/qfactoryloader_p.h>
+#include <private/qfunctions_p.h>
#ifdef Q_OS_UNIX
# if !defined(QT_NO_GLIB)
@@ -83,6 +84,10 @@
# include <locale.h>
#endif
+#ifdef Q_OS_VXWORKS
+# include <taskLib.h>
+#endif
+
QT_BEGIN_NAMESPACE
#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
@@ -1821,8 +1826,9 @@ qint64 QCoreApplication::applicationPid()
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
return GetCurrentProcessId();
+#elif defined(Q_OS_VXWORKS)
+ return (pid_t) taskIdCurrent;
#else
- // UNIX
return getpid();
#endif
}
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 2943c6d..51c7b9c 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -55,6 +55,16 @@
#include <stdio.h>
#include <stdlib.h>
+// VxWorks doesn't correctly set the _POSIX_... options
+#if defined(Q_OS_VXWORKS)
+# if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK <= 0)
+# undef _POSIX_MONOTONIC_CLOCK
+# define _POSIX_MONOTONIC_CLOCK 1
+# endif
+# include <pipeDrv.h>
+# include <selectLib.h>
+#endif
+
#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
# include <sys/times.h>
#endif
@@ -77,7 +87,7 @@ static void signalHandler(int sig)
}
-#ifdef Q_OS_INTEGRITY
+#if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS)
static void initThreadPipeFD(int fd)
{
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -98,20 +108,47 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
{
extern Qt::HANDLE qt_application_thread_id;
mainThread = (QThread::currentThreadId() == qt_application_thread_id);
+ bool pipefail = false;
// initialize the common parts of the event loop
-#ifdef Q_OS_INTEGRITY
+#if defined(Q_OS_INTEGRITY)
// INTEGRITY doesn't like a "select" on pipes, so use socketpair instead
- if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1)
+ if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) {
perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair");
-
- initThreadPipeFD(thread_pipe[0]);
- initThreadPipeFD(thread_pipe[1]);
+ pipefail = true;
+ } else {
+ initThreadPipeFD(thread_pipe[0]);
+ initThreadPipeFD(thread_pipe[1]);
+ }
+#elif defined(Q_OS_VXWORKS)
+ char name[20];
+ qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent));
+
+ // make sure there is no pipe with this name
+ pipeDevDelete(name, true);
+ // create the pipe
+ if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
+ perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe device");
+ pipefail = true;
+ } else {
+ if ((thread_pipe[0] = open(name, O_RDWR, 0)) < 0) {
+ perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
+ pipefail = true;
+ } else {
+ initThreadPipeFD(thread_pipe[0]);
+ thread_pipe[1] = thread_pipe[0];
+ }
+ }
#else
- if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1)
+ if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) {
perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
+ pipefail = true;
+ }
#endif
+ if (pipefail)
+ qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
+
sn_highest = -1;
interrupt = false;
@@ -119,9 +156,18 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate()
{
+#if defined(Q_OS_VXWORKS)
+ close(thread_pipe[0]);
+
+ char name[20];
+ qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent));
+
+ pipeDevDelete(name, true);
+#else
// cleanup the common parts of the event loop
close(thread_pipe[0]);
close(thread_pipe[1]);
+#endif
// cleanup timers
qDeleteAll(timerList);
@@ -226,9 +272,15 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags,
// select doesn't immediately return next time
int nevents = 0;
if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) {
+#if defined(Q_OS_VXWORKS)
+ char c[16];
+ ::read(thread_pipe[0], c, sizeof(c));
+ ::ioctl(thread_pipe[0], FIOFLUSH, 0);
+#else
char c[16];
while (::read(thread_pipe[0], c, sizeof(c)) > 0)
;
+#endif
if (!wakeUps.testAndSetRelease(1, 0)) {
// hopefully, this is dead code
qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAndSetRelease(1, 0) failed!");
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index 61d94c9..30d566d 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -59,9 +59,13 @@
#include "private/qpodlist_p.h"
#include <sys/types.h>
-#include <sys/time.h>
-#if !defined(Q_OS_HPUX) || defined(__ia64)
-#include <sys/select.h>
+#if defined(Q_OS_VXWORKS)
+# include <sys/times.h>
+#else
+# include <sys/time.h>
+# if !defined(Q_OS_HPUX) || defined(__ia64)
+# include <sys/select.h>
+# endif
#endif
#include <unistd.h>
diff --git a/src/corelib/kernel/qfunctions_p.h b/src/corelib/kernel/qfunctions_p.h
index a7f2f9d..ad44a15 100644
--- a/src/corelib/kernel/qfunctions_p.h
+++ b/src/corelib/kernel/qfunctions_p.h
@@ -57,6 +57,8 @@
#if defined(Q_OS_WINCE)
# include "QtCore/qfunctions_wince.h"
+#elif defined(Q_OS_VXWORKS)
+# include "QtCore/qfunctions_vxworks.h"
#endif
#ifdef Q_CC_RVCT
diff --git a/src/corelib/kernel/qfunctions_vxworks.cpp b/src/corelib/kernel/qfunctions_vxworks.cpp
new file mode 100644
index 0000000..6d5e7cc
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_vxworks.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#ifdef Q_OS_VXWORKS
+
+#include "qplatformdefs.h"
+#include "qfunctions_vxworks.h"
+
+#include <vmLib.h>
+#include <selectLib.h>
+#include <ioLib.h>
+
+QT_USE_NAMESPACE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// no lfind() - used by the TIF image format
+void *lfind(const void* key, const void* base, size_t* elements, size_t size,
+ int (*compare)(const void*, const void*))
+{
+ const char* current = (char*) base;
+ const char* const end = (char*) (current + (*elements) * size);
+ while (current != end) {
+ if (compare(current, key) == 0)
+ return (void*)current;
+ current += size;
+ }
+ return 0;
+}
+
+
+// no rand_r(), but rand()
+// NOTE: this implementation is wrong for multi threaded applications,
+// but there is no way to get it right on VxWorks (in kernel mode)
+int rand_r(unsigned int * /*seedp*/)
+{
+ return rand();
+}
+
+// no usleep() support
+int usleep(unsigned int usec)
+{
+ div_t dt = div(usec, 1000000);
+ struct timespec ts = { dt.quot, dt.rem * 1000 };
+
+ return nanosleep(&ts, 0);
+}
+
+
+// gettimeofday() is declared, but is missing from the library
+// It IS however defined in the Curtis-Wright X11 libraries, so
+// we have to make the symbol 'weak'
+#if defined(Q_CC_DIAB)
+# pragma weak gettimeofday
+#endif
+int gettimeofday(struct timeval *tv, void /*struct timezone*/ *)
+{
+ // the compiler will optimize this and will only use one code path
+ if (sizeof(struct timeval) == sizeof(struct timespec)) {
+ int res = clock_gettime(CLOCK_REALTIME, (struct timespec *) tv);
+ if (!res)
+ tv->tv_usec /= 1000;
+ return res;
+ } else {
+ struct timespec ts;
+
+ int res = clock_gettime(CLOCK_REALTIME, &ts);
+ if (!res) {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ }
+ return res;
+ }
+}
+
+// neither getpagesize() or sysconf(_SC_PAGESIZE) are available
+int getpagesize()
+{
+ return vmPageSizeGet();
+}
+
+// symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h)
+int symlink(const char *, const char *)
+{
+ errno = EIO;
+ return -1;
+}
+
+ssize_t readlink(const char *, char *, size_t)
+{
+ errno = EIO;
+ return -1;
+}
+
+// there's no truncate(), but ftruncate() support...
+int truncate(const char *path, off_t length)
+{
+ int fd = open(path, O_WRONLY, 00777);
+ if (fd >= 0) {
+ int res = ftruncate(fd, length);
+ int en = errno;
+ close(fd);
+ errno = en;
+ return res;
+ }
+ // errno is already set by open
+ return -1;
+}
+
+
+
+// VxWorks doesn't know about passwd & friends.
+// in order to avoid patching the unix fs path everywhere
+// we introduce some dummy functions that simulate a single
+// 'root' user on the system.
+
+uid_t getuid()
+{
+ return 0;
+}
+
+gid_t getgid()
+{
+ return 0;
+}
+
+uid_t geteuid()
+{
+ return 0;
+}
+
+struct passwd *getpwuid(uid_t uid)
+{
+ static struct passwd pwbuf = { "root", 0, 0, 0, 0, 0, 0 };
+
+ if (uid == 0) {
+ return &pwbuf;
+ } else {
+ errno = ENOENT;
+ return 0;
+ }
+}
+
+struct group *getgrgid(gid_t gid)
+{
+ static struct group grbuf = { "root", 0, 0, 0 };
+
+ if (gid == 0) {
+ return &grbuf;
+ } else {
+ errno = ENOENT;
+ return 0;
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // Q_OS_VXWORKS
diff --git a/src/corelib/kernel/qfunctions_vxworks.h b/src/corelib/kernel/qfunctions_vxworks.h
new file mode 100644
index 0000000..cc98948
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_vxworks.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFUNCTIONS_VXWORKS_H
+#define QFUNCTIONS_VXWORKS_H
+#ifdef Q_OS_VXWORKS
+
+#include <unistd.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <signal.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/times.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#ifndef QT_NO_IPV6IFNAME
+#include <net/if.h>
+#endif
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BUILD_CORE_LIB
+QT_MODULE(Core)
+#endif
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+
+#ifndef NSIG
+#define NSIG _NSIGS
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// isascii is missing (sometimes!!)
+#ifndef isascii
+inline int isascii(int c) { return (c & 0x7f); }
+#endif
+
+// no lfind() - used by the TIF image format
+void *lfind(const void* key, const void* base, size_t* elements, size_t size,
+ int (*compare)(const void*, const void*));
+
+// no rand_r(), but rand()
+// NOTE: this implementation is wrong for multi threaded applications,
+// but there is no way to get it right on VxWorks (in kernel mode)
+int rand_r(unsigned int * /*seedp*/);
+
+// no usleep() support
+int usleep(unsigned int);
+
+// gettimeofday() is declared, but is missing from the library.
+// It IS however defined in the Curtis-Wright X11 libraries, so
+// we have to make the symbol 'weak'
+int gettimeofday(struct timeval *tv, void /*struct timezone*/ *) __attribute__((weak));
+
+// neither getpagesize() or sysconf(_SC_PAGESIZE) are available
+int getpagesize();
+
+// symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h)
+int symlink(const char *, const char *);
+ssize_t readlink(const char *, char *, size_t);
+
+// there's no truncate(), but ftruncate() support...
+int truncate(const char *path, off_t length);
+
+// VxWorks doesn't know about passwd & friends.
+// in order to avoid patching the unix fs path everywhere
+// we introduce some dummy functions that simulate a single
+// 'root' user on the system.
+
+uid_t getuid();
+gid_t getgid();
+uid_t geteuid();
+
+struct passwd {
+ char *pw_name; /* user name */
+ char *pw_passwd; /* user password */
+ uid_t pw_uid; /* user ID */
+ gid_t pw_gid; /* group ID */
+ char *pw_gecos; /* real name */
+ char *pw_dir; /* home directory */
+ char *pw_shell; /* shell program */
+};
+
+struct group {
+ char *gr_name; /* group name */
+ char *gr_passwd; /* group password */
+ gid_t gr_gid; /* group ID */
+ char **gr_mem; /* group members */
+};
+
+struct passwd *getpwuid(uid_t uid);
+struct group *getgrgid(gid_t gid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // Q_OS_VXWORKS
+#endif // QFUNCTIONS_VXWORKS_H