Skip to content

Commit

Permalink
Merge pull request #843 from aschnell/master
Browse files Browse the repository at this point in the history
- improved error handling in SystemCmd
  • Loading branch information
aschnell authored Oct 23, 2023
2 parents 00be91f + d17442a commit 9647066
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 36 deletions.
61 changes: 31 additions & 30 deletions snapper/SystemCmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,6 @@ SystemCmd::~SystemCmd()
}


void
SystemCmd::closeOpenFds() const
{
int max_fd = getdtablesize();
for( int fd = 3; fd < max_fd; fd++ )
{
close(fd);
}
}


void
SystemCmd::execute()
{
Expand Down Expand Up @@ -123,38 +112,50 @@ SystemCmd::closeOpenFds() const
}
y2deb("sout:" << pfds[0].fd << " serr:" << pfds[1].fd);

const int max_fd = getdtablesize();

const TmpForExec args_p(make_args());
const TmpForExec env_p(make_env());

switch( (Pid_i=fork()) )
{
case 0:
{
// Do not use exit() here. Use _exit() instead.

// Only use async‐signal‐safe functions here, see fork(2) and
// signal-safety(7).

if( dup2( sout[1], STDOUT_FILENO )<0 )
{
y2err("dup2 stdout child failed errno:" << errno << " (" << stringerror(errno) << ")");
}
_exit(125);
if( dup2( serr[1], STDERR_FILENO )<0 )
{
y2err("dup2 stderr child failed errno:" << errno << " (" << stringerror(errno) << ")");
}
_exit(125);
if( close( sout[0] )<0 )
{
y2err("close child failed errno:" << errno << " (" << stringerror(errno) << ")");
}
_exit(125);
if( close( serr[0] )<0 )
{
y2err("close child failed errno:" << errno << " (" << stringerror(errno) << ")");
}
_exit(125);

for (int fd = 3; fd < max_fd; ++fd)
close(fd);

execvpe(args.get_values()[0].c_str(), args_p.get(), env_p.get());

closeOpenFds();
if (errno == ENOENT)
_exit(127);
if (errno == ENOEXEC || errno == EACCES || errno == EISDIR)
_exit(126);
_exit(125);
}
break;

Ret_i = execvpe(args.get_values()[0].c_str(), args_p.get(), env_p.get());
y2err("SHOULD NOT HAPPEN execvpe returned ret=" << Ret_i << " errno=" << errno);
break;
case -1:
{
Ret_i = -1;
break;
}
break;

default:
{
if( close( sout[1] )<0 )
{
y2err("close parent failed errno:" << errno << " (" << stringerror(errno) << ")");
Expand All @@ -177,8 +178,8 @@ SystemCmd::closeOpenFds() const

doWait( Ret_i );
y2mil("stopwatch " << stopwatch << " for \"" << cmd() << "\"");

break;
}
break;
}
}
else
Expand Down
8 changes: 2 additions & 6 deletions snapper/SystemCmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ namespace snapper
private:

void invalidate();
void closeOpenFds() const;
void execute();
bool doWait(int& Ret_ir);
void checkOutput();
Expand Down Expand Up @@ -140,17 +139,14 @@ namespace snapper
/**
* Constructs the args for the child process.
*
* Must not be called after exec since allocating the memory
* for the vector is not allowed then (in a multithreaded
* program), see fork(2) and signal-safety(7). So simply call
* it right before fork.
* Not async‐signal‐safe, see fork(2) and signal-safety(7).
*/
TmpForExec make_args() const;

/**
* Constructs the environment for the child process.
*
* Same not as for make_args().
* Not async‐signal‐safe, see fork(2) and signal-safety(7).
*/
TmpForExec make_env() const;

Expand Down

0 comments on commit 9647066

Please sign in to comment.