File
Blob: src/workerd/tests/libreprl/libreprl.h
| 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. |
| 28 | const uint64_t REPRL_MAX_DATA_SIZE = 16 << 20; |
| 29 | |
| 30 | /// Opaque struct representing a REPRL execution context. |
| 31 | struct reprl_context; |
| 32 | |
| 33 | /// Allocates a new REPRL context. |
| 34 | /// @return an uninitialzed REPRL context |
| 35 | struct 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 |
| 47 | int 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 |
| 56 | void 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 |
| 72 | int 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. |
| 86 | static inline int RIFSIGNALED(int status) { |
| 87 | return (status & 0xff) != 0; |
| 88 | } |
| 89 | |
| 90 | /// Returns true if the execution terminated due to a timeout. |
| 91 | static inline int RIFTIMEDOUT(int status) { |
| 92 | return (status & 0xff0000) != 0; |
| 93 | } |
| 94 | |
| 95 | /// Returns true if the execution finished normally. |
| 96 | static inline int RIFEXITED(int status) { |
| 97 | return !RIFSIGNALED(status) && !RIFTIMEDOUT(status); |
| 98 | } |
| 99 | |
| 100 | /// Returns the terminating signal in case RIFSIGNALED is true. |
| 101 | static inline int RTERMSIG(int status) { |
| 102 | return status & 0xff; |
| 103 | } |
| 104 | |
| 105 | /// Returns the exit status in case RIFEXITED is true. |
| 106 | static 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 |
| 117 | const 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 |
| 126 | const 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 |
| 134 | const 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 |
| 142 | const char* reprl_get_last_error(struct reprl_context* ctx); |
| 143 | |
| 144 | #endif |