Console System("") Question

Hi,

I am attempting to write a program that calls other programs and process the output of it.

in my test case i am calling a never ending ping, when i then exit the ping by typing ctrl+c the program crashes.

1
2
3
4
5
6
7
8
9
10
11
12
  #include <iostream>
#include <Windows.h>

int main()
{
	std::cout << "test" << std::endl;

	int tmp = system("ping google.nl -t");

	std::cin.get();
	return 0;
}


i thought it might be because i am not handling the input the correct way but even if i try and catch the event it crashes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <Windows.h>

BOOL WINAPI ConsoleHandlerRoutine(DWORD dwCtrlType)
{
	if (dwCtrlType == CTRL_C_EVENT)
	{
		return false;
	}

	return true;
}

int main()
{
	BOOL ret = SetConsoleCtrlHandler(ConsoleHandlerRoutine, TRUE);

	std::cout << "test" << std::endl;

	int tmp = system("ping google.nl -t");

	std::cin.get();
	return 0;
}


i am pretty sure it happens in a place where i have no control over seeing the place the error is produced.
 
First-chance exception at 0x767122CB (KernelBase.dll) in TestConsoleStuff.exe: 0x40010005: Control-C.


so my question is what am i doing wrong? heck am i even going the right direction to get what i want?
What exactly is the problem? When you press Ctrl+C program instantly terminates returning some unsuccesfull error code. It is exactly what are you seeing. You can disable ctrl-c combination or set handler for it (Actually now you handle everything aside the ctrl+c events), but you said you want to use it in your program.

Generally speaking, if you want to tie the output of a child process to the input of your process then you'll want to start the child with one of the "CreateProcess()" functions. Set the 'bInheritHandles' parameter to 'TRUE' and for the STARTUPINFO struct, you'll want to set the appropriate values for 'hStdInput' and 'hStdOutput' which you grab with "GetStdHandle()".

Like MiiNiPaa said though, the behavior you are seeing is exactly what should be happening. You should probably not use a continuous ping.

That is all generically speaking though. If all you want is a built in ping function then using "ICMPSendEcho()" isn't that difficult:
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
bool Ping(std::string SiteName)
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);


    addrinfo* AddrInfo = NULL;

    addrinfo hints;
        memset(&hints, 0, sizeof(addrinfo));
        hints.ai_family     = AF_INET;
        hints.ai_socktype   = SOCK_STREAM;
        hints.ai_protocol   = IPPROTO_TCP;
        hints.ai_flags      = AI_PASSIVE;

    if(getaddrinfo(SiteName.c_str(), "http", &hints, &AddrInfo) != ERROR_SUCCESS)
    {
        WSACleanup();
        return false;
    }

    sockaddr_in* AddrIn = reinterpret_cast<sockaddr_in*>(AddrInfo->ai_addr);
    std::string dotAddress = inet_ntoa(AddrIn->sin_addr);

    HANDLE ICMPHandle = IcmpCreateFile();
    IPAddr IPAddress = inet_addr(dotAddress.c_str());

    bool Return = true;

    char Data[100];
        sprintf_s(Data, 100, "Data");

    unsigned DataBufferSize = sizeof(Data);
    DWORD DataSize;

    const unsigned EchoArraySize = 25;
    ICMP_ECHO_REPLY Echo[EchoArraySize];
    DWORD EchoSize = (sizeof(ICMP_ECHO_REPLY) * EchoArraySize);

    DWORD EchoResult = IcmpSendEcho(ICMPHandle, IPAddress, Data, DataBufferSize, NULL, Echo, EchoSize, 3000);

    if(EchoResult == 0)
    {
        //std::cout << "Echo Result: " << EchoResult << "\n";
		WSACleanup();
        Return = false;
    }

    CloseHandle(ICMPHandle);
    WSACleanup();

    //std::cout << "Echo Result: " << EchoResult << "\n";
    return Return;
}

You'll have to link to "Iphlpapi.lib", "Ws2_32.lib" and I believe "advapi32.lib" as well. The headers to include are: "Icmpapi.h" and "Winsock2.h". If you try to compile this and you get any errors let me know, I may have deleted more then I should have.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
#include <cstdlib>
#include <iostream>

int main()
{
    std::cout << "test" << std::endl;

    int tmp = system("ping google.com");

    std::cin.get();
    return 0;
}


I tested the above on my arch linux machine and it worked as expected. I pressed ctrl+c, then I pressed enter, and the program exited without error.
@ kevinkjt2000: I'm glad to hear that your apple is not in fact an orange. OP wants to process the output of the child process, which is something that the "system()" function does not provide a mechanism for.
@Computergeek01: I was merely demonstrating that ctrl+c worked as the OP expected on my machine. Perhaps the OP would be interested knowing that the orange did work on my system. I am not in any way implying that this is how to process output of a child process, but just merely taking the OP's code and showing that I did see the hoped for results that were described in the first post.
Last edited on
Hello thanks for the replies. Computergeek01: I think the first part of your post is what i want, i will see if i can get working what i want. i will post my code if and when i get it working, for now some research is in order.

everyone else thanks for taking the time to read and attempt to help I really appreciate it.
Ok, an update.

i have been testing a lot of things but because i could not figure out what is causing my problem i thought i would make a dummy program to test if it even works.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <Windows.h>
#include <iostream>

int main()
{
	while (true)
	{
		Sleep(1000);
		std::cout << "test" << std::endl;
	}

	return 0;
}


even this simple code manages to crash when i press Ctrl+c with the message
First-chance exception at 0x767122CB (KernelBase.dll) in TestConsoleStuff.exe: 0x40010005: Control-C.

now the thing is i don't understand what this means can any one clarify?

even when i set "SetConsoleCtrlHandler" i get the message, if i then press continue it goes into the function and does what it should

Edit:
http://stackoverflow.com/questions/13206911/why-getting-first-chace-exception-in-c
oh it seems its visual studio that is causing my problems, so part one of my problem is solved now for part two. stay tuned...

Last edited on
Pressing Ctrl-c is sending your program signal to immideately abort. This is abnormal termination, so it is seen as such by caller (probably debugger in your case).

What are you trying to do by pressing Ctrl+c in first place?

Your question is like "Why my clothes gets wet if I put them in water?" or "Why my PC is rebooting when I press reset?"
Hehe Yes and no, if you have never experienced water it is weird right ;}

ok i will explain my train of thought, i am working on a game of sorts that is built around the console. it will require you to call other programs to find out information. whenever i do anything in the console lets say my internet is not working i open the command prompt and run a ping after the first reply i know i have connection then i pres ctrl+c and go to my next program to see why its not working. I use it often so when calling a ping inside an other console program i want to be able to close the one but leave the other open simple as that.
I use it often so when calling a ping inside an other console program i want to be able to close the one but leave the other open simple as that.
Spawn it as another process, as Computergeek01 suggested.
MiiNiPaa: yep working on it ;} hehe.
Topic archived. No new replies allowed.