diff --git a/usr.sbin/lpd/engine.c b/usr.sbin/lpd/engine.c
index f3ef987afe5..c089b1c20b1 100644
--- a/usr.sbin/lpd/engine.c
+++ b/usr.sbin/lpd/engine.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: engine.c,v 1.3 2022/12/28 21:30:17 jmc Exp $	*/
+/*	$OpenBSD: engine.c,v 1.4 2024/11/21 13:34:51 claudio Exp $	*/
 
 /*
  * Copyright (c) 2017 Eric Faurot <eric@openbsd.org>
@@ -93,6 +93,7 @@ static void
 engine_dispatch_priv(struct imsgproc *proc, struct imsg *imsg, void *arg)
 {
 	struct lp_printer lp;
+	int fd;
 
 	if (imsg == NULL) {
 		log_debug("%s: imsg connection lost", __func__);
@@ -107,10 +108,10 @@ engine_dispatch_priv(struct imsgproc *proc, struct imsg *imsg, void *arg)
 	case IMSG_SOCK_FRONTEND:
 		m_end(proc);
 
-		if (imsg->fd == -1)
+		if ((fd = imsg_get_fd(imsg)) == -1)
 			fatalx("failed to receive frontend socket");
 
-		p_frontend = proc_attach(PROC_FRONTEND, imsg->fd);
+		p_frontend = proc_attach(PROC_FRONTEND, fd);
 		proc_setcallback(p_frontend, engine_dispatch_frontend, NULL);
 		proc_enable(p_frontend);
 		break;
diff --git a/usr.sbin/lpd/frontend.c b/usr.sbin/lpd/frontend.c
index 4521ef7ec34..faeb14c8f9e 100644
--- a/usr.sbin/lpd/frontend.c
+++ b/usr.sbin/lpd/frontend.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: frontend.c,v 1.3 2022/12/28 21:30:17 jmc Exp $	*/
+/*	$OpenBSD: frontend.c,v 1.4 2024/11/21 13:34:51 claudio Exp $	*/
 
 /*
  * Copyright (c) 2017 Eric Faurot <eric@openbsd.org>
@@ -248,6 +248,7 @@ static void
 frontend_dispatch_priv(struct imsgproc *proc, struct imsg *imsg, void *arg)
 {
 	struct listener *l;
+	int fd;
 
 	if (imsg == NULL) {
 		log_debug("%s: imsg connection lost", __func__);
@@ -260,10 +261,10 @@ frontend_dispatch_priv(struct imsgproc *proc, struct imsg *imsg, void *arg)
 
 	switch (imsg->hdr.type) {
 	case IMSG_SOCK_ENGINE:
-		if (imsg->fd == -1)
+		if ((fd = imsg_get_fd(imsg)) == -1)
 			fatalx("%s: engine socket not received", __func__);
 		m_end(proc);
-		p_engine = proc_attach(PROC_ENGINE, imsg->fd);
+		p_engine = proc_attach(PROC_ENGINE, fd);
 		proc_setcallback(p_engine, frontend_dispatch_engine, NULL);
 		proc_enable(p_engine);
 		break;
@@ -276,14 +277,14 @@ frontend_dispatch_priv(struct imsgproc *proc, struct imsg *imsg, void *arg)
 		break;
 
 	case IMSG_CONF_LISTENER:
-		if (imsg->fd == -1)
+		if ((fd = imsg_get_fd(imsg)) == -1)
 			fatalx("%s: listener socket not received", __func__);
 		if ((l = calloc(1, sizeof(*l))) == NULL)
 			fatal("%s: calloc", __func__);
 		m_get_int(proc, &l->proto);
 		m_get_sockaddr(proc, (struct sockaddr *)&l->ss);
 		m_end(proc);
-		l->sock = imsg->fd;
+		l->sock = fd;
 		TAILQ_INSERT_TAIL(&tmpconf->listeners, l, entry);
 		break;
 
diff --git a/usr.sbin/lpd/frontend_lpr.c b/usr.sbin/lpd/frontend_lpr.c
index 23b4d687843..1309c740f53 100644
--- a/usr.sbin/lpd/frontend_lpr.c
+++ b/usr.sbin/lpd/frontend_lpr.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: frontend_lpr.c,v 1.4 2022/12/28 21:30:17 jmc Exp $	*/
+/*	$OpenBSD: frontend_lpr.c,v 1.5 2024/11/21 13:34:51 claudio Exp $	*/
 
 /*
  * Copyright (c) 2017 Eric Faurot <eric@openbsd.org>
@@ -148,8 +148,6 @@ lpr_dispatch_engine(struct imsgproc *proc, struct imsg *imsg)
 		conn = SPLAY_FIND(lpr_conn_tree, &conns, &key);
 		if (conn == NULL) {
 			log_debug("%08x dead-session", key.id);
-			if (imsg->fd != -1)
-				close(imsg->fd);
 			return;
 		}
 	}
@@ -174,7 +172,7 @@ lpr_dispatch_engine(struct imsgproc *proc, struct imsg *imsg)
 		m_get_int(proc, &ack);
 		m_get_size(proc, &sz);
 		m_end(proc);
-		lpr_on_recvjob_file(conn, ack, sz, cf, imsg->fd);
+		lpr_on_recvjob_file(conn, ack, sz, cf, imsg_get_fd(imsg));
 		break;
 
 	case IMSG_LPR_DISPLAYQ:
@@ -182,7 +180,7 @@ lpr_dispatch_engine(struct imsgproc *proc, struct imsg *imsg)
 		m_get_string(proc, &hostname);
 		m_get_string(proc, &cmd);
 		m_end(proc);
-		lpr_on_request(conn, imsg->fd, hostname, cmd);
+		lpr_on_request(conn, imsg_get_fd(imsg), hostname, cmd);
 		break;
 
 	default:
diff --git a/usr.sbin/lpd/logmsg.c b/usr.sbin/lpd/logmsg.c
index b2e21c558d1..8269862a889 100644
--- a/usr.sbin/lpd/logmsg.c
+++ b/usr.sbin/lpd/logmsg.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: logmsg.c,v 1.2 2018/09/05 17:32:56 eric Exp $	*/
+/*	$OpenBSD: logmsg.c,v 1.3 2024/11/21 13:34:51 claudio Exp $	*/
 
 /*
  * Copyright (c) 2017 Eric Faurot <eric@openbsd.org>
@@ -147,10 +147,10 @@ log_imsg(struct imsgproc *proc, struct imsg *imsg)
 		log_debug("imsg src=%s closed",
 		    log_fmt_proctype(proc_gettype(proc)));
 	else
-		log_debug("imsg src=%s type=%s len=%d fd=%d",
+		log_debug("imsg src=%s type=%s len=%d",
 		    log_fmt_proctype(proc_gettype(proc)),
 		    log_fmt_imsgtype(imsg->hdr.type),
-		    imsg->hdr.len, imsg->fd);
+		    imsg->hdr.len);
 }
 
 void
diff --git a/usr.sbin/lpd/proc.c b/usr.sbin/lpd/proc.c
index 09155b9af78..21d13cd3e4a 100644
--- a/usr.sbin/lpd/proc.c
+++ b/usr.sbin/lpd/proc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: proc.c,v 1.6 2024/11/21 13:22:48 claudio Exp $	*/
+/*	$OpenBSD: proc.c,v 1.7 2024/11/21 13:34:51 claudio Exp $	*/
 
 /*
  * Copyright (c) 2017 Eric Faurot <eric@openbsd.org>
@@ -217,10 +217,15 @@ proc_new(int type)
 	if (p == NULL)
 		return NULL;
 
+	if (imsgbuf_init(&p->imsgbuf, -1) == -1) {
+		free(p);
+		return NULL;
+	}
+	imsgbuf_allow_fdpass(&p->imsgbuf);
+
 	p->type = type;
 	p->instance = -1;
 	p->pid = -1;
-	imsgbuf_init(&p->imsgbuf, -1);
 
 	TAILQ_INSERT_TAIL(&procs, p, tqe);
 
@@ -231,7 +236,6 @@ static void
 proc_setsock(struct imsgproc *p, int sock)
 {
 	p->imsgbuf.fd = sock;
-	p->imsgbuf.w.fd = sock;
 }
 
 static void
@@ -240,7 +244,7 @@ proc_event_add(struct imsgproc *p)
 	short	events;
 
 	events = EV_READ;
-	if (p->imsgbuf.w.queued)
+	if (imsgbuf_queuelen(&p->imsgbuf) > 0)
 		events |= EV_WRITE;
 
 	if (p->events)