Skip to content

Commit 758b594

Browse files
option to apply file permission bits to created shared memory
1 parent 5e4d6d5 commit 758b594

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

src/main.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ int main(int argc, char **argv) {
171171
"Do not use this option per default! "
172172
"It should only be used if the semaphore of an improperly terminated instance continues "
173173
"to exist as an orphan and is no longer used.");
174+
options.add_options()("b,permissions",
175+
"permission bits that are applied when creating a shared memory.",
176+
cxxopts::value<std::string>()->default_value("0640"));
174177
options.add_options()("h,help", "print usage");
175178
options.add_options()("version", "print version information");
176179
options.add_options()("license", "show licences");
@@ -262,6 +265,23 @@ int main(int argc, char **argv) {
262265

263266
const auto FORCE_SHM = args.count("force") > 0;
264267

268+
mode_t shm_permissions = 0660;
269+
{
270+
const auto shm_permissions_str = args["permissions"].as<std::string>();
271+
bool fail = false;
272+
std::size_t idx = 0;
273+
try {
274+
shm_permissions = std::stoul(shm_permissions_str, &idx, 0);
275+
} catch (const std::exception &) { fail = true; }
276+
fail = fail || idx != shm_permissions_str.size();
277+
278+
if (fail || (~static_cast<mode_t>(0x1FF) & shm_permissions) != 0) {
279+
std::cerr << Print_Time::iso << " ERROR: Invalid file permissions \"" << shm_permissions_str << '"'
280+
<< std::endl;
281+
return EX_USAGE;
282+
}
283+
}
284+
265285
// check ulimit
266286
std::size_t min_files =
267287
CONNECTIONS + 5; // number of connections + stderr + stdout + stdin + signal_fd + server socket
@@ -291,7 +311,8 @@ int main(int argc, char **argv) {
291311
args["ao-registers"].as<std::size_t>(),
292312
args["ai-registers"].as<std::size_t>(),
293313
args["name-prefix"].as<std::string>(),
294-
FORCE_SHM);
314+
FORCE_SHM,
315+
shm_permissions);
295316
} catch (const std::system_error &e) {
296317
std::cerr << Print_Time::iso << " ERROR: " << e.what() << std::endl;
297318
return EX_OSERR;
@@ -313,7 +334,8 @@ int main(int argc, char **argv) {
313334
args["ao-registers"].as<std::size_t>(),
314335
args["ai-registers"].as<std::size_t>(),
315336
sstr.str(),
316-
FORCE_SHM));
337+
FORCE_SHM,
338+
shm_permissions));
317339
mb_mappings[i] = separate_mappings.back()->get_mapping();
318340
} catch (const std::system_error &e) {
319341
std::cerr << Print_Time::iso << " ERROR: " << e.what() << std::endl;
@@ -340,7 +362,8 @@ int main(int argc, char **argv) {
340362
args["ao-registers"].as<std::size_t>(),
341363
args["ai-registers"].as<std::size_t>(),
342364
sstr.str(),
343-
FORCE_SHM));
365+
FORCE_SHM,
366+
shm_permissions));
344367
mb_mappings[a] = separate_mappings.back()->get_mapping();
345368
} catch (const std::system_error &e) {
346369
std::cerr << Print_Time::iso << " ERROR: " << e.what() << std::endl;

src/modbus_shm.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ Shm_Mapping::Shm_Mapping(std::size_t nb_bits,
1919
std::size_t nb_registers,
2020
std::size_t nb_input_registers,
2121
const std::string &prefix,
22-
bool force) {
22+
bool force,
23+
mode_t permissions) {
2324
// check argument ranges
2425
if (nb_bits > 0x10000 || !nb_bits) throw std::invalid_argument("invalid number of digital output registers.");
2526
if (nb_input_bits > 0x10000 || !nb_input_bits)
@@ -36,10 +37,11 @@ Shm_Mapping::Shm_Mapping(std::size_t nb_bits,
3637
mapping.nb_input_registers = static_cast<int>(nb_input_registers);
3738

3839
// create shm objects
39-
shm_data[DO] = std::make_unique<cxxshm::SharedMemory>(prefix + "DO", nb_bits, false, !force);
40-
shm_data[DI] = std::make_unique<cxxshm::SharedMemory>(prefix + "DI", nb_input_bits, false, !force);
41-
shm_data[AO] = std::make_unique<cxxshm::SharedMemory>(prefix + "AO", 2 * nb_registers, false, !force);
42-
shm_data[AI] = std::make_unique<cxxshm::SharedMemory>(prefix + "AI", 2 * nb_input_registers, false, !force);
40+
shm_data[DO] = std::make_unique<cxxshm::SharedMemory>(prefix + "DO", nb_bits, false, !force, permissions);
41+
shm_data[DI] = std::make_unique<cxxshm::SharedMemory>(prefix + "DI", nb_input_bits, false, !force, permissions);
42+
shm_data[AO] = std::make_unique<cxxshm::SharedMemory>(prefix + "AO", 2 * nb_registers, false, !force, permissions);
43+
shm_data[AI] =
44+
std::make_unique<cxxshm::SharedMemory>(prefix + "AI", 2 * nb_input_registers, false, !force, permissions);
4345

4446
// set shm objects as modbus register storage
4547
mapping.tab_bits = static_cast<uint8_t *>(shm_data[DO]->get_addr());

src/modbus_shm.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,15 @@ class Shm_Mapping final {
5353
* @param nb_input_registers number of analog input registers (AI)
5454
* @param shm_name_prefix name prefix of the created shared memory object
5555
* @param force do not fail if the shared memory exist, but use the existing shared memory
56+
* @param permissions shared memory file permissions
5657
*/
5758
Shm_Mapping(std::size_t nb_bits,
5859
std::size_t nb_input_bits,
5960
std::size_t nb_registers,
6061
std::size_t nb_input_registers,
6162
const std::string &shm_name_prefix,
62-
bool force);
63+
bool force,
64+
mode_t permissions);
6365

6466
~Shm_Mapping() = default;
6567

0 commit comments

Comments
 (0)