reproc (Redirected Process) adalah pustaka C/C++ lintas platform yang menyederhanakan memulai, menghentikan, dan berkomunikasi dengan program eksternal. Kasus penggunaan utama adalah menjalankan aplikasi baris perintah langsung dari kode C atau C++ dan mengambil outputnya.
reproc terdiri dari dua perpustakaan: reproc dan reproc++. reproc adalah perpustakaan C99 yang berisi kode aktual untuk bekerja dengan program eksternal. reproc++ bergantung pada reproc dan mengadaptasi API-nya ke API C++11 idiomatis. Itu juga menambahkan beberapa tambahan yang menyederhanakan bekerja dengan program eksternal dari C++.
#include <reproc/run.h>
int main ( void )
{
const char * args [] = { "echo" , "Hello, world!" , NULL };
return reproc_run ( args , ( reproc_options ) { 0 });
}
Jika Anda memiliki pertanyaan setelah membaca readme dan dokumentasi, Anda dapat membuat masalah atau mengajukan pertanyaan langsung di saluran reproc gitter.
Catatan: Pembuatan ulang memerlukan CMake 3.12 atau lebih tinggi.
Ada beberapa cara untuk memasukkan reproc ke dalam proyek Anda. Salah satu caranya adalah dengan membangun reproc sebagai bagian dari proyek Anda menggunakan CMake. Untuk melakukan ini, pertama-tama kita harus memasukkan kode sumber reproc ke dalam proyek. Hal ini dapat dilakukan dengan menggunakan salah satu opsi berikut:
FetchContent
API untuk mengunduh reproc saat menjalankan CMake. Lihat https://cliutils.gitlab.io/modern-cmake/chapters/projects/fetch.html untuk contohnya.Setelah menyertakan kode sumber reproc dalam proyek Anda, kode tersebut dapat dibuat dari file root CMakeLists.txt sebagai berikut:
add_subdirectory (< path -to-reproc>) # For example: add_subdirectory(external/reproc)
Opsi CMake dapat ditentukan sebelum memanggil add_subdirectory
:
set (REPROC++ ON )
add_subdirectory (< path -to-reproc>)
Catatan: Jika opsi telah di-cache pada proses CMake sebelumnya, Anda harus menghapus cache CMake untuk menerapkan nilai default baru.
Untuk informasi selengkapnya tentang mengonfigurasi build reproc, lihat Opsi CMake.
Anda juga dapat bergantung pada versi reproc yang terinstal. Anda dapat membuat dan menginstal reproc sendiri atau menginstal reproc melalui manajer paket. reproc tersedia di repositori paket berikut:
Jika menggunakan manajer paket bukan suatu pilihan, Anda dapat membangun dan menginstal reproc dari sumber (CMake 3.13+):
cmake -B build
cmake --build build
cmake --install build
Aktifkan opsi REPROC_TEST
dan buat target test
untuk menjalankan pengujian (CMake 3.13+):
cmake -B build -DREPROC_TEST=ON
cmake --build build
cmake --build build --target test
Setelah menginstal reproc, sistem build Anda harus menemukannya. reproc menyediakan file konfigurasi CMake dan file pkg-config untuk menyederhanakan pencarian instalasi reproc menggunakan CMake dan pkg-config. Perhatikan bahwa reproc dan reproc++ adalah perpustakaan terpisah dan sebagai hasilnya memiliki file konfigurasi terpisah juga. Pastikan untuk mencari yang ingin Anda gunakan.
Untuk menemukan versi reproc yang terinstal menggunakan CMake:
find_package (reproc) # Find reproc.
find_package (reproc++) # Find reproc++.
Setelah membuat reproc sebagai bagian dari proyek Anda atau menemukan versi reproc yang terinstal, Anda dapat menautkannya dari dalam file CMakeLists.txt sebagai berikut:
target_link_libraries (myapp reproc) # Link against reproc.
target_link_libraries (myapp reproc++) # Link against reproc++.
Mulai Meson 0.53.2 dan seterusnya, reproc dapat disertakan sebagai subproyek CMake dalam skrip build Meson. Lihat https://mesonbuild.com/CMake-module.html untuk informasi lebih lanjut.
Secara default, reproc memiliki ketergantungan pada pthreads pada sistem POSIX ( -pthread
) dan ketergantungan pada Winsock 2.2 pada sistem Windows ( -lws2_32
). CMake dan pkg-config menangani dependensi ini secara otomatis.
build reproc dapat dikonfigurasi menggunakan opsi CMake berikut:
REPROC++
: Membangun reproc++ (default: ${REPROC_DEVELOP}
)
REPROC_TEST
: Tes pembuatan (default: ${REPROC_DEVELOP}
)
Jalankan pengujian dengan menjalankan biner test
yang dapat ditemukan di direktori build setelah membuat reproc.
REPROC_EXAMPLES
: Contoh pembuatan (default: ${REPROC_DEVELOP}
)
Biner yang dihasilkan akan ditempatkan di folder contoh setiap subdirektori proyek di direktori build setelah membuat reproc.
REPROC_OBJECT_LIBRARIES
: Membangun pustaka objek CMake (default: ${REPROC_DEVELOP}
)
Ini berguna untuk langsung menyertakan reproc di perpustakaan lain. Saat membuat reproc sebagai pustaka statis atau bersama, reproc harus dipasang bersama pustaka yang menggunakan sehingga membuat pendistribusian pustaka yang menggunakan lebih sulit. Saat menggunakan pustaka objek, file objek reproc disertakan langsung ke pustaka yang digunakan dan tidak diperlukan instalasi tambahan.
Catatan: pustaka objek reproc hanya akan tertaut dengan benar mulai CMake 3.14 dan seterusnya.
Catatan: Opsi ini menggantikan BUILD_SHARED_LIBS
.
REPROC_INSTALL
: Buat aturan instalasi (default: ON
kecuali REPROC_OBJECT_LIBRARIES
diaktifkan)
REPROC_INSTALL_CMAKECONFIGDIR
: Direktori instalasi file konfigurasi CMake (default: ${CMAKE_INSTALL_LIBDIR}/cmake
)
REPROC_INSTALL_PKGCONFIG
: Instal file pkg-config (default: ON
)
REPROC_INSTALL_PKGCONFIGDIR
: direktori instalasi file pkg-config (default: ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
REPROC_MULTITHREADED
: Gunakan pthread_sigmask
dan tautkan ke pustaka thread sistem (default: ON
)
REPROC_DEVELOP
: Konfigurasikan nilai default opsi untuk pengembangan (default: OFF
kecuali variabel lingkungan REPROC_DEVELOP
disetel)REPROC_SANITIZERS
: Dibuat dengan pembersih (default: ${REPROC_DEVELOP}
)REPROC_TIDY
: Jalankan clang-tidy saat membangun (default: ${REPROC_DEVELOP}
)REPROC_WARNINGS
: Aktifkan peringatan kompiler (default: ${REPROC_DEVELOP}
)REPROC_WARNINGS_AS_ERRORS
: Tambahkan -Werror atau setara dengan flag kompilasi dan clang-tidy (default: OFF
) Setiap fungsi dan kelas didokumentasikan secara ekstensif dalam file headernya. Contohnya dapat ditemukan di subdirektori contoh reproc dan reproc++.
Jika gagal, Sebagian besar fungsi di API reproc mengembalikan kode kesalahan gaya errno
negatif (POSIX) atau GetLastError
(Windows). Untuk kesalahan yang dapat ditindaklanjuti, reproc menyediakan konstanta ( REPROC_ETIMEDOUT
, REPROC_EPIPE
, ...) yang dapat digunakan untuk mencocokkan kesalahan tanpa harus menulis kode khusus platform. Untuk mendapatkan representasi string dari kesalahan, teruskan ke reproc_strerror
.
API reproc++ terintegrasi dengan mekanisme kode kesalahan perpustakaan standar C++ ( std::error_code
dan std::error_condition
). Sebagian besar metode di API reproc++ mengembalikan nilai std::error_code
yang berisi kesalahan sistem sebenarnya yang terjadi. Anda dapat menguji kode kesalahan ini menggunakan nilai dari std::errc
enum.
Lihat contoh untuk informasi selengkapnya tentang cara menangani kesalahan saat menggunakan reproc.
Catatan:
Baik API reproc maupun reproc++ menggunakan argumen options
yang dapat menentukan satu atau beberapa tindakan stop
seperti terminate
atau kill
. Oleh karena itu, jika proses anak dihentikan atau dihentikan menggunakan sinyal di POSIX, kode kesalahan tidak akan mencerminkan kesalahan.
Proyek hilir berhak menafsirkan kode status yang mencerminkan perilaku tak terduga di samping kode kesalahan (lihat contoh ini).
Jangan panggil operasi yang sama pada proses anak yang sama dari lebih dari satu thread secara bersamaan. Misalnya: membaca dan menulis ke proses anak dari thread berbeda tidak masalah, tetapi menunggu proses anak yang sama dari dua thread berbeda di waktu yang sama akan menimbulkan masalah.
(POSIX) Sangat disarankan untuk tidak memanggil waitpid
pada pids proses yang dimulai oleh reproc.
reproc menggunakan waitpid
untuk menunggu hingga suatu proses keluar. Sayangnya, waitpid
tidak bisa dipanggil dua kali pada proses yang sama. Artinya reproc_wait
tidak akan berfungsi dengan benar jika waitpid
telah dipanggil pada proses anak sebelumnya di luar reproc.
Sangat disarankan untuk memastikan setiap proses turunan benar-benar keluar menggunakan reproc_wait
atau reproc_stop
.
Di POSIX, proses anak yang telah keluar adalah proses zombie hingga proses induk menunggunya menggunakan waitpid
. Proses zombie memakan sumber daya dan dapat dianggap sebagai kebocoran sumber daya sehingga penting untuk memastikan semua proses keluar dengan benar dan tepat waktu.
Sangat disarankan untuk mencoba menghentikan proses anak dengan menunggu sampai keluar atau dengan menelepon reproc_terminate
sebelum beralih ke reproc_kill
.
Saat menggunakan reproc_kill
proses anak tidak mendapat kesempatan untuk melakukan pembersihan yang dapat mengakibatkan kebocoran sumber daya. Salah satu kebocoran yang paling utama adalah bahwa proses turunan tidak akan dapat menghentikan proses turunannya sendiri. Selalu mencoba untuk membiarkan proses anak keluar secara normal dengan memanggil reproc_terminate
sebelum memanggil reproc_kill
. reproc_stop
adalah fungsi pembantu praktis yang dapat digunakan untuk melakukan beberapa tindakan penghentian berturut-turut dengan batas waktu di antaranya.
(POSIX) Sangat disarankan untuk mengabaikan sinyal SIGPIPE
dalam proses induk.
Di POSIX, menulis ke pipa stdin tertutup dari proses anak akan menghentikan proses induk dengan sinyal SIGPIPE
secara default. Untuk menghindari hal ini, sinyal SIGPIPE
harus diabaikan dalam proses induk. Jika sinyal SIGPIPE
diabaikan, reproc_write
akan mengembalikan REPROC_EPIPE
seperti yang diharapkan saat menulis ke pipa stdin tertutup.
Meskipun reproc_terminate
mengizinkan proses anak untuk melakukan pembersihan, proses anak tersebut harus membersihkannya dengan benar. reproc hanya mengirimkan sinyal penghentian ke proses anak. Proses anak itu sendiri bertanggung jawab untuk membersihkan proses anak itu sendiri dan sumber daya lainnya.
(Windows) reproc_kill
tidak dijamin akan langsung menghentikan proses anak di Windows. Untuk informasi lebih lanjut, baca bagian Keterangan dalam dokumentasi fungsi Windows TerminateProcess
yang digunakan reproc untuk mematikan proses anak di Windows.
Proses anak yang dihasilkan melalui reproc mewarisi satu pegangan file tambahan yang digunakan untuk menunggu proses anak keluar. Jika proses anak menutup pegangan file ini secara manual, reproc akan salah mendeteksi proses anak telah keluar. Jika pegangan ini diwarisi lebih lanjut oleh proses lain yang hidup lebih lama dari proses anak, reproc akan mendeteksi proses anak masih berjalan meskipun sudah keluar. Jika data ditulis ke pegangan ini, reproc juga akan salah mendeteksi proses anak telah keluar.
(Windows) Tidak mungkin mendeteksi apakah proses anak menutup aliran stdout atau stderr sebelum keluar. Proses induk hanya akan diberitahu bahwa aliran keluaran proses anak ditutup setelah proses anak tersebut keluar.
Reproc (Windows) mengasumsikan bahwa Windows membuat soket yang dapat digunakan sebagai objek sistem file. Lebih khusus lagi, soket default yang dikembalikan oleh WSASocket
harus memiliki flag XP1_IFS_HANDLES
yang disetel. Hal ini mungkin tidak terjadi jika ada penyedia LSP eksternal yang diinstal pada mesin Windows. Jika hal ini terjadi, sebaiknya hapus perangkat lunak yang menyediakan penyedia layanan tambahan karena perangkat lunak tersebut sudah tidak digunakan lagi dan tidak boleh digunakan lagi (lihat https://docs.microsoft.com/en-us/windows/win32/winsock/ mengkategorikan-penyedia-layanan-dan-aplikasi-berlapis).