Qt 4.8
Classes | Macros | Functions
qcore_unix_p.h File Reference
#include "qplatformdefs.h"
#include "qatomic.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>

Go to the source code of this file.

Classes

union  qt_semun
 

Macros

#define _POSIX_MONOTONIC_CLOCK   -1
 
#define EINTR_LOOP(var, cmd)
 
#define QT_CLOSE   qt_safe_close
 
#define QT_OPEN   qt_safe_open
 
#define QT_READ   qt_safe_read
 
#define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC   0
 
#define QT_WRITE   qt_safe_write
 

Functions

timeval & normalizedTimeval (timeval &t)
 
timeval operator* (const timeval &t1, int mul)
 
timeval operator+ (const timeval &t1, const timeval &t2)
 
timeval & operator+= (timeval &t1, const timeval &t2)
 
timeval operator- (const timeval &t1, const timeval &t2)
 
bool operator< (const timeval &t1, const timeval &t2)
 
bool operator== (const timeval &t1, const timeval &t2)
 
timeval qt_gettime ()
 
void qt_ignore_sigpipe ()
 
static int qt_safe_close (int fd)
 
static int qt_safe_dup (int oldfd, int atleast=0, int flags=FD_CLOEXEC)
 
static int qt_safe_dup2 (int oldfd, int newfd, int flags=FD_CLOEXEC)
 
static int qt_safe_execv (const char *path, char *const argv[])
 
static int qt_safe_execve (const char *filename, char *const argv[], char *const envp[])
 
static int qt_safe_execvp (const char *file, char *const argv[])
 
static int qt_safe_open (const char *pathname, int flags, mode_t mode=0777)
 
static int qt_safe_pipe (int pipefd[2], int flags=0)
 
static qint64 qt_safe_read (int fd, void *data, qint64 maxlen)
 
Q_CORE_EXPORT int qt_safe_select (int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, const struct timeval *tv)
 
static pid_t qt_safe_waitpid (pid_t pid, int *status, int options)
 
static qint64 qt_safe_write (int fd, const void *data, qint64 len)
 
static qint64 qt_safe_write_nosignal (int fd, const void *data, qint64 len)
 

Macro Definition Documentation

◆ _POSIX_MONOTONIC_CLOCK

#define _POSIX_MONOTONIC_CLOCK   -1

Definition at line 343 of file qcore_unix_p.h.

◆ EINTR_LOOP

#define EINTR_LOOP (   var,
  cmd 
)

◆ QT_CLOSE

#define QT_CLOSE   qt_safe_close

◆ QT_OPEN

#define QT_OPEN   qt_safe_open

◆ QT_READ

#define QT_READ   qt_safe_read

◆ QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC

#define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC   0

Definition at line 93 of file qcore_unix_p.h.

◆ QT_WRITE

#define QT_WRITE   qt_safe_write

Function Documentation

◆ normalizedTimeval()

timeval& normalizedTimeval ( timeval &  t)
inline

Definition at line 104 of file qcore_unix_p.h.

Referenced by operator*(), operator+(), operator+=(), operator-(), and QTimerInfoList::updateCurrentTime().

105 {
106  while (t.tv_usec > 1000000l) {
107  ++t.tv_sec;
108  t.tv_usec -= 1000000l;
109  }
110  while (t.tv_usec < 0l) {
111  --t.tv_sec;
112  t.tv_usec += 1000000l;
113  }
114  return t;
115 }
QFactoryLoader * l

◆ operator*()

timeval operator* ( const timeval &  t1,
int  mul 
)
inline

Definition at line 140 of file qcore_unix_p.h.

Referenced by QVector< QPoint >::constData().

141 {
142  timeval tmp;
143  tmp.tv_sec = t1.tv_sec * mul;
144  tmp.tv_usec = t1.tv_usec * mul;
145  return normalizedTimeval(tmp);
146 }
timeval & normalizedTimeval(timeval &t)
Definition: qcore_unix_p.h:104

◆ operator+()

timeval operator+ ( const timeval &  t1,
const timeval &  t2 
)
inline

◆ operator+=()

timeval& operator+= ( timeval &  t1,
const timeval &  t2 
)
inline

◆ operator-()

timeval operator- ( const timeval &  t1,
const timeval &  t2 
)
inline

Definition at line 133 of file qcore_unix_p.h.

Referenced by QVector< QPoint >::constData(), QPainterPath::swap(), and QRegion::xored().

134 {
135  timeval tmp;
136  tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1);
137  tmp.tv_usec = t1.tv_usec - (t2.tv_usec + 1000000);
138  return normalizedTimeval(tmp);
139 }
timeval & normalizedTimeval(timeval &t)
Definition: qcore_unix_p.h:104

◆ operator<()

bool operator< ( const timeval &  t1,
const timeval &  t2 
)
inline

Definition at line 116 of file qcore_unix_p.h.

117 { return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); }

◆ operator==()

bool operator== ( const timeval &  t1,
const timeval &  t2 
)
inline

Definition at line 118 of file qcore_unix_p.h.

119 { return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; }

◆ qt_gettime()

timeval qt_gettime ( )

Definition at line 74 of file qelapsedtimer_mac.cpp.

Referenced by qt_safe_select(), QTimerInfoList::QTimerInfoList(), QEventDispatcherBlackberry::select(), time_update(), and QTimerInfoList::updateCurrentTime().

75 {
76  timeval tv;
77 
78  uint64_t cpu_time = mach_absolute_time();
79  uint64_t nsecs = absoluteToNSecs(cpu_time);
80  tv.tv_sec = nsecs / 1000000000ull;
81  tv.tv_usec = (nsecs / 1000) - (tv.tv_sec * 1000000);
82  return tv;
83 }
static qint64 absoluteToNSecs(qint64 cpuTime)

◆ qt_ignore_sigpipe()

void qt_ignore_sigpipe ( )
inline

Definition at line 148 of file qcore_unix_p.h.

Referenced by qt_safe_sendto(), and qt_safe_write_nosignal().

149 {
150 #ifndef Q_NO_POSIX_SIGNALS
151  // Set to ignore SIGPIPE once only.
153  if (!atom) {
154  // More than one thread could turn off SIGPIPE at the same time
155  // But that's acceptable because they all would be doing the same
156  // action
157  struct sigaction noaction;
158  memset(&noaction, 0, sizeof(noaction));
159  noaction.sa_handler = SIG_IGN;
160  ::sigaction(SIGPIPE, &noaction, 0);
161  atom = 1;
162  }
163 #else
164  // Posix signals are not supported by the underlying platform
165  // so we don't need to ignore sigpipe signal explicitly
166 #endif
167 }
#define Q_BASIC_ATOMIC_INITIALIZER(a)
Definition: qbasicatomic.h:218
int sigaction(int, const struct sigaction *, struct sigaction *)

◆ qt_safe_close()

static int qt_safe_close ( int  fd)
inlinestatic

◆ qt_safe_dup()

static int qt_safe_dup ( int  oldfd,
int  atleast = 0,
int  flags = FD_CLOEXEC 
)
inlinestatic

Definition at line 227 of file qcore_unix_p.h.

Referenced by QDnotifyFileSystemWatcherEngine::addPaths(), QUnixSocketRights::dupFd(), QUnixSocketRights::QUnixSocketRights(), and QDBusUnixFileDescriptor::setFileDescriptor().

