# HG changeset patch # User Paul Boddie # Date 1677620402 -3600 # Node ID fbac8f26ad0e6b3763e67b90533431b624dc36d6 # Parent d9b9ac497264fedcbb67e50adccf3cb97f74c64c Changed the process server to act as a plain Opener object, yielding a context through which program invocation details are communicated. Such details include program arguments which are now, once again, passed to the created process. When starting a process, only a collection of argument strings, this including the program filename, are now provided. This is to permit the indication of programs accessible to the process creator that are not necessarily resident in the filesystem of the initiating task. diff -r d9b9ac497264 -r fbac8f26ad0e libexec/include/exec/process_creator_context_resource.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libexec/include/exec/process_creator_context_resource.h Tue Feb 28 22:40:02 2023 +0100 @@ -0,0 +1,72 @@ +/* + * Support for creating a new process. + * + * Copyright (C) 2022, 2023 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#pragma once + +#include + +#include "process_creator_context_object_interface.h" + + + +/* Forward declaration. */ + +class ProcessCreatorResource; + + + +/* A process creating context employing a simple pager to transfer process + details. */ + +class ProcessCreatorContextResource : public SimplePager, + public ProcessCreatorContextObject +{ +protected: + ProcessCreatorResource *_creator; + +public: + explicit ProcessCreatorContextResource(ProcessCreatorResource *creator); + + virtual ~ProcessCreatorContextResource(); + + /* Server details. */ + + ipc_server_default_config_type config(); + + void *interface() + { return static_cast(this); } + + /* Process creator context interface methods. */ + + virtual long start(int argc, l4_cap_idx_t *process); + + /* Pager/dataspace methods. */ + + long map(offset_t offset, map_address_t hot_spot, map_flags_t flags, + l4_snd_fpage_t *region) + { return SimplePager::map(offset, hot_spot, flags, region); } + + long info(offset_t *size, map_flags_t *flags) + { return SimplePager::info(size, flags); } +}; + +/* vim: tabstop=2 expandtab shiftwidth=2 +*/ diff -r d9b9ac497264 -r fbac8f26ad0e libexec/include/exec/process_creator_resource.h --- a/libexec/include/exec/process_creator_resource.h Tue Feb 28 22:35:25 2023 +0100 +++ b/libexec/include/exec/process_creator_resource.h Tue Feb 28 22:40:02 2023 +0100 @@ -24,13 +24,13 @@ #include #include -#include "process_creator_interface.h" +#include "opener_interface.h" /* Process creator. */ -class ProcessCreatorResource : public Resource, public ProcessCreator +class ProcessCreatorResource : public Opener, public Resource { protected: ProcessCreating _creating; @@ -45,11 +45,15 @@ ipc_server_default_config_type config(); void *interface() - { return static_cast(this); } + { return static_cast(this); } /* Process creator interface methods. */ - virtual long start(l4_cap_idx_t program, l4_cap_idx_t *process); + virtual long start(int argc, const char *argv[], l4_cap_idx_t *process); + + /* Opener interface methods. */ + + virtual long context(l4_cap_idx_t *context); }; /* vim: tabstop=2 expandtab shiftwidth=2 diff -r d9b9ac497264 -r fbac8f26ad0e libexec/lib/src/Makefile --- a/libexec/lib/src/Makefile Tue Feb 28 22:35:25 2023 +0100 +++ b/libexec/lib/src/Makefile Tue Feb 28 22:40:02 2023 +0100 @@ -17,7 +17,7 @@ CLIENT_INTERFACES_CC = dataspace mapped_file notifier -SERVER_INTERFACES_CC = pager_object parent_pager_object process_creator +SERVER_INTERFACES_CC = opener pager_object parent_pager_object process_creator_context_object # Generated and plain source files. @@ -31,6 +31,7 @@ common.cc elf.cc external_pager.cc \ internal_pager.cc memory.cc pager.cc \ process.cc process_creating.cc \ + process_creator_context_resource.cc \ process_creator_resource.cc \ segment.cc stack.cc diff -r d9b9ac497264 -r fbac8f26ad0e libexec/lib/src/process_creator_context_resource.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libexec/lib/src/process_creator_context_resource.cc Tue Feb 28 22:40:02 2023 +0100 @@ -0,0 +1,76 @@ +/* + * A resource offering support for creating processes. + * + * Copyright (C) 2023 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include + +#include "process_creator_resource.h" +#include "process_creator_context_resource.h" +#include "process_creator_context_object_server.h" + +#include +#include + + + +/* Support for creating processes. */ + +ProcessCreatorContextResource::ProcessCreatorContextResource(ProcessCreatorResource *creator) +: SimplePager(), _creator(creator) +{ +} + +ProcessCreatorContextResource::~ProcessCreatorContextResource() +{ +} + +ipc_server_default_config_type ProcessCreatorContextResource::config() +{ + return config_ProcessCreatorContextObject; +} + + + +/* ProcessCreatorContext interface methods. */ + +long ProcessCreatorContextResource::start(int argc, l4_cap_idx_t *process) +{ + /* Obtain the arguments by reading from the shared memory. */ + + const char *argv[argc]; + offset_t pos = 0; + + for (int i = 0; i < argc; i++) + { + argv[i] = get_string(pos); + + if (argv[i] != NULL) + pos += strlen(argv[i]) + 1; + + printf("argv[%d] = %s\n", i, argv[i]); + } + + /* Start the new process, obtaining a reference to it. */ + + return _creator->start(argc, argv, process); +} + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r d9b9ac497264 -r fbac8f26ad0e libexec/lib/src/process_creator_resource.cc --- a/libexec/lib/src/process_creator_resource.cc Tue Feb 28 22:35:25 2023 +0100 +++ b/libexec/lib/src/process_creator_resource.cc Tue Feb 28 22:40:02 2023 +0100 @@ -19,14 +19,14 @@ * Boston, MA 02110-1301, USA */ +#include #include +#include "opener_server.h" #include "process_creating.h" +#include "process_creator_context_resource.h" #include "process_creator_resource.h" -#include "notifier_client.h" -#include "process_creator_server.h" - /* Support for creating processes. */ @@ -42,32 +42,32 @@ ipc_server_default_config_type ProcessCreatorResource::config() { - return config_ProcessCreator; + return config_Opener; } /* ProcessCreator interface methods. */ -long ProcessCreatorResource::start(l4_cap_idx_t program, l4_cap_idx_t *process) +long ProcessCreatorResource::start(int argc, const char *argv[], l4_cap_idx_t *process) { - file_t file; - - file_init(&file); - file.ref = program; - - /* Obtain a distinct and usable file object. */ - - file_t *program_file = client_reopen(&file, O_RDONLY); - - /* NOTE: To be replaced with the actual arguments, perhaps involving a - context object. */ - - const char *argv[] = {""}; + file_t *program_file = client_open(argv[0], O_RDONLY); /* Start the new process, obtaining a reference to it. */ - return _creating.start(program_file, 1, argv, process); + return _creating.start(program_file, argc, argv, process); +} + +/* Opener interface methods. */ + +long ProcessCreatorResource::context(l4_cap_idx_t *context) +{ + ProcessCreatorContextResource *resource = new ProcessCreatorContextResource(this); + + /* Complete the initialisation and start a server in a new thread. + If the thread does not start, the resource will be finalised. */ + + return ResourceServer(resource).start_thread(context); } // vim: tabstop=4 expandtab shiftwidth=4 diff -r d9b9ac497264 -r fbac8f26ad0e libfsclient/include/fsclient/process.h --- a/libfsclient/include/fsclient/process.h Tue Feb 28 22:35:25 2023 +0100 +++ b/libfsclient/include/fsclient/process.h Tue Feb 28 22:40:02 2023 +0100 @@ -58,7 +58,7 @@ process_t *process_new(); void process_init(process_t *process); -long process_start(process_t *process, file_t *file); +long process_start(process_t *process, int argc, char *argv[]); /* Notification support. */ diff -r d9b9ac497264 -r fbac8f26ad0e libfsclient/lib/src/Makefile --- a/libfsclient/lib/src/Makefile Tue Feb 28 22:35:25 2023 +0100 +++ b/libfsclient/lib/src/Makefile Tue Feb 28 22:40:02 2023 +0100 @@ -17,7 +17,7 @@ CLIENT_INTERFACES_CC = dataspace directory file filesystem flush \ mapped_file notifier notification opener \ - opener_context pipe pipe_opener process_creator + opener_context pipe pipe_opener process_creator_context # Generated and plain source files. diff -r d9b9ac497264 -r fbac8f26ad0e libfsclient/lib/src/process.cc --- a/libfsclient/lib/src/process.cc Tue Feb 28 22:35:25 2023 +0100 +++ b/libfsclient/lib/src/process.cc Tue Feb 28 22:40:02 2023 +0100 @@ -25,7 +25,7 @@ #include #include -#include "process_creator_client.h" +#include "process_creator_context_client.h" #include "file.h" #include "process.h" @@ -58,24 +58,47 @@ process->notifiable.base = (notifiable_base_t *) process; } -/* Start a process using the given file as payload. - NOTE: This does not yet communicate arguments or obtain input/output - pipes. */ +/* Start a process using the given arguments. + NOTE: This does not yet obtain input/output pipes. */ -long process_start(process_t *process, file_t *file) +long process_start(process_t *process, int argc, char *argv[]) { l4_cap_idx_t server = l4re_env_get_cap("pserver"); if (l4_is_invalid_cap(server)) return -L4_ENOMEM; - /* Obtain a client for the process creator. */ + /* Obtain a context for process creation. */ + + file_t context; + long err = file_context(&context, server); + + if (err) + return err; + + offset_t pos = 0, written; - client_ProcessCreator creator(server); + for (int i = 0; i < argc; i++) + { + if (!file_string_set(&context, argv[i], pos, &written)) + return -L4_ENOMEM; + + pos += written + 1; + } + + /* Obtain a client for the process creator context. */ + + client_ProcessCreatorContext creator(context.ref); /* Start the process, obtaining a reference to it. */ - return creator.start(file->ref, &process->ref); + err = creator.start(argc, &process->ref); + + /* Close the context, although a separate mechanism could permit contexts to + open several processes. */ + + file_close(&context); + return err; } diff -r d9b9ac497264 -r fbac8f26ad0e libsystypes/idl/opener.idl --- a/libsystypes/idl/opener.idl Tue Feb 28 22:35:25 2023 +0100 +++ b/libsystypes/idl/opener.idl Tue Feb 28 22:40:02 2023 +0100 @@ -1,5 +1,3 @@ -#include /* size_t */ - /* An interface providing a way of opening filesystem objects. */ interface Opener diff -r d9b9ac497264 -r fbac8f26ad0e libsystypes/idl/process_creator.idl --- a/libsystypes/idl/process_creator.idl Tue Feb 28 22:35:25 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -interface ProcessCreator -{ - /* Start a process, using the given file reference as the payload. */ - - [opcode(30)] void start(in cap program, out cap process); -}; diff -r d9b9ac497264 -r fbac8f26ad0e libsystypes/idl/process_creator_context.idl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libsystypes/idl/process_creator_context.idl Tue Feb 28 22:40:02 2023 +0100 @@ -0,0 +1,10 @@ +/* An interface providing a way of creating processes, relying on a dataspace to + transfer arguments to initialise each new process. */ + +interface ProcessCreatorContext +{ + /* Start a process, using the given argument count to refer to the process + arguments supplied via the dataspace, including the program itself. */ + + [opcode(30)] void start(in int argc, out cap process); +}; diff -r d9b9ac497264 -r fbac8f26ad0e libsystypes/idl/process_creator_context_object.idl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libsystypes/idl/process_creator_context_object.idl Tue Feb 28 22:40:02 2023 +0100 @@ -0,0 +1,4 @@ +import "dataspace.idl"; +import "process_creator_context.idl"; + +interface ProcessCreatorContextObject composes Dataspace, ProcessCreatorContext; diff -r d9b9ac497264 -r fbac8f26ad0e tests/dstest_exec.cc --- a/tests/dstest_exec.cc Tue Feb 28 22:35:25 2023 +0100 +++ b/tests/dstest_exec.cc Tue Feb 28 22:40:02 2023 +0100 @@ -23,9 +23,7 @@ #include #include -#include #include -#include #include #include @@ -42,26 +40,13 @@ return 1; } - char *program_filename = argv[1]; - - file_t *program_file = client_open(program_filename, O_RDONLY); - - if (!client_opened(program_file)) - { - printf("Could not open program file.\n"); - return 1; - } - /* Create a new process structure. */ process_t *process = process_new(); /* Start a process for the given program. */ - err = process_start(process, program_file); - - /* NOTE: Need to be able to send arguments, which would be sent via a context, - although capabilities could be sent via arguments. */ + err = process_start(process, argc - 1, argv + 1); if (err) {