openwrt使用list
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的更多相关文章
- OpenWrt中开启usb存储和samba服务
在从官网安装的WNDR3800 15.05.1版本OpenWrt中, 不带usb存储支持以及samba, 需要另外安装 1. 启用usb支持 USB Basic Support https://wik ...
- (转)利用libcurl和国内著名的两个物联网云端通讯的例程, ubuntu和openwrt下调试成功(四)
1. libcurl 的参考文档如下 CURLOPT_HEADERFUNCTION Pass a pointer to a function that matches the following pr ...
- (转)利用libcurl获取新浪股票接口, ubuntu和openwrt实验成功(三)
1. 利用 CURLOPT_WRITEFUNCTION 设置回调函数, 利用 CURLOPT_WRITEDATA 获取数据指针 官网文档如下 CALLBACK OPTIONS CURLOPT_WRI ...
- (转)linux下和云端通讯的例程, ubuntu和openwrt下实验成功(二)
前言: 上节用纯linux的函数实现了和云端通讯, 本节开始利用传说中的神器libcurl 话说一个网络程序员对书法十分感兴趣,退休后决定在这方面有所建树. 于是花重金购买了上等的文房四宝. 一 ...
- (转)linux下和云端通讯的例程, ubuntu和openwrt实验成功(一)
一. HTTP请求的数据流总结#上传数据, yeelink的数据流如下POST /v1.0/device/4420/sensor/9089/datapoints HTTP/1.1Host: api. ...
- OpenWRT镜像爬虫搭建本地源
网上的爬虫不能用,还是先表达谢意,不过我比较懒不喜欢重复写别人写的教程,只贴出修改,怎么用自己看教程吧. 我自己改了一版可以正常爬: #!/usr/bin/env python #coding=utf ...
- 安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制
安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制 socket 连接采用流的方式进行发送接收数据,采用thread线程的方式. 什么是线程? 详细代码介 ...
- 极路由2(极贰)在OpenWrt下定制自己的ss服务
默认刷入的OpenWrt带的ss, 只有ss-redir服务, 但是在实际使用中, 很多时候还是希望访问直接通过正常网关, 只有少部分访问需要通过ss, 所以希望能配置成为ss-local服务. 在保 ...
- 极路由2(极贰)ROOT并刷了OpenWrt
绕过官方的ROOT 查了一下root教程, 如果还需要保留保修, 则需要自己想办法回退版本, 下载搜狐插件到sd卡, 找个linux系统修改sd卡上程序的执行权限, 然后才能开启ssh, 具体的方法可 ...
- 使用 Docker 编译 OpenWRT(Widora)
Docker 是一种新的被称之为容器的虚拟机.本文将使用此工具,进行 OpenWRT 的编译. 在 Docker 中下载 Ubuntu 14.04 的镜像 使用以下命令可以十分方便的从远程服务器上将 ...
随机推荐
- inet_ntoa 的一个小问题
一个简单点的阻塞式tcp服务器如下所示: #include <stdio.h> #include <string.h> #include <sys/socket.h> ...
- HTML:关于HTML的Doctype和严格模式与混杂模式
DOCTYPE标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档. Doctype可声明三种DTD类型,分别表示严格 ...
- 安装R语言的包的方法
安装R语言的包的方法: 1. 在线安装 在R的控制台,输入类似install.packages("TSA") # 安装 TSA install.packages("TS ...
- C语言訪问MySQL数据库的方法
1.加入头文件路径(MySQL安装路径中的include路径) 2.加入库文件(直接从MySQL安装路径中copy libmysql.lib就可以) 3.编程操作数据库 代码 // AccessToM ...
- python标准库介绍——12 time 模块详解
==time 模块== ``time`` 模块提供了一些处理日期和一天内时间的函数. 它是建立在 C 运行时库的简单封装. 给定的日期和时间可以被表示为浮点型(从参考时间, 通常是 1970.1.1 ...
- mysql创建数据库和删除数据库
1.创建数据库 启动MySQL 服务之后,输入以下命令连接到MySQL 服务器: [mysql@db3 ~]$ mysql -uroot -p Enter password: Welcome to t ...
- yii2 数据库操作详解(转载)
开始使用数据库首先需要配置数据库连接组件,通过添加 db 组件到应用配置实现("基础的" Web 应用是 config/web.php),DSN( Data Source Name ...
- 3dmax坐标系与导出fbx的坐标系
3dmax和opengl都是右手坐标系,但是3dmax是z轴向上,而opengl中是Y轴向上.如图: 所以在3dmax的fbx导出对话框中有“轴转化”一项,可以设置“Y向上”或者“Z向上”. 默认是“ ...
- 开源的报表系统easyreport的部署
https://github.com/xianrendzw/EasyReport/blob/master/docs/manual/version2_0.md
- 【转】js frame 框架编程
源地址:http://www.blogjava.net/lusm/archive/2008/02/11/179620.html 1 框架编程概述 一个Html 页面可以有一个或多个子框架,这些子框架以 ...