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 的镜像 使用以下命令可以十分方便的从远程服务器上将 ...
随机推荐
- HOJ 1402 整数划分
HOJ1402 整数划分 http://acm.hit.edu.cn/hoj/problem/view?id=1402 [题目描述] 整数划分是一个经典的问题.希望这道题会对你的组合数学的解题能力有所 ...
- C# 打开钱箱支持北洋、佳博、爱普生
/// <summary> /// 执行开钱箱操作 /// 没钱箱或打印机原功能都可以正常使用 /// </summary> public void ExecuteOpenCa ...
- ASP.NET中UrlEncode应该用Uri.EscapeDataString()
今天,茄子_2008反馈他博客中的“C++”标签失效.检查了一下代码,生成链接时用的是HttpUtility.UrlEncode(url),从链接地址获取标签时用的是HttpUtility.UrlDe ...
- python学习笔记013——推导式
1 推导式简介 推导式comprehensions(又称解析式),是Python的一种独有特性. 推导式是可以从一个数据序列构建另一个新的数据序列的结构体. 推导式有三种形式: 1)列表推导式 (li ...
- RHCE7 管理I-12归档文件并在Linux系统间复制文件
tar命令使用 默认tar只有归档的功能,没有压缩功能 tar [option...] [file]... -c,--create 创建 -x,--extract,--get 解压 -t, ...
- Android中实现下拉刷新
需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新: 思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到 ListView中,从而实现消息 ...
- Linux内核(4) - 内核学习的心理问题
对于学习来说,无论是在学校的课堂学习,还是这里说的内核学习,效果好或者坏,最主要取决于两个方面——方法论和心理.注意,我无视了智商的差异,这玩意儿玄之又玄,岔开了说,属于迷信的范畴. 前面又是Kern ...
- Leet Code -- Unique BST
对于数字n(大于1).从1到n有多少种binary search tree(BST序列)?当n=3时,BST序列为: 1 3 3 2 1 \ ...
- Android开发5——文件读写
一.基本概念 在Android应用中保存文件,保存的位置有两处 ①手机自带的存储空间,较小(如200M),适合保存一些小文件,Android中保存位置在data/data/应用包名/files目录 ② ...
- linux分享一:进程全攻略--守护进程(服务)
概括: 进程是程序的运行实例.进程对应一个唯一的进程PID, 统一程序的多个实例可以同时运行,他们的pid互不相同. 进程一般分为交互进程.批处理进程和守护进程(daemons)三类 一:什么是守护进 ...