int CreateSocket()
{
// SOCKET connectedSocket;
// SOCKADDR_IN addr;
// char buf[256];
// char buf2[300];
// Winsock starten
HANDLE h1,h2,h3;
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster ;
long rc;
SOCKET acceptSocket;
rc=startWinsock();
if(rc!=0)
{
printf("Fehler: startWinsock, fehler code: %d\n",rc);
return 1;
}
else
{
printf("Winsock gestartet!\n");
}
// Socket erstellen
acceptSocket=socket(AF_INET,SOCK_STREAM,0);
if(acceptSocket==INVALID_SOCKET)
{
printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("Socket erstellt!\n");
}
memset(&addr,0,sizeof(SOCKADDR_IN));
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
if(rc==SOCKET_ERROR)
{
printf("Fehler: bind, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("Socket an port %d gebunden\n",port);
}
rc=listen(acceptSocket,10);
if(rc==SOCKET_ERROR)
{
printf("Fehler: listen, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("acceptSocket ist im listen Modus....\n");
}
connectedSocket=accept(acceptSocket,NULL,NULL);
if(connectedSocket==INVALID_SOCKET)
{
printf("Fehler: accept, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("Neue Verbindung wurde akzeptiert!\n");
// strcpy(buf,"Hallo wie gehts?");
// rc=send(acceptSocket,buf,9,0);
// Daten austauschen
while(rc!=SOCKET_ERROR)
{
rc=recv(connectedSocket,buf,256,0);
if(rc==0)
{
printf("Server hat die Verbindung getrennt..\n");
break;
}
if(rc==SOCKET_ERROR)
{
printf("Fehler: recv, fehler code: %d\n",WSAGetLastError());
break;
}
XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );
h1=TimerTask(2,TASK1,&Task2ms_Raster);
h2=TimerTask(10,TASK2,&Task10ms_Raster);
h3=TimerTask(100,TASK3,&Task100ms_Raster);
}
}
closesocket(acceptSocket);
closesocket(connectedSocket);
XcpIp_OnTcpCxnClosed((uint16) port );
WSACleanup();
return 0;
}
The above code is a server code and accepts a connection from the client via the ip address and port number. I am accepting the connection and recieving the data from the client. I want to run the TimerTask in the background, timer task is calling a function called TASK1, TASK2 and TASK3 for every 2ms , 10ms and 100ms. So how to run those function in the background. Please someone help me.
If you want to make things run in parallel, you can use threads for Multithreading, or forks for multiprocessing.
Here's an example for multithreading in c:
#include <pthread.h>
void handleClient(SOCKET clientSock)
{
... read and write ...
}
int main()
{
... prepare the server ...
... listen on socket ...
for(;;){
connectedSocket=accept(acceptSocket,NULL,NULL);
pthread_t *tid = malloc( sizeof(pthread_t) );
pthread_create( &tid, NULL, handleClient, connectSocket );
... test, if the server should be killed, and break the loop ...
}
}
Notice, that this is a very minimalistic example. You should also care about "collecting your threads" with pthread_join( tid, NULL );, thus you have to store all your pthread_t-Variables inside an Array or a linked list.
Related
I have a raspberry pi that connects to a TCP server and sends some data every couple of seconds, I want to be able to handle all kind of failures and disconnects, so at the moment I am trying a test where I disconnect the Huawei USB dongle that I am connecting through.
I have a thread that runs in the background and check the connection periodically. The code does not reconnect when I remove the USB dongle and plug it back in sometime later, I need help on how to make this more robust. At the moment on the server side I see that after I plug back in the USB dongle I see the client connect but immediately disconnect from it.
The thread is called KeepSocketOpen and inside here I call a ping function to 8.8.8.8 to see if the connection is still active and here is my code, I'm kind of new to socket programming so excuse the mess:
int ping(char *ipaddr)
{
char *command = NULL;
FILE *fp;
int x, match=0;
char* result = NULL;
size_t len = 0;
asprintf (&command, "%s %s -p 50 -r 3", "fping", ipaddr);
//printf ("%s %s -q 2>&1", "fping", ipaddr);
fp = popen(command, "r");
if (fp == NULL) {
fprintf(stderr, "Failed to execute fping command\n");
free(command);
return -1;
}
while(getline(&result, &len, fp) != -1) {
fputs(result, stdout);
//printf("%s",result);
}
for(x=0;x<len;x++)
{
if(x>5 && result[x]=='e'&& result[x-1]=='v'&& result[x-2]=='i'&& result[x-3]=='l'&& result[x-4]=='a')
{
match=1;
break;
}
}
if(match==0)
sleep(5);
free(result);
fflush(fp);
if (pclose(fp) != 0) {
perror("Cannot close stream.\n");
}
free(command);
//printf("%s\r\n",result);
if(match==0)
return -1;
else
return 1;
}
void* KeepSocketOpen(void *arg)
{
pthread_t id= pthread_self();
char tcprxbuff[1024];
int numbytes, status=0,attempts,reuse=1;
struct timeval timeout={0};
timeout.tv_sec=10;
timeout.tv_usec=0;
printf("in sock thread\r\n");
while(1)
{
if(is_socket_connected==0)
{
sock=socket(AF_INET,SOCK_STREAM,0);
addr.sin_family = AF_INET;
addr.sin_port = htons(34879);
addr.sin_addr.s_addr=inet_addr("X.X.X.X");
attempts=0;
setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout));
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout));
setsockopt(sock, SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));
status=connect(sock, (struct sockaddr *) &addr,sizeof (addr));
// wait for 5s and see if the socket has connected
do
{
delay(5);
}
while(errno && attempts++<1000);
if (attempts >=1000 || errno) // this is the fail case
{
printf("socket not connected %s\r\n",strerror(errno));
is_socket_connected=0;
close(sock);
//shutdown(sock,SHUT_RDWR);
sleep(30);
}
else
{
// fcntl(sock, F_SETFL, O_NONBLOCK);
printf("socket reconnected %d,%s\r\n",attempts,strerror(errno));
is_socket_connected=1;
write(sock, "HI FROM RASPI", strlen("HI FROM RASPI"));
}
}
else
{
numbytes=read(sock,tcprxbuff,sizeof(tcprxbuff));
if(numbytes==0)// if this is zero, socket was closed by server
{
is_socket_connected=0;
while(close(sock)==-1);
}
else
{
printf("socket connected:%d\r\n",numbytes);
status = ping("8.8.8.8");
if (status!=-1) {
printf("socket still connected:%d\r\n",status);
is_socket_connected=1;
} else {
printf("socket disconnected:%d\r\n",status);
is_socket_connected=0;
//shutdown(sock,SHUT_RDWR);
while(close(sock)==-1);
}
}
sleep(30);
}
}
}
void main()
{
HANDLE h1,h2,h3;
uint8 data;
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster ;
CreateSocket();
XCP_FN_TYPE Xcp_Initialize( );
while(1)
{
data = recv(fd, recv_data, 99, 0);
if (data == SOCKET_ERROR) {
printf("recv failed with error %d\n", WSAGetLastError());
}
else
{
pChunkData = &recv_data;
chunkLen = sizeof(pChunkData);
XcpIp_RxCallback ((uint16) chunkLen, (char*) pChunkData, (uint16) port);
}
}
h1=TimerTask(2,TASK1,&Task2ms_Raster);
h2=TimerTask(10,TASK2,&Task10ms_Raster);
h3=TimerTask(100,TASK3,&Task100ms_Raster);
XCP_FN_TYPE XcpIp_OnTcpCxnClosed( port );
}
I have created the server socket and recieving data from the client via the ip address and the port number. I have to run the timer task in parallel with the recieve data from the socket.The function definition of create scoket and TimerTask functionality is not shown. So could anyone please help me how to run the timer task parallel to it ??
I have developed a chat server program using threads. In this program there are two threads:
One to receive data
One to send data
Both of the threads contain the infinite loop in order to continuously send and receive data. But when it is executed the thread for receiving data gets stuck in the loop.
The code of the server:
{
addr_len=sizeof(cli_addr);
cli_sock=accept(sock,(struct sockaddr *)&cli_addr,&addr_len);
if(cli_sock<0)
printf("\nConnetion Error\n");
else
printf("conneted\n");
status_s=pthread_create(&thread_s,NULL,send_data,&cli_sock);
if(status_s==0)
printf("sending");
status_r=pthread_create(&thread_r,NULL,recieve_data,&cli_sock);
if(status_r==0)
printf("recieving");
}
}
void *recieve_data(void *num)
{
int *sock_r=(int *) num;
int sock=*sock_r;
char msg[50];
while(1)
{
recv(sock_r,msg,sizeof(msg),0);
if(strcmp(msg,"exit")==0)
{
break;
}
printf("recieved data:");
recv(sock_r,msg,sizeof(msg),0);
printf("\n%s",msg);
}
}
void *send_data(void *num)
{
int *sock_s=(int *) num;
int sock=*sock_s;
char msg[50];
while(1)
{
gets(msg);
//printf("sending data");
if(strcmp(msg,"exit")==0)
{
break;
}
send(sock_s,msg,sizeof(msg),0);
}
send(sock,msg,sizeof(msg),0);
}
Would be better if control commands like "exit" are int based.
Also, receive data doesn't handle peer connection closure status. Ex:
Copied from here.
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while( iResult > 0 );
I am new to this website so I do appologize in advance if this question has been answered before though I have searched it before opening it to everyone here.
I am using socket programming in one of my C program. It has server and client modules where sever and client can communicate in both directions. Program is working fine as I am able to send files and messages in both directions.
My server program is using port 3873 and I have confirmed this with netstat -anp | grep 3873
I have observed one weird behaviour with socket especially when I try to connect socket using browser such as http://localhost:3873 or telnet localhost 3873. It immediately closed socket and subsequent 'netstat -anp | grep 3873' output confirms that localhost is no longer listening on the port 3873.
I would really appreciate if someone can shed light on this behavior. Is it expected behavior?
Here is relevant section from the server code: Main program initiate a dedicated thread and calls startFileServerMT, which subsequent calls handleClient to service each client connected to server on the socket
int handleClient(void *ptr){
DEBUG("Inside the %s %s() \n",__FILE__,__func__);
int connectSOCKET;
connectSOCKET = (int ) ptr;
char recvBUFF[4096],sendBUFF[4096];
char *filename;
FILE * recvFILE;
char *header[4096];
while(1){
if( recv(connectSOCKET, recvBUFF, sizeof(recvBUFF), 0) > 0){
if(!strncmp(recvBUFF,"FBEGIN",6)) {
recvBUFF[strlen(recvBUFF) - 2] = 0;
parseArgs(header,recvBUFF);
filename = (char*) strngDup(header[1]);
DEBUG(" About to receive file: %s\n", filename);
}
char *rfile = ALLOC(sizeof(char) * (strlen(This.uploadDIR) + strlen(filename) + 35));
strcpy(rfile,This.uploadDIR);
if (strngLastChar(rfile) == '/'){
strcat(rfile,filename);
}else{
strcat(rfile,"/");
strcat(rfile,filename);
}
DEBUG(" Absolute file is : %s\n", rfile);
recvBUFF[0] = 0;
if ((recvFILE = fopen (rfile,"w" )) == NULL){
LogError("Server could not create file %s on the shared location %s.\n",filename,This.uploadDIR);
}else{
bzero(recvBUFF,4096);
int fr_block_sz, write_sz;
while((fr_block_sz = recv(connectSOCKET, recvBUFF, 512, 0)) > 0 ){
write_sz = fwrite (recvBUFF , sizeof(recvBUFF[0]) , fr_block_sz , recvFILE );
DEBUG(" Received buffer is : %s\n", recvBUFF);
if(write_sz < fr_block_sz){
LogError("Failed writing file %s on the Server shared location.\n",filename);
break;
}
bzero(recvBUFF,4096);
recvBUFF[0] = 0;
if(write_sz == 0 || fr_block_sz != 512 ){
break;
}
}
if(fr_block_sz < 0){
if(errno == EAGAIN){
LogError("Server collection file %s receive timed out.\n",filename);
}else{
LogError("Failed file %s transfer due to error %d\n",filename,errno);
fclose(recvFILE);
FREE(rfile);
// Start - Following code send failed status to client
sprintf(sendBUFF,"FSTATUS:FAILED\r\n");
if (send(connectSOCKET, sendBUFF, sizeof(sendBUFF), 0) >= 0){
DEBUG("File transfer status for file %s sent\n",filename);
}else{
DEBUG("Failed sending transfer status for file %s\n",filename);
return FALSE;
}
// End
close(connectSOCKET);
return FALSE;
}
}
DEBUG("File %s received on OM Server successfully.\n",filename);
// Start - Following code send failed status to client
sprintf(sendBUFF,"FSTATUS:SUCCESS\r\n");
if (send(connectSOCKET, sendBUFF, sizeof(sendBUFF), 0) >= 0){
DEBUG("File transfer status for file %s sent\n",filename);
}else{
DEBUG("Failed sending transfer status for file %s\n",filename);
return FALSE;
}
// End
fclose(recvFILE);
updateTargets(rfile);
FREE(rfile);
close(connectSOCKET);
break;
}
}
else {
LogInfo("Client dropped connection\n");
}
/** End*/
return TRUE;
}
}
int startFileServerMT(){
DEBUG("Inside %s %s() \n",__FILE__,__func__);
int listenSOCKET, connectSOCKET[512],thread_status;
int socketINDEX = 0;
pthread_t clientFileThread[512];
socklen_t clientADDRESSLENGTH[512];
struct sockaddr_in clientADDRESS[512], serverADDRESS;
if((listenSOCKET = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
LogAbortError("File server could not create socket.\n");
close(listenSOCKET);
return FALSE;
}
serverADDRESS.sin_family = AF_INET;
serverADDRESS.sin_addr.s_addr = htonl(INADDR_ANY);
serverADDRESS.sin_port = htons(This.serverport);
if (bind(listenSOCKET, (struct sockaddr *) &serverADDRESS, sizeof(serverADDRESS)) < 0) {
LogAbortError("File server could not bind socket and will stop server now.\n");
close(listenSOCKET);
This.stopped = TRUE;
return FALSE;
}
if(listen(listenSOCKET, 5) == -1){
LogAbortError("Server failed to listen on port %d and will stop server now.\n",This.serverport);
close(listenSOCKET);
This.stopped = TRUE;
return FALSE;
}else{
LogInfo("Server listening on port %d successfully.\n",This.serverport);
}
clientADDRESSLENGTH[socketINDEX] = sizeof(clientADDRESS[socketINDEX]);
while(TRUE){
// DEBUG(" Inside the file server main loop index[%d].\n",socketINDEX);
connectSOCKET[socketINDEX] = accept(listenSOCKET, (struct sockaddr *) &clientADDRESS[socketINDEX], &clientADDRESSLENGTH[socketINDEX]);
if(connectSOCKET[socketINDEX] < 0){
LogError("Server could not accept connection.\n");
close(listenSOCKET);
return FALSE;
}else
DEBUG(" Another client connected to server socket.\n");
ThreadCreateDetached( &clientFileThread[socketINDEX], handleClient, connectSOCKET[socketINDEX]);
if(socketINDEX=512) {
socketINDEX = 0;
} else {
socketINDEX++;
}
if (This.stopped == TRUE){
close(listenSOCKET);
return TRUE;
}
/** End*/
// return TRUE;
}
close(listenSOCKET);
return TRUE;
}
This is your problem - or at least a part of your problem. It's not only an off-by-one error (connectSOCKET accepts indices from 0-511 inclusive so if you're at 512, you've already written past the end of the connectSOCKET array) but you do an assignment instead of a comparison:
if(socketINDEX=512) { // Error: you are *setting* socketINDEX to 512,
// then immediately *resetting* it back to 0. So
// every new connection overrides the existing
// socket.
socketINDEX = 0;
} else {
socketINDEX++;
}
As a sidenote, you really ought to refactor your code and try to clean it up.
Here is server code i took from microsoft. Below it is my main which needs to run void important_code(bool);. I have always had this problem when using pipes and sockets on both linux and windows.
How do i exit the select() when i want to quit my app? Assume important_code is always executed on the same thread after the socket code. How would i do that?
I know this is windows code but i get this problem under linux as well
bonus test code: If you comment out main2() in my main function and uncomment the loop you can exit cleanly with ctrl+c. With socket code the blocking select prevents me from doing so. How do i solve this?
#pragma comment(lib, "Ws2_32.lib")
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#define DEFAULT_FAMILY AF_UNSPEC
#define DEFAULT_SOCKTYPE SOCK_STREAM
#define DEFAULT_PORT "1234"
#define BUFFER_SIZE 23 // length of "WinCE Echo Test Packet"
void Print(TCHAR *pFormat, ...)
{
va_list ArgList;
TCHAR Buffer[256];
va_start (ArgList, pFormat);
(void)StringCchPrintf(Buffer, 256, pFormat, ArgList);
#ifndef UNDER_CE
_putts(Buffer);
#else
printf("%s",Buffer);
#endif
va_end(ArgList);
}
int main2 ()
{
SOCKET sock, SockServ[FD_SETSIZE];
int nFamily = DEFAULT_FAMILY;
int nSockType = DEFAULT_SOCKTYPE;
char *szPort = DEFAULT_PORT;
SOCKADDR_STORAGE ssRemoteAddr;
int i, nNumSocks, cbRemoteAddrSize, cbXfer, cbTotalRecvd;
WSADATA wsaData;
ADDRINFO Hints, *AddrInfo = NULL, *AI;
fd_set fdSockSet;
char pBuf[BUFFER_SIZE];
char szRemoteAddrString[128];
if(WSAStartup(MAKEWORD(2,2), &wsaData))
{
// WSAStartup failed
return 1;
}
sock = INVALID_SOCKET;
for(i = 0; i < FD_SETSIZE; i++)
SockServ[i] = INVALID_SOCKET;
//
// Get a list of available addresses to serve on
//
memset(&Hints, 0, sizeof(Hints));
Hints.ai_family = nFamily;
Hints.ai_socktype = nSockType;
Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
if(getaddrinfo(NULL, szPort, &Hints, &AddrInfo))
{
Print(TEXT("ERROR: getaddrinfo failed with error %d\r\n"), WSAGetLastError());
goto Cleanup;
}
//
// Create a list of serving sockets, one for each address
//
i = 0;
for(AI = AddrInfo; AI != NULL; AI = AI->ai_next)
{
if (i == FD_SETSIZE)
{
// getaddrinfo returned more addresses than we could use
break;
}
if((AI->ai_family == PF_INET) || (AI->ai_family == PF_INET6)) // only want PF_INET or PF_INET6
{
SockServ[i] = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
if (SockServ[i] != INVALID_SOCKET)
{
if (bind(SockServ[i], AI->ai_addr, AI->ai_addrlen) == SOCKET_ERROR)
closesocket(SockServ[i]);
else
{
if(nSockType == SOCK_STREAM)
{
if (listen(SockServ[i], 5) == SOCKET_ERROR)
{
closesocket(SockServ[i]);
continue;
}
}
Print(
TEXT("Socket 0x%08x ready for connection with %hs family, %hs type, on port %hs\r\n"),
SockServ[i],
(AI->ai_family == AF_INET) ? "AF_INET" : ((AI->ai_family == AF_INET6) ? "AF_INET6" : "UNKNOWN"),
(AI->ai_socktype == SOCK_STREAM) ? "TCP" : ((AI->ai_socktype == SOCK_DGRAM) ? "UDP" : "UNKNOWN"),
szPort);
i++;
}
}
}
}
freeaddrinfo(AddrInfo);
if (i == 0)
{
Print(TEXT("ERROR: Unable to serve on any address. Error = %d\r\n"), WSAGetLastError());
goto Cleanup;
}
//
// Wait for incomming data/connections
//
nNumSocks = i;
FD_ZERO(&fdSockSet);
for (i = 0; i < nNumSocks; i++) // want to check all available sockets
FD_SET(SockServ[i], &fdSockSet);
if (select(nNumSocks, &fdSockSet, 0, 0, NULL) == SOCKET_ERROR)
{
Print(TEXT("ERROR: select() failed with error = %d\r\n"), WSAGetLastError());
goto Cleanup;
}
for (i = 0; i < nNumSocks; i++) // check which socket is ready to process
{
if (FD_ISSET(SockServ[i], &fdSockSet)) // proceed for connected socket
{
FD_CLR(SockServ[i], &fdSockSet);
if(nSockType == SOCK_STREAM)
{
cbRemoteAddrSize = sizeof(ssRemoteAddr);
sock = accept(SockServ[i], (SOCKADDR*)&ssRemoteAddr, &cbRemoteAddrSize);
if(sock == INVALID_SOCKET)
{
Print(TEXT("ERROR: accept() failed with error = %d\r\n"), WSAGetLastError());
goto Cleanup;
}
Print(TEXT("Accepted TCP connection from socket 0x%08x\r\n"), sock);
}
else
{
sock = SockServ[i];
Print(TEXT("UDP data available on socket 0x%08x\r\n"), sock);
}
break; // Only need one socket
}
}
//
// Receive data from a client
//
cbTotalRecvd = 0;
do
{
cbRemoteAddrSize = sizeof(ssRemoteAddr);
cbXfer = recvfrom(sock, pBuf + cbTotalRecvd, sizeof(pBuf) - cbTotalRecvd, 0,
(SOCKADDR *)&ssRemoteAddr, &cbRemoteAddrSize);
cbTotalRecvd += cbXfer;
} while(cbXfer > 0 && cbTotalRecvd < sizeof(pBuf));
if(cbXfer == SOCKET_ERROR)
{
Print(TEXT("ERROR: Couldn't receive the data! Error = %d\r\n"), WSAGetLastError());
goto Cleanup;
}
else if(cbXfer == 0)
{
Print(TEXT("ERROR: Didn't get all the expected data from the client!\r\n"));
goto Cleanup;
}
if(nSockType == SOCK_STREAM)
{
cbRemoteAddrSize = sizeof(ssRemoteAddr);
getpeername(sock, (SOCKADDR *)&ssRemoteAddr, &cbRemoteAddrSize);
}
if (getnameinfo((SOCKADDR *)&ssRemoteAddr, cbRemoteAddrSize,
szRemoteAddrString, sizeof(szRemoteAddrString), NULL, 0, NI_NUMERICHOST) != 0)
strcpy(szRemoteAddrString, "");
Print(TEXT("SUCCESS - Received %d bytes from client %hs\r\n"), cbTotalRecvd, szRemoteAddrString);
//
// Echo the data back to the client
//
cbXfer = 0;
cbXfer = sendto(sock, pBuf, cbTotalRecvd, 0, (SOCKADDR *)&ssRemoteAddr, cbRemoteAddrSize);
if(cbXfer != cbTotalRecvd)
Print(TEXT("ERROR: Couldn't send the data! error = %d\r\n"), WSAGetLastError());
else
Print(TEXT("SUCCESS - Echo'd %d bytes back to the client\r\n"), cbXfer);
Cleanup:
for(i = 0; i < nNumSocks && SockServ[i] != INVALID_SOCKET; i++)
closesocket(SockServ[i]);
if(sock != INVALID_SOCKET)
{
shutdown(sock, SD_BOTH);
closesocket(sock);
}
WSACleanup();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
volatile bool terminate_app=false;
void terminate (int param)
{
printf("Terminating program...\n");
terminate_app=true;
}
void important_code(bool v)
{
printf("Important code here %d\n", v);
}
int main ()
{
try{
void (*prev_fn)(int);
prev_fn = signal (SIGINT,terminate);
main2();
//while(terminate_app==false)
{
}
}
catch(...){
important_code(1);
}
important_code(0);
return 0;
}
On POSIX select() will return on timeout, or when one of the descriptors is ready, or possibly it with return with errno set to EINTR if it's interrupted by a signal.
So, you could use the EINTR behavior. Just install a signal handler with the sigaction() function without the SA_RESTART (restart system calls interrupted by signals) flag. (The behavior of signal() differs between systems, and on some systems it can be changed via #defines).
Or, you could use the self-pipe trick: write to a pipe to signal that you want to exit. If your select() selects the read descriptor for that pipe, it will return.
Why make things so complicated with pipes? Surely the exit does not matter if it takes a few seconds. Just put a time out of (say) 3 seconds and check if an exit is required after doing the select.
Will it matter if it takes a few seconds to start the exit process?