Skip to content

Commit

Permalink
Merge pull request #18 from one-pr/code
Browse files Browse the repository at this point in the history
[code] 添加原始的示例代码
  • Loading branch information
luohaha authored Jan 21, 2022
2 parents 83eca87 + 5014a6c commit 5db70ce
Show file tree
Hide file tree
Showing 34 changed files with 1,795 additions and 0 deletions.
81 changes: 81 additions & 0 deletions code/cgi/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>

uv_loop_t *loop;
uv_process_t child_req;
uv_process_options_t options;

void cleanup_handles(uv_process_t *req, int64_t exit_status, int term_signal) {
fprintf(stderr, "Process exited with status %" PRId64 ", signal %d\n", exit_status, term_signal);
uv_close((uv_handle_t*) req->data, NULL);
uv_close((uv_handle_t*) req, NULL);
}

void invoke_cgi_script(uv_tcp_t *client) {
size_t size = 500;
char path[size];
uv_exepath(path, &size);
strcpy(path + (strlen(path) - strlen("cgi")), "tick");

char* args[2];
args[0] = path;
args[1] = NULL;

/* ... finding the executable path and setting up arguments ... */

options.stdio_count = 3;
uv_stdio_container_t child_stdio[3];
child_stdio[0].flags = UV_IGNORE;
child_stdio[1].flags = UV_INHERIT_STREAM;
child_stdio[1].data.stream = (uv_stream_t*) client;
child_stdio[2].flags = UV_IGNORE;
options.stdio = child_stdio;

options.exit_cb = cleanup_handles;
options.file = args[0];
options.args = args;

// Set this so we can close the socket after the child process exits.
child_req.data = (void*) client;
int r;
if ((r = uv_spawn(loop, &child_req, &options))) {
fprintf(stderr, "%s\n", uv_strerror(r));
return;
}
}

void on_new_connection(uv_stream_t *server, int status) {
if (status == -1) {
// error!
return;
}

uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
uv_tcp_init(loop, client);
if (uv_accept(server, (uv_stream_t*) client) == 0) {
invoke_cgi_script(client);
}
else {
uv_close((uv_handle_t*) client, NULL);
}
}

int main() {
loop = uv_default_loop();

uv_tcp_t server;
uv_tcp_init(loop, &server);

struct sockaddr_in bind_addr;
uv_ip4_addr("0.0.0.0", 7000, &bind_addr);
uv_tcp_bind(&server, (const struct sockaddr *)&bind_addr, 0);
int r = uv_listen((uv_stream_t*) &server, 128, on_new_connection);
if (r) {
fprintf(stderr, "Listen error %s\n", uv_err_name(r));
return 1;
}
return uv_run(loop, UV_RUN_DEFAULT);
}
13 changes: 13 additions & 0 deletions code/cgi/tick.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <stdio.h>
#include <unistd.h>

int main() {
int i;
for (i = 0; i < 10; i++) {
printf("tick\n");
fflush(stdout);
sleep(1);
}
printf("BOOM!\n");
return 0;
}
31 changes: 31 additions & 0 deletions code/detach/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <stdio.h>

#include <uv.h>

uv_loop_t *loop;
uv_process_t child_req;
uv_process_options_t options;

int main() {
loop = uv_default_loop();

char* args[3];
args[0] = "sleep";
args[1] = "100";
args[2] = NULL;

options.exit_cb = NULL;
options.file = "sleep";
options.args = args;
options.flags = UV_PROCESS_DETACHED;

int r;
if ((r = uv_spawn(loop, &child_req, &options))) {
fprintf(stderr, "%s\n", uv_strerror(r));
return 1;
}
fprintf(stderr, "Launched sleep with PID %d\n", child_req.pid);
uv_unref((uv_handle_t*) &child_req);

return uv_run(loop, UV_RUN_DEFAULT);
}
80 changes: 80 additions & 0 deletions code/dns/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>

uv_loop_t *loop;

void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = malloc(suggested_size);
buf->len = suggested_size;
}

void on_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t*) client, NULL);
free(buf->base);
free(client);
return;
}

char *data = (char*) malloc(sizeof(char) * (nread+1));
data[nread] = '\0';
strncpy(data, buf->base, nread);

fprintf(stderr, "%s", data);
free(data);
free(buf->base);
}

void on_connect(uv_connect_t *req, int status) {
if (status < 0) {
fprintf(stderr, "connect failed error %s\n", uv_err_name(status));
free(req);
return;
}

uv_read_start((uv_stream_t*) req->handle, alloc_buffer, on_read);
free(req);
}

void on_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res) {
if (status < 0) {
fprintf(stderr, "getaddrinfo callback error %s\n", uv_err_name(status));
return;
}

char addr[17] = {'\0'};
uv_ip4_name((struct sockaddr_in*) res->ai_addr, addr, 16);
fprintf(stderr, "%s\n", addr);

uv_connect_t *connect_req = (uv_connect_t*) malloc(sizeof(uv_connect_t));
uv_tcp_t *socket = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
uv_tcp_init(loop, socket);

uv_tcp_connect(connect_req, socket, (const struct sockaddr*) res->ai_addr, on_connect);

uv_freeaddrinfo(res);
}

