時間:2015/6/28來源:IT貓撲網(wǎng)作者:網(wǎng)管聯(lián)盟我要評論(0)
現(xiàn)在就來實踐一下,寫一個自動關(guān)機的小程序。該程序可以守護進程的方式運行,當用戶在一定時間(比如30分鐘)沒有鼠標和鍵盤操作后就會自動關(guān)機。
這個程序利用了上篇文章中實現(xiàn)的daemonize函數(shù),為程序創(chuàng)建了守護進程所需要的運行環(huán)境。
由于需要同時監(jiān)聽鼠標和鍵盤操作,所以需要采用多線程的方式來實現(xiàn)。其中兩個線程分別監(jiān)視鼠標和鍵盤,一旦檢測到相應動作(鼠標點擊和移動、擊鍵等),全局時間戳stamp(time_t)就會被設成當前時間。主線程每隔一定時間(比如1秒)檢查stamp,若當前時間值(time(NULL))比stamp大30*60,則執(zhí)行停機操作(使用system函數(shù)執(zhí)行init 0命令,或者使用reboot函數(shù))。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h> //~ O_RDWR, S_IRWXU etc.
#include <pthread.h>
#include <time.h>
#include <limits.h>
#include <signal.h>
void daemonize();
//~ thread functions
void *listen_ms(void *);
void *listen_kb(void *);
//~ time stamp, keeping the time
//~ when the last KB or Mouse event happened.
volatile time_t stamp;
//~ mutex keeping stamp consistent.
pthread_mutex_t stamp_mutex;
int
main()
{
daemonize();
//~ initialize the mutex, stamp
pthread_mutex_init(&stamp_mutex, NULL);
//time(&stamp);
stamp = time(NULL);
//~ create two threads monitoring the Mouse and keyboard.
pthread_t ms_tid, kb_tid;
if(pthread_create(&ms_tid, NULL, listen_ms, NULL) != 0)
{
perror("pthread_create");
exit(1);
}
if(pthread_create(&kb_tid, NULL, listen_kb, NULL) != 0)
{
perror("pthread_create");
exit(1);
}
unsigned int interval = 60 * 30;
while(1)
{
sleep(1);
pthread_mutex_lock(&stamp_mutex);
if( time(NULL) - stamp > interval )
{
/*printf("shutdown\n");*/
/*fflush(stdin);*/
system("init 0");
}
pthread_mutex_unlock(&stamp_mutex);
}
//~ join the threads, though it'll never be excuted.
pthread_join(ms_tid, NULL);
pthread_join(kb_tid, NULL);
return 0;
}
void *
listen_ms(void * arg)
{
int fd = open("/dev/input/mice", O_RDONLY);
if(fd < 0)
{
perror("open mice");
exit(1);
}
char buf[256];
while( read(fd, buf, sizeof(buf)) > 0 )
{
/*printf("Moused Moved.\n");*/
pthread_mutex_lock(&stamp_mutex);
//time(&stamp);
stamp = time(NULL);
pthread_mutex_unlock(&stamp_mutex);
}
close(fd);
}
void *
listen_kb(void * arg)
{
int fd = open("/dev/input/event3", O_RDONLY);
if(fd < 0)
{
perror("open event3");
exit(1);
}
char buf[256];
while( read(fd, buf, sizeof(buf)) > 0 )
{
/*printf("Key Hit.\n");*/
pthread_mutex_lock(&stamp_mutex);
//time(&stamp);
stamp = time(NULL);
pthread_mutex_unlock(&stamp_mutex);
}
close(fd);
}
void
daemonize()
{
if( fork() > 0)
exit(0);
setsid();
close(0);
close(1);
close(2);
int fd = open("/dev/null", O_RDWR);
//int fd = open("log.txt", O_RDWR);
dup2(fd, 1);
dup2(fd, 2);
chdir("/");
umask(0);
signal(SIGCHLD, SIG_IGN);
}
需要說明的是,共享變量stamp需要互斥地訪問。另外,對鼠標事件的監(jiān)聽是借助于對設備文件/dev/input/mice的讀。ㄗ枞绞剑,鍵盤的監(jiān)聽借助于對/dev/input/event3的非阻塞讀取,但我猜想在不同機器上可能會是其它諸如event0,event5之類的文件。
不足之處在于,無法對全屏模式進行判斷,即是說,如果你全屏看一部較長的電影,可能會被關(guān)機……
關(guān)鍵詞標簽:Linux
相關(guān)閱讀
熱門文章 安裝紅帽子RedHat Linux9.0操作系統(tǒng)教程使用screen管理你的遠程會話GNU/Linux安裝vmware如何登錄linux vps圖形界面 Linux遠程桌面連
人氣排行 Linux下獲取CPUID、硬盤序列號與MAC地址linux tc實現(xiàn)ip流量限制dmidecode命令查看內(nèi)存型號linux下解壓rar文件安裝紅帽子RedHat Linux9.0操作系統(tǒng)教程Ubuntu linux 關(guān)機、重啟、注銷 命令lcx.exe、nc.exe、sc.exe入侵中的使用方法查看linux服務器硬盤IO讀寫負載