Enviado em 19/10/2011 - 16:55h
Olá pessoal!
#include <string>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <syslog.h>
#include "execute.h"
#include "path.h"
#define BUFFER_SIZE 4096
using namespace std;
void sighandler(int sig)
{
// force the child process to exit...
syslog( LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Aborting request execution by timeout!" );
exit(3);
}
int my_system(const string &command, unsigned int timeout, string &output)
{
pid_t pid = fork();
/* Falhou o fork */
if( pid < 0 ){
syslog( LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Failed to create fork! Aborting plugin execution..." );
output = "Could not execute plugin: fork failed!";
return 3; // Unknown
}
/* Processo pai */
if( pid > 0 ){
int status;
if( wait(&status) == -1 ){
syslog( LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Could not retrieve the child process status!" );
output = "Could not execute plugin: failed to retrieve process status";
}
else{
/* Execucao OK */
if( WIFEXITED(status) )
return WEXITSTATUS(status);
/* Execucao abortada por sinal */
else if( WIFSIGNALED(status) ){
output = "Could not execute plugin: execution aborted by signal (probably timeout)";
return WTERMSIG(status);
}
}
/*
Se chegar aqui, ou nao pode dispara o wait
ou nao sabe como pegar o status de saida do child
*/
return 3;
}
/* Processo filho, que ira executar o popen */
else{
FILE* fp = NULL;
output = "";
int returnValue;
unsigned int tries = 0;
/*
Se em 'timeout' segundos o plugin nao terminar
sua execucar, desvia para o 'sighandler'
e retorna 3 (i.e. UNKNOWN)
*/
signal(SIGALRM, sighandler);
alarm (timeout);
char* final_command = (char*)malloc( BUFFER_SIZE * sizeof(char) );
if( !final_command ){
syslog( LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "Could not create the command line!" );
returnValue = -1;
goto finish;
}
/*
Final Command = Command + [Redirect of 'stderr' to /dev/null]
*/
sprintf( final_command, "%s 2> /dev/null", command.c_str() );
do{
// run the command
fp = popen( final_command, "r" );
output = "";
/*
Retorna erro se nao foi possivel rodar o comando,
ou le a saida do comando em caso de sucesso.
*/
if( fp == NULL ){
syslog( LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "command could not be executed: %s", command.c_str() );
returnValue = -1;
}
else{
char buffer[ BUFFER_SIZE ];
while( fgets( buffer, BUFFER_SIZE, fp ) != NULL )
output += buffer;
returnValue = pclose( fp );
}
}
while( tries++ < 6 && ( returnValue < 0 || returnValue > 3 ) );
/*
Em alguns sistemas o pclose retorna
o status de saida do comando executado
na parte alta da palavra.
Logo, se a saida do pclose for maior que 3 (valor maximo do plugin),
divide por 256 para colocar na parte baixa.
*/
if( returnValue > 3 )
returnValue /= 256;
finish:
exit(returnValue);
}
return 3;
}
Resolver problemas de Internet
Como compartilhar a tela do Ubuntu com uma Smart TV (LG, Samsung, etc.)
Descritores de Arquivos e Swappiness
Como instalar no Linux Jogos da Steam só para Windows
Instalando o Team Viewer no Debian Trixie - problema no Policykit
O Que Fazer Após Instalar Ubuntu 25.04
O que você está ouvindo agora? [2] (176)
Erro ao executar o comando para dar um get email (1)
Problema ao iniciar o Opensuse Tumbleweed (2)