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-------1753大明A+B(大数之小数加法)

    大明A+B Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  2. Java优化技巧

    过早的优化是万恶之源. 优化了的代码可读性变差,可改性可适应性变差,可维护性变差. 远离过度优化,优化是个无底洞,把主要精力放在代码逻辑上. 优化的代码是活在当下的,是严重依赖硬件的,不利于表达永恒的 ...

  3. iOS与H5交互遇到的坑

    之前的博客写过使用<JavaScriptCore/JavaScriptCore.h>库来实现与H5的交互,但是在项目中还是遇到了一些不得不踩的坑.在这里将我遇到的问题以及参考网上几位大神的 ...

  4. 可以尝试用Google Font API来摆脱网页字体的单调 仅仅抛砖引玉

    http://www.nowamagic.net/librarys/veda/detail/2513

  5. Asp.Net Core 轻松学-一行代码搞定文件上传 JSONHelper

    Asp.Net Core 轻松学-一行代码搞定文件上传   前言     在 Web 应用程序开发过程中,总是无法避免涉及到文件上传,这次我们来聊一聊怎么去实现一个简单方便可复用文件上传功能:通过创建 ...

  6. 转 HTTP协议 (四) 缓存

    转自:http://www.cnblogs.com/TankXiao/archive/2012/11/28/2793365.html 缓存的概念 缓存这个东西真的是无处不在, 有浏览器端的缓存, 有服 ...

  7. Java实现文件自动打包成zip并下载的代码

      import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java. ...

  8. RCU介绍

    RCU原理: RCU(Read-Copy Update),顾名思义就是读-拷贝修改,它是基于其原理命名的.对于被RCU保护的共享数据结构,读者不需要获得任何锁就可以访问它,但写者在访问它时首先拷贝一个 ...

  9. nginx实战七

    Nginx优化-配置参数优化上 https://coding.net/u/aminglinux/p/nginx/git/blob/master/optimize/nginx_opt.md Nginx作 ...

  10. Python 元组 count() 方法

    描述 Python 元组 count() 方法用于统计某个元素在元祖中出现的次数. 语法 count() 方法语法: T.count(obj) 参数 obj -- 元祖中统计的对象. 返回值 返回元素 ...