C語言標準輸入被關閉程序死循環

#現象

如果測試端使用標準輸入流的標識進行循環控制while(任意字符==q){scanf("%c\n",&q);}形式程序

此端發送,循環內嵌入UDP發送,嵌入的無其他形勢跳出循環。

彼端接收,可查看此端發送條數。

 

1.在CRT開始運行./a.out args,並鍵盤輸入控制,程序還在循環中,直接X掉CRT程序可能變成後臺程序繼續運行,略過scanf,保持原來的值死循環,暫時定爲【標準輸入控制失控】。在其他的crt窗口中ps -ef|grep a.out。有可能出現該程序還在後端運行。根據增加while(任意==q&&i<5){scanf("%c\n",&q);}可以顯示發現輸入失控的時候,程序循環依舊進行。程序會接收到signo=1.程序退出。一旦忽略該信號SIGHUP。程序會後臺一直運行,即死循環。【在該信號默認程序退出的情況下,程序輸入失控一段時間】

freopen("input.log","a+",stdout);while(任意==q&&i<5){scanf("%c\n",&q);printf(":%d:\n",q);}可以通過日誌查看crt失控的過程依舊是原來的q值。

 

2.使用nohup ./a.out args 啓用程序,也出現【標準輸入控制失控】。在行首同時ctrl和c按鍵中斷程序退出。一旦忽略,依舊失控。

 

3.使用nohup ./a.out args & 啓用程序【標準輸入控制失控】。kill -9 `pidof a.out`程序強制退出

 

#猜測原因

根據守護進程,代碼來自

https://www.cnblogs.com/wiessharling/p/4105956.html

猜測 標準輸入流 關閉

bool daemonize()
{
    pid_t pid = fork();
    if ( pid < 0 )
    {
        return false;
    }
    else if ( pid > 0 )
    {
        exit( 0 );
    }

    umask( 0 );

    pid_t sid = setsid();
    if ( sid < 0 )
    {
        return false;
    }

    if ( ( chdir( "/" ) ) < 0 )
    {
        /* Log the failure */
        return false;
    }
    close( STDIN_FILENO );
    close( STDOUT_FILENO );
    close( STDERR_FILENO );

    open( "/dev/null", O_RDONLY );
    open( "/dev/null", O_RDWR );
    open( "/dev/null", O_RDWR );
    return true;
}

#模擬程序

 

#include<stdio.h>
#include<string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<errno.h>
#include<unistd.h>
int main()
{
int a_errno=0;
int ret=0;
char q='c';
printf("<%d>\n",q);

close( STDIN_FILENO );
ret=scanf("%c\n",&q);
if(EOF==ret)
{ 
        a_errno=errno;
}
  printf("[%d] ret=%d eno[%d]%s\n",q,ret,a_errno,strerror(a_errno));

return 0;
}

可發現打印的兩次都爲99

#解決方法

c=getchar();命令行後所有字符均被讀入

標準輸入的參數前面進行賦值和判斷的不一致的參數。

如果是int如果使用清空,一旦是0,也會同樣失效。

程序kill掉命令a.out 爲程序名
kill -9 `pidof a.out`
/*彼端*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#define LOGP  printf

void  udp_server_test(int lsa_port)
{
  	int 				socketfd=0;
	int				iReadLen=-1;
	int				peer_len=0;
	char				readbuf[1500]; 
	union sockaddr_types {
         struct sockaddr_storage storage;
         struct sockaddr addr; 
        struct sockaddr_in in4;
        struct sockaddr_in6 in6;
        };
	union sockaddr_types    peer;
	union sockaddr_types	local_server;
	char			IP_peer[INET6_ADDRSTRLEN];
	unsigned  int           port_peer;  
	int                      eno;

	bzero(&local_server, sizeof(local_server)); 
	
#if    1
	  local_server.in4.sin_family = AF_INET;
          local_server.in4.sin_addr.s_addr = htonl(INADDR_ANY);
          local_server.in4.sin_port = htons(lsa_port);

#else
 
	   local_server.in6.sin6_family = AF_INET6;
           local_server.in6.sin6_addr = in6addr_any;
           local_server.in6.sin6_port = htons(lsa_port);
#endif 
        /* AF_INET:IPv4;  AF_INET6:Allow IPv4 or IPv6 */
	socketfd = socket(local_server.addr.sa_family, SOCK_DGRAM, 0);
	if(socketfd < 0)
	{
	        eno=errno;
		LOGP("socket failed!errno[%d][%s].",eno,strerror(eno));
	}
	else
	{
		LOGP("socket suc.\n");
	}

	if (bind(socketfd, &local_server.addr, sizeof(local_server)) < 0)
	{
	        eno=errno;
		LOGP("bind socket failed!errno[%d][%s].",eno,strerror(eno));
	}
	else
	{
		LOGP("bind suc.\n");
	}

	//freopen("out_ser.log","a+",stdout);
	while(1)
	{
		memset(readbuf,0,sizeof(readbuf));
         peer_len = sizeof(struct sockaddr_storage);	
		iReadLen = recvfrom(socketfd, readbuf, sizeof(readbuf), 0, &peer.addr, (socklen_t*)&peer_len);
		if(0==iReadLen)
		{
		   continue;
		}
		if(iReadLen<0)
		{    eno=errno;
		    if(EBADF==eno)
			break;/*The socket argument is not a valid file descriptor*/
		     else continue;
		} 
		  { 
		       if(NULL==inet_ntop(peer.addr.sa_family, 
		         (AF_INET==peer.addr.sa_family? 
			 ((void*)&peer.in4.sin_addr):((void*)&peer.in6.sin6_addr)),
		           IP_peer, sizeof(IP_peer)))
		       {
		       } 
		       port_peer=ntohs(AF_INET==peer.addr.sa_family?peer.in4.sin_port:peer.in6.sin6_port);
                   
          } 
		printf("IP[%s:%d]len=%d content=[%s]\n",IP_peer,port_peer,iReadLen,readbuf); 

	} 
	close(socketfd); 

}

