Because filters use system(3) after forking we get 2 processes for every filter: one for waiting for system(3) to return and one running the actual filter.
Since the extra smtpd process does absolutely nothing we can just as easily copy over what system(3) does internally for execve and call the shell command directly. OK? martijn@ Index: smtpd.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtpd.c,v retrieving revision 1.335 diff -u -p -r1.335 smtpd.c --- smtpd.c 23 Sep 2020 19:11:50 -0000 1.335 +++ smtpd.c 27 Dec 2020 17:39:02 -0000 @@ -1304,7 +1304,9 @@ fork_filter_process(const char *name, co struct passwd *pw; struct group *gr; char exec[_POSIX_ARG_MAX]; + char *argp[] = { "sh", "-c", exec, NULL }; int execr; + extern char **environ; if (user == NULL) user = SMTPD_USER; @@ -1387,11 +1389,8 @@ fork_filter_process(const char *name, co */ if (read(STDERR_FILENO, &buf, 1) != 0) errx(1, "lka didn't properly close write end of error socket"); - if (system(exec) == -1) - err(1, NULL); - - /* there's no successful exit from a processor */ - _exit(1); + execve(_PATH_BSHELL, argp, environ); + err(1, "execve"); } static void