summaryrefslogtreecommitdiffstats
path: root/qmake/qpopen.cpp
blob: 3b0e2dafcee6f298b225028dbcb06097e891d57a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $TROLLTECH_DUAL_LICENSE$
**
****************************************************************************/

#include "qpopen.h"


QPopen::QPopen()
{
}

bool QPopen::init(const char *command, const char* /* mode */)
{
    SECURITY_ATTRIBUTES attributes;

    attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
    attributes.bInheritHandle = TRUE;
    attributes.lpSecurityDescriptor = NULL;

    if (! CreatePipe(&childStdOutR, &childStdOutW, &attributes, 0)) {
        return false;
    }

    // Ensure that the read handle to the child process's pipe for STDOUT is not inherited.
    SetHandleInformation( childStdOutR, HANDLE_FLAG_INHERIT, 0);

    // Create a pipe for the child process's STDIN.
    if (! CreatePipe(&childStdInR, &childStdInW, &attributes, 0)) {
        return false;
    }

    // Ensure that the write handle to the child process's pipe for STDIN is not inherited.
    SetHandleInformation( childStdInW, HANDLE_FLAG_INHERIT, 0);

    //TCHAR szCmdline[strlen(command)]=TEXT(command);
    TCHAR *szCmdLine = new TCHAR[strlen(command)+1];
    strcpy(szCmdLine, command);

    // Set up members of the PROCESS_INFORMATION structure.

    ZeroMemory( &processInfo, sizeof(PROCESS_INFORMATION) );

    // Set up members of the STARTUPINFO structure.

    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.hStdError = childStdOutW;
    siStartInfo.hStdOutput = childStdOutW;
    siStartInfo.hStdInput = childStdInR;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

    // Create the child process.

    bool success = CreateProcess(NULL,
            szCmdLine,     // command line
            NULL,          // process security attributes
            NULL,          // primary thread security attributes
            TRUE,          // handles are inherited
            0,             // creation flags
            NULL,          // use parent's environment
            NULL,          // use parent's current directory
            &siStartInfo,  // STARTUPINFO pointer
            &processInfo);  // receives PROCESS_INFORMATION

    delete szCmdLine;

    return success;
}

QPopen::~QPopen()
{
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
    CloseHandle(childStdInR);
    CloseHandle(childStdInW);
    CloseHandle(childStdOutR);
    CloseHandle(childStdOutW);
}

int QPopen::fwrite(char* buffer, int maxBytes)
{
    DWORD bytesWritten;

    bool success = WriteFile(childStdInW, buffer, maxBytes, &bytesWritten, NULL);
    if(success) {
        return bytesWritten;
    }

    return 0;
}


int QPopen::fread(char* buffer, int maxBytes)
{
    DWORD bytesRead;

    if( !CloseHandle(childStdOutW) )
        return 0;

    bool success = ReadFile(childStdOutR, buffer, maxBytes, &bytesRead, NULL);
    if(success)
        return bytesRead;

    return 0;
}