This file is indexed.

/usr/include/nih/alloc.h is in libnih-dev 1.0.3-6ubuntu2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/* libnih
 *
 * Copyright © 2009 Scott James Remnant <scott@netsplit.com>.
 * Copyright © 2009 Canonical Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef NIH_ALLOC_H
#define NIH_ALLOC_H

/**
 * All functions in libnih use these functions to allocate and destroy
 * objects in memory, they wrap the usual malloc(), realloc() and free()
 * calls to provide a multi-reference hierarchial allocator.
 *
 * When you allocate an object using nih_alloc() or nih_new(), you pass
 * an optional parent.  This may be any other object allocated with these
 * functions.  A reference from the parent to the newly allocated object
 * is created.  If no parent is passed the object is referenced from the
 * special NULL parent.
 *
 * You may add additional references to the object using nih_ref(), again
 * passing any other object allocated with these functions as the parent
 * or the special NULL parent.
 *
 * Thus any object may have one or more parents.  Indeed, an object
 * (including the NULL parent) may hold multiple references to another
 * object.
 *
 * When an object is freed, the references to its children are discarded
 * and if it held the last reference to one of those children, the child
 * is freed as well.
 *
 * This takes away a lof the effort of object management; allocating the
 * members of a structure with the structure as a parent means that if you
 * free the structure, all of its members will be freed as well.
 *
 * You may still need to do additional clean-up, for example closing file
 * descriptors or other non-allocated resources.  You can set a destructor
 * function for the object with nih_alloc_set_destructor(), this is called
 * during the free process.
 *
 * To remove a reference to a child, potentially freeing it but without
 * freeing the parent object, use nih_unref().
 *
 * To free a top-level object, use nih_free().  nih_free() always frees the
 * object, even if it has parent references which it will discard.  This
 * obviously does not clean up any pointers in the parent object which
 * point at the freed child.
 *
 * In many situations, you will allocate an object using nih_alloc() with
 * no parent and pass that to functions which may take a reference to it.
 * When finished, you need to discard the object safely; if no references
 * were taken, it should be freed - otherwise it's safe to leave.  Use
 * nih_discard() instead of nih_free() to do this.
 *
 * Such constructs are often better handled using nih_local variables.
 *
 *
 * = Common patterns =
 *
 * At first, it seems like there's a bewildering array of different ways
 * you can shoot yourself in the foot with this library, however if you
 * stick to the usual patterns it's a very safe and versatile library.
 *
 * == Structures ==
 *
 * When allocating structures, you tend to write your function so that
 * the prospective parent is passed in as the first argument and always
 * allocate with that.
 *
 *   obj = nih_new (parent, Object);
 *
 * That way, the caller decides how they want your object linked to
 * other things.  If there's an error while populating the structure,
 * the standard style is just to call nih_free() rather than
 * unreferencing
 *
 *   error:
 *     nih_free (obj);
 *     return NULL;
 *
 * Since you're putting it together, this use of nih_free() is perfectly
 * acceptable.
 *
 * == Structure members ==
 *
 * Structure members are just about always allocated with the structure
 * as their parent context.
 *
 *   obj->child = nih_new (obj, Child);
 *
 * This pretty much saves you from ever worrying about them, as they
 * will be automatically freed whenever you free the parent object;
 * including error handling cases.
 *
 * Should you ever replace the child, you shouldn't call nih_free() but
 * nih_unref(), to be safe against other code having taken a reference.
 *
 *   nih_unref (obj->child, obj);
 *   obj->child = nih_new (obj, Child);
 *
 * This will clean up the child, unless someone else is using it.
 *
 * == Floating objects ==
 *
 * Often in a function you'll want to allocate an object but won't yet
 * have anything to attach it to.  This also often applies to global
 * variables as well.
 *
 * You simply pass NULL in as the parent; the returned object has only
 * this special reference.
 *
 *   obj = nih_new (NULL, Object);
 *
 * To discard the floating object you should use nih_discard() instead
 * of nih_free(), which will not free the object if another function
 * you've called in the meantime took a reference to it.
 *
 * Better yet, use nih_local to have the object automatically discarded
 * when it goes out of scope:
 *
 *   {
 *     nih_local Object *obj = NULL;
 *     obj = nih_new (NULL, Object);
 *
 *     // work with obj, including passing it to functions that may
 *     // reference it
 *   }
 *
 * == Taking a reference ==
 *
 * Provided the above patterns are followed, taking a reference to an
 * object you are passed is perfectly safe.  Simply call nih_ref(),
 * for example to store it in your own structure:
 *
 *   adopt->obj = obj;
 *   nih_ref (adopt->obj, adopt);
 *
 * When you want to drop your reference, you should only ever use
 * nih_unref().
 *
 *   nih_unref (adopt->obj, adopt);
 *   adopt->obj = NULL;
 *
 * == Returning a member ==
 *
 * This is a relatively rare case, but examples exist.
 *
 * Sometimes you want to provide a function that returns one of your
 * structure members, disowning it in the process.  Your function will
 * most likely take a parent object to which you want to reparent the
 * member.
 *
 * This is as easy as referencing the new parent and dropping your own
 * reference.
 *
 *   nih_ref (child, parent);
 *
 *   child = obj->child;
 *   obj->child = NULL;
 *
 *   nih_unref (obj->child, obj);
 *
 *   // child may now be returned
 *
 * == Worker objects ==
 *
 * Finally another pattern exits in the nih_alloc() world that doesn't
 * quite obey the above rules, and instead takes advantage of the design
 * to provide something that wouldn't be possible otherwise.
 *
 * A worker is an object that performs some function out-of-band on
 * behalf of another object.  They may be stored elsewhere, such as a
 * linked list, and will be set up such that if they are freed, the
 * work they are doing is cancelled.
 *
 * A good example would be a timer object; you'd have a list of timers
 * which you iterate in the main loop.  The destructor of the timer
 * object removes it from this list.  When the timer expires, some
 * work occurs, and the timer object frees itself.
 *
 * Thus to attach a timer to our object, all we need do is create the
 * timer with our object as a parent.  There is absolutely no need
 * to store the timer as a structure member, unless we would need to
 * cancel it for other reasons.
 *
 * If our object is freed, the timer is freed to so there's no danger
 * of the callback firing and acting on a freed object.  If the timer
 * fires, the callback can do its work, and the timer will be freed
 * afterwards.
 *
 * Much of the main loop related objects in libnih behave in this way.
 **/

#include <nih/macros.h>


/**
 * NihDestructor:
 * @ptr: pointer to be destroyed.
 *
 * A destructor is a function that can be associated with an allocated
 * object in memory and is called before the object is freed.  The pointer
 * @ptr passed to the destructor is that of the object being freed.
 *
 * A typical use of a destructor would be to close a file descriptor held
 * by an object.
 *
 * When the destructor is called, the parent references to the object will
 * have already been discarded but all children references will be intact
 * and none of the children will have been freed.  There is no need to use
 * a destructor to unreference or free children, that is automatic.
 *
 * Returns: value returned by nih_free() or nih_discard() if used directly
 * on the object.
 **/
typedef int (*NihDestructor) (void *ptr);


/**
 * nih_new:
 * @parent: parent object for new object,
 * @type: type of data to store.
 *
 * Allocates an object in memory large enough to store a @type object
 * and returns a pointer to it.
 *
 * If @parent is not NULL, it should be a pointer to another object which
 * will be used as a parent for the returned object otherwise the special
 * NULL parent will be used instead.  When all parents of the returned
 * object are freed, the returned object will also be freed.
 *
 * If you have clean-up that you would like to run, you can assign a
 * destructor using the nih_alloc_set_destructor() function.
 *
 * Returns: newly allocated object or NULL if insufficient memory.
 **/
#define nih_new(parent, type) (type *)nih_alloc(parent, sizeof (type))

/**
 * nih_alloc_set_destructor:
 * @ptr: pointer to object,
 * @destructor: destructor function to set.
 *
 * Sets the destructor of the allocated object @ptr to @destructor, which
 * may be NULL to unset an existing destructor.  This is a macro that casts
 * @destructor to the NihDestructor type, since almost all destructors
 * will be defined with their argument to be the type of the object
 * rather than void *.
 *
 * The destructor will be called before the object is freed, either
 * explicitly by nih_free() or nih_discard(), or because the last parent
 * has unreferenced the object.
 *
 * When the destructor is called, the parent references to the object will
 * have already been discarded but all children references will be intact
 * and none of the children will have been freed.  There is no need to use
 * a destructor to unreference or free children, that is automatic.
 *
 * The pointer @ptr passed to the destructor is that of the object being
 * freed, and the destructor may return a value which will be the return
 * value of nih_free() or nih_discard() if used directly on the object.
 *
 * Since objects may also be freed by unreferencing, and the value is not
 * returned in this case, it should only be used for informational or
 * debugging purposes.
 **/
#define nih_alloc_set_destructor(ptr, destructor)	\
	nih_alloc_real_set_destructor (ptr, (NihDestructor)destructor)


/**
 * nih_local:
 *
 * This macro may be used in a variable definition when the variable
 * should be automatically cleaned up when it goes out of scope.  You
 * should ensure that the pointer is either allocated with nih_alloc()
 * or set to NULL;
 *
 *   {
 *     nih_local char *foo = NULL;
 *
 *     foo = nih_strdup (NULL, "some data");
 *   } // foo is automatically discarded
 *
 * It is permissible to take references to foo within its scope, or by
 * functions called, in which case it will not be freed.  Also it is
 * generally nonsensical to allocate with a parent, since this too will
 * prevent it from being freed.
 **/
#define nih_local __attribute__ ((cleanup(_nih_discard_local)))


NIH_BEGIN_EXTERN

void * nih_alloc                     (const void *parent, size_t size)
	__attribute__ ((warn_unused_result));

void * nih_realloc                   (void *ptr, const void *parent,
				      size_t size)
	__attribute__ ((warn_unused_result));

int    nih_free                      (void *ptr);
int    nih_discard                   (void *ptr);
void   _nih_discard_local            (void *ptraddr);

void   nih_alloc_real_set_destructor (const void *ptr,
				      NihDestructor destructor);

void   nih_ref                       (const void *ptr, const void *parent);
void   nih_unref                     (void *ptr, const void *parent);

int    nih_alloc_parent              (const void *ptr, const void *parent);

size_t nih_alloc_size                (const void *ptr);

NIH_END_EXTERN

#endif /* NIH_ALLOC_H */