1 /* Copyright (c) 1998-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <sys/time.h>
21 #include <libc-lock.h>
22 #include <rpc/rpc.h>
23 
24 /* The RPC code is not threadsafe, but new code should be threadsafe. */
25 
26 __libc_lock_define_initialized (static, createxid_lock)
27 
28 static pid_t is_initialized;
29 static struct drand48_data __rpc_lrand48_data;
30 
31 unsigned long
_create_xid(void)32 _create_xid (void)
33 {
34   long int res;
35 
36   __libc_lock_lock (createxid_lock);
37 
38   pid_t pid = getpid ();
39   if (is_initialized != pid)
40     {
41       struct timespec now;
42 
43       __clock_gettime (CLOCK_REALTIME, &now);
44       __srand48_r (now.tv_sec ^ now.tv_nsec ^ pid,
45 		   &__rpc_lrand48_data);
46       is_initialized = pid;
47     }
48 
49   lrand48_r (&__rpc_lrand48_data, &res);
50 
51   __libc_lock_unlock (createxid_lock);
52 
53   return res;
54 }
55