54 #include <private/qwineventnotifier_p.h> 55 #include <private/qthread_p.h> 58 #include "private/qfsfileengine_p.h" 67 #define NOTIFYTIMEOUT 100 75 #if !defined(Q_OS_WINCE) 76 SECURITY_ATTRIBUTES secAtt = {
sizeof( SECURITY_ATTRIBUTES ), NULL,
TRUE };
80 if (!CreatePipe(&pipe[0], &tmpHandle, &secAtt, 1024 * 1024))
82 if (!DuplicateHandle(GetCurrentProcess(), tmpHandle, GetCurrentProcess(),
83 &pipe[1], 0,
FALSE, DUPLICATE_SAME_ACCESS))
86 if (!CreatePipe(&tmpHandle, &pipe[1], &secAtt, 1024 * 1024))
88 if (!DuplicateHandle(GetCurrentProcess(), tmpHandle, GetCurrentProcess(),
89 &pipe[0], 0,
FALSE, DUPLICATE_SAME_ACCESS))
93 CloseHandle(tmpHandle);
110 return DuplicateHandle(GetCurrentProcess(),
stdoutChannel.
pipe[1], GetCurrentProcess(),
121 SECURITY_ATTRIBUTES secAtt = {
sizeof(SECURITY_ATTRIBUTES), NULL,
TRUE };
129 FILE_SHARE_READ | FILE_SHARE_WRITE,
132 FILE_ATTRIBUTE_NORMAL,
138 q->setErrorString(
QProcess::tr(
"Could not open input redirection for reading"));
145 FILE_SHARE_READ | FILE_SHARE_WRITE,
147 channel.append ? OPEN_ALWAYS : CREATE_ALWAYS,
148 FILE_ATTRIBUTE_NORMAL,
152 if (channel.append) {
153 SetFilePointer(channel.pipe[1], 0, NULL, FILE_END);
158 q->setErrorString(
QProcess::tr(
"Could not open output redirection for writing"));
167 Q_ASSERT_X(channel.process,
"QProcess::start",
"Internal error");
175 sink = &channel.process->stdinChannel;
180 HANDLE tmpHandle = source->pipe[1];
181 if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
182 GetCurrentProcess(), &source->pipe[1],
183 0,
TRUE, DUPLICATE_SAME_ACCESS))
186 CloseHandle(tmpHandle);
194 sink->pipe[0] = source->pipe[0];
200 source = &channel.process->stdoutChannel;
206 HANDLE tmpHandle = sink->pipe[0];
207 if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
208 GetCurrentProcess(), &sink->pipe[0],
209 0,
TRUE, DUPLICATE_SAME_ACCESS))
212 CloseHandle(tmpHandle);
219 source->pipe[1] = sink->pipe[1];
235 CloseHandle(pipe[0]);
239 CloseHandle(pipe[1]);
252 programName.
replace(QLatin1Char(
'/'), QLatin1Char(
'\\'));
255 args = programName + QLatin1Char(
' ');
258 for (
int i=0; i<arguments.
size(); ++i) {
280 #if !defined(Q_OS_WINCE) 283 if (
wchar_t *envStrings = GetEnvironmentStringsW()) {
284 for (
const wchar_t *entry = envStrings; *entry; ) {
285 int entryLen = wcslen(entry);
287 if (
const wchar_t *
equal = wcschr(entry + 1, L
'=')) {
288 int nameLen =
equal - entry;
293 entry += entryLen + 1;
295 FreeEnvironmentStringsW(envStrings);
301 #if !defined(Q_OS_WINCE) 328 static const wchar_t equal = L
'=';
329 static const wchar_t nul = L
'\0';
331 for ( ; it !=
end; ++
it) {
332 uint tmpSize =
sizeof(wchar_t) * (it.key().length() + it.value().length() + 2);
334 if (tmpSize ==
sizeof(
wchar_t) * 2)
338 tmpSize = it.key().length() *
sizeof(wchar_t);
339 memcpy(envlist.
data()+
pos, it.key().utf16(), tmpSize);
343 pos +=
sizeof(wchar_t);
345 tmpSize = it.value().length() *
sizeof(wchar_t);
346 memcpy(envlist.
data()+
pos, it.value().utf16(), tmpSize);
349 memcpy(envlist.
data()+
pos, &nul,
sizeof(wchar_t));
350 pos +=
sizeof(wchar_t);
367 bool success =
false;
370 CloseHandle(
pid->hThread);
371 CloseHandle(
pid->hProcess);
375 pid =
new PROCESS_INFORMATION;
376 memset(
pid, 0,
sizeof(PROCESS_INFORMATION));
385 #if defined(Q_OS_WINCE) 390 if (environment.
d.constData())
391 envlist = qt_create_environment(environment.
d.constData()->hash);
399 #if defined QPROCESS_DEBUG 400 qDebug(
"Creating process");
403 qDebug(
" pass environment : %s", environment.
isEmpty() ?
"no" :
"yes");
406 #if defined(Q_OS_WINCE) 411 success = CreateProcess((
wchar_t*)fullPathProgram.utf16(),
412 (
wchar_t*)args.
utf16(),
413 0, 0,
false, 0, 0, 0, 0,
pid);
416 dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
417 STARTUPINFOW startupInfo = {
sizeof( STARTUPINFO ), 0, 0, 0,
421 STARTF_USESTDHANDLES,
425 success = CreateProcess(0, (
wchar_t*)args.
utf16(),
426 0, 0,
TRUE, dwCreationFlags,
487 DWORD bytesAvail = 0;
488 #if !defined(Q_OS_WINCE) 490 #if defined QPROCESS_DEBUG 491 qDebug(
"QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail);
497 HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
499 DWORD bytesWritten = 0;
500 WriteFile(hStdout, buf.
data(), bytesRead, &bytesWritten, 0);
514 DWORD bytesAvail = 0;
515 #if !defined(Q_OS_WINCE) 517 #if defined QPROCESS_DEBUG 518 qDebug(
"QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail);
524 HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
526 DWORD bytesWritten = 0;
527 WriteFile(hStderr, buf.
data(), bytesRead, &bytesWritten, 0);
559 DWORD currentProcId = 0;
560 GetWindowThreadProcessId(hwnd, ¤tProcId);
561 if (currentProcId == (DWORD)procId)
562 PostMessage(hwnd, WM_CLOSE, 0, 0);
571 PostThreadMessage(
pid->dwThreadId, WM_CLOSE, 0, 0);
578 TerminateProcess(
pid->hProcess, 0xf291);
592 q->setErrorString(
QProcess::tr(
"Process operation timed out"));
600 #if defined(Q_OS_WINCE) 602 q->setErrorString(
QProcess::tr(
"Error reading from process"));
614 bool readyReadEmitted =
false;
625 if (readyReadEmitted)
642 q->setErrorString(
QProcess::tr(
"Process operation timed out"));
650 #if defined(Q_OS_WINCE) 652 q->setErrorString(
QProcess::tr(
"Error reading from process"));
673 if (!pendingDataInPipe) {
717 q->setErrorString(
QProcess::tr(
"Process operation timed out"));
725 #if defined QPROCESS_DEBUG 726 qDebug(
"QProcessPrivate::waitForFinished(%d)", msecs);
759 q->setErrorString(
QProcess::tr(
"Process operation timed out"));
767 if (GetExitCodeProcess(
pid->hProcess, &theExitCode)) {
790 #if defined(Q_OS_WINCE) 792 q->setErrorString(
QProcess::tr(
"Error writing to process"));
813 q->setErrorString(
QProcess::tr(
"Process operation timed out"));
836 #if defined(Q_OS_WINCE) 843 bool success =
false;
845 PROCESS_INFORMATION pinfo;
847 #if defined(Q_OS_WINCE) 852 success = CreateProcess((
wchar_t*)fullPathProgram.
utf16(),
853 (
wchar_t*)args.
utf16(),
854 0, 0,
false, CREATE_NEW_CONSOLE, 0, 0, 0, &pinfo);
856 STARTUPINFOW startupInfo = {
sizeof( STARTUPINFO ), 0, 0, 0,
859 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
861 success = CreateProcess(0, (
wchar_t*)args.
utf16(),
862 0, 0,
FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE, 0,
863 workingDir.
isEmpty() ? 0 : (
wchar_t*)workingDir.
utf16(),
864 &startupInfo, &pinfo);
868 CloseHandle(pinfo.hThread);
869 CloseHandle(pinfo.hProcess);
871 *pid = pinfo.dwProcessId;
879 #endif // QT_NO_PROCESS static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
The QProcessEnvironment class holds the environment variables that can be passed to a program...
bool _q_canReadStandardOutput()
QBool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
qint64 write(const char *data, qint64 maxlen)
QString qt_error_string(int errorCode)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
static QString fromLocal8Bit(const char *, int size=-1)
Returns a QString initialized with the first size characters of the 8-bit string str.
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
#define QT_END_NAMESPACE
This macro expands to.
char * data()
Returns a pointer to the data stored in the byte array.
const QChar at(int i) const
Returns the character at the given index position in the string.
The QRegExp class provides pattern matching using regular expressions.
static bool isAbsolutePath(const QString &path)
Returns true if path is absolute; returns false if it is relative.
#define it(className, varName)
QString & replace(int i, int len, QChar after)
The QByteArray class provides an array of bytes.
qint64 bytesAvailableFromStdout() const
int length() const
Returns the number of characters in this string.
QString & prepend(QChar c)
QProcess::ProcessState processState
const_iterator ConstIterator
Qt-style synonym for QHash::const_iterator.
static bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory=QString(), qint64 *pid=0)
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
QString absoluteFilePath() const
Returns an absolute path including the file name.
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QSharedDataPointer< QProcessEnvironmentPrivate > d
The QString class provides a Unicode character string.
static QString currentPath()
Returns the absolute path of the application's current directory.
QProcessEnvironment environment
qint64 bytesAvailableFromStderr() const
qint64 writeToStdin(const char *data, qint64 maxlen)
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
static QString longFileName(const QString &path)
bool waitForReadyRead(int msecs=30000)
bool waitForWrite(int msecs=30000)
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Q_CORE_EXPORT void qDebug(const char *,...)
QWindowsPipeWriter * pipeWriter
qint64 bytesToWrite() const
qint64 readFromStdout(char *data, qint64 maxlen)
#define QT_BEGIN_NAMESPACE
This macro expands to.
bool waitForStarted(int msecs=30000)
QProcess::ProcessError processError
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
const T & at(int i) const
Returns the item at index position i in the list.
The QStringList class provides a list of strings.
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
static const char * data(const QByteArray &arr)
bool _q_startupNotification()
#define FALSE
Synonym for false.
static QProcessEnvironment systemEnvironment()
The systemEnvironment function returns the environment of the calling process.
QProcess::ProcessChannelMode processChannelMode
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
qint64 readFromStderr(char *data, qint64 maxlen)
static void qt_create_pipe(Q_PIPE *pipe, bool in)
#define TRUE
Synonym for true.
const char * constData() const
Returns a pointer to the data stored in the byte array.
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
#define Q_ASSERT_X(cond, where, what)
bool waitForBytesWritten(int msecs=30000)
void start(Priority=InheritPriority)
Begins execution of the thread by calling run().
bool waitForFinished(int msecs=30000)
void resize(int size)
Sets the size of the byte array to size bytes.
int size() const
Returns the number of items in the list.
qint64 pipeWriterBytesToWrite() const
int size() const
Returns the number of bytes in this byte array.
bool waitForWrite(int msecs)
bool _q_canReadStandardError()
bool createChannel(Channel &channel)
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
QWinEventNotifier * processFinishedNotifier
The QTimer class provides repetitive and single-shot timers.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
The QFileInfo class provides system-independent file information.
void destroyPipe(Q_PIPE pipe[2])
static const KeyPair *const end
static QString toNativeSeparators(const QString &pathName)
Returns pathName with the '/' separators converted to separators that are appropriate for the underly...
void stop()
Stops the timer.
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
QString & insert(int i, QChar c)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
QAbstractEventDispatcher * eventDispatcher
void setEnabled(bool enable)
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
The QProcess class is used to start external programs and to communicate with them.
static bool equal(const QChar *a, int l, const char *b)
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
static QString qt_create_commandline(const QString &program, const QStringList &arguments)
#define forever
This macro is provided for convenience for writing infinite loops.