1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or https://opensource.org/licenses/CDDL-1.0. 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 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include "libuutil_common.h" 27 28 #include <stdarg.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 33 void * 34 uu_zalloc(size_t n) 35 { 36 void *p = malloc(n); 37 38 if (p == NULL) { 39 uu_set_error(UU_ERROR_SYSTEM); 40 return (NULL); 41 } 42 43 (void) memset(p, 0, n); 44 45 return (p); 46 } 47 48 void 49 uu_free(void *p) 50 { 51 free(p); 52 } 53 54 char * 55 uu_strdup(const char *str) 56 { 57 char *buf = NULL; 58 59 if (str != NULL) { 60 size_t sz; 61 62 sz = strlen(str) + 1; 63 buf = uu_zalloc(sz); 64 if (buf != NULL) 65 (void) memcpy(buf, str, sz); 66 } 67 return (buf); 68 } 69 70 /* 71 * Duplicate up to n bytes of a string. Kind of sort of like 72 * strdup(strlcpy(s, n)). 73 */ 74 char * 75 uu_strndup(const char *s, size_t n) 76 { 77 size_t len; 78 char *p; 79 80 len = strnlen(s, n); 81 p = uu_zalloc(len + 1); 82 if (p == NULL) 83 return (NULL); 84 85 if (len > 0) 86 (void) memcpy(p, s, len); 87 p[len] = '\0'; 88 89 return (p); 90 } 91 92 /* 93 * Duplicate a block of memory. Combines malloc with memcpy, much as 94 * strdup combines malloc, strlen, and strcpy. 95 */ 96 void * 97 uu_memdup(const void *buf, size_t sz) 98 { 99 void *p; 100 101 p = uu_zalloc(sz); 102 if (p == NULL) 103 return (NULL); 104 (void) memcpy(p, buf, sz); 105 return (p); 106 } 107 108 char * 109 uu_msprintf(const char *format, ...) 110 { 111 va_list args; 112 char attic[1]; 113 uint_t M, m; 114 char *b; 115 116 va_start(args, format); 117 M = vsnprintf(attic, 1, format, args); 118 va_end(args); 119 120 for (;;) { 121 m = M; 122 if ((b = uu_zalloc(m + 1)) == NULL) 123 return (NULL); 124 125 va_start(args, format); 126 M = vsnprintf(b, m + 1, format, args); 127 va_end(args); 128 129 if (M == m) 130 break; /* sizes match */ 131 132 uu_free(b); 133 } 134 135 return (b); 136 } 137