getauxv.c revision 1219:f89f56c2d9ac
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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23/*
24 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25 * Use is subject to license terms.
26 */
27
28#pragma ident	"%Z%%M%	%I%	%E% SMI"
29
30#include "synonyms.h"
31#include <libc.h>
32#include <fcntl.h>
33#include <stdlib.h>
34#include <unistd.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <sys/auxv.h>
38#include <mtlib.h>
39#include <thread.h>
40#include <synch.h>
41
42static mutex_t auxlock = DEFAULTMUTEX;
43
44/*
45 * Get auxiliary entry.
46 * Returns pointer to entry, or 0 if entry does not exist.
47 */
48static auxv_t *
49_getaux(int type)
50{
51	static auxv_t *auxb = NULL;
52	static size_t nauxv = 0;
53	ssize_t i;
54
55	/*
56	 * The first time through, read the initial aux vector that was
57	 * passed to the process at exec(2).  Only do this once.
58	 */
59	if (auxb == NULL) {
60		struct stat statb;
61		int fd;
62
63		lmutex_lock(&auxlock);
64
65		if (auxb == NULL) {
66			if ((fd = open("/proc/self/auxv", O_RDONLY)) != -1 &&
67			    fstat(fd, &statb) != -1)
68				auxb = libc_malloc(
69				    statb.st_size + sizeof (auxv_t));
70
71			if (auxb != NULL) {
72				i = read(fd, auxb, statb.st_size);
73				if (i != -1) {
74					nauxv = i / sizeof (auxv_t);
75					auxb[nauxv].a_type = AT_NULL;
76				} else {
77					libc_free(auxb);
78					auxb = NULL;
79				}
80			}
81
82			if (fd != -1)
83				(void) close(fd);
84		}
85
86		lmutex_unlock(&auxlock);
87	}
88
89	/*
90	 * Scan the auxiliary entries looking for the required type.
91	 */
92	for (i = 0; i < nauxv; i++)
93		if (auxb[i].a_type == type)
94			return (&auxb[i]);
95
96	/*
97	 * No auxiliary array (static executable) or entry not found.
98	 */
99	return ((auxv_t *)0);
100}
101
102/*
103 * These two routines are utilities exported to the rest of libc.
104 */
105
106long
107___getauxval(int type)
108{
109	auxv_t *auxp;
110
111	if ((auxp = _getaux(type)) != (auxv_t *)0)
112		return (auxp->a_un.a_val);
113	return (0);
114}
115
116void *
117___getauxptr(int type)
118{
119	auxv_t *auxp;
120
121	if ((auxp = _getaux(type)) != (auxv_t *)0)
122		return (auxp->a_un.a_ptr);
123	return (0);
124}
125