From 31ce147c50e853f63b70048b0bbf71bb8889ca18 Mon Sep 17 00:00:00 2001 From: egor-tensin Date: Mon, 28 Aug 2023 07:43:34 +0000 Subject: =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20egor-tensin/cimp?= =?UTF-8?q?le@efb0a921609cf06080308a6a7c321d451489db8a=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ....base64.c.6cc41135837c80527c8f246c27adf87e.html | 603 +++ ...ndex.ci.c.aafc6aa1373a4054fe8dceca1e5a2cd2.html | 990 ++++ ....client.c.7eeddcdb2bd1344daca0a340abd305ae.html | 1036 +++++ ...nt_main.c.0ff1a98449e6ae22cf540fe28921fa2d.html | 909 ++++ ...md_line.c.fc55483624faae9ff92546137d095857.html | 680 +++ ...command.c.d26991ef13eb41283f88bf34125ef986.html | 2048 +++++++++ coverage/index.css | 505 +++ ...nt_loop.c.037d09258818a0617a2d29f47e2b5064.html | 2163 +++++++++ ...ex.file.c.0cc24881e570d19e625204519d50254f.html | 1491 ++++++ ...dex.git.c.ecafe65200a95f92fc10a3095d9e5f09.html | 1092 +++++ coverage/index.html | 461 ++ ...ex.json.c.9fe0913c76249e448eec3131d7e8b263.html | 2187 +++++++++ ...son_rpc.c.2aeccc6679171fb423f72eef95ec01c0.html | 4752 ++++++++++++++++++++ ...dex.log.c.47179e5db7ed3f2db741c99372ba24f3.html | 539 +++ ...dex.net.c.37012fce13860cefc5963f57e0f36732.html | 2705 +++++++++++ ...process.c.52f9324f34485af6c2c0f7cc7bbf5f8b.html | 1491 ++++++ ...rotocol.c.4964764a2e677a55c2f4207a995c3ce7.html | 1776 ++++++++ ...n_queue.c.fdfaa39d71447cf1e7d01ff206bd91e5.html | 1097 +++++ ....server.c.0235f01a49d01b35e981a41f59a9d2d6.html | 4186 +++++++++++++++++ ...er_main.c.3ca591a47eaf0cc37ef7579efe6031fe.html | 885 ++++ ....signal.c.71d63611c8a63e0778dd598afad76dfd.html | 826 ++++ ....sqlite.c.13cf77e7262c599539f10e3be0248b3e.html | 2719 +++++++++++ ...storage.c.96d197609feea4b630e7b775fb18af81.html | 1070 +++++ ..._sqlite.c.b44f7f73d467be85cd4227a40c11d12a.html | 4493 ++++++++++++++++++ ....string.c.2a75186e465ffeac1b306a350f4a56f8.html | 515 +++ ..._server.c.68fbb5aebb39dbc263f5110d228c9b35.html | 2532 +++++++++++ ....worker.c.4cbdfac39be7d0330fdfd94f65ce9ea9.html | 2492 ++++++++++ ...er_main.c.3e96ea0429977547c8b5eee564591fe0.html | 885 ++++ ...r_queue.c.aeb7258cd8f695c41a9aa8634701b38c.html | 755 ++++ 29 files changed, 47883 insertions(+) create mode 100644 coverage/index.base64.c.6cc41135837c80527c8f246c27adf87e.html create mode 100644 coverage/index.ci.c.aafc6aa1373a4054fe8dceca1e5a2cd2.html create mode 100644 coverage/index.client.c.7eeddcdb2bd1344daca0a340abd305ae.html create mode 100644 coverage/index.client_main.c.0ff1a98449e6ae22cf540fe28921fa2d.html create mode 100644 coverage/index.cmd_line.c.fc55483624faae9ff92546137d095857.html create mode 100644 coverage/index.command.c.d26991ef13eb41283f88bf34125ef986.html create mode 100644 coverage/index.css create mode 100644 coverage/index.event_loop.c.037d09258818a0617a2d29f47e2b5064.html create mode 100644 coverage/index.file.c.0cc24881e570d19e625204519d50254f.html create mode 100644 coverage/index.git.c.ecafe65200a95f92fc10a3095d9e5f09.html create mode 100644 coverage/index.html create mode 100644 coverage/index.json.c.9fe0913c76249e448eec3131d7e8b263.html create mode 100644 coverage/index.json_rpc.c.2aeccc6679171fb423f72eef95ec01c0.html create mode 100644 coverage/index.log.c.47179e5db7ed3f2db741c99372ba24f3.html create mode 100644 coverage/index.net.c.37012fce13860cefc5963f57e0f36732.html create mode 100644 coverage/index.process.c.52f9324f34485af6c2c0f7cc7bbf5f8b.html create mode 100644 coverage/index.protocol.c.4964764a2e677a55c2f4207a995c3ce7.html create mode 100644 coverage/index.run_queue.c.fdfaa39d71447cf1e7d01ff206bd91e5.html create mode 100644 coverage/index.server.c.0235f01a49d01b35e981a41f59a9d2d6.html create mode 100644 coverage/index.server_main.c.3ca591a47eaf0cc37ef7579efe6031fe.html create mode 100644 coverage/index.signal.c.71d63611c8a63e0778dd598afad76dfd.html create mode 100644 coverage/index.sqlite.c.13cf77e7262c599539f10e3be0248b3e.html create mode 100644 coverage/index.storage.c.96d197609feea4b630e7b775fb18af81.html create mode 100644 coverage/index.storage_sqlite.c.b44f7f73d467be85cd4227a40c11d12a.html create mode 100644 coverage/index.string.c.2a75186e465ffeac1b306a350f4a56f8.html create mode 100644 coverage/index.tcp_server.c.68fbb5aebb39dbc263f5110d228c9b35.html create mode 100644 coverage/index.worker.c.4cbdfac39be7d0330fdfd94f65ce9ea9.html create mode 100644 coverage/index.worker_main.c.3e96ea0429977547c8b5eee564591fe0.html create mode 100644 coverage/index.worker_queue.c.aeb7258cd8f695c41a9aa8634701b38c.html (limited to 'coverage') diff --git a/coverage/index.base64.c.6cc41135837c80527c8f246c27adf87e.html b/coverage/index.base64.c.6cc41135837c80527c8f246c27adf87e.html new file mode 100644 index 0000000..67f0b93 --- /dev/null +++ b/coverage/index.base64.c.6cc41135837c80527c8f246c27adf87e.html @@ -0,0 +1,603 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/base64.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:182766.7%
Branches:31225.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "base64.h"
9 + #include "log.h"
10 +
11 + #include <sodium.h>
12 +
13 + #include <stddef.h>
14 + #include <stdlib.h>
15 + #include <string.h>
16 +
17 + static const int base64_variant = sodium_base64_VARIANT_ORIGINAL;
18 +
19 + 9180int base64_encode(const unsigned char *src, size_t src_len, char **_dst)
20 + {
21 + 9180 const size_t dst_len = sodium_base64_encoded_len(src_len, base64_variant);
22 +
23 + 9180 char *dst = calloc(dst_len, 1);
24 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!dst) {
25 + log_errno("calloc");
26 + return -1;
27 + }
28 +
29 + 9180 sodium_bin2base64(dst, dst_len, src, src_len, base64_variant);
30 +
31 + 9180 *_dst = dst;
32 + 9180 return 0;
33 + }
34 +
35 + 9180int base64_decode(const char *src, unsigned char **_dst, size_t *_dst_len)
36 + {
37 + 9180 const size_t src_len = strlen(src);
38 + 9180 const size_t dst_max_len = src_len / 4 * 3;
39 + 9180 size_t dst_len = 0;
40 +
41 + 9180 unsigned char *dst = calloc(dst_max_len, 1);
42 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!dst) {
43 + log_errno("calloc");
44 + return -1;
45 + }
46 +
47 + int ret =
48 + 9180 sodium_base642bin(dst, dst_max_len, src, src_len, NULL, &dst_len, NULL, base64_variant);
49 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
50 + log_err("Couldn't parse base64-encoded string\n");
51 + goto free;
52 + }
53 +
54 + 9180 *_dst = dst;
55 + 9180 *_dst_len = dst_len;
56 + 9180 return ret;
57 +
58 + free:
59 + free(dst);
60 +
61 + return ret;
62 + }
63 +
+
+ +
+ + + + diff --git a/coverage/index.ci.c.aafc6aa1373a4054fe8dceca1e5a2cd2.html b/coverage/index.ci.c.aafc6aa1373a4054fe8dceca1e5a2cd2.html new file mode 100644 index 0000000..9f34424 --- /dev/null +++ b/coverage/index.ci.c.aafc6aa1373a4054fe8dceca1e5a2cd2.html @@ -0,0 +1,990 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/ci.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:374778.7%
Branches:91850.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "ci.h"
9 + #include "file.h"
10 + #include "git.h"
11 + #include "log.h"
12 + #include "process.h"
13 +
14 + #include <git2.h>
15 + #include <stddef.h>
16 + #include <stdlib.h>
17 +
18 + /* clang-format off */
19 + static const char *ci_scripts[] = {
20 + "./.ci.sh",
21 + "./.ci",
22 + "./ci.sh",
23 + "./ci",
24 + NULL,
25 + };
26 +
27 + static const char *ci_env[] = {
28 + "CI=y",
29 + "CIMPLE=y",
30 + NULL,
31 + };
32 + /* clang-format on */
33 +
34 + 9180static int ci_run_script(const char *script, struct proc_output *result)
35 + {
36 + 9180 const char *args[] = {script, NULL};
37 + 9180 return proc_capture(args, ci_env, result);
38 + }
39 +
40 + 9180int ci_run(struct proc_output *result)
41 + {
42 +
+ 1/2 +
+
✓ Branch 0 taken 36720 times.
+
✗ Branch 1 not taken.
+
+
+
36720 for (const char **script = ci_scripts; *script; ++script) {
43 +
+ 2/2 +
+
✓ Branch 1 taken 27540 times.
+
✓ Branch 2 taken 9180 times.
+
+
+
36720 if (!file_exists(*script))
44 + 27540 continue;
45 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Going to run: %s\n", *script);
46 + 9180 return ci_run_script(*script, result);
47 + }
48 +
49 + log("Couldn't find any CI scripts to run\n");
50 + return -1;
51 + }
52 +
53 + 9180static void ci_cleanup_git_repo(git_repository *repo)
54 + {
55 + 9180 rm_rf(git_repository_workdir(repo));
56 + 9180 libgit_repository_free(repo);
57 + 9180}
58 +
59 + 9180static int ci_prepare_git_repo(git_repository **repo, const char *url, const char *rev)
60 + {
61 + 9180 int ret = 0;
62 +
63 + 9180 ret = libgit_clone_to_tmp(repo, url);
64 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
65 + return ret;
66 +
67 + 9180 ret = libgit_checkout(*repo, rev);
68 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
69 + goto cleanup_repo;
70 +
71 + 9180 return ret;
72 +
73 + cleanup_repo:
74 + ci_cleanup_git_repo(*repo);
75 +
76 + return ret;
77 + }
78 +
79 + 9180int ci_run_git_repo(const char *url, const char *rev, struct proc_output *output)
80 + {
81 + 9180 char *oldpwd = NULL;
82 + 9180 git_repository *repo = NULL;
83 + 9180 int ret = 0;
84 +
85 + 9180 ret = ci_prepare_git_repo(&repo, url, rev);
86 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
87 + goto exit;
88 +
89 + 9180 ret = my_chdir(git_repository_workdir(repo), &oldpwd);
90 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
91 + goto free_repo;
92 +
93 + 9180 ret = ci_run(output);
94 +
+ 1/2 +
+
✓ Branch 0 taken 9180 times.
+
✗ Branch 1 not taken.
+
+
+
9180 if (ret < 0)
95 + goto oldpwd;
96 +
97 + 9180oldpwd:
98 + 9180 my_chdir(oldpwd, NULL);
99 + 9180 free(oldpwd);
100 +
101 + 9180free_repo:
102 + 9180 ci_cleanup_git_repo(repo);
103 +
104 + 9180exit:
105 + 9180 return ret;
106 + }
107 +
+
+ +
+ + + + diff --git a/coverage/index.client.c.7eeddcdb2bd1344daca0a340abd305ae.html b/coverage/index.client.c.7eeddcdb2bd1344daca0a340abd305ae.html new file mode 100644 index 0000000..2c136b4 --- /dev/null +++ b/coverage/index.client.c.7eeddcdb2bd1344daca0a340abd305ae.html @@ -0,0 +1,1036 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/client.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:435578.2%
Branches:132454.2%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "client.h"
9 + #include "cmd_line.h"
10 + #include "compiler.h"
11 + #include "const.h"
12 + #include "json_rpc.h"
13 + #include "log.h"
14 + #include "net.h"
15 + #include "protocol.h"
16 + #include "run_queue.h"
17 +
18 + #include <stdlib.h>
19 + #include <string.h>
20 +
21 + struct client {
22 + int dummy;
23 + };
24 +
25 + 9182int client_create(struct client **_client)
26 + {
27 + 9182 int ret = 0;
28 +
29 + 9182 struct client *client = malloc(sizeof(struct client));
30 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9182 times.
+
+
+
9182 if (!client) {
31 + log_errno("malloc");
32 + return -1;
33 + }
34 +
35 + 9182 *_client = client;
36 + 9182 return ret;
37 + }
38 +
39 + 9180void client_destroy(struct client *client)
40 + {
41 + 9180 free(client);
42 + 9180}
43 +
44 + 9182static int make_request(struct jsonrpc_request **request, int argc, const char **argv)
45 + {
46 +
+ 2/2 +
+
✓ Branch 0 taken 1 times.
+
✓ Branch 1 taken 9181 times.
+
+
+
9182 if (argc < 1) {
47 + 1 exit_with_usage_err("no action specified");
48 + return -1;
49 + }
50 +
51 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 1 times.
+
+
+
9181 if (!strcmp(argv[0], CMD_RUN)) {
52 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (argc != 3)
53 + return -1;
54 +
55 + 9180 struct run *run = NULL;
56 + 9180 int ret = run_create(&run, 0, argv[1], argv[2]);
57 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
58 + return ret;
59 +
60 + 9180 ret = run_request_create(request, run);
61 + 9180 run_destroy(run);
62 + 9180 return ret;
63 + }
64 +
65 + 1 return -1;
66 + }
67 +
68 + 9182int client_main(UNUSED const struct client *client, const struct settings *settings, int argc,
69 + const char **argv)
70 + {
71 + 9182 int ret = 0;
72 +
73 + 9182 struct jsonrpc_request *request = NULL;
74 + 9182 ret = make_request(&request, argc, argv);
75 +
+ 2/2 +
+
✓ Branch 0 taken 1 times.
+
✓ Branch 1 taken 9180 times.
+
+
+
9181 if (ret < 0) {
76 + 1 exit_with_usage_err("invalid request");
77 + return ret;
78 + }
79 +
80 + 9180 ret = net_connect(settings->host, settings->port);
81 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
82 + goto free_request;
83 + 9180 int fd = ret;
84 +
85 + 9180 ret = jsonrpc_request_send(request, fd);
86 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
87 + goto close;
88 +
89 + 9180 struct jsonrpc_response *response = NULL;
90 + 9180 ret = jsonrpc_response_recv(&response, fd);
91 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
92 + goto close;
93 +
94 +
+ 1/2 +
+
✓ Branch 1 taken 9180 times.
+
✗ Branch 2 not taken.
+
+
+
9180 if (jsonrpc_response_is_error(response)) {
95 + log_err("server failed to process the request\n");
96 + ret = -1;
97 + goto free_response;
98 + }
99 +
100 + 9180free_response:
101 + 9180 jsonrpc_response_destroy(response);
102 +
103 + 9180close:
104 + 9180 net_close(fd);
105 +
106 + 9180free_request:
107 + 9180 jsonrpc_request_destroy(request);
108 +
109 + 9180 return ret;
110 + }
111 +
+
+ +
+ + + + diff --git a/coverage/index.client_main.c.0ff1a98449e6ae22cf540fe28921fa2d.html b/coverage/index.client_main.c.0ff1a98449e6ae22cf540fe28921fa2d.html new file mode 100644 index 0000000..bfb102e --- /dev/null +++ b/coverage/index.client_main.c.0ff1a98449e6ae22cf540fe28921fa2d.html @@ -0,0 +1,909 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/client_main.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:344379.1%
Branches:101471.4%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "client.h"
9 + #include "cmd_line.h"
10 + #include "const.h"
11 + #include "log.h"
12 +
13 + #include <getopt.h>
14 + #include <unistd.h>
15 +
16 + 9188static struct settings default_settings(void)
17 + {
18 + 9188 struct settings settings = {
19 + .host = default_host,
20 + .port = default_port,
21 + };
22 + 9188 return settings;
23 + }
24 +
25 + 6const char *get_usage_string(void)
26 + {
27 + 6 return "[-h|--help] [-V|--version] [-v|--verbose] [-H|--host HOST] [-p|--port PORT] ACTION [ARG...]\n\
28 + \n\
29 + available actions:\n\
30 + \t" CMD_RUN " URL REV - schedule a CI run of repository at URL, revision REV";
31 + }
32 +
33 + 9188static int parse_settings(struct settings *settings, int argc, char *argv[])
34 + {
35 + int opt, longind;
36 +
37 + 9188 *settings = default_settings();
38 +
39 + /* clang-format off */
40 + static struct option long_options[] = {
41 + {"help", no_argument, 0, 'h'},
42 + {"version", no_argument, 0, 'V'},
43 + {"verbose", no_argument, 0, 'v'},
44 + {"host", required_argument, 0, 'H'},
45 + {"port", required_argument, 0, 'p'},
46 + {0, 0, 0, 0},
47 + };
48 + /* clang-format on */
49 +
50 +
+ 2/2 +
+
✓ Branch 1 taken 18370 times.
+
✓ Branch 2 taken 9182 times.
+
+
+
27552 while ((opt = getopt_long(argc, argv, "hVvH:p:", long_options, &longind)) != -1) {
51 +
+ 5/6 +
+
✓ Branch 0 taken 2 times.
+
✓ Branch 1 taken 2 times.
+
✗ Branch 2 not taken.
+
✓ Branch 3 taken 9182 times.
+
✓ Branch 4 taken 9182 times.
+
✓ Branch 5 taken 2 times.
+
+
+
18370 switch (opt) {
52 + 2 case 'h':
53 + 2 exit_with_usage(0);
54 + break;
55 + 2 case 'V':
56 + 2 exit_with_version();
57 + break;
58 + case 'v':
59 + g_log_lvl = LOG_LVL_DEBUG;
60 + break;
61 + 9182 case 'H':
62 + 9182 settings->host = optarg;
63 + 9182 break;
64 + 9182 case 'p':
65 + 9182 settings->port = optarg;
66 + 9182 break;
67 + 2 default:
68 + 2 exit_with_usage(1);
69 + break;
70 + }
71 + }
72 +
73 + 9182 return 0;
74 + }
75 +
76 + 9188int main(int argc, char *argv[])
77 + {
78 + struct settings settings;
79 + 9188 struct client *client = NULL;
80 + 9188 int ret = 0;
81 +
82 + 9188 ret = parse_settings(&settings, argc, argv);
83 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9182 times.
+
+
+
9182 if (ret < 0)
84 + return ret;
85 +
86 + 9182 ret = client_create(&client);
87 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9182 times.
+
+
+
9182 if (ret < 0)
88 + return ret;
89 +
90 + 9182 ret = client_main(client, &settings, argc - optind, (const char **)argv + optind);
91 +
+ 1/2 +
+
✓ Branch 0 taken 9180 times.
+
✗ Branch 1 not taken.
+
+
+
9180 if (ret < 0)
92 + goto destroy_client;
93 +
94 + 9180destroy_client:
95 + 9180 client_destroy(client);
96 +
97 + 9180 return ret;
98 + }
99 +
+
+ +
+ + + + diff --git a/coverage/index.cmd_line.c.fc55483624faae9ff92546137d095857.html b/coverage/index.cmd_line.c.fc55483624faae9ff92546137d095857.html new file mode 100644 index 0000000..cac3a81 --- /dev/null +++ b/coverage/index.cmd_line.c.fc55483624faae9ff92546137d095857.html @@ -0,0 +1,680 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/cmd_line.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:283190.3%
Branches:71450.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "cmd_line.h"
9 + #include "const.h"
10 + #include "file.h"
11 + #include "log.h"
12 +
13 + #include <stdio.h>
14 + #include <stdlib.h>
15 + #include <string.h>
16 +
17 + 20static char *get_current_binary_path(void)
18 + {
19 + 20 return my_readlink("/proc/self/exe");
20 + }
21 +
22 + 20static char *get_current_binary_name(void)
23 + {
24 + 20 char *path = get_current_binary_path();
25 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 20 times.
+
+
+
20 if (!path)
26 + return NULL;
27 +
28 + 20 char *name = basename(path);
29 +
30 + 20 char *result = strdup(name);
31 +
+ 1/2 +
+
✓ Branch 0 taken 20 times.
+
✗ Branch 1 not taken.
+
+
+
20 if (!result) {
32 + log_errno("strdup");
33 + goto free_path;
34 + }
35 +
36 + 20free_path:
37 + 20 free(path);
38 +
39 + 20 return result;
40 + }
41 +
42 + 14void exit_with_usage(int ec)
43 + {
44 + 14 FILE *dest = stdout;
45 +
+ 2/2 +
+
✓ Branch 0 taken 8 times.
+
✓ Branch 1 taken 6 times.
+
+
+
14 if (ec)
46 + 8 dest = stderr;
47 +
48 + 14 char *binary = get_current_binary_name();
49 +
50 +
+ 1/2 +
+
✓ Branch 1 taken 14 times.
+
✗ Branch 2 not taken.
+
+
+
14 fprintf(dest, "usage: %s %s\n", binary ? binary : "prog", get_usage_string());
51 + 14 free(binary);
52 + 14 exit(ec);
53 + }
54 +
55 + 2void exit_with_usage_err(const char *msg)
56 + {
57 +
+ 1/2 +
+
✓ Branch 0 taken 2 times.
+
✗ Branch 1 not taken.
+
+
+
2 if (msg)
58 + 2 fprintf(stderr, "usage error: %s\n", msg);
59 + 2 exit_with_usage(1);
60 + }
61 +
62 + 6void exit_with_version(void)
63 + {
64 + 6 char *binary = get_current_binary_name();
65 +
66 +
+ 1/2 +
+
✓ Branch 0 taken 6 times.
+
✗ Branch 1 not taken.
+
+
+
6 printf("%s v%s (%s)\n", binary ? binary : "prog", project_version, project_rev);
67 + 6 free(binary);
68 + 6 exit(0);
69 + }
70 +
+
+ +
+ + + + diff --git a/coverage/index.command.c.d26991ef13eb41283f88bf34125ef986.html b/coverage/index.command.c.d26991ef13eb41283f88bf34125ef986.html new file mode 100644 index 0000000..acda1bd --- /dev/null +++ b/coverage/index.command.c.d26991ef13eb41283f88bf34125ef986.html @@ -0,0 +1,2048 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/command.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:8912074.2%
Branches:336650.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "command.h"
9 + #include "compiler.h"
10 + #include "event_loop.h"
11 + #include "json_rpc.h"
12 + #include "log.h"
13 +
14 + #include <poll.h>
15 + #include <stdlib.h>
16 + #include <string.h>
17 +
18 + struct cmd_dispatcher {
19 + struct cmd_desc *cmds;
20 + size_t numof_cmds;
21 + void *ctx;
22 + };
23 +
24 + 141static int copy_cmd(struct cmd_desc *dest, const struct cmd_desc *src)
25 + {
26 + 141 dest->name = strdup(src->name);
27 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 141 times.
+
+
+
141 if (!dest->name) {
28 + log_errno("strdup");
29 + return -1;
30 + }
31 + 141 dest->handler = src->handler;
32 + 141 return 0;
33 + }
34 +
35 + 141static void free_cmd(struct cmd_desc *desc)
36 + {
37 + 141 free(desc->name);
38 + 141}
39 +
40 + 83static int copy_cmds(struct cmd_desc *dest, const struct cmd_desc *src, size_t numof_cmds)
41 + {
42 + 83 size_t numof_copied = 0;
43 + 83 int ret = 0;
44 +
45 +
+ 2/2 +
+
✓ Branch 0 taken 141 times.
+
✓ Branch 1 taken 83 times.
+
+
+
224 for (numof_copied = 0; numof_copied < numof_cmds; ++numof_copied) {
46 + 141 ret = copy_cmd(&dest[numof_copied], &src[numof_copied]);
47 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 141 times.
+
+
+
141 if (ret < 0)
48 + goto free;
49 + }
50 +
51 + 83 return 0;
52 +
53 + free:
54 + for (size_t i = 0; i < numof_copied; ++i)
55 + free_cmd(&dest[numof_copied]);
56 +
57 + return -1;
58 + }
59 +
60 + 83static void free_cmds(struct cmd_desc *cmds, size_t numof_cmds)
61 + {
62 +
+ 2/2 +
+
✓ Branch 0 taken 141 times.
+
✓ Branch 1 taken 83 times.
+
+
+
224 for (size_t i = 0; i < numof_cmds; ++i)
63 + 141 free_cmd(&cmds[i]);
64 + 83}
65 +
66 + 83int cmd_dispatcher_create(struct cmd_dispatcher **_dispatcher, struct cmd_desc *cmds,
67 + size_t numof_cmds, void *ctx)
68 + {
69 + 83 int ret = 0;
70 +
71 + 83 struct cmd_dispatcher *dispatcher = malloc(sizeof(struct cmd_dispatcher));
72 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 83 times.
+
+
+
83 if (!dispatcher) {
73 + log_errno("malloc");
74 + return -1;
75 + }
76 +
77 + 83 dispatcher->ctx = ctx;
78 +
79 + 83 dispatcher->cmds = malloc(sizeof(struct cmd_desc) * numof_cmds);
80 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 83 times.
+
+
+
83 if (!dispatcher->cmds) {
81 + log_errno("malloc");
82 + goto free;
83 + }
84 + 83 dispatcher->numof_cmds = numof_cmds;
85 +
86 + 83 ret = copy_cmds(dispatcher->cmds, cmds, numof_cmds);
87 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 83 times.
+
+
+
83 if (ret < 0)
88 + goto free_cmds;
89 +
90 + 83 *_dispatcher = dispatcher;
91 + 83 return 0;
92 +
93 + free_cmds:
94 + free(dispatcher->cmds);
95 +
96 + free:
97 + free(dispatcher);
98 +
99 + return -1;
100 + }
101 +
102 + 83void cmd_dispatcher_destroy(struct cmd_dispatcher *dispatcher)
103 + {
104 + 83 free_cmds(dispatcher->cmds, dispatcher->numof_cmds);
105 + 83 free(dispatcher->cmds);
106 + 83 free(dispatcher);
107 + 83}
108 +
109 + 36774static int cmd_dispatcher_handle_internal(const struct cmd_dispatcher *dispatcher,
110 + const struct jsonrpc_request *request,
111 + struct jsonrpc_response **result, void *arg)
112 + {
113 + 36774 const char *actual_cmd = jsonrpc_request_get_method(request);
114 +
115 +
+ 1/2 +
+
✓ Branch 0 taken 64314 times.
+
✗ Branch 1 not taken.
+
+
+
64314 for (size_t i = 0; i < dispatcher->numof_cmds; ++i) {
116 + 64314 struct cmd_desc *cmd = &dispatcher->cmds[i];
117 +
118 +
+ 2/2 +
+
✓ Branch 0 taken 27540 times.
+
✓ Branch 1 taken 36774 times.
+
+
+
64314 if (strcmp(cmd->name, actual_cmd))
119 + 27540 continue;
120 +
121 + 36774 return cmd->handler(request, result, arg);
122 + }
123 +
124 + log_err("Received an unknown command: %s\n", actual_cmd);
125 + return -1;
126 + }
127 +
128 + int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher,
129 + const struct jsonrpc_request *command, struct jsonrpc_response **result)
130 + {
131 + return cmd_dispatcher_handle_internal(dispatcher, command, result, dispatcher->ctx);
132 + }
133 +
134 + 36774static struct cmd_conn_ctx *make_conn_ctx(int fd, void *arg)
135 + {
136 + 36774 struct cmd_conn_ctx *ctx = malloc(sizeof(struct cmd_conn_ctx));
137 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (!ctx) {
138 + log_errno("malloc");
139 + return NULL;
140 + }
141 +
142 + 36774 ctx->fd = fd;
143 + 36774 ctx->arg = arg;
144 +
145 + 36774 return ctx;
146 + }
147 +
148 + 36774static int cmd_dispatcher_handle_conn_internal(int conn_fd, struct cmd_dispatcher *dispatcher)
149 + {
150 + 36774 int ret = 0;
151 +
152 + 36774 struct cmd_conn_ctx *new_ctx = make_conn_ctx(conn_fd, dispatcher->ctx);
153 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (!new_ctx)
154 + return -1;
155 +
156 + 36774 struct jsonrpc_request *request = NULL;
157 + 36774 ret = jsonrpc_request_recv(&request, conn_fd);
158 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0)
159 + goto free_ctx;
160 +
161 + 36774 const int requires_response = !jsonrpc_request_is_notification(request);
162 +
163 + 36774 struct jsonrpc_response *default_response = NULL;
164 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 27594 times.
+
+
+
36774 if (requires_response) {
165 + 9180 ret = jsonrpc_response_create(&default_response, request, NULL);
166 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
167 + goto free_request;
168 + }
169 +
170 + 36774 struct jsonrpc_response *default_error = NULL;
171 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 27594 times.
+
+
+
36774 if (requires_response) {
172 + 9180 ret = jsonrpc_error_create(&default_error, request, -1, "An error occured");
173 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
174 + goto free_default_response;
175 + }
176 +
177 + 36774 struct jsonrpc_response *response = NULL;
178 + 36774 ret = cmd_dispatcher_handle_internal(dispatcher, request, &response, new_ctx);
179 +
180 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 27594 times.
+
+
+
36774 if (requires_response) {
181 + 9180 struct jsonrpc_response *actual_response = response;
182 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!actual_response) {
183 + actual_response = ret < 0 ? default_error : default_response;
184 + }
185 +
+ 1/4 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
✗ Branch 3 not taken.
+
✗ Branch 4 not taken.
+
+
+
9180 if (ret < 0 && !jsonrpc_response_is_error(actual_response)) {
186 + actual_response = default_error;
187 + }
188 +
+ 1/2 +
+
✓ Branch 1 taken 9180 times.
+
✗ Branch 2 not taken.
+
+
+
9180 ret = jsonrpc_response_send(actual_response, conn_fd) < 0 ? -1 : ret;
189 + }
190 +
191 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 27594 times.
+
+
+
36774 if (response)
192 + 9180 jsonrpc_response_destroy(response);
193 +
194 +
+ 2/2 +
+
✓ Branch 0 taken 27594 times.
+
✓ Branch 1 taken 9180 times.
+
+
+
36774 if (default_error)
195 + 9180 jsonrpc_response_destroy(default_error);
196 +
197 + 27594free_default_response:
198 +
+ 2/2 +
+
✓ Branch 0 taken 27594 times.
+
✓ Branch 1 taken 9180 times.
+
+
+
36774 if (default_response)
199 + 9180 jsonrpc_response_destroy(default_response);
200 +
201 + 27594free_request:
202 + 36774 jsonrpc_request_destroy(request);
203 +
204 + 36774free_ctx:
205 + 36774 free(new_ctx);
206 +
207 + 36774 return ret;
208 + }
209 +
210 + 27594int cmd_dispatcher_handle_conn(int conn_fd, void *_dispatcher)
211 + {
212 + 27594 return cmd_dispatcher_handle_conn_internal(conn_fd, (struct cmd_dispatcher *)_dispatcher);
213 + }
214 +
215 + 9180int cmd_dispatcher_handle_event(UNUSED struct event_loop *loop, int fd, short revents,
216 + void *_dispatcher)
217 + {
218 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!(revents & POLLIN)) {
219 + log_err("Descriptor %d is not readable\n", fd);
220 + return -1;
221 + }
222 +
223 + 9180 return cmd_dispatcher_handle_conn_internal(fd, (struct cmd_dispatcher *)_dispatcher);
224 + }
225 +
+
+ +
+ + + + diff --git a/coverage/index.css b/coverage/index.css new file mode 100644 index 0000000..b51dc2e --- /dev/null +++ b/coverage/index.css @@ -0,0 +1,505 @@ +:root { + font-family: sans-serif; + --unknown_color: LightGray; + --low_color: #FF6666; + --medium_color: #F9FD63; + --high_color: #85E485; + --covered_color: #85E485; + --uncovered_color: #FF8C8C; + --takenBranch_color: Green; + --notTakenBranch_color: Red; +} + +body +{ + color: #000000; + background-color: #FFFFFF; +} + +h1 +{ + text-align: center; + margin: 0; + padding-bottom: 10px; + font-size: 20pt; + font-weight: bold; +} + +hr +{ + background-color: navy; + height: 2px; + border: 0; +} + +/* Link formats: use maroon w/underlines */ +a:link +{ + color: navy; + text-decoration: underline; +} +a:visited +{ + color: maroon; + text-decoration: underline; +} + +/*** Summary formats ***/ + +.summary +{ + display: flex; + flex-flow: row wrap; + max-width: 100%; + justify-content: flex-start; +} + +.summary > table +{ + flex: 1 0 7em; + border: 0; +} + +.summary > :last-child { + margin-left: auto; +} + +table.legend +{ + color: black; + display: flex; + flex-flow: row wrap; + justify-content: flex-start; +} + +table.legend th[scope=row] +{ + font-weight: normal; + text-align: right; + white-space: nowrap; +} + +table.legend td +{ + color: blue; + text-align: left; + white-space: nowrap; + padding-left: 5px; +} + +table.legend td.legend +{ + color: black; + font-size: 80%; +} + +table.coverage td, +table.coverage th +{ + text-align: right; + color: black; + font-weight: normal; + white-space: nowrap; + padding-left: 5px; + padding-right: 4px; +} + +table.coverage td +{ + background-color: LightSteelBlue; +} + +table.coverage th[scope=row] +{ + color: black; + font-weight: normal; + white-space: nowrap; +} + +table.coverage th[scope=col] +{ + color: blue; + font-weight: normal; + white-space: nowrap; +} + +table.legend span +{ + margin-right: 4px; + padding: 2px; +} + +table.legend span.coverage-unknown, +table.legend span.coverage-none, +table.legend span.coverage-low, +table.legend span.coverage-medium, +table.legend span.coverage-high +{ + padding-left: 3px; + padding-right: 3px; +} + +table.legend span.coverage-unknown, +table.coverage td.coverage-unknown +{ + background-color: var(--unknown_color) !important; +} + +table.legend span.coverage-none, +table.legend span.coverage-low, +table.coverage td.coverage-none, +table.coverage td.coverage-low +{ + background-color: var(--low_color) !important; +} + +table.legend span.coverage-medium, +table.coverage td.coverage-medium +{ + background-color: var(--medium_color) !important; +} + +table.legend span.coverage-high, +table.coverage td.coverage-high +{ + background-color: var(--high_color) !important; +} + + +/*** End of Summary formats ***/ +/*** Meter formats ***/ + +/* Common */ +meter { + -moz-appearance: none; + + width: 30vw; + min-width: 4em; + max-width: 15em; + height: 0.75em; + padding: 0; + vertical-align: baseline; + margin-top: 3px; + /* Outer background for Mozilla */ + background: none; + background-color: whitesmoke; +} + +/* Webkit */ + +meter::-webkit-meter-bar { + /* Outer background for Webkit */ + background: none; + background-color: whitesmoke; + height: 0.75em; + border-radius: 0px; +} + +meter::-webkit-meter-optimum-value, +meter::-webkit-meter-suboptimum-value, +meter::-webkit-meter-even-less-good-value +{ + /* Inner shadow for Webkit */ + border: solid 1px black; +} + +meter.coverage-none::-webkit-meter-optimum-value, +meter.coverage-low::-webkit-meter-optimum-value +{ + background: var(--low_color); +} + +meter.coverage-medium::-webkit-meter-optimum-value +{ + background: var(--medium_color); +} + +meter.coverage-high::-webkit-meter-optimum-value +{ + background: var(--high_color); +} + +/* Mozilla */ + +meter::-moz-meter-bar +{ + box-sizing: border-box; +} + +meter:-moz-meter-optimum::-moz-meter-bar, +meter:-moz-meter-sub-optimum::-moz-meter-bar, +meter:-moz-meter-sub-sub-optimum::-moz-meter-bar +{ + /* Inner shadow for Mozilla */ + border: solid 1px black; +} + +meter.coverage-none:-moz-meter-optimum::-moz-meter-bar, +meter.coverage-low:-moz-meter-optimum::-moz-meter-bar +{ + background: var(--low_color); +} + +meter.coverage-medium:-moz-meter-optimum::-moz-meter-bar +{ + background: var(--medium_color); +} + +meter.coverage-high:-moz-meter-optimum::-moz-meter-bar +{ + background: var(--high_color); +} + +/*** End of Meter formats ***/ +.file-list td, .file-list th { + padding: 0 10px; + font-weight: bold; +} + +.file-list th[scope^=col] +{ + text-align: center; + color: white; + background-color: SteelBlue; + font-size: 120%; +} + +.file-list th[scope=row] +{ + text-align: left; + color: black; + font-family: monospace; + font-weight: bold; + font-size: 110%; +} + +.file-list tr > td, +.file-list tr > th { + background: aliceblue; +} + +.file-list tr:nth-child(even) > td, +.file-list tr:nth-child(even) > th { + background: LightSteelBlue +} + +.file-list tr:hover > td, +.file-list tr:hover > th[scope=row] +{ + background-color: #ddd; +} +td.CoverValue +{ + text-align: right; + white-space: nowrap; +} + +td.coveredLine, +span.coveredLine +{ + background-color: var(--covered_color) !important; +} + +td.uncoveredLine, +span.uncoveredLine +{ + background-color: var(--uncovered_color) !important; +} + +.linebranch, .linecount +{ + font-family: monospace; + border-right: 1px gray solid; + background-color: lightgray; + text-align: right; +} + +.linebranchDetails +{ + position: relative; +} +.linebranchSummary +{ + cursor: help; +} +.linebranchContents +{ + font-family: sans-serif; + font-size: small; + text-align: left; + position: absolute; + width: 15em; + padding: 1em; + background: white; + border: solid gray 1px; + box-shadow: 5px 5px 10px gray; + z-index: 1; /* show in front of the table entries */ +} + +.takenBranch +{ + color: var(--takenBranch_color) !important; +} + +.notTakenBranch +{ + color: var(--notTakenBranch_color) !important; +} + +.src +{ + padding-left: 12px; + text-align: left; + + font-family: monospace; + white-space: pre; + + tab-size: var(--tab_size); + -moz-tab-size: var(--tab_size); +} + +span.takenBranch, +span.notTakenBranch +{ + font-family: monospace; + font-weight: bold; +} + +pre +{ + height : 15px; + margin-top: 0; + margin-bottom: 0; +} + +.source-line +{ + height : 15px; + margin-top: 0; + margin-bottom: 0; +} + +.lineno +{ + background-color: #EFE383; + border-right: 1px solid #BBB15F; + text-align: right; + unicode-bidi: embed; + font-family: monospace; + white-space: pre; +} + +.lineno > a +{ + text-decoration: none; + color: inherit; +} + +.file-list +{ + margin: 1em auto; + border: 0; + border-spacing: 1px; +} + +.file-source table +{ + border-spacing: 0; +} + +.file-source table td, +.file-source table th +{ + padding: 1px 10px; +} + +.file-source table th +{ + font-family: monospace; + font-weight: bold; +} + +.file-source table td:last-child +{ + width: 100%; +} +footer +{ + text-align: center; + padding-top: 3px; +} + +/* pygments syntax highlighting */ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.hll { background-color: #ffffcc } +.c { color: #3D7B7B; font-style: italic } /* Comment */ +.err { border: 1px solid #FF0000 } /* Error */ +.k { color: #008000; font-weight: bold } /* Keyword */ +.o { color: #666666 } /* Operator */ +.ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.cp { color: #9C6500 } /* Comment.Preproc */ +.cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.gd { color: #A00000 } /* Generic.Deleted */ +.ge { font-style: italic } /* Generic.Emph */ +.gr { color: #E40000 } /* Generic.Error */ +.gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.gi { color: #008400 } /* Generic.Inserted */ +.go { color: #717171 } /* Generic.Output */ +.gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.gt { color: #0044DD } /* Generic.Traceback */ +.kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #008000 } /* Keyword.Pseudo */ +.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #B00040 } /* Keyword.Type */ +.m { color: #666666 } /* Literal.Number */ +.s { color: #BA2121 } /* Literal.String */ +.na { color: #687822 } /* Name.Attribute */ +.nb { color: #008000 } /* Name.Builtin */ +.nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.no { color: #880000 } /* Name.Constant */ +.nd { color: #AA22FF } /* Name.Decorator */ +.ni { color: #717171; font-weight: bold } /* Name.Entity */ +.ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.nf { color: #0000FF } /* Name.Function */ +.nl { color: #767600 } /* Name.Label */ +.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.nt { color: #008000; font-weight: bold } /* Name.Tag */ +.nv { color: #19177C } /* Name.Variable */ +.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.w { color: #bbbbbb } /* Text.Whitespace */ +.mb { color: #666666 } /* Literal.Number.Bin */ +.mf { color: #666666 } /* Literal.Number.Float */ +.mh { color: #666666 } /* Literal.Number.Hex */ +.mi { color: #666666 } /* Literal.Number.Integer */ +.mo { color: #666666 } /* Literal.Number.Oct */ +.sa { color: #BA2121 } /* Literal.String.Affix */ +.sb { color: #BA2121 } /* Literal.String.Backtick */ +.sc { color: #BA2121 } /* Literal.String.Char */ +.dl { color: #BA2121 } /* Literal.String.Delimiter */ +.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.s2 { color: #BA2121 } /* Literal.String.Double */ +.se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.sh { color: #BA2121 } /* Literal.String.Heredoc */ +.si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.sx { color: #008000 } /* Literal.String.Other */ +.sr { color: #A45A77 } /* Literal.String.Regex */ +.s1 { color: #BA2121 } /* Literal.String.Single */ +.ss { color: #19177C } /* Literal.String.Symbol */ +.bp { color: #008000 } /* Name.Builtin.Pseudo */ +.fm { color: #0000FF } /* Name.Function.Magic */ +.vc { color: #19177C } /* Name.Variable.Class */ +.vg { color: #19177C } /* Name.Variable.Global */ +.vi { color: #19177C } /* Name.Variable.Instance */ +.vm { color: #19177C } /* Name.Variable.Magic */ +.il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/coverage/index.event_loop.c.037d09258818a0617a2d29f47e2b5064.html b/coverage/index.event_loop.c.037d09258818a0617a2d29f47e2b5064.html new file mode 100644 index 0000000..aa6e531 --- /dev/null +++ b/coverage/index.event_loop.c.037d09258818a0617a2d29f47e2b5064.html @@ -0,0 +1,2163 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/event_loop.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:11113184.7%
Branches:397651.3%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "event_loop.h"
9 + #include "log.h"
10 + #include "string.h"
11 +
12 + #include <poll.h>
13 + #include <stddef.h>
14 + #include <stdlib.h>
15 + #include <sys/queue.h>
16 +
17 + SIMPLEQ_HEAD(event_fd_queue, event_fd);
18 +
19 + struct event_fd {
20 + int fd;
21 + short events;
22 + event_handler handler;
23 + void *arg;
24 + int once;
25 +
26 + SIMPLEQ_ENTRY(event_fd) entries;
27 + };
28 +
29 + 36940static struct event_fd *event_fd_create(int fd, short events, event_handler handler, void *arg)
30 + {
31 + 36940 struct event_fd *res = calloc(1, sizeof(struct event_fd));
32 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36940 times.
+
+
+
36940 if (!res) {
33 + log_errno("calloc");
34 + return NULL;
35 + }
36 +
37 + 36940 res->fd = fd;
38 + 36940 res->events = events;
39 + 36940 res->handler = handler;
40 + 36940 res->arg = arg;
41 + 36940 res->once = 0;
42 +
43 + 36940 return res;
44 + }
45 +
46 + 36940static void event_fd_destroy(struct event_fd *entry)
47 + {
48 + 36940 free(entry);
49 + 36940}
50 +
51 + 83static void event_fd_queue_create(struct event_fd_queue *queue)
52 + {
53 + 83 SIMPLEQ_INIT(queue);
54 + 83}
55 +
56 + 83static void event_fd_queue_destroy(struct event_fd_queue *queue)
57 + {
58 + 83 struct event_fd *entry1 = SIMPLEQ_FIRST(queue);
59 +
+ 2/2 +
+
✓ Branch 0 taken 166 times.
+
✓ Branch 1 taken 83 times.
+
+
+
249 while (entry1) {
60 + 166 struct event_fd *entry2 = SIMPLEQ_NEXT(entry1, entries);
61 + 166 event_fd_destroy(entry1);
62 + 166 entry1 = entry2;
63 + }
64 + 83 SIMPLEQ_INIT(queue);
65 + 83}
66 +
67 + struct event_loop {
68 + nfds_t nfds;
69 + struct event_fd_queue entries;
70 + };
71 +
72 + 83int event_loop_create(struct event_loop **_loop)
73 + {
74 + 83 int ret = 0;
75 +
76 + 83 struct event_loop *loop = calloc(1, sizeof(struct event_loop));
77 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 83 times.
+
+
+
83 if (!loop) {
78 + log_errno("calloc");
79 + return -1;
80 + }
81 + 83 *_loop = loop;
82 +
83 + 83 event_fd_queue_create(&loop->entries);
84 +
85 + 83 return ret;
86 + }
87 +
88 + 83void event_loop_destroy(struct event_loop *loop)
89 + {
90 + 83 event_fd_queue_destroy(&loop->entries);
91 + 83 free(loop);
92 + 83}
93 +
94 + 36940static void event_loop_add_internal(struct event_loop *loop, struct event_fd *entry)
95 + {
96 +
+ 1/2 +
+
✓ Branch 1 taken 36940 times.
+
✗ Branch 2 not taken.
+
+
+
36940 log_debug("Adding descriptor %d to event loop\n", entry->fd);
97 +
98 + 36940 nfds_t nfds = loop->nfds + 1;
99 + 36940 SIMPLEQ_INSERT_TAIL(&loop->entries, entry, entries);
100 + 36940 loop->nfds = nfds;
101 + 36940}
102 +
103 + 112int event_loop_add(struct event_loop *loop, int fd, short events, event_handler handler, void *arg)
104 + {
105 + 112 struct event_fd *entry = event_fd_create(fd, events, handler, arg);
106 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 112 times.
+
+
+
112 if (!entry)
107 + return -1;
108 + 112 event_loop_add_internal(loop, entry);
109 + 112 return 0;
110 + }
111 +
112 + 36828int event_loop_add_once(struct event_loop *loop, int fd, short events, event_handler handler,
113 + void *arg)
114 + {
115 + 36828 struct event_fd *entry = event_fd_create(fd, events, handler, arg);
116 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36828 times.
+
+
+
36828 if (!entry)
117 + return -1;
118 + 36828 entry->once = 1;
119 + 36828 event_loop_add_internal(loop, entry);
120 + 36828 return 0;
121 + }
122 +
123 + 36774static void event_loop_remove(struct event_loop *loop, struct event_fd *entry)
124 + {
125 +
+ 1/2 +
+
✓ Branch 1 taken 36774 times.
+
✗ Branch 2 not taken.
+
+
+
36774 log_debug("Removing descriptor %d from event loop\n", entry->fd);
126 +
127 +
+ 5/8 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
✗ Branch 2 not taken.
+
✗ Branch 3 not taken.
+
✓ Branch 4 taken 51921 times.
+
✓ Branch 5 taken 36774 times.
+
✓ Branch 6 taken 22111 times.
+
✓ Branch 7 taken 14663 times.
+
+
+
88695 SIMPLEQ_REMOVE(&loop->entries, entry, event_fd, entries);
128 + 36774 event_fd_destroy(entry);
129 + 36774 --loop->nfds;
130 + 36774}
131 +
132 + 326633static char *append_event(char *buf, size_t sz, char *ptr, const char *event)
133 + {
134 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (ptr > buf)
135 + ptr = stpecpy(ptr, buf + sz, ",");
136 + 326633 return stpecpy(ptr, buf + sz, event);
137 + }
138 +
139 + 326633static char *events_to_string(short events)
140 + {
141 + 326633 const size_t sz = 128;
142 + 326633 char *buf = calloc(1, sz);
143 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (!buf)
144 + return NULL;
145 +
146 + 326633 char *ptr = buf;
147 +
148 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (events & POLLNVAL)
149 + ptr = append_event(buf, sz, ptr, "POLLNVAL");
150 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (events & POLLERR)
151 + ptr = append_event(buf, sz, ptr, "POLLERR");
152 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (events & POLLHUP)
153 + ptr = append_event(buf, sz, ptr, "POLLHUP");
154 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (events & POLLRDHUP)
155 + ptr = append_event(buf, sz, ptr, "POLLRDHUP");
156 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (events & POLLPRI)
157 + ptr = append_event(buf, sz, ptr, "POLLPRI");
158 +
+ 1/2 +
+
✓ Branch 0 taken 326633 times.
+
✗ Branch 1 not taken.
+
+
+
326633 if (events & POLLIN)
159 + 326633 ptr = append_event(buf, sz, ptr, "POLLIN");
160 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (events & POLLOUT)
161 + ptr = append_event(buf, sz, ptr, "POLLOUT");
162 +
163 + 326633 return buf;
164 + }
165 +
166 + 63144static struct pollfd *make_pollfds(const struct event_loop *loop)
167 + {
168 + 63144 struct pollfd *fds = calloc(loop->nfds, sizeof(struct pollfd));
169 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 63144 times.
+
+
+
63144 if (!fds) {
170 + log_errno("calloc");
171 + return NULL;
172 + }
173 +
174 + 63144 struct event_fd *entry = SIMPLEQ_FIRST(&loop->entries);
175 +
+ 2/2 +
+
✓ Branch 0 taken 262182 times.
+
✓ Branch 1 taken 63144 times.
+
+
+
325326 for (nfds_t i = 0; i < loop->nfds; ++i, entry = SIMPLEQ_NEXT(entry, entries)) {
176 + 262182 fds[i].fd = entry->fd;
177 + 262182 fds[i].events = entry->events;
178 + }
179 +
180 +
+ 1/2 +
+
✓ Branch 1 taken 63144 times.
+
✗ Branch 2 not taken.
+
+
+
63144 log_debug("Descriptors:\n");
181 +
+ 2/2 +
+
✓ Branch 0 taken 262182 times.
+
✓ Branch 1 taken 63144 times.
+
+
+
325326 for (nfds_t i = 0; i < loop->nfds; ++i) {
182 + 262182 char *events = events_to_string(fds[i].events);
183 +
+ 1/4 +
+
✓ Branch 1 taken 262182 times.
+
✗ Branch 2 not taken.
+
✗ Branch 3 not taken.
+
✗ Branch 4 not taken.
+
+
+
262182 log_debug(" %d (%s)\n", fds[i].fd, events ? events : "");
184 + 262182 free(events);
185 + }
186 +
187 + 63144 return fds;
188 + }
189 +
190 + 63144int event_loop_run(struct event_loop *loop)
191 + {
192 + /* Cache the number of event descriptors so that event handlers can
193 + * append new ones. */
194 + 63144 const nfds_t nfds = loop->nfds;
195 +
196 + 63144 struct pollfd *fds = make_pollfds(loop);
197 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 63144 times.
+
+
+
63144 if (!fds)
198 + return -1;
199 +
200 + 63144 int ret = poll(fds, nfds, -1);
201 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 63144 times.
+
+
+
63144 if (ret < 0) {
202 + log_errno("poll");
203 + return ret;
204 + }
205 + 63144 ret = 0;
206 +
207 + 63144 struct event_fd *entry = SIMPLEQ_FIRST(&loop->entries);
208 +
+ 2/2 +
+
✓ Branch 0 taken 262182 times.
+
✓ Branch 1 taken 63144 times.
+
+
+
325326 for (nfds_t i = 0; i < nfds; ++i) {
209 + 262182 struct event_fd *next = SIMPLEQ_NEXT(entry, entries);
210 +
211 +
+ 2/2 +
+
✓ Branch 0 taken 197731 times.
+
✓ Branch 1 taken 64451 times.
+
+
+
262182 if (!fds[i].revents)
212 + 197731 goto next;
213 +
214 + 64451 char *events = events_to_string(fds[i].revents);
215 +
+ 1/4 +
+
✓ Branch 1 taken 64451 times.
+
✗ Branch 2 not taken.
+
✗ Branch 3 not taken.
+
✗ Branch 4 not taken.
+
+
+
64451 log_debug("Descriptor %d is ready: %s\n", fds[i].fd, events ? events : "");
216 + 64451 free(events);
217 +
218 + /* Execute all handlers but notice if any of them fail. */
219 + 64451 const int handler_ret = entry->handler(loop, fds[i].fd, fds[i].revents, entry->arg);
220 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 64451 times.
+
+
+
64451 if (handler_ret < 0)
221 + ret = handler_ret;
222 +
223 +
+ 2/2 +
+
✓ Branch 0 taken 27677 times.
+
✓ Branch 1 taken 36774 times.
+
+
+
64451 if (entry->once)
224 + 36774 event_loop_remove(loop, entry);
225 +
226 + 27677 next:
227 + 262182 entry = next;
228 + 262182 continue;
229 + }
230 +
231 + 63144 free(fds);
232 + 63144 return ret;
233 + }
234 +
+
+ +
+ + + + diff --git a/coverage/index.file.c.0cc24881e570d19e625204519d50254f.html b/coverage/index.file.c.0cc24881e570d19e625204519d50254f.html new file mode 100644 index 0000000..ef10190 --- /dev/null +++ b/coverage/index.file.c.0cc24881e570d19e625204519d50254f.html @@ -0,0 +1,1491 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/file.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:568466.7%
Branches:205238.5%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "file.h"
9 + #include "compiler.h"
10 + #include "log.h"
11 +
12 + #include <fcntl.h>
13 + #include <ftw.h>
14 + #include <stdio.h>
15 + #include <stdlib.h>
16 + #include <sys/stat.h>
17 + #include <unistd.h>
18 +
19 + 403663static int unlink_cb(const char *fpath, UNUSED const struct stat *sb, UNUSED int typeflag,
20 + UNUSED struct FTW *ftwbuf)
21 + {
22 + 403663 int ret = 0;
23 +
24 + 403663 ret = remove(fpath);
25 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 403663 times.
+
+
+
403663 if (ret < 0) {
26 + log_errno("remove");
27 + return ret;
28 + }
29 +
30 + 403663 return ret;
31 + }
32 +
33 + 9180int rm_rf(const char *dir)
34 + {
35 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Recursively removing directory: %s\n", dir);
36 + 9180 return nftw(dir, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
37 + }
38 +
39 + 18360int my_chdir(const char *dir, char **old)
40 + {
41 + 18360 int ret = 0;
42 +
43 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 9180 times.
+
+
+
18360 if (old) {
44 + 9180 *old = get_current_dir_name();
45 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!*old) {
46 + log_errno("get_current_dir_name");
47 + return -1;
48 + }
49 + }
50 +
51 + 18360 ret = chdir(dir);
52 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 18360 times.
+
+
+
18360 if (ret < 0) {
53 + log_errno("chdir");
54 + goto free_old;
55 + }
56 +
57 + 18360 return ret;
58 +
59 + free_old:
60 + if (old)
61 + free(*old);
62 +
63 + return ret;
64 + }
65 +
66 + 20char *my_readlink(const char *path)
67 + {
68 + 20 size_t current_size = 256;
69 + 20 char *buf = NULL;
70 +
71 + while (1) {
72 + 20 char *tmp_buf = realloc(buf, current_size);
73 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 20 times.
+
+
+
20 if (!tmp_buf) {
74 + log_errno("realloc");
75 + goto free;
76 + }
77 + 20 buf = tmp_buf;
78 +
79 + 20 ssize_t res = readlink(path, buf, current_size);
80 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 20 times.
+
+
+
20 if (res < 0) {
81 + log_errno("readlink");
82 + goto free;
83 + }
84 +
85 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 20 times.
+
+
+
20 if ((size_t)res == current_size) {
86 + current_size *= 2;
87 + continue;
88 + }
89 +
90 + 20 buf[res] = '\0';
91 + 20 break;
92 + }
93 +
94 + 20 return buf;
95 +
96 + free:
97 + free(buf);
98 +
99 + return NULL;
100 + }
101 +
102 + 9234int file_dup(int fd)
103 + {
104 + 9234 int ret = 0;
105 +
106 + 9234 ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
107 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0) {
108 + log_errno("fcntl");
109 + return ret;
110 + }
111 +
112 + 9234 return ret;
113 + }
114 +
115 + 110488void file_close(int fd)
116 + {
117 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 110488 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
110488 log_errno_if(close(fd), "close");
118 + 110488}
119 +
120 + 36720int file_exists(const char *path)
121 + {
122 + struct stat stat;
123 + 36720 int ret = lstat(path, &stat);
124 +
+ 3/4 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 27540 times.
+
✓ Branch 2 taken 9180 times.
+
✗ Branch 3 not taken.
+
+
+
36720 return !ret && S_ISREG(stat.st_mode);
125 + }
126 +
127 + 9180int file_read(int fd, unsigned char **_contents, size_t *_size)
128 + {
129 + 9180 size_t alloc_size = 256;
130 + 9180 unsigned char *contents = NULL;
131 + 9180 size_t size = 0;
132 +
133 + 362720 while (1) {
134 + 371900 unsigned char *tmp_contents = realloc(contents, alloc_size);
135 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 371900 times.
+
+
+
371900 if (!tmp_contents) {
136 + log_errno("realloc");
137 + free(contents);
138 + return -1;
139 + }
140 + 371900 contents = tmp_contents;
141 +
142 + 371900 ssize_t read_size = read(fd, contents + size, alloc_size - size);
143 +
144 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 371900 times.
+
+
+
371900 if (read_size < 0) {
145 + log_errno("read");
146 + free(contents);
147 + return read_size;
148 + }
149 +
150 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 362720 times.
+
+
+
371900 if (!read_size) {
151 + 9180 *_contents = contents;
152 + 9180 *_size = size;
153 + 9180 return 0;
154 + }
155 +
156 + 362720 size += read_size;
157 +
158 +
+ 2/2 +
+
✓ Branch 0 taken 49896 times.
+
✓ Branch 1 taken 312824 times.
+
+
+
362720 if (size == alloc_size) {
159 + 49896 alloc_size *= 2;
160 + }
161 + }
162 + }
163 +
+
+ +
+ + + + diff --git a/coverage/index.git.c.ecafe65200a95f92fc10a3095d9e5f09.html b/coverage/index.git.c.ecafe65200a95f92fc10a3095d9e5f09.html new file mode 100644 index 0000000..f97b10e --- /dev/null +++ b/coverage/index.git.c.ecafe65200a95f92fc10a3095d9e5f09.html @@ -0,0 +1,1092 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/git.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:395570.9%
Branches:106415.6%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "git.h"
9 + #include "log.h"
10 +
11 + #include <git2.h>
12 +
13 + #include <stdlib.h>
14 +
15 + #define git_log_err(fn) \
16 + do { \
17 + const git_error *error = git_error_last(); \
18 + const char *msg = error && error->message ? error->message : "???"; \
19 + log_err("%s: %s\n", fn, msg); \
20 + } while (0)
21 +
22 + 54int libgit_init(void)
23 + {
24 + 54 int ret = 0;
25 +
26 + 54 ret = git_libgit2_init();
27 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (ret < 0) {
28 + git_log_err("git_libgit2_init");
29 + return ret;
30 + }
31 +
32 + 54 return 0;
33 + }
34 +
35 + 54void libgit_shutdown(void)
36 + {
37 + 54 git_libgit2_shutdown();
38 + 54}
39 +
40 + 9180int libgit_clone(git_repository **repo, const char *url, const char *dir)
41 + {
42 + git_clone_options opts;
43 + 9180 int ret = 0;
44 +
45 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Cloning git repository from %s to %s\n", url, dir);
46 +
47 + 9180 ret = git_clone_options_init(&opts, GIT_CLONE_OPTIONS_VERSION);
48 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
49 + git_log_err("git_clone_options_init");
50 + return ret;
51 + }
52 + 9180 opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_NONE;
53 +
54 + 9180 ret = git_clone(repo, url, dir, &opts);
55 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
56 + git_log_err("git_clone");
57 + return ret;
58 + }
59 +
60 + 9180 return 0;
61 + }
62 +
63 + 9180int libgit_clone_to_tmp(git_repository **repo, const char *url)
64 + {
65 + 9180 char dir[] = "/tmp/git.XXXXXX";
66 +
67 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 if (!mkdtemp(dir)) {
68 + log_errno("mkdtemp");
69 + return -1;
70 + }
71 +
72 + 9180 return libgit_clone(repo, url, dir);
73 + }
74 +
75 + 9180void libgit_repository_free(git_repository *repo)
76 + {
77 + 9180 git_repository_free(repo);
78 + 9180}
79 +
80 + 9180int libgit_checkout(git_repository *repo, const char *rev)
81 + {
82 + git_checkout_options opts;
83 + git_object *obj;
84 + 9180 int ret = 0;
85 +
86 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Checking out revision %s\n", rev);
87 +
88 + 9180 ret = git_revparse_single(&obj, repo, rev);
89 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
90 + git_log_err("git_revparse_single");
91 + return ret;
92 + }
93 +
94 + 9180 ret = git_checkout_options_init(&opts, GIT_CHECKOUT_OPTIONS_VERSION);
95 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
96 + git_log_err("git_checkout_options_init");
97 + goto free_obj;
98 + }
99 + 9180 opts.checkout_strategy = GIT_CHECKOUT_FORCE;
100 +
101 + 9180 ret = git_checkout_tree(repo, obj, &opts);
102 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
103 + git_log_err("git_checkout_tree");
104 + goto free_obj;
105 + }
106 +
107 + 9180 ret = git_repository_set_head_detached(repo, git_object_id(obj));
108 +
+ 1/2 +
+
✓ Branch 0 taken 9180 times.
+
✗ Branch 1 not taken.
+
+
+
9180 if (ret < 0) {
109 + git_log_err("git_repository_set_head_detached");
110 + goto free_obj;
111 + }
112 +
113 + 9180free_obj:
114 + 9180 git_object_free(obj);
115 +
116 + 9180 return ret;
117 + }
118 +
+
+ +
+ + + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 0000000..02157c1 --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,461 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
Date:2023-08-28 07:33:56
Legend: + low: >= 0% + medium: >= 75.0% + high: >= 90.0% +
+
+ +
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:1857268269.2%
Branches:522135738.5%
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLinesBranches
+ base64.c + + 66.7 + 66.7%18 / 2725.0%3 / 12
+ ci.c + + 78.7 + 78.7%37 / 4750.0%9 / 18
+ client.c + + 78.2 + 78.2%43 / 5554.2%13 / 24
+ client_main.c + + 79.1 + 79.1%34 / 4371.4%10 / 14
+ cmd_line.c + + 90.3 + 90.3%28 / 3150.0%7 / 14
+ command.c + + 74.2 + 74.2%89 / 12050.0%33 / 66
+ event_loop.c + + 84.7 + 84.7%111 / 13151.3%39 / 76
+ file.c + + 66.7 + 66.7%56 / 8438.5%20 / 52
+ git.c + + 70.9 + 70.9%39 / 5515.6%10 / 64
+ json.c + + 72.2 + 72.2%91 / 12632.8%19 / 58
+ json_rpc.c + + 63.6 + 63.6%194 / 30537.7%58 / 154
+ log.c + + 91.7 + 91.7%22 / 2466.7%4 / 6
+ net.c + + 64.3 + 64.3%101 / 15732.3%31 / 96
+ process.c + + 48.8 + 48.8%41 / 8423.1%12 / 52
+ protocol.c + + 68.4 + 68.4%78 / 11450.0%22 / 44
+ run_queue.c + + 71.7 + 71.7%43 / 6033.3%6 / 18
+ server.c + + 71.4 + 71.4%182 / 25542.0%58 / 138
+ server_main.c + + 79.1 + 79.1%34 / 4371.4%10 / 14
+ signal.c + + 81.6 + 81.6%31 / 3850.0%5 / 10
+ sqlite.c + + 55.6 + 55.6%90 / 16220.0%19 / 95
+ storage.c + + 75.0 + 75.0%33 / 4444.4%8 / 18
+ storage_sqlite.c + + 65.0 + 65.0%197 / 30337.0%54 / 146
+ string.c + + 27.3 + 27.3%6 / 2218.8%3 / 16
+ tcp_server.c + + 71.3 + 71.3%87 / 12240.9%27 / 66
+ worker.c + + 70.2 + 70.2%106 / 15143.5%27 / 62
+ worker_main.c + + 79.1 + 79.1%34 / 4371.4%10 / 14
+ worker_queue.c + + 88.9 + 88.9%32 / 3650.0%5 / 10
+ +
+ + + + diff --git a/coverage/index.json.c.9fe0913c76249e448eec3131d7e8b263.html b/coverage/index.json.c.9fe0913c76249e448eec3131d7e8b263.html new file mode 100644 index 0000000..865f858 --- /dev/null +++ b/coverage/index.json.c.9fe0913c76249e448eec3131d7e8b263.html @@ -0,0 +1,2187 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/json.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:9112672.2%
Branches:195832.8%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "json.h"
9 + #include "log.h"
10 + #include "net.h"
11 +
12 + #include <json-c/json_object.h>
13 + #include <json-c/json_tokener.h>
14 +
15 + #include <errno.h>
16 + #include <stdint.h>
17 + #include <stdlib.h>
18 + #include <string.h>
19 +
20 + 45954const char *json_to_string(struct json_object *obj)
21 + {
22 + 45954 const char *result = json_object_to_json_string(obj);
23 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (!result) {
24 + json_errno("json_object_to_json_string");
25 + return NULL;
26 + }
27 + 45954 return result;
28 + }
29 +
30 + 45954struct json_object *json_from_string(const char *src)
31 + {
32 + enum json_tokener_error error;
33 +
34 + 45954 struct json_object *result = json_tokener_parse_verbose(src, &error);
35 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (!result) {
36 + json_errno("json_tokener_parse_verbose");
37 + log_err("JSON: parsing failed: %s\n", json_tokener_error_desc(error));
38 + return NULL;
39 + }
40 +
41 + 45954 return result;
42 + }
43 +
44 + 27540int json_clone(const struct json_object *obj, const char *key, struct json_object **_value)
45 + {
46 + 27540 int ret = 0;
47 +
48 + 27540 struct json_object *old_value = NULL;
49 + 27540 ret = json_get(obj, key, &old_value);
50 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0)
51 + return ret;
52 +
53 + 27540 struct json_object *new_value = NULL;
54 + 27540 ret = json_object_deep_copy(old_value, &new_value, NULL);
55 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0)
56 + return ret;
57 +
58 + 27540 *_value = new_value;
59 + 27540 return ret;
60 + }
61 +
62 + 45954int json_send(struct json_object *obj, int fd)
63 + {
64 + 45954 int ret = 0;
65 +
66 + 45954 const char *str = json_to_string(obj);
67 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (!str)
68 + return -1;
69 +
70 + 45954 struct buf *buf = NULL;
71 + 45954 ret = buf_create_from_string(&buf, str);
72 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (ret < 0)
73 + return ret;
74 +
75 + 45954 ret = net_send_buf(fd, buf);
76 + 45954 buf_destroy(buf);
77 + 45954 return ret;
78 + }
79 +
80 + 45954struct json_object *json_recv(int fd)
81 + {
82 + 45954 struct json_object *result = NULL;
83 + 45954 int ret = 0;
84 +
85 + 45954 struct buf *buf = NULL;
86 + 45954 ret = net_recv_buf(fd, &buf);
87 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (ret < 0)
88 + return NULL;
89 +
90 + 45954 result = json_from_string((const char *)buf_get_data(buf));
91 +
+ 1/2 +
+
✓ Branch 0 taken 45954 times.
+
✗ Branch 1 not taken.
+
+
+
45954 if (!result)
92 + goto destroy_buf;
93 +
94 + 45954destroy_buf:
95 + 45954 free((void *)buf_get_data(buf));
96 + 45954 buf_destroy(buf);
97 +
98 + 45954 return result;
99 + }
100 +
101 + 606204int json_has(const struct json_object *obj, const char *key)
102 + {
103 + 606204 return json_object_object_get_ex(obj, key, NULL);
104 + }
105 +
106 + 385722int json_get(const struct json_object *obj, const char *key, struct json_object **value)
107 + {
108 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 385722 times.
+
+
+
385722 if (!json_has(obj, key)) {
109 + log_err("JSON: key is missing: %s\n", key);
110 + return -1;
111 + }
112 +
113 + 385722 return json_object_object_get_ex(obj, key, value);
114 + }
115 +
116 + 165402int json_get_string(const struct json_object *obj, const char *key, const char **_value)
117 + {
118 + 165402 struct json_object *value = NULL;
119 +
120 + 165402 int ret = json_get(obj, key, &value);
121 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 165402 times.
+
+
+
165402 if (ret < 0)
122 + return ret;
123 +
124 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 165402 times.
+
+
+
165402 if (!json_object_is_type(value, json_type_string)) {
125 + log_err("JSON: key is not a string: %s\n", key);
126 + return -1;
127 + }
128 +
129 + 165402 *_value = json_object_get_string(value);
130 + 165402 return 0;
131 + }
132 +
133 + 27540int json_get_int(const struct json_object *obj, const char *key, int64_t *_value)
134 + {
135 + 27540 struct json_object *value = NULL;
136 +
137 + 27540 int ret = json_get(obj, key, &value);
138 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0)
139 + return ret;
140 +
141 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 27540 times.
+
+
+
27540 if (!json_object_is_type(value, json_type_int)) {
142 + log_err("JSON: key is not an integer: %s\n", key);
143 + return -1;
144 + }
145 +
146 + 27540 errno = 0;
147 + 27540 int64_t tmp = json_object_get_int64(value);
148 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (errno) {
149 + log_err("JSON: failed to parse integer from key: %s\n", key);
150 + return -1;
151 + }
152 +
153 + 27540 *_value = tmp;
154 + 27540 return 0;
155 + }
156 +
157 + 284688static int json_set_internal(struct json_object *obj, const char *key, struct json_object *value,
158 + unsigned flags)
159 + {
160 + 284688 int ret = 0;
161 +
162 + 284688 ret = json_object_object_add_ex(obj, key, value, flags);
163 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 284688 times.
+
+
+
284688 if (ret < 0) {
164 + json_errno("json_object_object_add_ex");
165 + return ret;
166 + }
167 +
168 + 284688 return 0;
169 + }
170 +
171 + 156168static int json_set_string_internal(struct json_object *obj, const char *key, const char *_value,
172 + unsigned flags)
173 + {
174 + 156168 struct json_object *value = json_object_new_string(_value);
175 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 156168 times.
+
+
+
156168 if (!value) {
176 + json_errno("json_object_new_string");
177 + return -1;
178 + }
179 +
180 + 156168 int ret = json_set_internal(obj, key, value, flags);
181 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 156168 times.
+
+
+
156168 if (ret < 0)
182 + goto free_value;
183 +
184 + 156168 return ret;
185 +
186 + free_value:
187 + json_object_put(value);
188 +
189 + return ret;
190 + }
191 +
192 + 45900static int json_set_int_internal(struct json_object *obj, const char *key, int64_t _value,
193 + unsigned flags)
194 + {
195 + 45900 struct json_object *value = json_object_new_int64(_value);
196 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45900 times.
+
+
+
45900 if (!value) {
197 + json_errno("json_object_new_int");
198 + return -1;
199 + }
200 +
201 + 45900 int ret = json_set_internal(obj, key, value, flags);
202 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45900 times.
+
+
+
45900 if (ret < 0)
203 + goto free_value;
204 +
205 + 45900 return ret;
206 +
207 + free_value:
208 + json_object_put(value);
209 +
210 + return ret;
211 + }
212 +
213 + 55080int json_set(struct json_object *obj, const char *key, struct json_object *value)
214 + {
215 + 55080 return json_set_internal(obj, key, value, 0);
216 + }
217 +
218 + 45900int json_set_string(struct json_object *obj, const char *key, const char *value)
219 + {
220 + 45900 return json_set_string_internal(obj, key, value, 0);
221 + }
222 +
223 + 27540int json_set_int(struct json_object *obj, const char *key, int64_t value)
224 + {
225 + 27540 return json_set_int_internal(obj, key, value, 0);
226 + }
227 +
228 + #ifndef JSON_C_OBJECT_ADD_CONSTANT_KEY
229 + #define JSON_C_OBJECT_ADD_CONSTANT_KEY JSON_C_OBJECT_KEY_IS_CONSTANT
230 + #endif
231 + static const unsigned json_const_key_flags = JSON_C_OBJECT_ADD_CONSTANT_KEY;
232 +
233 + 27540int json_set_const_key(struct json_object *obj, const char *key, struct json_object *value)
234 + {
235 + 27540 return json_set_internal(obj, key, value, json_const_key_flags);
236 + }
237 +
238 + 110268int json_set_string_const_key(struct json_object *obj, const char *key, const char *value)
239 + {
240 + 110268 return json_set_string_internal(obj, key, value, json_const_key_flags);
241 + }
242 +
243 + 18360int json_set_int_const_key(struct json_object *obj, const char *key, int64_t value)
244 + {
245 + 18360 return json_set_int_internal(obj, key, value, json_const_key_flags);
246 + }
247 +
+
+ +
+ + + + diff --git a/coverage/index.json_rpc.c.2aeccc6679171fb423f72eef95ec01c0.html b/coverage/index.json_rpc.c.2aeccc6679171fb423f72eef95ec01c0.html new file mode 100644 index 0000000..ca195d1 --- /dev/null +++ b/coverage/index.json_rpc.c.2aeccc6679171fb423f72eef95ec01c0.html @@ -0,0 +1,4752 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/json_rpc.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:19430563.6%
Branches:5815437.7%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "json_rpc.h"
9 + #include "json.h"
10 + #include "log.h"
11 +
12 + #include <json-c/json_object.h>
13 +
14 + #include <stdint.h>
15 + #include <stdlib.h>
16 + #include <string.h>
17 +
18 + struct jsonrpc_request {
19 + struct json_object *impl;
20 + };
21 +
22 + struct jsonrpc_response {
23 + struct json_object *impl;
24 + };
25 +
26 + static const char *const jsonrpc_key_version = "jsonrpc";
27 + static const char *const jsonrpc_key_id = "id";
28 + static const char *const jsonrpc_key_method = "method";
29 + static const char *const jsonrpc_key_params = "params";
30 +
31 + static const char *const jsonrpc_value_version = "2.0";
32 +
33 + 45954static int jsonrpc_check_version(struct json_object *obj)
34 + {
35 + 45954 const char *key = jsonrpc_key_version;
36 + 45954 const char *version = NULL;
37 +
38 + 45954 int ret = json_get_string(obj, key, &version);
39 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (ret < 0)
40 + return ret;
41 +
42 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (strcmp(version, jsonrpc_value_version)) {
43 + log_err("JSON-RPC: invalid '%s' value: %s\n", key, version);
44 + return -1;
45 + }
46 +
47 + 45954 return 0;
48 + }
49 +
50 + 64314static int jsonrpc_set_version(struct json_object *obj)
51 + {
52 + 64314 return json_set_string_const_key(obj, jsonrpc_key_version, jsonrpc_value_version);
53 + }
54 +
55 + 18360static int jsonrpc_check_id_type(struct json_object *id)
56 + {
57 +
+ 2/4 +
+
✓ Branch 1 taken 18360 times.
+
✗ Branch 2 not taken.
+
✗ Branch 4 not taken.
+
✓ Branch 5 taken 18360 times.
+
+
+
18360 if (!json_object_is_type(id, json_type_string) && !json_object_is_type(id, json_type_int)) {
58 + log_err("JSON-RPC: key '%s' must be either an integer or a string\n",
59 + jsonrpc_key_id);
60 + return -1;
61 + }
62 + 18360 return 0;
63 + }
64 +
65 + 45954static int jsonrpc_check_id(struct json_object *obj, int required)
66 + {
67 + 45954 const char *key = jsonrpc_key_id;
68 +
69 +
+ 2/2 +
+
✓ Branch 1 taken 27594 times.
+
✓ Branch 2 taken 18360 times.
+
+
+
45954 if (!json_has(obj, key)) {
70 +
+ 1/2 +
+
✓ Branch 0 taken 27594 times.
+
✗ Branch 1 not taken.
+
+
+
27594 if (!required)
71 + 27594 return 0;
72 + log_err("JSON-RPC: key is missing: %s\n", key);
73 + return -1;
74 + }
75 +
76 + 18360 struct json_object *id = NULL;
77 +
78 + 18360 int ret = json_get(obj, key, &id);
79 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 18360 times.
+
+
+
18360 if (ret < 0)
80 + return ret;
81 + 18360 return jsonrpc_check_id_type(id);
82 + }
83 +
84 + 9180static int jsonrpc_set_id(struct json_object *obj, int id)
85 + {
86 + 9180 return json_set_int_const_key(obj, jsonrpc_key_id, id);
87 + }
88 +
89 + 36774static int jsonrpc_check_method(struct json_object *obj)
90 + {
91 + 36774 const char *key = jsonrpc_key_method;
92 + 36774 const char *method = NULL;
93 + 36774 return json_get_string(obj, key, &method);
94 + }
95 +
96 + 36774static int jsonrpc_set_method(struct json_object *obj, const char *method)
97 + {
98 + 36774 return json_set_string_const_key(obj, jsonrpc_key_method, method);
99 + }
100 +
101 + 27540static int jsonrpc_check_params_type(struct json_object *params)
102 + {
103 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 27540 times.
+
✗ Branch 3 not taken.
+
✗ Branch 4 not taken.
+
+
+
27540 if (!json_object_is_type(params, json_type_object) &&
104 + !json_object_is_type(params, json_type_array)) {
105 + log_err("JSON-RPC: key '%s' must be either an object or an array\n",
106 + jsonrpc_key_params);
107 + return -1;
108 + }
109 + 27540 return 0;
110 + }
111 +
112 + 36774static int jsonrpc_check_params(struct json_object *obj)
113 + {
114 + 36774 const char *key = jsonrpc_key_params;
115 +
116 +
+ 2/2 +
+
✓ Branch 1 taken 9234 times.
+
✓ Branch 2 taken 27540 times.
+
+
+
36774 if (!json_has(obj, key))
117 + 9234 return 0;
118 +
119 + 27540 struct json_object *params = NULL;
120 +
121 + 27540 int ret = json_get(obj, key, &params);
122 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0)
123 + return ret;
124 + 27540 return jsonrpc_check_params_type(params);
125 + }
126 +
127 + static int jsonrpc_set_params(struct json_object *obj, struct json_object *params)
128 + {
129 + const char *key = jsonrpc_key_params;
130 +
131 + int ret = jsonrpc_check_params_type(params);
132 + if (ret < 0)
133 + return ret;
134 + return json_set_const_key(obj, key, params);
135 + }
136 +
137 + static const char *const jsonrpc_key_result = "result";
138 + static const char *const jsonrpc_key_error = "error";
139 +
140 + static const char *const jsonrpc_key_code = "code";
141 + static const char *const jsonrpc_key_message = "message";
142 +
143 + static int jsonrpc_check_error(struct json_object *obj)
144 + {
145 + const char *key = jsonrpc_key_error;
146 + struct json_object *error = NULL;
147 +
148 + int ret = json_get(obj, key, &error);
149 + if (ret < 0)
150 + return ret;
151 +
152 + int64_t code = -1;
153 +
154 + ret = json_get_int(error, jsonrpc_key_code, &code);
155 + if (ret < 0) {
156 + log_err("JSON-RPC: key is missing or not an integer: %s\n", jsonrpc_key_code);
157 + return -1;
158 + }
159 +
160 + const char *message = NULL;
161 +
162 + ret = json_get_string(error, jsonrpc_key_message, &message);
163 + if (ret < 0) {
164 + log_err("JSON-RPC: key is missing or not a string: %s\n", jsonrpc_key_message);
165 + return -1;
166 + }
167 +
168 + return ret;
169 + }
170 +
171 + 9180static int jsonrpc_check_result_or_error(struct json_object *obj)
172 + {
173 + 9180 const char *key_result = jsonrpc_key_result;
174 + 9180 const char *key_error = jsonrpc_key_error;
175 +
176 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
9180 if (!json_has(obj, key_result) && !json_has(obj, key_error)) {
177 + log_err("JSON-RPC: either '%s' or '%s' must be present\n", key_result, key_error);
178 + return -1;
179 + }
180 +
181 +
+ 1/2 +
+
✓ Branch 1 taken 9180 times.
+
✗ Branch 2 not taken.
+
+
+
9180 if (json_has(obj, key_result))
182 + 9180 return 0;
183 +
184 + return jsonrpc_check_error(obj);
185 + }
186 +
187 + 36774static int jsonrpc_request_create_internal(struct jsonrpc_request **_request, int *id,
188 + const char *method, struct json_object *params)
189 + {
190 + 36774 int ret = 0;
191 +
192 + 36774 struct jsonrpc_request *request = malloc(sizeof(struct jsonrpc_request));
193 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (!request) {
194 + log_errno("malloc");
195 + ret = -1;
196 + goto exit;
197 + }
198 +
199 + 36774 request->impl = json_object_new_object();
200 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (!request->impl) {
201 + json_errno("json_object_new_object");
202 + ret = -1;
203 + goto free;
204 + }
205 +
206 + 36774 ret = jsonrpc_set_version(request->impl);
207 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0)
208 + goto free_impl;
209 +
210 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 27594 times.
+
+
+
36774 if (id) {
211 + 9180 ret = jsonrpc_set_id(request->impl, *id);
212 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
213 + goto free_impl;
214 + }
215 +
216 + 36774 ret = jsonrpc_set_method(request->impl, method);
217 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0)
218 + goto free_impl;
219 +
220 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (params) {
221 + ret = jsonrpc_set_params(request->impl, params);
222 + if (ret < 0)
223 + goto free_impl;
224 + }
225 +
226 + 36774 *_request = request;
227 + 36774 goto exit;
228 +
229 + free_impl:
230 + json_object_put(request->impl);
231 + free:
232 + free(request);
233 + 36774exit:
234 + 36774 return ret;
235 + }
236 +
237 + 9180int jsonrpc_request_create(struct jsonrpc_request **_request, int id, const char *method,
238 + struct json_object *params)
239 + {
240 + 9180 return jsonrpc_request_create_internal(_request, &id, method, params);
241 + }
242 +
243 + 73548void jsonrpc_request_destroy(struct jsonrpc_request *request)
244 + {
245 + 73548 json_object_put(request->impl);
246 + 73548 free(request);
247 + 73548}
248 +
249 + 27594int jsonrpc_notification_create(struct jsonrpc_request **_request, const char *method,
250 + struct json_object *params)
251 + {
252 + 27594 return jsonrpc_request_create_internal(_request, NULL, method, params);
253 + }
254 +
255 + 36774int jsonrpc_request_is_notification(const struct jsonrpc_request *request)
256 + {
257 + 36774 return !json_has(request->impl, jsonrpc_key_id);
258 + }
259 +
260 + 36774static int jsonrpc_request_from_json(struct jsonrpc_request **_request, struct json_object *impl)
261 + {
262 + 36774 int ret = 0;
263 +
264 + 36774 ret = jsonrpc_check_version(impl);
265 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0)
266 + return ret;
267 + 36774 ret = jsonrpc_check_id(impl, 0);
268 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0)
269 + return ret;
270 + 36774 ret = jsonrpc_check_method(impl);
271 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0)
272 + return ret;
273 + 36774 ret = jsonrpc_check_params(impl);
274 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0)
275 + return ret;
276 +
277 + 36774 struct jsonrpc_request *request = malloc(sizeof(struct jsonrpc_request));
278 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (!request) {
279 + log_errno("malloc");
280 + return -1;
281 + }
282 + 36774 request->impl = impl;
283 +
284 + 36774 *_request = request;
285 + 36774 return ret;
286 + }
287 +
288 + 36774int jsonrpc_request_send(const struct jsonrpc_request *request, int fd)
289 + {
290 + 36774 return json_send(request->impl, fd);
291 + }
292 +
293 + 36774int jsonrpc_request_recv(struct jsonrpc_request **request, int fd)
294 + {
295 + 36774 struct json_object *impl = json_recv(fd);
296 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (!impl) {
297 + log_err("JSON-RPC: failed to receive request\n");
298 + return -1;
299 + }
300 +
301 + 36774 int ret = jsonrpc_request_from_json(request, impl);
302 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0)
303 + goto free_impl;
304 +
305 + 36774 return ret;
306 +
307 + free_impl:
308 + json_object_put(impl);
309 +
310 + return ret;
311 + }
312 +
313 + 36774const char *jsonrpc_request_get_method(const struct jsonrpc_request *request)
314 + {
315 + 36774 const char *method = NULL;
316 + 36774 int ret = json_get_string(request->impl, jsonrpc_key_method, &method);
317 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36774 times.
+
+
+
36774 if (ret < 0) {
318 + /* Should never happen. */
319 + return NULL;
320 + }
321 + 36774 return method;
322 + }
323 +
324 + 73440static struct json_object *jsonrpc_request_create_params(struct jsonrpc_request *request)
325 + {
326 + 73440 const char *const key = jsonrpc_key_params;
327 +
328 +
+ 2/2 +
+
✓ Branch 1 taken 27540 times.
+
✓ Branch 2 taken 45900 times.
+
+
+
73440 if (!json_has(request->impl, key)) {
329 + 27540 struct json_object *params = json_object_new_object();
330 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (!params) {
331 + json_errno("json_object_new_object");
332 + return NULL;
333 + }
334 + 27540 int ret = json_set(request->impl, key, params);
335 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0) {
336 + json_object_put(params);
337 + return NULL;
338 + }
339 + 27540 return params;
340 + }
341 +
342 + 45900 struct json_object *params = NULL;
343 + 45900 int ret = json_get(request->impl, key, &params);
344 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45900 times.
+
+
+
45900 if (ret < 0)
345 + return NULL;
346 + 45900 return params;
347 + }
348 +
349 + 45900int jsonrpc_request_get_param_string(const struct jsonrpc_request *request, const char *name,
350 + const char **value)
351 + {
352 + 45900 struct json_object *params = NULL;
353 + 45900 int ret = json_get(request->impl, jsonrpc_key_params, &params);
354 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45900 times.
+
+
+
45900 if (ret < 0)
355 + return ret;
356 + 45900 return json_get_string(params, name, value);
357 + }
358 +
359 + 45900int jsonrpc_request_set_param_string(struct jsonrpc_request *request, const char *name,
360 + const char *value)
361 + {
362 + 45900 struct json_object *params = jsonrpc_request_create_params(request);
363 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45900 times.
+
+
+
45900 if (!params)
364 + return -1;
365 + 45900 return json_set_string(params, name, value);
366 + }
367 +
368 + 27540int jsonrpc_request_get_param_int(const struct jsonrpc_request *request, const char *name,
369 + int64_t *value)
370 + {
371 + 27540 struct json_object *params = NULL;
372 + 27540 int ret = json_get(request->impl, jsonrpc_key_params, &params);
373 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0)
374 + return ret;
375 + 27540 return json_get_int(params, name, value);
376 + }
377 +
378 + 27540int jsonrpc_request_set_param_int(struct jsonrpc_request *request, const char *name, int64_t value)
379 + {
380 + 27540 struct json_object *params = jsonrpc_request_create_params(request);
381 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (!params)
382 + return -1;
383 + 27540 return json_set_int(params, name, value);
384 + }
385 +
386 + 27540int jsonrpc_response_create_internal(struct jsonrpc_response **_response,
387 + const struct jsonrpc_request *request,
388 + struct json_object *result, struct json_object *error)
389 + {
390 + 27540 int ret = 0;
391 +
392 + 27540 struct jsonrpc_response *response = malloc(sizeof(struct jsonrpc_response));
393 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (!response) {
394 + log_errno("malloc");
395 + ret = -1;
396 + goto exit;
397 + }
398 +
399 + 27540 response->impl = json_object_new_object();
400 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (!response->impl) {
401 + json_errno("json_object_new_object");
402 + ret = -1;
403 + goto free;
404 + }
405 +
406 + 27540 ret = jsonrpc_set_version(response->impl);
407 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0)
408 + goto free_impl;
409 +
410 + 27540 struct json_object *id = NULL;
411 + 27540 ret = json_clone(request->impl, jsonrpc_key_id, &id);
412 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0)
413 + goto free_impl;
414 +
415 + 27540 ret = json_set(response->impl, jsonrpc_key_id, id);
416 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret < 0) {
417 + json_object_put(id);
418 + goto free_impl;
419 + }
420 +
421 +
+ 2/2 +
+
✓ Branch 0 taken 9180 times.
+
✓ Branch 1 taken 18360 times.
+
+
+
27540 if (error) {
422 + 9180 ret = json_set_const_key(response->impl, jsonrpc_key_error, error);
423 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
424 + goto free_impl;
425 + } else {
426 + 18360 ret = json_set_const_key(response->impl, jsonrpc_key_result, result);
427 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 18360 times.
+
+
+
18360 if (ret < 0)
428 + goto free_impl;
429 + }
430 +
431 + 27540 *_response = response;
432 + 27540 goto exit;
433 +
434 + free_impl:
435 + json_object_put(response->impl);
436 + free:
437 + free(response);
438 + 27540exit:
439 + 27540 return ret;
440 + }
441 +
442 + 18360int jsonrpc_response_create(struct jsonrpc_response **response,
443 + const struct jsonrpc_request *request, struct json_object *result)
444 + {
445 + 18360 return jsonrpc_response_create_internal(response, request, result, NULL);
446 + }
447 +
448 + 36720void jsonrpc_response_destroy(struct jsonrpc_response *response)
449 + {
450 + 36720 json_object_put(response->impl);
451 + 36720 free(response);
452 + 36720}
453 +
454 + 9180int jsonrpc_error_create(struct jsonrpc_response **response, struct jsonrpc_request *request,
455 + int code, const char *message)
456 + {
457 + 9180 struct json_object *error = json_object_new_object();
458 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!error) {
459 + json_errno("json_object_new_object");
460 + return -1;
461 + }
462 +
463 + 9180 int ret = 0;
464 +
465 + 9180 ret = json_set_int_const_key(error, jsonrpc_key_code, code);
466 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
467 + goto free;
468 + 9180 ret = json_set_string_const_key(error, jsonrpc_key_message, message);
469 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
470 + goto free;
471 +
472 + 9180 ret = jsonrpc_response_create_internal(response, request, NULL, error);
473 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
474 + goto free;
475 +
476 + 9180 return ret;
477 +
478 + free:
479 + json_object_put(error);
480 +
481 + return ret;
482 + }
483 +
484 + 9180int jsonrpc_response_is_error(const struct jsonrpc_response *response)
485 + {
486 + 9180 return json_has(response->impl, jsonrpc_key_error);
487 + }
488 +
489 + 9180static int jsonrpc_response_from_json(struct jsonrpc_response **_response, struct json_object *impl)
490 + {
491 + 9180 int ret = 0;
492 +
493 + 9180 ret = jsonrpc_check_version(impl);
494 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
495 + return ret;
496 + 9180 ret = jsonrpc_check_id(impl, 1);
497 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
498 + return ret;
499 + 9180 ret = jsonrpc_check_result_or_error(impl);
500 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
501 + return ret;
502 +
503 + 9180 struct jsonrpc_response *response = malloc(sizeof(struct jsonrpc_response));
504 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!response) {
505 + log_errno("malloc");
506 + return -1;
507 + }
508 + 9180 response->impl = impl;
509 +
510 + 9180 *_response = response;
511 + 9180 return ret;
512 + }
513 +
514 + 9180int jsonrpc_response_send(const struct jsonrpc_response *response, int fd)
515 + {
516 + 9180 return json_send(response->impl, fd);
517 + }
518 +
519 + 9180int jsonrpc_response_recv(struct jsonrpc_response **response, int fd)
520 + {
521 + 9180 struct json_object *impl = json_recv(fd);
522 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!impl) {
523 + log_err("JSON-RPC: failed to receive response\n");
524 + return -1;
525 + }
526 +
527 + 9180 int ret = jsonrpc_response_from_json(response, impl);
528 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
529 + goto free_impl;
530 +
531 + 9180 return ret;
532 +
533 + free_impl:
534 + json_object_put(impl);
535 +
536 + return ret;
537 + }
538 +
+
+ +
+ + + + diff --git a/coverage/index.log.c.47179e5db7ed3f2db741c99372ba24f3.html b/coverage/index.log.c.47179e5db7ed3f2db741c99372ba24f3.html new file mode 100644 index 0000000..e2ed177 --- /dev/null +++ b/coverage/index.log.c.47179e5db7ed3f2db741c99372ba24f3.html @@ -0,0 +1,539 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/log.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:222491.7%
Branches:4666.7%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "log.h"
9 +
10 + #include <stdio.h>
11 + #include <sys/time.h>
12 + #include <time.h>
13 + #include <unistd.h>
14 +
15 + int g_log_lvl = LOG_LVL_INFO;
16 +
17 + 173557static inline void log_prefix_timestamp(FILE *dest)
18 + {
19 + struct timeval tv;
20 + struct tm tm;
21 + char buf[64];
22 + 173557 size_t used = 0;
23 +
24 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 173557 times.
+
+
+
173557 if (gettimeofday(&tv, NULL) < 0)
25 + return;
26 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 173557 times.
+
+
+
173557 if (!gmtime_r(&tv.tv_sec, &tm))
27 + return;
28 +
29 + 173557 buf[0] = '\0';
30 + 173557 used += strftime(buf + used, sizeof(buf) - used, "%F %T", &tm);
31 + 173557 long long msec = (long long)tv.tv_usec / 1000;
32 + 173557 used += snprintf(buf + used, sizeof(buf) - used, ".%03lld | ", msec);
33 + 173557 fprintf(dest, "%s", buf);
34 + }
35 +
36 + 173557static inline void log_prefix_thread_id(FILE *dest)
37 + {
38 + 173557 fprintf(dest, "%d | ", gettid());
39 + 173557}
40 +
41 + 719830int log_entry_start(int lvl, FILE *dest)
42 + {
43 +
+ 2/2 +
+
✓ Branch 0 taken 546273 times.
+
✓ Branch 1 taken 173557 times.
+
+
+
719830 if (lvl < g_log_lvl)
44 + 546273 return 0;
45 + 173557 flockfile(dest);
46 + 173557 log_prefix_timestamp(dest);
47 + 173557 log_prefix_thread_id(dest);
48 + 173557 return 1;
49 + }
50 +
51 + 173557void log_entry_end(FILE *dest)
52 + {
53 + 173557 funlockfile(dest);
54 + 173557}
55 +
+
+ +
+ + + + diff --git a/coverage/index.net.c.37012fce13860cefc5963f57e0f36732.html b/coverage/index.net.c.37012fce13860cefc5963f57e0f36732.html new file mode 100644 index 0000000..52179a9 --- /dev/null +++ b/coverage/index.net.c.37012fce13860cefc5963f57e0f36732.html @@ -0,0 +1,2705 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/net.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:10115764.3%
Branches:319632.3%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "net.h"
9 + #include "file.h"
10 + #include "log.h"
11 +
12 + #include <netdb.h>
13 + #include <stdint.h>
14 + #include <stdlib.h>
15 + #include <string.h>
16 + #include <sys/socket.h>
17 + #include <sys/types.h>
18 + #include <unistd.h>
19 +
20 + #define gai_log_errno(ec) log_err("getaddrinfo: %s\n", gai_strerror(ec))
21 +
22 + 29int net_bind(const char *port)
23 + {
24 + static const int flags = SOCK_CLOEXEC;
25 + 29 struct addrinfo *result = NULL, *it = NULL;
26 + struct addrinfo hints;
27 + 29 int socket_fd = -1, ret = 0;
28 +
29 + 29 memset(&hints, 0, sizeof(hints));
30 + 29 hints.ai_family = AF_INET6;
31 + 29 hints.ai_socktype = SOCK_STREAM;
32 + 29 hints.ai_flags = AI_PASSIVE;
33 +
34 + 29 ret = getaddrinfo(NULL, port, &hints, &result);
35 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret) {
36 + gai_log_errno(ret);
37 + return -1;
38 + }
39 +
40 +
+ 1/2 +
+
✓ Branch 0 taken 29 times.
+
✗ Branch 1 not taken.
+
+
+
29 for (it = result; it; it = it->ai_next) {
41 + 29 socket_fd = socket(it->ai_family, it->ai_socktype | flags, it->ai_protocol);
42 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (socket_fd < 0) {
43 + log_errno("socket");
44 + continue;
45 + }
46 +
47 + static const int yes = 1;
48 + static const int no = 0;
49 +
50 +
+ 1/2 +
+
✓ Branch 0 taken 29 times.
+
✗ Branch 1 not taken.
+
+
+
29 if (it->ai_family == AF_INET6) {
51 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
+
+
29 if (setsockopt(socket_fd, IPPROTO_IPV6, IPV6_V6ONLY, &no, sizeof(no)) < 0) {
52 + log_errno("setsockopt");
53 + goto close_socket;
54 + }
55 + }
56 +
57 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
+
+
29 if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
58 + log_errno("setsockopt");
59 + goto close_socket;
60 + }
61 +
62 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
+
+
29 if (bind(socket_fd, it->ai_addr, it->ai_addrlen) < 0) {
63 + log_errno("bind");
64 + goto close_socket;
65 + }
66 +
67 + 29 break;
68 +
69 + close_socket:
70 + net_close(socket_fd);
71 + }
72 +
73 + 29 freeaddrinfo(result);
74 +
75 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!it) {
76 + log_err("Couldn't bind to port %s\n", port);
77 + return -1;
78 + }
79 +
80 + 29 ret = listen(socket_fd, 4096);
81 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0) {
82 + log_errno("listen");
83 + goto fail;
84 + }
85 +
86 + 29 return socket_fd;
87 +
88 + fail:
89 + net_close(socket_fd);
90 +
91 + return ret;
92 + }
93 +
94 + 27594int net_accept(int fd)
95 + {
96 + static const int flags = SOCK_CLOEXEC;
97 + 27594 int ret = 0;
98 +
99 + 27594 ret = accept4(fd, NULL, NULL, flags);
100 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret < 0) {
101 + log_errno("accept4");
102 + return ret;
103 + }
104 +
105 + 27594 return ret;
106 + }
107 +
108 + 27594int net_connect(const char *host, const char *port)
109 + {
110 + static const int flags = SOCK_CLOEXEC;
111 + 27594 struct addrinfo *result = NULL, *it = NULL;
112 + struct addrinfo hints;
113 + 27594 int socket_fd = -1, ret = 0;
114 +
115 + 27594 memset(&hints, 0, sizeof(hints));
116 + 27594 hints.ai_family = AF_UNSPEC;
117 + 27594 hints.ai_socktype = SOCK_STREAM;
118 +
119 + 27594 ret = getaddrinfo(host, port, &hints, &result);
120 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret) {
121 + gai_log_errno(ret);
122 + return -1;
123 + }
124 +
125 +
+ 1/2 +
+
✓ Branch 0 taken 27594 times.
+
✗ Branch 1 not taken.
+
+
+
27594 for (it = result; it; it = it->ai_next) {
126 + 27594 socket_fd = socket(it->ai_family, it->ai_socktype | flags, it->ai_protocol);
127 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (socket_fd < 0) {
128 + log_errno("socket");
129 + continue;
130 + }
131 +
132 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 27594 times.
+
+
+
27594 if (connect(socket_fd, it->ai_addr, it->ai_addrlen) < 0) {
133 + log_errno("connect");
134 + goto close_socket;
135 + }
136 +
137 + 27594 break;
138 +
139 + close_socket:
140 + net_close(socket_fd);
141 + }
142 +
143 + 27594 freeaddrinfo(result);
144 +
145 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (!it) {
146 + log_err("Couldn't connect to host %s, port %s\n", host, port);
147 + return -1;
148 + }
149 +
150 + 27594 return socket_fd;
151 + }
152 +
153 + 64451void net_close(int fd)
154 + {
155 + 64451 file_close(fd);
156 + 64451}
157 +
158 + 91908static ssize_t net_send_part(int fd, const void *buf, size_t size)
159 + {
160 + static const int flags = MSG_NOSIGNAL;
161 +
162 + 91908 ssize_t ret = send(fd, buf, size, flags);
163 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 91908 times.
+
+
+
91908 if (ret < 0) {
164 + log_errno("send");
165 + return -1;
166 + }
167 +
168 + 91908 return ret;
169 + }
170 +
171 + 91908int net_send(int fd, const void *buf, size_t size)
172 + {
173 + 91908 size_t sent_total = 0;
174 +
175 +
+ 2/2 +
+
✓ Branch 0 taken 91908 times.
+
✓ Branch 1 taken 91908 times.
+
+
+
183816 while (sent_total < size) {
176 + ssize_t sent_now =
177 + 91908 net_send_part(fd, (const char *)buf + sent_total, size - sent_total);
178 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 91908 times.
+
+
+
91908 if (sent_now < 0)
179 + return -1;
180 + 91908 sent_total += sent_now;
181 + }
182 +
183 + 91908 return 0;
184 + }
185 +
186 + 91908int net_recv(int fd, void *buf, size_t size)
187 + {
188 + 91908 ssize_t read_total = 0;
189 +
190 +
+ 2/2 +
+
✓ Branch 0 taken 104687 times.
+
✓ Branch 1 taken 91908 times.
+
+
+
196595 while ((size_t)read_total < size) {
191 + 104687 ssize_t read_now = read(fd, (unsigned char *)buf + read_total, size - read_total);
192 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 104687 times.
+
+
+
104687 if (!read_now)
193 + break;
194 +
195 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 104687 times.
+
+
+
104687 if (read_now < 0) {
196 + log_errno("read");
197 + return -1;
198 + }
199 +
200 + 104687 read_total += read_now;
201 + }
202 +
203 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 91908 times.
+
+
+
91908 if ((size_t)read_total < size) {
204 + log_err("Received only %zd bytes out of %zu\n", read_total, size);
205 + return -1;
206 + }
207 +
208 + 91908 return 0;
209 + }
210 +
211 + struct buf {
212 + uint32_t size;
213 + const void *data;
214 + };
215 +
216 + 91908int buf_create(struct buf **_buf, const void *data, uint32_t size)
217 + {
218 + 91908 struct buf *buf = malloc(sizeof(struct buf));
219 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 91908 times.
+
+
+
91908 if (!buf) {
220 + log_errno("malloc");
221 + return -1;
222 + }
223 +
224 + 91908 buf->data = data;
225 + 91908 buf->size = size;
226 +
227 + 91908 *_buf = buf;
228 + 91908 return 0;
229 + }
230 +
231 + 45954int buf_create_from_string(struct buf **buf, const char *str)
232 + {
233 + 45954 return buf_create(buf, str, strlen(str) + 1);
234 + }
235 +
236 + 91908void buf_destroy(struct buf *buf)
237 + {
238 + 91908 free(buf);
239 + 91908}
240 +
241 + uint32_t buf_get_size(const struct buf *buf)
242 + {
243 + return buf->size;
244 + }
245 +
246 + 91908const void *buf_get_data(const struct buf *buf)
247 + {
248 + 91908 return buf->data;
249 + }
250 +
251 + 45954int net_send_buf(int fd, const struct buf *buf)
252 + {
253 + 45954 int ret = 0;
254 +
255 + 45954 uint32_t size = htonl(buf->size);
256 + 45954 ret = net_send(fd, &size, sizeof(size));
257 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (ret < 0)
258 + return ret;
259 +
260 + 45954 ret = net_send(fd, buf->data, buf->size);
261 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (ret < 0)
262 + return ret;
263 +
264 + 45954 return ret;
265 + }
266 +
267 + 45954int net_recv_buf(int fd, struct buf **buf)
268 + {
269 + 45954 uint32_t size = 0;
270 + 45954 int ret = 0;
271 +
272 + 45954 ret = net_recv(fd, &size, sizeof(size));
273 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (ret < 0) {
274 + log_err("Couldn't read buffer size\n");
275 + goto fail;
276 + }
277 + 45954 size = ntohl(size);
278 +
279 + 45954 void *data = malloc(size);
280 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (!data) {
281 + log_errno("malloc");
282 + goto fail;
283 + }
284 +
285 + 45954 ret = net_recv(fd, data, size);
286 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (ret < 0) {
287 + log_err("Couldn't read buffer\n");
288 + goto free_data;
289 + }
290 +
291 + 45954 ret = buf_create(buf, data, size);
292 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45954 times.
+
+
+
45954 if (ret < 0)
293 + goto free_data;
294 +
295 + 45954 return ret;
296 +
297 + free_data:
298 + free(data);
299 +
300 + fail:
301 + return -1;
302 + }
303 +
+
+ +
+ + + + diff --git a/coverage/index.process.c.52f9324f34485af6c2c0f7cc7bbf5f8b.html b/coverage/index.process.c.52f9324f34485af6c2c0f7cc7bbf5f8b.html new file mode 100644 index 0000000..8480dac --- /dev/null +++ b/coverage/index.process.c.52f9324f34485af6c2c0f7cc7bbf5f8b.html @@ -0,0 +1,1491 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/process.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:418448.8%
Branches:125223.1%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "process.h"
9 + #include "file.h"
10 + #include "log.h"
11 +
12 + #include <fcntl.h>
13 + #include <stdlib.h>
14 + #include <sys/wait.h>
15 + #include <unistd.h>
16 +
17 + static int exec_child(const char *args[], const char *envp[])
18 + {
19 + static const char *default_envp[] = {NULL};
20 +
21 + if (!envp)
22 + envp = default_envp;
23 +
24 + int ret = execvpe(args[0], (char *const *)args, (char *const *)envp);
25 + if (ret < 0) {
26 + log_errno("execvpe");
27 + return ret;
28 + }
29 +
30 + return ret;
31 + }
32 +
33 + 9180static int wait_for_child(pid_t pid, int *ec)
34 + {
35 + int status;
36 +
37 + 9180 pid_t ret = waitpid(pid, &status, __WNOTHREAD);
38 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
39 + log_errno("waitpid");
40 + return ret;
41 + }
42 +
43 + /* The child process reports the lowest 8 bits of its exit code, which
44 + * are treated as an unsigned integer on Linux.
45 + *
46 + * If it was killed by a signal, indicate that by negating the signal
47 + * number. */
48 +
49 +
+ 2/2 +
+
✓ Branch 0 taken 9144 times.
+
✓ Branch 1 taken 36 times.
+
+
+
9180 if (WIFEXITED(status)) {
50 + 9144 *ec = WEXITSTATUS(status);
51 +
+ 1/2 +
+
✓ Branch 0 taken 36 times.
+
✗ Branch 1 not taken.
+
+
+
36 } else if (WIFSIGNALED(status)) {
52 + 36 *ec = -WTERMSIG(status);
53 + } else {
54 + log_err("This shouldn't happen: %d\n", status);
55 + *ec = 1;
56 + }
57 +
58 + 9180 return 0;
59 + }
60 +
61 + int proc_spawn(const char *args[], const char *envp[], int *ec)
62 + {
63 + pid_t child_pid = fork();
64 + if (child_pid < 0) {
65 + log_errno("fork");
66 + return child_pid;
67 + }
68 +
69 + if (!child_pid)
70 + exit(exec_child(args, envp));
71 +
72 + return wait_for_child(child_pid, ec);
73 + }
74 +
75 + static int redirect_and_exec_child(int pipe_fds[2], const char *args[], const char *envp[])
76 + {
77 + int ret = 0;
78 +
79 + file_close(pipe_fds[0]);
80 +
81 + ret = dup2(pipe_fds[1], STDOUT_FILENO);
82 + if (ret < 0) {
83 + log_errno("dup2");
84 + return ret;
85 + }
86 +
87 + ret = dup2(pipe_fds[1], STDERR_FILENO);
88 + if (ret < 0) {
89 + log_errno("dup2");
90 + return ret;
91 + }
92 +
93 + return exec_child(args, envp);
94 + }
95 +
96 + 9180int proc_capture(const char *args[], const char *envp[], struct proc_output *result)
97 + {
98 + static const int flags = O_CLOEXEC;
99 + int pipe_fds[2];
100 + 9180 int ret = 0;
101 +
102 + 9180 ret = pipe2(pipe_fds, flags);
103 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
104 + log_errno("pipe2");
105 + return -1;
106 + }
107 +
108 + 9180 pid_t child_pid = fork();
109 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (child_pid < 0) {
110 + log_errno("fork");
111 + goto close_pipe;
112 + }
113 +
114 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!child_pid)
115 + exit(redirect_and_exec_child(pipe_fds, args, envp));
116 +
117 + 9180 file_close(pipe_fds[1]);
118 +
119 + 9180 ret = file_read(pipe_fds[0], &result->data, &result->data_size);
120 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
121 + goto close_pipe;
122 +
123 + 9180 ret = wait_for_child(child_pid, &result->ec);
124 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
125 + goto free_data;
126 +
127 + 9180 goto close_pipe;
128 +
129 + free_data:
130 + free(result->data);
131 +
132 + 9180close_pipe:
133 + 9180 file_close(pipe_fds[0]);
134 + /* No errno checking here, we might've already closed the write end. */
135 + 9180 close(pipe_fds[1]);
136 +
137 + 9180 return ret;
138 + }
139 +
140 + 18360int proc_output_create(struct proc_output **_output)
141 + {
142 + 18360 struct proc_output *output = calloc(1, sizeof(struct proc_output));
143 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 18360 times.
+
+
+
18360 if (!output) {
144 + log_errno("calloc");
145 + return -1;
146 + }
147 +
148 + 18360 output->ec = 0;
149 + 18360 output->data = NULL;
150 + 18360 output->data_size = 0;
151 +
152 + 18360 *_output = output;
153 + 18360 return 0;
154 + }
155 +
156 + 18360void proc_output_destroy(struct proc_output *output)
157 + {
158 + 18360 free(output->data);
159 + 18360 free(output);
160 + 18360}
161 +
162 + 9180void proc_output_dump(const struct proc_output *output)
163 + {
164 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Process exit code: %d\n", output->ec);
165 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Process output: %zu bytes\n", output->data_size);
166 + 9180}
167 +
+
+ +
+ + + + diff --git a/coverage/index.protocol.c.4964764a2e677a55c2f4207a995c3ce7.html b/coverage/index.protocol.c.4964764a2e677a55c2f4207a995c3ce7.html new file mode 100644 index 0000000..3c8f928 --- /dev/null +++ b/coverage/index.protocol.c.4964764a2e677a55c2f4207a995c3ce7.html @@ -0,0 +1,1776 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/protocol.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:7811468.4%
Branches:224450.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "protocol.h"
9 + #include "base64.h"
10 + #include "compiler.h"
11 + #include "const.h"
12 + #include "json_rpc.h"
13 + #include "process.h"
14 + #include "run_queue.h"
15 +
16 + #include <stddef.h>
17 + #include <stdint.h>
18 + #include <stdlib.h>
19 +
20 + static const char *const run_key_id = "id";
21 + static const char *const run_key_url = "url";
22 + static const char *const run_key_rev = "rev";
23 +
24 + 9180int run_request_create(struct jsonrpc_request **request, const struct run *run)
25 + {
26 + 9180 int ret = 0;
27 +
28 + 9180 ret = jsonrpc_request_create(request, 1, CMD_RUN, NULL);
29 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
30 + return ret;
31 + 9180 ret = jsonrpc_request_set_param_string(*request, run_key_url, run_get_url(run));
32 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
33 + goto free_request;
34 + 9180 ret = jsonrpc_request_set_param_string(*request, run_key_rev, run_get_rev(run));
35 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
36 + goto free_request;
37 +
38 + 9180 return ret;
39 +
40 + free_request:
41 + jsonrpc_request_destroy(*request);
42 +
43 + return ret;
44 + }
45 +
46 + 9180int run_request_parse(const struct jsonrpc_request *request, struct run **run)
47 + {
48 + 9180 int ret = 0;
49 +
50 + 9180 const char *url = NULL;
51 + 9180 ret = jsonrpc_request_get_param_string(request, run_key_url, &url);
52 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
53 + return ret;
54 + 9180 const char *rev = NULL;
55 + 9180 ret = jsonrpc_request_get_param_string(request, run_key_rev, &rev);
56 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
57 + return ret;
58 +
59 + 9180 return run_create(run, 0, url, rev);
60 + }
61 +
62 + 9234int new_worker_request_create(struct jsonrpc_request **request)
63 + {
64 + 9234 return jsonrpc_notification_create(request, CMD_NEW_WORKER, NULL);
65 + }
66 +
67 + int new_worker_request_parse(UNUSED const struct jsonrpc_request *request)
68 + {
69 + return 0;
70 + }
71 +
72 + 9180int start_request_create(struct jsonrpc_request **request, const struct run *run)
73 + {
74 + 9180 int ret = 0;
75 +
76 + 9180 ret = jsonrpc_notification_create(request, CMD_START, NULL);
77 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
78 + return ret;
79 + 9180 ret = jsonrpc_request_set_param_int(*request, run_key_id, run_get_id(run));
80 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
81 + goto free_request;
82 + 9180 ret = jsonrpc_request_set_param_string(*request, run_key_url, run_get_url(run));
83 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
84 + goto free_request;
85 + 9180 ret = jsonrpc_request_set_param_string(*request, run_key_rev, run_get_rev(run));
86 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
87 + goto free_request;
88 +
89 + 9180 return ret;
90 +
91 + free_request:
92 + jsonrpc_request_destroy(*request);
93 +
94 + return ret;
95 + }
96 +
97 + 9180int start_request_parse(const struct jsonrpc_request *request, struct run **run)
98 + {
99 + 9180 int ret = 0;
100 +
101 + 9180 int64_t id = 0;
102 + 9180 ret = jsonrpc_request_get_param_int(request, run_key_id, &id);
103 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
104 + return ret;
105 + 9180 const char *url = NULL;
106 + 9180 ret = jsonrpc_request_get_param_string(request, run_key_url, &url);
107 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
108 + return ret;
109 + 9180 const char *rev = NULL;
110 + 9180 ret = jsonrpc_request_get_param_string(request, run_key_rev, &rev);
111 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
112 + return ret;
113 +
114 + 9180 return run_create(run, (int)id, url, rev);
115 + }
116 +
117 + static const char *const finished_key_run_id = "run_id";
118 + static const char *const finished_key_ec = "exit_code";
119 + static const char *const finished_key_data = "output";
120 +
121 + 9180int finished_request_create(struct jsonrpc_request **request, int run_id,
122 + const struct proc_output *output)
123 + {
124 + 9180 int ret = 0;
125 +
126 + 9180 ret = jsonrpc_notification_create(request, CMD_FINISHED, NULL);
127 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
128 + return ret;
129 + 9180 ret = jsonrpc_request_set_param_int(*request, finished_key_run_id, run_id);
130 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
131 + goto free_request;
132 + 9180 ret = jsonrpc_request_set_param_int(*request, finished_key_ec, output->ec);
133 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
134 + goto free_request;
135 +
136 + 9180 char *b64data = NULL;
137 + 9180 ret = base64_encode(output->data, output->data_size, &b64data);
138 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
139 + goto free_request;
140 +
141 + 9180 ret = jsonrpc_request_set_param_string(*request, finished_key_data, b64data);
142 + 9180 free(b64data);
143 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
144 + goto free_request;
145 +
146 + 9180 return ret;
147 +
148 + free_request:
149 + jsonrpc_request_destroy(*request);
150 +
151 + return ret;
152 + }
153 +
154 + 9180int finished_request_parse(const struct jsonrpc_request *request, int *_run_id,
155 + struct proc_output **_output)
156 + {
157 + 9180 int ret = 0;
158 +
159 + 9180 struct proc_output *output = NULL;
160 + 9180 ret = proc_output_create(&output);
161 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
162 + return ret;
163 +
164 + 9180 int64_t run_id = 0;
165 + 9180 ret = jsonrpc_request_get_param_int(request, finished_key_run_id, &run_id);
166 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
167 + goto free_output;
168 +
169 + 9180 int64_t ec = -1;
170 + 9180 ret = jsonrpc_request_get_param_int(request, finished_key_ec, &ec);
171 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
172 + goto free_output;
173 + 9180 output->ec = (int)ec;
174 +
175 + 9180 const char *b64data = NULL;
176 + 9180 ret = jsonrpc_request_get_param_string(request, finished_key_data, &b64data);
177 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
178 + goto free_output;
179 +
180 + 9180 ret = base64_decode(b64data, &output->data, &output->data_size);
181 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
182 + goto free_output;
183 +
184 + 9180 *_run_id = (int)run_id;
185 + 9180 *_output = output;
186 + 9180 return ret;
187 +
188 + free_output:
189 + proc_output_destroy(output);
190 +
191 + return ret;
192 + }
193 +
+
+ +
+ + + + diff --git a/coverage/index.run_queue.c.fdfaa39d71447cf1e7d01ff206bd91e5.html b/coverage/index.run_queue.c.fdfaa39d71447cf1e7d01ff206bd91e5.html new file mode 100644 index 0000000..6971eff --- /dev/null +++ b/coverage/index.run_queue.c.fdfaa39d71447cf1e7d01ff206bd91e5.html @@ -0,0 +1,1097 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/run_queue.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:436071.7%
Branches:61833.3%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "run_queue.h"
9 + #include "log.h"
10 +
11 + #include <stdlib.h>
12 + #include <string.h>
13 + #include <sys/queue.h>
14 +
15 + struct run {
16 + int id;
17 + char *url;
18 + char *rev;
19 + SIMPLEQ_ENTRY(run) entries;
20 + };
21 +
22 + 27540int run_create(struct run **_entry, int id, const char *_url, const char *_rev)
23 + {
24 + 27540 struct run *entry = malloc(sizeof(struct run));
25 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (!entry) {
26 + log_errno("malloc");
27 + goto fail;
28 + }
29 +
30 + 27540 char *url = strdup(_url);
31 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (!url) {
32 + log_errno("strdup");
33 + goto free_entry;
34 + }
35 +
36 + 27540 char *rev = strdup(_rev);
37 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (!rev) {
38 + log_errno("strdup");
39 + goto free_url;
40 + }
41 +
42 + 27540 entry->id = id;
43 + 27540 entry->url = url;
44 + 27540 entry->rev = rev;
45 +
46 + 27540 *_entry = entry;
47 + 27540 return 0;
48 +
49 + free_url:
50 + free(url);
51 +
52 + free_entry:
53 + free(entry);
54 +
55 + fail:
56 + return -1;
57 + }
58 +
59 + 27540void run_destroy(struct run *entry)
60 + {
61 + 27540 free(entry->rev);
62 + 27540 free(entry->url);
63 + 27540 free(entry);
64 + 27540}
65 +
66 + 45900int run_get_id(const struct run *entry)
67 + {
68 + 45900 return entry->id;
69 + }
70 +
71 + 64260const char *run_get_url(const struct run *entry)
72 + {
73 + 64260 return entry->url;
74 + }
75 +
76 + 36720const char *run_get_rev(const struct run *entry)
77 + {
78 + 36720 return entry->rev;
79 + }
80 +
81 + 9180void run_set_id(struct run *entry, int id)
82 + {
83 + 9180 entry->id = id;
84 + 9180}
85 +
86 + 29void run_queue_create(struct run_queue *queue)
87 + {
88 + 29 SIMPLEQ_INIT(queue);
89 + 29}
90 +
91 + 29void run_queue_destroy(struct run_queue *queue)
92 + {
93 + 29 struct run *entry1 = SIMPLEQ_FIRST(queue);
94 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 while (entry1) {
95 + struct run *entry2 = SIMPLEQ_NEXT(entry1, entries);
96 + run_destroy(entry1);
97 + entry1 = entry2;
98 + }
99 + 29 SIMPLEQ_INIT(queue);
100 + 29}
101 +
102 + 27375int run_queue_is_empty(const struct run_queue *queue)
103 + {
104 + 27375 return SIMPLEQ_EMPTY(queue);
105 + }
106 +
107 + void run_queue_add_first(struct run_queue *queue, struct run *entry)
108 + {
109 + SIMPLEQ_INSERT_HEAD(queue, entry, entries);
110 + }
111 +
112 + 9180void run_queue_add_last(struct run_queue *queue, struct run *entry)
113 + {
114 + 9180 SIMPLEQ_INSERT_TAIL(queue, entry, entries);
115 + 9180}
116 +
117 + 9180struct run *run_queue_remove_first(struct run_queue *queue)
118 + {
119 + 9180 struct run *entry = SIMPLEQ_FIRST(queue);
120 +
+ 2/2 +
+
✓ Branch 0 taken 74 times.
+
✓ Branch 1 taken 9106 times.
+
+
+
9180 SIMPLEQ_REMOVE_HEAD(queue, entries);
121 + 9180 return entry;
122 + }
123 +
+
+ +
+ + + + diff --git a/coverage/index.server.c.0235f01a49d01b35e981a41f59a9d2d6.html b/coverage/index.server.c.0235f01a49d01b35e981a41f59a9d2d6.html new file mode 100644 index 0000000..371483f --- /dev/null +++ b/coverage/index.server.c.0235f01a49d01b35e981a41f59a9d2d6.html @@ -0,0 +1,4186 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/server.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:18225571.4%
Branches:5813842.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "server.h"
9 + #include "command.h"
10 + #include "compiler.h"
11 + #include "const.h"
12 + #include "event_loop.h"
13 + #include "file.h"
14 + #include "json_rpc.h"
15 + #include "log.h"
16 + #include "net.h"
17 + #include "process.h"
18 + #include "protocol.h"
19 + #include "run_queue.h"
20 + #include "signal.h"
21 + #include "storage.h"
22 + #include "storage_sqlite.h"
23 + #include "tcp_server.h"
24 + #include "worker_queue.h"
25 +
26 + #include <poll.h>
27 + #include <pthread.h>
28 + #include <stdlib.h>
29 +
30 + struct server {
31 + pthread_mutex_t server_mtx;
32 + pthread_cond_t server_cv;
33 +
34 + int stopping;
35 +
36 + struct cmd_dispatcher *cmd_dispatcher;
37 +
38 + struct event_loop *event_loop;
39 + int signalfd;
40 +
41 + struct worker_queue worker_queue;
42 + struct run_queue run_queue;
43 +
44 + struct storage storage;
45 +
46 + pthread_t main_thread;
47 +
48 + struct tcp_server *tcp_server;
49 + };
50 +
51 + 18472static int server_lock(struct server *server)
52 + {
53 + 18472 int ret = pthread_mutex_lock(&server->server_mtx);
54 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 18472 times.
+
+
+
18472 if (ret) {
55 + pthread_errno(ret, "pthread_mutex_lock");
56 + return ret;
57 + }
58 + 18472 return ret;
59 + }
60 +
61 + 18472static void server_unlock(struct server *server)
62 + {
63 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 18472 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
18472 pthread_errno_if(pthread_mutex_unlock(&server->server_mtx), "pthread_mutex_unlock");
64 + 18472}
65 +
66 + 18195static int server_wait(struct server *server)
67 + {
68 + 18195 int ret = pthread_cond_wait(&server->server_cv, &server->server_mtx);
69 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 18195 times.
+
+
+
18195 if (ret) {
70 + pthread_errno(ret, "pthread_cond_wait");
71 + return ret;
72 + }
73 + 18195 return ret;
74 + }
75 +
76 + 18443static void server_notify(struct server *server)
77 + {
78 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 18443 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
18443 pthread_errno_if(pthread_cond_signal(&server->server_cv), "pthread_cond_signal");
79 + 18443}
80 +
81 + 29static int server_set_stopping(UNUSED struct event_loop *loop, UNUSED int fd, UNUSED short revents,
82 + void *_server)
83 + {
84 + 29 struct server *server = (struct server *)_server;
85 + 29 int ret = 0;
86 +
87 + 29 ret = server_lock(server);
88 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
89 + return ret;
90 +
91 + 29 server->stopping = 1;
92 +
93 + 29 server_notify(server);
94 + 29 server_unlock(server);
95 + 29 return ret;
96 + }
97 +
98 + 27169static int server_has_workers(const struct server *server)
99 + {
100 + 27169 return !worker_queue_is_empty(&server->worker_queue);
101 + }
102 +
103 + 9234static int server_enqueue_worker(struct server *server, struct worker *worker)
104 + {
105 + 9234 int ret = 0;
106 +
107 + 9234 ret = server_lock(server);
108 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
109 + return ret;
110 +
111 + 9234 worker_queue_add_last(&server->worker_queue, worker);
112 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9234 times.
+
+
+
9234 log("Added a new worker %d to the queue\n", worker_get_fd(worker));
113 +
114 + 9234 server_notify(server);
115 + 9234 server_unlock(server);
116 + 9234 return ret;
117 + }
118 +
119 + 27375static int server_has_runs(const struct server *server)
120 + {
121 + 27375 return !run_queue_is_empty(&server->run_queue);
122 + }
123 +
124 + 9180static int server_enqueue_run(struct server *server, struct run *run)
125 + {
126 + 9180 int ret = 0;
127 +
128 + 9180 ret = storage_run_create(&server->storage, run_get_url(run), run_get_rev(run));
129 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
130 + return ret;
131 + 9180 run_set_id(run, ret);
132 +
133 + 9180 ret = server_lock(server);
134 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
135 + return ret;
136 +
137 + 9180 run_queue_add_last(&server->run_queue, run);
138 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Added a new run %d for repository %s to the queue\n", run_get_id(run),
139 + run_get_url(run));
140 +
141 + 9180 server_notify(server);
142 + 9180 server_unlock(server);
143 + 9180 return ret;
144 + }
145 +
146 + 27404static int server_ready_for_action(const struct server *server)
147 + {
148 +
+ 6/6 +
+
✓ Branch 0 taken 27375 times.
+
✓ Branch 1 taken 29 times.
+
✓ Branch 3 taken 27169 times.
+
✓ Branch 4 taken 206 times.
+
✓ Branch 6 taken 9180 times.
+
✓ Branch 7 taken 17989 times.
+
+
+
27404 return server->stopping || (server_has_runs(server) && server_has_workers(server));
149 + }
150 +
151 + 9209static int server_wait_for_action(struct server *server)
152 + {
153 + 9209 int ret = 0;
154 +
155 +
+ 2/2 +
+
✓ Branch 1 taken 18195 times.
+
✓ Branch 2 taken 9209 times.
+
+
+
27404 while (!server_ready_for_action(server)) {
156 + 18195 ret = server_wait(server);
157 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 18195 times.
+
+
+
18195 if (ret < 0)
158 + return ret;
159 + }
160 +
161 + 9209 return ret;
162 + }
163 +
164 + 9180static void server_assign_run(struct server *server)
165 + {
166 + 9180 struct run *run = run_queue_remove_first(&server->run_queue);
167 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Removed run %d for repository %s from the queue\n", run_get_id(run), run_get_url(run));
168 +
169 + 9180 struct worker *worker = worker_queue_remove_first(&server->worker_queue);
170 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Removed worker %d from the queue\n", worker_get_fd(worker));
171 +
172 + 9180 struct jsonrpc_request *start_request = NULL;
173 + 9180 int ret = 0;
174 +
175 + 9180 ret = start_request_create(&start_request, run);
176 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
177 + goto exit;
178 +
179 + 9180 ret = jsonrpc_request_send(start_request, worker_get_fd(worker));
180 + 9180 jsonrpc_request_destroy(start_request);
181 +
+ 1/2 +
+
✓ Branch 0 taken 9180 times.
+
✗ Branch 1 not taken.
+
+
+
9180 if (ret < 0)
182 + goto exit;
183 +
184 + 9180exit:
185 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
186 + log("Failed to assign run for repository %s to worker %d, requeueing\n",
187 + run_get_url(run), worker_get_fd(worker));
188 + run_queue_add_first(&server->run_queue, run);
189 + } else {
190 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Assigned run %d for repository %s to worker %d\n", run_get_id(run),
191 + run_get_url(run), worker_get_fd(worker));
192 + 9180 run_destroy(run);
193 + }
194 +
195 + 9180 worker_destroy(worker);
196 + 9180}
197 +
198 + 29static void *server_main_thread(void *_server)
199 + {
200 + 29 struct server *server = (struct server *)_server;
201 + 29 int ret = 0;
202 +
203 + 29 ret = server_lock(server);
204 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
205 + goto exit;
206 +
207 + while (1) {
208 + 9209 ret = server_wait_for_action(server);
209 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9209 times.
+
+
+
9209 if (ret < 0)
210 + goto unlock;
211 +
212 +
+ 2/2 +
+
✓ Branch 0 taken 29 times.
+
✓ Branch 1 taken 9180 times.
+
+
+
9209 if (server->stopping)
213 + 29 goto unlock;
214 +
215 + 9180 server_assign_run(server);
216 + }
217 +
218 + 29unlock:
219 + 29 server_unlock(server);
220 +
221 + 29exit:
222 + 29 return NULL;
223 + }
224 +
225 + 9234static int server_handle_cmd_new_worker(UNUSED const struct jsonrpc_request *request,
226 + UNUSED struct jsonrpc_response **response, void *_ctx)
227 + {
228 + 9234 struct cmd_conn_ctx *ctx = (struct cmd_conn_ctx *)_ctx;
229 + 9234 struct server *server = (struct server *)ctx->arg;
230 + 9234 int ret = 0;
231 +
232 + 9234 ret = file_dup(ctx->fd);
233 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
234 + return ret;
235 +
236 + 9234 const int fd = ret;
237 + 9234 struct worker *worker = NULL;
238 +
239 + 9234 ret = worker_create(&worker, fd);
240 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
241 + goto close;
242 +
243 + 9234 ret = server_enqueue_worker(server, worker);
244 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
245 + goto destroy_worker;
246 +
247 + 9234 return ret;
248 +
249 + destroy_worker:
250 + worker_destroy(worker);
251 +
252 + close:
253 + net_close(fd);
254 +
255 + return ret;
256 + }
257 +
258 + 9180static int server_handle_cmd_run(const struct jsonrpc_request *request,
259 + struct jsonrpc_response **response, void *_ctx)
260 + {
261 + 9180 struct cmd_conn_ctx *ctx = (struct cmd_conn_ctx *)_ctx;
262 + 9180 struct server *server = (struct server *)ctx->arg;
263 + 9180 int ret = 0;
264 +
265 + 9180 struct run *run = NULL;
266 +
267 + 9180 ret = run_request_parse(request, &run);
268 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
269 + return ret;
270 +
271 + 9180 ret = jsonrpc_response_create(response, request, NULL);
272 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
273 + goto destroy_run;
274 +
275 + 9180 ret = server_enqueue_run(server, run);
276 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
277 + goto free_response;
278 +
279 + 9180 return ret;
280 +
281 + free_response:
282 + jsonrpc_response_destroy(*response);
283 + *response = NULL;
284 +
285 + destroy_run:
286 + run_destroy(run);
287 +
288 + return ret;
289 + }
290 +
291 + 9180static int server_handle_cmd_finished(const struct jsonrpc_request *request,
292 + UNUSED struct jsonrpc_response **response, void *_ctx)
293 + {
294 + 9180 struct cmd_conn_ctx *ctx = (struct cmd_conn_ctx *)_ctx;
295 + 9180 struct server *server = (struct server *)ctx->arg;
296 + 9180 int ret = 0;
297 +
298 + 9180 int run_id = 0;
299 + struct proc_output *output;
300 +
301 + 9180 ret = finished_request_parse(request, &run_id, &output);
302 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
303 + return ret;
304 +
305 + 9180 ret = storage_run_finished(&server->storage, run_id, output);
306 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
307 + log_err("Failed to mark run %d as finished\n", run_id);
308 + goto free_output;
309 + }
310 +
311 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9180 times.
+
+
+
9180 log("Marked run %d as finished\n", run_id);
312 +
313 + 9180free_output:
314 + 9180 proc_output_destroy(output);
315 +
316 + 9180 return ret;
317 + }
318 +
319 + static struct cmd_desc commands[] = {
320 + {CMD_NEW_WORKER, server_handle_cmd_new_worker},
321 + {CMD_RUN, server_handle_cmd_run},
322 + {CMD_FINISHED, server_handle_cmd_finished},
323 + };
324 +
325 + static const size_t numof_commands = sizeof(commands) / sizeof(commands[0]);
326 +
327 + 29int server_create(struct server **_server, const struct settings *settings)
328 + {
329 + struct storage_settings storage_settings;
330 + 29 int ret = 0;
331 +
332 + 29 struct server *server = malloc(sizeof(struct server));
333 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!server) {
334 + log_errno("malloc");
335 + return -1;
336 + }
337 +
338 + 29 ret = pthread_mutex_init(&server->server_mtx, NULL);
339 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret) {
340 + pthread_errno(ret, "pthread_mutex_init");
341 + goto free;
342 + }
343 +
344 + 29 ret = pthread_cond_init(&server->server_cv, NULL);
345 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret) {
346 + pthread_errno(ret, "pthread_cond_init");
347 + goto destroy_mtx;
348 + }
349 +
350 + 29 server->stopping = 0;
351 +
352 + 29 ret = cmd_dispatcher_create(&server->cmd_dispatcher, commands, numof_commands, server);
353 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
354 + goto destroy_cv;
355 +
356 + 29 ret = event_loop_create(&server->event_loop);
357 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
358 + goto destroy_cmd_dispatcher;
359 +
360 + 29 ret = signalfd_create_sigterms();
361 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
362 + goto destroy_event_loop;
363 + 29 server->signalfd = ret;
364 +
365 + 29 ret = event_loop_add(server->event_loop, server->signalfd, POLLIN, server_set_stopping,
366 + server);
367 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
368 + goto close_signalfd;
369 +
370 + 29 worker_queue_create(&server->worker_queue);
371 +
372 + 29 ret = storage_sqlite_settings_create(&storage_settings, settings->sqlite_path);
373 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
374 + goto destroy_worker_queue;
375 +
376 + 29 ret = storage_create(&server->storage, &storage_settings);
377 + 29 storage_settings_destroy(&storage_settings);
378 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
379 + goto destroy_worker_queue;
380 +
381 + 29 ret = storage_get_run_queue(&server->storage, &server->run_queue);
382 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
383 + goto destroy_storage;
384 +
385 + 29 ret = tcp_server_create(&server->tcp_server, server->event_loop, settings->port,
386 + 29 cmd_dispatcher_handle_conn, server->cmd_dispatcher);
387 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
388 + goto destroy_run_queue;
389 +
390 + 29 ret = pthread_create(&server->main_thread, NULL, server_main_thread, server);
391 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret) {
392 + pthread_errno(ret, "pthread_create");
393 + goto destroy_tcp_server;
394 + }
395 +
396 + 29 *_server = server;
397 + 29 return ret;
398 +
399 + destroy_tcp_server:
400 + tcp_server_destroy(server->tcp_server);
401 +
402 + destroy_run_queue:
403 + run_queue_destroy(&server->run_queue);
404 +
405 + destroy_storage:
406 + storage_destroy(&server->storage);
407 +
408 + destroy_worker_queue:
409 + worker_queue_destroy(&server->worker_queue);
410 +
411 + close_signalfd:
412 + signalfd_destroy(server->signalfd);
413 +
414 + destroy_event_loop:
415 + event_loop_destroy(server->event_loop);
416 +
417 + destroy_cmd_dispatcher:
418 + cmd_dispatcher_destroy(server->cmd_dispatcher);
419 +
420 + destroy_cv:
421 + pthread_errno_if(pthread_cond_destroy(&server->server_cv), "pthread_cond_destroy");
422 +
423 + destroy_mtx:
424 + pthread_errno_if(pthread_mutex_destroy(&server->server_mtx), "pthread_mutex_destroy");
425 +
426 + free:
427 + free(server);
428 +
429 + return ret;
430 + }
431 +
432 + 29void server_destroy(struct server *server)
433 + {
434 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
+
+
29 log("Shutting down\n");
435 +
436 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
29 pthread_errno_if(pthread_join(server->main_thread, NULL), "pthread_join");
437 + 29 tcp_server_destroy(server->tcp_server);
438 + 29 storage_destroy(&server->storage);
439 + 29 run_queue_destroy(&server->run_queue);
440 + 29 worker_queue_destroy(&server->worker_queue);
441 + 29 signalfd_destroy(server->signalfd);
442 + 29 event_loop_destroy(server->event_loop);
443 + 29 cmd_dispatcher_destroy(server->cmd_dispatcher);
444 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
29 pthread_errno_if(pthread_cond_destroy(&server->server_cv), "pthread_cond_destroy");
445 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
29 pthread_errno_if(pthread_mutex_destroy(&server->server_mtx), "pthread_mutex_destroy");
446 + 29 free(server);
447 + 29}
448 +
449 + 29static int server_listen_thread(struct server *server)
450 + {
451 + 29 int ret = 0;
452 +
453 +
+ 2/2 +
+
✓ Branch 0 taken 53910 times.
+
✓ Branch 1 taken 29 times.
+
+
+
53939 while (!server->stopping) {
454 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 53910 times.
+
+
+
53910 log("Waiting for new connections\n");
455 +
456 + 53910 ret = event_loop_run(server->event_loop);
457 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 53910 times.
+
+
+
53910 if (ret < 0)
458 + return ret;
459 + }
460 +
461 + 29 return 0;
462 + }
463 +
464 + 29int server_main(struct server *server)
465 + {
466 + 29 return server_listen_thread(server);
467 + }
468 +
+
+ +
+ + + + diff --git a/coverage/index.server_main.c.3ca591a47eaf0cc37ef7579efe6031fe.html b/coverage/index.server_main.c.3ca591a47eaf0cc37ef7579efe6031fe.html new file mode 100644 index 0000000..4b13f88 --- /dev/null +++ b/coverage/index.server_main.c.3ca591a47eaf0cc37ef7579efe6031fe.html @@ -0,0 +1,885 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/server_main.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:344379.1%
Branches:101471.4%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "cmd_line.h"
9 + #include "const.h"
10 + #include "log.h"
11 + #include "server.h"
12 +
13 + #include <getopt.h>
14 + #include <unistd.h>
15 +
16 + 35static struct settings default_settings(void)
17 + {
18 + 35 struct settings settings = {
19 + .port = default_port,
20 + .sqlite_path = default_sqlite_path,
21 + };
22 + 35 return settings;
23 + }
24 +
25 + 4const char *get_usage_string(void)
26 + {
27 + 4 return "[-h|--help] [-V|--version] [-v|--verbose] [-p|--port PORT] [-s|--sqlite PATH]";
28 + }
29 +
30 + 35static int parse_settings(struct settings *settings, int argc, char *argv[])
31 + {
32 + int opt, longind;
33 +
34 + 35 *settings = default_settings();
35 +
36 + /* clang-format off */
37 + static struct option long_options[] = {
38 + {"help", no_argument, 0, 'h'},
39 + {"version", no_argument, 0, 'V'},
40 + {"verbose", no_argument, 0, 'v'},
41 + {"port", required_argument, 0, 'p'},
42 + {"sqlite", required_argument, 0, 's'},
43 + {0, 0, 0, 0},
44 + };
45 + /* clang-format on */
46 +
47 +
+ 2/2 +
+
✓ Branch 1 taken 64 times.
+
✓ Branch 2 taken 29 times.
+
+
+
93 while ((opt = getopt_long(argc, argv, "hVvp:s:", long_options, &longind)) != -1) {
48 +
+ 5/6 +
+
✓ Branch 0 taken 2 times.
+
✓ Branch 1 taken 2 times.
+
✗ Branch 2 not taken.
+
✓ Branch 3 taken 29 times.
+
✓ Branch 4 taken 29 times.
+
✓ Branch 5 taken 2 times.
+
+
+
64 switch (opt) {
49 + 2 case 'h':
50 + 2 exit_with_usage(0);
51 + break;
52 + 2 case 'V':
53 + 2 exit_with_version();
54 + break;
55 + case 'v':
56 + g_log_lvl = LOG_LVL_DEBUG;
57 + break;
58 + 29 case 'p':
59 + 29 settings->port = optarg;
60 + 29 break;
61 + 29 case 's':
62 + 29 settings->sqlite_path = optarg;
63 + 29 break;
64 + 2 default:
65 + 2 exit_with_usage(1);
66 + break;
67 + }
68 + }
69 +
70 + 29 return 0;
71 + }
72 +
73 + 35int main(int argc, char *argv[])
74 + {
75 + struct settings settings;
76 + 35 struct server *server = NULL;
77 + 35 int ret = 0;
78 +
79 + 35 ret = parse_settings(&settings, argc, argv);
80 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
81 + return ret;
82 +
83 + 29 ret = server_create(&server, &settings);
84 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
85 + return ret;
86 +
87 + 29 ret = server_main(server);
88 +
+ 1/2 +
+
✓ Branch 0 taken 29 times.
+
✗ Branch 1 not taken.
+
+
+
29 if (ret < 0)
89 + goto destroy_server;
90 +
91 + 29destroy_server:
92 + 29 server_destroy(server);
93 +
94 + 29 return ret;
95 + }
96 +
+
+ +
+ + + + diff --git a/coverage/index.signal.c.71d63611c8a63e0778dd598afad76dfd.html b/coverage/index.signal.c.71d63611c8a63e0778dd598afad76dfd.html new file mode 100644 index 0000000..2473dad --- /dev/null +++ b/coverage/index.signal.c.71d63611c8a63e0778dd598afad76dfd.html @@ -0,0 +1,826 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/signal.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:313881.6%
Branches:51050.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "signal.h"
9 + #include "file.h"
10 + #include "log.h"
11 +
12 + #include <signal.h>
13 + #include <stddef.h>
14 + #include <sys/signalfd.h>
15 +
16 + static int sigterm_signals[] = {SIGINT, SIGTERM, SIGQUIT};
17 +
18 + 27677static void sigterms_mask(sigset_t *set)
19 + {
20 + 27677 sigemptyset(set);
21 +
+ 2/2 +
+
✓ Branch 0 taken 83031 times.
+
✓ Branch 1 taken 27677 times.
+
+
+
110708 for (size_t i = 0; i < sizeof(sigterm_signals) / sizeof(sigterm_signals[0]); ++i)
22 + 83031 sigaddset(set, sigterm_signals[i]);
23 + 27677}
24 +
25 + 82865static int signal_set_mask_internal(const sigset_t *new, sigset_t *old)
26 + {
27 + 82865 int ret = 0;
28 +
29 + 82865 ret = pthread_sigmask(SIG_SETMASK, new, old);
30 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 82865 times.
+
+
+
82865 if (ret) {
31 + pthread_errno(ret, "pthread_sigmask");
32 + return ret;
33 + }
34 +
35 + 82865 return ret;
36 + }
37 +
38 + 27594int signal_set_mask(const sigset_t *new)
39 + {
40 + 27594 return signal_set_mask_internal(new, NULL);
41 + }
42 +
43 + 27594int signal_block_all(sigset_t *old)
44 + {
45 + sigset_t new;
46 + 27594 sigfillset(&new);
47 + 27594 return signal_set_mask_internal(&new, old);
48 + }
49 +
50 + 27594int signal_block_sigterms(void)
51 + {
52 + sigset_t set;
53 + 27594 sigterms_mask(&set);
54 + 27594 return signal_set_mask_internal(&set, NULL);
55 + }
56 +
57 + 83int signalfd_create(const sigset_t *set)
58 + {
59 + static const int flags = SFD_CLOEXEC;
60 + sigset_t old;
61 + 83 int ret = 0;
62 +
63 + 83 ret = signal_set_mask_internal(set, &old);
64 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 83 times.
+
+
+
83 if (ret < 0)
65 + return ret;
66 +
67 + 83 ret = signalfd(-1, set, flags);
68 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 83 times.
+
+
+
83 if (ret < 0)
69 + goto restore;
70 +
71 + 83 return ret;
72 +
73 + restore:
74 + signal_set_mask_internal(&old, NULL);
75 +
76 + return ret;
77 + }
78 +
79 + 83int signalfd_create_sigterms(void)
80 + {
81 + sigset_t set;
82 + 83 sigterms_mask(&set);
83 + 83 return signalfd_create(&set);
84 + }
85 +
86 + 83void signalfd_destroy(int fd)
87 + {
88 + 83 file_close(fd);
89 + 83}
90 +
+
+ +
+ + + + diff --git a/coverage/index.sqlite.c.13cf77e7262c599539f10e3be0248b3e.html b/coverage/index.sqlite.c.13cf77e7262c599539f10e3be0248b3e.html new file mode 100644 index 0000000..ea46713 --- /dev/null +++ b/coverage/index.sqlite.c.13cf77e7262c599539f10e3be0248b3e.html @@ -0,0 +1,2719 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/sqlite.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:9016255.6%
Branches:199520.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "sqlite.h"
9 + #include "compiler.h"
10 + #include "log.h"
11 +
12 + #include <sqlite3.h>
13 +
14 + #include <stddef.h>
15 + #include <stdio.h>
16 + #include <stdlib.h>
17 + #include <string.h>
18 +
19 + #define sqlite_errno(var, fn) \
20 + do { \
21 + log_err("%s: %s\n", fn, sqlite3_errstr(var)); \
22 + var = -var; \
23 + } while (0)
24 +
25 + #define sqlite_errno_if(expr, fn) \
26 + do { \
27 + int CONCAT(ret, __LINE__) = expr; \
28 + if (CONCAT(ret, __LINE__)) \
29 + sqlite_errno(CONCAT(ret, __LINE__), fn); \
30 + } while (0)
31 +
32 + 29int sqlite_init(void)
33 + {
34 + 29 int ret = 0;
35 +
36 + 29 ret = sqlite3_initialize();
37 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret) {
38 + sqlite_errno(ret, "sqlite3_initialize");
39 + return ret;
40 + }
41 +
42 + 29 return ret;
43 + }
44 +
45 + 29void sqlite_destroy(void)
46 + {
47 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
29 sqlite_errno_if(sqlite3_shutdown(), "sqlite3_shutdown");
48 + 29}
49 +
50 + 29static int sqlite_open(const char *path, sqlite3 **db, int flags)
51 + {
52 + 29 int ret = 0;
53 +
54 + 29 ret = sqlite3_open_v2(path, db, flags, NULL);
55 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret) {
56 + sqlite_errno(ret, "sqlite3_open_v2");
57 + return ret;
58 + }
59 +
60 + 29 return ret;
61 + }
62 +
63 + 29int sqlite_open_rw(const char *path, sqlite3 **db)
64 + {
65 + static const int flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE;
66 + 29 return sqlite_open(path, db, flags);
67 + }
68 +
69 + int sqlite_open_ro(const char *path, sqlite3 **db)
70 + {
71 + static const int flags = SQLITE_OPEN_READONLY;
72 + return sqlite_open(path, db, flags);
73 + }
74 +
75 + 29void sqlite_close(sqlite3 *db)
76 + {
77 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
29 sqlite_errno_if(sqlite3_close(db), "sqlite3_close");
78 + 29}
79 +
80 + 58int sqlite_exec(sqlite3 *db, const char *stmt, sqlite3_callback callback, void *arg)
81 + {
82 + 58 int ret = 0;
83 +
84 + 58 ret = sqlite3_exec(db, stmt, callback, arg, NULL);
85 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 58 times.
+
+
+
58 if (ret) {
86 + sqlite_errno(ret, "sqlite3_exec");
87 + return ret;
88 + }
89 +
90 + 58 return ret;
91 + }
92 +
93 + int sqlite_exec_log_result(UNUSED void *arg, int numof_columns, char **values, char **column_names)
94 + {
95 + log("Row:\n");
96 + for (int i = 0; i < numof_columns; ++i) {
97 + log("\t%s: %s\n", column_names[i], values[i]);
98 + }
99 + return 0;
100 + }
101 +
102 + 174int sqlite_prepare(sqlite3 *db, const char *stmt, sqlite3_stmt **result)
103 + {
104 + 174 int ret = 0;
105 +
106 + 174 ret = sqlite3_prepare_v2(db, stmt, -1, result, NULL);
107 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 174 times.
+
+
+
174 if (ret) {
108 + sqlite_errno(ret, "sqlite3_prepare_v2");
109 + return ret;
110 + }
111 +
112 + 174 return ret;
113 + }
114 +
115 + 36720void sqlite_reset(sqlite3_stmt *stmt)
116 + {
117 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 36720 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
36720 sqlite_errno_if(sqlite3_reset(stmt), "sqlite3_reset");
118 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 36720 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
36720 sqlite_errno_if(sqlite3_clear_bindings(stmt), "sqlite3_clear_bindings");
119 + 36720}
120 +
121 + 174void sqlite_finalize(sqlite3_stmt *stmt)
122 + {
123 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 174 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
174 sqlite_errno_if(sqlite3_finalize(stmt), "sqlite3_finalize");
124 + 174}
125 +
126 + 36778int sqlite_step(sqlite3_stmt *stmt)
127 + {
128 + 36778 int ret = 0;
129 +
130 + 36778 ret = sqlite3_step(stmt);
131 +
132 +
+ 2/3 +
+
✓ Branch 0 taken 18389 times.
+
✓ Branch 1 taken 18389 times.
+
✗ Branch 2 not taken.
+
+
+
36778 switch (ret) {
133 + 18389 case SQLITE_ROW:
134 + 18389 return 1;
135 + 18389 case SQLITE_DONE:
136 + 18389 return 0;
137 +
138 + default:
139 + sqlite_errno(ret, "sqlite3_step");
140 + return ret;
141 + }
142 + }
143 +
144 + 18389int sqlite_column_int(sqlite3_stmt *stmt, int index)
145 + {
146 + 18389 return sqlite3_column_int(stmt, index);
147 + }
148 +
149 + int sqlite_column_text(sqlite3_stmt *stmt, int index, char **_result)
150 + {
151 + int ret = 0;
152 +
153 + const unsigned char *value = sqlite3_column_text(stmt, index);
154 + if (!value) {
155 + ret = sqlite3_errcode(sqlite3_db_handle(stmt));
156 + if (ret) {
157 + sqlite_errno(ret, "sqlite3_column_text");
158 + return ret;
159 + }
160 +
161 + *_result = NULL;
162 + return 0;
163 + }
164 +
165 + ret = sqlite3_column_bytes(stmt, index);
166 + size_t nb = (size_t)ret;
167 +
168 + char *result = calloc(nb + 1, 1);
169 + if (!result) {
170 + log_errno("calloc");
171 + return -1;
172 + }
173 + memcpy(result, value, nb);
174 +
175 + *_result = result;
176 + return 0;
177 + }
178 +
179 + int sqlite_column_blob(sqlite3_stmt *stmt, int index, unsigned char **_result)
180 + {
181 + int ret = 0;
182 +
183 + const unsigned char *value = sqlite3_column_blob(stmt, index);
184 + if (!value) {
185 + ret = sqlite3_errcode(sqlite3_db_handle(stmt));
186 + if (ret) {
187 + sqlite_errno(ret, "sqlite3_column_text");
188 + return ret;
189 + }
190 +
191 + *_result = NULL;
192 + return 0;
193 + }
194 +
195 + ret = sqlite3_column_bytes(stmt, index);
196 + size_t nb = (size_t)ret;
197 +
198 + unsigned char *result = malloc(nb);
199 + if (!result) {
200 + log_errno("malloc");
201 + return -1;
202 + }
203 + memcpy(result, value, nb);
204 +
205 + *_result = result;
206 + return 0;
207 + }
208 +
209 + 45929int sqlite_bind_int(sqlite3_stmt *stmt, int index, int value)
210 + {
211 + 45929 int ret = 0;
212 +
213 + 45929 ret = sqlite3_bind_int(stmt, index, value);
214 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 45929 times.
+
+
+
45929 if (ret) {
215 + sqlite_errno(ret, "sqlite3_bind_int");
216 + return ret;
217 + }
218 +
219 + 45929 return ret;
220 + }
221 +
222 + 27540int sqlite_bind_text(sqlite3_stmt *stmt, int index, const char *value)
223 + {
224 + 27540 int ret = 0;
225 +
226 + 27540 ret = sqlite3_bind_text(stmt, index, value, -1, SQLITE_STATIC);
227 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27540 times.
+
+
+
27540 if (ret) {
228 + sqlite_errno(ret, "sqlite3_bind_text");
229 + return ret;
230 + }
231 +
232 + 27540 return ret;
233 + }
234 +
235 + 9180int sqlite_bind_blob(sqlite3_stmt *stmt, int index, unsigned char *value, size_t nb)
236 + {
237 + 9180 int ret = 0;
238 +
239 + 9180 ret = sqlite3_bind_blob64(stmt, index, value, nb, SQLITE_STATIC);
240 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret) {
241 + sqlite_errno(ret, "sqlite3_bind_blob64");
242 + return ret;
243 + }
244 +
245 + 9180 return ret;
246 + }
247 +
248 + 29int sqlite_exec_as_transaction(sqlite3 *db, const char *stmt)
249 + {
250 + static const char *const fmt = "BEGIN; %s COMMIT;";
251 + 29 int ret = 0;
252 +
253 + 29 ret = snprintf(NULL, 0, fmt, stmt);
254 + 29 size_t nb = (size_t)ret + 1;
255 + 29 ret = 0;
256 +
257 + 29 char *full_stmt = malloc(nb);
258 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!full_stmt) {
259 + log_errno("malloc");
260 + return -1;
261 + }
262 + 29 snprintf(full_stmt, nb, fmt, stmt);
263 +
264 + 29 ret = sqlite_exec(db, stmt, NULL, NULL);
265 + 29 goto free;
266 +
267 + 29free:
268 + 29 free(full_stmt);
269 +
270 + 29 return ret;
271 + }
272 +
273 + 29int sqlite_get_user_version(sqlite3 *db, unsigned int *output)
274 + {
275 + static const char *const sql = "PRAGMA user_version;";
276 +
277 + 29 sqlite3_stmt *stmt = NULL;
278 + 29 int result = -1, ret = 0;
279 +
280 + 29 ret = sqlite_prepare(db, sql, &stmt);
281 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
282 + return ret;
283 + 29 ret = sqlite_step(stmt);
284 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
285 + goto finalize;
286 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!ret) {
287 + ret = -1;
288 + log_err("Failed to read database version\n");
289 + goto finalize;
290 + }
291 +
292 + 29 result = sqlite_column_int(stmt, 0);
293 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (result < 0) {
294 + log_err("Invalid database version: %d\n", result);
295 + ret = -1;
296 + goto finalize;
297 + }
298 + 29 *output = (unsigned int)result;
299 +
300 + 29 goto finalize;
301 +
302 + 29finalize:
303 + 29 sqlite_finalize(stmt);
304 +
305 + 29 return ret;
306 + }
307 +
308 + 29int sqlite_set_foreign_keys(sqlite3 *db)
309 + {
310 + static const char *const sql = "PRAGMA foreign_keys = ON;";
311 + 29 return sqlite_exec(db, sql, NULL, NULL);
312 + }
313 +
+
+ +
+ + + + diff --git a/coverage/index.storage.c.96d197609feea4b630e7b775fb18af81.html b/coverage/index.storage.c.96d197609feea4b630e7b775fb18af81.html new file mode 100644 index 0000000..3b71233 --- /dev/null +++ b/coverage/index.storage.c.96d197609feea4b630e7b775fb18af81.html @@ -0,0 +1,1070 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/storage.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:334475.0%
Branches:81844.4%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "storage.h"
9 + #include "log.h"
10 + #include "process.h"
11 + #include "run_queue.h"
12 + #include "storage_sqlite.h"
13 +
14 + #include <stddef.h>
15 +
16 + typedef void (*storage_settings_destroy_t)(const struct storage_settings *);
17 + typedef int (*storage_create_t)(struct storage *, const struct storage_settings *);
18 + typedef void (*storage_destroy_t)(struct storage *);
19 +
20 + typedef int (*storage_run_create_t)(struct storage *, const char *repo_url, const char *rev);
21 + typedef int (*storage_run_finished_t)(struct storage *, int repo_id, const struct proc_output *);
22 + typedef int (*storage_get_run_queue_t)(struct storage *, struct run_queue *);
23 +
24 + struct storage_api {
25 + storage_settings_destroy_t destroy_settings;
26 + storage_create_t create;
27 + storage_destroy_t destroy;
28 +
29 + storage_run_create_t run_create;
30 + storage_run_finished_t run_finished;
31 + storage_get_run_queue_t get_run_queue;
32 + };
33 +
34 + static const struct storage_api apis[] = {
35 + {
36 + storage_sqlite_settings_destroy,
37 + storage_sqlite_create,
38 + storage_sqlite_destroy,
39 +
40 + storage_sqlite_run_create,
41 + storage_sqlite_run_finished,
42 + storage_sqlite_get_run_queue,
43 + },
44 + };
45 +
46 + 18476static size_t numof_apis(void)
47 + {
48 + 18476 return sizeof(apis) / sizeof(apis[0]);
49 + }
50 +
51 + 18476static const struct storage_api *get_api(enum storage_type type)
52 + {
53 + if (type < 0)
54 + goto invalid_type;
55 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 18476 times.
+
+
+
18476 if ((size_t)type > numof_apis())
56 + goto invalid_type;
57 +
58 + 18476 return &apis[type];
59 +
60 + invalid_type:
61 + log_err("Unsupported storage type: %d\n", type);
62 + return NULL;
63 + }
64 +
65 + 29void storage_settings_destroy(const struct storage_settings *settings)
66 + {
67 + 29 const struct storage_api *api = get_api(settings->type);
68 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!api)
69 + return;
70 + 29 api->destroy_settings(settings);
71 + }
72 +
73 + 29int storage_create(struct storage *storage, const struct storage_settings *settings)
74 + {
75 + 29 int ret = 0;
76 + 29 const struct storage_api *api = get_api(settings->type);
77 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!api)
78 + return -1;
79 + 29 ret = api->create(storage, settings);
80 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
81 + return ret;
82 + 29 storage->type = settings->type;
83 + 29 return ret;
84 + }
85 +
86 + 29void storage_destroy(struct storage *storage)
87 + {
88 + 29 const struct storage_api *api = get_api(storage->type);
89 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!api)
90 + return;
91 + 29 api->destroy(storage);
92 + }
93 +
94 + 9180int storage_run_create(struct storage *storage, const char *repo_url, const char *rev)
95 + {
96 + 9180 const struct storage_api *api = get_api(storage->type);
97 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!api)
98 + return -1;
99 + 9180 return api->run_create(storage, repo_url, rev);
100 + }
101 +
102 + 9180int storage_run_finished(struct storage *storage, int run_id, const struct proc_output *output)
103 + {
104 + 9180 const struct storage_api *api = get_api(storage->type);
105 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!api)
106 + return -1;
107 + 9180 return api->run_finished(storage, run_id, output);
108 + }
109 +
110 + 29int storage_get_run_queue(struct storage *storage, struct run_queue *queue)
111 + {
112 + 29 const struct storage_api *api = get_api(storage->type);
113 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!api)
114 + return -1;
115 + 29 return api->get_run_queue(storage, queue);
116 + }
117 +
+
+ +
+ + + + diff --git a/coverage/index.storage_sqlite.c.b44f7f73d467be85cd4227a40c11d12a.html b/coverage/index.storage_sqlite.c.b44f7f73d467be85cd4227a40c11d12a.html new file mode 100644 index 0000000..fedfa60 --- /dev/null +++ b/coverage/index.storage_sqlite.c.b44f7f73d467be85cd4227a40c11d12a.html @@ -0,0 +1,4493 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/storage_sqlite.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:19730365.0%
Branches:5414637.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "storage_sqlite.h"
9 + #include "log.h"
10 + #include "process.h"
11 + #include "run_queue.h"
12 + #include "sql/sqlite_sql.h"
13 + #include "sqlite.h"
14 + #include "storage.h"
15 +
16 + #include <sqlite3.h>
17 +
18 + #include <pthread.h>
19 + #include <stdio.h>
20 + #include <stdlib.h>
21 + #include <string.h>
22 +
23 + struct storage_sqlite_settings {
24 + char *path;
25 + };
26 +
27 + 29int storage_sqlite_settings_create(struct storage_settings *settings, const char *path)
28 + {
29 + 29 struct storage_sqlite_settings *sqlite = malloc(sizeof(struct storage_sqlite_settings));
30 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!sqlite) {
31 + log_errno("malloc");
32 + return -1;
33 + }
34 +
35 + 29 sqlite->path = strdup(path);
36 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!sqlite->path) {
37 + log_errno("strdup");
38 + goto free;
39 + }
40 +
41 + 29 settings->type = STORAGE_TYPE_SQLITE;
42 + 29 settings->sqlite = sqlite;
43 + 29 return 0;
44 +
45 + free:
46 + free(sqlite);
47 +
48 + return -1;
49 + }
50 +
51 + 29void storage_sqlite_settings_destroy(const struct storage_settings *settings)
52 + {
53 + 29 free(settings->sqlite->path);
54 + 29 free(settings->sqlite);
55 + 29}
56 +
57 + enum run_status {
58 + RUN_STATUS_CREATED = 1,
59 + RUN_STATUS_FINISHED = 2,
60 + };
61 +
62 + struct prepared_stmt {
63 + pthread_mutex_t mtx;
64 + sqlite3_stmt *impl;
65 + };
66 +
67 + 116static int prepared_stmt_init(struct prepared_stmt *stmt, sqlite3 *db, const char *sql)
68 + {
69 + 116 int ret = 0;
70 +
71 + 116 ret = pthread_mutex_init(&stmt->mtx, NULL);
72 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 116 times.
+
+
+
116 if (ret) {
73 + pthread_errno(ret, "pthread_mutex_init");
74 + return ret;
75 + }
76 +
77 + 116 ret = sqlite_prepare(db, sql, &stmt->impl);
78 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 116 times.
+
+
+
116 if (ret < 0)
79 + goto destroy_mtx;
80 +
81 + 116 return ret;
82 +
83 + destroy_mtx:
84 + pthread_errno_if(pthread_mutex_destroy(&stmt->mtx), "pthread_mutex_destroy");
85 +
86 + return ret;
87 + }
88 +
89 + 116static void prepared_stmt_destroy(struct prepared_stmt *stmt)
90 + {
91 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 116 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
116 pthread_errno_if(pthread_mutex_destroy(&stmt->mtx), "pthread_mutex_destroy");
92 + 116 sqlite_finalize(stmt->impl);
93 + 116}
94 +
95 + 36720static int prepared_stmt_lock(struct prepared_stmt *stmt)
96 + {
97 + 36720 int ret = pthread_mutex_lock(&stmt->mtx);
98 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 36720 times.
+
+
+
36720 if (ret) {
99 + pthread_errno(ret, "pthread_mutex_unlock");
100 + return ret;
101 + }
102 + 36720 return ret;
103 + }
104 +
105 + 36720static void prepared_stmt_unlock(struct prepared_stmt *stmt)
106 + {
107 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 36720 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
36720 pthread_errno_if(pthread_mutex_unlock(&stmt->mtx), "pthread_mutex_unlock");
108 + 36720}
109 +
110 + struct storage_sqlite {
111 + sqlite3 *db;
112 +
113 + struct prepared_stmt stmt_repo_find;
114 + struct prepared_stmt stmt_repo_insert;
115 + struct prepared_stmt stmt_run_insert;
116 + struct prepared_stmt stmt_run_finished;
117 + };
118 +
119 + 29static int storage_sqlite_upgrade_to(struct storage_sqlite *storage, size_t version)
120 + {
121 + static const char *const fmt = "%s PRAGMA user_version = %zu;";
122 +
123 + 29 const char *script = sqlite_schemas[version];
124 + 29 int ret = 0;
125 +
126 + 29 ret = snprintf(NULL, 0, fmt, script, version + 1);
127 + 29 size_t nb = (size_t)ret + 1;
128 + 29 ret = 0;
129 +
130 + 29 char *full_script = malloc(nb);
131 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!full_script) {
132 + log_errno("malloc");
133 + return -1;
134 + }
135 + 29 snprintf(full_script, nb, fmt, script, version + 1);
136 +
137 + 29 ret = sqlite_exec_as_transaction(storage->db, full_script);
138 + 29 goto free;
139 +
140 + 29free:
141 + 29 free(full_script);
142 +
143 + 29 return ret;
144 + }
145 +
146 + 29static int storage_sqlite_upgrade_from_to(struct storage_sqlite *storage, size_t from, size_t to)
147 + {
148 + 29 int ret = 0;
149 +
150 +
+ 2/2 +
+
✓ Branch 0 taken 29 times.
+
✓ Branch 1 taken 29 times.
+
+
+
58 for (size_t i = from; i < to; ++i) {
151 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
+
+
29 log("Upgrading SQLite database from version %zu to version %zu\n", i, i + 1);
152 + 29 ret = storage_sqlite_upgrade_to(storage, i);
153 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0) {
154 + log_err("Failed to upgrade to version %zu\n", i + 1);
155 + return ret;
156 + }
157 + }
158 +
159 + 29 return ret;
160 + }
161 +
162 + 29static int storage_sqlite_upgrade(struct storage_sqlite *storage)
163 + {
164 + 29 unsigned int current_version = 0;
165 + 29 int ret = 0;
166 +
167 + 29 ret = sqlite_get_user_version(storage->db, &current_version);
168 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
169 + return ret;
170 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
+
+
29 log("SQLite database version: %u\n", current_version);
171 +
172 + 29 size_t newest_version = sizeof(sqlite_schemas) / sizeof(sqlite_schemas[0]);
173 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
+
+
29 log("Newest database version: %zu\n", newest_version);
174 +
175 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (current_version > newest_version) {
176 + log_err("Unknown database version: %u\n", current_version);
177 + return -1;
178 + }
179 +
180 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (current_version == newest_version) {
181 + log("SQLite database already at the newest version\n");
182 + return 0;
183 + }
184 +
185 + 29 return storage_sqlite_upgrade_from_to(storage, current_version, newest_version);
186 + }
187 +
188 + 29static int storage_sqlite_setup(struct storage_sqlite *storage)
189 + {
190 + 29 int ret = 0;
191 +
192 + 29 ret = sqlite_set_foreign_keys(storage->db);
193 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
194 + return ret;
195 +
196 + 29 ret = storage_sqlite_upgrade(storage);
197 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
198 + return ret;
199 +
200 + 29 return ret;
201 + }
202 +
203 + 29static int storage_sqlite_prepare_statements(struct storage_sqlite *storage)
204 + {
205 + static const char *const fmt_repo_find = "SELECT id FROM cimple_repos WHERE url = ?;";
206 + static const char *const fmt_repo_insert =
207 + "INSERT INTO cimple_repos(url) VALUES (?) ON CONFLICT(url) DO NOTHING;";
208 + static const char *const fmt_run_insert =
209 + "INSERT INTO cimple_runs(status, exit_code, output, repo_id, repo_rev) VALUES (?, -1, x'', ?, ?) RETURNING id;";
210 + static const char *const fmt_run_finished =
211 + "UPDATE cimple_runs SET status = ?, exit_code = ?, output = ? WHERE id = ?;";
212 +
213 + 29 int ret = 0;
214 +
215 + 29 ret = prepared_stmt_init(&storage->stmt_repo_find, storage->db, fmt_repo_find);
216 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
217 + return ret;
218 + 29 ret = prepared_stmt_init(&storage->stmt_repo_insert, storage->db, fmt_repo_insert);
219 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
220 + goto finalize_repo_find;
221 + 29 ret = prepared_stmt_init(&storage->stmt_run_insert, storage->db, fmt_run_insert);
222 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
223 + goto finalize_repo_insert;
224 + 29 ret = prepared_stmt_init(&storage->stmt_run_finished, storage->db, fmt_run_finished);
225 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
226 + goto finalize_run_insert;
227 +
228 + 29 return ret;
229 +
230 + finalize_run_insert:
231 + prepared_stmt_destroy(&storage->stmt_run_insert);
232 + finalize_repo_insert:
233 + prepared_stmt_destroy(&storage->stmt_repo_insert);
234 + finalize_repo_find:
235 + prepared_stmt_destroy(&storage->stmt_repo_find);
236 +
237 + return ret;
238 + }
239 +
240 + 29static void storage_sqlite_finalize_statements(struct storage_sqlite *storage)
241 + {
242 + 29 prepared_stmt_destroy(&storage->stmt_run_finished);
243 + 29 prepared_stmt_destroy(&storage->stmt_run_insert);
244 + 29 prepared_stmt_destroy(&storage->stmt_repo_insert);
245 + 29 prepared_stmt_destroy(&storage->stmt_repo_find);
246 + 29}
247 +
248 + 29int storage_sqlite_create(struct storage *storage, const struct storage_settings *settings)
249 + {
250 + 29 int ret = 0;
251 +
252 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 29 times.
+
+
+
29 log("Using SQLite database at %s\n", settings->sqlite->path);
253 +
254 + 29 struct storage_sqlite *sqlite = malloc(sizeof(struct storage_sqlite));
255 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!sqlite) {
256 + log_errno("malloc");
257 + return -1;
258 + }
259 +
260 + 29 ret = sqlite_init();
261 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
262 + goto free;
263 + 29 ret = sqlite_open_rw(settings->sqlite->path, &sqlite->db);
264 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
265 + goto destroy;
266 + 29 ret = storage_sqlite_setup(sqlite);
267 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
268 + goto close;
269 + 29 ret = storage_sqlite_prepare_statements(sqlite);
270 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
271 + goto close;
272 +
273 + 29 storage->sqlite = sqlite;
274 + 29 return ret;
275 +
276 + close:
277 + sqlite_close(storage->sqlite->db);
278 + destroy:
279 + sqlite_destroy();
280 + free:
281 + free(sqlite);
282 +
283 + return ret;
284 + }
285 +
286 + 29void storage_sqlite_destroy(struct storage *storage)
287 + {
288 + 29 storage_sqlite_finalize_statements(storage->sqlite);
289 + 29 sqlite_close(storage->sqlite->db);
290 + 29 sqlite_destroy();
291 + 29 free(storage->sqlite);
292 + 29}
293 +
294 + 9180static int storage_sqlite_find_repo(struct storage_sqlite *storage, const char *url)
295 + {
296 + 9180 struct prepared_stmt *stmt = &storage->stmt_repo_find;
297 + 9180 int ret = 0;
298 +
299 + 9180 ret = prepared_stmt_lock(stmt);
300 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
301 + return ret;
302 + 9180 ret = sqlite_bind_text(stmt->impl, 1, url);
303 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
304 + goto reset;
305 + 9180 ret = sqlite_step(stmt->impl);
306 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
307 + goto reset;
308 +
309 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!ret)
310 + goto reset;
311 +
312 + 9180 ret = sqlite_column_int(stmt->impl, 0);
313 + 9180 goto reset;
314 +
315 + 9180reset:
316 + 9180 sqlite_reset(stmt->impl);
317 + 9180 prepared_stmt_unlock(stmt);
318 +
319 + 9180 return ret;
320 + }
321 +
322 + 9180static int storage_sqlite_insert_repo(struct storage_sqlite *storage, const char *url)
323 + {
324 + 9180 struct prepared_stmt *stmt = &storage->stmt_repo_insert;
325 + 9180 int ret = 0;
326 +
327 + 9180 ret = prepared_stmt_lock(stmt);
328 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
329 + return ret;
330 + 9180 ret = sqlite_bind_text(stmt->impl, 1, url);
331 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
332 + goto reset;
333 + 9180 ret = sqlite_step(stmt->impl);
334 +
+ 1/2 +
+
✓ Branch 0 taken 9180 times.
+
✗ Branch 1 not taken.
+
+
+
9180 if (ret < 0)
335 + goto reset;
336 +
337 + 9180reset:
338 + 9180 sqlite_reset(stmt->impl);
339 + 9180 prepared_stmt_unlock(stmt);
340 +
341 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
342 + return ret;
343 +
344 + 9180 return storage_sqlite_find_repo(storage, url);
345 + }
346 +
347 + 9180static int storage_sqlite_insert_run(struct storage_sqlite *storage, int repo_id, const char *rev)
348 + {
349 + 9180 struct prepared_stmt *stmt = &storage->stmt_run_insert;
350 + 9180 int ret = 0;
351 +
352 + 9180 ret = prepared_stmt_lock(stmt);
353 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
354 + return ret;
355 + 9180 ret = sqlite_bind_int(stmt->impl, 1, RUN_STATUS_CREATED);
356 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
357 + goto reset;
358 + 9180 ret = sqlite_bind_int(stmt->impl, 2, repo_id);
359 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
360 + goto reset;
361 + 9180 ret = sqlite_bind_text(stmt->impl, 3, rev);
362 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
363 + goto reset;
364 + 9180 ret = sqlite_step(stmt->impl);
365 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
366 + goto reset;
367 +
368 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (!ret) {
369 + ret = -1;
370 + log_err("Failed to insert a run\n");
371 + goto reset;
372 + }
373 +
374 + 9180 ret = sqlite_column_int(stmt->impl, 0);
375 + 9180 goto reset;
376 +
377 + 9180reset:
378 + 9180 sqlite_reset(stmt->impl);
379 + 9180 prepared_stmt_unlock(stmt);
380 +
381 + 9180 return ret;
382 + }
383 +
384 + 9180int storage_sqlite_run_create(struct storage *storage, const char *repo_url, const char *rev)
385 + {
386 + 9180 int ret = 0;
387 +
388 + 9180 ret = storage_sqlite_insert_repo(storage->sqlite, repo_url);
389 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
390 + return ret;
391 +
392 + 9180 ret = storage_sqlite_insert_run(storage->sqlite, ret, rev);
393 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
394 + return ret;
395 +
396 + 9180 return ret;
397 + }
398 +
399 + 9180int storage_sqlite_run_finished(struct storage *storage, int run_id,
400 + const struct proc_output *output)
401 + {
402 + 9180 struct prepared_stmt *stmt = &storage->sqlite->stmt_run_finished;
403 + 9180 int ret = 0;
404 +
405 + 9180 ret = prepared_stmt_lock(stmt);
406 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
407 + return ret;
408 + 9180 ret = sqlite_bind_int(stmt->impl, 1, RUN_STATUS_FINISHED);
409 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
410 + goto reset;
411 + 9180 ret = sqlite_bind_int(stmt->impl, 2, output->ec);
412 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
413 + goto reset;
414 + 9180 ret = sqlite_bind_blob(stmt->impl, 3, output->data, output->data_size);
415 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
416 + goto reset;
417 + 9180 ret = sqlite_bind_int(stmt->impl, 4, run_id);
418 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
419 + goto reset;
420 + 9180 ret = sqlite_step(stmt->impl);
421 +
+ 1/2 +
+
✓ Branch 0 taken 9180 times.
+
✗ Branch 1 not taken.
+
+
+
9180 if (ret < 0)
422 + goto reset;
423 +
424 + 9180reset:
425 + 9180 sqlite_reset(stmt->impl);
426 + 9180 prepared_stmt_unlock(stmt);
427 +
428 + 9180 return ret;
429 + }
430 +
431 + static int storage_sqlite_row_to_run(struct sqlite3_stmt *stmt, struct run **run)
432 + {
433 + int ret = 0;
434 +
435 + int id = sqlite_column_int(stmt, 0);
436 +
437 + char *url = NULL;
438 + ret = sqlite_column_text(stmt, 1, &url);
439 + if (ret < 0)
440 + return ret;
441 +
442 + char *rev = NULL;
443 + ret = sqlite_column_text(stmt, 2, &rev);
444 + if (ret < 0)
445 + goto free_url;
446 +
447 + ret = run_create(run, id, url, rev);
448 + if (ret < 0)
449 + goto free_rev;
450 +
451 + log("Adding a run %d for repository %s to the queue\n", id, url);
452 +
453 + free_rev:
454 + free(rev);
455 +
456 + free_url:
457 + free(url);
458 +
459 + return ret;
460 + }
461 +
462 + 29int storage_sqlite_get_run_queue(struct storage *storage, struct run_queue *queue)
463 + {
464 + static const char *const fmt =
465 + "SELECT id, repo_url, repo_rev FROM cimple_runs_view WHERE status = ?;";
466 +
467 + sqlite3_stmt *stmt;
468 + 29 int ret = 0;
469 +
470 + 29 ret = sqlite_prepare(storage->sqlite->db, fmt, &stmt);
471 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
472 + return ret;
473 + 29 ret = sqlite_bind_int(stmt, 1, RUN_STATUS_CREATED);
474 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
475 + goto finalize;
476 +
477 + 29 run_queue_create(queue);
478 +
479 + while (1) {
480 + 29 ret = sqlite_step(stmt);
481 +
+ 1/2 +
+
✓ Branch 0 taken 29 times.
+
✗ Branch 1 not taken.
+
+
+
29 if (!ret)
482 + 29 break;
483 + if (ret < 0)
484 + goto run_queue_destroy;
485 +
486 + struct run *run = NULL;
487 +
488 + ret = storage_sqlite_row_to_run(stmt, &run);
489 + if (ret < 0)
490 + goto run_queue_destroy;
491 +
492 + run_queue_add_last(queue, run);
493 + }
494 +
495 + 29 goto finalize;
496 +
497 + run_queue_destroy:
498 + run_queue_destroy(queue);
499 +
500 + 29finalize:
501 + 29 sqlite_finalize(stmt);
502 +
503 + 29 return ret;
504 + }
505 +
+
+ +
+ + + + diff --git a/coverage/index.string.c.2a75186e465ffeac1b306a350f4a56f8.html b/coverage/index.string.c.2a75186e465ffeac1b306a350f4a56f8.html new file mode 100644 index 0000000..1e1eb9f --- /dev/null +++ b/coverage/index.string.c.2a75186e465ffeac1b306a350f4a56f8.html @@ -0,0 +1,515 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/string.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:62227.3%
Branches:31618.8%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "string.h"
9 + #include "log.h"
10 +
11 + #include <errno.h>
12 + #include <stdlib.h>
13 + #include <string.h>
14 +
15 + /* This is not provided by glibc; however, it does provide a possible
16 + * implementation in string_copying(7), which I copied from. */
17 + 326633char *stpecpy(char *dst, char *end, const char *src)
18 + {
19 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (!dst)
20 + return NULL;
21 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 326633 times.
+
+
+
326633 if (dst == end)
22 + return end;
23 +
24 + 326633 char *p = memccpy(dst, src, '\0', end - dst);
25 +
+ 1/2 +
+
✓ Branch 0 taken 326633 times.
+
✗ Branch 1 not taken.
+
+
+
326633 if (p)
26 + 326633 return p - 1;
27 +
28 + end[-1] = '\0';
29 + return end;
30 + }
31 +
32 + int string_to_int(const char *src, int *result)
33 + {
34 + char *endptr = NULL;
35 +
36 + errno = 0;
37 + long ret = strtol(src, &endptr, 10);
38 +
39 + if (errno) {
40 + log_errno("strtol");
41 + return -1;
42 + }
43 +
44 + if (endptr == src || *endptr != '\0') {
45 + log_err("Invalid number: %s\n", src);
46 + return -1;
47 + }
48 +
49 + *result = (int)ret;
50 + return 0;
51 + }
52 +
+
+ +
+ + + + diff --git a/coverage/index.tcp_server.c.68fbb5aebb39dbc263f5110d228c9b35.html b/coverage/index.tcp_server.c.68fbb5aebb39dbc263f5110d228c9b35.html new file mode 100644 index 0000000..f799489 --- /dev/null +++ b/coverage/index.tcp_server.c.68fbb5aebb39dbc263f5110d228c9b35.html @@ -0,0 +1,2532 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/tcp_server.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:8712271.3%
Branches:276640.9%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "tcp_server.h"
9 + #include "compiler.h"
10 + #include "event_loop.h"
11 + #include "file.h"
12 + #include "log.h"
13 + #include "net.h"
14 + #include "signal.h"
15 +
16 + #include <poll.h>
17 + #include <pthread.h>
18 + #include <signal.h>
19 + #include <stdlib.h>
20 + #include <sys/eventfd.h>
21 + #include <sys/queue.h>
22 + #include <unistd.h>
23 +
24 + /*
25 + * This is a simple threaded TCP server implementation. Each client is handled
26 + * in a separate thread.
27 + *
28 + * It used to be much simpler; basically, we have two types of client
29 + * connections: those made by cimple-worker and cimple-client respectively.
30 + * cimple-server would keep track of cimple-worker threads/connections, and
31 + * clean them up when assigning tasks/on shutdown.
32 + *
33 + * What about cimple-client connections though? I struggled to come up with a
34 + * scheme that would allow cimple-server to clean them up gracefully. When
35 + * would it do the cleanup even? I didn't want to do it on shutdown, since
36 + * there would be potentially a lot of them.
37 + *
38 + * One solution is to make client threads detached. This is a common advise;
39 + * I really don't understand the merit of this approach though. Client threads
40 + * actively work on shared data, take locks, etc. Data corruption is very
41 + * likely after the main thread exits and all the rest are killed.
42 + *
43 + * Another approach is pre-threading; we make a number of threads beforehand
44 + * and handle all client connections; I view this approach as limiting in
45 + * principle; probably that's foolish of me.
46 + *
47 + * Finally, I cannot bring myself to do non-blocking I/O. I honestly fear the
48 + * amount of work it would require to maintain read buffers, etc.
49 + *
50 + * So I came up with this convoluted scheme. The TCP server adds the listening
51 + * socket to the event loop, as before. Each client thread makes an eventfd
52 + * descriptor that it writes to when it's about to finish. The eventfd
53 + * descriptor is added to the event loop; once it's readable, we clean up the
54 + * client thread quickly from the main event loop thread. The TCP server itself
55 + * keeps track of client threads; on shutdown, it cleans up those still working.
56 + *
57 + * I'm _really_ not sure about this approach, it seems fishy as hell; I guess,
58 + * we'll see.
59 + */
60 +
61 + struct client {
62 + struct tcp_server *server;
63 + int conn_fd;
64 +
65 + int cleanup_fd;
66 +
67 + pid_t tid;
68 + pthread_t thread;
69 +
70 + SIMPLEQ_ENTRY(client) entries;
71 + };
72 +
73 + SIMPLEQ_HEAD(client_queue, client);
74 +
75 + struct tcp_server {
76 + struct event_loop *loop;
77 +
78 + tcp_server_conn_handler conn_handler;
79 + void *conn_handler_arg;
80 +
81 + struct client_queue client_queue;
82 +
83 + int accept_fd;
84 + };
85 +
86 + 27594static void client_destroy(struct client *client)
87 + {
88 +
+ 1/2 +
+
✓ Branch 1 taken 27594 times.
+
✗ Branch 2 not taken.
+
+
+
27594 log_debug("Cleaning up client thread %d\n", client->tid);
89 +
90 +
+ 8/8 +
+
✓ Branch 0 taken 14272 times.
+
✓ Branch 1 taken 13322 times.
+
✓ Branch 2 taken 4937 times.
+
✓ Branch 3 taken 9335 times.
+
✓ Branch 4 taken 11005 times.
+
✓ Branch 5 taken 13322 times.
+
✓ Branch 6 taken 7994 times.
+
✓ Branch 7 taken 5328 times.
+
+
+
38599 SIMPLEQ_REMOVE(&client->server->client_queue, client, client, entries);
91 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 27594 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
27594 pthread_errno_if(pthread_join(client->thread, NULL), "pthread_join");
92 + 27594 file_close(client->cleanup_fd);
93 + 27594 net_close(client->conn_fd);
94 + 27594 free(client);
95 + 27594}
96 +
97 + 27594static int client_destroy_handler(UNUSED struct event_loop *loop, UNUSED int fd,
98 + UNUSED short revents, void *_client)
99 + {
100 + 27594 struct client *client = (struct client *)_client;
101 +
+ 1/2 +
+
✓ Branch 1 taken 27594 times.
+
✗ Branch 2 not taken.
+
+
+
27594 log_debug("Client thread %d indicated that it's done\n", client->tid);
102 +
103 + 27594 client_destroy(client);
104 + 27594 return 0;
105 + }
106 +
107 + 27594static void *client_thread_func(void *_client)
108 + {
109 + 27594 struct client *client = (struct client *)_client;
110 + 27594 int ret = 0;
111 +
112 + 27594 client->tid = gettid();
113 +
+ 1/2 +
+
✓ Branch 1 taken 27594 times.
+
✗ Branch 2 not taken.
+
+
+
27594 log_debug("New client thread thread %d has started\n", client->tid);
114 +
115 + /* Let the client thread handle its signals except those that should be
116 + * handled in the main thread. */
117 + 27594 ret = signal_block_sigterms();
118 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret < 0)
119 + goto cleanup;
120 +
121 + 27594 ret = client->server->conn_handler(client->conn_fd, client->server->conn_handler_arg);
122 +
+ 1/2 +
+
✓ Branch 0 taken 27594 times.
+
✗ Branch 1 not taken.
+
+
+
27594 if (ret < 0)
123 + goto cleanup;
124 +
125 + 27594cleanup:
126 +
+ 1/4 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 27594 times.
+
✗ Branch 4 not taken.
+
✗ Branch 5 not taken.
+
+
+
27594 log_errno_if(eventfd_write(client->cleanup_fd, 1), "eventfd_write");
127 +
128 + 27594 return NULL;
129 + }
130 +
131 + 27594static int client_create_thread(struct client *client)
132 + {
133 + sigset_t old_mask;
134 + 27594 int ret = 0;
135 +
136 + /* Block all signals (we'll unblock them later); the client thread will
137 + * have all signals blocked initially. This allows the main thread to
138 + * handle SIGINT/SIGTERM/etc. */
139 + 27594 ret = signal_block_all(&old_mask);
140 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret < 0)
141 + return ret;
142 +
143 + 27594 ret = pthread_create(&client->thread, NULL, client_thread_func, client);
144 +
+ 1/2 +
+
✓ Branch 0 taken 27594 times.
+
✗ Branch 1 not taken.
+
+
+
27594 if (ret) {
145 + pthread_errno(ret, "pthread_create");
146 + goto restore_mask;
147 + }
148 +
149 + 27594restore_mask:
150 + /* Restore the previously-enabled signals for handling in the main thread. */
151 + 27594 signal_set_mask(&old_mask);
152 +
153 + 27594 return ret;
154 + }
155 +
156 + 27594static int client_create(struct tcp_server *server, int conn_fd)
157 + {
158 + 27594 int ret = 0;
159 +
160 + 27594 struct client *client = calloc(1, sizeof(struct client));
161 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (!client) {
162 + log_errno("calloc");
163 + return -1;
164 + }
165 +
166 + 27594 client->server = server;
167 + 27594 client->conn_fd = conn_fd;
168 +
169 + 27594 ret = eventfd(0, EFD_CLOEXEC);
170 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret < 0) {
171 + log_errno("eventfd");
172 + goto free;
173 + }
174 + 27594 client->cleanup_fd = ret;
175 +
176 + 27594 ret = event_loop_add_once(server->loop, client->cleanup_fd, POLLIN, client_destroy_handler,
177 + client);
178 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret < 0)
179 + goto close_cleanup_fd;
180 +
181 + 27594 SIMPLEQ_INSERT_TAIL(&server->client_queue, client, entries);
182 +
183 + 27594 ret = client_create_thread(client);
184 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret < 0)
185 + goto remove_from_client_queue;
186 +
187 + 27594 return ret;
188 +
189 + remove_from_client_queue:
190 + SIMPLEQ_REMOVE(&server->client_queue, client, client, entries);
191 +
192 + close_cleanup_fd:
193 + file_close(client->cleanup_fd);
194 +
195 + free:
196 + free(client);
197 +
198 + return ret;
199 + }
200 +
201 + 29static void client_queue_create(struct client_queue *client_queue)
202 + {
203 + 29 SIMPLEQ_INIT(client_queue);
204 + 29}
205 +
206 + 29static void client_queue_destroy(struct client_queue *client_queue)
207 + {
208 + 29 struct client *entry1 = SIMPLEQ_FIRST(client_queue);
209 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 while (entry1) {
210 + struct client *entry2 = SIMPLEQ_NEXT(entry1, entries);
211 + client_destroy(entry1);
212 + entry1 = entry2;
213 + }
214 + 29}
215 +
216 + 27594static int tcp_server_accept_handler(UNUSED struct event_loop *loop, UNUSED int fd,
217 + UNUSED short revents, void *_server)
218 + {
219 + 27594 struct tcp_server *server = (struct tcp_server *)_server;
220 + 27594 return tcp_server_accept(server);
221 + }
222 +
223 + 29int tcp_server_create(struct tcp_server **_server, struct event_loop *loop, const char *port,
224 + tcp_server_conn_handler conn_handler, void *conn_handler_arg)
225 + {
226 + 29 int ret = 0;
227 +
228 + 29 struct tcp_server *server = calloc(1, sizeof(struct tcp_server));
229 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (!server) {
230 + log_errno("calloc");
231 + return -1;
232 + }
233 +
234 + 29 server->loop = loop;
235 +
236 + 29 server->conn_handler = conn_handler;
237 + 29 server->conn_handler_arg = conn_handler_arg;
238 +
239 + 29 client_queue_create(&server->client_queue);
240 +
241 + 29 ret = net_bind(port);
242 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
243 + goto free;
244 + 29 server->accept_fd = ret;
245 +
246 + 29 ret = event_loop_add(loop, server->accept_fd, POLLIN, tcp_server_accept_handler, server);
247 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 29 times.
+
+
+
29 if (ret < 0)
248 + goto close;
249 +
250 + 29 *_server = server;
251 + 29 return ret;
252 +
253 + close:
254 + net_close(server->accept_fd);
255 + free:
256 + free(server);
257 +
258 + return ret;
259 + }
260 +
261 + 29void tcp_server_destroy(struct tcp_server *server)
262 + {
263 + 29 net_close(server->accept_fd);
264 + 29 client_queue_destroy(&server->client_queue);
265 + 29 free(server);
266 + 29}
267 +
268 + 27594int tcp_server_accept(struct tcp_server *server)
269 + {
270 + 27594 int conn_fd = -1, ret = 0;
271 +
272 + 27594 ret = net_accept(server->accept_fd);
273 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret < 0)
274 + return ret;
275 + 27594 conn_fd = ret;
276 +
277 + 27594 ret = client_create(server, conn_fd);
278 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 27594 times.
+
+
+
27594 if (ret < 0)
279 + goto close_conn;
280 +
281 + 27594 return ret;
282 +
283 + close_conn:
284 + net_close(conn_fd);
285 +
286 + return ret;
287 + }
288 +
+
+ +
+ + + + diff --git a/coverage/index.worker.c.4cbdfac39be7d0330fdfd94f65ce9ea9.html b/coverage/index.worker.c.4cbdfac39be7d0330fdfd94f65ce9ea9.html new file mode 100644 index 0000000..8bf5781 --- /dev/null +++ b/coverage/index.worker.c.4cbdfac39be7d0330fdfd94f65ce9ea9.html @@ -0,0 +1,2492 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/worker.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:10615170.2%
Branches:276243.5%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "worker.h"
9 + #include "ci.h"
10 + #include "command.h"
11 + #include "compiler.h"
12 + #include "const.h"
13 + #include "event_loop.h"
14 + #include "git.h"
15 + #include "log.h"
16 + #include "net.h"
17 + #include "process.h"
18 + #include "protocol.h"
19 + #include "run_queue.h"
20 + #include "signal.h"
21 +
22 + #include <poll.h>
23 + #include <stdlib.h>
24 + #include <string.h>
25 +
26 + struct worker {
27 + struct settings *settings;
28 +
29 + int stopping;
30 +
31 + struct cmd_dispatcher *cmd_dispatcher;
32 +
33 + struct event_loop *event_loop;
34 + int signalfd;
35 +
36 + struct run *run;
37 + };
38 +
39 + 54static struct settings *worker_settings_copy(const struct settings *src)
40 + {
41 + 54 struct settings *result = malloc(sizeof(*src));
42 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (!result) {
43 + log_errno("malloc");
44 + return NULL;
45 + }
46 +
47 + 54 result->host = strdup(src->host);
48 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (!result->host) {
49 + log_errno("strdup");
50 + goto free_result;
51 + }
52 +
53 + 54 result->port = strdup(src->port);
54 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (!result->port) {
55 + log_errno("strdup");
56 + goto free_host;
57 + }
58 +
59 + 54 return result;
60 +
61 + free_host:
62 + free((void *)result->host);
63 +
64 + free_result:
65 + free(result);
66 +
67 + return NULL;
68 + }
69 +
70 + 54static void worker_settings_destroy(struct settings *settings)
71 + {
72 + 54 free((void *)settings->port);
73 + 54 free((void *)settings->host);
74 + 54 free(settings);
75 + 54}
76 +
77 + 54static int worker_set_stopping(UNUSED struct event_loop *loop, UNUSED int fd, UNUSED short revents,
78 + void *_worker)
79 + {
80 + 54 struct worker *worker = (struct worker *)_worker;
81 + 54 worker->stopping = 1;
82 + 54 return 0;
83 + }
84 +
85 + 9180static int worker_handle_cmd_start(const struct jsonrpc_request *request,
86 + UNUSED struct jsonrpc_response **response, void *_ctx)
87 + {
88 + 9180 struct cmd_conn_ctx *ctx = (struct cmd_conn_ctx *)_ctx;
89 + 9180 struct worker *worker = (struct worker *)ctx->arg;
90 + 9180 int ret = 0;
91 +
92 + 9180 ret = start_request_parse(request, &worker->run);
93 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
94 + return ret;
95 +
96 + 9180 return ret;
97 + }
98 +
99 + static struct cmd_desc commands[] = {
100 + {CMD_START, worker_handle_cmd_start},
101 + };
102 +
103 + static const size_t numof_commands = sizeof(commands) / sizeof(commands[0]);
104 +
105 + 54int worker_create(struct worker **_worker, const struct settings *settings)
106 + {
107 + 54 int ret = 0;
108 +
109 + 54 struct worker *worker = malloc(sizeof(struct worker));
110 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (!worker) {
111 + log_errno("malloc");
112 + return -1;
113 + }
114 +
115 + 54 worker->settings = worker_settings_copy(settings);
116 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (!worker->settings) {
117 + ret = -1;
118 + goto free;
119 + }
120 +
121 + 54 worker->stopping = 0;
122 +
123 + 54 ret = cmd_dispatcher_create(&worker->cmd_dispatcher, commands, numof_commands, worker);
124 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (ret < 0)
125 + goto free_settings;
126 +
127 + 54 ret = event_loop_create(&worker->event_loop);
128 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (ret < 0)
129 + goto destroy_cmd_dispatcher;
130 +
131 + 54 ret = signalfd_create_sigterms();
132 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (ret < 0)
133 + goto destroy_event_loop;
134 + 54 worker->signalfd = ret;
135 +
136 + 54 ret = event_loop_add(worker->event_loop, worker->signalfd, POLLIN, worker_set_stopping,
137 + worker);
138 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (ret < 0)
139 + goto close_signalfd;
140 +
141 + 54 ret = libgit_init();
142 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (ret < 0)
143 + goto close_signalfd;
144 +
145 + 54 *_worker = worker;
146 + 54 return ret;
147 +
148 + close_signalfd:
149 + signalfd_destroy(worker->signalfd);
150 +
151 + destroy_event_loop:
152 + event_loop_destroy(worker->event_loop);
153 +
154 + destroy_cmd_dispatcher:
155 + cmd_dispatcher_destroy(worker->cmd_dispatcher);
156 +
157 + free_settings:
158 + worker_settings_destroy(worker->settings);
159 +
160 + free:
161 + free(worker);
162 +
163 + return ret;
164 + }
165 +
166 + 54void worker_destroy(struct worker *worker)
167 + {
168 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 54 times.
+
+
+
54 log("Shutting down\n");
169 +
170 + 54 libgit_shutdown();
171 + 54 signalfd_destroy(worker->signalfd);
172 + 54 event_loop_destroy(worker->event_loop);
173 + 54 cmd_dispatcher_destroy(worker->cmd_dispatcher);
174 + 54 worker_settings_destroy(worker->settings);
175 + 54 free(worker);
176 + 54}
177 +
178 + 9180static int worker_do_run(struct worker *worker)
179 + {
180 + 9180 int ret = 0;
181 +
182 + 9180 struct proc_output *result = NULL;
183 + 9180 ret = proc_output_create(&result);
184 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
185 + return ret;
186 +
187 + 9180 ret = ci_run_git_repo(run_get_url(worker->run), run_get_rev(worker->run), result);
188 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0) {
189 + log_err("Run failed with an error\n");
190 + goto free_output;
191 + }
192 +
193 + 9180 proc_output_dump(result);
194 +
195 + 9180 struct jsonrpc_request *finished_request = NULL;
196 +
197 + 9180 ret = finished_request_create(&finished_request, run_get_id(worker->run), result);
198 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
199 + goto free_output;
200 +
201 + 9180 ret = net_connect(worker->settings->host, worker->settings->port);
202 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
203 + goto free_request;
204 + 9180 int fd = ret;
205 +
206 + 9180 ret = jsonrpc_request_send(finished_request, fd);
207 +
+ 1/2 +
+
✓ Branch 0 taken 9180 times.
+
✗ Branch 1 not taken.
+
+
+
9180 if (ret < 0)
208 + goto close_conn;
209 +
210 + 9180close_conn:
211 + 9180 net_close(fd);
212 +
213 + 9180free_request:
214 + 9180 jsonrpc_request_destroy(finished_request);
215 +
216 + 9180free_output:
217 + 9180 proc_output_destroy(result);
218 +
219 + 9180 run_destroy(worker->run);
220 +
221 + 9180 return ret;
222 + }
223 +
224 + 9234static int worker_get_run(struct worker *worker)
225 + {
226 + 9234 int ret = 0, fd = -1;
227 +
228 + 9234 ret = net_connect(worker->settings->host, worker->settings->port);
229 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
230 + return ret;
231 + 9234 fd = ret;
232 +
233 + 9234 struct jsonrpc_request *new_worker_request = NULL;
234 + 9234 ret = new_worker_request_create(&new_worker_request);
235 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
236 + goto close;
237 +
238 + 9234 ret = jsonrpc_request_send(new_worker_request, fd);
239 + 9234 jsonrpc_request_destroy(new_worker_request);
240 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
241 + goto close;
242 +
243 + 9234 ret = event_loop_add_once(worker->event_loop, fd, POLLIN, cmd_dispatcher_handle_event,
244 + 9234 worker->cmd_dispatcher);
245 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
246 + goto close;
247 +
248 +
+ 1/2 +
+
✗ Branch 1 not taken.
+
✓ Branch 2 taken 9234 times.
+
+
+
9234 log("Waiting for a new command\n");
249 +
250 + 9234 ret = event_loop_run(worker->event_loop);
251 +
+ 1/2 +
+
✓ Branch 0 taken 9234 times.
+
✗ Branch 1 not taken.
+
+
+
9234 if (ret < 0)
252 + goto close;
253 +
254 + 9234close:
255 + 9234 net_close(fd);
256 +
257 + 9234 return ret;
258 + }
259 +
260 + 54int worker_main(struct worker *worker)
261 + {
262 + 54 int ret = 0;
263 +
264 + while (1) {
265 + 9234 ret = worker_get_run(worker);
266 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (ret < 0)
267 + return ret;
268 +
269 +
+ 2/2 +
+
✓ Branch 0 taken 54 times.
+
✓ Branch 1 taken 9180 times.
+
+
+
9234 if (worker->stopping)
270 + 54 break;
271 +
272 + 9180 ret = worker_do_run(worker);
273 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9180 times.
+
+
+
9180 if (ret < 0)
274 + return ret;
275 + }
276 +
277 + 54 return ret;
278 + }
279 +
+
+ +
+ + + + diff --git a/coverage/index.worker_main.c.3e96ea0429977547c8b5eee564591fe0.html b/coverage/index.worker_main.c.3e96ea0429977547c8b5eee564591fe0.html new file mode 100644 index 0000000..84c9372 --- /dev/null +++ b/coverage/index.worker_main.c.3e96ea0429977547c8b5eee564591fe0.html @@ -0,0 +1,885 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/worker_main.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:344379.1%
Branches:101471.4%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2022 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "cmd_line.h"
9 + #include "const.h"
10 + #include "log.h"
11 + #include "worker.h"
12 +
13 + #include <getopt.h>
14 + #include <unistd.h>
15 +
16 + 60static struct settings default_settings(void)
17 + {
18 + 60 struct settings settings = {
19 + .host = default_host,
20 + .port = default_port,
21 + };
22 + 60 return settings;
23 + }
24 +
25 + 4const char *get_usage_string(void)
26 + {
27 + 4 return "[-h|--help] [-V|--version] [-v|--verbose] [-H|--host HOST] [-p|--port PORT]";
28 + }
29 +
30 + 60static int parse_settings(struct settings *settings, int argc, char *argv[])
31 + {
32 + int opt, longind;
33 +
34 + 60 *settings = default_settings();
35 +
36 + /* clang-format off */
37 + static struct option long_options[] = {
38 + {"help", no_argument, 0, 'h'},
39 + {"version", no_argument, 0, 'V'},
40 + {"verbose", no_argument, 0, 'v'},
41 + {"host", required_argument, 0, 'H'},
42 + {"port", required_argument, 0, 'p'},
43 + {0, 0, 0, 0},
44 + };
45 + /* clang-format on */
46 +
47 +
+ 2/2 +
+
✓ Branch 1 taken 114 times.
+
✓ Branch 2 taken 54 times.
+
+
+
168 while ((opt = getopt_long(argc, argv, "hVvH:p:", long_options, &longind)) != -1) {
48 +
+ 5/6 +
+
✓ Branch 0 taken 2 times.
+
✓ Branch 1 taken 2 times.
+
✗ Branch 2 not taken.
+
✓ Branch 3 taken 54 times.
+
✓ Branch 4 taken 54 times.
+
✓ Branch 5 taken 2 times.
+
+
+
114 switch (opt) {
49 + 2 case 'h':
50 + 2 exit_with_usage(0);
51 + break;
52 + 2 case 'V':
53 + 2 exit_with_version();
54 + break;
55 + case 'v':
56 + g_log_lvl = LOG_LVL_DEBUG;
57 + break;
58 + 54 case 'H':
59 + 54 settings->host = optarg;
60 + 54 break;
61 + 54 case 'p':
62 + 54 settings->port = optarg;
63 + 54 break;
64 + 2 default:
65 + 2 exit_with_usage(1);
66 + break;
67 + }
68 + }
69 +
70 + 54 return 0;
71 + }
72 +
73 + 60int main(int argc, char *argv[])
74 + {
75 + struct settings settings;
76 + 60 struct worker *worker = NULL;
77 + 60 int ret = 0;
78 +
79 + 60 ret = parse_settings(&settings, argc, argv);
80 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (ret < 0)
81 + return ret;
82 +
83 + 54 ret = worker_create(&worker, &settings);
84 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 54 times.
+
+
+
54 if (ret < 0)
85 + return ret;
86 +
87 + 54 ret = worker_main(worker);
88 +
+ 1/2 +
+
✓ Branch 0 taken 54 times.
+
✗ Branch 1 not taken.
+
+
+
54 if (ret < 0)
89 + goto destroy_worker;
90 +
91 + 54destroy_worker:
92 + 54 worker_destroy(worker);
93 +
94 + 54 return ret;
95 + }
96 +
+
+ +
+ + + + diff --git a/coverage/index.worker_queue.c.aeb7258cd8f695c41a9aa8634701b38c.html b/coverage/index.worker_queue.c.aeb7258cd8f695c41a9aa8634701b38c.html new file mode 100644 index 0000000..a2dab67 --- /dev/null +++ b/coverage/index.worker_queue.c.aeb7258cd8f695c41a9aa8634701b38c.html @@ -0,0 +1,755 @@ + + + + + + GCC Code Coverage Report + + + + + +

