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
audit_queue_init(au_queue_t * q)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
audit_enqueue(au_queue_t * q,void * p)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
audit_dequeue(au_queue_t * q,void ** p)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
audit_incr_ref(pthread_mutex_t * l,audit_rec_t * p)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 *
audit_release(pthread_mutex_t * l,audit_rec_t * p)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
audit_queue_size(au_queue_t * q)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
audit_queue_destroy(au_queue_t * q)170 audit_queue_destroy(au_queue_t *q)
171 {
172 (void) pthread_mutex_destroy(&q->auq_lock);
173 }
174