int main() {
loop = uv_default_loop();

struct addrinfo hints;
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = 0;

uv_getaddrinfo_t resolver;
fprintf(stderr, "irc.libera.chat is... ");
int r = uv_getaddrinfo(loop, &resolver, on_resolved, "irc.libera.chat", "6667", &hints);

if (r) {
fprintf(stderr, "getaddrinfo call error %s\n", uv_err_name(r));
return 1;
}
return uv_run(loop, UV_RUN_DEFAULT);
}
15 changes: 15 additions & 0 deletions code/helloworld/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>

int main() {
uv_loop_t *loop = malloc(sizeof(uv_loop_t));
uv_loop_init(loop);

printf("Now quitting.\n");
uv_run(loop, UV_RUN_DEFAULT);

uv_loop_close(loop);
free(loop);
return 0;
}
24 changes: 24 additions & 0 deletions code/idle-basic/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <stdio.h>
#include <uv.h>

int64_t counter = 0;

void wait_for_a_while(uv_idle_t* handle) {
counter++;

if (counter >= 10e6)
uv_idle_stop(handle);
}

int main() {
uv_idle_t idler;

uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for_a_while);

printf("Idling...\n");
uv_run(uv_default_loop(), UV_RUN_DEFAULT);

uv_loop_close(uv_default_loop());
return 0;
}
43 changes: 43 additions & 0 deletions code/idle-compute/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <stdio.h>

#include <uv.h>

uv_loop_t *loop;
uv_fs_t stdin_watcher;
uv_idle_t idler;
char buffer[1024];

void crunch_away(uv_idle_t* handle) {
// Compute extra-terrestrial life
// fold proteins
// computer another digit of PI
// or similar
fprintf(stderr, "Computing PI...\n");
// just to avoid overwhelming your terminal emulator
uv_idle_stop(handle);
}

void on_type(uv_fs_t *req) {
if (stdin_watcher.result > 0) {
buffer[stdin_watcher.result] = '\0';
printf("Typed %s\n", buffer);

uv_buf_t buf = uv_buf_init(buffer, 1024);
uv_fs_read(loop, &stdin_watcher, 0, &buf, 1, -1, on_type);
uv_idle_start(&idler, crunch_away);
}
else if (stdin_watcher.result < 0) {
fprintf(stderr, "error opening file: %s\n", uv_strerror(req->result));
}
}

int main() {
loop = uv_default_loop();

uv_idle_init(loop, &idler);

uv_buf_t buf = uv_buf_init(buffer, 1024);
uv_fs_read(loop, &stdin_watcher, 0, &buf, 1, -1, on_type);
uv_idle_start(&idler, crunch_away);
return uv_run(loop, UV_RUN_DEFAULT);
}
33 changes: 33 additions & 0 deletions code/interfaces/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <stdio.h>
#include <uv.h>

int main() {
char buf[512];
uv_interface_address_t *info;
int count, i;

uv_interface_addresses(&info, &count);
i = count;

printf("Number of interfaces: %d\n", count);
while (i--) {
uv_interface_address_t interface = info[i];

printf("Name: %s\n", interface.name);
printf("Internal? %s\n", interface.is_internal ? "Yes" : "No");

if (interface.address.address4.sin_family == AF_INET) {
uv_ip4_name(&interface.address.address4, buf, sizeof(buf));
printf("IPv4 address: %s\n", buf);
}
else if (interface.address.address4.sin_family == AF_INET6) {
uv_ip6_name(&interface.address.address6, buf, sizeof(buf));
printf("IPv6 address: %s\n", buf);
}

printf("\n");
}

uv_free_interface_addresses(info, count);
return 0;
}
57 changes: 57 additions & 0 deletions code/locks/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <stdio.h>
#include <uv.h>

uv_barrier_t blocker;
uv_rwlock_t numlock;
int shared_num;

void reader(void *n)
{
int num = *(int *)n;
int i;
for (i = 0; i < 20; i++) {
uv_rwlock_rdlock(&numlock);
printf("Reader %d: acquired lock\n", num);
printf("Reader %d: shared num = %d\n", num, shared_num);
uv_rwlock_rdunlock(&numlock);
printf("Reader %d: released lock\n", num);
}
uv_barrier_wait(&blocker);
}

void writer(void *n)
{
int num = *(int *)n;
int i;
for (i = 0; i < 20; i++) {
uv_rwlock_wrlock(&numlock);
printf("Writer %d: acquired lock\n", num);
shared_num++;
printf("Writer %d: incremented shared num = %d\n", num, shared_num);
uv_rwlock_wrunlock(&numlock);
printf("Writer %d: released lock\n", num);
}
uv_barrier_wait(&blocker);
}

int main()
{
uv_barrier_init(&blocker, 4);

shared_num = 0;
uv_rwlock_init(&numlock);

uv_thread_t threads[3];

int thread_nums[] = {1, 2, 1};
uv_thread_create(&threads[0], reader, &thread_nums[0]);
uv_thread_create(&threads[1], reader, &thread_nums[1]);

uv_thread_create(&threads[2], writer, &thread_nums[2]);

uv_barrier_wait(&blocker);
uv_barrier_destroy(&blocker);

uv_rwlock_destroy(&numlock);
return 0;
}
Loading

0 comments on commit 5db70ce

Please sign in to comment.