053098a97ce00058a9be79748a4e7d64435ae816
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / solaris2 / kopensolaris-gnu / privP.c
1 /* Copyright (C) 2008 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by David Bartley <dtbartle@csclub.uwaterloo.ca>, 2008.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <privP.h>
21 #include <inline-syscall.h>
22 #include <priv.h>
23 #include <sys/priocntl.h>
24 #include <alloca.h>
25 #include <bits/libc-lock.h>
26
27 DECLARE_INLINE_SYSCALL (int, privsys, int code, priv_op_t op,
28     priv_ptype_t type, void *buf, size_t bufsize, int itype);
29
30 /* Docs: http://docs.sun.com/app/docs/doc/816-5168/6mbb3hrjc?a=view
31          http://docs.sun.com/app/docs/doc/816-5167/setppriv-2?a=view */
32
33 __libc_lock_define (static, privimplinfo_lock);
34
35 libc_freeres_ptr (static priv_impl_info_t *__info);
36
37 int __getprivimplinfo_cached (priv_impl_info_t **info)
38 {
39   if (__info)
40     {
41       *info = __info;
42       return 0;
43     }
44
45   __libc_lock_lock (privimplinfo_lock);
46
47   /* First call: get header.  */
48   priv_impl_info_t _info;
49   int result = INLINE_SYSCALL (privsys, 6, PRIVSYS_GETIMPLINFO, 0, 0, &_info,
50       sizeof(_info), 0);
51   if (result != 0)
52     {
53       __libc_lock_unlock (privimplinfo_lock);
54       return -1;
55     }
56
57   /* Second call: alloc and get full priv_impl_info_t.  */
58   size_t info_size = PRIV_IMPL_INFO_SIZE (&_info);
59   __info = malloc (info_size);
60   result = INLINE_SYSCALL (privsys, 6, PRIVSYS_GETIMPLINFO, 0, 0, __info,
61       info_size, 0);
62   if (result != 0)
63     {
64       __libc_lock_unlock (privimplinfo_lock);
65       return -1;
66     }
67
68   __libc_lock_unlock (privimplinfo_lock);
69
70   *info = __info;
71   return 0;
72 }