|
Home > Archive > Unix Programming > January 2005 > execve with daemon process
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
execve with daemon process
|
|
| James Vanns 2005-01-25, 5:52 pm |
| All,
I have a small problem with execve. The catch is that I have forked a
process from a process that is already running as a daemon (no
controlling terminal and stdin/out redirected to /dev/null etc.).
The daemon function is as so (Ignore C++ specific stuff - its
unimportant):
Oh BTW apologies for the formatting of the code - no doubt Google will
fsck it up.
template<class T> void JServerSocket<T>::daemonise (void) {
switch (fork ()) {
case 0:
break;
case -1:
exit (EXIT_FAILURE);
break;
default:
exit (EXIT_SUCCESS);
break;
}
setsid ();
switch (fork ()) {
case 0:
break;
case -1:
exit (EXIT_FAILURE);
break;
default:
exit (EXIT_SUCCESS);
break;
}
chdir ("/");
umask (077);
// Don't close stderr
close (1);
close (0);
int i = open ("/dev/null", O_RDWR); // This should be 0
dup (i); // This should be 1
}
Later in the program I have this:
try {
switch (fork ()) {
case -1:
// Ah crap!
break;
case 0:
for (int i = 0 ; i < sysconf (_SC_OPEN_MAX) ; i++) {
int flags = fcntl (i, F_GETFD);
if (flags < 0)
continue;
if (!(flags & FD_CLOEXEC))
fcntl (i, F_SETFD, flags |= FD_CLOEXEC);
}
{
char* const env[1] = {NULL};
char* const arg[3] = {"/usr/bin/whatever", "start", NULL};
if (execve (arg[0], arg, env) < 0)
// Ah crap!
}
// CS:IP should NEVER get here! Well, unless execve itself
fails.
break;
default:
// A signal handler is setup elsewhere for SIGCHLD and
waitpid().
break;
}
}
Now, execve doesn't return therefore doesn't fail. However, nothing
actually gets executed! Is this because the parent process is
'daemonized' - it has no open FDs etc (specifically stdin/out). The
program being executed is actually a shell script.
Is there a way around this? Any help/light shed would be appreciated.
Regards
Jim
PS. I *know* about the security implications of this etc. it's not a
nice solution I know - just trying to get the thing working at the
moment!
| |
| Barry Margolin 2005-01-26, 2:48 am |
| In article <1106673089.141767.271560@z14g2000cwz.googlegroups.com>,
"James Vanns" <james.vanns@gmail.com> wrote:
> Now, execve doesn't return therefore doesn't fail. However, nothing
> actually gets executed! Is this because the parent process is
> 'daemonized' - it has no open FDs etc (specifically stdin/out). The
> program being executed is actually a shell script.
You should have stdin/out/err connected to /dev/null, not closed, to
avoid problems.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
| |
| James Vanns 2005-01-26, 6:02 pm |
| Sorry - makes no difference! stdin/out are redirected to /dev/null and
stderr is a valid file descriptor too - redirects to a terminal. I have
confirmed this with proc/<pid>/fd
Any other suggestions?
Barry Margolin wrote:
> In article <1106673089.141767.271560@z14g2000cwz.googlegroups.com>,
> "James Vanns" <james.vanns@gmail.com> wrote:
>
>
> You should have stdin/out/err connected to /dev/null, not closed, to
> avoid problems.
>
> --
> Barry Margolin, barmar@alum.mit.edu
> Arlington, MA
> *** PLEASE post questions in newsgroups, not directly to me ***
| |
| Barry Margolin 2005-01-26, 8:47 pm |
| In article <1106761858.286396.25500@c13g2000cwb.googlegroups.com>,
"James Vanns" <james.vanns@gmail.com> wrote:
> Sorry - makes no difference! stdin/out are redirected to /dev/null and
> stderr is a valid file descriptor too - redirects to a terminal. I have
> confirmed this with proc/<pid>/fd
>
> Any other suggestions?
Run it under a debugger, or trace the system calls?
[vbcol=seagreen]
>
> Barry Margolin wrote:
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
| |
| Villy Kruse 2005-01-27, 2:51 am |
| On 26 Jan 2005 09:50:58 -0800,
James Vanns <james.vanns@gmail.com> wrote:
> Sorry - makes no difference! stdin/out are redirected to /dev/null and
> stderr is a valid file descriptor too - redirects to a terminal. I have
> confirmed this with proc/<pid>/fd
>
A deamon should not have stderr directed to a terminal. A log file
would be a better destination for stderr data. Remember that either
nobody is using the terminal and then messages to it will be lost; or
the terminal is used in which case messages from a daemon is just anoying
interferrence with the work at the terminal.
VIlly
| |
| James Vanns 2005-01-27, 7:54 am |
| No no no! When I say that stderr is redirected to a terminal I mean
exactly that!
$ daemon 2> /dev/pts/3
Where /dev/pts/3 is a terminal I am monitoring. It could be a file if I
wanted. As the daemon forks it writes to a log file etc. only
exceptions are thrown and printed to stderr. This is purely for my
clarity. The point is that stdin/out and err are all 'pointing' to some
valid file.
Using gdb is gonna be difficult to say the least - it's a daemon for a
start and it forks n processes one of which could fork and execve this
script.
I'll comment out the daemonise() function and try from there. But if
anyone really does have any idea as to why this would happen I'd love
to hear from you!
Jim
PS. I should have mentioned earlier - when uing waitpid() in the parent
(to wait for the exit code of the script in the child) the return
status is indeed a success (0). Again however, nothing actually gets
executed.
| |
| Alex Fraser 2005-01-27, 7:54 am |
| "James Vanns" <james.vanns@gmail.com> wrote in message
news:1106820000.207900.207560@z14g2000cwz.googlegroups.com...
> Using gdb is gonna be difficult to say the least - it's a daemon for a
> start and it forks n processes one of which could fork and execve this
> script.
First, I'd replace the script that you're trying to exec with a trivial
program, eg:
#include <stdio.h>
int main(void) {
fputs("something you'll recognise\n", stderr);
return 0;
}
Then run the daemon under a system call tracer (logging the output) and
somehow provoke it to go through the code you pasted. Once that works, put
the script back in place and repeat. Another thing to try is exec'ing the
shell (and passing the script path as a parameter) rather than the script
itself.
> I'll comment out the daemonise() function and try from there. But if
> anyone really does have any idea as to why this would happen I'd love
> to hear from you!
AFAIK, there's nothing inherently special about the fact you are doing this
in a "daemonised" process.
> PS. I should have mentioned earlier - when uing waitpid() in the parent
> (to wait for the exit code of the script in the child) the return
> status is indeed a success (0). Again however, nothing actually gets
> executed.
What does the script do? Perhaps something in the script does not work as
expected because of the environment (descriptors, signals, environment
variables, current directory, uid/gid etc).
Alex
| |
| James Vanns 2005-01-27, 7:54 am |
| Spot on! You pretty much just described what I'm doing now. It is
indeed something in the script. Grr. I replaced it with
a) A Binary
b) A trivial script
Both of these work - so something more complex/sinister in the real
script is causing it to fail in a peculiar way.
Well, at least now I have an angle!
Cheers all.
Jim
|
|
|
|
|