test/smtp-dummy: add --background option and functionality

When shell executes background process using '&' the scheduling of
that new process is arbitrary. It could be that smtp-dummy doesn't
get execution time to listen() it's server socket until some other
process attempts to connect() to it. The --background option in
smtp-dummy makes it to go background *after* it started to listen
its server socket.

When --background option is used, the line "smtp_dummy_pid='<pid>'"
is printed to stdout from where shell can eval it.
This commit is contained in:
Tomi Ollila 2012-09-18 17:23:01 +03:00 committed by David Bremner
parent 1a4aa69492
commit d894887c94

View file

@ -119,6 +119,7 @@ do_smtp_to_file (FILE *peer, FILE *output)
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
const char * progname;
char *output_filename; char *output_filename;
FILE *peer_file, *output; FILE *peer_file, *output;
int sock, peer, err; int sock, peer, err;
@ -126,9 +127,31 @@ main (int argc, char *argv[])
struct hostent *hostinfo; struct hostent *hostinfo;
socklen_t peer_addr_len; socklen_t peer_addr_len;
int reuse; int reuse;
int background;
progname = argv[0];
background = 0;
for (; argc >= 2; argc--, argv++) {
if (argv[1][0] != '-')
break;
if (strcmp (argv[1], "--") == 0) {
argc--;
argv++;
break;
}
if (strcmp (argv[1], "--background") == 0) {
background = 1;
continue;
}
fprintf(stderr, "%s: unregognized option '%s'\n",
progname, argv[1]);
return 1;
}
if (argc != 2) { if (argc != 2) {
fprintf (stderr, "Usage: %s <output-file>\n", argv[0]); fprintf (stderr,
"Usage: %s [--background] <output-file>\n", progname);
return 1; return 1;
} }
@ -181,6 +204,36 @@ main (int argc, char *argv[])
return 1; return 1;
} }
if (background) {
int pid = fork ();
if (pid > 0) {
printf ("smtp_dummy_pid='%d'\n", pid);
fflush (stdout);
close (sock);
return 0;
}
if (pid < 0) {
fprintf (stderr, "Error: fork() failed: %s\n",
strerror (errno));
close (sock);
return 1;
}
/* Reached if pid == 0 (the child process). */
/* Close stdout so that the one interested in pid value will
also get EOF. */
close (STDOUT_FILENO);
/* dup2() will re-reserve fd of stdout (1) (opportunistically),
in case fd of stderr (2) is open. If that was not open we
don't care fd of stdout (1) either. */
dup2 (STDERR_FILENO, STDOUT_FILENO);
/* This process is now out of reach of shell's job control.
To resolve the rare but possible condition where this
"daemon" is started but never connected this process will
(only) have 30 seconds to exist. */
alarm (30);
}
peer_addr_len = sizeof (peer_addr); peer_addr_len = sizeof (peer_addr);
peer = accept (sock, (struct sockaddr *) &peer_addr, &peer_addr_len); peer = accept (sock, (struct sockaddr *) &peer_addr, &peer_addr_len);
if (peer == -1) { if (peer == -1) {