Import ubus tools.
This commit is contained in:
24
3P/libubox/examples/CMakeLists.txt
Normal file
24
3P/libubox/examples/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
PROJECT(ubox-examples C)
|
||||
ADD_DEFINITIONS(-O1 -Wall -Werror --std=gnu99 -g3)
|
||||
|
||||
IF(APPLE)
|
||||
INCLUDE_DIRECTORIES(/opt/local/include)
|
||||
LINK_DIRECTORIES(/opt/local/lib)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
|
||||
FIND_LIBRARY(json NAMES json-c json)
|
||||
|
||||
ADD_EXECUTABLE(blobmsg-example blobmsg-example.c)
|
||||
TARGET_LINK_LIBRARIES(blobmsg-example ubox blobmsg_json ${json})
|
||||
|
||||
ADD_EXECUTABLE(ustream-example ustream-example.c)
|
||||
TARGET_LINK_LIBRARIES(ustream-example ubox)
|
||||
|
||||
ADD_EXECUTABLE(runqueue-example runqueue-example.c)
|
||||
TARGET_LINK_LIBRARIES(runqueue-example ubox)
|
||||
|
||||
139
3P/libubox/examples/blobmsg-example.c
Normal file
139
3P/libubox/examples/blobmsg-example.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blobmsg.h"
|
||||
#include "blobmsg_json.h"
|
||||
|
||||
static const char *indent_str = "\t\t\t\t\t\t\t\t\t\t\t\t\t";
|
||||
|
||||
#define indent_printf(indent, ...) do { \
|
||||
if (indent > 0) \
|
||||
fwrite(indent_str, indent, 1, stderr); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
static void dump_attr_data(struct blob_attr *data, int indent, int next_indent);
|
||||
|
||||
static void
|
||||
dump_table(struct blob_attr *head, int len, int indent, bool array)
|
||||
{
|
||||
struct blob_attr *attr;
|
||||
struct blobmsg_hdr *hdr;
|
||||
|
||||
indent_printf(indent, "{\n");
|
||||
__blob_for_each_attr(attr, head, len) {
|
||||
hdr = blob_data(attr);
|
||||
if (!array)
|
||||
indent_printf(indent + 1, "%s : ", hdr->name);
|
||||
dump_attr_data(attr, 0, indent + 1);
|
||||
}
|
||||
indent_printf(indent, "}\n");
|
||||
}
|
||||
|
||||
static void dump_attr_data(struct blob_attr *data, int indent, int next_indent)
|
||||
{
|
||||
int type = blobmsg_type(data);
|
||||
switch(type) {
|
||||
case BLOBMSG_TYPE_STRING:
|
||||
indent_printf(indent, "%s\n", blobmsg_get_string(data));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT8:
|
||||
indent_printf(indent, "%d\n", blobmsg_get_u8(data));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT16:
|
||||
indent_printf(indent, "%d\n", blobmsg_get_u16(data));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT32:
|
||||
indent_printf(indent, "%d\n", blobmsg_get_u32(data));
|
||||
break;
|
||||
case BLOBMSG_TYPE_INT64:
|
||||
indent_printf(indent, "%"PRIu64"\n", blobmsg_get_u64(data));
|
||||
break;
|
||||
case BLOBMSG_TYPE_TABLE:
|
||||
case BLOBMSG_TYPE_ARRAY:
|
||||
if (!indent)
|
||||
indent_printf(indent, "\n");
|
||||
dump_table(blobmsg_data(data), blobmsg_data_len(data),
|
||||
next_indent, type == BLOBMSG_TYPE_ARRAY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
FOO_MESSAGE,
|
||||
FOO_LIST,
|
||||
FOO_TESTDATA
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy pol[] = {
|
||||
[FOO_MESSAGE] = {
|
||||
.name = "message",
|
||||
.type = BLOBMSG_TYPE_STRING,
|
||||
},
|
||||
[FOO_LIST] = {
|
||||
.name = "list",
|
||||
.type = BLOBMSG_TYPE_ARRAY,
|
||||
},
|
||||
[FOO_TESTDATA] = {
|
||||
.name = "testdata",
|
||||
.type = BLOBMSG_TYPE_TABLE,
|
||||
},
|
||||
};
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
static void dump_message(struct blob_buf *buf)
|
||||
{
|
||||
struct blob_attr *tb[ARRAY_SIZE(pol)];
|
||||
|
||||
if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
|
||||
fprintf(stderr, "Parse failed\n");
|
||||
return;
|
||||
}
|
||||
if (tb[FOO_MESSAGE])
|
||||
fprintf(stderr, "Message: %s\n", (char *) blobmsg_data(tb[FOO_MESSAGE]));
|
||||
|
||||
if (tb[FOO_LIST]) {
|
||||
fprintf(stderr, "List: ");
|
||||
dump_table(blobmsg_data(tb[FOO_LIST]), blobmsg_data_len(tb[FOO_LIST]), 0, true);
|
||||
}
|
||||
if (tb[FOO_TESTDATA]) {
|
||||
fprintf(stderr, "Testdata: ");
|
||||
dump_table(blobmsg_data(tb[FOO_TESTDATA]), blobmsg_data_len(tb[FOO_TESTDATA]), 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fill_message(struct blob_buf *buf)
|
||||
{
|
||||
void *tbl;
|
||||
|
||||
blobmsg_add_string(buf, "message", "Hello, world!");
|
||||
|
||||
tbl = blobmsg_open_table(buf, "testdata");
|
||||
blobmsg_add_u32(buf, "hello", 1);
|
||||
blobmsg_add_string(buf, "world", "2");
|
||||
blobmsg_close_table(buf, tbl);
|
||||
|
||||
tbl = blobmsg_open_array(buf, "list");
|
||||
blobmsg_add_u32(buf, NULL, 0);
|
||||
blobmsg_add_u32(buf, NULL, 1);
|
||||
blobmsg_add_u32(buf, NULL, 2);
|
||||
blobmsg_close_table(buf, tbl);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static struct blob_buf buf;
|
||||
|
||||
blobmsg_buf_init(&buf);
|
||||
fill_message(&buf);
|
||||
dump_message(&buf);
|
||||
fprintf(stderr, "json: %s\n", blobmsg_format_json(buf.head, true));
|
||||
|
||||
if (buf.buf)
|
||||
free(buf.buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
112
3P/libubox/examples/runqueue-example.c
Normal file
112
3P/libubox/examples/runqueue-example.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* runqueue-example.c
|
||||
*
|
||||
* Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <libubox/uloop.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "runqueue.h"
|
||||
|
||||
static struct runqueue q;
|
||||
|
||||
struct sleeper {
|
||||
struct runqueue_process proc;
|
||||
int val;
|
||||
};
|
||||
|
||||
static void q_empty(struct runqueue *q)
|
||||
{
|
||||
fprintf(stderr, "All done!\n");
|
||||
uloop_end();
|
||||
}
|
||||
|
||||
static void q_sleep_run(struct runqueue *q, struct runqueue_task *t)
|
||||
{
|
||||
struct sleeper *s = container_of(t, struct sleeper, proc.task);
|
||||
char str[32];
|
||||
pid_t pid;
|
||||
|
||||
fprintf(stderr, "[%d/%d] start 'sleep %d'\n", q->running_tasks, q->max_running_tasks, s->val);
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
return;
|
||||
|
||||
if (pid) {
|
||||
runqueue_process_add(q, &s->proc, pid);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(str, "%d", s->val);
|
||||
execlp("sleep", "sleep", str, NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void q_sleep_cancel(struct runqueue *q, struct runqueue_task *t, int type)
|
||||
{
|
||||
struct sleeper *s = container_of(t, struct sleeper, proc.task);
|
||||
|
||||
fprintf(stderr, "[%d/%d] cancel 'sleep %d'\n", q->running_tasks, q->max_running_tasks, s->val);
|
||||
runqueue_process_cancel_cb(q, t, type);
|
||||
}
|
||||
|
||||
static void q_sleep_complete(struct runqueue *q, struct runqueue_task *p)
|
||||
{
|
||||
struct sleeper *s = container_of(p, struct sleeper, proc.task);
|
||||
|
||||
fprintf(stderr, "[%d/%d] finish 'sleep %d'\n", q->running_tasks, q->max_running_tasks, s->val);
|
||||
free(s);
|
||||
}
|
||||
|
||||
static void add_sleeper(int val)
|
||||
{
|
||||
static const struct runqueue_task_type sleeper_type = {
|
||||
.run = q_sleep_run,
|
||||
.cancel = q_sleep_cancel,
|
||||
.kill = runqueue_process_kill_cb,
|
||||
};
|
||||
struct sleeper *s;
|
||||
|
||||
s = calloc(1, sizeof(*s));
|
||||
s->proc.task.type = &sleeper_type;
|
||||
s->proc.task.run_timeout = 500;
|
||||
s->proc.task.complete = q_sleep_complete;
|
||||
s->val = val;
|
||||
runqueue_task_add(&q, &s->proc.task, false);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uloop_init();
|
||||
|
||||
runqueue_init(&q);
|
||||
q.empty_cb = q_empty;
|
||||
q.max_running_tasks = 1;
|
||||
|
||||
if (argc > 1)
|
||||
q.max_running_tasks = atoi(argv[1]);
|
||||
|
||||
add_sleeper(1);
|
||||
add_sleeper(1);
|
||||
add_sleeper(1);
|
||||
uloop_run();
|
||||
uloop_done();
|
||||
|
||||
return 0;
|
||||
}
|
||||
78
3P/libubox/examples/uloop-example.lua
Executable file
78
3P/libubox/examples/uloop-example.lua
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
local socket = require "socket"
|
||||
|
||||
local uloop = require("uloop")
|
||||
uloop.init()
|
||||
|
||||
local udp = socket.udp()
|
||||
udp:settimeout(0)
|
||||
udp:setsockname('*', 8080)
|
||||
|
||||
-- timer example 1
|
||||
local timer
|
||||
function t()
|
||||
print("1000 ms timer run");
|
||||
timer:set(1000)
|
||||
end
|
||||
timer = uloop.timer(t)
|
||||
timer:set(1000)
|
||||
|
||||
-- timer example 2
|
||||
uloop.timer(function() print("2000 ms timer run"); end, 2000)
|
||||
|
||||
-- timer example 3
|
||||
uloop.timer(function() print("3000 ms timer run"); end, 3000):cancel()
|
||||
|
||||
-- process
|
||||
function p1(r)
|
||||
print("Process 1 completed")
|
||||
print(r)
|
||||
end
|
||||
|
||||
function p2(r)
|
||||
print("Process 2 completed")
|
||||
print(r)
|
||||
end
|
||||
|
||||
uloop.timer(
|
||||
function()
|
||||
uloop.process("uloop_pid_test.sh", {"foo", "bar"}, {"PROCESS=1"}, p1)
|
||||
end, 1000
|
||||
)
|
||||
uloop.timer(
|
||||
function()
|
||||
uloop.process("uloop_pid_test.sh", {"foo", "bar"}, {"PROCESS=2"}, p2)
|
||||
end, 2000
|
||||
)
|
||||
|
||||
udp_ev = uloop.fd_add(udp, function(ufd, events)
|
||||
local words, msg_or_ip, port_or_nil = ufd:receivefrom()
|
||||
print('Recv UDP packet from '..msg_or_ip..':'..port_or_nil..' : '..words)
|
||||
if words == "Stop!" then
|
||||
udp_ev:delete()
|
||||
end
|
||||
end, uloop.ULOOP_READ)
|
||||
|
||||
udp_count = 0
|
||||
udp_send_timer = uloop.timer(
|
||||
function()
|
||||
local s = socket.udp()
|
||||
local words
|
||||
if udp_count > 3 then
|
||||
words = "Stop!"
|
||||
udp_send_timer:cancel()
|
||||
else
|
||||
words = 'Hello!'
|
||||
udp_send_timer:set(1000)
|
||||
end
|
||||
print('Send UDP packet to 127.0.0.1:8080 :'..words)
|
||||
s:sendto(words, '127.0.0.1', 8080)
|
||||
s:close()
|
||||
|
||||
udp_count = udp_count + 1
|
||||
end, 3000
|
||||
)
|
||||
|
||||
uloop.run()
|
||||
|
||||
11
3P/libubox/examples/uloop_pid_test.sh
Executable file
11
3P/libubox/examples/uloop_pid_test.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo $0 $*
|
||||
echo Environment:
|
||||
env
|
||||
|
||||
sleep 2
|
||||
|
||||
echo "stopping child"
|
||||
|
||||
exit 5
|
||||
148
3P/libubox/examples/ustream-example.c
Normal file
148
3P/libubox/examples/ustream-example.c
Normal file
@@ -0,0 +1,148 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ustream.h"
|
||||
#include "uloop.h"
|
||||
#include "usock.h"
|
||||
|
||||
static struct uloop_fd server;
|
||||
static const char *port = "10000";
|
||||
struct client *next_client = NULL;
|
||||
|
||||
struct client {
|
||||
struct sockaddr_in sin;
|
||||
|
||||
struct ustream_fd s;
|
||||
int ctr;
|
||||
};
|
||||
|
||||
static void client_read_cb(struct ustream *s, int bytes)
|
||||
{
|
||||
struct client *cl = container_of(s, struct client, s.stream);
|
||||
struct ustream_buf *buf = s->r.head;
|
||||
char *newline, *str;
|
||||
|
||||
do {
|
||||
str = ustream_get_read_buf(s, NULL);
|
||||
if (!str)
|
||||
break;
|
||||
|
||||
newline = strchr(buf->data, '\n');
|
||||
if (!newline)
|
||||
break;
|
||||
|
||||
*newline = 0;
|
||||
ustream_printf(s, "%s\n", str);
|
||||
ustream_consume(s, newline + 1 - str);
|
||||
cl->ctr += newline + 1 - str;
|
||||
} while(1);
|
||||
|
||||
if (s->w.data_bytes > 256 && !ustream_read_blocked(s)) {
|
||||
fprintf(stderr, "Block read, bytes: %d\n", s->w.data_bytes);
|
||||
ustream_set_read_blocked(s, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void client_close(struct ustream *s)
|
||||
{
|
||||
struct client *cl = container_of(s, struct client, s.stream);
|
||||
|
||||
fprintf(stderr, "Connection closed\n");
|
||||
ustream_free(s);
|
||||
close(cl->s.fd.fd);
|
||||
free(cl);
|
||||
}
|
||||
|
||||
static void client_notify_write(struct ustream *s, int bytes)
|
||||
{
|
||||
fprintf(stderr, "Wrote %d bytes, pending: %d\n", bytes, s->w.data_bytes);
|
||||
|
||||
if (s->w.data_bytes < 128 && ustream_read_blocked(s)) {
|
||||
fprintf(stderr, "Unblock read\n");
|
||||
ustream_set_read_blocked(s, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void client_notify_state(struct ustream *s)
|
||||
{
|
||||
struct client *cl = container_of(s, struct client, s.stream);
|
||||
|
||||
if (!s->eof)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
|
||||
if (!s->w.data_bytes)
|
||||
return client_close(s);
|
||||
|
||||
}
|
||||
|
||||
static void server_cb(struct uloop_fd *fd, unsigned int events)
|
||||
{
|
||||
struct client *cl;
|
||||
unsigned int sl = sizeof(struct sockaddr_in);
|
||||
int sfd;
|
||||
|
||||
if (!next_client)
|
||||
next_client = calloc(1, sizeof(*next_client));
|
||||
|
||||
cl = next_client;
|
||||
sfd = accept(server.fd, (struct sockaddr *) &cl->sin, &sl);
|
||||
if (sfd < 0) {
|
||||
fprintf(stderr, "Accept failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cl->s.stream.string_data = true;
|
||||
cl->s.stream.notify_read = client_read_cb;
|
||||
cl->s.stream.notify_state = client_notify_state;
|
||||
cl->s.stream.notify_write = client_notify_write;
|
||||
ustream_fd_init(&cl->s, sfd);
|
||||
next_client = NULL;
|
||||
fprintf(stderr, "New connection\n");
|
||||
}
|
||||
|
||||
static int run_server(void)
|
||||
{
|
||||
|
||||
server.cb = server_cb;
|
||||
server.fd = usock(USOCK_TCP | USOCK_SERVER | USOCK_IPV4ONLY | USOCK_NUMERIC, "127.0.0.1", port);
|
||||
if (server.fd < 0) {
|
||||
perror("usock");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uloop_init();
|
||||
uloop_fd_add(&server, ULOOP_READ);
|
||||
uloop_run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usage(const char *name)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s -p <port>\n", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "p:")) != -1) {
|
||||
switch(ch) {
|
||||
case 'p':
|
||||
port = optarg;
|
||||
break;
|
||||
default:
|
||||
return usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return run_server();
|
||||
}
|
||||
Reference in New Issue
Block a user