# HG changeset patch # User Paul Boddie # Date 1705601594 -3600 # Node ID b4e5ea9661c6e96b9dcf3f2c8c95dd37cc9192a3 # Parent e3d2ac731e491fbbd0bc6ad3a74f452d788a030b Allow programs to be initiated as jobs to be monitored and completed explicitly. diff -r e3d2ac731e49 -r b4e5ea9661c6 fsaccess/fsaccess.c --- a/fsaccess/fsaccess.c Wed Jan 17 18:56:05 2024 +0100 +++ b/fsaccess/fsaccess.c Thu Jan 18 19:13:14 2024 +0100 @@ -53,13 +53,16 @@ script Read operations from a script file (or stdin)\n\ Execution operations:\n\ \n\ + jobs Show initiated programs\n\ run Run a program from the filesystem\n\ + wait Wait for a program to finish\n\ "; /* Operations exposed by the program. */ struct operation operations[] = { {"copy-in", copy_in}, + {"jobs", show_programs}, {"ls", list_objects}, {"mkdir", make_dirs}, {"rm", remove_non_dirs}, @@ -67,6 +70,7 @@ {"run", run_program}, {"script", run_script}, {"stat", stat_objects}, + {"wait", wait_program}, {NULL, NULL}, }; diff -r e3d2ac731e49 -r b4e5ea9661c6 fsaccess/op_run.c --- a/fsaccess/op_run.c Wed Jan 17 18:56:05 2024 +0100 +++ b/fsaccess/op_run.c Thu Jan 18 19:13:14 2024 +0100 @@ -1,5 +1,5 @@ /* - * Run a program residing in the filesystem. + * Run programs residing in the filesystem. * * Copyright (C) 2022, 2023, 2024 Paul Boddie * @@ -27,6 +27,8 @@ #include #include +#include +#include #include "ops.h" @@ -38,15 +40,60 @@ +/* Initiated programs (jobs). + NOTE: Arbitrary limit. */ + +#define NUMBER_OF_JOBS 32 + +static file_t *readers[NUMBER_OF_JOBS] = {NULL}; +static process_t *processes[NUMBER_OF_JOBS] = {NULL}; +static const char *programs[NUMBER_OF_JOBS] = {NULL}; +static int next_job = 0; + + + +/* Wait for a program to finish, showing its output. */ + +static int _wait_program(file_t *reader, process_t *process) +{ + char buffer[TO_TRANSFER]; + notify_flags_t flags; + notify_values_t values; + long err; + + /* Read until the pipe yields no more data. */ + + while (1) + { + offset_t nread = client_read(reader, buffer, TO_TRANSFER); + + if (nread) + fwrite(buffer, sizeof(char), nread, stdout); + else + break; + } + + /* Close the pipe and obtain the process state. */ + + client_close(reader); + + err = process_wait(process, &flags, &values); + + printf("End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", flags, values.sig, values.val); + + if (err) + return -1; + + return values.val; +} + /* Run the given program. */ int run_program(int argc, char *argv[]) { - char buffer[TO_TRANSFER]; process_t *process; file_t *reader, *writer; - notify_flags_t flags; - notify_values_t values; + int last_job; long err; /* Create a pipe for process output. */ @@ -75,30 +122,71 @@ client_close(writer); - /* Read until the pipe yields no more data. */ + /* Record the output stream. */ - while (1) + last_job = next_job; + + while (readers[next_job] != NULL) { - offset_t nread = client_read(reader, buffer, TO_TRANSFER); + next_job++; + + if (next_job >= NUMBER_OF_JOBS) + next_job = 0; - if (nread) - fwrite(buffer, sizeof(char), nread, stdout); - else - break; + /* Wait for the process to complete if no more job slots are available. */ + + if (next_job == last_job) + return _wait_program(reader, process); } - /* Close the pipe and obtain the process state. */ + readers[next_job] = reader; + processes[next_job] = process; + programs[next_job] = strdup(argv[0]); + + return 0; +} - client_close(reader); +/* Show initiated programs. */ + +int show_programs(int argc, char *argv[]) +{ + (void) argc; (void) argv; + + int job_number; - err = process_wait(process, &flags, &values); + for (job_number = 0; job_number < NUMBER_OF_JOBS; job_number++) + { + if (readers[job_number] != NULL) + printf("[%d] %s\n", job_number, programs[job_number]); + } + + return 0; +} - printf("End process (flags %" pFMTnotify_flags "x values: %ld, %ld)\n", flags, values.sig, values.val); +/* Wait for the indicated program to finish, showing its output. */ - if (err) +int wait_program(int argc, char *argv[]) +{ + int job_number; + int exitcode; + + if (argc < 1) return -1; - return values.val; + job_number = atoi(argv[0]); + + if (readers[job_number] == NULL) + return -1; + + exitcode = _wait_program(readers[job_number], processes[job_number]); + + readers[job_number] = NULL; + processes[job_number] = NULL; + + free(programs[job_number]); + programs[job_number] = NULL; + + return exitcode; } /* vim: tabstop=2 expandtab shiftwidth=2 diff -r e3d2ac731e49 -r b4e5ea9661c6 fsaccess/ops.h --- a/fsaccess/ops.h Wed Jan 17 18:56:05 2024 +0100 +++ b/fsaccess/ops.h Thu Jan 18 19:13:14 2024 +0100 @@ -52,7 +52,9 @@ int remove_non_dirs(int argc, char *argv[]); int run_program(int argc, char *argv[]); int run_script(int argc, char *argv[]); +int show_programs(int argc, char *argv[]); int stat_objects(int argc, char *argv[]); +int wait_program(int argc, char *argv[]); /* vim: tabstop=4 expandtab shiftwidth=4 */