+/******************************************************************************/
+/* Taint-checked file opens */
+static inline uschar *
+is_tainted2(const void *p, int lflags, const char* fmt, ...)
+{
+va_list ap;
+uschar *msg;
+rmark mark;
+
+if (!is_tainted(p))
+ return NULL;
+
+mark = store_mark();
+va_start(ap, fmt);
+msg = string_from_gstring(string_vformat(NULL, SVFMT_TAINT_NOCHK|SVFMT_EXTEND, fmt, ap));
+va_end(ap);
+
+#ifdef ALLOW_INSECURE_TAINTED_DATA
+if (allow_insecure_tainted_data)
+ {
+ if LOGGING(tainted) log_write(0, LOG_MAIN, "Warning: %s", msg);
+ store_reset(mark);
+ return NULL;
+ }
+#endif
+
+if (lflags) log_write(0, lflags, "%s", msg);
+return msg; /* no store_reset(), as the message might be used afterwards and Exim
+ is expected to exit anyway, so we do not care about the leaked
+ storage */
+}
+
+static inline int
+exim_open2(const char *pathname, int flags)
+{
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+ return open(pathname, flags);
+errno = EACCES;
+return -1;
+}
+
+static inline int
+exim_open(const char *pathname, int flags, mode_t mode)
+{
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+ return open(pathname, flags, mode);
+errno = EACCES;
+return -1;
+}
+#ifdef EXIM_HAVE_OPENAT
+static inline int
+exim_openat(int dirfd, const char *pathname, int flags)
+{
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+ return openat(dirfd, pathname, flags);
+errno = EACCES;
+return -1;
+}
+static inline int
+exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
+{
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+ return openat(dirfd, pathname, flags, mode);
+errno = EACCES;
+return -1;
+}
+#endif
+
+static inline FILE *
+exim_fopen(const char *pathname, const char *mode)
+{
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+ return fopen(pathname, mode);
+errno = EACCES;
+return NULL;
+}
+
+static inline DIR *
+exim_opendir(const uschar * name)
+{
+if (!is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name))
+ return opendir(CCS name);
+errno = EACCES;
+return NULL;
+}
+
+/******************************************************************************/
+# if !defined(COMPILE_UTILITY)
+/* Process manipulation */
+
+static inline pid_t
+exim_fork(const unsigned char * purpose)
+{
+pid_t pid;
+DEBUG(D_any) debug_printf("%s forking for %s\n", process_purpose, purpose);
+if ((pid = fork()) == 0)
+ {
+ process_purpose = purpose;
+ DEBUG(D_any) debug_printf("postfork: %s\n", purpose);
+ }
+else
+ {
+ testharness_pause_ms(100); /* let child work */
+ DEBUG(D_any) debug_printf("%s forked for %s: %d\n", process_purpose, purpose, (int)pid);
+ }
+return pid;
+}
+
+
+static inline pid_t
+child_open_exim(int * fdptr, const uschar * purpose)
+{ return child_open_exim_function(fdptr, purpose); }
+
+static inline pid_t
+child_open_exim2(int * fdptr, uschar * sender,
+ uschar * sender_auth, const uschar * purpose)
+{ return child_open_exim2_function(fdptr, sender, sender_auth, purpose); }
+
+static inline pid_t
+child_open(uschar **argv, uschar **envp, int newumask, int *infdptr,
+ int *outfdptr, BOOL make_leader, const uschar * purpose)
+{ return child_open_function(argv, envp, newumask, infdptr,
+ outfdptr, make_leader, purpose);
+}
+
+# endif /* !COMPILE_UTILITY */
+
+/******************************************************************************/