带超时的system
工作中,需要使用tftp等協(xié)議下載一些文件,但這時候遇到一個問題就是當(dāng)tftp的服務(wù)器沒有打開時,system
函數(shù)會阻塞較長時間(長達(dá)樹秒),這時候首先想到的就是設(shè)置tftp的超時參數(shù),但因為還有很多協(xié)議也有超時返回
的需求,我就想一勞永逸的封裝一個函數(shù)來完成這項任務(wù)。最后決定重寫一下system并設(shè)置超時函數(shù),封裝的函數(shù)
如下(system_timeout).這里需要解釋進(jìn)行兩層封裝的原因:在system_timeout中我們將_system_timeout進(jìn)行了一層封裝,
并將信號SIGCHLD設(shè)置為SIG_DFL是因為我們在_system_timeout中調(diào)用了waitpid,而這個函數(shù)在SIGCHLD被忽略是會
產(chǎn)生ECHILD錯誤,手冊解釋如下:
ERRORS
? ? ? ? ? ? ? ? ECHILD (for waitpid() or waitid()) The process specified by pid (wait-pid()) or idtype and id (waitid()) does?
? ? ? ? ? ? ? ? ? ? ? not exist or is not a child of the calling process. (This can happen for one's own child if the action for SIGCHLD
? ? ? ? ? ? ? ? ? ? ? is set to SIG_IGN. See also the Linux Notes section about threads.)
#include <sys/wait.h> #include <errno.h> #include <signal.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h>int _system_timeout(const char *cmdstring, int timeout); /*one hundred of a second*/ int system_timeout(const char *cmdstring, int timeout); int main(int argc, char **argv) {if (argc != 2) {printf("usage:%s [command]\n", argv[0]);}if (0 != system_timeout(argv[1], 50)) {printf("system_timeout error \n");return -1;}printf("system_timeout success\n");return 0; }int _system_timeout(const char *cmdstring, int timeout) {pid_t pid;int status;struct sigaction ignore, saveintr, savequit;sigset_t chldmask, savemask;if (cmdstring == NULL)return 1;ignore.sa_handler = SIG_IGN;sigemptyset(&ignore.sa_mask);ignore.sa_flags = 0;if (sigaction(SIGINT, &ignore, &saveintr) < 0) {return -1;}if (sigaction(SIGQUIT, &ignore, &savequit) < 0) {return -1;}sigemptyset(&chldmask);sigaddset(&chldmask, SIGCHLD);if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0) {return -1;}if ((pid = fork()) < 0) {return -1;} else if (pid == 0) {sigaction(SIGINT, &saveintr, NULL);sigaction(SIGQUIT, &savequit, NULL);sigprocmask(SIG_SETMASK, &savemask, NULL);execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);_exit(127);} else {usleep(timeout * 10000);kill(pid, SIGKILL);waitpid(pid, &status, 0);}if (sigaction(SIGINT, &saveintr, NULL) < 0) {return -1;}if (sigaction(SIGQUIT, &savequit, NULL) < 0) return -1;if (sigprocmask(SIG_SETMASK, &savemask, NULL) < 0)return -1;return status; }int system_timeout(const char *cmdstring, int timeout) {int ret = 0;struct sigaction chldnew, chldold;if (cmdstring == NULL) return -1;bzero(&chldnew, sizeof(struct sigaction));bzero(&chldold, sizeof(struct sigaction));chldnew.sa_handler = SIG_DFL;sigemptyset(&chldnew.sa_mask);chldnew.sa_flags = 0;if (sigaction(SIGCHLD, &chldnew, &chldold) < 0) {return -1;}if ((timeout * 10000) < 0) {return -1;} else if (timeout == 0) {ret = system(cmdstring);} else {ret = _system_timeout(cmdstring, timeout);}if (sigaction(SIGCHLD, &chldold, NULL) < 0) {return -1;}return ret; }?
轉(zhuǎn)自:https://blog.csdn.net/shanguangy111/article/details/47185533
這塊需要視項目的實際情況來修改代碼即可。
總結(jié)
以上是生活随笔為你收集整理的带超时的system的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux的system和popen的差
- 下一篇: nginx开发简单的http模块