int main(int argc,char *argv[])
{ 
	if(argc!=2)
   {
    printf("./Usage {port}\n");
   return 1;
   }
   udp_server_test(atoi(argv[1]));
   return 0;	
}
/*舊的此*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<time.h>
#include<signal.h>
int gsigno;
#define exit_printf(en,f,...)  do{fflush(stdout);freopen("fcexit.log","a+",stdout);printf(f,##__VA_ARGS__);fflush(stdout);exit(en);}while(0)
void Signcallback(int signo, siginfo_t *info, void *context){

    	
 gsigno=signo; 
  exit(1);	 
}
void registersignal()
{   
	  struct sigaction  ignoreact;
	  ignoreact.sa_handler = SIG_IGN;
           
	  ignoreact.sa_flags = SA_RESETHAND; 
	  sigaction(SIGHUP, &ignoreact, NULL); 
	   
	  struct sigaction  actp;
	  actp.sa_sigaction=Signcallback;
	  actp.sa_flags=SA_SIGINFO|SA_RESTART;
	  sigemptyset(&(actp.sa_mask));
	  sigaction(SIGTERM,&actp,NULL); 
	  sigaction(SIGQUIT,&actp,NULL); 
      sigaction(SIGPIPE, &actp, NULL);
      sigaction(SIGALRM, &actp, NULL); 
      sigaction(SIGILL, &actp, NULL);
      sigaction(SIGABRT, &actp,NULL);
      sigaction(SIGFPE, &actp, NULL);
      sigaction(SIGINT,&actp,NULL);
 
 	return ;

} 
 

void  exitHandle()
{
    time_t timer = time(NULL); 
    printf("ctime is %s", ctime(&timer)); 
    printf("<%d>test program exit\n",gsigno);  
}

int main(int argc,char *argv[])
{

atexit(exitHandle);/*註冊終止函數*/
registersignal();  

 if(argc!=3)
{
printf("./Usage [ip] [port]\n");
return 1;
}
int sock=socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
 {
perror("socket");
return 2;

}

 struct sockaddr_in rsa;
 rsa.sin_family=AF_INET;
 rsa.sin_port=htons(atoi(argv[2]));
 rsa.sin_addr.s_addr=inet_addr(argv[1]);

 char buf[1024];
        int buflen =0;
 struct sockaddr_in peer;
 char quitf='c';
int i=0;
int ret=0;
freopen("input.log","a+",stdout);
while('c'==quitf)
{  
  i++; 
  buflen=sprintf(buf,"%d",i);
  sendto(sock,buf,buflen,0, (struct sockaddr*)&rsa,sizeof(rsa));
  ret=scanf("%c",&quitf);
  getchar();
  printf(":ret(%d)%d:\n",ret,quitf); 
 }
close(sock);
exit_printf(0,"\'%d\'",quitf);
return 0;
} 
/* 增加 quitf=-'c';*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<time.h>
#include<signal.h>
int gsigno;
#define exit_printf(en,f,...)  do{fflush(stdout);freopen("fcexit.log","a+",stdout);printf(f,##__VA_ARGS__);fflush(stdout);exit(en);}while(0)
void Signcallback(int signo, siginfo_t *info, void *context){

    	
 gsigno=signo; 
  exit(1);	 
}
void registersignal()
{   
	  struct sigaction  ignoreact;
	  ignoreact.sa_handler = SIG_IGN;
           
	  ignoreact.sa_flags = SA_RESETHAND; 
	  sigaction(SIGHUP, &ignoreact, NULL); 
	   
	  struct sigaction  actp;
	  actp.sa_sigaction=Signcallback;
	  actp.sa_flags=SA_SIGINFO|SA_RESTART;
	  sigemptyset(&(actp.sa_mask));
	  sigaction(SIGTERM,&actp,NULL); 
	  sigaction(SIGQUIT,&actp,NULL); 
      sigaction(SIGPIPE, &actp, NULL);
      sigaction(SIGALRM, &actp, NULL); 
      sigaction(SIGILL, &actp, NULL);
      sigaction(SIGABRT, &actp,NULL);
      sigaction(SIGFPE, &actp, NULL);
      sigaction(SIGINT,&actp,NULL);
 
 	return ;

} 
 

void  exitHandle()
{
    time_t timer = time(NULL); 
    printf("ctime is %s", ctime(&timer)); 
    printf("<%d>test program exit\n",gsigno);  
}

int main(int argc,char *argv[])
{

atexit(exitHandle);/*註冊終止函數*/
registersignal();  

 if(argc!=3)
{
printf("./Usage [ip] [port]\n");
return 1;
}
int sock=socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
 {
perror("socket");
return 2;

}

 struct sockaddr_in rsa;
 rsa.sin_family=AF_INET;
 rsa.sin_port=htons(atoi(argv[2]));
 rsa.sin_addr.s_addr=inet_addr(argv[1]);

 char buf[1024];
        int buflen =0;
 struct sockaddr_in peer;
 char quitf='c';
int i=0;
int ret=0;
freopen("input.log","a+",stdout);
while('c'==quitf)
{  
  i++; 
  buflen=sprintf(buf,"%d",i);
  sendto(sock,buf,buflen,0, (struct sockaddr*)&rsa,sizeof(rsa));
  quitf=-'c';
  ret=scanf("%c",&quitf);
  getchar();
  printf(":ret(%d)%d:\n",ret,quitf); 
 }
close(sock);
exit_printf(0,"\'%d\'",quitf);
return 0;
} 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章