Path: blob/main/cddl/contrib/opensolaris/common/ctf/ctf_util.c
39507 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License, Version 1.0 only5* (the "License"). You may not use this file except in compliance6* with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or http://www.opensolaris.org/os/licensing.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright 2005 Sun Microsystems, Inc. All rights reserved.23* Use is subject to license terms.24*/2526#pragma ident "%Z%%M% %I% %E% SMI"2728#include <ctf_impl.h>2930/*31* Simple doubly-linked list append routine. This implementation assumes that32* each list element contains an embedded ctf_list_t as the first member.33* An additional ctf_list_t is used to store the head (l_next) and tail34* (l_prev) pointers. The current head and tail list elements have their35* previous and next pointers set to NULL, respectively.36*/37void38ctf_list_append(ctf_list_t *lp, void *new)39{40ctf_list_t *p = lp->l_prev; /* p = tail list element */41ctf_list_t *q = new; /* q = new list element */4243lp->l_prev = q;44q->l_prev = p;45q->l_next = NULL;4647if (p != NULL)48p->l_next = q;49else50lp->l_next = q;51}5253/*54* Prepend the specified existing element to the given ctf_list_t. The55* existing pointer should be pointing at a struct with embedded ctf_list_t.56*/57void58ctf_list_prepend(ctf_list_t *lp, void *new)59{60ctf_list_t *p = new; /* p = new list element */61ctf_list_t *q = lp->l_next; /* q = head list element */6263lp->l_next = p;64p->l_prev = NULL;65p->l_next = q;6667if (q != NULL)68q->l_prev = p;69else70lp->l_prev = p;71}7273/*74* Delete the specified existing element from the given ctf_list_t. The75* existing pointer should be pointing at a struct with embedded ctf_list_t.76*/77void78ctf_list_delete(ctf_list_t *lp, void *existing)79{80ctf_list_t *p = existing;8182if (p->l_prev != NULL)83p->l_prev->l_next = p->l_next;84else85lp->l_next = p->l_next;8687if (p->l_next != NULL)88p->l_next->l_prev = p->l_prev;89else90lp->l_prev = p->l_prev;91}9293/*94* Convert an encoded CTF string name into a pointer to a C string by looking95* up the appropriate string table buffer and then adding the offset.96*/97const char *98ctf_strraw(const ctf_file_t *fp, uint_t name)99{100const ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID(name)];101102if (ctsp->cts_strs != NULL && CTF_NAME_OFFSET(name) < ctsp->cts_len)103return (ctsp->cts_strs + CTF_NAME_OFFSET(name));104105/* string table not loaded or corrupt offset */106return (NULL);107}108109const char *110ctf_strptr(const ctf_file_t *fp, uint_t name)111{112const char *s = ctf_strraw(fp, name);113return (s != NULL ? s : "(?)");114}115116/*117* Same strdup(3C), but use ctf_alloc() to do the memory allocation.118*/119char *120ctf_strdup(const char *s1)121{122char *s2 = ctf_alloc(strlen(s1) + 1);123124if (s2 != NULL)125(void) strcpy(s2, s1);126127return (s2);128}129130/*131* Store the specified error code into errp if it is non-NULL, and then132* return NULL for the benefit of the caller.133*/134ctf_file_t *135ctf_set_open_errno(int *errp, int error)136{137if (errp != NULL)138*errp = error;139return (NULL);140}141142/*143* Store the specified error code into the CTF container, and then return144* CTF_ERR for the benefit of the caller.145*/146long147ctf_set_errno(ctf_file_t *fp, int err)148{149fp->ctf_errno = err;150return (CTF_ERR);151}152153154