This commit is contained in:
kento2 2026-09-04 19:59:24 +02:00
commit 55385f8857
69 changed files with 1125 additions and 0 deletions

10
fetcher/README Normal file
View file

@ -0,0 +1,10 @@
idea:
given a list of URL-to-path pairs, it downloads them in
parallel to the specified path.
implementation:
These pairs are added to a queue(FIFO) along with an
attempt counter. Multiple worker processes are spawned
that each handle an entry in a queue.
workers write to an error pipe and to a out pipe.

11
fetcher/a.txt Normal file
View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>lab 0x13</title>
</head>
<body>
<h1>welcome to the lab!</h1>
<p><a href="https://git.lab0x13.site/explore/repos">git</a></p>
<p><a href="intellij-colorscheme.icls">intellij colorscheme</a>
inspired by <a href="https://hank.bond/posts/highlighting-my-code-based-on-how-much-i-care/">this blog post</a></p>
</html>

5
fetcher/fetcher-worker.c Normal file
View file

@ -0,0 +1,5 @@
/*
* stdin serves as a queue in the form of
* URL outputDir
* where outputDir is the directory to save the downloaded
* file in.

60
fetcher/fetcher.c Normal file
View file

@ -0,0 +1,60 @@
#include <unistd.h>
#include <libowfat/errmsg.h>
#include <libowfat/buffer.h>
#include <sys/wait.h>
#include "fetcher.h"
#define dieusage() die(100, "usage: ", argv0, " [-v] [-j jobs] URL...\n\
(-v means verbose)")
int verbose = 0;
int jobs = 5;
int queuepipe[2];
/* merged stdout of workers */
int errpipe[2];
/* merged stderr of workers */
int outpipe[2];
int main(int argc, char **argv)
{
errmsg_iam(*argv);
int i;
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-') break;
if (argv[i][1] == '-' && !argv[i][2]) break;
switch (argv[i][1]) {
case 'j':
i++;
jobs = atoi(argv[i]);
if (jobs < 1)
die(100, "value for -n must be >= 1");
break;
case 'v':
verbose = 1;
break;
default: dieusage();
}
}
argc -= i;
argv += i;
if (argc < 1) dieusage();
if (pipe(errpipe)<0
|| pipe(outpipe)<0
) diesys(111, "pipe");
if (verbose) {
buffer_puts(buffer_2, "Using ");
buffer_putlong(buffer_2, jobs);
buffer_puts(buffer_2, " parallel jobs\n");
buffer_flush(buffer_2);
}
char **fetchcmd = (char *[]){"curl", "-o", "a.txt", "https://lab0x13.site/index.html", NULL};
pid_t pid = spawnchild(fetchcmd, outpipe[1], errpipe[1]);
if (pid<0)
exit(111);
waitpid(pid, NULL, 0);
exit(0);
}

13
fetcher/fetcher.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef FETCHER_H
#define FETCHER_H
#include <sys/types.h>
/*
* execs args[0] with args. output is connected to outfd
* and errfd.
* return: pid of child process or -1 on error.
*/
pid_t spawnchild(char **args, int outfd, int errfd);
#endif

26
fetcher/meson.build Normal file
View file

@ -0,0 +1,26 @@
project(
'fetcher', 'c',
default_options: [
'c_std=c99',
'warning_level=2',
],
)
cc = meson.get_compiler('c')
deps = [
cc.find_library('libowfat'),
dependency('libtoml'),
]
tmpdir = get_option('tmpdir')
add_project_arguments('-DTMPDIR="'+tmpdir+'"', language: 'c')
executable('fetcher', files(
'fetcher.c',
'spawnchild.c',
), dependencies:deps)
executable('fetcher-worker', files(
'fetcher-worker.c',
'spawnchild.c',
), dependencies:deps)

1
fetcher/meson.options Normal file
View file

@ -0,0 +1 @@
option('tmpdir', type : 'string', value : '/tmp', description : 'writable directory for temporary files')

41
fetcher/spawnchild.c Normal file
View file

@ -0,0 +1,41 @@
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <libowfat/errmsg.h>
#include <libowfat/buffer.h>
static void carpsysargs(char *args[])
{
buffer_puts(buffer_2, "failed to exec");
while (*args) {
buffer_puts(buffer_2, " \'");
buffer_puts(buffer_2, *args);
buffer_puts(buffer_2, "'");
args++;
}
buffer_puts(buffer_2, ": ");
buffer_puts(buffer_2, strerror(errno));
buffer_puts(buffer_2, "\n");
buffer_flush(buffer_2);
}
pid_t spawnchild(char *args[], int infd, int outfd, int errfd)
{
pid_t pid = fork();
switch (pid) {
case -1: carpsys("fork: "); return -1;
case 0:
// TODO pipe
if (dup2(1, outfd)<0
|| dup2(2, errfd)<0
) {
carpsys("dup2");
return -1;
}
execvp(args[0], args);
carpsysargs(args);
return -1;
default:
return pid;
}
}