Add sys/rctl_impl.h
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / solaris2 / kopensolaris-gnu / rctl.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 <inline-syscall.h>
21 #include <rctl.h>
22 #include <sys/rctl_impl.h>
23
24 /* Docs: http://docs.sun.com/app/docs/doc/816-5167/getrctl-2?a=view
25          http://docs.sun.com/app/docs/doc/816-5168/rctlblk-size-3c?a=view  */
26
27 DECLARE_INLINE_SYSCALL (long, rctlsys, int code, const char *name, void *obuf,
28     void *nbuf, size_t obufsz, int flags);
29
30
31 int getrctl (const char *name, rctlblk_t *old_rblk, rctlblk_t *new_rblk,
32       unsigned int flags)
33 {
34   return (int)INLINE_SYSCALL (rctlsys, 6, SYS_SUB_rctlsys_get, name, old_rblk,
35     new_rblk, 0, flags);
36 }
37
38
39 int setrctl (const char *name, rctlblk_t *old_rblk, rctlblk_t *new_rblk,
40       unsigned int flags)
41 {
42   return (int)INLINE_SYSCALL (rctlsys, 6, SYS_SUB_rctlsys_set, name, old_rblk,
43     new_rblk, 0, flags);
44 }
45
46
47 size_t rctllist (char *buf, size_t bufsz)
48 {
49   return (size_t)INLINE_SYSCALL (rctlsys, 6, SYS_SUB_rctlsys_list, NULL, buf,
50     NULL, bufsz, 0);
51 }
52
53
54 int rctlctl (const char *name, rctlblk_t *blk, int flags)
55 {
56   return (int)INLINE_SYSCALL (rctlsys, 6, SYS_SUB_rctlsys_ctl, name, blk,
57     NULL, 0, flags);
58 }
59
60
61 int setprojrctl (const char *name, rctlblk_t *blk, size_t size, int flags)
62 {
63   return (int)INLINE_SYSCALL (rctlsys, 6, SYS_SUB_rctlsys_projset, name,
64     NULL, blk, size, flags);
65 }
66
67
68 hrtime_t rctlblk_get_firing_time (rctlblk_t *rblk)
69 {
70   return ((rctl_opaque_t *)rblk)->rcq_firing_time;
71 }
72
73
74 unsigned int rctlblk_get_global_action (rctlblk_t *rblk)
75 {
76   /* Note: rcq_global_flagaction contains both flags and action.  */
77   return ((rctl_opaque_t *)rblk)->rcq_global_flagaction &
78     ~RCTL_GLOBAL_ACTION_MASK;
79 }
80
81
82 unsigned int rctlblk_get_global_flags (rctlblk_t *rblk)
83 {
84   /* Note: rcq_global_flagaction contains both flags and action.  */
85   return ((rctl_opaque_t *)rblk)->rcq_global_flagaction &
86     RCTL_GLOBAL_ACTION_MASK;
87 }
88
89
90 unsigned int rctlblk_get_local_action (rctlblk_t *rblk, int *signalp)
91 {
92   /* Note: rcq_local_flagaction contains both flags and action.  */
93   return ((rctl_opaque_t *)rblk)->rcq_local_flagaction &
94     ~RCTL_LOCAL_ACTION_MASK;
95 }
96
97
98 unsigned int rctlblk_get_local_flags (rctlblk_t *rblk)
99 {
100   /* Note: rcq_local_flagaction contains both flags and action.  */
101   return ((rctl_opaque_t *)rblk)->rcq_local_flagaction &
102     RCTL_LOCAL_ACTION_MASK;
103 }
104
105
106 rctl_priv_t rctlblk_get_privilege (rctlblk_t *rblk)
107 {
108   return ((rctl_opaque_t *)rblk)->rcq_privilege;
109 }
110
111
112 id_t rctlblk_get_recipient_pid (rctlblk_t *rblk)
113 {
114   return ((rctl_opaque_t *)rblk)->rcq_local_recipient_pid;
115 }
116
117
118 rctl_qty_t rctlblk_get_value (rctlblk_t *rblk)
119 {
120   return ((rctl_opaque_t *)rblk)->rcq_value;
121 }
122
123
124 rctl_qty_t rctlblk_get_enforced_value (rctlblk_t *rblk)
125 {
126   return ((rctl_opaque_t *)rblk)->rcq_enforced_value;
127 }
128
129
130 void rctlblk_set_local_action (rctlblk_t *rblk, unsigned int action,
131      int signal)
132 {
133   /* Note: rcq_local_flagaction contains both flags and action.  */
134   rctl_opaque_t *_rblk = (rctl_opaque_t *)rblk;
135   _rblk->rcq_local_signal = signal;
136   _rblk->rcq_local_flagaction = (_rblk->rcq_local_flagaction &
137       RCTL_LOCAL_ACTION_MASK) | action;
138 }
139
140
141 void rctlblk_set_local_flags (rctlblk_t *rblk, unsigned int flags)
142 {
143   /* Note: rcq_local_flagaction contains both flags and action.  */
144   rctl_opaque_t *_rblk = (rctl_opaque_t *)rblk;
145   _rblk->rcq_local_flagaction = (_rblk->rcq_local_flagaction &
146       ~RCTL_LOCAL_ACTION_MASK) | flags;
147 }
148
149
150 void rctlblk_set_privilege (rctlblk_t *rblk, rctl_priv_t privilege)
151 {
152   ((rctl_opaque_t *)rblk)->rcq_privilege = privilege;
153 }
154
155
156 void rctlblk_set_value (rctlblk_t *rblk, rctl_qty_t value)
157 {
158   ((rctl_opaque_t *)rblk)->rcq_value = value;
159 }
160
161
162 void  rctlblk_set_recipient_pid (rctlblk_t *rblk, id_t pid)
163 {
164   ((rctl_opaque_t *)rblk)->rcq_local_recipient_pid = pid;
165 }
166
167
168 size_t rctlblk_size (void)
169 {
170   return sizeof (rctl_opaque_t);
171 }
172
173
174 int rctl_walk (int (*callback)(const char *rctlname, void *walk_data),
175       void *init_data)
176 {
177   size_t len = rctllist (NULL, 0);
178   if (len < 0)
179     return -1;
180   char *names = malloc (len);
181   if (!names)
182     return -1;
183   if (rctllist (names, len) != 0)
184     {
185       free (names);
186       return -1;
187     }
188
189   char *namesptr = names;
190   while (*namesptr)
191     {
192       callback (namesptr, init_data);
193       namesptr += strlen (namesptr) + 1;
194     }
195
196   free (names);
197   return 0;
198 }