228 {
229  Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
230 
231  register int ret;
232 #ifdef F_DUPFD_CLOEXEC
233  // use this fcntl
234  if (flags & FD_CLOEXEC) {
235  ret = ::fcntl(oldfd, F_DUPFD_CLOEXEC, atleast);
236  if (ret != -1 || errno != EINVAL)
237  return ret;
238  }
239 #endif
240 
241  // use F_DUPFD
242  ret = ::fcntl(oldfd, F_DUPFD, atleast);
243 
244  if (flags && ret != -1)
245  ::fcntl(ret, F_SETFD, flags);
246  return ret;
247 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
int fcntl(int, int,...)
int errno

◆ qt_safe_dup2()

static int qt_safe_dup2 ( int  oldfd,
int  newfd,
int  flags = FD_CLOEXEC 
)
inlinestatic

Definition at line 251 of file qcore_unix_p.h.

Referenced by QProcessPrivate::execChild().

252 {
253  Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
254 
255  register int ret;
256 #if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC)
257  // use dup3
258  if (flags & FD_CLOEXEC) {
259  EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC));
260  if (ret == 0 || errno != ENOSYS)
261  return ret;
262  }
263 #endif
264  EINTR_LOOP(ret, ::dup2(oldfd, newfd));
265  if (ret == -1)
266  return -1;
267 
268  if (flags)
269  ::fcntl(newfd, F_SETFD, flags);
270  return 0;
271 }
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
int fcntl(int, int,...)
int errno

◆ qt_safe_execv()

static int qt_safe_execv ( const char *  path,
char *const  argv[] 
)
inlinestatic

Definition at line 317 of file qcore_unix_p.h.

Referenced by QProcessPrivate::startDetached().

318 {
319  register int ret;
320  EINTR_LOOP(ret, ::execv(path, argv));
321  return ret;
322 }
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96

◆ qt_safe_execve()

static int qt_safe_execve ( const char *  filename,
char *const  argv[],
char *const  envp[] 
)
inlinestatic

Definition at line 309 of file qcore_unix_p.h.

Referenced by QProcessPrivate::execChild().

311 {
312  register int ret;
313  EINTR_LOOP(ret, ::execve(filename, argv, envp));
314  return ret;
315 }
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96

◆ qt_safe_execvp()

static int qt_safe_execvp ( const char *  file,
char *const  argv[] 
)
inlinestatic

Definition at line 324 of file qcore_unix_p.h.

Referenced by QProcessPrivate::execChild().

325 {
326  register int ret;
327  EINTR_LOOP(ret, ::execvp(file, argv));
328  return ret;
329 }
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96

◆ qt_safe_open()

static int qt_safe_open ( const char *  pathname,
int  flags,
mode_t  mode = 0777 
)
inlinestatic

Definition at line 171 of file qcore_unix_p.h.

Referenced by QKqueueFileSystemWatcherEngine::addPaths(), QProcessPrivate::createChannel(), QSharedMemoryPrivate::createUnixKeyFile(), detectProcessorFeatures(), QBBSystemLocaleData::QBBSystemLocaleData(), QBBNavigatorEventNotifier::start(), and QBBButtonEventNotifier::start().

172 {
173 #ifdef O_CLOEXEC
174  flags |= O_CLOEXEC;
175 #endif
176  register int fd;
177  EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode));
178 
179  // unknown flags are ignored, so we have no way of verifying if
180  // O_CLOEXEC was accepted
181  if (fd != -1)
182  ::fcntl(fd, F_SETFD, FD_CLOEXEC);
183  return fd;
184 }
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96
int fcntl(int, int,...)
#define QT_OPEN
Definition: qcore_unix_p.h:186

◆ qt_safe_pipe()

static int qt_safe_pipe ( int  pipefd[2],
int  flags = 0 
)
inlinestatic

Definition at line 191 of file qcore_unix_p.h.

Referenced by QPdfBaseEnginePrivate::openPrintDevice(), QDnotifySignalThread::QDnotifySignalThread(), QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate(), QProcessManager::QProcessManager(), qt_create_pipe(), and QProcessPrivate::startDetached().

192 {
193 #ifdef O_CLOEXEC
194  Q_ASSERT((flags & ~(O_CLOEXEC | O_NONBLOCK)) == 0);
195 #else
196  Q_ASSERT((flags & ~O_NONBLOCK) == 0);
197 #endif
198 
199  register int ret;
200 #if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC)
201  // use pipe2
202  flags |= O_CLOEXEC;
203  ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR
204  if (ret == 0 || errno != ENOSYS)
205  return ret;
206 #endif
207 
208  ret = ::pipe(pipefd);
209  if (ret == -1)
210  return -1;
211 
212  ::fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);
213  ::fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
214 
215  // set non-block too?
216  if (flags & O_NONBLOCK) {
217  ::fcntl(pipefd[0], F_SETFL, ::fcntl(pipefd[0], F_GETFL) | O_NONBLOCK);
218  ::fcntl(pipefd[1], F_SETFL, ::fcntl(pipefd[1], F_GETFL) | O_NONBLOCK);
219  }
220 
221  return 0;
222 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
int fcntl(int, int,...)
int errno

◆ qt_safe_read()

static qint64 qt_safe_read ( int  fd,
void *  data,
qint64  maxlen 
)
inlinestatic

◆ qt_safe_select()

Q_CORE_EXPORT int qt_safe_select ( int  nfds,
fd_set *  fdread,
fd_set *  fdwrite,
fd_set *  fdexcept,
const struct timeval *  tv 
)

Definition at line 73 of file qcore_unix.cpp.

Referenced by QNativeSocketEnginePrivate::nativeSelect(), SelectWorker::run(), QEventDispatcherUNIX::select(), and select_msecs().

75 {
76  if (!orig_timeout) {
77  // no timeout -> block forever
78  register int ret;
79  EINTR_LOOP(ret, select(nfds, fdread, fdwrite, fdexcept, 0));
80  return ret;
81  }
82 
83  timeval start = qt_gettime();
84  timeval timeout = *orig_timeout;
85 
86  // loop and recalculate the timeout as needed
87  int ret;
88  forever {
89  ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeout);
90  if (ret != -1 || errno != EINTR)
91  return ret;
92 
93  // recalculate the timeout
94  if (!time_update(&timeout, start, *orig_timeout)) {
95  // timeout during update
96  // or clock reset, fake timeout error
97  return 0;
98  }
99  }
100 }
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *)
timeval qt_gettime()
int errno
static bool time_update(struct timeval *tv, const struct timeval &start, const struct timeval &timeout)
Definition: qcore_unix.cpp:63
#define forever
This macro is provided for convenience for writing infinite loops.
Definition: qglobal.h:2452

◆ qt_safe_waitpid()

static pid_t qt_safe_waitpid ( pid_t  pid,
int *  status,
int  options 
)
inlinestatic

Definition at line 333 of file qcore_unix_p.h.

Referenced by QProcessPrivate::startDetached(), and QProcessPrivate::waitForDeadChild().

334 {
335  register int ret;
336  EINTR_LOOP(ret, ::waitpid(pid, status, options));
337  return ret;
338 }
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96
static LibLoadStatus status
Definition: qlocale_icu.cpp:69

◆ qt_safe_write()

static qint64 qt_safe_write ( int  fd,
const void *  data,
qint64  len 
)
inlinestatic

Definition at line 282 of file qcore_unix_p.h.

Referenced by QProcessManager::catchDeadChildren(), QProcessPrivate::execChild(), QProcessPrivate::processStarted(), qfswd_sigio_monitor(), qt_sa_sigchld_sigaction(), qt_safe_write_nosignal(), QProcessPrivate::startDetached(), QEventDispatcherUNIX::wakeUp(), and QProcessManager::~QProcessManager().

283 {
284  qint64 ret = 0;
285  EINTR_LOOP(ret, QT_WRITE(fd, data, len));
286  return ret;
287 }
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96
static const char * data(const QByteArray &arr)
__int64 qint64
Definition: qglobal.h:942
#define QT_WRITE
Definition: qcore_unix_p.h:289

◆ qt_safe_write_nosignal()

static qint64 qt_safe_write_nosignal ( int  fd,
const void *  data,
qint64  len 
)
inlinestatic

Definition at line 291 of file qcore_unix_p.h.

Referenced by QNativeSocketEnginePrivate::nativeWrite(), and QProcessPrivate::writeToStdin().

292 {
294  return qt_safe_write(fd, data, len);
295 }
void qt_ignore_sigpipe()
Definition: qcore_unix_p.h:148
static const char * data(const QByteArray &arr)
static qint64 qt_safe_write(int fd, const void *data, qint64 len)
Definition: qcore_unix_p.h:282