From: Alejandro Colomar <alx@kernel.org>
To: Douglas McIlroy <douglas.mcilroy@dartmouth.edu>
Cc: linux-man <linux-man@vger.kernel.org>, kleink <kleink@netbsd.org>,
Garrett Wollman <wollman@freebsd.org>
Subject: Re: mkstemp(3)
Date: Thu, 7 May 2026 22:23:01 +0200 [thread overview]
Message-ID: <afzrREof611q7MIX@devuan> (raw)
In-Reply-To: <CAKH6PiUk2L35i4i4TYkEP5VWH8DWodgRDLqUTSRQ27MB20HRhA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4486 bytes --]
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 <wollman@FreeBSD.org>
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 <rgrimes@FreeBSD.org>
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 <kleink@NetBSD.org>
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>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2026-05-07 20:23 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-07 17:22 mkstemp(3) Douglas McIlroy
2026-05-07 20:23 ` Alejandro Colomar [this message]
2026-05-07 21:19 ` mkstemp(3) Garrett Wollman
2026-05-07 23:29 ` mkstemp(3) Alejandro Colomar
2026-05-08 1:34 ` mkstemp(3) Douglas McIlroy
2026-05-08 2:32 ` mkstemp(3) Garrett Wollman
2026-05-08 12:33 ` mkstemp(3) Alejandro Colomar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=afzrREof611q7MIX@devuan \
--to=alx@kernel.org \
--cc=douglas.mcilroy@dartmouth.edu \
--cc=kleink@netbsd.org \
--cc=linux-man@vger.kernel.org \
--cc=wollman@freebsd.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox