tux() - Unix 和 Linux 系统调用
广告
名称tux - 与 TUX 内核子系统交互语法
#include <sys/tuxmodule.h>
int tux (unsigned int action, user_req_t * req);
|
描述tux() 系统调用调用内核代表当前正在执行的用户空间 TUX 模块执行操作。
操作可以是以下之一
enum tux_actions {
TUX_ACTION_STARTUP = 1,
TUX_ACTION_SHUTDOWN = 2,
TUX_ACTION_STARTTHREAD = 3,
TUX_ACTION_STOPTHREAD = 4,
TUX_ACTION_EVENTLOOP = 5,
TUX_ACTION_GET_OBJECT = 6,
TUX_ACTION_SEND_OBJECT = 7,
TUX_ACTION_READ_OBJECT = 8,
TUX_ACTION_FINISH_REQ = 9,
TUX_ACTION_FINISH_CLOSE_REQ = 10,
TUX_ACTION_REGISTER_MODULE = 11,
TUX_ACTION_UNREGISTER_MODULE = 12,
TUX_ACTION_CURRENT_DATE = 13,
TUX_ACTION_REGISTER_MIMETYPE = 14,
TUX_ACTION_READ_HEADERS = 15,
TUX_ACTION_POSTPONE_REQ = 16,
TUX_ACTION_CONTINUE_REQ = 17,
TUX_ACTION_REDIRECT_REQ = 18,
TUX_ACTION_READ_POST_DATA = 19,
TUX_ACTION_SEND_BUFFER = 20,
TUX_ACTION_WATCH_PROXY_SOCKET = 21,
TUX_ACTION_WAIT_PROXY_SOCKET = 22,
TUX_ACTION_QUERY_VERSION = 23,
MAX_TUX_ACTION
};
|
下面列出的第一个操作值是管理性的,通常仅在 tux 程序中使用。 TUX_ACTION_STARTUP 启动 tux 子系统,并使用 NULL req。待办事项:只有 root 可以使用 TUX_ACTION_STARTUP。 TUX_ACTION_SHUTDOWN 停止 tux 子系统,并接受任何req,即使是零填充的req。 TUX_ACTION_STARTTHREAD 每个线程调用一次,其中req->thread_nr 元素从 0 开始单调递增。 TUX_ACTION_STOPTHREAD 当前未使用 tux 守护进程,因为所有线程在 TUX_ACTION_SHUTDOWN 上都会自动停止。它仍然可用,因为它在 tux 守护进程尚未处理的情况下可能很有用。 TUX_ACTION_REGISTER_MODULE 注册由req->modulename 字符串标识的用户空间模块。一个 VFS 名称只能注册一次。
req->version_major、req->version_minor 和req->version_patch 必须分别从 TUX_MAJOR_VERSION、TUX_MINOR_VERSION 和 TUX_PATCHLEVEL_VERSION 设置为适当的值;内核将检查模块的二进制兼容性。 TUX_ACTION_UNREGISTER_MODULE 取消注册由 req->modulename 字符串标识的用户空间模块。只有已注册的模块才能取消注册。 TUX_ACTION_CURRENT_DATE 将当前日期字符串设置为 req->new_date。日期字符串必须符合 RFC 1123 且必须单调递增。tux 守护进程通常每秒调用一次。 TUX_ACTION_REGISTER_MIMETYPE 设置扩展名 req->objectname 以映射到 mimetype req->object_addr。tux 守护进程通常在 /etc/tux.mime.types 中注册 mime 类型,但模块可以想象创建自己的 mimetype 映射。 TUX_ACTION_QUERY_VERSION 返回内核 TUX 子系统的主版本、次版本和补丁级别,在返回值中编码为
(TUX_MAJOR_VERSION << 24) | (TUX_MINOR_VERSION << 16) | TUX_PATCHLEVEL_VERSION
如果系统调用将 errno 设置为 EINVAL,则假设主版本为 2,次版本为 1。
其余的操作值用于响应 TUX 事件。总体架构是调用 TUX 的事件循环来捕获 HTTP 事件,然后生成响应以响应这些事件。 TUX_ACTION_EVENTLOOP 调用 TUX 事件循环 - TUX 子系统将立即返回新的请求req,或等待新的请求到达。 TUX_ACTION_GET_OBJECT 发出对req->objectname 中命名的 URL 对象的请求。如果对象无法立即使用,则当前处理的请求将被挂起,并返回一个新的请求,或者 TUX 子系统等待新的请求。 URL 对象是通过 URL 访问的数据流,并直接与该 URL 指向的文件相关联。(将来,我们可能会扩展 URL 对象的概念。)
TUX_ACTION_SEND_OBJECT 将当前 URL 对象发送到客户端。 TUX_ACTION_READ_OBJECT 将当前 URL 对象读入req->object_addr 指定的地址。除非req->objectlen >= 0,否则不得调用 TUX_ACTION_READ_OBJECT。 TUX_ACTION_READ_HEADERS 将一个非零分隔符字符串读入 req->object_addr,字符串的长度保存在 req->objectlen 中。这是一种用于读取 tux 当前未解析的字段的解决方法;如果您需要它,请将其报告为错误,以便可以向 user_req 添加更多字段(除非您的用途非常专门,以至于没有普遍效用)。 TUX_ACTION_POSTPONE_REQ 推迟请求,这意味着在调用 TUX_ACTION_CONTINUE_REQ 之前,任何 tux 系统调用都不会为此请求返回数据。 TUX_ACTION_CONTINUE_REQ 继续推迟的请求。与普通的 TUX_ACTION 不同,它以套接字描述符作为参数(如果需要,这允许它从与调用 TUX_ACTION_POSTPONE_REQ 的程序无关的程序中调用)。它像这样调用
ret = tux(TUX_ACTION_CONTINUE_REQ, (user_req_t *)socket);
|
TUX_ACTION_READ_POST_DATA 是一个原子操作(它将始终返回相同的请求,无需处理新请求),它将非零分隔符 POST 数据(最多 req->objectlen 中设置的最大值,并受 /proc/sys/net/tux/max_header_len 限制)放入 req->object_addr,并将 req->objectlen 重置为长度。 TUX_ACTION_REDIRECT_REQ 导致请求重定向到辅助服务器。(无需调用 TUX_ACTION_FINISH_REQ。) TUX_ACTION_FINISH_REQ 完成并记录请求。 TUX_ACTION_FINISH_CLOSE_REQ 与 TUX_ACTION_FINISH_REQ 类似,但它还会关闭 HTTP 1.1 保活连接。 TUX_ACTION_SEND_BUFFER 与 TUX_ACTION_SEND_OBJECT 类似,但它会发送 req->object_addr 缓冲区中的任何内容。这可以用作通用输出缓冲区。 TUX_ACTION_WATCH_PROXY_SOCKET 设置一个非 TUX 套接字,用于与 TUX_ACTION_WAIT_PROXY_SOCKET 一起使用。套接字必须是网络套接字。该函数是原子的。对该操作的重复调用将替换以前的代理套接字,因此无需对其进行反初始化。套接字文件描述符必须放入 req->object_addr 中。 TUX_ACTION_WAIT_PROXY_SOCKET 推迟当前请求,直到通过 TUX_ACTION_WATCH_PROXY_SOCKET 设置的套接字上有输入数据包。代理套接字有一个保活计时器正在运行。一旦套接字上有输入活动,请求就会恢复 - 模块可以使用套接字上的非阻塞 recv() 处理输入数据包。 user_req_t req 是 TUX 子系统返回的请求。定义的字段取决于版本。对于主版本 2,它们是
typedef struct user_req_s {
int version_major;
int version_minor;
int version_patch;
int http_version;
int http_method;
int sock;
int event;
int thread_nr;
void *id;
void *priv;
int http_status;
int bytes_sent;
char *object_addr;
int module_index;
char modulename[MAX_MODULENAME_LEN];
unsigned int client_host;
unsigned int objectlen;
char query[MAX_URI_LEN];
char objectname[MAX_URI_LEN];
unsigned int cookies_len;
char cookies[MAX_COOKIE_LEN];
char content_type[MAX_FIELD_LEN];
char user_agent[MAX_FIELD_LEN];
char accept[MAX_FIELD_LEN];
char accept_charset[MAX_FIELD_LEN];
char accept_encoding[MAX_FIELD_LEN];
char accept_language[MAX_FIELD_LEN];
char cache_control[MAX_FIELD_LEN];
char if_modified_since[MAX_FIELD_LEN];
char negotiate[MAX_FIELD_LEN];
char pragma[MAX_FIELD_LEN];
char referer[MAX_FIELD_LEN];
char *post_data;
char new_date[DATE_LEN];
int keep_alive;
} user_req_t;
|
对于主版本 3,它们是
typedef struct user_req_s {
uint32_t version_major;
uint32_t version_minor;
uint32_t version_patch;
uint32_t http_version;
uint32_t http_method;
uint32_t http_status;
uint32_t sock;
uint32_t event;
uint32_t error;
uint32_t thread_nr;
uint32_t bytes_sent;
uint32_t client_host;
uint32_t objectlen;
uint32_t module_index;
uint32_t keep_alive;
uint32_t cookies_len;
uint64_t id;
uint64_t priv;
uint64_t object_addr;
uint8_t query[MAX_URI_LEN];
uint8_t objectname[MAX_URI_LEN];
uint8_t cookies[MAX_COOKIE_LEN];
uint8_t content_type[MAX_FIELD_LEN];
uint8_t user_agent[MAX_FIELD_LEN];
uint8_t accept[MAX_FIELD_LEN];
uint8_t accept_charset[MAX_FIELD_LEN];
uint8_t accept_encoding[MAX_FIELD_LEN];
uint8_t accept_language[MAX_FIELD_LEN];
uint8_t cache_control[MAX_FIELD_LEN];
uint8_t if_modified_since[MAX_FIELD_LEN];
uint8_t negotiate[MAX_FIELD_LEN];
uint8_t pragma[MAX_FIELD_LEN];
uint8_t referer[MAX_FIELD_LEN];
uint8_t new_date[DATE_LEN];
} user_req_t;
|
标签 | 描述 |
version_major | | 始终设置为 TUX_MAJOR_VERSION,用于标记二进制不兼容性。 |
version_minor | | 始终设置为 TUX_MINOR_VERSION,用于标记二进制不兼容性。 |
version_patch | | 始终设置为 TUX_PATCHLEVEL_VERSION,用于标记二进制不兼容性。 |
http_version | | HTTP_1_0 或HTTP_1_1 之一 |
http_method | | METHOD_NONE、METHOD_GET、METHOD_HEAD、METHOD_POST 或METHOD_PUT 之一 |
sock | 套接字文件描述符;写入此文件将数据发送到与此请求关联的已连接客户端。不要从此套接字文件描述符读取;您可能会混淆 HTTP 引擎。 |
event | tux 模块使用的私有、每个请求状态。只要请求处于活动状态,系统就会保留此值。 |
thread_nr | | 线程索引;请参阅TUX_ACTION_STARTTHREAD 的讨论。 |
id | tux 守护进程内部的值,用于将请求多路复用到正确的模块。 |
priv | 与event 类似,只是它指向私有数据而不是整数。 |
http_status | | 将错误状态设置为整数以进行错误报告。默认情况下状态良好,因此除非要报告错误,否则不应修改它。 |
bytes_sent | | 当您写入 sock 时,必须将 bytes_sent 设置为自上次对该req 执行 tux() 操作以来发送的字节总数,否则日志条目的发送字节计数将不正确。(这可能会在将来的 tux 版本中更改或消失。) |
object_addr | | 设置为至少req->objectlen 大小的缓冲区的地址,以便使用 TUX_ACTION_READ_OBJECT 操作从 URL 缓存中读取对象。除非req->objectlen >= 0,否则不得调用 TUX_ACTION_READ_OBJECT,并且 TUX 隐式依赖于req->object_addr 至少为req->objectlen 大小。 |
module_index | | tux(8) 守护进程用于确定将哪个可加载模块与req 关联。 |
modulename | | 由 TUX_ACTION_REGISTER_MODULE 设置的模块名称;tux 守护进程的私有数据。 |
client_host | | sock 连接到的主机的 IP 地址。 |
objectlen | | 满足当前请求的文件的大小,该文件当前位于 URL 缓存中。如果请求在 TUX_ACTION_GET_OBJECT 后返回,则会设置此值。模块应确保在调用 TUX_ACTION_READ_OBJECT 之前,req->object_addr 处的缓冲区至少为req->objectlen 大小。 |
query | 客户端发送的完整查询字符串。 |
objectname | | 使用 TUX_ACTION_GET_OBJECT 操作指定要获取的 URL 的名称。如果 URL 无法立即使用(即不在 URL 缓存中),则请求将排队,并且 tux 子系统可能会在等待时继续处理其他就绪请求。 |
cookies_len | | 如果请求标头中存在 cookie,则cookies_len 包含cookies 字符串的长度 |
cookies | | 如果请求标头中存在 cookie,则cookies 是将 cookie 传递给模块的字符串。 |
content_type | | 请求的 Content-Type 标头值 |
user_agent | | 请求的 User-Agent 标头值 |
accept | 请求的 Accept 标头值 |
accept_charset | | 请求的 Accept-Charset 标头值 |
accept_encoding | | 请求的 Accept-Encoding 标头值 |
accept_language | | 请求的 Accept-Language 标头值 |
cache_control | | 请求的 Cache-Control 标头值 |
if_modified_since | | 请求的 If-Modified-Since 标头值 |
negotiate | | 请求的 Negotiate 标头值 |
pragma | 请求的 Pragma 标头值
|
referer | | 请求的 Referer 头部值 |
post_data | | 对于 POST 请求,传入的数据会被放置在 post_data 中。 |
new_date | | 返回当前日期/时间 |
keep_alive | | 请求的 KeepAlive 头部值
|
返回值
tux() 返回以下值
enum tux_reactions {
TUX_RETURN_USERSPACE_REQUEST = 0,
TUX_RETURN_EXIT = 1,
TUX_RETURN_SIGNAL = 2,
};
|
TUX_RETURN_USERSPACE_REQUEST 表示内核已将新的请求放入 req 中;必须使用 TUX_ACTION_GET_OBJECT、TUX_ACTION_SEND_OBJECT、TUX_ACTION_READ_OBJECT 或 TUX_ACTION_FINISH_REQ 中的一个来响应此请求。 TUX_RETURN_EXIT 表示 TUX 已停止。 TUX_RETURN_SIGNAL 表示发生了信号。没有安排新的请求。
错误任何负值(例如 -EFAULT、-EINVAL)都表示发生了错误。
缺陷此手册页不完整。
广告
|