/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* NOTICE: This is a clean room re-implementation of libnl */ #include #include "netlink-types.h" #include "netlink/handlers.h" /* Allocate a new callback handle. */ struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind) { struct nl_cb *cb; cb = (struct nl_cb *) malloc(sizeof(struct nl_cb)); if (cb == NULL) goto fail; memset(cb, 0, sizeof(*cb)); return nl_cb_get(cb); fail: return NULL; } /* Clone an existing callback handle */ struct nl_cb *nl_cb_clone(struct nl_cb *orig) { struct nl_cb *new_cb; new_cb = nl_cb_alloc(NL_CB_DEFAULT); if (new_cb == NULL) goto fail; /* Copy original and set refcount to 1 */ memcpy(new_cb, orig, sizeof(*orig)); new_cb->cb_refcnt = 1; return new_cb; fail: return NULL; } /* Set up a callback. */ int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, \ nl_recvmsg_msg_cb_t func, void *arg) { cb->cb_set[type] = func; cb->cb_args[type] = arg; return 0; } /* Set up an error callback. */ int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, \ nl_recvmsg_err_cb_t func, void *arg) { cb->cb_err = func; cb->cb_err_arg = arg; return 0; } struct nl_cb *nl_cb_get(struct nl_cb *cb) { cb->cb_refcnt++; return cb; } void nl_cb_put(struct nl_cb *cb) { if (!cb) return; cb->cb_refcnt--; if (cb->cb_refcnt <= 0) free(cb); }