xref: /illumos-gate/usr/src/cmd/auditd/queue.c (revision 8fc99e42676a23421c75e76660640f9765d693b1)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <pthread.h>
27 #include <memory.h>
28 #include "queue.h"
29 #include <stdio.h>
30 #include <assert.h>
31 #include "plugin.h"
32 
33 #define	DEBUG	0
34 
35 #if DEBUG
36 extern FILE *dbfp;
37 extern FILE *__auditd_debug_file_open();
38 #define	DPRINT(x) { (void) fprintf x; }
39 #else
40 #define	DPRINT(x)
41 #endif
42 
43 void
44 audit_queue_init(au_queue_t *q)
45 {
46 	q->auq_head = NULL;
47 	q->auq_tail = NULL;
48 	(void) pthread_mutex_init(&q->auq_lock, NULL);
49 	q->auq_count = 0;
50 #if DEBUG
51 	if (dbfp == NULL) {
52 		dbfp = __auditd_debug_file_open();
53 	}
54 #endif
55 }
56 
57 /*
58  * enqueue()	caller creates queue entry
59  */
60 
61 void
62 audit_enqueue(au_queue_t *q,  void *p)
63 {
64 	(void) pthread_mutex_lock(&q->auq_lock);
65 
66 	DPRINT((dbfp, "enqueue0(%p): p=%p, head=%p, tail=%p, count=%d\n",
67 	    (void *)q, (void *)p, (void *)q->auq_head, (void *)q->auq_tail,
68 	    q->auq_count));
69 
70 	if (q->auq_head == NULL)
71 		q->auq_head = p;
72 	else {
73 		DPRINT((dbfp, "\tindirect tail=%p\n",
74 		    (void *)&(((audit_link_t *)(q->auq_tail))->aln_next)));
75 
76 		((audit_link_t *)(q->auq_tail))->aln_next = p;
77 	}
78 	q->auq_tail = p;
79 	((audit_link_t *)p)->aln_next = NULL;
80 	q->auq_count++;
81 
82 	DPRINT((dbfp, "enqueue1(%p): p=%p, head=%p, tail=%p, "
83 	    "count=%d, pnext=%p\n", (void *)q, (void *)p, (void *)q->auq_head,
84 	    (void *)q->auq_tail, q->auq_count,
85 	    (void *)((audit_link_t *)p)->aln_next));
86 
87 	(void) pthread_mutex_unlock(&q->auq_lock);
88 }
89 
90 /*
91  * audit_dequeue() returns entry; caller is responsible for free
92  */
93 
94 int
95 audit_dequeue(au_queue_t *q, void **p)
96 {
97 	(void) pthread_mutex_lock(&q->auq_lock);
98 
99 	if ((*p = q->auq_head) == NULL) {
100 		DPRINT((dbfp, "dequeue1(%p): p=%p, head=%p, "
101 		    "tail=%p, count=%d\n", (void *)q, (void *)*p,
102 		    (void *)q->auq_head, (void *)q->auq_tail, q->auq_count));
103 
104 		(void) pthread_mutex_unlock(&q->auq_lock);
105 		return (1);
106 	}
107 	q->auq_count--;
108 
109 	/* if *p is the last, next is NULL */
110 	q->auq_head = ((audit_link_t *)*p)->aln_next;
111 
112 	DPRINT((dbfp, "dequeue0(%p): p=%p, head=%p, tail=%p, "
113 	    "count=%d, pnext=%p\n", (void *)q, (void *)*p, (void *)q->auq_head,
114 	    (void *)q->auq_tail, q->auq_count,
115 	    (void *)((audit_link_t *)*p)->aln_next));
116 
117 	(void) pthread_mutex_unlock(&q->auq_lock);
118 	return (0);
119 }
120 
121 /*
122  * increment ref count
123  */
124 void
125 audit_incr_ref(pthread_mutex_t *l, audit_rec_t *p)
126 {
127 	(void) pthread_mutex_lock(l);
128 	p->abq_ref_count++;
129 	DPRINT((dbfp, "incr_ref: p=%p, count=%d\n",
130 	    (void *)p, p->abq_ref_count));
131 	(void) pthread_mutex_unlock(l);
132 }
133 /*
134  * decrement reference count; if it reaches zero,
135  * return a pointer to it.  Otherwise, return NULL.
136  */
137 audit_rec_t *
138 audit_release(pthread_mutex_t *l, audit_rec_t *p)
139 {
140 	assert(p != NULL);
141 
142 	(void) pthread_mutex_lock(l);
143 
144 	DPRINT((dbfp, "release: p=%p , count=%d\n",
145 	    (void *)p, p->abq_ref_count));
146 
147 	if (--(p->abq_ref_count) > 0) {
148 		(void) pthread_mutex_unlock(l);
149 		return (NULL);
150 	}
151 	(void) pthread_mutex_unlock(l);
152 
153 	return (p);
154 }
155 
156 int
157 audit_queue_size(au_queue_t *q)
158 {
159 	int	size;
160 
161 	(void) pthread_mutex_lock(&q->auq_lock);
162 	size = q->auq_count;
163 	(void) pthread_mutex_unlock(&q->auq_lock);
164 
165 	return (size);
166 }
167 
168 
169 void
170 audit_queue_destroy(au_queue_t *q)
171 {
172 	(void) pthread_mutex_destroy(&q->auq_lock);
173 }
174