openwrt中用到双向无头链表,实际应用时应在外部定义实体链表头,后续可直接应用链表函数(宏定义已将链表头排除在外):

static struct list_head timeouts = LIST_HEAD_INIT(timeouts);
static struct list_head processes = LIST_HEAD_INIT(processes);

与linux相同,定义如下:

#ifndef _LINUX_LIST_H_
#define _LINUX_LIST_H_ #include <stddef.h>
#include <stdbool.h> #define prefetch(x) #ifndef container_of
#define container_of(ptr, type, member) \
({ \
const typeof(((type *)NULL)->member) *__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); \
})
#endif struct list_head {
struct list_head *next;
struct list_head *prev;
};

初始化

#define LIST_HEAD_INIT(name) {&(name), &(name)}
#undef LIST_HEAD
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) static inline void
INIT_LIST_HEAD(struct list_head *list)
{
list->next = list->prev = list;
}

list属性

static inline bool
list_empty(const struct list_head *head)
{
return (head->next == head);
} static inline bool
list_is_first(const struct list_head *list,
const struct list_head *head)
{
return (list->prev == head);
} static inline bool
list_is_last(const struct list_head *list,
const struct list_head *head)
{
return (list->next == head);
}

list常用操作--增add

static inline void
_list_add(struct list_head *_new, struct list_head *prev,
struct list_head *next)
{
prev->next = _new;
_new->prev = prev;
_new->next = next;
next->prev = _new;
} static inline void
list_add(struct list_head *_new, struct list_head *head)
{
_list_add(_new, head, head->next);
} static inline void
list_add_tail(struct list_head *_new, struct list_head, *head)
{
_list_add(_new, head->prev, head);
}

list常用操作--删del

static inline void
_list_del(struct list_head *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
} static inline void
list_del(struct list_head *entry)
{
_list_del(entry);
entry->next = entry->prev = NULL;
} static inline void
list_del_init(struct list_head *entry)
{
_list_del(entry);
INIT_LIST_HEAD(entry);
}

list常用操作--改move

static inline void
list_move(struct list_head *list, struct list_head * head)
{
_list_del(list);
list_add(list, head);
} static inline void
list_move_tail(struct list_head *list, struct list_head *head)
{
_list_del(list);
list_add_tail(list, head);
}

list常用操作--查

#define list_entry(ptr, type, field) container_of(ptr, type, field)
#define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field)
#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field) #define list_for_each(p, head) \
for(p=(head)->next; p!=(head); p=p->next) #define list_for_each_safe(p, n, head) \
for(p = (head)->next, n=p->next; p!= (head); p=n, n=p->next) #define list_for_each_entry(p, h, field) \
for(p = list_first_entry(h, typeof(*p), field); \
&p->field != (h); \
p = list_entry(p->field.next, typeof(*p), field)) #define list_for_each_entry_safe(p, n, h, field) \
for(p = list_first_entry(h, typeof(*p), field), \
n = list_entry(p->field.next, typeof(*p), field); \
&p->field != (h); \
p = n, n = list_entry(n->field.next, typeof(*p), field)) #define list_for_each_entry_reverse(p, h, field) \
for(p = list_last_entry(h, typeof(*p), field); \
&p->field != (h); \
p = list_entry(p->field.prev, typeof(*p), field)) #define list_for_each_prev(p, h) \
for(p = (h)->prev; p != (h); p = p->prev) #define list_for_each_prev_safe(p, n, h) \
for(p = (h)->prev, n = p->prev; p != (h); \
p = n, n = p->prev)

list常用操作--拼接splice

static inline void
_list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next)
{
struct list_head *first, last; if(list_empty(list))
return ; first = list->next;
last = list->prev;
first->prev = prev;
prev->next = first;
last->next = next;
next->prev = last;
} static inline void
list_splice(const struct list_head *list, struct list_head *head)
{
_list_splice(list, head, head->next);
} static inline void
list_splice_tail(struct list_head *list, struct list_head *head)
{
_list_splice(list, head->prev, head);
} static inline void
list_splice_init(struct list_head *list, struct list_head *head)
{
_list_splice(list, head, head->next);
INIT_LIST_HEAD(list);
}
static inline void
list_splice_tail_init(struct list_head *list, struct list_head *head)
{
_list_splice(list, head->prev, head);
INIT_LIST_HEAD(list);
} #endif

摘自:libubox

