update folders
This commit is contained in:
38
snipplets/code/C/AF_INET_sockets/echo_client.c
Normal file
38
snipplets/code/C/AF_INET_sockets/echo_client.c
Normal file
@ -0,0 +1,38 @@
|
||||
/* https://rsdn.org/article/unix/sockets.xml */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
char message[] = "Hello there!\n";
|
||||
char buf[sizeof(message)];
|
||||
|
||||
int main()
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(3425); // или любой другой порт...
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
perror("connect");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
send(sock, message, sizeof(message), 0);
|
||||
recv(sock, buf, sizeof(message), 0);
|
||||
|
||||
printf(buf);
|
||||
close(sock);
|
||||
|
||||
return 0;
|
||||
}
|
48
snipplets/code/C/AF_INET_sockets/echo_server.c
Normal file
48
snipplets/code/C/AF_INET_sockets/echo_server.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* https://rsdn.org/article/unix/sockets.xml */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int sock, listener;
|
||||
struct sockaddr_in addr;
|
||||
char buf[1024];
|
||||
int bytes_read;
|
||||
|
||||
listener = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listener < 0) {
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(3425);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if (bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
perror("bind");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
listen(listener, 1);
|
||||
|
||||
while(1) {
|
||||
sock = accept(listener, NULL, NULL);
|
||||
if (sock < 0) {
|
||||
perror("accept");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
bytes_read = recv(sock, buf, 1024, 0);
|
||||
if (bytes_read <= 0) break;
|
||||
send(sock, buf, bytes_read, 0);
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
snipplets/code/C/Makefile
Normal file
8
snipplets/code/C/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
CC = clang
|
||||
CFLAGS = -O2
|
||||
LDFLAGS = -lsqlite3
|
||||
|
||||
all: sqlite3_create sqlite3_insert sqlite3_select sqlite3_update sqlite3_delete
|
||||
|
||||
clean:
|
||||
rm sqlite3_create sqlite3_insert sqlite3_select sqlite3_update sqlite3_delete
|
9
snipplets/code/C/README.md
Normal file
9
snipplets/code/C/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# C
|
||||
|
||||
## SQLite 3
|
||||
|
||||
- [CREATE TABLE](sqlite/sqlite3_create.c)
|
||||
- [INSERT INTO](sqlite/sqlite3_insert.c)
|
||||
- [SELECT](sqlite/sqlite3_select.c)
|
||||
- [UPDATE](sqlite/sqlite3_update.c)
|
||||
- [DELETE](sqlite/sqlite3_delete.c)
|
30
snipplets/code/C/atomic.c
Normal file
30
snipplets/code/C/atomic.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
#include <threads.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
atomic_int acnt;
|
||||
int cnt;
|
||||
|
||||
int f(void* thr_data)
|
||||
{
|
||||
(void)thr_data;
|
||||
for(int n = 0; n < 1000; ++n) {
|
||||
++cnt;
|
||||
++acnt;
|
||||
// for this example, relaxed memory order is sufficient, e.g.
|
||||
// atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
thrd_t thr[10];
|
||||
for(int n = 0; n < 10; ++n)
|
||||
thrd_create(&thr[n], f, NULL);
|
||||
for(int n = 0; n < 10; ++n)
|
||||
thrd_join(thr[n], NULL);
|
||||
|
||||
printf("The atomic counter is %u\n", acnt);
|
||||
printf("The non-atomic counter is %u\n", cnt);
|
||||
}
|
10
snipplets/code/C/clear_string.c
Normal file
10
snipplets/code/C/clear_string.c
Normal file
@ -0,0 +1,10 @@
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
char *buffer = malloc(256 + 1);
|
||||
|
||||
buffer[0] = '\0';
|
||||
strcpy(buffer, "");
|
||||
memset(buffer, '\0', sizeof(buffer));
|
||||
|
||||
return 0;
|
||||
}
|
10
snipplets/code/C/format-code
Executable file
10
snipplets/code/C/format-code
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
files=(
|
||||
"file.c"
|
||||
)
|
||||
|
||||
for file in "${files[@]}"
|
||||
do
|
||||
clang-format -i --style=LLVM --sort-includes=false $file
|
||||
done
|
6
snipplets/code/C/libserialport/.editorconfig
Normal file
6
snipplets/code/C/libserialport/.editorconfig
Normal file
@ -0,0 +1,6 @@
|
||||
[{clear,build,format-code}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[{*.c,*.ino}]
|
||||
indent_size = 2
|
12
snipplets/code/C/libserialport/.gitignore
vendored
Normal file
12
snipplets/code/C/libserialport/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# libserialport examples
|
||||
port_info.c
|
||||
list_ports.c
|
||||
send_receive.c
|
||||
|
||||
# binaries
|
||||
port_info
|
||||
list_ports
|
||||
send_receive
|
||||
|
||||
listen
|
||||
abc.txt
|
1
snipplets/code/C/libserialport/Board/.gitignore
vendored
Normal file
1
snipplets/code/C/libserialport/Board/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
3party/
|
24
snipplets/code/C/libserialport/Board/Board.ino
Normal file
24
snipplets/code/C/libserialport/Board/Board.ino
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
Author: Alexander Popov
|
||||
License: Unlicense
|
||||
*/
|
||||
|
||||
#include "3party/AsyncStream.h"
|
||||
AsyncStream<50> serial(&Serial, '\n');
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (strcmp(serial.buf, "ping") == 0) {
|
||||
Serial.println("PONG");
|
||||
}
|
||||
|
||||
Serial.println("ooooo");
|
||||
// delay(1000);
|
||||
Serial.println("zzzz");
|
||||
// delay(1000);
|
||||
Serial.println("xxx");
|
||||
// delay(1000);
|
||||
}
|
3
snipplets/code/C/libserialport/Board/README.md
Normal file
3
snipplets/code/C/libserialport/Board/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
Download `AsyncStream.h` from
|
||||
https://github.com/GyverLibs/AsyncStream
|
||||
and drop in to `3party` folder.
|
18
snipplets/code/C/libserialport/README.md
Normal file
18
snipplets/code/C/libserialport/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
Download `libserialport` library.
|
||||
|
||||
```sh
|
||||
git clone git://sigrok.org/libserialport
|
||||
```
|
||||
|
||||
For **build** code use `build` script or build files manually.
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
export C_INCLUDE_PATH=<path/to/libserialport>
|
||||
export LIBRARY_PATH=<path/to/libserialport/.libs>
|
||||
|
||||
gcc -static -Wall -O3 -o <output_filename> <file.c> -lserialport
|
||||
```
|
||||
|
||||
Arduino example project store in `Board` folder.
|
20
snipplets/code/C/libserialport/build_gcc
Executable file
20
snipplets/code/C/libserialport/build_gcc
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# build - script for build all files.
|
||||
#
|
||||
# Alexander Popov <iiiypuk@fastmail.fm>
|
||||
|
||||
export C_INCLUDE_PATH=$HOME/Git/libserialport
|
||||
export LIBRARY_PATH=$HOME/Git/libserialport/.libs
|
||||
|
||||
for file in \
|
||||
port_info.c \
|
||||
list_ports.c \
|
||||
send_receive.c \
|
||||
listen.c \
|
||||
|
||||
do
|
||||
echo -ne "[ ] Building $file...\r"
|
||||
gcc -static -Wall -O3 -o ${file%.*} $file -lserialport
|
||||
echo [OK
|
||||
done
|
20
snipplets/code/C/libserialport/build_tcc
Executable file
20
snipplets/code/C/libserialport/build_tcc
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# build - script for build all files.
|
||||
#
|
||||
# Alexander Popov <iiiypuk@fastmail.fm>
|
||||
|
||||
export C_INCLUDE_PATH=$HOME/Git/libserialport
|
||||
export LIBRARY_PATH=$HOME/Git/libserialport/.libs
|
||||
|
||||
for file in \
|
||||
port_info.c \
|
||||
list_ports.c \
|
||||
send_receive.c \
|
||||
listen.c \
|
||||
|
||||
do
|
||||
echo -ne "[ ] Building $file...\r"
|
||||
tcc -Wall -O3 -o ${file%.*} -I$C_INCLUDE_PATH $file $LIBRARY_PATH/libserialport.a
|
||||
echo [OK
|
||||
done
|
17
snipplets/code/C/libserialport/clear
Executable file
17
snipplets/code/C/libserialport/clear
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# clear - script for delete all builded files.
|
||||
#
|
||||
# Alexander Popov <iiiypuk@fastmail.fm>
|
||||
|
||||
files=(
|
||||
"port_info"
|
||||
"list_ports"
|
||||
"send_receive"
|
||||
"listen"
|
||||
)
|
||||
|
||||
for file in ${files[@]}
|
||||
do
|
||||
rm $file &> /dev/null
|
||||
done
|
14
snipplets/code/C/libserialport/format-code
Executable file
14
snipplets/code/C/libserialport/format-code
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# formt-code - script for beautify code by clang-format.
|
||||
#
|
||||
# Alexander Popov <iiiypuk@fastmail.fm>
|
||||
|
||||
files=(
|
||||
"listen.c"
|
||||
)
|
||||
|
||||
for file in "${files[@]}"
|
||||
do
|
||||
clang-format -i --style=LLVM --sort-includes=false $file
|
||||
done
|
133
snipplets/code/C/libserialport/listen.c
Normal file
133
snipplets/code/C/libserialport/listen.c
Normal file
@ -0,0 +1,133 @@
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result);
|
||||
void handle_sigint(int sig);
|
||||
|
||||
bool INTERRUPT = false;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct sp_port *serial_port;
|
||||
char *port_name;
|
||||
|
||||
const int size = 256;
|
||||
char *buffer = malloc(size + 1);
|
||||
|
||||
const unsigned int timeout = 1000;
|
||||
int result;
|
||||
|
||||
/* Get the port name from the command line. */
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <port>\n\n", argv[0]);
|
||||
|
||||
struct sp_port **port_list;
|
||||
enum sp_return result = sp_list_ports(&port_list);
|
||||
|
||||
/* Getting the available ports. */
|
||||
if (result != SP_OK) {
|
||||
puts("Getting available ports failed!");
|
||||
} else {
|
||||
puts("Available ports:");
|
||||
|
||||
int i;
|
||||
for (i = 0; port_list[i] != NULL; i++) {
|
||||
/* Get the name of the port. */
|
||||
struct sp_port *port = port_list[i];
|
||||
char *port_name = sp_get_port_name(port);
|
||||
|
||||
printf(" * %s\n", port_name);
|
||||
}
|
||||
|
||||
printf("\nAvailable %d ports.\n", i);
|
||||
|
||||
sp_free_port_list(port_list);
|
||||
}
|
||||
|
||||
return -1;
|
||||
} else {
|
||||
port_name = argv[1];
|
||||
}
|
||||
|
||||
printf("Connecting to '%s'...\n", port_name);
|
||||
check(sp_get_port_by_name(port_name, &serial_port));
|
||||
check(sp_open(serial_port, SP_MODE_READ_WRITE));
|
||||
|
||||
check(sp_set_baudrate(serial_port, 9600));
|
||||
check(sp_set_bits(serial_port, 8));
|
||||
check(sp_set_parity(serial_port, SP_PARITY_NONE));
|
||||
check(sp_set_stopbits(serial_port, 1));
|
||||
check(sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE));
|
||||
puts("Connected.");
|
||||
|
||||
signal(SIGINT, handle_sigint);
|
||||
|
||||
FILE *output_file;
|
||||
output_file = fopen("./abc.txt", "w");
|
||||
|
||||
/* Reading lines from serial port. */
|
||||
bool reading = true;
|
||||
while (reading && !INTERRUPT) {
|
||||
int pos = 0;
|
||||
|
||||
/* Character-by-character reading. */
|
||||
while (pos < size) {
|
||||
result = check(sp_blocking_read(serial_port, buffer + pos, 1, timeout));
|
||||
|
||||
if (result == -1) {
|
||||
puts("Error reading from serial port");
|
||||
|
||||
reading = false;
|
||||
break;
|
||||
} else if (result == 0) {
|
||||
puts("No more data");
|
||||
break;
|
||||
} else {
|
||||
if (buffer[pos] == '\n') {
|
||||
buffer[pos] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
puts(buffer);
|
||||
fputs(buffer, output_file);
|
||||
}
|
||||
|
||||
fclose(output_file);
|
||||
free(buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result) {
|
||||
char *error_message;
|
||||
|
||||
switch (result) {
|
||||
case SP_ERR_ARG:
|
||||
puts("Error: Invalid argument.");
|
||||
abort();
|
||||
case SP_ERR_FAIL:
|
||||
error_message = sp_last_error_message();
|
||||
printf("Error: Failed: %s\n", error_message);
|
||||
sp_free_error_message(error_message);
|
||||
abort();
|
||||
case SP_ERR_SUPP:
|
||||
puts("Error: Not supported.");
|
||||
abort();
|
||||
case SP_ERR_MEM:
|
||||
puts("Error: Couldn't allocate memory.");
|
||||
abort();
|
||||
case SP_OK:
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_sigint(int sig) { INTERRUPT = true; }
|
3
snipplets/code/C/read csv/example.csv
Normal file
3
snipplets/code/C/read csv/example.csv
Normal file
@ -0,0 +1,3 @@
|
||||
id,text,desc
|
||||
1,ololo,none
|
||||
2,l33t,hack
|
|
31
snipplets/code/C/read csv/read_csv.c
Normal file
31
snipplets/code/C/read csv/read_csv.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <stdio.h> // file handling functions
|
||||
#include <stdlib.h> // atoi
|
||||
#include <string.h> // strtok
|
||||
|
||||
int main() {
|
||||
char buffer[80];
|
||||
FILE *stream = fopen("example.csv", "r");
|
||||
|
||||
while (fgets(buffer, 80, stream)) {
|
||||
char *token = strtok(buffer, ",");
|
||||
|
||||
// If you only need the first column of each row
|
||||
// Если нам нужен только первый столбец каждой строки
|
||||
if (token) {
|
||||
int n = atoi(token);
|
||||
printf("%s\n", n);
|
||||
}
|
||||
|
||||
// If you need all the values in a row
|
||||
// Если нам нужны все значения подряд
|
||||
while (token) {
|
||||
// Just printing each integer here but handle as needed
|
||||
// int n = atoi(token);
|
||||
printf("%s\n", token);
|
||||
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
6
snipplets/code/C/rest_server/.gitignore
vendored
Normal file
6
snipplets/code/C/rest_server/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
orcania/
|
||||
ulfius/
|
||||
|
||||
*.a
|
||||
|
||||
rest
|
7
snipplets/code/C/rest_server/Makefile
Normal file
7
snipplets/code/C/rest_server/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
CC = clang
|
||||
|
||||
all:
|
||||
$(CC) -std=c99 -Wall -O3 -o rest main.c -lulfius -lorcania
|
||||
|
||||
tcc:
|
||||
tcc -O3 -I./ulfius/include -I./orcania/include -o rest main.c libulfius.2.7.13.a liborcania.2.3.2.a -lyder -lgnutls -lz -ljansson -lmicrohttpd -lcurl
|
16
snipplets/code/C/rest_server/README.md
Normal file
16
snipplets/code/C/rest_server/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
REST API
|
||||
--------
|
||||
|
||||
* `http://localhost:8000/api/param/:name` - возвращает `:name`
|
||||
* `http://localhost:8000/api/param/quit` - завершит выполнение программы
|
||||
|
||||
Зависимости
|
||||
-----------
|
||||
|
||||
* [ulfius](https://github.com/babelouest/ulfius)
|
||||
* [orcania](https://github.com/babelouest/orcania)
|
||||
|
||||
```sh
|
||||
ar rcs libulfius.2.7.13.a ulfius.o u_map.o u_request.o u_response.o u_send_request.o u_websocket.o yuarel.o
|
||||
ar rcs liborcania.2.3.2.a orcania.o memory.o base64.o
|
||||
```
|
26
snipplets/code/C/rest_server/main.c
Normal file
26
snipplets/code/C/rest_server/main.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <ulfius.h>
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "server.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// создаём отдельный поток, в котором запускаем сервер
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, thread_server, (void *)&tid);
|
||||
|
||||
// while (true) {
|
||||
// }
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
BIN
snipplets/code/C/rest_server/qa/answer.png
Normal file
BIN
snipplets/code/C/rest_server/qa/answer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
61
snipplets/code/C/rest_server/qa/question.md
Normal file
61
snipplets/code/C/rest_server/qa/question.md
Normal file
@ -0,0 +1,61 @@
|
||||
Помогите с проблемой. Не завершается `while` цикл при изменении переменной `running`.
|
||||
|
||||
```
|
||||
while (running) {
|
||||
// loop
|
||||
}
|
||||
```
|
||||
|
||||
Использую библиотеку `ulfius` для реализации REST API сервера.
|
||||
Есть функция `thread_server()`, которую из `main()` запускаю в отдельном потоке,
|
||||
в которой запускается `ulfius` сервер.
|
||||
|
||||
```
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, thread_server, (void *)&tid);
|
||||
```
|
||||
|
||||
Сервер запускаю следующим образом:
|
||||
```
|
||||
int ret;
|
||||
ret = ulfius_start_framework(&instance);
|
||||
|
||||
if (ret == U_OK) {
|
||||
printf("Server started at %d.\n", PORT);
|
||||
} else {
|
||||
printf("Error starting server as %d port.\n", PORT);
|
||||
}
|
||||
|
||||
while (running) {
|
||||
printf("\r%b", running);
|
||||
}
|
||||
printf("Server halt.\n");
|
||||
|
||||
ulfius_stop_framework(&instance);
|
||||
ulfius_clean_instance(&instance);
|
||||
```
|
||||
|
||||
`running` - глобальная переменная типа `bool`.
|
||||
|
||||
В документации к библиотеке, чтобы сервер не схлопывался используется следующий код.
|
||||
```
|
||||
if (ret == U_OK) {
|
||||
getchar();
|
||||
}
|
||||
```
|
||||
|
||||
Есть callback функция, которая вызывается при обращении к API,
|
||||
в которой я проверяю отправленное пользователем значение, и если оно равняется `quit`
|
||||
присваиваю переменной `running` значение `false`, чтобы сервер закрылся.
|
||||
|
||||
Если из цикла `while (running) { printf("\r%b", running); }` убрать `printf()`,
|
||||
либо выполнять другие операции, например присвоение `a = 1;` то сервер не закрывается,
|
||||
хотя значение `running` равняется `0`.
|
||||
|
||||
Я пишу утилиту для внутенного использования, которая общается с Arduino платой
|
||||
посредством библиотеки `libserialport` и в цикле читает данные.
|
||||
|
||||
Хочу, чтобы утилита по REST получала данные и отправляла их на плату,
|
||||
но не получается реализовать нормальное завершение программы, потому что сервер не умирает.
|
||||
|
||||
**OS:** Linux
|
75
snipplets/code/C/rest_server/server.h
Normal file
75
snipplets/code/C/rest_server/server.h
Normal file
@ -0,0 +1,75 @@
|
||||
atomic_bool running = true;
|
||||
|
||||
#define PORT 8000
|
||||
#define PREFIX "/api"
|
||||
|
||||
int callback_default(const struct _u_request *request,
|
||||
struct _u_response *response, void *user_data);
|
||||
int callback_all_test_foo(const struct _u_request *request,
|
||||
struct _u_response *response, void *user_data);
|
||||
|
||||
void *thread_server(void *vargp) {
|
||||
int ret;
|
||||
struct _u_instance instance;
|
||||
|
||||
if (ulfius_init_instance(&instance, PORT, NULL, NULL) != U_OK) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
instance.max_post_body_size = 1024;
|
||||
|
||||
ulfius_add_endpoint_by_val(&instance, "GET", PREFIX, "/param/:name", 0,
|
||||
&callback_all_test_foo, "user data 1");
|
||||
ulfius_add_endpoint_by_val(&instance, "POST", PREFIX, "/param/:name", 0,
|
||||
&callback_all_test_foo, "user data 2");
|
||||
|
||||
ulfius_set_default_endpoint(&instance, &callback_default, NULL);
|
||||
|
||||
ret = ulfius_start_framework(&instance);
|
||||
|
||||
if (ret == U_OK) {
|
||||
printf("Server started at %d.\n", PORT);
|
||||
} else {
|
||||
printf("Error starting server as %d port.\n", PORT);
|
||||
}
|
||||
|
||||
while (running) {
|
||||
}
|
||||
printf("Server halt.\n");
|
||||
|
||||
ulfius_stop_framework(&instance);
|
||||
ulfius_clean_instance(&instance);
|
||||
}
|
||||
|
||||
int callback_default(const struct _u_request *request,
|
||||
struct _u_response *response, void *user_data) {
|
||||
(void)(request);
|
||||
(void)(user_data);
|
||||
ulfius_set_string_body_response(response, 404,
|
||||
"Page not found, do what you want");
|
||||
|
||||
return U_CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
int callback_all_test_foo(const struct _u_request *request,
|
||||
struct _u_response *response, void *user_data) {
|
||||
// url_params = request->map_url
|
||||
// post_params = request->map_post_body
|
||||
|
||||
const char **keys, *value;
|
||||
keys = u_map_enum_keys(request->map_url);
|
||||
value = u_map_get(request->map_url, keys[0]);
|
||||
|
||||
if (strcmp("quit", value) == 0) {
|
||||
running = false;
|
||||
}
|
||||
|
||||
char *response_body = msprintf("Your %s is %s\n", keys[0], value);
|
||||
|
||||
print_to_terminal(response_body);
|
||||
ulfius_set_string_body_response(response, 200, response_body);
|
||||
|
||||
o_free(response_body);
|
||||
|
||||
return U_CALLBACK_CONTINUE;
|
||||
}
|
1
snipplets/code/C/rest_server/utils.h
Normal file
1
snipplets/code/C/rest_server/utils.h
Normal file
@ -0,0 +1 @@
|
||||
void print_to_terminal(char *text) { printf("%s", text); }
|
12
snipplets/code/C/rgbToHex.c
Normal file
12
snipplets/code/C/rgbToHex.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
int red = 0;
|
||||
int green = 128;
|
||||
int blue = 64;
|
||||
|
||||
printf("#%.2x%.2x%.2x\n", red, green, blue); //#008040
|
||||
|
||||
return 0;
|
||||
}
|
52
snipplets/code/C/sqlite/sqlite3_create.c
Normal file
52
snipplets/code/C/sqlite/sqlite3_create.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
for(i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stdout, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create SQL statement */
|
||||
sql = "CREATE TABLE COMPANY(" \
|
||||
"ID INT PRIMARY KEY NOT NULL," \
|
||||
"NAME TEXT NOT NULL," \
|
||||
"AGE INT NOT NULL," \
|
||||
"ADDRESS CHAR(50)," \
|
||||
"SALARY REAL);";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Table created successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
51
snipplets/code/C/sqlite/sqlite3_delete.c
Normal file
51
snipplets/code/C/sqlite/sqlite3_delete.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *data, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
fprintf(stderr, "%s: ", (const char*)data);
|
||||
|
||||
for (i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
const char* data = "Callback function called";
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stderr, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create merged SQL statement */
|
||||
sql = "DELETE from COMPANY where ID=2; " \
|
||||
"SELECT * from COMPANY";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Operation done successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
55
snipplets/code/C/sqlite/sqlite3_insert.c
Normal file
55
snipplets/code/C/sqlite/sqlite3_insert.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
for (i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stderr, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create SQL statement */
|
||||
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
|
||||
"VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
|
||||
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
|
||||
"VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); " \
|
||||
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
|
||||
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
|
||||
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
|
||||
"VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00);";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Records created successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
50
snipplets/code/C/sqlite/sqlite3_select.c
Normal file
50
snipplets/code/C/sqlite/sqlite3_select.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *data, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
fprintf(stderr, "%s: ", (const char*)data);
|
||||
|
||||
for (i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
const char* data = "Callback function called";
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stderr, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create SQL statement */
|
||||
sql = "SELECT * from COMPANY";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Operation done successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
51
snipplets/code/C/sqlite/sqlite3_update.c
Normal file
51
snipplets/code/C/sqlite/sqlite3_update.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *data, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
fprintf(stderr, "%s: ", (const char*)data);
|
||||
|
||||
for(i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
const char* data = "Callback function called";
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stderr, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create merged SQL statement */
|
||||
sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
|
||||
"SELECT * from COMPANY";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Operation done successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
31
snipplets/code/C/thread.c
Normal file
31
snipplets/code/C/thread.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* https://www.geeksforgeeks.org/multithreading-in-c/ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
int g = 0;
|
||||
|
||||
void *my_thread(void *vargp) {
|
||||
int *id = (int *)vargp;
|
||||
|
||||
static int s = 0;
|
||||
|
||||
++s;
|
||||
++g;
|
||||
|
||||
printf("Thread ID: %d, Static: %d, Global: %d\n", *id, ++s, ++g);
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t tid;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 3; i++)
|
||||
pthread_create(&tid, NULL, my_thread, (void *)&tid);
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
BIN
snipplets/code/C/unixsocket/a.out
Executable file
BIN
snipplets/code/C/unixsocket/a.out
Executable file
Binary file not shown.
BIN
snipplets/code/C/unixsocket/client
Executable file
BIN
snipplets/code/C/unixsocket/client
Executable file
Binary file not shown.
79
snipplets/code/C/unixsocket/client.c
Normal file
79
snipplets/code/C/unixsocket/client.c
Normal file
@ -0,0 +1,79 @@
|
||||
// https://systemprogrammingatntu.github.io/mp2/unix_socket.html
|
||||
|
||||
#define SOCKET_NAME "/tmp/resol.sock"
|
||||
#define BUFFER_SIZE 12
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct sockaddr_un addr;
|
||||
int i;
|
||||
int ret;
|
||||
int data_socket;
|
||||
char buffer[BUFFER_SIZE];
|
||||
|
||||
/* Create local socket. */
|
||||
data_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (data_socket == -1) {
|
||||
perror("socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* For portability clear the whole structure, since some
|
||||
* implementations have additional (nonstandard) fields in
|
||||
* the structure.
|
||||
*/
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
|
||||
/* Connect socket to socket address */
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
|
||||
|
||||
ret = connect (data_socket, (const struct sockaddr *) &addr,
|
||||
sizeof(struct sockaddr_un));
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "The server is down.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Send arguments. */
|
||||
for (i = 1; i < argc; ++i) {
|
||||
ret = write(data_socket, argv[i], strlen(argv[i]) + 1);
|
||||
if (ret == -1) {
|
||||
perror("write");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Request result. */
|
||||
strcpy (buffer, "END");
|
||||
ret = write(data_socket, buffer, strlen(buffer) + 1);
|
||||
if (ret == -1) {
|
||||
perror("write");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Receive result. */
|
||||
ret = read(data_socket, buffer, BUFFER_SIZE);
|
||||
if (ret == -1) {
|
||||
perror("read");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Ensure buffer is 0-terminated. */
|
||||
buffer[BUFFER_SIZE - 1] = 0;
|
||||
|
||||
printf("Result = %s\n", buffer);
|
||||
|
||||
/* Close socket. */
|
||||
close(data_socket);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
BIN
snipplets/code/C/unixsocket/server
Executable file
BIN
snipplets/code/C/unixsocket/server
Executable file
Binary file not shown.
123
snipplets/code/C/unixsocket/server.c
Normal file
123
snipplets/code/C/unixsocket/server.c
Normal file
@ -0,0 +1,123 @@
|
||||
// https://systemprogrammingatntu.github.io/mp2/unix_socket.html
|
||||
|
||||
#define SOCKET_NAME "/tmp/resol.sock"
|
||||
#define BUFFER_SIZE 12
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct sockaddr_un addr;
|
||||
int down_flag = 0;
|
||||
int ret;
|
||||
int listen_socket;
|
||||
int data_socket;
|
||||
int result;
|
||||
char buffer[BUFFER_SIZE];
|
||||
|
||||
/*
|
||||
* In case the program exited inadvertently on the last run,
|
||||
* remove the socket.
|
||||
*/
|
||||
unlink(SOCKET_NAME);
|
||||
|
||||
/* Create local socket. */
|
||||
listen_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (listen_socket == -1) {
|
||||
perror("socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* For portability clear the whole structure, since some
|
||||
* implementations have additional (nonstandard) fields in
|
||||
* the structure.
|
||||
*/
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
|
||||
/* Bind socket to socket name. */
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
|
||||
|
||||
ret = bind(listen_socket, (const struct sockaddr *) &addr,
|
||||
sizeof(struct sockaddr_un));
|
||||
if (ret == -1) {
|
||||
perror("bind");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for accepting connections. The backlog size is set
|
||||
* to 20. So while one request is being processed other requests
|
||||
* can be waiting.
|
||||
*/
|
||||
ret = listen(listen_socket, 20);
|
||||
if (ret == -1) {
|
||||
perror("listen");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* This is the main loop for handling connections. */
|
||||
for (;;) {
|
||||
/* Wait for incoming connection. */
|
||||
data_socket = accept(listen_socket, NULL, NULL);
|
||||
if (data_socket == -1) {
|
||||
perror("accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
result = 0;
|
||||
for(;;) {
|
||||
/* Wait for next data packet. */
|
||||
ret = read(data_socket, buffer, BUFFER_SIZE);
|
||||
if (ret == -1) {
|
||||
perror("read");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Ensure buffer is 0-terminated. */
|
||||
buffer[BUFFER_SIZE - 1] = 0;
|
||||
|
||||
/* Handle commands. */
|
||||
if (!strncmp(buffer, "DOWN", BUFFER_SIZE)) {
|
||||
down_flag = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strncmp(buffer, "END", BUFFER_SIZE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add received summand. */
|
||||
result += atoi(buffer);
|
||||
}
|
||||
|
||||
/* Send result. */
|
||||
sprintf(buffer, "%d", result);
|
||||
ret = write(data_socket, buffer, BUFFER_SIZE);
|
||||
|
||||
if (ret == -1) {
|
||||
perror("write");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Close socket. */
|
||||
close(data_socket);
|
||||
|
||||
/* Quit on DOWN command. */
|
||||
if (down_flag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(listen_socket);
|
||||
|
||||
/* Unlink the socket. */
|
||||
unlink(SOCKET_NAME);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
Reference in New Issue
Block a user