Harden LinuxCNC wasm and native probe workflows
This commit is contained in:
58
core/wasm_shims/tooldata/tooldata.hh
Normal file
58
core/wasm_shims/tooldata/tooldata.hh
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "nml_intf/canon.hh"
|
||||
#include "nml_intf/emc_nml.hh"
|
||||
|
||||
extern "C" {
|
||||
|
||||
typedef enum {
|
||||
IDX_OK = 0,
|
||||
IDX_NEW,
|
||||
IDX_FAIL,
|
||||
} toolidx_t;
|
||||
|
||||
typedef enum {
|
||||
DB_NOTUSED = 0,
|
||||
DB_ACTIVE,
|
||||
} tooldb_t;
|
||||
|
||||
typedef enum {
|
||||
SPINDLE_LOAD,
|
||||
SPINDLE_UNLOAD,
|
||||
TOOL_OFFSET,
|
||||
} tool_notify_t;
|
||||
|
||||
struct CANON_TOOL_TABLE tooldata_entry_init(void);
|
||||
toolidx_t tooldata_put(struct CANON_TOOL_TABLE tdata, int idx);
|
||||
toolidx_t tooldata_get(CANON_TOOL_TABLE *pdata, int idx);
|
||||
|
||||
void tooldata_init(bool random_tool_changer);
|
||||
void tooldata_reset(void);
|
||||
void tooldata_last_index_set(int idx);
|
||||
int tooldata_last_index_get(void);
|
||||
int tooldata_find_index_for_tool(int toolno);
|
||||
|
||||
void tooldata_format_toolline(int idx,
|
||||
bool ignore_zero_values,
|
||||
CANON_TOOL_TABLE tdata,
|
||||
char formatted_line[CANON_TOOL_ENTRY_LEN]);
|
||||
|
||||
void tooldata_add_init(int nonrandom_start_idx);
|
||||
int tooldata_read_entry(const char *input_line);
|
||||
|
||||
void tooldata_set_db(tooldb_t mode);
|
||||
int tooldata_load(const char *filename);
|
||||
int tooldata_save(const char *filename);
|
||||
int tool_mmap_creator(EMC_TOOL_STAT const *ptr, int random_toolchanger);
|
||||
int tool_mmap_user(void);
|
||||
void tool_mmap_close(void);
|
||||
bool tool_mmap_is_random_toolchanger(void);
|
||||
int tool_nml_register(CANON_TOOL_TABLE *tblptr);
|
||||
int tooldata_db_init(char progname_plus_args[], int random_toolchanger);
|
||||
int tooldata_db_notify(tool_notify_t ntype,
|
||||
int toolno,
|
||||
int pocketno,
|
||||
CANON_TOOL_TABLE tdata);
|
||||
int tooldata_db_getall(void);
|
||||
|
||||
} // extern "C"
|
||||
101
core/wasm_shims/tooldata/tooldata_common_probe_main.cc
Normal file
101
core/wasm_shims/tooldata/tooldata_common_probe_main.cc
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "tooldata.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string make_temp_template(const char *name) {
|
||||
const char *tmpdir = std::getenv("TMPDIR");
|
||||
std::string tmpl = std::string(tmpdir ? tmpdir : "/tmp") + "/" + name;
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
if (tool_mmap_user() != -1) {
|
||||
return 11;
|
||||
}
|
||||
if (tool_mmap_creator(nullptr, 1) != 0) {
|
||||
return 12;
|
||||
}
|
||||
if (tool_mmap_user() != 0) {
|
||||
return 13;
|
||||
}
|
||||
if (!tool_mmap_is_random_toolchanger()) {
|
||||
return 14;
|
||||
}
|
||||
|
||||
tooldata_init(true);
|
||||
tooldata_reset();
|
||||
tooldata_add_init(0);
|
||||
|
||||
if (tooldata_read_entry("T7 P12 Z3.5 D8 ;probe\n") != 12) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
CANON_TOOL_TABLE loaded = tooldata_entry_init();
|
||||
if (tooldata_get(&loaded, 12) != IDX_OK) {
|
||||
return 2;
|
||||
}
|
||||
if (loaded.toolno != 7 || loaded.pocketno != 12 ||
|
||||
loaded.offset.tran.z != 3.5 || loaded.diameter != 8.0 ||
|
||||
std::strcmp(loaded.comment, "probe") != 0) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
char line[CANON_TOOL_ENTRY_LEN] = {};
|
||||
tooldata_format_toolline(12, true, loaded, line);
|
||||
if (!std::strstr(line, "T7") || !std::strstr(line, "P12") ||
|
||||
!std::strstr(line, "D+8.000000") || !std::strstr(line, ";probe")) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
std::string path_template = make_temp_template("cnc_tooldata_common_probe_XXXXXX");
|
||||
std::vector<char> path(path_template.begin(), path_template.end());
|
||||
path.push_back('\0');
|
||||
const int fd = mkstemp(path.data());
|
||||
if (fd < 0) {
|
||||
return 5;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (tooldata_save(path.data()) != 0) {
|
||||
std::remove(path.data());
|
||||
return 6;
|
||||
}
|
||||
|
||||
tooldata_reset();
|
||||
if (tooldata_find_index_for_tool(7) != -1) {
|
||||
std::remove(path.data());
|
||||
return 7;
|
||||
}
|
||||
if (tooldata_load(path.data()) != 0) {
|
||||
std::remove(path.data());
|
||||
return 8;
|
||||
}
|
||||
std::remove(path.data());
|
||||
|
||||
if (tooldata_get(&loaded, 12) != IDX_OK || loaded.toolno != 7 ||
|
||||
loaded.pocketno != 12 || loaded.offset.tran.z != 3.5 ||
|
||||
loaded.diameter != 8.0) {
|
||||
return 9;
|
||||
}
|
||||
|
||||
tooldata_set_db(DB_ACTIVE);
|
||||
if (tooldata_load(path.data()) != -1) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
tool_mmap_close();
|
||||
if (tool_mmap_user() != -1) {
|
||||
return 15;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
127
core/wasm_shims/tooldata/tooldata_mmap_backend.cc
Normal file
127
core/wasm_shims/tooldata/tooldata_mmap_backend.cc
Normal file
@@ -0,0 +1,127 @@
|
||||
#include "tooldata.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
|
||||
CANON_TOOL_TABLE tool_table[CANON_POCKETS_MAX];
|
||||
EMC_TOOL_STAT const *toolstat = nullptr;
|
||||
int last_index = 0;
|
||||
bool mmap_created = false;
|
||||
bool mmap_random_toolchanger = false;
|
||||
bool mmap_creator_called = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
toolidx_t tooldata_put(CANON_TOOL_TABLE tdata, int idx) {
|
||||
if (!mmap_created) {
|
||||
return IDX_FAIL;
|
||||
}
|
||||
if (idx < 0 || idx >= CANON_POCKETS_MAX) {
|
||||
return IDX_FAIL;
|
||||
}
|
||||
|
||||
const toolidx_t result = idx > last_index ? IDX_NEW : IDX_OK;
|
||||
tool_table[idx] = tdata;
|
||||
if (idx > last_index) {
|
||||
last_index = idx;
|
||||
}
|
||||
if (idx == 0 && toolstat) {
|
||||
*(CANON_TOOL_TABLE *)(&toolstat->toolTableCurrent) = tdata;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
toolidx_t tooldata_get(CANON_TOOL_TABLE *pdata, int idx) {
|
||||
if (!mmap_created) {
|
||||
std::fprintf(stderr, "%5d tooldata_get() not mmapped BYE\n", getpid());
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!pdata || idx < 0 || idx >= CANON_POCKETS_MAX) {
|
||||
return IDX_FAIL;
|
||||
}
|
||||
*pdata = tool_table[idx];
|
||||
return IDX_OK;
|
||||
}
|
||||
|
||||
void tooldata_reset(void) {
|
||||
if (!mmap_created) {
|
||||
return;
|
||||
}
|
||||
|
||||
const CANON_TOOL_TABLE empty = tooldata_entry_init();
|
||||
for (int idx = 0; idx < CANON_POCKETS_MAX; ++idx) {
|
||||
tool_table[idx] = empty;
|
||||
}
|
||||
}
|
||||
|
||||
void tooldata_last_index_set(int idx) {
|
||||
if (!mmap_created) {
|
||||
return;
|
||||
}
|
||||
if (idx < 0 || idx >= CANON_POCKETS_MAX) {
|
||||
idx = 0;
|
||||
}
|
||||
last_index = idx;
|
||||
}
|
||||
|
||||
int tooldata_last_index_get(void) {
|
||||
if (!mmap_created) {
|
||||
return -1;
|
||||
}
|
||||
return last_index;
|
||||
}
|
||||
|
||||
int tooldata_find_index_for_tool(int toolno) {
|
||||
if (!mmap_created || toolno == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (!mmap_random_toolchanger && toolno == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int found = -1;
|
||||
for (int idx = 0; idx <= last_index && idx < CANON_POCKETS_MAX; ++idx) {
|
||||
if (tool_table[idx].toolno == toolno) {
|
||||
found = idx;
|
||||
if (idx != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int tool_mmap_creator(EMC_TOOL_STAT const *ptr, int random_toolchanger) {
|
||||
if (mmap_creator_called) {
|
||||
std::fprintf(stderr, "Error: tool_mmap_creator already called BYE\n");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
toolstat = ptr;
|
||||
mmap_creator_called = true;
|
||||
mmap_created = true;
|
||||
mmap_random_toolchanger = random_toolchanger;
|
||||
last_index = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tool_mmap_user(void) {
|
||||
return mmap_created ? 0 : -1;
|
||||
}
|
||||
|
||||
void tool_mmap_close(void) {
|
||||
mmap_created = false;
|
||||
mmap_random_toolchanger = false;
|
||||
toolstat = nullptr;
|
||||
last_index = 0;
|
||||
}
|
||||
|
||||
bool tool_mmap_is_random_toolchanger(void) {
|
||||
return mmap_random_toolchanger;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
340
core/wasm_shims/tooldata/tooldata_probe_main.cc
Normal file
340
core/wasm_shims/tooldata/tooldata_probe_main.cc
Normal file
@@ -0,0 +1,340 @@
|
||||
#include "tooldata/tooldata.hh"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string make_temp_path(const char *name) {
|
||||
const char *tmpdir = std::getenv("TMPDIR");
|
||||
return std::string(tmpdir ? tmpdir : "/tmp") + "/" + name;
|
||||
}
|
||||
|
||||
class ScopedTempWorkdir {
|
||||
public:
|
||||
explicit ScopedTempWorkdir(const char *name_template) {
|
||||
cwd_fd_ = open(".", O_RDONLY);
|
||||
if (cwd_fd_ < 0) {
|
||||
return;
|
||||
}
|
||||
std::string path_template = make_temp_path(name_template);
|
||||
dir_buffer_.assign(path_template.begin(), path_template.end());
|
||||
dir_buffer_.push_back('\0');
|
||||
dir_ = mkdtemp(dir_buffer_.data());
|
||||
if (!dir_) {
|
||||
return;
|
||||
}
|
||||
if (chdir(dir_) != 0) {
|
||||
dir_ = nullptr;
|
||||
return;
|
||||
}
|
||||
ok_ = true;
|
||||
}
|
||||
|
||||
~ScopedTempWorkdir() {
|
||||
if (cwd_fd_ >= 0) {
|
||||
if (ok_) {
|
||||
fchdir(cwd_fd_);
|
||||
}
|
||||
close(cwd_fd_);
|
||||
}
|
||||
if (dir_) {
|
||||
rmdir(dir_);
|
||||
}
|
||||
}
|
||||
|
||||
bool ok() const {
|
||||
return ok_;
|
||||
}
|
||||
|
||||
private:
|
||||
int cwd_fd_ = -1;
|
||||
std::vector<char> dir_buffer_;
|
||||
char *dir_ = nullptr;
|
||||
bool ok_ = false;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
const pid_t creator_child = fork();
|
||||
if (creator_child < 0) {
|
||||
return 41;
|
||||
}
|
||||
if (creator_child == 0) {
|
||||
if (tool_mmap_creator(nullptr, 1) != 0) {
|
||||
_exit(42);
|
||||
}
|
||||
tool_mmap_creator(nullptr, 0);
|
||||
_exit(43);
|
||||
}
|
||||
int creator_status = 0;
|
||||
if (waitpid(creator_child, &creator_status, 0) != creator_child) {
|
||||
return 44;
|
||||
}
|
||||
if (!WIFEXITED(creator_status) || WEXITSTATUS(creator_status) == 0) {
|
||||
return 45;
|
||||
}
|
||||
|
||||
if (tool_mmap_user() != -1) {
|
||||
return 25;
|
||||
}
|
||||
CANON_TOOL_TABLE uncreated_tool = tooldata_entry_init();
|
||||
if (tooldata_put(uncreated_tool, 0) != IDX_FAIL) {
|
||||
return 27;
|
||||
}
|
||||
|
||||
const pid_t get_child = fork();
|
||||
if (get_child < 0) {
|
||||
return 46;
|
||||
}
|
||||
if (get_child == 0) {
|
||||
tooldata_get(&uncreated_tool, 0);
|
||||
_exit(47);
|
||||
}
|
||||
int get_status = 0;
|
||||
if (waitpid(get_child, &get_status, 0) != get_child) {
|
||||
return 48;
|
||||
}
|
||||
if (!WIFEXITED(get_status) || WEXITSTATUS(get_status) == 0) {
|
||||
return 38;
|
||||
}
|
||||
if (tooldata_last_index_get() != -1) {
|
||||
return 40;
|
||||
}
|
||||
if (tooldata_db_getall() != -1) {
|
||||
return 28;
|
||||
}
|
||||
std::string missing_db_program_with_arg_string =
|
||||
make_temp_path("cnc_tooldata_probe_missing_db_program arg");
|
||||
std::vector<char> missing_db_program_with_arg(
|
||||
missing_db_program_with_arg_string.begin(),
|
||||
missing_db_program_with_arg_string.end());
|
||||
missing_db_program_with_arg.push_back('\0');
|
||||
if (tooldata_db_init(missing_db_program_with_arg.data(), 1) != -1) {
|
||||
return 55;
|
||||
}
|
||||
const auto separator = missing_db_program_with_arg_string.find(' ');
|
||||
if (separator == std::string::npos || missing_db_program_with_arg[separator] != 0) {
|
||||
return 56;
|
||||
}
|
||||
std::string missing_db_program_string = make_temp_path("cnc_tooldata_probe_missing_db_program");
|
||||
std::vector<char> missing_db_program(
|
||||
missing_db_program_string.begin(),
|
||||
missing_db_program_string.end());
|
||||
missing_db_program.push_back('\0');
|
||||
if (tooldata_db_init(missing_db_program.data(), 1) != -1) {
|
||||
return 31;
|
||||
}
|
||||
char too_many_db_args[] = "/bin/true a b c d e f g h i";
|
||||
if (tooldata_db_init(too_many_db_args, 1) != -1) {
|
||||
return 32;
|
||||
}
|
||||
char non_db_program[] = "/bin/true";
|
||||
if (tooldata_db_init(non_db_program, 1) != -1) {
|
||||
return 33;
|
||||
}
|
||||
if (tool_nml_register(nullptr) != -1) {
|
||||
return 29;
|
||||
}
|
||||
alignas(EMC_TOOL_STAT) unsigned char toolstat_storage[sizeof(EMC_TOOL_STAT)] = {};
|
||||
auto *toolstat = reinterpret_cast<EMC_TOOL_STAT *>(toolstat_storage);
|
||||
if (tool_mmap_creator(toolstat, 1) != 0) {
|
||||
return 15;
|
||||
}
|
||||
if (tool_mmap_user() != 0) {
|
||||
return 26;
|
||||
}
|
||||
if (!tool_mmap_is_random_toolchanger()) {
|
||||
return 16;
|
||||
}
|
||||
tooldata_set_db(DB_ACTIVE);
|
||||
const std::string unavailable_db_path = make_temp_path("cnc_tooldata_probe_db_unavailable.tbl");
|
||||
if (tooldata_load(unavailable_db_path.c_str()) != -1) {
|
||||
return 30;
|
||||
}
|
||||
tooldata_set_db(DB_ACTIVE);
|
||||
tooldata_init(false);
|
||||
if (tooldata_save(nullptr) != 0) {
|
||||
return 34;
|
||||
}
|
||||
tooldata_set_db(DB_NOTUSED);
|
||||
tooldata_init(true);
|
||||
tooldata_reset();
|
||||
|
||||
CANON_TOOL_TABLE spindle = tooldata_entry_init();
|
||||
spindle.toolno = 0;
|
||||
spindle.pocketno = 0;
|
||||
if (tooldata_put(spindle, 0) != IDX_OK) {
|
||||
return 1;
|
||||
}
|
||||
if (toolstat->toolTableCurrent.toolno != 0 || toolstat->toolTableCurrent.pocketno != 0) {
|
||||
return 49;
|
||||
}
|
||||
|
||||
CANON_TOOL_TABLE tool = tooldata_entry_init();
|
||||
tool.toolno = 7;
|
||||
tool.pocketno = 12;
|
||||
tool.offset.tran.z = 3.5;
|
||||
tool.diameter = 8.0;
|
||||
std::strncpy(tool.comment, "probe", CANON_TOOL_COMMENT_SIZE - 1);
|
||||
if (tooldata_put(tool, 12) != IDX_NEW) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
CANON_TOOL_TABLE loaded = tooldata_entry_init();
|
||||
if (tooldata_get(&loaded, 12) != IDX_OK) {
|
||||
return 3;
|
||||
}
|
||||
if (loaded.toolno != 7 || loaded.pocketno != 12 || loaded.offset.tran.z != 3.5 || loaded.diameter != 8.0) {
|
||||
return 4;
|
||||
}
|
||||
char db_spindle_line[CANON_TOOL_ENTRY_LEN] = {};
|
||||
{
|
||||
ScopedTempWorkdir db_spindle_workdir("cnc_tooldata_probe_workdir.XXXXXX");
|
||||
if (!db_spindle_workdir.ok()) {
|
||||
return 35;
|
||||
}
|
||||
std::remove("./db_spindle.tbl");
|
||||
tooldata_set_db(DB_ACTIVE);
|
||||
if (tooldata_save(nullptr) != 0) {
|
||||
return 36;
|
||||
}
|
||||
FILE *db_spindle_fp = std::fopen("./db_spindle.tbl", "r");
|
||||
if (!db_spindle_fp) {
|
||||
return 37;
|
||||
}
|
||||
std::fread(db_spindle_line, 1, sizeof(db_spindle_line) - 1, db_spindle_fp);
|
||||
std::fclose(db_spindle_fp);
|
||||
std::remove("./db_spindle.tbl");
|
||||
tooldata_set_db(DB_NOTUSED);
|
||||
}
|
||||
if (!std::strstr(db_spindle_line, "T0") || std::strstr(db_spindle_line, "T7")) {
|
||||
return 38;
|
||||
}
|
||||
if (tooldata_find_index_for_tool(7) != 12) {
|
||||
return 5;
|
||||
}
|
||||
if (tooldata_find_index_for_tool(0) != 0) {
|
||||
return 6;
|
||||
}
|
||||
if (tooldata_find_index_for_tool(-1) != -1) {
|
||||
return 17;
|
||||
}
|
||||
|
||||
tooldata_init(false);
|
||||
if (tooldata_find_index_for_tool(0) != 0) {
|
||||
return 18;
|
||||
}
|
||||
tooldata_init(true);
|
||||
|
||||
tooldata_last_index_set(12);
|
||||
if (tooldata_last_index_get() != 12) {
|
||||
return 7;
|
||||
}
|
||||
if (tooldata_put(tool, -1) != IDX_FAIL) {
|
||||
return 50;
|
||||
}
|
||||
if (tooldata_put(tool, CANON_POCKETS_MAX) != IDX_FAIL) {
|
||||
return 51;
|
||||
}
|
||||
if (tooldata_last_index_get() != 12) {
|
||||
return 52;
|
||||
}
|
||||
if (tooldata_get(&loaded, -1) != IDX_FAIL) {
|
||||
return 53;
|
||||
}
|
||||
if (tooldata_get(&loaded, CANON_POCKETS_MAX) != IDX_FAIL) {
|
||||
return 54;
|
||||
}
|
||||
tooldata_last_index_set(CANON_POCKETS_MAX);
|
||||
if (tooldata_last_index_get() != 0) {
|
||||
return 24;
|
||||
}
|
||||
tooldata_last_index_set(12);
|
||||
|
||||
char line[CANON_TOOL_ENTRY_LEN] = {};
|
||||
tooldata_format_toolline(12, true, loaded, line);
|
||||
if (!std::strstr(line, "T7") || !std::strstr(line, "P12") || !std::strstr(line, "D+8.000000")) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
std::string path_template = make_temp_path("cnc_tooldata_probe_XXXXXX");
|
||||
std::vector<char> path(path_template.begin(), path_template.end());
|
||||
path.push_back('\0');
|
||||
const int fd = mkstemp(path.data());
|
||||
if (fd < 0) {
|
||||
return 9;
|
||||
}
|
||||
close(fd);
|
||||
tooldata_last_index_set(0);
|
||||
if (tooldata_save(path.data()) != 0) {
|
||||
std::remove(path.data());
|
||||
return 10;
|
||||
}
|
||||
|
||||
tooldata_reset();
|
||||
if (tooldata_find_index_for_tool(7) != -1) {
|
||||
std::remove(path.data());
|
||||
return 11;
|
||||
}
|
||||
if (tooldata_load(path.data()) != 0) {
|
||||
std::remove(path.data());
|
||||
return 12;
|
||||
}
|
||||
std::remove(path.data());
|
||||
|
||||
CANON_TOOL_TABLE reloaded = tooldata_entry_init();
|
||||
if (tooldata_get(&reloaded, 12) != IDX_OK) {
|
||||
return 13;
|
||||
}
|
||||
if (reloaded.toolno != 7 || reloaded.pocketno != 12 ||
|
||||
reloaded.offset.tran.z != 3.5 || reloaded.diameter != 8.0) {
|
||||
return 14;
|
||||
}
|
||||
|
||||
tooldata_init(false);
|
||||
std::string nonrandom_path_template = make_temp_path("cnc_tooldata_nonrandom_probe_XXXXXX");
|
||||
std::vector<char> nonrandom_path(nonrandom_path_template.begin(), nonrandom_path_template.end());
|
||||
nonrandom_path.push_back('\0');
|
||||
const int nonrandom_fd = mkstemp(nonrandom_path.data());
|
||||
if (nonrandom_fd < 0) {
|
||||
return 19;
|
||||
}
|
||||
FILE *nonrandom_fp = fdopen(nonrandom_fd, "w");
|
||||
if (!nonrandom_fp) {
|
||||
close(nonrandom_fd);
|
||||
std::remove(nonrandom_path.data());
|
||||
return 20;
|
||||
}
|
||||
std::fputs("T-1 P5 Z4.25\n", nonrandom_fp);
|
||||
std::fclose(nonrandom_fp);
|
||||
|
||||
if (tooldata_load(nonrandom_path.data()) != 0) {
|
||||
std::remove(nonrandom_path.data());
|
||||
return 21;
|
||||
}
|
||||
std::remove(nonrandom_path.data());
|
||||
|
||||
CANON_TOOL_TABLE nonrandom_spindle = tooldata_entry_init();
|
||||
if (tooldata_get(&nonrandom_spindle, 0) != IDX_OK) {
|
||||
return 22;
|
||||
}
|
||||
if (nonrandom_spindle.toolno != -1 || nonrandom_spindle.pocketno != 5 ||
|
||||
nonrandom_spindle.offset.tran.z != 4.25) {
|
||||
return 23;
|
||||
}
|
||||
|
||||
tool_mmap_close();
|
||||
if (tool_mmap_user() != -1) {
|
||||
return 39;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
47
core/wasm_shims/tooldata/tooldata_runtime_stubs.cc
Normal file
47
core/wasm_shims/tooldata/tooldata_runtime_stubs.cc
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "tooldata.hh"
|
||||
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int MAX_DB_PROGRAM_ARGS = 10;
|
||||
bool db_live = false;
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
int tool_nml_register(CANON_TOOL_TABLE *tblptr) {
|
||||
return tblptr ? 0 : -1;
|
||||
}
|
||||
|
||||
int tooldata_db_init(char progname_plus_args[], int) {
|
||||
if (!progname_plus_args) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *saveptr = nullptr;
|
||||
char *program = strtok_r(progname_plus_args, " ", &saveptr);
|
||||
int argc = 0;
|
||||
for (char *token = program; token; token = strtok_r(nullptr, " ", &saveptr)) {
|
||||
++argc;
|
||||
if (argc >= MAX_DB_PROGRAM_ARGS) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!program || access(program, X_OK) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tooldata_db_notify(tool_notify_t, int, int, CANON_TOOL_TABLE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tooldata_db_getall(void) {
|
||||
return db_live ? 0 : -1;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
Reference in New Issue
Block a user