Re: mkstemp(3)

Alejandro Colomar <[email protected]>
Newsgroups org.kernel.vger.linux-man
Message-ID <afzrREof611q7MIX@devuan>
Hi Doug,

On 2026-05-07T13:22:44-0400, Douglas McIlroy wrote:
> The synopses of mkstemp(3) that I have seen, e.g. in ubuntu 13.3.0,
> say incorrectly that it is declared in <stdlib.h>.

That's conforming to POSIX.

	$ MANWIDTH=64 man 3posix mkstemp | head -n20
	MKSTEMP(3POSIX)    POSIX Programmer’s Manual    MKSTEMP(3POSIX)

	PROLOG
	     This manual page is part of the POSIX Programmer’s Manual.
	     The  Linux  implementation  of  this  interface may differ
	     (consult the corresponding Linux manual page  for  details
	     of  Linux  behavior),  or  the interface may not be imple‐
	     mented on Linux.

	NAME
	     mkstemp —— create a unique file

	SYNOPSIS
	     #include <stdlib.h>

	     int mkstemp(char *template);

	DESCRIPTION
	     Refer to mkdtemp().

<https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdtemp.html>

> It is not in gcc's
> <stdlib.h>, and should not be, because stdlib.h is part of the C
> standard and mkstemp is a construct of Unix, not C. (It returns a file
> descriptor.)

It really is in <stdlib.h>.

	alx@devuan:~$ grepc mkstemp /usr/include/
	/usr/include/stdlib.h:extern int mkstemp (char *__template) __nonnull ((1)) __wur;
	/usr/include/stdlib.h:#   define mkstemp mkstemp64

However, it is hidden behind preprocessor macros that enable it only
when POSIX extensions are enabled:

	$ man -w mkstemp | MANWIDTH=64 xargs mansectf SYNOPSIS | cat;
	mkstemp(3)          Library Functions Manual         mkstemp(3)

	SYNOPSIS
	     #include <stdlib.h>

	     int mkstemp(char *template);
	     int mkostemp(char *template, int flags);
	     int mkstemps(char *template, int suffixlen);
	     int mkostemps(char *template, int suffixlen, int flags);

	 Feature   Test   Macro   Requirements   for  glibc  (see  fea‐
	 ture_test_macros(7)):

	     mkstemp():
		 _XOPEN_SOURCE >= 500
		     || /* glibc >= 2.12: */ _POSIX_C_SOURCE >= 200809L
		     || /* glibc <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE

	     mkostemp():
		 _GNU_SOURCE

	     mkstemps():
		 /* glibc >= 2.19: */ _DEFAULT_SOURCE
		     || /* glibc <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE

	     mkostemps():
		 _GNU_SOURCE

	Linux man‐pages 6.18‐16... 2026‐02‐08                mkstemp(3)

This is, because as you say, ISO C doesn't allow that identifier to be
declared in <stdlib.h>.

I guess the reason this is in <stdlib.h> is due to Historical
Reasons (TM).

Interestingly, the function first appeared in 4.3BSD, but it had no
header: the user had to declare it manually.  Later, in 4.4BSD, it was
provided in <unistd.h> (which is the usual header where you'd expect
it).  I don't see the function in POSIX.1-1990, so I guess SysVr4 didn't
have it yet.

Later, in POSIX.1-2001, it already appears in <stdlib.h>.  So, at some
point, people decided to move it there.  POSIX doesn't say anything
about the move, though.

FreeBSD provides it in both.
Here's the commit that added it to <stdlib.h>:

	commit 3ecc48e2ea69c322abc93ef02f1b7eadac73b774
	Author: Garrett Wollman <[email protected]>
	Date:   2002-09-21 02:03:58 +0000

	    Use new visibility macros.  Reorder some disordered declarations.  Add
	    new 1003.1-2001 declarations, commented out in cases where we do not
	    implement the function.  Note that strtoq() and strtouq() are slated
	    for deletion in 6.0.  (2 of 5)

While the <unistd.h> declaration comes from 4.4BSD-Lite:

	commit 59deaec541ae8baaa58daf6c5a2196ea7de180c3
	Author: Rodney W. Grimes <[email protected]>
	Date:   1994-05-24 09:57:34 +0000

	    BSD 4.4 Lite Include Sources

It doesn't tell much.  NetBSD has some more information:

	commit 9b9e2550519f0e7c0cb730c9c3c95137dc14c314
	Author: kleink <[email protected]>
	Date:   1998-06-01 20:10:15 +0000

	    * Further name space protection reorganization: distinguish between various
	      issues of the XPG.
	    * Move setkey() prototype from <unistd.h> to this file. (XPG4)
	    * Move mkstemp(), mktemp(), ttyslot() and valloc() prototypes from <unistd.h>
	      to this file. (XPG4.2)

So, the point where it was moved seems to have been XPG4v2 (which was
later repackaged as SUSv1).  I don't know why XPG4v2 decided to move the
prototype from <unistd.h> to <stdlib.h>.  I've CCed kleink, in case it
knows (and remembers).


Have a lovely night!
Alex

> 
> Doug McIlroy

-- 
<https://www.alejandro-colomar.es>
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmn89J8ACgkQ64mZXMKQ
wqkxQw/8C8hDxkBgcM2Z01JrAtIAfyGXnkBzso/M/MueYroFuWzWI6wqqRhUjF/D
+w/DQnfXK2vF5OpJbc2qDdoEiBrBBLuYJnodWeGcZlAjZLxRV60xOMgCRsexJQWh
zlSC+28yK13e8UTSbqEh73CEmHksByaXIDg//3rJ8qdjyXmejubhRcQGw8OerHLJ
RhaRY9bRrveBoA3hdhz9DAuVBwpz/+ttL8LKR/WSnir8JTF/Bz9h+BJqPk1F6Gf5
5J3dnqCevVGAMMxaHYgCIiwoHEgVCoDvBu9ip05aC0S3eazrZEauKk6lhOI1C/OQ
/3ZqA9gliK47JTcRclMrHbA9E+vB+WGy5pnoi14T0SzqdYKs/aJV4P65r7D/grmF
TCQqphR1adAbxdd6BEdUKvBA0D/gEn8UlEZ7i0J5VXca43mWoTwMxeYa2+Elu7VT
nscffgqcjd2rJWCHqeRmLdJLllzEr9AyKD3UMmWQfeBYjflLZ5gNaBKqrsF8nYot
QTw89e51J0huI+wloXRmYbKTBLDPTDub5W6dzO0ZwP/E+qzezkbscXsKudwViyX/
UReI0pt7jkmHsotamYXSAfL2k6u94liVX78y8bFB6f8sOfLkoisYt2B5+2tHdKRV
LHFakOP1aCnUVdQUe8dsSeDbFXl6E9lq/m/k1SRZ1PQ1ItY2sGA=
=bFHk
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.