diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index 8796383..c01c0e3 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -149,7 +149,6 @@ struct slbt_exec_ctx {
 	char ** mout[2];
 	char ** rpath[2];
 	char ** sentinel;
-	FILE *	fwrapper;
 	char *	csrc;
 	int	ldirdepth;
 	char *	ldirname;
diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index 47c854e..2eb7a14 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -99,6 +99,17 @@ struct slbt_driver_ctx_impl {
 	struct slbt_error_info	erribuf[64];
 };
 
+struct slbt_exec_ctx_impl {
+	int			argc;
+	char *			args;
+	char *			shadow;
+	char *			dsoprefix;
+	size_t			size;
+	struct slbt_exec_ctx	ctx;
+	int			fdwrapper;
+	char *			vbuffer[];
+};
+
 static inline struct slbt_driver_ctx_impl * slbt_get_driver_ictx(const struct slbt_driver_ctx * dctx)
 {
 	uintptr_t addr;
@@ -139,4 +150,34 @@ static inline int slbt_driver_fdlog(const struct slbt_driver_ctx * dctx)
 	return fdctx.fdlog;
 }
 
+static inline struct slbt_exec_ctx_impl * slbt_get_exec_ictx(const struct slbt_exec_ctx * ectx)
+{
+	uintptr_t addr;
+
+	addr = (uintptr_t)ectx - offsetof(struct slbt_exec_ctx_impl,ctx);
+	return (struct slbt_exec_ctx_impl *)addr;
+}
+
+static inline int slbt_exec_get_fdwrapper(const struct slbt_exec_ctx * ectx)
+{
+	struct slbt_exec_ctx_impl * ictx;
+	ictx = slbt_get_exec_ictx(ectx);
+	return ictx->fdwrapper;
+}
+
+static inline void slbt_exec_set_fdwrapper(const struct slbt_exec_ctx * ectx, int fd)
+{
+	struct slbt_exec_ctx_impl * ictx;
+	ictx = slbt_get_exec_ictx(ectx);
+	ictx->fdwrapper = fd;
+}
+
+static inline void slbt_exec_close_fdwrapper(const struct slbt_exec_ctx * ectx)
+{
+	struct slbt_exec_ctx_impl * ictx;
+	ictx = slbt_get_exec_ictx(ectx);
+	close(ictx->fdwrapper);
+	ictx->fdwrapper = (-1);
+}
+
 #endif
diff --git a/src/logic/slbt_exec_ctx.c b/src/logic/slbt_exec_ctx.c
index bc89ca4..230dd7f 100644
--- a/src/logic/slbt_exec_ctx.c
+++ b/src/logic/slbt_exec_ctx.c
@@ -10,21 +10,11 @@
 #include <string.h>
 
 #include <slibtool/slibtool.h>
+#include "slibtool_driver_impl.h"
 #include "slibtool_errinfo_impl.h"
 
 #define SLBT_ARGV_SPARE_PTRS	16
 
-struct slbt_exec_ctx_impl {
-	int			argc;
-	char *			args;
-	char *			shadow;
-	char *			dsoprefix;
-	size_t			size;
-	struct slbt_exec_ctx	ctx;
-	char *			vbuffer[];
-};
-
-
 static size_t slbt_parse_comma_separated_flags(
 	const char *	str,
 	int *		argc)
@@ -135,7 +125,8 @@ static struct slbt_exec_ctx_impl * slbt_exec_ctx_alloc(
 	ictx->size   = size;
 	ictx->shadow = shadow;
 
-	ictx->ctx.csrc = csrc;
+	ictx->ctx.csrc  = csrc;
+	ictx->fdwrapper = (-1);
 
 	return ictx;
 }
@@ -470,12 +461,13 @@ static int slbt_free_exec_ctx_impl(
 	struct slbt_exec_ctx_impl *	ictx,
 	int				status)
 {
-	if (ictx->ctx.fwrapper)
-		fclose(ictx->ctx.fwrapper);
+	if (ictx->fdwrapper >= 0)
+		close(ictx->fdwrapper);
 
 	free(ictx->args);
 	free(ictx->shadow);
 	free (ictx);
+
 	return status;
 }
 
diff --git a/src/logic/slbt_exec_link.c b/src/logic/slbt_exec_link.c
index 8ad1af3..c9f62e4 100644
--- a/src/logic/slbt_exec_link.c
+++ b/src/logic/slbt_exec_link.c
@@ -15,6 +15,7 @@
 #include <slibtool/slibtool.h>
 #include "slibtool_spawn_impl.h"
 #include "slibtool_mkdir_impl.h"
+#include "slibtool_driver_impl.h"
 #include "slibtool_dprintf_impl.h"
 #include "slibtool_errinfo_impl.h"
 #include "slibtool_mapfile_impl.h"
@@ -242,6 +243,7 @@ static int slbt_exec_link_adjust_argument_vector(
 	bool				flibrary)
 {
 	int			fd;
+	int			fdwrap;
 	char ** 		carg;
 	char ** 		aarg;
 	char *			ldir;
@@ -383,10 +385,10 @@ static int slbt_exec_link_adjust_argument_vector(
 				mark   = strrchr(*carg,'/');
 				*mark  = 0;
 
-				if (ectx->fwrapper) {
+				if ((fdwrap = slbt_exec_get_fdwrapper(ectx)) >= 0) {
 					*slash = 0;
 
-					if (fprintf(ectx->fwrapper,
+					if (slbt_dprintf(fdwrap,
 							"DL_PATH=\"$DL_PATH$COLON%s/%s\"\n"
 							"COLON=':'\n\n",
 							cwd,arg) < 0)
@@ -1259,6 +1261,7 @@ static int slbt_exec_link_create_executable(
 	struct slbt_exec_ctx *		ectx,
 	const char *			exefilename)
 {
+	int	fdwrap;
 	char ** parg;
 	char *	base;
 	char	cwd    [PATH_MAX];
@@ -1297,18 +1300,22 @@ static int slbt_exec_link_create_executable(
 	if (dctx->cctx->drvflags & SLBT_DRIVER_NO_UNDEFINED)
 		*ectx->noundef = "-Wl,--no-undefined";
 
-	/* executable wrapper: header */
-	if ((size_t)snprintf(wrapper,sizeof(wrapper),"%s.wrapper.tmp",
+	/* executable wrapper: create */
+	if ((size_t)snprintf(wrapper,sizeof(wrapper),
+				"%s.wrapper.tmp",
 				dctx->cctx->output)
 			>= sizeof(wrapper))
 		return SLBT_BUFFER_ERROR(dctx);
 
-	if (!(ectx->fwrapper = fopen(wrapper,"w")))
+	if ((fdwrap = openat(AT_FDCWD,wrapper,O_RDWR|O_CREAT|O_TRUNC,0644)) < 0)
 		return SLBT_SYSTEM_ERROR(dctx);
 
+	slbt_exec_set_fdwrapper(ectx,fdwrap);
+
+	/* executable wrapper: header */
 	verinfo = slbt_source_version();
 
-	if (fprintf(ectx->fwrapper,
+	if (slbt_dprintf(fdwrap,
 			"#!/bin/sh\n"
 			"# libtool compatible executable wrapper\n"
 			"# Generated by %s (slibtool %d.%d.%d)\n"
@@ -1372,7 +1379,7 @@ static int slbt_exec_link_create_executable(
 	/* executable wrapper: footer */
 	fabspath = (exefilename[0] == '/');
 
-	if (fprintf(ectx->fwrapper,
+	if (slbt_dprintf(fdwrap,
 			"DL_PATH=\"$DL_PATH$LCOLON$%s\"\n\n"
 			"export %s=$DL_PATH\n\n"
 			"if [ `basename \"$0\"` = \"%s\" ]; then\n"
@@ -1407,8 +1414,7 @@ static int slbt_exec_link_create_executable(
 			SLBT_SPAWN_ERROR(dctx));
 
 	/* executable wrapper: finalize */
-	fclose(ectx->fwrapper);
-	ectx->fwrapper = 0;
+	slbt_exec_close_fdwrapper(ectx);
 
 	if (slbt_create_symlink(
 			dctx,ectx,