📄 utils.c
字号:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
#include <Windows.h>
#else
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utils.h"
#include "common.h"
char* trim_strLR(const char *str, char *buf)
{
char *pTmp = NULL;
char *p = NULL;
pTmp = (char*)malloc(strlen(str)+1);
memset(pTmp, 0, strlen(str)+1);
strcpy(pTmp, str);
p = pTmp;
for (; *p != '\0' && (*p == 9 || *p == 10 || *p == 13 || *p == 32); p++);
strcpy(buf, p);
if (*p == '\0')
{
free(pTmp);
return buf;
}
p = buf + strlen(buf);
for (p--; p != buf && (*p == 9 || *p == 10 || *p == 13 || *p == 32); p--);
*(p + 1) = '\0';
free(pTmp);
return buf;
}
char* trim_str(char *str, char *buf)
{
char *pTmp = NULL;
char *p = NULL;
pTmp = (char*)malloc((strlen(str)+1));
memset(pTmp, 0, (strlen(str)+1));
strcpy(pTmp, str);
p = pTmp;
while (*p != '\0')
{
if ((*p == 9 || *p == 10 || *p == 13 || *p == 32))
{
p++;
continue;
}
*buf++ = *p++;
}
free(pTmp);
return buf;
}
char* my_strtok(char **pToken, const char *strDelimit)
{
char *p, *tmp;
int len;
if (!pToken || !(*pToken))
{
return (char*)0;
}
p = *pToken;
len = strlen(strDelimit);
tmp = strstr(*pToken, strDelimit);
if (tmp)
{
*tmp = 0;
*pToken = tmp + len;
}
else
{
*pToken = (char*)0;
}
return p;
}
void spl_str(const char *str, const char *sep, char **v, int *c)
{
const char *pStr = 0;
char *pPos = 0;
char *p = 0;
int len;
int offset;
int i = 0;
pStr = str;
offset = strlen(sep);
pPos = strstr(pStr, sep);
if (v)
{
while (pPos && i < *c)
{
len = pPos - pStr;
if (len != 0)
{
p = (char*)malloc(len + 1);
memset(p, 0, len + 1);
strncpy(p, pStr, len);
v[i] = p;
i++;
}
pStr = pPos + offset;
pPos = strstr(pStr, sep);
}
if (*pStr != '\0' && i < *c)
{
len = strlen(pStr);
p = (char*)malloc(len + 1);
memset(p, 0, len + 1);
strcpy(p, pStr);
v[i] = p;
i++;
}
}
else
{
while (pPos && i < *c)
{
len = pPos - pStr;
if (len != 0)
{
i++;
}
pStr = pPos + offset;
pPos = strstr(pStr, sep);
}
if (*pStr != '\0' && i < *c)
{
i++;
}
}
*c = i;
}
void free_arg(char **v, int c)
{
int i;
for (i = 0; i < c; i++)
{
if (v[i])
{
free(v[i]);
v[i] = 0;
}
}
}
#ifdef WIN32
int my_system(char *command, unsigned long timeout, char *buffer, int buflen)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
HANDLE hChildOutR, hChildOutW, hChildInR, hChildInW;
SECURITY_ATTRIBUTES sec;
DWORD dwread, dwstate, dwexitcode;
int ret, result;
BOOL processOK;
// Set up members of SECURITY_ATTRIBUTES structure.
sec.nLength = sizeof(SECURITY_ATTRIBUTES);
sec.bInheritHandle = TRUE;
sec.lpSecurityDescriptor = NULL;
// Create Pipes
CreatePipe(&hChildInR, &hChildInW, &sec, 0);
CreatePipe(&hChildOutR, &hChildOutW, &sec, MAX_BUF_LEN);
// Set up members of STARTUPINFO structure.
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
si.hStdInput = hChildInR;
si.hStdOutput = hChildOutW;
si.hStdError = hChildOutW;
si.wShowWindow = SW_HIDE;
// Create the child process.
processOK = CreateProcess(NULL, command, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&si, // STARTUPINFO pointer
&pi); // receives PROCESS_INFORMATION
if (processOK)
{
dwstate = WaitForSingleObject(pi.hProcess, timeout*1000);
CloseHandle(hChildInR);
CloseHandle(hChildInW);
CloseHandle(hChildOutW);
if (dwstate == WAIT_TIMEOUT)
{
TerminateProcess(pi.hProcess, STATE_UNKNOWN);
strcpy(buffer, "timeout!");
result = STATE_UNKNOWN;
}
else
{
memset(buffer, 0, buflen);
ret = ReadFile(hChildOutR, buffer, buflen, &dwread, NULL);
if (!ret || dwread == 0)
{
//strcpy(buffer, "No output available from command...");
result = GetExitCodeProcess(pi.hProcess, &dwexitcode);
if (!result)
{
result = STATE_ERROR;
}
else
{
result = dwexitcode;
}
}
else
{
buffer[buflen - 1] = 0;
result = GetExitCodeProcess(pi.hProcess, &dwexitcode);
if (!result)
{
result = STATE_ERROR;
}
else
{
result = dwexitcode;
}
}
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hChildOutR);
}
else
{
//strcpy(buffer, "failed to create process!");
result = STATE_ERROR;
CloseHandle(hChildInR);
CloseHandle(hChildInW);
CloseHandle(hChildOutW);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hChildOutR);
}
return result;
}
#else /** #ifdef WIN32 */
void my_system_sighandler_ex(int sig)
{
/* force the child process to exit... */
printf("time out!\n");
exit(STATE_ERROR);
}
int my_system(char *command, unsigned long timeout, char *buffer, int buflen)
{
pid_t pid;
int status;
int result;
FILE *fp = NULL;
int fd[2];
int ret = 0;
int cur = 0;
time_t start_time,end_time;
char szTmp[MIN_BUF_LEN];
time(&start_time);
/* create a pipe */
pipe(fd);
/* fork */
pid = fork();
/* return an error if we couldn't fork */
if (pid==-1)
{
/* close both ends of the pipe */
close(fd[0]);
close(fd[1]);
return STATE_ERROR;
}
/* execute the command in the child process */
if (pid==0)
{
/* close pipe for reading */
close(fd[0]);
/* become process group leader */
setpgid(0,0);
/* trap commands that timeout */
signal(SIGALRM,my_system_sighandler_ex);
alarm(timeout);
strcpy(szTmp, "LANG=POSIX");
putenv(szTmp);
strcpy(szTmp, "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH");
putenv(szTmp);
/* run the command */
fp=popen(command,"r");
/* report an error if we couldn't run the command */
if (fp==NULL)
{
//strcpy(buffer, "Call to popen() failed");
/* write the error back to the parent process */
//write(fd[1],buffer,strlen(buffer)+1);
close(fd[1]);
exit(STATE_ERROR);
}
else
{
/* read in the first line of output from the command */
memset(buffer, 0, buflen);
while (cur < buflen)
{
if (!fgets(buffer+cur, buflen-cur, fp))
{
break;
}
cur = strlen(buffer);
}
buffer[buflen-1] = 0;
/* close the command and get termination status */
status=pclose(fp);
/*if (cur == 0)
{
close(fd[1]);
exit(STATE_UNKNOWN);
}
else*/
{
/* report an error if we couldn't close the command */
if (status==-1)
{
result=STATE_ERROR;
}
else
{
result=WEXITSTATUS(status);
}
}
/* write the output back to the parent process */
write(fd[1],buffer,strlen(buffer)+1);
}
/* close pipe for writing */
close(fd[1]);
/* reset the alarm */
alarm(0);
exit(result);
}
/* parent waits for child to finish executing command */
else
{
/* close pipe for writing */
close(fd[1]);
/* wait for child to exit */
waitpid(pid,&status,0);
/* get the end time for running the command */
time(&end_time);
/* get the exit code returned from the program */
result=WEXITSTATUS(status);
/* check bounds on the return value */
if(result<0 || result>3)
{
result=STATE_UNKNOWN;
}
/* try and read the results from the command output (retry if we encountered a signal) */
memset(buffer, 0, buflen);
ret = read(fd[0],buffer,buflen);
if (ret==-1)
{
strcpy(buffer,"");
}
/* if there was a critical return code and no output AND the command time exceeded the timeout thresholds, assume a timeout */
if (result==STATE_ERROR && ret==-1 && (end_time-start_time)>=timeout)
{
/* send termination signal to child process group */
kill((pid_t)(-pid),SIGTERM);
kill((pid_t)(-pid),SIGKILL);
}
/* close the pipe for reading */
close(fd[0]);
}
return result;
}
/*int my_system(char *command, unsigned long timeout, char *buffer, int buflen)
{
char envstr[128];
int fd[2];
pid_t pid;
if (!command || !buffer || buflen <= 0)
{
return STATE_ERROR;
}
if (pipe(fd) < 0)
{
snprintf(buffer, buflen - 1,"pipe faild:%s", strerror(errno));
buffer[buflen-1] = 0;
return STATE_FAIL;
}
pid = fork();
if (pid == -1)
{
close(fd[0]);
close(fd[1]);
snprintf(buffer, buflen - 1,"fork faild:%s", strerror(errno));
buffer[buflen-1] = 0;
return STATE_FAIL;
}
if (pid == 0)
{
close(0);
close(1);
close(2);
setpgid(0,0);
dup(fd[0]);
dup(fd[1]);
dup(fd[1]);
memset(envstr, 0, sizeof(envstr));
snprintf (envstr, sizeof(envstr) - 1, "%s", "LANG=posix");
putenv(envstr);
memset(envstr, 0, sizeof(envstr));
snprintf(envstr, sizeof(envstr) - 1, "%s", "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH");
putenv(envstr);
execl("/bin/sh", "sh", "-c", command, (char *)0);
_exit(STATE_FAIL);
}
else
{
int status = 0,result = 0,bytes_read = 0,fd_count = 0;
struct timeval tv;
fd_set set;
tv.tv_sec = timeout;
tv.tv_usec = 0;
FD_ZERO(&set);
FD_SET(fd[0], &set);
fd_count = select(fd[0]+1,&set,NULL,NULL,&tv);
if (fd_count < 0)
{
kill((pid_t)(-pid),SIGTERM);
kill((pid_t)(-pid),SIGKILL);
waitpid(pid, &status, 0);
close(fd[0]);
close(fd[1]);
snprintf(buffer, buflen - 1, "error:child process:%s", strerror(errno));
return STATE_ERROR;
}
else if (!fd_count)
{
kill((pid_t)(-pid),SIGTERM);
kill((pid_t)(-pid),SIGKILL);
waitpid(pid, &status, 0);
close(fd[0]);
close(fd[1]);
snprintf(buffer, buflen - 1, "error:child process timeout");
return STATE_ERROR;
}
if(FD_ISSET(fd[0], &set))
{
memset(buffer, 0, buflen);
do
{
bytes_read = read(fd[0], buffer, buflen - 1);
}while(bytes_read==-1 && errno==EINTR);
}
close(fd[0]);
close(fd[1]);
waitpid(pid,&status,0);
result = WEXITSTATUS(status);
if (result < 0 || result > 3)
{
result = STATE_ERROR;
}
if (bytes_read == -1)
{
snprintf(buffer, buflen - 1, "read child process data faild:%s", strerror(errno));
buffer[buflen-1] = 0;
return STATE_ERROR;
}
if (result != STATE_OK)
{
snprintf(buffer, buflen - 1, "%s", buffer);
buffer[buflen-1] = 0;
return result;
}
return STATE_OK;
}
}*/
#endif
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -