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