Skip to content
File

Blob: src/workerd/tests/libreprl/libreprl.h

cpp145 lines
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4// Copyright 2019 Google LLC
5//
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// https://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17 
18#ifndef LIBREPRL_H
19#define LIBREPRL_H
20 
21#include <limits.h>
22#include <stdint.h>
23 
24/// Maximum size for data transferred through REPRL. In particular, this is the
25/// maximum size of scripts that can be executed. Currently, this is 16MB.
26/// Executing a 16MB script file is very likely to take longer than the typical
27/// timeout, so the limit on script size shouldn't be a problem in practice.
28const uint64_t REPRL_MAX_DATA_SIZE = 16 << 20;
29 
30/// Opaque struct representing a REPRL execution context.
31struct reprl_context;
32 
33/// Allocates a new REPRL context.
34/// @return an uninitialzed REPRL context
35struct reprl_context* reprl_create_context();
36 
37/// Initializes a REPRL context.
38///
39/// @param ctx An uninitialized context
40/// @param argv The argv vector for the child processes
41/// @param envp The envp vector for the child processes
42/// @param capture_stdout Whether this REPRL context should capture the child's
43/// stdout
44/// @param capture_stderr Whether this REPRL context should capture the child's
45/// stderr
46/// @return zero in case of no errors, otherwise a negative value
47int reprl_initialize_context(struct reprl_context* ctx,
48 const char** argv,
49 const char** envp,
50 int capture_stdout,
51 int capture_stderr);
52 
53/// Destroys a REPRL context, freeing all resources held by it.
54///
55/// @param ctx The context to destroy
56void reprl_destroy_context(struct reprl_context* ctx);
57 
58/// Executes the provided script in the target process, wait for its completion,
59/// and return the result. If necessary, or if fresh_instance is true, this will
60/// automatically spawn a new instance of the target process.
61///
62/// @param ctx The REPRL context
63/// @param script The script to execute as utf-8 encoded data
64/// @param script_size Size of the script as number of bytes
65/// @param timeout The maximum allowed execution time in microseconds
66/// @param execution_time A pointer to which, if execution succeeds, the
67/// execution time in microseconds is written to
68/// @param fresh_instance if true, forces the creation of a new instance of the
69/// target
70/// @return A REPRL exit status (see below) or a negative number in case of an
71/// error
72int reprl_execute(struct reprl_context* ctx,
73 const char* script,
74 uint64_t script_size,
75 uint64_t timeout,
76 uint64_t* execution_time,
77 int fresh_instance);
78 
79/// Returns true if the execution terminated due to a signal.
80///
81/// The 32bit REPRL exit status as returned by reprl_execute has the following
82/// format:
83/// [ 00000000 | did_timeout | exit_code | terminating_signal ]
84/// Only one of did_timeout, exit_code, or terminating_signal may be set at one
85/// time.
86static inline int RIFSIGNALED(int status) {
87 return (status & 0xff) != 0;
88}
89 
90/// Returns true if the execution terminated due to a timeout.
91static inline int RIFTIMEDOUT(int status) {
92 return (status & 0xff0000) != 0;
93}
94 
95/// Returns true if the execution finished normally.
96static inline int RIFEXITED(int status) {
97 return !RIFSIGNALED(status) && !RIFTIMEDOUT(status);
98}
99 
100/// Returns the terminating signal in case RIFSIGNALED is true.
101static inline int RTERMSIG(int status) {
102 return status & 0xff;
103}
104 
105/// Returns the exit status in case RIFEXITED is true.
106static inline int REXITSTATUS(int status) {
107 return (status >> 8) & 0xff;
108}
109 
110/// Returns the stdout data of the last successful execution if the context is
111/// capturing stdout, otherwise an empty string. The output is limited to
112/// REPRL_MAX_DATA_SIZE (currently 16MB).
113///
114/// @param ctx The REPRL context
115/// @return A string pointer which is owned by the REPRL context and thus should
116/// not be freed by the caller
117const char* reprl_fetch_stdout(struct reprl_context* ctx);
118 
119/// Returns the stderr data of the last successful execution if the context is
120/// capturing stderr, otherwise an empty string. The output is limited to
121/// REPRL_MAX_DATA_SIZE (currently 16MB).
122///
123/// @param ctx The REPRL context
124/// @return A string pointer which is owned by the REPRL context and thus should
125/// not be freed by the caller
126const char* reprl_fetch_stderr(struct reprl_context* ctx);
127 
128/// Returns the fuzzout data of the last successful execution.
129/// The output is limited to REPRL_MAX_DATA_SIZE (currently 16MB).
130///
131/// @param ctx The REPRL context
132/// @return A string pointer which is owned by the REPRL context and thus should
133/// not be freed by the caller
134const char* reprl_fetch_fuzzout(struct reprl_context* ctx);
135 
136/// Returns a string describing the last error that occurred in the given
137/// context.
138///
139/// @param ctx The REPRL context
140/// @return A string pointer which is owned by the REPRL context and thus should
141/// not be freed by the caller
142const char* reprl_get_last_error(struct reprl_context* ctx);
143 
144#endif