On Tue, 20 Oct 2026, Andrea Venturoli wrote:
Hello.
I've got:
_ FreeBSD 14.4;
_ a mail jail;
_ cyrus-imapd312 installed inside the jail;
_ a file "/usr/local/etc/rc.conf.d/cyrus_imapd" (inside the jai), with
cyrus_imapd_enable="YES" as content.
With this setup Cyrus IMAP has always started at boot (or when
restarting the jail).
Upgrade to 15.1 and it doesn't anymore.
However, "service imapd start" does its job.
All the other daemons (mimedefang, rbldnsd, saslauthd, opendkim,
etc...), set up in the same way, work.
How do I get around this?
Or, at least, I do I debug this?
I just ran into this after upgrading from 14.5-STABLE to 15.1-STABLE. I
have not yet found out why it happens as I have other things needing
fixing, but it appears from running a test program that dup(0) is
returning 4 instead of 3 when imapd starts, which causes this to fail in
master/master.c:
/* we reserve fds for children to communicate with us, so they
better be available. */
for (fd = STATUS_FD; fd <= LISTEN_FD; fd++) {
close(fd);
if (dup(0) != fd) fatalf(2, "couldn't dup fd 0: %m");
}
As you noticed, that is only happening during the jail startup and not
when the service is started manually. In my case, I am using the base
jail command and not ezjail.
I am attaching a simple workaround for the startup script, but it is not
the solution. The workaround is duplicating stdin to file descriptor 3,
which placates that test because 3 can be closed and returned in the
dup(0) call.
Sean
--
[email protected]
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int main(void)
{
int fd, flags, n;
for (fd = 3; fd <= 5; fd++)
{
errno = 0;
flags = fcntl(fd, F_GETFD);
printf("before close(%d): flags=%d errno=%d (%s)\n", fd, flags, errno,
strerror(errno));
if (close(fd) == -1 && errno != EBADF)
{
printf("close: %s\n", strerror(errno));
return (1);
}
errno = 0;
n = dup(0);
printf("expected=%d, dup(0)=%d, errno=%d (%s)\n", fd, n, errno,
strerror(errno));
if (n != fd)
{
printf("Mismatch at fd %d\n", fd);
return (1);
}
}
return (0);
}
diff --git a/mail/cyrus-imapd38/files/imapd.in
b/mail/cyrus-imapd38/files/imapd.in
index 89e6c2ce8ea1..443eb947cae2 100644
--- a/mail/cyrus-imapd38/files/imapd.in
+++ b/mail/cyrus-imapd38/files/imapd.in
@@ -25,9 +25,14 @@ rcvar=cyrus_imapd_enable
command="%%PREFIX%%/cyrus/libexec/master"
pidfile="/var/run/cyrus-master.pid"
required_files="%%PREFIX%%/etc/cyrus.conf %%PREFIX%%/etc/imapd.conf"
+start_cmd="cyrus_imapd_start"
stop_postcmd="cyrus_imapd_poststop"
extra_commands="reload"
+cyrus_imapd_start() {
+ limits -C daemon ${command} ${cyrus_imapd_flags} 3<&0
+}
+
cyrus_imapd_poststop() {
/bin/rm -f ${pidfile}
}