GCC Code Coverage Report

+ +
+ +
+
+ + + + + + + + + + + + + +
Directory:src/
File:src/worker_queue.c
Date:2023-08-28 07:33:56
+
+
+ + + + + + + + + + + + + + + + + + + +
ExecTotalCoverage
Lines:323688.9%
Branches:51050.0%
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineBranchExecSource
1 + /*
2 + * Copyright (c) 2023 Egor Tensin <Egor.Tensin@gmail.com>
3 + * This file is part of the "cimple" project.
4 + * For details, see https://github.com/egor-tensin/cimple.
5 + * Distributed under the MIT License.
6 + */
7 +
8 + #include "worker_queue.h"
9 + #include "log.h"
10 + #include "net.h"
11 +
12 + #include <stdlib.h>
13 + #include <sys/queue.h>
14 +
15 + struct worker {
16 + int fd;
17 + SIMPLEQ_ENTRY(worker) entries;
18 + };
19 +
20 + 9234int worker_create(struct worker **_entry, int fd)
21 + {
22 + 9234 struct worker *entry = malloc(sizeof(struct worker));
23 +
+ 1/2 +
+
✗ Branch 0 not taken.
+
✓ Branch 1 taken 9234 times.
+
+
+
9234 if (!entry) {
24 + log_errno("malloc");
25 + return -1;
26 + }
27 +
28 + 9234 entry->fd = fd;
29 +
30 + 9234 *_entry = entry;
31 + 9234 return 0;
32 + }
33 +
34 + 9234void worker_destroy(struct worker *entry)
35 + {
36 + 9234 net_close(entry->fd);
37 + 9234 free(entry);
38 + 9234}
39 +
40 + 36774int worker_get_fd(const struct worker *entry)
41 + {
42 + 36774 return entry->fd;
43 + }
44 +
45 + 29void worker_queue_create(struct worker_queue *queue)
46 + {
47 + 29 SIMPLEQ_INIT(queue);
48 + 29}
49 +
50 + 29void worker_queue_destroy(struct worker_queue *queue)
51 + {
52 + 29 struct worker *entry1 = SIMPLEQ_FIRST(queue);
53 +
+ 2/2 +
+
✓ Branch 0 taken 54 times.
+
✓ Branch 1 taken 29 times.
+
+
+
83 while (entry1) {
54 + 54 struct worker *entry2 = SIMPLEQ_NEXT(entry1, entries);
55 + 54 worker_destroy(entry1);
56 + 54 entry1 = entry2;
57 + }
58 + 29 SIMPLEQ_INIT(queue);
59 + 29}
60 +
61 + 27169int worker_queue_is_empty(const struct worker_queue *queue)
62 + {
63 + 27169 return SIMPLEQ_EMPTY(queue);
64 + }
65 +
66 + void worker_queue_add_first(struct worker_queue *queue, struct worker *entry)
67 + {
68 + SIMPLEQ_INSERT_HEAD(queue, entry, entries);
69 + }
70 +
71 + 9234void worker_queue_add_last(struct worker_queue *queue, struct worker *entry)
72 + {
73 + 9234 SIMPLEQ_INSERT_TAIL(queue, entry, entries);
74 + 9234}
75 +
76 + 9180struct worker *worker_queue_remove_first(struct worker_queue *queue)
77 + {
78 + 9180 struct worker *entry = SIMPLEQ_FIRST(queue);
79 +
+ 2/2 +
+
✓ Branch 0 taken 9021 times.
+
✓ Branch 1 taken 159 times.
+
+
+
9180 SIMPLEQ_REMOVE_HEAD(queue, entries);
80 + 9180 return entry;
81 + }
82 +
+
+ +
+ + + + -- cgit v1.2.3