/*
* lftp - file transfer program
*
* Copyright (c) 1996-2012 by Alexander V. Lukyanov (lav@yars.free.net)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include "SysCmdJob.h"
#include "SignalHook.h"
#include "misc.h"
#define super Job
SysCmdJob::SysCmdJob(const char *c)
: cmd(c)
{
}
void SysCmdJob::PrepareToDie()
{
Bg();
AcceptSig(SIGTERM);
if(w)
w.borrow()->Auto();
super::PrepareToDie();
}
SysCmdJob::~SysCmdJob() {}
int SysCmdJob::Do()
{
int m=STALL;
if(w)
return m;
const char *shell=getenv("SHELL");
if(!shell)
shell="/bin/sh";
ProcWait::Signal(false);
pid_t pid;
fflush(stderr);
switch(pid=fork())
{
case(0): /* child */
setpgid(0,0);
kill(getpid(),SIGSTOP);
SignalHook::RestoreAll();
if(cmd)
execlp(shell,basename_ptr(shell),"-c",cmd.get(),NULL);
else
execlp(shell,basename_ptr(shell),NULL);
fprintf(stderr,_("execlp(%s) failed: %s\n"),shell,strerror(errno));
fflush(stderr);
_exit(1);
case(-1): /* error */
TimeoutS(1); // wait a second and retry
goto out;
}
/* parent */
int info;
waitpid(pid,&info,WUNTRACED); // wait until the process stops
w=new ProcWait(pid);
fg_data=new FgData(pid,fg);
m=MOVED;
out:
ProcWait::Signal(true);
return m;
}
int SysCmdJob::AcceptSig(int sig)
{
if(!w)
{
if(sig==SIGINT)
return WANTDIE;
return STALL;
}
w->Kill(sig);
if(sig!=SIGCONT)
AcceptSig(SIGCONT); // for the case of stopped process
return MOVED;
}