openwrt使用list的更多相关文章

  1. OpenWrt中开启usb存储和samba服务

    在从官网安装的WNDR3800 15.05.1版本OpenWrt中, 不带usb存储支持以及samba, 需要另外安装 1. 启用usb支持 USB Basic Support https://wik ...

  2. (转)利用libcurl和国内著名的两个物联网云端通讯的例程, ubuntu和openwrt下调试成功(四)

    1. libcurl 的参考文档如下 CURLOPT_HEADERFUNCTION Pass a pointer to a function that matches the following pr ...

  3. (转)利用libcurl获取新浪股票接口, ubuntu和openwrt实验成功(三)

    1.  利用 CURLOPT_WRITEFUNCTION 设置回调函数, 利用 CURLOPT_WRITEDATA 获取数据指针 官网文档如下 CALLBACK OPTIONS CURLOPT_WRI ...

  4. (转)linux下和云端通讯的例程, ubuntu和openwrt下实验成功(二)

    前言: 上节用纯linux的函数实现了和云端通讯, 本节开始利用传说中的神器libcurl 话说一个网络程序员对书法十分感兴趣,退休后决定在这方面有所建树. 于是花重金购买了上等的文房四宝.    一 ...

  5. (转)linux下和云端通讯的例程, ubuntu和openwrt实验成功(一)

    一.  HTTP请求的数据流总结#上传数据, yeelink的数据流如下POST /v1.0/device/4420/sensor/9089/datapoints HTTP/1.1Host: api. ...

  6. OpenWRT镜像爬虫搭建本地源

    网上的爬虫不能用,还是先表达谢意,不过我比较懒不喜欢重复写别人写的教程,只贴出修改,怎么用自己看教程吧. 我自己改了一版可以正常爬: #!/usr/bin/env python #coding=utf ...

  7. 安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制

    安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制 socket 连接采用流的方式进行发送接收数据,采用thread线程的方式. 什么是线程?  详细代码介 ...

  8. 极路由2(极贰)在OpenWrt下定制自己的ss服务

    默认刷入的OpenWrt带的ss, 只有ss-redir服务, 但是在实际使用中, 很多时候还是希望访问直接通过正常网关, 只有少部分访问需要通过ss, 所以希望能配置成为ss-local服务. 在保 ...

  9. 极路由2(极贰)ROOT并刷了OpenWrt

    绕过官方的ROOT 查了一下root教程, 如果还需要保留保修, 则需要自己想办法回退版本, 下载搜狐插件到sd卡, 找个linux系统修改sd卡上程序的执行权限, 然后才能开启ssh, 具体的方法可 ...

  10. 使用 Docker 编译 OpenWRT(Widora)

    Docker 是一种新的被称之为容器的虚拟机.本文将使用此工具,进行 OpenWRT 的编译. 在 Docker 中下载 Ubuntu 14.04 的镜像 使用以下命令可以十分方便的从远程服务器上将 ...

随机推荐

  1. HDUOJ---携程员工运动会场地问题

    携程员工运动会场地问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. HDUOJ-----1166敌兵布阵

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. Linux vi命令大全

    http://www.cnblogs.com/88999660/articles/1581524.html一.Unix编辑器概述 编辑器是使用计算机的重要工具之一,在各种操作系统中,编辑器都是必不可少 ...

  4. vi/vim 计算搜寻关键字数量

    http://hi.baidu.com/xletian/blog/item/f19962061a9a506c020881dc.html 在看过 vim 的全域指令和 search 指令之後,你会不会也 ...

  5. Python基本数据类型详细介绍(转)

    1.空(None)表示该值是一个空对象,空值是Python里一个特殊的值,用None表示.None不能理解为0,因为0是有意义的,而None是一个特殊的空值.2.布尔类型(Boolean)在 Pyth ...

  6. iOS - PairProgramming 结对编程

    1.PairProgramming 结对编程(Pair-Programming)可能是近年来最为流行的编程方式.所谓结对编程,也就是两个人写一个程序,其中,一个人叫 Driver,另一个人叫 Obse ...

  7. iOS - UnitTests 单元测试

    1.UnitTests 在计算机编程中,单元测试(又称为模块测试, Unit Testing)是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作.程序单元是应用的最小可测试部件.在过程化编 ...

  8. 【php】基础学习2

    主要包括数组的学习,具体如下: <html xmlns=http://www.w3.org/1999/xhtml> <head> <meta http-equiv=Con ...

  9. map以自定义类型当Key

    关于map的定义: template < class Key, class T, class Compare = less<Key>, class Allocator = alloc ...

  10. SIPp常用脚本之二:UAS

    看名字就能猜出来,这是作为SIP消息服务端的存在,启动uas,等着接受SIP消息并且给出响应. 一.uas.xml <?xml version="2.0" encoding= ...