Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions builtin-functions/_functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1620,3 +1620,7 @@ class DateTimeImmutable implements DateTimeInterface {
}

function getenv(string $varname = '', bool $local_only = false): mixed;

//2022-04-19 comm644
function popen ($command ::: string, $mode ::: string) ::: mixed;
function pclose ($stream ::: mixed ) ::: bool;
6 changes: 6 additions & 0 deletions runtime/files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,11 @@ Optional<string> f$realpath(const string &path) {
}

static Optional<string> full_realpath(const string &path) { // realpath resolving only dirname to work with unexisted files

if (!strncmp(path.c_str(), "popen://", 8)) {
return path;
}

static char full_realpath_cache_storage[sizeof(array<string>)];
static array<string> *full_realpath_cache = reinterpret_cast <array<string> *> (full_realpath_cache_storage);
static long long full_realpath_last_query_num = -1;
Expand Down Expand Up @@ -939,3 +944,4 @@ void free_files_lib() {
dl::leave_critical_section();
}

#include "files_popen.cpp"
2 changes: 2 additions & 0 deletions runtime/files.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,5 @@ Optional<string> file_file_get_contents(const string &name);
void global_init_files_lib();

void free_files_lib();

#include "files_popen.h"
90 changes: 90 additions & 0 deletions runtime/files_popen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "streams.h"
#include "files_popen.h"

#include <stdio.h>
#include "runtime/string_functions.h"//php_buf, TODO

const string popen_wrapper_name("popen://", 8);

//2022-04-19 av
Stream f$popen(const string &command, const string &mode)
{
if (dl::query_num != opened_files_last_query_num) {
new(opened_files_storage) array<FILE *>();

opened_files_last_query_num = dl::query_num;
}
string fullname = popen_wrapper_name;
fullname.append( command );

printf("open: %s\n", fullname.c_str());
dl::enter_critical_section();//NOT OK: opened_files
FILE *file = popen(command.c_str(), mode.c_str());
if (file == nullptr) {
dl::leave_critical_section();
return false;
}

opened_files->set_value(fullname, file);
dl::leave_critical_section();

return fullname;
}

bool f$pclose(const Stream &stream) {

string filename = stream.to_string();
if (dl::query_num == opened_files_last_query_num && opened_files->has_key(filename)) {
dl::enter_critical_section();//NOT OK: opened_files
int result = pclose(opened_files->get_value(filename));
opened_files->unset(filename);
dl::leave_critical_section();
return (result == 0);
}
return false;
}

void global_init_popen_lib() {
static stream_functions file_stream_functions;

file_stream_functions.name = string("popen", 5);
file_stream_functions.fopen = f$popen;
file_stream_functions.fwrite = file_fwrite;
file_stream_functions.fseek = nullptr;;
file_stream_functions.ftell = nullptr;
file_stream_functions.fread = file_fread;
file_stream_functions.fgetc = file_fgetc;
file_stream_functions.fgets = file_fgets;
file_stream_functions.fpassthru = file_fpassthru;
file_stream_functions.fflush = file_fflush;
file_stream_functions.feof = file_feof;
file_stream_functions.fclose = f$pclose;

file_stream_functions.file_get_contents = file_file_get_contents;
file_stream_functions.file_put_contents = file_file_put_contents;

file_stream_functions.stream_socket_client = nullptr;
file_stream_functions.context_set_option = nullptr;
file_stream_functions.stream_set_option = nullptr;
file_stream_functions.get_fd = nullptr;

register_stream_functions(&file_stream_functions, false);
}


void free_popen_lib() {
dl::enter_critical_section();//OK
if (dl::query_num == opened_files_last_query_num) {
const array<FILE *> *const_opened_files = opened_files;
for (array<FILE *>::const_iterator p = const_opened_files->begin(); p != const_opened_files->end(); ++p) {
fclose(p.get_value());
}
opened_files_last_query_num--;
}

if (opened_fd != -1) {
close_safe(opened_fd);
}
opened_fd = -1;
dl::leave_critical_section();
}
13 changes: 13 additions & 0 deletions runtime/files_popen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include "runtime/kphp_core.h"

using Stream =mixed;

//2022-04-19 av (comm644)
Stream f$popen(const string &stream, const string &mode);
bool f$pclose(const Stream &stream);

void global_init_popen_lib();

void free_popen_lib();
1 change: 1 addition & 0 deletions runtime/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2389,6 +2389,7 @@ void global_init_runtime_libs() {
global_init_profiler();
global_init_instance_cache_lib();
global_init_files_lib();
global_init_popen_lib();
global_init_interface_lib();
global_init_openssl_lib();
global_init_regexp_lib();
Expand Down