1 /* 2 * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 #define _GNU_SOURCE 33 #include <config.h> 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <unistd.h> 38 #include <sys/types.h> 39 #include <sys/stat.h> 40 #include <fcntl.h> 41 #include <string.h> 42 #include <sys/sysctl.h> 43 44 #include "ibverbs.h" 45 46 static const char *sysfs_path; 47 48 const char *ibv_get_sysfs_path(void) 49 { 50 const char *env = NULL; 51 52 if (sysfs_path) 53 return sysfs_path; 54 55 /* 56 * Only follow use path passed in through the calling user's 57 * environment if we're not running SUID. 58 */ 59 if (getuid() == geteuid()) 60 env = getenv("SYSFS_PATH"); 61 62 if (env) { 63 int len; 64 char *dup; 65 66 sysfs_path = dup = strndup(env, IBV_SYSFS_PATH_MAX); 67 len = strlen(dup); 68 while (len > 0 && dup[len - 1] == '/') { 69 --len; 70 dup[len] = '\0'; 71 } 72 } else 73 sysfs_path = "/sys"; 74 75 return sysfs_path; 76 } 77 78 int ibv_read_sysfs_file(const char *dir, const char *file, 79 char *buf, size_t size) 80 { 81 char *path, *s; 82 int fd; 83 size_t len; 84 85 if (asprintf(&path, "%s/%s", dir, file) < 0) 86 return -1; 87 88 for (s = &path[0]; *s != '\0'; s++) 89 if (*s == '/') 90 *s = '.'; 91 92 len = size; 93 if (sysctlbyname(&path[1], buf, &len, NULL, 0) == -1) 94 return -1; 95 96 free(path); 97 98 if (len > 0 && buf[len - 1] == '\n') 99 buf[--len] = '\0'; 100 101 return len; 102 } 103