getpagesizes.c revision 211416
1197331Salc/*- 2197331Salc * Copyright (c) 2009 Alan L. Cox <alc@cs.rice.edu> 3197331Salc * All rights reserved. 4197331Salc * 5197331Salc * Redistribution and use in source and binary forms, with or without 6197331Salc * modification, are permitted provided that the following conditions 7197331Salc * are met: 8197331Salc * 1. Redistributions of source code must retain the above copyright 9197331Salc * notice, this list of conditions and the following disclaimer. 10197331Salc * 2. Redistributions in binary form must reproduce the above copyright 11197331Salc * notice, this list of conditions and the following disclaimer in the 12197331Salc * documentation and/or other materials provided with the distribution. 13197331Salc * 14197331Salc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15197331Salc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16197331Salc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17197331Salc * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18197331Salc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19197331Salc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20197331Salc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21197331Salc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22197331Salc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23197331Salc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24197331Salc * SUCH DAMAGE. 25197331Salc */ 26197331Salc 27197331Salc#include <sys/cdefs.h> 28197331Salc__FBSDID("$FreeBSD: head/lib/libc/gen/getpagesizes.c 211416 2010-08-17 09:13:26Z kib $"); 29197331Salc 30197331Salc#include <sys/param.h> 31197331Salc#include <sys/mman.h> 32197331Salc#include <sys/sysctl.h> 33197331Salc 34197331Salc#include <errno.h> 35211416Skib#include <link.h> 36197331Salc 37211416Skib#include "libc_private.h" 38211416Skib 39197331Salc/* 40197331Salc * Retrieves page size information from the system. Specifically, returns the 41197331Salc * number of distinct page sizes that are supported by the system, if 42197331Salc * "pagesize" is NULL and "nelem" is 0. Otherwise, assigns up to "nelem" of 43197331Salc * the system-supported page sizes to consecutive elements of the array 44197331Salc * referenced by "pagesize", and returns the number of such page sizes that it 45197331Salc * assigned to the array. These page sizes are expressed in bytes. 46197331Salc * 47197331Salc * The implementation of this function does not directly or indirectly call 48197331Salc * malloc(3) or any other dynamic memory allocator that may itself call this 49197331Salc * function. 50197331Salc */ 51197331Salcint 52197331Salcgetpagesizes(size_t pagesize[], int nelem) 53197331Salc{ 54197331Salc static u_long ps[MAXPAGESIZES]; 55197331Salc static int nops; 56197331Salc size_t size; 57211416Skib int error, i; 58197331Salc 59197331Salc if (nelem < 0 || (nelem > 0 && pagesize == NULL)) { 60197331Salc errno = EINVAL; 61197331Salc return (-1); 62197331Salc } 63197331Salc /* Cache the result of the sysctl(2). */ 64197331Salc if (nops == 0) { 65211416Skib error = _elf_aux_info(AT_PAGESIZES, ps, sizeof(ps)); 66197331Salc size = sizeof(ps); 67211416Skib if (error != 0 || ps[0] == 0) { 68211416Skib if (sysctlbyname("hw.pagesizes", ps, &size, NULL, 0) 69211416Skib == -1) 70211416Skib return (-1); 71211416Skib } 72197331Salc /* Count the number of page sizes that are supported. */ 73197331Salc nops = size / sizeof(ps[0]); 74197331Salc while (nops > 0 && ps[nops - 1] == 0) 75197331Salc nops--; 76197331Salc } 77197331Salc if (pagesize == NULL) 78197331Salc return (nops); 79197331Salc /* Return up to "nelem" page sizes from the cached result. */ 80197331Salc if (nelem > nops) 81197331Salc nelem = nops; 82197331Salc for (i = 0; i < nelem; i++) 83197331Salc pagesize[i] = ps[i]; 84197331Salc return (nelem); 85197331Salc} 86