firasuke / cross / slibtool

Forked from cross/slibtool a month ago
Clone

Blame src/internal/slibtool_tmpfile_impl.c

86d1f4
/*******************************************************************/
86d1f4
/*  slibtool: a strong libtool implementation, written in C        */
86d1f4
/*  Copyright (C) 2016--2024  SysDeer Technologies, LLC            */
86d1f4
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
86d1f4
/*******************************************************************/
86d1f4
86d1f4
#define _GNU_SOURCE
86d1f4
#include <time.h>
86d1f4
#include <fcntl.h>
86d1f4
#include <limits.h>
86d1f4
#include <stdlib.h>
86d1f4
#include <unistd.h>
86d1f4
#include <string.h>
86d1f4
#include <stdio.h>
86d1f4
#include <inttypes.h>
86d1f4
86d1f4
#include "slibtool_visibility_impl.h"
86d1f4
86d1f4
#define PPRIX64 "%"PRIx64
86d1f4
86d1f4
/* mkostemp might be guarded by non-standard macros */
86d1f4
/* unless HAVE_NO_MKOSTEMP, assume it is available */
86d1f4
extern int mkstemp(char *);
86d1f4
extern int mkostemp(char *, int);
86d1f4
86d1f4
/* __fs_tmpfile() atomically provides a private tmpfile */
86d1f4
static int slbt_tmpfile_by_framework(void)
86d1f4
{
86d1f4
#ifdef _MIDIPIX_ABI
86d1f4
	extern int __fs_tmpfile(int);
86d1f4
	return __fs_tmpfile(O_CLOEXEC);
86d1f4
#else
86d1f4
	return (-1);
86d1f4
#endif
86d1f4
}
86d1f4
86d1f4
/* O_TMPFILE atomically provides a private tmpfile */
86d1f4
static int slbt_tmpfile_by_kernel(void)
86d1f4
{
86d1f4
#ifdef O_TMPFILE
86d1f4
	return openat(AT_FDCWD,"/tmp",O_RDWR|O_TMPFILE|O_CLOEXEC,0);
86d1f4
#else
86d1f4
	return (-1);
86d1f4
#endif
86d1f4
}
86d1f4
86d1f4
/* mk{o}stemp() provides a non-private tmpfile */
86d1f4
static int slbt_mkostemp(char * tmplate)
86d1f4
{
86d1f4
	int fd;
86d1f4
#ifdef HAVE_NO_MKOSTEMP
86d1f4
	if ((fd = mkstemp(tmplate)) >= 0)
86d1f4
		fcntl(fd,F_SETFD,FD_CLOEXEC);
86d1f4
#else
86d1f4
	fd = mkostemp(tmplate,O_CLOEXEC);
86d1f4
#endif
86d1f4
	return fd;
86d1f4
}
86d1f4
86d1f4
slbt_hidden int slbt_tmpfile(void)
86d1f4
{
86d1f4
	int             fd;
86d1f4
	void *          addr;
86d1f4
	char            tmplate[128];
86d1f4
86d1f4
	/* try with __fs_tmpfile() */
86d1f4
	if ((fd = slbt_tmpfile_by_framework()) >= 0)
86d1f4
		return fd;
86d1f4
86d1f4
	/* try with O_TMPFILE */
86d1f4
	if ((fd = slbt_tmpfile_by_kernel()) >= 0)
86d1f4
		return fd;
86d1f4
86d1f4
	/* fallback to mk{o}stemp */
86d1f4
	addr = tmplate;
86d1f4
	memset(tmplate,0,sizeof(tmplate));
86d1f4
	snprintf(tmplate,sizeof(tmplate),
86d1f4
		"/tmp/"
86d1f4
		".slibtool.tmpfile"
86d1f4
		".time."PPRIX64
86d1f4
		".salt.%p"
86d1f4
		".pid.%d"
86d1f4
		".XXXXXXXXXXXX",
86d1f4
		time(0),
86d1f4
		addr,
86d1f4
		getpid());
86d1f4
86d1f4
	return slbt_mkostemp(tmplate);
86d1f4
}