comparison Resources/Orthanc/Core/SystemToolbox.cpp @ 107:a3e8ac8b7256

support for OpenBSD
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 23 Aug 2017 11:10:48 +0200
parents ff0ef01c332c
children a18bfe1fdd62
comparison
equal deleted inserted replaced
105:42dcf1438943 107:a3e8ac8b7256
33 33
34 #include "PrecompiledHeaders.h" 34 #include "PrecompiledHeaders.h"
35 #include "SystemToolbox.h" 35 #include "SystemToolbox.h"
36 36
37 37
38 #if BOOST_HAS_DATE_TIME == 1
39 # include <boost/date_time/posix_time/posix_time.hpp>
40 #endif
41
42
43 #if defined(_WIN32) 38 #if defined(_WIN32)
44 # include <windows.h> 39 # include <windows.h>
45 # include <process.h> // For "_spawnvp()" and "_getpid()" 40 # include <process.h> // For "_spawnvp()" and "_getpid()"
46 #else 41 #else
47 # include <unistd.h> // For "execvp()" 42 # include <unistd.h> // For "execvp()"
60 # include <signal.h> 55 # include <signal.h>
61 # include <unistd.h> 56 # include <unistd.h>
62 #endif 57 #endif
63 58
64 59
60 #if defined(__OpenBSD__)
61 # include <sys/sysctl.h> // For "sysctl", "CTL_KERN" and "KERN_PROC_ARGS"
62 #endif
63
64
65 // Inclusions for UUID 65 // Inclusions for UUID
66 // http://stackoverflow.com/a/1626302 66 // http://stackoverflow.com/a/1626302
67 67
68 extern "C" 68 extern "C"
69 { 69 {
70 #ifdef WIN32 70 #if defined(_WIN32)
71 # include <rpc.h> 71 # include <rpc.h>
72 #else 72 #else
73 # include <uuid/uuid.h> 73 # include <uuid/uuid.h>
74 #endif 74 #endif
75 } 75 }
79 #include "OrthancException.h" 79 #include "OrthancException.h"
80 #include "Toolbox.h" 80 #include "Toolbox.h"
81 81
82 #include <boost/filesystem.hpp> 82 #include <boost/filesystem.hpp>
83 #include <boost/filesystem/fstream.hpp> 83 #include <boost/filesystem/fstream.hpp>
84 #include <boost/date_time/posix_time/posix_time.hpp>
84 85
85 86
86 namespace Orthanc 87 namespace Orthanc
87 { 88 {
88 static bool finish_; 89 static bool finish_;
155 156
156 void SystemToolbox::USleep(uint64_t microSeconds) 157 void SystemToolbox::USleep(uint64_t microSeconds)
157 { 158 {
158 #if defined(_WIN32) 159 #if defined(_WIN32)
159 ::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000))); 160 ::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000)));
160 #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__native_client__) 161 #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__native_client__)
161 usleep(microSeconds); 162 usleep(microSeconds);
162 #else 163 #else
163 #error Support your platform here 164 #error Support your platform here
164 #endif 165 #endif
165 } 166 }
191 { 192 {
192 throw OrthancException(ErrorCode_InexistentFile); 193 throw OrthancException(ErrorCode_InexistentFile);
193 } 194 }
194 195
195 std::streamsize size = GetStreamSize(f); 196 std::streamsize size = GetStreamSize(f);
196 content.resize(size); 197 content.resize(static_cast<size_t>(size));
197 if (size != 0) 198 if (size != 0)
198 { 199 {
199 f.read(reinterpret_cast<char*>(&content[0]), size); 200 f.read(reinterpret_cast<char*>(&content[0]), size);
200 } 201 }
201 202
229 headerSize = 0; 230 headerSize = 0;
230 full = false; 231 full = false;
231 } 232 }
232 else if (static_cast<size_t>(size) < headerSize) 233 else if (static_cast<size_t>(size) < headerSize)
233 { 234 {
234 headerSize = size; // Truncate to the size of the file 235 headerSize = static_cast<size_t>(size); // Truncate to the size of the file
235 full = false; 236 full = false;
236 } 237 }
237 } 238 }
238 239
239 header.resize(headerSize); 240 header.resize(headerSize);
347 } 348 }
348 349
349 #elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) 350 #elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
350 static std::string GetPathToExecutableInternal() 351 static std::string GetPathToExecutableInternal()
351 { 352 {
353 // NOTE: For FreeBSD, using KERN_PROC_PATHNAME might be a better alternative
354
352 std::vector<char> buffer(PATH_MAX + 1); 355 std::vector<char> buffer(PATH_MAX + 1);
353 ssize_t bytes = readlink("/proc/self/exe", &buffer[0], buffer.size() - 1); 356 ssize_t bytes = readlink("/proc/self/exe", &buffer[0], buffer.size() - 1);
354 if (bytes == 0) 357 if (bytes == 0)
355 { 358 {
356 throw OrthancException(ErrorCode_PathToExecutable); 359 throw OrthancException(ErrorCode_PathToExecutable);
366 unsigned int bufsize = static_cast<int>(sizeof(pathbuf)); 369 unsigned int bufsize = static_cast<int>(sizeof(pathbuf));
367 370
368 _NSGetExecutablePath( pathbuf, &bufsize); 371 _NSGetExecutablePath( pathbuf, &bufsize);
369 372
370 return std::string(pathbuf); 373 return std::string(pathbuf);
374 }
375
376 #elif defined(__OpenBSD__)
377 static std::string GetPathToExecutableInternal()
378 {
379 // This is an adapted version of the patch proposed in issue #64
380 // without an explicit call to "malloc()" to prevent memory leak
381 // https://bitbucket.org/sjodogne/orthanc/issues/64/add-openbsd-support
382 // https://stackoverflow.com/q/31494901/881731
383
384 const int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
385
386 size_t len;
387 if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
388 {
389 throw OrthancException(ErrorCode_PathToExecutable);
390 }
391
392 std::string tmp;
393 tmp.resize(len);
394
395 char** buffer = reinterpret_cast<char**>(&tmp[0]);
396
397 if (sysctl(mib, 4, buffer, &len, NULL, 0) == -1)
398 {
399 throw OrthancException(ErrorCode_PathToExecutable);
400 }
401 else
402 {
403 return std::string(buffer[0]);
404 }
371 } 405 }
372 406
373 #else 407 #else
374 #error Support your platform here 408 #error Support your platform here
375 #endif 409 #endif
525 #endif 559 #endif
526 return s; 560 return s;
527 } 561 }
528 562
529 563
530 #if BOOST_HAS_DATE_TIME == 1
531 std::string SystemToolbox::GetNowIsoString() 564 std::string SystemToolbox::GetNowIsoString()
532 { 565 {
533 boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); 566 boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
534 return boost::posix_time::to_iso_string(now); 567 return boost::posix_time::to_iso_string(now);
535 } 568 }
536 569
570
537 void SystemToolbox::GetNowDicom(std::string& date, 571 void SystemToolbox::GetNowDicom(std::string& date,
538 std::string& time) 572 std::string& time)
539 { 573 {
540 boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); 574 boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
541 tm tm = boost::posix_time::to_tm(now); 575 tm tm = boost::posix_time::to_tm(now);
546 580
547 // TODO milliseconds 581 // TODO milliseconds
548 sprintf(s, "%02d%02d%02d.%06d", tm.tm_hour, tm.tm_min, tm.tm_sec, 0); 582 sprintf(s, "%02d%02d%02d.%06d", tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
549 time.assign(s); 583 time.assign(s);
550 } 584 }
551 #endif
552 } 585 }