#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <sys/times.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "ace/SOCK_Stream.h"
#include "ace/INET_Addr.h"
#include "ace/OS.h"
#include "ace/SOCK_Dgram.h"
#include "ace/INET_Addr.h"
#include "ace/Reactor.h"
#include "ace/Synch.h"
#include "ace/OS.h"
#include "ace/INET_Addr.h"
#include "ace/Acceptor.h"
#include "ace/Connector.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/SOCK_Connector.h"
#include "ace/Reactor.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Dgram.h"
#include "ace/Log_Msg.h"
#include "ace/Log_Priority.h"
#include "ace/Get_Opt.h"
#include "time.h"
#include "pexec_share.h"
#include "wd.h"
// global variables
//struct buff_stdout outbuff;
//struct buff_stderr errbuff;
//int exitcode;
extern int errno;
enum status_type execprocess(char* uname,
char* cmdline,
int nmili_sec,
int& exitcode,
struct buff_stdout& outbuff,
struct buff_stderr& errbuff);
class PEXEC_Handler:
public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_MT_SYNCH>
{
public:
PEXEC_Handler(){
}
int init();
int open(void*);
int handle_input(ACE_HANDLE);
int handle_timeout(const ACE_Time_Value&, const void*);
int handle_close(ACE_HANDLE,ACE_Reactor_Mask);
int svc();
private:
param_pack pex_pps;
ACE_Thread_Mutex mutex_;
};
typedef ACE_Acceptor<PEXEC_Handler, ACE_SOCK_ACCEPTOR> PEXEC_Acceptor;
int
PEXEC_Handler::open(void *)
{
//ACE_DEBUG((LM_DEBUG,"the gsd_handler is going to be opened\n"));
ACE_Reactor::instance()->register_handler(this,ACE_Event_Handler::READ_MASK);
return 0;
}
int
PEXEC_Handler::handle_input(ACE_HANDLE)
{
// int rlen = peer().recv(tmp_recv,128,0);
struct param_pack pps, net_pps;
//enum status_type exec_status;
//int nint;
int rlen = peer().recv((char *)&net_pps, sizeof(net_pps), 0);
if (rlen <= -1) // can not recv messge from client
{
cout << "[" << __FILE__ << ":" << __LINE__ << "]" << "\t";
/*new add 0525*/
peer().close();
/*end add*/
ACE_ERROR_RETURN((LM_ERROR,"(%P|%t, %p)","recv message failed"),-1);
return -1;
}
if (rlen == 0){
peer().close();
return -1;
}
//convert net_pps to pps
strncpy(pps.user, net_pps.user, sizeof(pps.user));
strncpy(pps.cmdline, net_pps.cmdline, sizeof(pps.cmdline));
pps.fexitcode = ntohl(net_pps.fexitcode);
pps.milisec = ntohl(net_pps.milisec);
//cout<<"user name is "<<pps.user<<endl
// <<"cmdline is "<<pps.cmdline<<endl
//<<"exitcode only is "<<pps.exitcode_only<<endl
//<<"timeout is "<<pps.timeout<<endl;
mutex_.acquire();
pex_pps = net_pps;
activate(THR_NEW_LWP,
1, //2 new threads
1, //force active false, if already created don~Rt try again.
ACE_DEFAULT_THREAD_PRIORITY,//Use default thread priority
-1,
this,//Which ACE_Task object to create? In this case this one.
0,// don~Rt care about thread handles used
0,// don~Rt care about where stacks are created
0);//don~Rt care about stack sizes
//thread_names); // keep identifiers in thread_names
return 0;
}
int
PEXEC_Handler::handle_close(ACE_HANDLE,ACE_Reactor_Mask)
{
return 0;
}
int
PEXEC_Handler::handle_timeout(const ACE_Time_Value&, const void*) {
send_wd_heartbeat(PEXEC_SRC_TYPE);
return 0;
}
int
PEXEC_Handler::svc() {
struct buff_stdout outbuff;
struct buff_stderr errbuff;
int exitcode;
status_type exec_status;
int nint;
param_pack pps;
pps = pex_pps;
mutex_.release();
//exec cmdline
exec_status = execprocess(pps.user,
pps.cmdline,
pps.milisec,
exitcode,
outbuff,
errbuff);
nint = htonl(exec_status);
if (peer().send_n((char *)&nint, sizeof(nint), 0) == -1){
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
//cout<<"errbuff.len = "<<errbuff.len<<endl;
//cout<<errbuff.buffer<<endl;
if (exec_status == EXEC_SUCCESS) {
//send exit code back
nint = htonl(exitcode);
if (peer().send_n((char *)&nint, sizeof(nint)) == -1) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
//ACE_OS::printf("send data failed\n");
return -1;
}
if (pps.fexitcode) {
//send stdout len back
nint = htonl(outbuff.len);
if (peer().send_n((char *)&nint, sizeof(nint), 0) == -1) {
//ACE_OS::printf("send data failed\n");
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
if (outbuff.len > 0) {
if (peer().send_n(outbuff.buffer, outbuff.len, 0) == -1) {
//ACE_OS::printf("send data failed\n");
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
}
//send stderr len back
nint = htonl(errbuff.len);
if (peer().send_n((char *)&nint, sizeof(nint), 0) == -1) {
//ACE_OS::printf("send data failed\n");
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
if (errbuff.len > 0) {
if (peer().send_n(errbuff.buffer, errbuff.len, 0) == -1) {
//ACE_OS::printf("send data failed\n");
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
}
}
}
// peer().close();
return 0;
}
int main(int argc, char** argv)
{
ACE_INET_Addr tcp_addr(PEXEC_PORT);
ACE_INET_Addr remote_addr;
PEXEC_Acceptor *acceptor;
ACE::daemonize();
//open log
ofstream *output_file = new ofstream("/home/dware/pexecd.log", ios::out);
if (output_file && output_file->rdstate() == ios::goodbit)
ACE_LOG_MSG->msg_ostream(output_file, 1);
ACE_LOG_MSG->open(argv[0], ACE_Log_Msg::OSTREAM,0);
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%T (%t): Starting service.\n")));
acceptor = new PEXEC_Acceptor;
if(acceptor->open(tcp_addr, ACE_Reactor::instance()) == -1)
{
char error_message[64];
printf("[%s|%d]open failed: %s", __FILE__, __LINE__, strerror(errno));
}
PEXEC_Handler My_Pexec_Handler;
ACE_Time_Value timeout(HB_TIMEOUT);
ACE_Reactor::instance()->schedule_timer(&My_Pexec_Handler,0,timeout,timeout);
while(1)
ACE_Reactor::instance()->handle_events();
return 0;
}
status_type execprocess(char* uname,
char* cmdline,
int nmili_sec,
int& exitcode,
struct buff_stdout& outbuff,
struct buff_stderr& errbuff) {
int chuser;
struct passwd *pw;
int pp_out[2], pp_err[2];
pid_t pid;
uid_t uid;
gid_t gid;
char *shellpath, *shellname;
fd_set readfd, allfd;
int nfds, rt_sel;
struct timeval tm;
int nrd_out, nrd_err;
size_t nleft_out, nleft_err;
char *ppos_out, *ppos_err;
char buff_rub[BUFF_SIZ];
int status;
int i;
//enum status_type exec_status;
chuser = strcmp(uname, "root"); /* if we are required to change user id */
//printf("chuser is %d\n", chuser);
if ((pw = getpwnam(uname)) == NULL) { /* get passwd file entry */
ACE_DEBUG((LM_DEBUG, ACE_TEXT("getpwnam error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
uid = pw->pw_uid;
gid = pw->pw_gid;
//printf("%s : uid is %d, gid is %d\n", uname, uid, gid);
/* create pipes for stdout and stderr of child process */
if (pipe(pp_out) != 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("create stdout pipe error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
if (pipe(pp_err) != 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("create stderr pipe error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
/* create child process */
pid = fork();
if (pid < 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("fork error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
if (pid == 0) { /* child process */
close(pp_out[0]); /* close read end of stdout pipe */
close(pp_err[0]); /* close read end of stderr pipe */
if (dup2(pp_out[1], 1) == -1) { /* make stdout a copy of write end of pipe */
ACE_DEBUG((LM_DEBUG, ACE_TEXT("dup error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
close(pp_out[1]);
if (dup2(pp_err[1], 2) == -1) { /* make stderr a copy of write end of pipe */
ACE_DEBUG((LM_DEBUG, ACE_TEXT("dup error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
close(pp_err[1]);
if (chuser != 0) {
//printf("now changing uid and gid\n");
uid = pw->pw_uid;
gid = pw->pw_gid;
errno = 0;
if (setgid(gid) != 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("setgid error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
if (setuid(uid) != 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("setuid error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
}
for (i = 3; i < 65536; i++)
ACE_OS::close(i);
//printf("now uid is %d, gid is %d\n", getuid(), getgid());
shellpath = pw->pw_shell;
shellname = strrchr(shellpath, '/');
execl(shellpath, shellname, "-c", cmdline, NULL); /* execute new process */
perror("");
exit(EXIT_FAILURE);
}
/* in parent process */
close(pp_out[1]); /* close write end of stdout pipe */
close(pp_err[1]); /* close write end of stderr pipe */
/* get num of fds to detect */
nfds = (pp_out[0] > pp_err[0]) ? pp_out[0] : pp_err[0];
nfds++;
/* initialization */
tm.tv_usec = (nmili_sec % 1000) * 1000;
tm.tv_sec = nmili_sec / 1000;
nleft_out = STDOUT_BUFF_SIZ;
nleft_err = STDERR_BUFF_SIZ;
outbuff.len = errbuff.len = 0;
ppos_out = outbuff.buffer;
ppos_err = errbuff.buffer;
nrd_out = nrd_err = 0;
FD_ZERO(&allfd);
FD_SET(pp_out[0], &allfd);
FD_SET(pp_err[0], &allfd);
while (1) {
readfd = allfd;
if (nmili_sec > 0)
rt_sel = select(nfds, &readfd, NULL, NULL, &tm);
else
rt_sel = select(nfds, &readfd, NULL, NULL, NULL);
if (rt_sel > 0) {
if (FD_ISSET(pp_out[0], &readfd) != 0) {
if (nleft_out > 0) {
nrd_out = read(pp_out[0], ppos_out, nleft_out);
if (nrd_out > 0) {
ppos_out += nrd_out;
//outbuff.len += nrd_out;
nleft_out -= nrd_out;
}
}
else
nrd_out = read(pp_out[0], buff_rub, sizeof(buff_rub));
}
if (FD_ISSET(pp_err[0], &readfd) != 0) {
if (nleft_err > 0) {
nrd_err = read(pp_err[0], ppos_err, nleft_err);
if (nrd_err > 0) {
ppos_err += nrd_err;
//errbuff.len += nrd_err;
nleft_err -= nrd_err;
}
}
else
nrd_err = read(pp_err[0], buff_rub, sizeof(buff_rub));
}
if (nrd_out == 0 && nrd_err == 0) {
outbuff.len = STDOUT_BUFF_SIZ - nleft_out;
errbuff.len = STDERR_BUFF_SIZ - nleft_err;
*ppos_out = *ppos_err = '\0';
break;
}
}
else
if (rt_sel == 0) {//time out
return ERR_EXEC_TIMEOUT;
}
else
if (rt_sel < 0) {
if (errno == EINTR) {
tm.tv_sec = nmili_sec / 1000; /* reset the timeout value */
tm.tv_usec = 0;
//printf("error\n");
continue;
}
else
break;
}
}
wait(&status);
if (WIFEXITED(status)) {
exitcode = WEXITSTATUS(status);
return EXEC_SUCCESS;
}
else
return ERR_INVALID_EXITCODE;
//turn exec_status;
}
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <sys/times.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "ace/SOCK_Stream.h"
#include "ace/INET_Addr.h"
#include "ace/OS.h"
#include "ace/SOCK_Dgram.h"
#include "ace/INET_Addr.h"
#include "ace/Reactor.h"
#include "ace/Synch.h"
#include "ace/OS.h"
#include "ace/INET_Addr.h"
#include "ace/Acceptor.h"
#include "ace/Connector.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/SOCK_Connector.h"
#include "ace/Reactor.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Dgram.h"
#include "ace/Log_Msg.h"
#include "ace/Log_Priority.h"
#include "ace/Get_Opt.h"
#include "time.h"
#include "pexec_share.h"
#include "wd.h"
// global variables
//struct buff_stdout outbuff;
//struct buff_stderr errbuff;
//int exitcode;
extern int errno;
enum status_type execprocess(char* uname,
char* cmdline,
int nmili_sec,
int& exitcode,
struct buff_stdout& outbuff,
struct buff_stderr& errbuff);
class PEXEC_Handler:
public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_MT_SYNCH>
{
public:
PEXEC_Handler(){
}
int init();
int open(void*);
int handle_input(ACE_HANDLE);
int handle_timeout(const ACE_Time_Value&, const void*);
int handle_close(ACE_HANDLE,ACE_Reactor_Mask);
int svc();
private:
param_pack pex_pps;
ACE_Thread_Mutex mutex_;
};
typedef ACE_Acceptor<PEXEC_Handler, ACE_SOCK_ACCEPTOR> PEXEC_Acceptor;
int
PEXEC_Handler::open(void *)
{
//ACE_DEBUG((LM_DEBUG,"the gsd_handler is going to be opened\n"));
ACE_Reactor::instance()->register_handler(this,ACE_Event_Handler::READ_MASK);
return 0;
}
int
PEXEC_Handler::handle_input(ACE_HANDLE)
{
// int rlen = peer().recv(tmp_recv,128,0);
struct param_pack pps, net_pps;
//enum status_type exec_status;
//int nint;
int rlen = peer().recv((char *)&net_pps, sizeof(net_pps), 0);
if (rlen <= -1) // can not recv messge from client
{
cout << "[" << __FILE__ << ":" << __LINE__ << "]" << "\t";
/*new add 0525*/
peer().close();
/*end add*/
ACE_ERROR_RETURN((LM_ERROR,"(%P|%t, %p)","recv message failed"),-1);
return -1;
}
if (rlen == 0){
peer().close();
return -1;
}
//convert net_pps to pps
strncpy(pps.user, net_pps.user, sizeof(pps.user));
strncpy(pps.cmdline, net_pps.cmdline, sizeof(pps.cmdline));
pps.fexitcode = ntohl(net_pps.fexitcode);
pps.milisec = ntohl(net_pps.milisec);
//cout<<"user name is "<<pps.user<<endl
// <<"cmdline is "<<pps.cmdline<<endl
//<<"exitcode only is "<<pps.exitcode_only<<endl
//<<"timeout is "<<pps.timeout<<endl;
mutex_.acquire();
pex_pps = net_pps;
activate(THR_NEW_LWP,
1, //2 new threads
1, //force active false, if already created don~Rt try again.
ACE_DEFAULT_THREAD_PRIORITY,//Use default thread priority
-1,
this,//Which ACE_Task object to create? In this case this one.
0,// don~Rt care about thread handles used
0,// don~Rt care about where stacks are created
0);//don~Rt care about stack sizes
//thread_names); // keep identifiers in thread_names
return 0;
}
int
PEXEC_Handler::handle_close(ACE_HANDLE,ACE_Reactor_Mask)
{
return 0;
}
int
PEXEC_Handler::handle_timeout(const ACE_Time_Value&, const void*) {
send_wd_heartbeat(PEXEC_SRC_TYPE);
return 0;
}
int
PEXEC_Handler::svc() {
struct buff_stdout outbuff;
struct buff_stderr errbuff;
int exitcode;
status_type exec_status;
int nint;
param_pack pps;
pps = pex_pps;
mutex_.release();
//exec cmdline
exec_status = execprocess(pps.user,
pps.cmdline,
pps.milisec,
exitcode,
outbuff,
errbuff);
nint = htonl(exec_status);
if (peer().send_n((char *)&nint, sizeof(nint), 0) == -1){
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
//cout<<"errbuff.len = "<<errbuff.len<<endl;
//cout<<errbuff.buffer<<endl;
if (exec_status == EXEC_SUCCESS) {
//send exit code back
nint = htonl(exitcode);
if (peer().send_n((char *)&nint, sizeof(nint)) == -1) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
//ACE_OS::printf("send data failed\n");
return -1;
}
if (pps.fexitcode) {
//send stdout len back
nint = htonl(outbuff.len);
if (peer().send_n((char *)&nint, sizeof(nint), 0) == -1) {
//ACE_OS::printf("send data failed\n");
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
if (outbuff.len > 0) {
if (peer().send_n(outbuff.buffer, outbuff.len, 0) == -1) {
//ACE_OS::printf("send data failed\n");
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
}
//send stderr len back
nint = htonl(errbuff.len);
if (peer().send_n((char *)&nint, sizeof(nint), 0) == -1) {
//ACE_OS::printf("send data failed\n");
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
if (errbuff.len > 0) {
if (peer().send_n(errbuff.buffer, errbuff.len, 0) == -1) {
//ACE_OS::printf("send data failed\n");
ACE_DEBUG((LM_DEBUG, ACE_TEXT("send data error : %s"),
ACE_OS::strerror(ACE_OS::last_error())));
return -1;
}
}
}
}
// peer().close();
return 0;
}
int main(int argc, char** argv)
{
ACE_INET_Addr tcp_addr(PEXEC_PORT);
ACE_INET_Addr remote_addr;
PEXEC_Acceptor *acceptor;
ACE::daemonize();
//open log
ofstream *output_file = new ofstream("/home/dware/pexecd.log", ios::out);
if (output_file && output_file->rdstate() == ios::goodbit)
ACE_LOG_MSG->msg_ostream(output_file, 1);
ACE_LOG_MSG->open(argv[0], ACE_Log_Msg::OSTREAM,0);
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%T (%t): Starting service.\n")));
acceptor = new PEXEC_Acceptor;
if(acceptor->open(tcp_addr, ACE_Reactor::instance()) == -1)
{
char error_message[64];
printf("[%s|%d]open failed: %s", __FILE__, __LINE__, strerror(errno));
}
PEXEC_Handler My_Pexec_Handler;
ACE_Time_Value timeout(HB_TIMEOUT);
ACE_Reactor::instance()->schedule_timer(&My_Pexec_Handler,0,timeout,timeout);
while(1)
ACE_Reactor::instance()->handle_events();
return 0;
}
status_type execprocess(char* uname,
char* cmdline,
int nmili_sec,
int& exitcode,
struct buff_stdout& outbuff,
struct buff_stderr& errbuff) {
int chuser;
struct passwd *pw;
int pp_out[2], pp_err[2];
pid_t pid;
uid_t uid;
gid_t gid;
char *shellpath, *shellname;
fd_set readfd, allfd;
int nfds, rt_sel;
struct timeval tm;
int nrd_out, nrd_err;
size_t nleft_out, nleft_err;
char *ppos_out, *ppos_err;
char buff_rub[BUFF_SIZ];
int status;
int i;
//enum status_type exec_status;
chuser = strcmp(uname, "root"); /* if we are required to change user id */
//printf("chuser is %d\n", chuser);
if ((pw = getpwnam(uname)) == NULL) { /* get passwd file entry */
ACE_DEBUG((LM_DEBUG, ACE_TEXT("getpwnam error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
uid = pw->pw_uid;
gid = pw->pw_gid;
//printf("%s : uid is %d, gid is %d\n", uname, uid, gid);
/* create pipes for stdout and stderr of child process */
if (pipe(pp_out) != 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("create stdout pipe error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
if (pipe(pp_err) != 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("create stderr pipe error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
/* create child process */
pid = fork();
if (pid < 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("fork error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
if (pid == 0) { /* child process */
close(pp_out[0]); /* close read end of stdout pipe */
close(pp_err[0]); /* close read end of stderr pipe */
if (dup2(pp_out[1], 1) == -1) { /* make stdout a copy of write end of pipe */
ACE_DEBUG((LM_DEBUG, ACE_TEXT("dup error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
close(pp_out[1]);
if (dup2(pp_err[1], 2) == -1) { /* make stderr a copy of write end of pipe */
ACE_DEBUG((LM_DEBUG, ACE_TEXT("dup error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
close(pp_err[1]);
if (chuser != 0) {
//printf("now changing uid and gid\n");
uid = pw->pw_uid;
gid = pw->pw_gid;
errno = 0;
if (setgid(gid) != 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("setgid error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
if (setuid(uid) != 0) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("setuid error : %s"), strerror(errno)));
return ERR_EXEC_COMMAND;
}
}
for (i = 3; i < 65536; i++)
ACE_OS::close(i);
//printf("now uid is %d, gid is %d\n", getuid(), getgid());
shellpath = pw->pw_shell;
shellname = strrchr(shellpath, '/');
execl(shellpath, shellname, "-c", cmdline, NULL); /* execute new process */
perror("");
exit(EXIT_FAILURE);
}
/* in parent process */
close(pp_out[1]); /* close write end of stdout pipe */
close(pp_err[1]); /* close write end of stderr pipe */
/* get num of fds to detect */
nfds = (pp_out[0] > pp_err[0]) ? pp_out[0] : pp_err[0];
nfds++;
/* initialization */
tm.tv_usec = (nmili_sec % 1000) * 1000;
tm.tv_sec = nmili_sec / 1000;
nleft_out = STDOUT_BUFF_SIZ;
nleft_err = STDERR_BUFF_SIZ;
outbuff.len = errbuff.len = 0;
ppos_out = outbuff.buffer;
ppos_err = errbuff.buffer;
nrd_out = nrd_err = 0;
FD_ZERO(&allfd);
FD_SET(pp_out[0], &allfd);
FD_SET(pp_err[0], &allfd);
while (1) {
readfd = allfd;
if (nmili_sec > 0)
rt_sel = select(nfds, &readfd, NULL, NULL, &tm);
else
rt_sel = select(nfds, &readfd, NULL, NULL, NULL);
if (rt_sel > 0) {
if (FD_ISSET(pp_out[0], &readfd) != 0) {
if (nleft_out > 0) {
nrd_out = read(pp_out[0], ppos_out, nleft_out);
if (nrd_out > 0) {
ppos_out += nrd_out;
//outbuff.len += nrd_out;
nleft_out -= nrd_out;
}
}
else
nrd_out = read(pp_out[0], buff_rub, sizeof(buff_rub));
}
if (FD_ISSET(pp_err[0], &readfd) != 0) {
if (nleft_err > 0) {
nrd_err = read(pp_err[0], ppos_err, nleft_err);
if (nrd_err > 0) {
ppos_err += nrd_err;
//errbuff.len += nrd_err;
nleft_err -= nrd_err;
}
}
else
nrd_err = read(pp_err[0], buff_rub, sizeof(buff_rub));
}
if (nrd_out == 0 && nrd_err == 0) {
outbuff.len = STDOUT_BUFF_SIZ - nleft_out;
errbuff.len = STDERR_BUFF_SIZ - nleft_err;
*ppos_out = *ppos_err = '\0';
break;
}
}
else
if (rt_sel == 0) {//time out
return ERR_EXEC_TIMEOUT;
}
else
if (rt_sel < 0) {
if (errno == EINTR) {
tm.tv_sec = nmili_sec / 1000; /* reset the timeout value */
tm.tv_usec = 0;
//printf("error\n");
continue;
}
else
break;
}
}
wait(&status);
if (WIFEXITED(status)) {
exitcode = WEXITSTATUS(status);
return EXEC_SUCCESS;
}
else
return ERR_INVALID_EXITCODE;
//turn exec_status;
}
相关推荐
Ace Admin 是一个强大的前端框架,专为开发企业级Web应用后台管理系统而设计。这个框架以其高效、可定制性高和用户界面友好而受到广大开发者欢迎。Ace Admin 的核心是基于Bootstrap,一个流行的前端开发框架,这使得...
**ACE完整牛逼定时器详解** ACE(Adaptive Communication Environment)是一个开源的、跨平台的C++库,专为分布式实时系统设计,提供了一系列高级网络编程接口和工具。在这个“ACE完整牛逼定时器”中,我们将深入...
ace.js编辑器是一个功能强大的开源代码编辑器,它以JavaScript为基础,并通过浏览器提供丰富的编辑功能。以下是关于ace.js编辑器的详细描述: 首先,ace.js编辑器支持多种编程语言,包括但不限于JavaScript、HTML、...
Bootstrap Ace Tab是一个基于Bootstrap和ACE框架的前端页面模板,用于实现管理界面的页签功能。Ace是一个功能丰富的代码编辑器,而Bootstrap则是一个流行的前端开发框架,提供了响应式布局和一系列预先设计的组件。...
ACE库,全称为Adaptive Communication Environment,是一款强大的跨平台网络编程框架,由Dr. Douglas C. Schmidt领导的团队在1995年开发。这个库主要用于构建高度可靠、可伸缩和可移植的分布式系统。ACE库的核心理念...
ACE Admin 是一个强大的后台管理模板,它基于 Bootstrap 框架构建,提供了丰富的组件和功能,使得开发者可以快速地构建高效、美观的Web管理界面。官方文档是学习和使用 ACE Admin 的重要参考资料,包含了所有组件的...
《ACE程序员指南:网络与系统编程的实用设计模式》是ACE资料系列的第五部分,对于深入理解和应用ACE框架至关重要。这本书是ACE学习者的必备读物,尤其适合那些希望提升网络和系统编程技能的开发者。 ACE(Adaptive ...
ACE JavaScript 插件是一款强大的代码编辑器,常用于在线编程环境、代码片段分享网站和开发者工具。它以其高效的性能、丰富的语言支持以及高度可定制性而受到开发者的喜爱。本篇将详细介绍ACE插件的核心特性、如何...
Ace Admin是一款基于Ace框架的后台管理系统模板,它提供了丰富的UI组件和优雅的界面设计,适合开发Web应用的管理后台。在“Ace Admin Tab页实现”这个主题中,我们将深入探讨如何利用Ace框架来构建和管理Tab页功能。...
- `ace-elements.js`、`ace-extra.js`:可能是ACE_ADMIN框架中定制的JavaScript插件或者功能模块。 - `ace.js`:ACE_ADMIN框架的主要JavaScript文件,它可能包含了框架的核心功能和API。 5. 在HTML结构中,可以...
### ACE自适配通信环境关键技术知识点 #### 一、ACE简介 ACE(Adaptive Communication Environment,自适配通信环境)是一种面向对象(Object-Oriented, OO)的工具包,旨在帮助开发者简化通信软件的开发过程。ACE...
Ace+Admin前端框架是一款广泛应用在企业级Web应用中的开源UI框架,它结合了Ace和AdminLTE两个优秀的前端组件库,提供了丰富的界面元素、布局选项和交互设计,旨在为开发者提供一个高效、美观且易于定制的开发环境。...
ACE(Adaptive Communication Environment)是一个跨平台的网络编程框架,由Dale Schurmann和Douglas C. Schmidt等人开发,广泛应用于分布式系统和实时网络应用。这个“ACE.rar”压缩包包含了ACE网络库的相关资源,...
AceEditor是一款广受欢迎的前端代码编辑器,以其高性能和丰富的API功能著称。这款编辑器支持多种编程语言的代码高亮显示,适用于构建在线代码编辑器、开发者工具或任何需要文本编辑功能的Web应用。在官方文档无法...
Ace Editor 是一个强大的开源代码编辑器,常用于Web应用程序中,提供丰富的文本编辑功能。它由Ajax.org B.V.开发,最初是Cloud9 IDE的一部分,现在已成为独立的项目,广泛应用于各种在线编程环境和代码编辑工具。这...
《ace技术内幕:深入解析ace架构设计与实现原理》从构架模式、编程示例和源代码3个维度系统地对经典网络框架ace(adaptivemunicationenvironment)的架构设计和实现原理进行了深入分析,它能解决4个方面的问题:,...
Ace 前端框架是一款专为后台开发人员设计的强大工具,它填补了开发者在前端技能上的空白,使得那些专注于后端技术的工程师也能轻松应对前端开发任务。Ace 框架以其高效、易用和丰富的功能特性,成为了许多开发团队的...
根据提供的文件信息,“ace各个版本下载地址”,我们可以深入探讨ACE软件的不同版本以及如何获取它们。 ### ACE软件简介 ACE(Adaptive Communication Environment)是一个开放源代码的中间件框架,主要用于高性能...
Ace Admin是一款广受欢迎的开源后台模板,专为Web应用程序设计,尤其适合开发人员构建管理界面。这个资源包含Ace的中英文双语版本,确保了在不同语言环境下的使用灵活性。Ace框架基于Bootstrap 3,一个强大的前端...