static void qt_create_symbian_commandline( const QStringList &arguments, const QString &nativeArguments, QString &commandLine) { for (int i = 0; i < arguments.size(); ++i) { QString tmp = arguments.at(i); // in the case of \" already being in the string the \ must also be escaped tmp.replace(QLatin1String("\\\""), QLatin1String("\\\\\"")); // escape a single " because the arguments will be parsed tmp.replace(QLatin1String("\""), QLatin1String("\\\"")); if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) { // The argument must not end with a \ since this would be interpreted // as escaping the quote -- rather put the \ behind the quote: e.g. // rather use "foo"\ than "foo\" QString endQuote(QLatin1String("\"")); int i = tmp.length(); while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\')) { --i; endQuote += QLatin1String("\\"); } commandLine += QLatin1String("\"") + tmp.left(i) + endQuote + QLatin1Char(' '); } else { commandLine += tmp + QLatin1Char(' '); } } if (!nativeArguments.isEmpty()) commandLine += nativeArguments; else if (!commandLine.isEmpty()) // Chop the extra trailing space if any arguments were appended commandLine.chop(1); }
static const char *getTok(const char *args, agxbuf * xb) { char c; int more = 1; args = skipWS(args); if (*args == '\0') return 0; while (more) { c = *args++; if (isspace(c)) more = 0; else if (c == '\0') { more = 0; args--; } else if ((c == '"') || (c == '\'')) { args = endQuote(args, xb, c); } else if (c == '\\') { c = *args++; if (c == '\0') args--; else agxbputc(xb, c); } else agxbputc(xb, c); } return args; }
QRUNINFO_NAMEPASE_BEGIN // taken from qprocess_win.cpp static QString qt_create_commandline(const QString &program, const QStringList &arguments) { QString args; if (!program.isEmpty()) { QString programName = program; if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) && programName.contains(QLatin1Char(' '))) { programName = QLatin1Char('\"') + programName + QLatin1Char('\"'); } programName.replace(QLatin1Char('/'), QLatin1Char('\\')); // add the program as the first arg ... it works better args = programName + QLatin1Char(' '); } for (int i = 0; i < arguments.size(); ++i) { QString tmp = arguments.at(i); // in the case of \" already being in the string the \ must also be escaped tmp.replace(QLatin1String("\\\""), QLatin1String("\\\\\"")); // escape a single " because the arguments will be parsed tmp.replace(QLatin1Char('\"'), QLatin1String("\\\"")); if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) { // The argument must not end with a \ since this would be interpreted // as escaping the quote -- rather put the \ behind the quote: e.g. // rather use "foo"\ than "foo\" QString endQuote(QLatin1Char('\"')); int i = tmp.length(); while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\')) { --i; endQuote += QLatin1Char('\\'); } args += QLatin1String(" \"") + tmp.left(i) + endQuote; } else { args += QLatin1Char(' ') + tmp; } } return args; }
QString AbstractProcess::createWinCommandline(const QString &program, const QStringList &args) { const QChar doubleQuote = QLatin1Char('"'); const QChar blank = QLatin1Char(' '); const QChar backSlash = QLatin1Char('\\'); QString programName = program; if (!programName.startsWith(doubleQuote) && !programName.endsWith(doubleQuote) && programName.contains(blank)) { programName.insert(0, doubleQuote); programName.append(doubleQuote); } // add the prgram as the first arrg ... it works better programName.replace(QLatin1Char('/'), backSlash); QString cmdLine = programName; if (args.empty()) return cmdLine; cmdLine += blank; for (int i = 0; i < args.size(); ++i) { QString tmp = args.at(i); // in the case of \" already being in the string the \ must also be escaped tmp.replace(QLatin1String("\\\""), QLatin1String("\\\\\"")); // escape a single " because the arguments will be parsed tmp.replace(QString(doubleQuote), QLatin1String("\\\"")); if (tmp.isEmpty() || tmp.contains(blank) || tmp.contains('\t')) { // The argument must not end with a \ since this would be interpreted // as escaping the quote -- rather put the \ behind the quote: e.g. // rather use "foo"\ than "foo\" QString endQuote(doubleQuote); int i = tmp.length(); while (i > 0 && tmp.at(i - 1) == backSlash) { --i; endQuote += backSlash; } cmdLine += QLatin1String(" \""); cmdLine += tmp.left(i); cmdLine += endQuote; } else { cmdLine += blank; cmdLine += tmp; } } return cmdLine; }
QString CAuthHelperTest::create_commandline ( const QString& program, const QStringList& arguments ) { QString programName = program; if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) && programName.contains(" ")) programName = "\"" + programName + "\""; programName.replace("/", "\\"); QString args; // add the prgram as the first arrg ... it works better args = programName + " "; for (int i=0; i<arguments.size(); ++i) { QString tmp = arguments.at(i); // in the case of \" already being in the string // the \ must also be escaped tmp.replace( "\\\"", "\\\\\"" ); // escape a single " because the arguments will be parsed tmp.replace( "\"", "\\\"" ); if (tmp.isEmpty() || tmp.contains(' ') || tmp.contains('\t')) { // The argument must not end with a \ since this would be // interpreted as escaping the quote -- rather put the \ behind // the quote: e.g. rather use "foo"\ than "foo\" QString endQuote("\""); int i = tmp.length(); while (i>0 && tmp.at(i-1) == '\\') { --i; endQuote += "\\"; } args += QString(" \"") + tmp.left(i) + endQuote; } else { args += ' ' + tmp; } } return args; }
bool Q3Process::start( QStringList *env ) { #if defined(QT_Q3PROCESS_DEBUG) qDebug( "Q3Process::start()" ); #endif reset(); if ( _arguments.isEmpty() ) return false; // Open the pipes. Make non-inheritable copies of input write and output // read handles to avoid non-closable handles (this is done by the // DuplicateHandle() call). SECURITY_ATTRIBUTES secAtt = { sizeof( SECURITY_ATTRIBUTES ), NULL, TRUE }; #ifndef Q_OS_WINCE // I guess there is no stdin stdout and stderr on Q_OS_WINCE to dup // CreatePipe and DupilcateHandle aren't available for Q_OS_WINCE HANDLE tmpStdin, tmpStdout, tmpStderr; if ( comms & Stdin ) { if ( !CreatePipe( &d->pipeStdin[0], &tmpStdin, &secAtt, 0 ) ) { d->closeHandles(); return false; } if ( !DuplicateHandle( GetCurrentProcess(), tmpStdin, GetCurrentProcess(), &d->pipeStdin[1], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { d->closeHandles(); return false; } if ( !CloseHandle( tmpStdin ) ) { d->closeHandles(); return false; } } if ( comms & Stdout ) { if ( !CreatePipe( &tmpStdout, &d->pipeStdout[1], &secAtt, 0 ) ) { d->closeHandles(); return false; } if ( !DuplicateHandle( GetCurrentProcess(), tmpStdout, GetCurrentProcess(), &d->pipeStdout[0], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { d->closeHandles(); return false; } if ( !CloseHandle( tmpStdout ) ) { d->closeHandles(); return false; } } if ( comms & Stderr ) { if ( !CreatePipe( &tmpStderr, &d->pipeStderr[1], &secAtt, 0 ) ) { d->closeHandles(); return false; } if ( !DuplicateHandle( GetCurrentProcess(), tmpStderr, GetCurrentProcess(), &d->pipeStderr[0], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) { d->closeHandles(); return false; } if ( !CloseHandle( tmpStderr ) ) { d->closeHandles(); return false; } } if ( comms & DupStderr ) { CloseHandle( d->pipeStderr[1] ); d->pipeStderr[1] = d->pipeStdout[1]; } #endif // construct the arguments for CreateProcess() QString args; QString appName; QStringList::Iterator it = _arguments.begin(); args = *it; ++it; if ( args.endsWith( QLatin1String(".bat") ) && args.contains( QLatin1Char(' ') ) ) { // CreateProcess() seems to have a strange semantics (see also // http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_11138647.html): // If you start a batch file with spaces in the filename, the first // argument to CreateProcess() must be the name of the batchfile // without quotes, but the second argument must start with the same // argument with quotes included. But if the same approach is used for // .exe files, it doesn't work. appName = args; args = QLatin1Char('"') + args + QLatin1Char('"'); } for ( ; it != _arguments.end(); ++it ) { QString tmp = *it; // escape a single " because the arguments will be parsed tmp.replace( QLatin1String("\""), QLatin1String("\\\"") ); if ( tmp.isEmpty() || tmp.contains( QLatin1Char(' ') ) || tmp.contains( QLatin1Char('\t') ) ) { // The argument must not end with a \ since this would be interpreted // as escaping the quote -- rather put the \ behind the quote: e.g. // rather use "foo"\ than "foo\" QString endQuote( QLatin1String("\"") ); int i = tmp.length(); while ( i>0 && tmp.at( i-1 ) == QLatin1Char('\\') ) { --i; endQuote += QLatin1String("\\"); } args += QString( QLatin1String(" \"") ) + tmp.left( i ) + endQuote; } else { args += QLatin1Char(' ') + tmp; } } #if defined(QT_Q3PROCESS_DEBUG) qDebug( "Q3Process::start(): args [%s]", args.latin1() ); #endif // CreateProcess() bool success; d->newPid(); #ifdef UNICODE if (!(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)) { STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, 0, 0, 0, STARTF_USESTDHANDLES, 0, 0, 0, d->pipeStdin[0], d->pipeStdout[1], d->pipeStderr[1] }; TCHAR *applicationName; if ( appName.isNull() ) applicationName = 0; else applicationName = _wcsdup( (TCHAR*)appName.ucs2() ); TCHAR *commandLine = _wcsdup( (TCHAR*)args.ucs2() ); QByteArray envlist; if ( env != 0 ) { int pos = 0; // add PATH if necessary (for DLL loading) QByteArray path = qgetenv( "PATH" ); if ( env->grep( QRegExp(QLatin1String("^PATH="),FALSE) ).empty() && !path.isNull() ) { QString tmp = QString( QLatin1String("PATH=%1") ).arg(QString::fromLatin1(path.constData())); uint tmpSize = sizeof(TCHAR) * (tmp.length()+1); envlist.resize( envlist.size() + tmpSize ); memcpy( envlist.data()+pos, tmp.ucs2(), tmpSize ); pos += tmpSize; } // add the user environment for ( QStringList::Iterator it = env->begin(); it != env->end(); it++ ) { QString tmp = *it; uint tmpSize = sizeof(TCHAR) * (tmp.length()+1); envlist.resize( envlist.size() + tmpSize ); memcpy( envlist.data()+pos, tmp.ucs2(), tmpSize ); pos += tmpSize; } // add the 2 terminating 0 (actually 4, just to be on the safe side) envlist.resize( envlist.size()+4 ); envlist[pos++] = 0; envlist[pos++] = 0; envlist[pos++] = 0; envlist[pos++] = 0; } success = CreateProcessW( applicationName, commandLine, 0, 0, TRUE, ( comms==0 ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW ) #ifndef Q_OS_WINCE | CREATE_UNICODE_ENVIRONMENT #endif , env==0 ? 0 : envlist.data(), (TCHAR*)QDir::toNativeSeparators(workingDir.absPath()).ucs2(), &startupInfo, d->pid ); free( applicationName ); free( commandLine ); } else #endif // UNICODE { #ifndef Q_OS_WINCE STARTUPINFOA startupInfo = { sizeof( STARTUPINFOA ), 0, 0, 0, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, 0, 0, 0, STARTF_USESTDHANDLES, 0, 0, 0, d->pipeStdin[0], d->pipeStdout[1], d->pipeStderr[1] }; QByteArray envlist; if ( env != 0 ) { int pos = 0; // add PATH if necessary (for DLL loading) QByteArray path = qgetenv( "PATH" ); if ( env->grep( QRegExp(QLatin1String("^PATH="),FALSE) ).empty() && !path.isNull() ) { Q3CString tmp = QString( QLatin1String("PATH=%1") ).arg(QString::fromLatin1(path.constData())).local8Bit(); uint tmpSize = tmp.length() + 1; envlist.resize( envlist.size() + tmpSize ); memcpy( envlist.data()+pos, tmp.data(), tmpSize ); pos += tmpSize; } // add the user environment for ( QStringList::Iterator it = env->begin(); it != env->end(); it++ ) { Q3CString tmp = (*it).local8Bit(); uint tmpSize = tmp.length() + 1; envlist.resize( envlist.size() + tmpSize ); memcpy( envlist.data()+pos, tmp.data(), tmpSize ); pos += tmpSize; } // add the terminating 0 (actually 2, just to be on the safe side) envlist.resize( envlist.size()+2 ); envlist[pos++] = 0; envlist[pos++] = 0; } char *applicationName; if ( appName.isNull() ) applicationName = 0; else applicationName = const_cast<char *>(appName.toLocal8Bit().data()); success = CreateProcessA( applicationName, const_cast<char *>(args.toLocal8Bit().data()), 0, 0, TRUE, comms==0 ? CREATE_NEW_CONSOLE : DETACHED_PROCESS, env==0 ? 0 : envlist.data(), (const char*)QDir::toNativeSeparators(workingDir.absPath()).local8Bit(), &startupInfo, d->pid ); #endif // Q_OS_WINCE } if ( !success ) { d->deletePid(); return false; } #ifndef Q_OS_WINCE if ( comms & Stdin ) CloseHandle( d->pipeStdin[0] ); if ( comms & Stdout ) CloseHandle( d->pipeStdout[1] ); if ( (comms & Stderr) && !(comms & DupStderr) ) CloseHandle( d->pipeStderr[1] ); #endif if ( ioRedirection || notifyOnExit ) { d->lookup->start( 100 ); } // cleanup and return return true; }