MIDAS
Loading...
Searching...
No Matches
System Functions (ss_xxx)

Classes

struct  FL_PARAM
 
struct  suspend_struct
 

Macros

#define bin_to_ascii(c)   ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
 
#define N_STACK_HISTORY   500
 

Typedefs

typedef struct suspend_struct SUSPEND_STRUCT
 

Functions

static void check_shm_type (const char *shm_type)
 
static void check_shm_host ()
 
static int ss_shm_name (const char *name, std::string &mem_name, std::string &file_name, std::string &shm_name)
 
INT ss_shm_open (const char *name, INT size, void **adr, size_t *shm_size, HNDLE *handle, BOOL get_size)
 
INT ss_shm_close (const char *name, void *adr, size_t shm_size, HNDLE handle, INT destroy_flag)
 
INT ss_shm_delete (const char *name)
 
INT ss_shm_protect (HNDLE handle, void *adr, size_t shm_size)
 
INT ss_shm_unprotect (HNDLE handle, void **adr, size_t shm_size, BOOL read, BOOL write, const char *caller_name)
 
INT ss_shm_flush_thread (void *p)
 
INT ss_shm_flush (const char *name, const void *adr, size_t size, HNDLE handle, bool wait_for_thread)
 
INT ss_get_struct_align ()
 
INT ss_get_struct_padding ()
 
INT ss_getpid (void)
 
BOOL ss_pid_exists (int pid)
 
void ss_kill (int pid)
 
std::string ss_get_executable (void)
 
midas_thread_t ss_gettid (void)
 
std::string ss_tid_to_string (midas_thread_t thread_id)
 
INT ss_spawnv (INT mode, const char *cmdname, const char *const argv[])
 
INT ss_shell (int sock)
 
INT ss_daemon_init (BOOL keep_stdout)
 
BOOL ss_existpid (INT pid)
 
INT ss_system (const char *command)
 
INT ss_exec (const char *command, INT *pid)
 
std::string ss_replace_env_variables (const std::string &inputPath)
 
std::string ss_execs (const char *cmd)
 
midas_thread_t ss_thread_create (INT(*thread_func)(void *), void *param)
 
INT ss_thread_kill (midas_thread_t thread_id)
 
INT EXPRT ss_thread_set_name (std::string name)
 
std::string EXPRT ss_thread_get_name ()
 
INT ss_semaphore_create (const char *name, HNDLE *semaphore_handle)
 
INT ss_semaphore_wait_for (HNDLE semaphore_handle, DWORD timeout_millisec)
 
INT ss_semaphore_release (HNDLE semaphore_handle)
 
INT ss_semaphore_delete (HNDLE semaphore_handle, INT destroy_flag)
 
INT ss_mutex_create (MUTEX_T **mutex, BOOL recursive)
 
INT ss_mutex_wait_for (MUTEX_T *mutex, INT timeout)
 
INT ss_mutex_release (MUTEX_T *mutex)
 
INT ss_mutex_delete (MUTEX_T *mutex)
 
bool ss_timed_mutex_wait_for_sec (std::timed_mutex &mutex, const char *mutex_name, double timeout_sec)
 
void ss_tzset ()
 
time_t ss_mktime (struct tm *tms)
 
DWORD ss_millitime ()
 
DWORD ss_time ()
 
double ss_time_sec ()
 
DWORD ss_settime (DWORD seconds)
 
std::string ss_asctime ()
 
INT ss_timezone ()
 
INT ss_sleep (INT millisec)
 
BOOL ss_kbhit ()
 
INT ss_alarm (INT millitime, void(*func)(int))
 
INT ss_exception_handler (void(*func)(void))
 
voidss_ctrlc_handler (void(*func)(int))
 
static bool ss_match_thread (midas_thread_t tid1, midas_thread_t tid2)
 
INT ss_suspend_set_rpc_thread (midas_thread_t thread_id)
 
static INT ss_suspend_init_struct (SUSPEND_STRUCT *psuspend)
 
SUSPEND_STRUCTss_suspend_get_struct (midas_thread_t thread_id)
 
static void ss_suspend_close (SUSPEND_STRUCT *psuspend)
 
INT ss_suspend_exit ()
 
INT ss_suspend_set_server_listener (int listen_socket)
 
INT ss_suspend_set_client_listener (int listen_socket)
 
INT ss_suspend_set_client_connection (RPC_SERVER_CONNECTION *connection)
 
INT ss_suspend_set_server_acceptions (RPC_SERVER_ACCEPTION_LIST *acceptions)
 
INT ss_suspend_init_odb_port ()
 
INT ss_suspend_get_odb_port (INT *port)
 
INT ss_suspend_get_buffer_port (midas_thread_t thread_id, INT *port)
 
static int ss_suspend_process_ipc (INT millisec, INT msg, int ipc_recv_socket)
 
static int ss_socket_check (int sock)
 
bool ss_event_socket_has_data ()
 
INT ss_suspend (INT millisec, INT msg)
 
INT ss_resume (INT port, const char *message)
 
int ss_socket_wait (int sock, INT millisec)
 
INT ss_socket_connect_tcp (const char *hostname, int tcp_port, int *sockp, std::string *error_msg_p)
 
INT ss_socket_listen_tcp (bool listen_localhost, int tcp_port, int *sockp, int *tcp_port_p, std::string *error_msg_p)
 
INT ss_socket_close (int *sockp)
 
INT ss_socket_get_peer_name (int sock, std::string *hostp, int *portp)
 
INT send_tcp (int sock, char *buffer, DWORD buffer_size, INT flags)
 
INT ss_write_tcp (int sock, const char *buffer, size_t buffer_size)
 
INT recv_string (int sock, char *buffer, DWORD buffer_size, INT millisec)
 
INT recv_tcp (int sock, char *net_buffer, DWORD buffer_size, INT flags)
 
INT recv_tcp2 (int sock, char *net_buffer, int buffer_size, int timeout_ms)
 
INT ss_recv_net_command (int sock, DWORD *routine_id, DWORD *param_size, char **param_ptr, int timeout_ms)
 
std::string ss_gethostname ()
 
INT ss_gethostname (char *buffer, int buffer_size)
 
std::string ss_getcwd ()
 
INT ss_tape_open (char *path, INT oflag, INT *channel)
 
INT ss_tape_close (INT channel)
 
INT ss_tape_status (char *path)
 
INT ss_tape_write (INT channel, void *pdata, INT count)
 
INT ss_tape_read (INT channel, void *pdata, INT *count)
 
INT ss_tape_write_eof (INT channel)
 
INT ss_tape_fskip (INT channel, INT count)
 
INT ss_tape_rskip (INT channel, INT count)
 
INT ss_tape_rewind (INT channel)
 
INT ss_tape_spool (INT channel)
 
INT ss_tape_mount (INT channel)
 
INT ss_tape_unmount (INT channel)
 
INT ss_tape_get_blockn (INT channel)
 
double ss_disk_free (const char *path)
 
INT ss_file_find (const char *path, const char *pattern, char **plist)
 
INT ss_file_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_dir_find (const char *path, const char *pattern, char **plist)
 
INT ss_dir_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_dirlink_find (const char *path, const char *pattern, char **plist)
 
INT ss_dirlink_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_file_remove (const char *path)
 
double ss_file_size (const char *path)
 
time_t ss_file_time (const char *path)
 
double ss_disk_size (const char *path)
 
int ss_file_exist (const char *path)
 
int ss_file_link_exist (const char *path)
 
int ss_dir_exist (const char *path)
 
int ss_file_copy (const char *src, const char *dst, bool append)
 
void ss_clear_screen ()
 
void ss_set_screen_size (int x, int y)
 
void ss_printf (INT x, INT y, const char *format,...)
 
charss_getpass (const char *prompt)
 
INT ss_getchar (BOOL reset)
 
charss_gets (char *string, int size)
 
INT ss_directio_give_port (INT start, INT end)
 
INT ss_directio_lock_port (INT start, INT end)
 
charss_crypt (const char *buf, const char *salt)
 
double ss_nan ()
 
int ss_isnan (double x)
 
int ss_isfin (double x)
 
INT ss_stack_get (char ***string)
 
void ss_stack_print ()
 
void ss_stack_history_entry (char *tag)
 
void ss_stack_history_dump (char *filename)
 
bool ss_is_valid_utf8 (const char *string)
 
bool ss_repair_utf8 (char *string)
 
bool ss_repair_utf8 (std::string &s)
 
std::chrono::time_point< std::chrono::high_resolution_clockss_us_start ()
 
unsigned int ss_us_since (std::chrono::time_point< std::chrono::high_resolution_clock > start)
 
int rpc_flush_event_socket (int timeout_msec)
 

Variables

struct { 
 
   char   c 
 
   double   d 
 
test_align 
 
struct { 
 
   double   d 
 
   char   c 
 
test_padding 
 
static BOOL _daemon_flag
 
static std::atomic_bool s_semaphore_trace {false}
 
static std::atomic_int s_semaphore_nest_level {0}
 
static std::mutex gTzMutex
 
void(* MidasExceptionHandler )(void)
 
static std::vector< SUSPEND_STRUCT * > _ss_suspend_vector
 
static midas_thread_t _ss_odb_thread = 0
 
static SUSPEND_STRUCT_ss_suspend_odb = NULL
 
static midas_thread_t _ss_listen_thread = 0
 
static int _ss_server_listen_socket = 0
 
static int _ss_client_listen_socket = 0
 
static midas_thread_t _ss_client_thread = 0
 
static RPC_SERVER_CONNECTION_ss_client_connection = NULL
 
static midas_thread_t _ss_server_thread = 0
 
static RPC_SERVER_ACCEPTION_LIST_ss_server_acceptions = NULL
 
static bool gSocketTrace = false
 
char stack_history [N_STACK_HISTORY][80]
 
int stack_history_pointer = -1
 

Detailed Description

dox


Macro Definition Documentation

◆ bin_to_ascii

#define bin_to_ascii (   c)    ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')

Definition at line 7889 of file system.cxx.

◆ N_STACK_HISTORY

#define N_STACK_HISTORY   500

Definition at line 7990 of file system.cxx.

Typedef Documentation

◆ SUSPEND_STRUCT

Function Documentation

◆ check_shm_host()

static void check_shm_host ( )
static

Definition at line 168 of file system.cxx.

169{
170 std::string file_name;
171 char buf[256], cwd[256];
172 char hostname[256];
173 char* s;
174 FILE *fp;
175
176 gethostname(hostname, sizeof(hostname));
177
178 //printf("hostname [%s]\n", hostname);
179
180 std::string path = cm_get_path();
181 if (path.empty()) {
182 if (getcwd(cwd, sizeof(cwd)))
183 path = std::string(cwd);
184#if defined(OS_VMS)
185#elif defined(OS_UNIX)
186 path += "/";
187#elif defined(OS_WINNT)
188 path += "\\";
189#endif
190 }
191
192 file_name = path;
193#if defined (OS_UNIX)
194 file_name += "."; /* dot file under UNIX */
195#endif
196 file_name += "SHM_HOST.TXT";
197
198 fp = fopen(file_name.c_str(), "r");
199 if (!fp) {
200 fp = fopen(file_name.c_str(), "w");
201 if (!fp)
202 cm_msg(MERROR, "check_shm_host", "Cannot write to \'%s\', errno %d (%s)", file_name.c_str(), errno, strerror(errno));
203 assert(fp != NULL);
204 fprintf(fp, "%s\n", hostname);
205 fclose(fp);
206 return;
207 }
208
209 buf[0] = 0;
210
211 if (!fgets(buf, sizeof(buf), fp))
212 buf[0] = 0;
213
214 fclose(fp);
215
216 s = strchr(buf, '\n');
217 if (s)
218 *s = 0;
219
220 if (strlen(buf) < 1)
221 return; // success - provide user with a way to defeat this check
222
223 if (strcmp(buf, hostname) == 0)
224 return; // success!
225
226 cm_msg(MERROR, "check_shm_host", "Error: Cannot connect to MIDAS shared memory - this computer hostname is \'%s\' while \'%s\' says that MIDAS shared memory for this experiment is located on computer \'%s\'. To connect to this experiment from this computer, use the mserver. Please see the MIDAS documentation for details.", hostname, file_name.c_str(), buf);
227 exit(1);
228}
std::string cm_get_path()
Definition midas.cxx:1537
#define MERROR
Definition midas.h:559
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
static FILE * fp
char file_name[256]
Definition odbhist.cxx:41
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_shm_type()

static void check_shm_type ( const char shm_type)
static

Definition at line 80 of file system.cxx.

81{
82#ifdef OS_UNIX
83 std::string file_name;
84 char cwd[256], buf[256];
85 char* s;
86
87 std::string path = cm_get_path();
88 if (path.empty()) {
89 if (getcwd(cwd, sizeof(cwd)))
90 path = std::string(cwd);
91 path += "/";
92 }
93
94
95 file_name = path;
96 file_name += ".SHM_TYPE.TXT";
97
98 FILE* fp = fopen(file_name.c_str(), "r");
99 if (!fp) {
100 fp = fopen(file_name.c_str(), "w");
101 if (!fp) {
102 fprintf(stderr, "check_shm_type: Cannot write to config file \'%s\', errno %d (%s)", file_name.c_str(), errno, strerror(errno));
103 exit(1);
104 // DOES NOT RETURN
105 }
106
107 fprintf(fp, "%s\n", shm_type);
108 fclose(fp);
109
110 fp = fopen(file_name.c_str(), "r");
111 if (!fp) {
112 fprintf(stderr, "check_shm_type: Cannot open config file \'%s\', errno %d (%s)", file_name.c_str(), errno, strerror(errno));
113 exit(1);
114 // DOES NOT RETURN
115 }
116 }
117
118 if (!fgets(buf, sizeof(buf), fp))
119 buf[0] = 0;
120
121 fclose(fp);
122
123 s = strchr(buf, '\n');
124 if (s)
125 *s = 0;
126
127 //printf("check_shm_type: preferred %s got %s\n", shm_type, buf);
128
129 if (strcmp(buf, "SYSV_SHM") == 0) {
130 use_sysv_shm = 1;
131 return;
132 }
133
134 if (strcmp(buf, "MMAP_SHM") == 0) {
135 use_mmap_shm = 1;
136 return;
137 }
138
139 if (strcmp(buf, "POSIX_SHM") == 0) {
140 use_posix1_shm = 1;
141 use_posix_shm = 1;
142 return;
143 }
144
145 if (strcmp(buf, "POSIXv2_SHM") == 0) {
146 use_posix2_shm = 1;
147 use_posix_shm = 1;
148 return;
149 }
150
151 if (strcmp(buf, "POSIXv3_SHM") == 0) {
152 use_posix3_shm = 1;
153 use_posix_shm = 1;
154 return;
155 }
156
157 if (strcmp(buf, "POSIXv4_SHM") == 0) {
158 use_posix4_shm = 1;
159 use_posix_shm = 1;
160 return;
161 }
162
163 fprintf(stderr, "check_shm_type: Config file \"%s\" specifies unknown or unsupported shared memory type \"%s\", supported types are: SYSV_SHM, MMAP_SHM, POSIX_SHM, POSIXv2_SHM, POSIXv3_SHM, POSIXv4_SHM, default/preferred type is \"%s\"\n", file_name.c_str(), buf, shm_type);
164 exit(1);
165#endif
166}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_string()

INT EXPRT recv_string ( int  sock,
char buffer,
DWORD  buffer_size,
INT  millisec 
)

Definition at line 5393 of file system.cxx.

5418{
5419 INT i, status;
5420 DWORD n;
5421
5422 n = 0;
5423 memset(buffer, 0, buffer_size);
5424
5425 do {
5426 if (millisec > 0) {
5428 if (status != SS_SUCCESS)
5429 break;
5430 }
5431
5432 i = recv(sock, buffer + n, 1, 0);
5433
5434 if (i <= 0)
5435 break;
5436
5437 n++;
5438
5439 if (n >= buffer_size)
5440 break;
5441
5442 } while (buffer[n - 1] && buffer[n - 1] != 10);
5443
5444 return n - 1;
5445}
#define SS_SUCCESS
Definition midas.h:663
unsigned int DWORD
Definition mcstd.h:51
int ss_socket_wait(int sock, INT millisec)
Definition system.cxx:4898
DWORD n[4]
Definition mana.cxx:247
INT i
Definition mdump.cxx:32
int INT
Definition midas.h:129
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_tcp()

INT EXPRT recv_tcp ( int  sock,
char net_buffer,
DWORD  buffer_size,
INT  flags 
)

Definition at line 5448 of file system.cxx.

5478{
5479 INT param_size, n_received, n;
5480 NET_COMMAND *nc;
5481
5482 if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
5483 cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
5484 return -1;
5485 }
5486
5487 /* first receive header */
5488 n_received = 0;
5489 do {
5490#ifdef OS_UNIX
5491 do {
5492 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
5493
5494 /* don't return if an alarm signal was cought */
5495 } while (n == -1 && errno == EINTR);
5496#else
5497 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
5498#endif
5499
5500 if (n == 0) {
5501 cm_msg(MERROR, "recv_tcp", "header: recv(%d) returned %d, n_received = %d, unexpected connection closure", (int)sizeof(NET_COMMAND_HEADER), n, n_received);
5502 return n;
5503 }
5504
5505 if (n < 0) {
5506 cm_msg(MERROR, "recv_tcp", "header: recv(%d) returned %d, n_received = %d, errno: %d (%s)", (int)sizeof(NET_COMMAND_HEADER), n, n_received, errno, strerror(errno));
5507 return n;
5508 }
5509
5510 n_received += n;
5511
5512 } while (n_received < (int) sizeof(NET_COMMAND_HEADER));
5513
5514 /* now receive parameters */
5515
5516 nc = (NET_COMMAND *) net_buffer;
5517 param_size = nc->header.param_size;
5518 n_received = 0;
5519
5520 if (param_size == 0)
5521 return sizeof(NET_COMMAND_HEADER);
5522
5523 if (param_size > (INT)buffer_size) {
5524 cm_msg(MERROR, "recv_tcp", "param: receive buffer size %d is too small for received data size %d", buffer_size, param_size);
5525 return -1;
5526 }
5527
5528 do {
5529#ifdef OS_UNIX
5530 do {
5531 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received, param_size - n_received, flags);
5532
5533 /* don't return if an alarm signal was cought */
5534 } while (n == -1 && errno == EINTR);
5535#else
5536 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received, param_size - n_received, flags);
5537#endif
5538
5539 if (n == 0) {
5540 cm_msg(MERROR, "recv_tcp", "param: recv() returned %d, n_received = %d, unexpected connection closure", n, n_received);
5541 return n;
5542 }
5543
5544 if (n < 0) {
5545 cm_msg(MERROR, "recv_tcp", "param: recv() returned %d, n_received = %d, errno: %d (%s)", n, n_received, errno, strerror(errno));
5546 return n;
5547 }
5548
5549 n_received += n;
5550 } while (n_received < param_size);
5551
5552 return sizeof(NET_COMMAND_HEADER) + param_size;
5553}
NET_COMMAND_HEADER header
Definition msystem.h:286
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_tcp2()

INT EXPRT recv_tcp2 ( int  sock,
char net_buffer,
int  buffer_size,
int  timeout_ms 
)

Definition at line 5556 of file system.cxx.

5582{
5583 int n_received = 0;
5584 int flags = 0;
5585 int n;
5586
5587 //printf("recv_tcp2: %p+%d bytes, timeout %d ms!\n", net_buffer + n_received, buffer_size - n_received, timeout_ms);
5588
5589 while (n_received != buffer_size) {
5590
5591 if (timeout_ms > 0) {
5592 int status = ss_socket_wait(sock, timeout_ms);
5593 if (status == SS_TIMEOUT)
5594 return n_received;
5595 if (status != SS_SUCCESS)
5596 return -1;
5597 }
5598
5599 n = recv(sock, net_buffer + n_received, buffer_size - n_received, flags);
5600
5601 //printf("recv_tcp2: %p+%d bytes, returned %d, errno %d (%s)\n", net_buffer + n_received, buffer_size - n_received, n, errno, strerror(errno));
5602
5603#ifdef EINTR
5604 /* don't return if an alarm signal was cought */
5605 if (n == -1 && errno == EINTR)
5606 continue;
5607#endif
5608
5609 if (n == 0) {
5610 // socket closed
5611 cm_msg(MERROR, "recv_tcp2", "unexpected connection closure");
5612 return -1;
5613 }
5614
5615 if (n < 0) {
5616 // socket error
5617 cm_msg(MERROR, "recv_tcp2", "unexpected connection error, recv() errno %d (%s)", errno, strerror(errno));
5618 return -1;
5619 }
5620
5621 n_received += n;
5622 }
5623
5624 return n_received;
5625}
#define SS_TIMEOUT
Definition midas.h:674
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 16136 of file midas.cxx.

16150{
16152
16153 //printf("ss_event_socket_has_data() returned %d\n", has_data);
16154
16155 if (has_data) {
16156 if (timeout_msec == BM_NO_WAIT) {
16157 return BM_ASYNC_RETURN;
16158 } else if (timeout_msec == BM_WAIT) {
16159 return BM_ASYNC_RETURN;
16160 } else {
16162 if (status == SS_ABORT || status == SS_EXIT)
16163 return status;
16164 return BM_ASYNC_RETURN;
16165 }
16166 }
16167
16169
16170 //printf("rpc_server_receive_event() status %d\n", status);
16171
16172 if (status == BM_ASYNC_RETURN) {
16173 return BM_ASYNC_RETURN;
16174 }
16175
16176 if (status == SS_ABORT || status == SS_EXIT)
16177 return status;
16178
16179 return BM_SUCCESS;
16180}
#define BM_ASYNC_RETURN
Definition midas.h:613
#define BM_SUCCESS
Definition midas.h:605
#define SS_ABORT
Definition midas.h:677
#define SS_EXIT
Definition midas.h:678
#define BM_NO_WAIT
Definition midas.h:366
#define BM_WAIT
Definition midas.h:365
#define MSG_BM
Definition msystem.h:295
INT ss_suspend(INT millisec, INT msg)
Definition system.cxx:4543
bool ss_event_socket_has_data()
Definition system.cxx:4520
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition midas.cxx:15981
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_tcp()

INT EXPRT send_tcp ( int  sock,
char buffer,
DWORD  buffer_size,
INT  flags 
)

Definition at line 5279 of file system.cxx.

5300{
5301 DWORD count;
5302 INT status;
5303 //int net_tcp_size = NET_TCP_SIZE;
5304 int net_tcp_size = 1024 * 1024;
5305
5306 /* transfer fragments until complete buffer is transferred */
5307
5308 for (count = 0; (INT) count < (INT) buffer_size - net_tcp_size;) {
5309 status = send(sock, buffer + count, net_tcp_size, flags & 0xFFFF);
5310 if (status != -1)
5311 count += status;
5312 else {
5313#ifdef OS_UNIX
5314 if (errno == EINTR)
5315 continue;
5316#endif
5317 if ((flags & 0x10000) == 0)
5318 cm_msg(MERROR, "send_tcp",
5319 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
5321 return status;
5322 }
5323 }
5324
5325 while (count < buffer_size) {
5326 status = send(sock, buffer + count, buffer_size - count, flags & 0xFFFF);
5327 if (status != -1)
5328 count += status;
5329 else {
5330#ifdef OS_UNIX
5331 if (errno == EINTR)
5332 continue;
5333#endif
5334 if ((flags & 0x10000) == 0)
5335 cm_msg(MERROR, "send_tcp",
5336 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
5337 sock, (int) (buffer_size - count), status, errno, strerror(errno));
5338 return status;
5339 }
5340 }
5341
5342 return count;
5343}
double count
Definition mdump.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_alarm()

INT ss_alarm ( INT  millitime,
void(*)(int func 
)

Definition at line 3737 of file system.cxx.

3757{
3758#ifdef OS_WINNT
3759
3760 UserCallback = func;
3761 if (millitime > 0)
3763 else {
3764 if (_timer_id)
3766 _timer_id = 0;
3767 }
3768
3769 return SS_SUCCESS;
3770
3771#endif /* OS_WINNT */
3772#ifdef OS_VMS
3773
3774 signal(SIGALRM, func);
3775 alarm(millitime / 1000);
3776 return SS_SUCCESS;
3777
3778#endif /* OS_VMS */
3779#ifdef OS_UNIX
3780
3781 signal(SIGALRM, func);
3782 alarm(millitime / 1000);
3783 return SS_SUCCESS;
3784
3785#endif /* OS_UNIX */
3786}
Here is the call graph for this function:

◆ ss_asctime()

std::string EXPRT ss_asctime ( )

Definition at line 3549 of file system.cxx.

3566{
3567 ss_tzset(); // required for localtime_t()
3569 struct tm tms;
3571 char str[32];
3572 asctime_r(&tms, str);
3573 /* strip new line */
3574 str[24] = 0;
3575
3576 return str;
3577}
void ss_tzset()
Definition system.cxx:3355
DWORD ss_time()
Definition system.cxx:3462
MUTEX_T * tm
Definition odbedit.cxx:39
char str[256]
Definition odbhist.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_clear_screen()

void EXPRT ss_clear_screen ( )

Definition at line 7299 of file system.cxx.

7316{
7317#ifdef OS_WINNT
7318
7320 COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */
7321 BOOL bSuccess;
7323 CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
7324 DWORD dwConSize; /* number of character cells in the current buffer */
7325
7327
7328 /* get the number of character cells in the current buffer */
7330 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
7331
7332 /* fill the entire screen with blanks */
7334
7335 /* put the cursor at (0, 0) */
7337 return;
7338
7339#endif /* OS_WINNT */
7340#if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7341 printf("\033[2J");
7342#endif
7343#ifdef OS_MSDOS
7344 clrscr();
7345#endif
7346}
DWORD BOOL
Definition midas.h:105
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_crypt()

char EXPRT * ss_crypt ( const char buf,
const char salt 
)

Definition at line 7891 of file system.cxx.

7911{
7912 int i, seed;
7913 static char enc_pw[13];
7914
7915 memset(enc_pw, 0, sizeof(enc_pw));
7916 enc_pw[0] = salt[0];
7917 enc_pw[1] = salt[1];
7918
7919 for (i = 0; i < 8 && buf[i]; i++)
7920 enc_pw[i + 2] = buf[i];
7921 for (; i < 8; i++)
7922 enc_pw[i + 2] = 0;
7923
7924 seed = 123;
7925 for (i = 2; i < 13; i++) {
7926 seed = 5 * seed + 27 + enc_pw[i];
7927 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
7928 }
7929
7930 return enc_pw;
7931}
#define bin_to_ascii(c)
Definition system.cxx:7889
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_ctrlc_handler()

void EXPRT * ss_ctrlc_handler ( void(*)(int func)

Definition at line 3899 of file system.cxx.

3919{
3920#ifdef OS_WINNT
3921
3922 if (func == NULL) {
3924 return signal(SIGINT, SIG_DFL);
3925 } else {
3926 signal(SIGBREAK, func);
3927 return signal(SIGINT, func);
3928 }
3929 return NULL;
3930
3931#endif /* OS_WINNT */
3932#ifdef OS_VMS
3933
3934 return signal(SIGINT, func);
3935
3936#endif /* OS_WINNT */
3937
3938#ifdef OS_UNIX
3939
3940 if (func == NULL) {
3942 return (void *) signal(SIGINT, SIG_DFL);
3943 } else {
3944 signal(SIGTERM, func);
3945 return (void *) signal(SIGINT, func);
3946 }
3947
3948#endif /* OS_UNIX */
3949}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_daemon_init()

INT EXPRT ss_daemon_init ( BOOL  keep_stdout)

Definition at line 2001 of file system.cxx.

2019{
2020#ifdef OS_UNIX
2021
2022 /* only implemented for UNIX */
2023 int i, fd, pid;
2024
2025#ifdef NO_FORK
2026 assert(!"support for fork() disabled by NO_FORK");
2027#else
2028 if ((pid = fork()) < 0)
2029 return SS_ABORT;
2030 else if (pid != 0)
2031 exit(0); /* parent finished */
2032#endif
2033
2034 /* child continues here */
2035
2037
2038 /* try and use up stdin, stdout and stderr, so other
2039 routines writing to stdout etc won't cause havoc. Copied from smbd */
2040 for (i = 0; i < 3; i++) {
2041 if (keep_stdout && ((i == 1) || (i == 2)))
2042 continue;
2043
2044 close(i);
2045 fd = open("/dev/null", O_RDWR, 0);
2046 if (fd < 0)
2047 fd = open("/dev/null", O_WRONLY, 0);
2048 if (fd < 0) {
2049 cm_msg(MERROR, "ss_daemon_init", "Can't open /dev/null");
2050 return SS_ABORT;
2051 }
2052 if (fd != i) {
2053 cm_msg(MERROR, "ss_daemon_init", "Did not get file descriptor");
2054 return SS_ABORT;
2055 }
2056 }
2057
2058 setsid(); /* become session leader */
2059
2060#endif
2061
2062 return SS_SUCCESS;
2063}
static BOOL _daemon_flag
Definition system.cxx:1999
#define TRUE
Definition midas.h:182
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_dir_exist()

INT EXPRT ss_dir_exist ( const char path)

Definition at line 7186 of file system.cxx.

7203{
7204#ifdef OS_UNIX
7205 struct stat buf;
7206
7207 int retval = stat(path, &buf);
7208 //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7209 if (retval < 0)
7210 return 0;
7211 if (!S_ISDIR(buf.st_mode))
7212 return 0;
7213#else
7214#warning ss_dir_exist() is not implemented!
7215#endif
7216 return 1;
7217}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_dir_find() [1/2]

INT EXPRT ss_dir_find ( const char path,
const char pattern,
char **  plist 
)

Definition at line 6796 of file system.cxx.

6797{
6799
6800 int count = ss_dir_find(path, pattern, &list);
6801 if (count <= 0)
6802 return count;
6803
6804 size_t size = list.size();
6805 *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6806 for (size_t i=0; i<size; i++) {
6807 //printf("file %d [%s]\n", (int)i, list[i].c_str());
6809 }
6810
6811 return size;
6812}
#define MAX_STRING_LENGTH
Definition msystem.h:113
INT ss_dir_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6796
std::vector< std::string > STRING_LIST
Definition midas.h:246
static te_expr * list(state *s)
Definition tinyexpr.c:567
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_dir_find() [2/2]

INT EXPRT ss_dir_find ( const char path,
const char pattern,
STRING_LIST plist 
)

Definition at line 6814 of file system.cxx.

6832{
6833 assert(plist);
6834#ifdef OS_UNIX
6836 struct dirent *dp;
6837
6838 if ((dir_pointer = opendir(path)) == NULL)
6839 return 0;
6840 plist->clear();
6841 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6842 if (fnmatch(pattern, dp->d_name, 0) == 0 && dp->d_type == DT_DIR) {
6843 plist->push_back(dp->d_name);
6845 }
6846 }
6848#endif
6849#ifdef OS_WINNT
6850 char str[255];
6851 int first;
6852
6853 strcpy(str, path);
6854 strcat(str, "\\");
6855 strcat(str, pattern);
6856 first = 1;
6857 plist->clear();
6861 return 0;
6862 first = 0;
6863 plist->push_back(lpfdata->cFileName);
6864 while (FindNextFile(pffile, lpfdata)) {
6865 plist->push_back(lpfdata->cFileName);
6866 }
6867 free(lpfdata);
6868#endif
6869 return plist->size();
6870}
@ DIR
Definition test_init.cxx:7
Here is the call graph for this function:

◆ ss_directio_give_port()

INT EXPRT ss_directio_give_port ( INT  start,
INT  end 
)

Definition at line 7811 of file system.cxx.

7812{
7813#ifdef OS_WINNT
7814
7815 /* under Windows NT, use DirectIO driver to open ports */
7816
7818 HANDLE hdio = 0;
7819 DWORD buffer[] = { 6, 0, 0, 0 };
7820 DWORD size;
7821
7822 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7823 GetVersionEx(&vi);
7824
7825 /* use DirectIO driver under NT to gain port access */
7826 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
7827 hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7828 if (hdio == INVALID_HANDLE_VALUE) {
7829 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
7830 return -1;
7831 }
7832
7833 /* open ports */
7834 buffer[1] = start;
7835 buffer[2] = end;
7836 if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
7837 return -1;
7838 }
7839
7840 return SS_SUCCESS;
7841#else
7842 return SS_SUCCESS;
7843#endif
7844}
#define end
Here is the call graph for this function:

◆ ss_directio_lock_port()

INT EXPRT ss_directio_lock_port ( INT  start,
INT  end 
)

Definition at line 7847 of file system.cxx.

7848{
7849#ifdef OS_WINNT
7850
7851 /* under Windows NT, use DirectIO driver to lock ports */
7852
7854 HANDLE hdio;
7855 DWORD buffer[] = { 7, 0, 0, 0 };
7856 DWORD size;
7857
7858 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7859 GetVersionEx(&vi);
7860
7861 /* use DirectIO driver under NT to gain port access */
7862 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
7863 hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7864 if (hdio == INVALID_HANDLE_VALUE) {
7865 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
7866 return -1;
7867 }
7868
7869 /* lock ports */
7870 buffer[1] = start;
7871 buffer[2] = end;
7872 if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
7873 return -1;
7874 }
7875
7876 return SS_SUCCESS;
7877#else
7878 return SS_SUCCESS;
7879#endif
7880}
Here is the call graph for this function:

◆ ss_dirlink_find() [1/2]

INT EXPRT ss_dirlink_find ( const char path,
const char pattern,
char **  plist 
)

Definition at line 6872 of file system.cxx.

6873{
6875
6876 int count = ss_dirlink_find(path, pattern, &list);
6877 if (count <= 0)
6878 return count;
6879
6880 size_t size = list.size();
6881 *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6882 for (size_t i=0; i<size; i++) {
6883 //printf("file %d [%s]\n", (int)i, list[i].c_str());
6885 }
6886
6887 return size;
6888}
INT ss_dirlink_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6872
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_dirlink_find() [2/2]

INT EXPRT ss_dirlink_find ( const char path,
const char pattern,
STRING_LIST plist 
)

Definition at line 6890 of file system.cxx.

6908{
6909 assert(plist);
6910#ifdef OS_UNIX
6912 struct dirent *dp;
6913
6914 if ((dir_pointer = opendir(path)) == NULL)
6915 return 0;
6916 plist->clear();
6917 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6918 if (fnmatch(pattern, dp->d_name, 0) == 0) {
6919 /* must have a "/" at the end, otherwise also links to files are accepted */
6920 std::string full_path = std::string(path) + "/" + dp->d_name + "/";
6921 struct stat st;
6922 if (lstat(full_path.c_str(), &st) == 0 && (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) {
6923 plist->push_back(dp->d_name);
6924 }
6925 }
6926 }
6928#endif
6929#ifdef OS_WINNT
6930 char str[255];
6931 int first;
6932
6933 strcpy(str, path);
6934 strcat(str, "\\");
6935 strcat(str, pattern);
6936 first = 1;
6937 plist->clear();
6941 return 0;
6942 first = 0;
6943 plist->push_back(lpfdata->cFileName);
6944 while (FindNextFile(pffile, lpfdata)) {
6945 plist->push_back(lpfdata->cFileName);
6946 }
6947 free(lpfdata);
6948#endif
6949 return plist->size();
6950}
Here is the call graph for this function:

◆ ss_disk_free()

double EXPRT ss_disk_free ( const char path)

Definition at line 6620 of file system.cxx.

6636{
6637#ifdef OS_UNIX
6638#if defined(OS_OSF1)
6639 struct statfs st;
6640 statfs(path, &st, sizeof(st));
6641 return (double) st.f_bavail * st.f_bsize;
6642#elif defined(OS_LINUX)
6643 struct statfs st;
6644 int status;
6645 status = statfs(path, &st);
6646 if (status != 0)
6647 return -1;
6648 return (double) st.f_bavail * st.f_bsize;
6649#elif defined(OS_SOLARIS)
6650 struct statvfs st;
6651 statvfs(path, &st);
6652 return (double) st.f_bavail * st.f_bsize;
6653#elif defined(OS_IRIX)
6654 struct statfs st;
6655 statfs(path, &st, sizeof(struct statfs), 0);
6656 return (double) st.f_bfree * st.f_bsize;
6657#else
6658 struct fs_data st;
6659 statfs(path, &st);
6660 return (double) st.fd_otsize * st.fd_bfree;
6661#endif
6662
6663#elif defined(OS_WINNT) /* OS_UNIX */
6668 char str[80];
6669
6670 strcpy(str, path);
6671 if (strchr(str, ':') != NULL) {
6672 *(strchr(str, ':') + 1) = 0;
6675 } else
6677
6679#else /* OS_WINNT */
6680
6681 return 1e9;
6682
6683#endif
6684}
#define DIR_SEPARATOR_STR
Definition midas.h:194
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_disk_size()

double EXPRT ss_disk_size ( const char path)

Definition at line 7048 of file system.cxx.

7064{
7065#ifdef OS_UNIX
7066#if defined(OS_OSF1)
7067 struct statfs st;
7068 statfs(path, &st, sizeof(st));
7069 return (double) st.f_blocks * st.f_fsize;
7070#elif defined(OS_LINUX)
7071 int status;
7072 struct statfs st;
7073 status = statfs(path, &st);
7074 if (status != 0)
7075 return -1;
7076 return (double) st.f_blocks * st.f_bsize;
7077#elif defined(OS_SOLARIS)
7078 struct statvfs st;
7079 statvfs(path, &st);
7080 if (st.f_frsize > 0)
7081 return (double) st.f_blocks * st.f_frsize;
7082 else
7083 return (double) st.f_blocks * st.f_bsize;
7084#elif defined(OS_ULTRIX)
7085 struct fs_data st;
7086 statfs(path, &st);
7087 return (double) st.fd_btot * 1024;
7088#elif defined(OS_IRIX)
7089 struct statfs st;
7090 statfs(path, &st, sizeof(struct statfs), 0);
7091 return (double) st.f_blocks * st.f_bsize;
7092#else
7093#error ss_disk_size not defined for this OS
7094#endif
7095#endif /* OS_UNIX */
7096
7097#ifdef OS_WINNT
7102 char str[80];
7103
7104 strcpy(str, path);
7105 if (strchr(str, ':') != NULL) {
7106 *(strchr(str, ':') + 1) = 0;
7109 } else
7111
7113#endif /* OS_WINNT */
7114
7115 return 1e9;
7116}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_event_socket_has_data()

bool ss_event_socket_has_data ( )

Definition at line 4520 of file system.cxx.

4521{
4523 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4524 /* event channel */
4525 int sock = (*_ss_server_acceptions)[i]->event_sock;
4526
4527 if (!sock)
4528 continue;
4529
4530 /* check for buffered event */
4531 int status = ss_socket_wait(sock, 1);
4532
4533 if (status == SS_SUCCESS)
4534 return true;
4535 }
4536 }
4537
4538 /* no event socket or no data in event socket */
4539 return false;
4540}
static RPC_SERVER_ACCEPTION_LIST * _ss_server_acceptions
Definition system.cxx:3990
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_exception_handler()

INT ss_exception_handler ( void(*)(void func)

Definition at line 3844 of file system.cxx.

3863{
3864#ifdef OS_WINNT
3865
3866 MidasExceptionHandler = func;
3867/* SetUnhandledExceptionFilter(
3868 (LPTOP_LEVEL_EXCEPTION_FILTER) MidasExceptionFilter);
3869
3870 signal(SIGINT, MidasExceptionSignal);
3871 signal(SIGILL, MidasExceptionSignal);
3872 signal(SIGFPE, MidasExceptionSignal);
3873 signal(SIGSEGV, MidasExceptionSignal);
3874 signal(SIGTERM, MidasExceptionSignal);
3875 signal(SIGBREAK, MidasExceptionSignal);
3876 signal(SIGABRT, MidasExceptionSignal); */
3877
3878#elif defined (OS_VMS)
3879
3880 MidasExceptionHandler = func;
3882
3889
3890#else /* OS_VMS */
3891#endif
3892
3893 return SS_SUCCESS;
3894}
void(* MidasExceptionHandler)(void)
Definition system.cxx:3789
Here is the call graph for this function:

◆ ss_exec()

INT EXPRT ss_exec ( const char command,
INT pid 
)

Definition at line 2132 of file system.cxx.

2151{
2152#ifdef OS_UNIX
2153
2154 /* only implemented for UNIX */
2155 int i, fd;
2156
2157#ifdef NO_FORK
2158 assert(!"support for fork() disabled by NO_FORK");
2159#else
2160 *pid = fork();
2161#endif
2162 if (*pid < 0)
2163 return SS_ABORT;
2164 else if (*pid != 0) {
2165 /* avoid <defunc> parent processes */
2167 return SS_SUCCESS; /* parent returns */
2168 }
2169
2170 /* child continues here... */
2171
2172 /* close all open file descriptors */
2173 for (i = 0; i < 256; i++)
2174 close(i);
2175
2176 /* try and use up stdin, stdout and stderr, so other
2177 routines writing to stdout etc won't cause havoc */
2178 for (i = 0; i < 3; i++) {
2179 fd = open("/dev/null", O_RDWR, 0);
2180 if (fd < 0)
2181 fd = open("/dev/null", O_WRONLY, 0);
2182 if (fd < 0) {
2183 cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
2184 return SS_ABORT;
2185 }
2186 if (fd != i) {
2187 cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
2188 return SS_ABORT;
2189 }
2190 }
2191
2192 setsid(); /* become session leader */
2193 /* chdir("/"); *//* change working directory (not on NFS!) */
2194
2195 /* execute command */
2196 int error = execl("/bin/sh", "sh", "-c", command, NULL);
2197 // NB: execl() does not return unless there is an error. K.O.
2198 fprintf(stderr, "ss_shell: Cannot execute /bin/sh for command \"%s\": execl() returned %d, errno %d (%s), aborting!\n", command, error, errno, strerror(errno));
2199 abort();
2200
2201#else
2202
2203 system(command);
2204
2205#endif
2206
2207 return SS_SUCCESS;
2208}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_execs()

std::string EXPRT ss_execs ( const char cmd)

Definition at line 2237 of file system.cxx.

2252{
2253#ifdef OS_UNIX
2254 std::array<char, 256> buffer{};
2255 std::string result;
2256 auto pclose_deleter = [](FILE* f) { pclose(f); };
2257 auto pipe = std::unique_ptr<FILE, decltype(pclose_deleter)>(
2258 popen(cmd, "r"),
2260 );
2261
2262 if (!pipe) {
2263 throw std::runtime_error("popen() failed!");
2264 }
2265
2266 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
2267 result += buffer.data();
2268 }
2269
2270 return result;
2271#else
2272 fprintf(stderr, "ss_execs: Function not supported on this OS, aborting!\n");
2273 abort();
2274#endif
2275}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_existpid()

BOOL EXPRT ss_existpid ( INT  pid)

Definition at line 2068 of file system.cxx.

2086{
2087#ifdef OS_UNIX
2088 /* only implemented for UNIX */
2089 return (kill(pid, 0) == 0 ? TRUE : FALSE);
2090#else
2091 cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
2092 return FALSE;
2093#endif
2094}
#define FALSE
Definition cfortran.h:309
#define MINFO
Definition midas.h:560
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_copy()

int EXPRT ss_file_copy ( const char src,
const char dst,
bool  append 
)

Definition at line 7219 of file system.cxx.

7236{
7237 int fd_to, fd_from;
7238 char buf[4096];
7239 ssize_t nread;
7240 int saved_errno;
7241
7242 fd_from = open(src, O_RDONLY);
7243 if (fd_from < 0)
7244 return -1;
7245
7246 if (append)
7247 fd_to = open(dst, O_WRONLY | O_CREAT | O_EXCL | O_APPEND, 0666);
7248 else
7249 fd_to = open(dst, O_WRONLY | O_CREAT | O_EXCL, 0666);
7250 if (fd_to < 0)
7251 goto out_error;
7252
7253 while (nread = read(fd_from, buf, sizeof(buf)), nread > 0) {
7254 char *out_ptr = buf;
7256
7257 do {
7259
7260 if (nwritten >= 0) {
7261 nread -= nwritten;
7262 out_ptr += nwritten;
7263 } else if (errno != EINTR) {
7264 goto out_error;
7265 }
7266 } while (nread > 0);
7267 }
7268
7269 if (nread == 0) {
7270 if (close(fd_to) < 0) {
7271 fd_to = -1;
7272 goto out_error;
7273 }
7274 close(fd_from);
7275
7276 /* Success! */
7277 return 0;
7278 }
7279
7280 out_error:
7282
7283 close(fd_from);
7284 if (fd_to >= 0)
7285 close(fd_to);
7286
7288 return -1;
7289}
#define read(n, a, f)
#define write(n, a, f, d)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_exist()

INT EXPRT ss_file_exist ( const char path)

Definition at line 7118 of file system.cxx.

7135{
7136#ifdef OS_UNIX
7137 struct stat buf;
7138
7139 int retval = stat(path, &buf);
7140 //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7141 if (retval < 0)
7142 return 0;
7143 if (S_ISDIR(buf.st_mode))
7144 return 0;
7145#endif
7146
7147 int fd = open(path, O_RDONLY, 0);
7148 if (fd < 0)
7149 return 0;
7150 close(fd);
7151 return 1;
7152}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_find() [1/2]

INT EXPRT ss_file_find ( const char path,
const char pattern,
char **  plist 
)

Definition at line 6713 of file system.cxx.

6714{
6716
6717 int count = ss_file_find(path, pattern, &list);
6718 if (count <= 0)
6719 return count;
6720
6721 size_t size = list.size();
6722 *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6723 for (size_t i=0; i<size; i++) {
6724 //printf("file %d [%s]\n", (int)i, list[i].c_str());
6726 }
6727
6728 return size;
6729}
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6713
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_find() [2/2]

INT EXPRT ss_file_find ( const char path,
const char pattern,
STRING_LIST plist 
)

Definition at line 6731 of file system.cxx.

6749{
6750 assert(plist);
6751 // Check if the directory exists
6752 if (access(path, F_OK) != 0) {
6753 return -1; // Return -1 files if directory doesn't exist
6754 }
6755
6756#ifdef OS_UNIX
6758 struct dirent *dp;
6759
6760 plist->clear();
6761 if ((dir_pointer = opendir(path)) == NULL)
6762 return 0;
6763 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6764 if (fnmatch(pattern, dp->d_name, 0) == 0 && (dp->d_type == DT_REG || dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN)) {
6765 plist->push_back(dp->d_name);
6767 }
6768 }
6770#endif
6771#ifdef OS_WINNT
6772 char str[255];
6773 int first;
6774
6775 strcpy(str, path);
6776 strcat(str, "\\");
6777 strcat(str, pattern);
6778 first = 1;
6780 *plist->clear();
6783 return 0;
6784 first = 0;
6785 plist->push_back(lpfdata->cFileName);
6786 i++;
6787 while (FindNextFile(pffile, lpfdata)) {
6788 plist->push_back(lpfdata->cFileName);
6789 i++;
6790 }
6791 free(lpfdata);
6792#endif
6793 return plist->size();
6794}
Here is the call graph for this function:

◆ ss_file_link_exist()

INT EXPRT ss_file_link_exist ( const char path)

Definition at line 7154 of file system.cxx.

7171{
7172#ifdef OS_UNIX
7173 struct stat buf;
7174
7175 int retval = lstat(path, &buf);
7176 if (retval < 0)
7177 return 0;
7178 if (S_ISLNK(buf.st_mode))
7179 return 1;
7180 return 0;
7181#endif
7182
7183 return 0;
7184}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_remove()

INT EXPRT ss_file_remove ( const char path)

Definition at line 6952 of file system.cxx.

6968{
6969 return remove(path);
6970}
static std::string remove(const std::string s, char c)
Definition mjsonrpc.cxx:253
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_size()

double EXPRT ss_file_size ( const char path)

Definition at line 6972 of file system.cxx.

6988{
6989#ifdef _LARGEFILE64_SOURCE
6990 struct stat64 stat_buf;
6991 int status;
6992
6993 /* allocate buffer with file size */
6994 status = stat64(path, &stat_buf);
6995 if (status != 0)
6996 return -1;
6997 return (double) stat_buf.st_size;
6998#else
6999 struct stat stat_buf;
7000 int status;
7001
7002 /* allocate buffer with file size */
7003 status = stat(path, &stat_buf);
7004 if (status != 0)
7005 return -1;
7006 return (double) stat_buf.st_size;
7007#endif
7008}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_time()

time_t EXPRT ss_file_time ( const char path)

Definition at line 7010 of file system.cxx.

7026{
7027#ifdef _LARGEFILE64_SOURCE
7028 struct stat64 stat_buf;
7029 int status;
7030
7031 /* allocate buffer with file size */
7032 status = stat64(path, &stat_buf);
7033 if (status != 0)
7034 return -1;
7035 return stat_buf.st_mtime;
7036#else
7037 struct stat stat_buf;
7038 int status;
7039
7040 /* allocate buffer with file size */
7041 status = stat(path, &stat_buf);
7042 if (status != 0)
7043 return -1;
7044 return stat_buf.st_mtime;
7045#endif
7046}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_get_executable()

std::string ss_get_executable ( void  )

Definition at line 1488 of file system.cxx.

1499{
1500 char path[PATH_MAX];
1501
1502#if defined(OS_DARWIN)
1503 uint32_t size = sizeof(path);
1504 if (_NSGetExecutablePath(path, &size) == 0)
1505 return path;
1506#elif defined(OS_LINUX)
1507
1508 ssize_t count = readlink("/proc/self/exe", path, PATH_MAX);
1509 if (count != -1) {
1510 path[count] = '\0'; // Null-terminate the string
1511 return std::string(path);
1512 }
1513#endif
1514 return "";
1515}
#define PATH_MAX
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_get_struct_align()

INT EXPRT ss_get_struct_align ( )

Definition at line 1319 of file system.cxx.

1341{
1342 return (POINTER_T) (&test_align.d) - (POINTER_T) & test_align.c;
1343}
static struct @3 test_align
#define POINTER_T
Definition midas.h:166
Here is the caller graph for this function:

◆ ss_get_struct_padding()

INT EXPRT ss_get_struct_padding ( )

Definition at line 1345 of file system.cxx.

1366{
1367 return (INT) sizeof(test_padding) - 8;
1368}
static struct @4 test_padding

◆ ss_getchar()

INT EXPRT ss_getchar ( BOOL  reset)

Definition at line 7503 of file system.cxx.

7523{
7524#ifdef OS_UNIX
7525
7526 static BOOL init = FALSE;
7527 static struct termios save_termios;
7528 struct termios buf;
7529 int i, fd;
7530 char c[3];
7531
7532 if (_daemon_flag)
7533 return 0;
7534
7535 fd = fileno(stdin);
7536
7537 if (reset) {
7538 if (init)
7540 init = FALSE;
7541 return 0;
7542 }
7543
7544 if (!init) {
7545 tcgetattr(fd, &save_termios);
7546 memcpy(&buf, &save_termios, sizeof(buf));
7547
7548 buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
7549
7550 buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
7551
7552 buf.c_cflag &= ~(CSIZE | PARENB);
7553 buf.c_cflag |= CS8;
7554 /* buf.c_oflag &= ~(OPOST); */
7555 buf.c_cc[VMIN] = 0;
7556 buf.c_cc[VTIME] = 0;
7557
7558 tcsetattr(fd, TCSAFLUSH, &buf);
7559 init = TRUE;
7560 }
7561
7562 memset(c, 0, 3);
7563 i = read(fd, c, 1);
7564
7565 if (i == 0)
7566 return 0;
7567
7568 /* check if ESC */
7569 if (c[0] == 27) {
7570 i = read(fd, c, 2);
7571 if (i == 0) /* return if only ESC */
7572 return 27;
7573
7574 /* cursor keys return 2 chars, others 3 chars */
7575 if (c[1] < 65) {
7576 i = read(fd, c, 1);
7577 }
7578
7579 /* convert ESC sequence to CH_xxx */
7580 switch (c[1]) {
7581 case 49:
7582 return CH_HOME;
7583 case 50:
7584 return CH_INSERT;
7585 case 51:
7586 return CH_DELETE;
7587 case 52:
7588 return CH_END;
7589 case 53:
7590 return CH_PUP;
7591 case 54:
7592 return CH_PDOWN;
7593 case 65:
7594 return CH_UP;
7595 case 66:
7596 return CH_DOWN;
7597 case 67:
7598 return CH_RIGHT;
7599 case 68:
7600 return CH_LEFT;
7601 }
7602 }
7603
7604 /* BS/DEL -> BS */
7605 if (c[0] == 127)
7606 return CH_BS;
7607
7608 return c[0];
7609
7610#elif defined(OS_WINNT)
7611
7612 static BOOL init = FALSE;
7613 static INT repeat_count = 0;
7614 static INT repeat_char;
7619
7620 /* find out if we are under W95 */
7621 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7622 GetVersionEx(&vi);
7623
7624 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
7625 /* under W95, console doesn't work properly */
7626 int c;
7627
7628 if (!kbhit())
7629 return 0;
7630
7631 c = getch();
7632 if (c == 224) {
7633 c = getch();
7634 switch (c) {
7635 case 71:
7636 return CH_HOME;
7637 case 72:
7638 return CH_UP;
7639 case 73:
7640 return CH_PUP;
7641 case 75:
7642 return CH_LEFT;
7643 case 77:
7644 return CH_RIGHT;
7645 case 79:
7646 return CH_END;
7647 case 80:
7648 return CH_DOWN;
7649 case 81:
7650 return CH_PDOWN;
7651 case 82:
7652 return CH_INSERT;
7653 case 83:
7654 return CH_DELETE;
7655 }
7656 }
7657 return c;
7658 }
7659
7661
7662 if (reset) {
7664 init = FALSE;
7665 return 0;
7666 }
7667
7668 if (!init) {
7670 init = TRUE;
7671 }
7672
7673 if (repeat_count) {
7674 repeat_count--;
7675 return repeat_char;
7676 }
7677
7679
7680 if (nCharsRead == 0)
7681 return 0;
7682
7684
7685 if (ir.EventType != KEY_EVENT)
7686 return ss_getchar(0);
7687
7688 if (!ir.Event.KeyEvent.bKeyDown)
7689 return ss_getchar(0);
7690
7691 if (ir.Event.KeyEvent.wRepeatCount > 1) {
7692 repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
7693 repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
7694 return repeat_char;
7695 }
7696
7697 if (ir.Event.KeyEvent.uChar.AsciiChar)
7698 return ir.Event.KeyEvent.uChar.AsciiChar;
7699
7700 if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
7701 switch (ir.Event.KeyEvent.wVirtualKeyCode) {
7702 case 33:
7703 return CH_PUP;
7704 case 34:
7705 return CH_PDOWN;
7706 case 35:
7707 return CH_END;
7708 case 36:
7709 return CH_HOME;
7710 case 37:
7711 return CH_LEFT;
7712 case 38:
7713 return CH_UP;
7714 case 39:
7715 return CH_RIGHT;
7716 case 40:
7717 return CH_DOWN;
7718 case 45:
7719 return CH_INSERT;
7720 case 46:
7721 return CH_DELETE;
7722 }
7723
7724 return ir.Event.KeyEvent.wVirtualKeyCode;
7725 }
7726
7727 return ss_getchar(0);
7728
7729#elif defined(OS_MSDOS)
7730
7731 int c;
7732
7733 if (!kbhit())
7734 return 0;
7735
7736 c = getch();
7737 if (!c) {
7738 c = getch();
7739 switch (c) {
7740 case 71:
7741 return CH_HOME;
7742 case 72:
7743 return CH_UP;
7744 case 73:
7745 return CH_PUP;
7746 case 75:
7747 return CH_LEFT;
7748 case 77:
7749 return CH_RIGHT;
7750 case 79:
7751 return CH_END;
7752 case 80:
7753 return CH_DOWN;
7754 case 81:
7755 return CH_PDOWN;
7756 case 82:
7757 return CH_INSERT;
7758 case 83:
7759 return CH_DELETE;
7760 }
7761 }
7762 return c;
7763
7764#else
7765 return -1;
7766#endif
7767}
INT ss_getchar(BOOL reset)
Definition system.cxx:7503
#define CH_END
Definition midas.h:455
#define CH_DOWN
Definition midas.h:459
#define CH_PUP
Definition midas.h:456
#define CH_DELETE
Definition midas.h:454
#define CH_RIGHT
Definition midas.h:460
#define CH_INSERT
Definition midas.h:453
#define CH_LEFT
Definition midas.h:461
#define CH_HOME
Definition midas.h:452
#define CH_UP
Definition midas.h:458
#define CH_BS
Definition midas.h:445
#define CH_PDOWN
Definition midas.h:457
char c
Definition system.cxx:1310
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_getcwd()

std::string EXPRT ss_getcwd ( )

Definition at line 5770 of file system.cxx.

5771{
5772 char *s = getcwd(NULL, 0);
5773 if (s) {
5774 std::string cwd = s;
5775 free(s);
5776 //printf("ss_getcwd: %s\n", cwd.c_str());
5777 return cwd;
5778 } else {
5779 return "/GETCWD-FAILED-ON-US";
5780 }
5781}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_gethostname() [1/2]

std::string ss_gethostname ( )

Definition at line 5706 of file system.cxx.

5723{
5724 char buf[256];
5725 memset(buf, 0, sizeof(buf));
5726
5727 int status = gethostname(buf, sizeof(buf)-1);
5728
5729 //printf("gethostname %d (%s)\n", status, buffer);
5730
5731 if (status != 0) {
5732 cm_msg(MERROR, "ss_gethostname", "gethostname() errno %d (%s)", errno, strerror(errno));
5733 return "";
5734 }
5735
5736 return buf;
5737}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_gethostname() [2/2]

INT ss_gethostname ( char buffer,
int  buffer_size 
)

Definition at line 5740 of file system.cxx.

5757{
5758 std::string h = ss_gethostname();
5759
5760 if (h.length() == 0) {
5761 return SS_IO_ERROR;
5762 } else {
5763 mstrlcpy(buffer, h.c_str(), buffer_size);
5764 return SS_SUCCESS;
5765 }
5766}
#define SS_IO_ERROR
Definition midas.h:681
std::string ss_gethostname()
Definition system.cxx:5706
Here is the call graph for this function:

◆ ss_getpass()

char EXPRT * ss_getpass ( const char prompt)

Definition at line 7440 of file system.cxx.

7457{
7458 static char password[32];
7459
7460 fprintf(stdout, "%s", prompt);
7461 fflush(stdout);
7462 memset(password, 0, sizeof(password));
7463
7464#ifdef OS_UNIX
7465 return (char *) getpass("");
7466#elif defined(OS_WINNT)
7467 {
7470
7473 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
7475 printf("\n");
7476
7477 if (password[strlen(password) - 1] == '\r')
7478 password[strlen(password) - 1] = 0;
7479
7480 return password;
7481 }
7482#elif defined(OS_MSDOS)
7483 {
7484 char c, *ptr;
7485
7486 ptr = password;
7487 while ((c = getchar()) != EOF && c != '\n')
7488 *ptr++ = c;
7489 *ptr = 0;
7490
7491 printf("\n");
7492 return password;
7493 }
7494#else
7495 {
7496 ss_gets(password, 32);
7497 return password;
7498 }
7499#endif
7500}
char * ss_gets(char *string, int size)
Definition system.cxx:7770
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_getpid()

INT EXPRT ss_getpid ( void  )

Definition at line 1377 of file system.cxx.

1394{
1395#ifdef OS_WINNT
1396
1397 return (int) GetCurrentProcessId();
1398
1399#endif /* OS_WINNT */
1400#ifdef OS_VMS
1401
1402 return getpid();
1403
1404#endif /* OS_VMS */
1405#ifdef OS_UNIX
1406
1407 return getpid();
1408
1409#endif /* OS_UNIX */
1410#ifdef OS_VXWORKS
1411
1412 return 0;
1413
1414#endif /* OS_VXWORKS */
1415#ifdef OS_MSDOS
1416
1417 return 0;
1418
1419#endif /* OS_MSDOS */
1420}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_gets()

char EXPRT * ss_gets ( char string,
int  size 
)

Definition at line 7770 of file system.cxx.

7789{
7790 char *p;
7791
7792 do {
7793 p = fgets(string, size, stdin);
7794 } while (p == NULL);
7795
7796
7797 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
7798 p[strlen(p) - 1] = 0;
7799
7800 return p;
7801}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_gettid()

midas_thread_t EXPRT ss_gettid ( void  )

Definition at line 1519 of file system.cxx.

1536{
1537#if defined OS_MSDOS
1538
1539 return 0;
1540
1541#elif defined OS_WINNT
1542
1543 return GetCurrentThreadId();
1544
1545#elif defined OS_VMS
1546
1547 return ss_getpid();
1548
1549#elif defined OS_DARWIN
1550
1551 return pthread_self();
1552
1553#elif defined OS_CYGWIN
1554
1555 return pthread_self();
1556
1557#elif defined OS_UNIX
1558
1559 return pthread_self();
1560 //return syscall(SYS_gettid);
1561
1562#elif defined OS_VXWORKS
1563
1564 return ss_getpid();
1565
1566#else
1567#error Do not know how to do ss_gettid()
1568#endif
1569}
INT ss_getpid(void)
Definition system.cxx:1377
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_is_valid_utf8()

bool ss_is_valid_utf8 ( const char string)

Definition at line 8068 of file system.cxx.

8069{
8070 assert(string);
8071
8072 // FIXME: this function over-reads the input array. K.O. May 2021
8073
8074 const unsigned char * bytes = (const unsigned char *)string;
8075 while(*bytes) {
8076 if( (// ASCII
8077 // use bytes[0] <= 0x7F to allow ASCII control characters
8078 bytes[0] == 0x09 ||
8079 bytes[0] == 0x0A ||
8080 bytes[0] == 0x0D ||
8081 (0x20 <= bytes[0] && bytes[0] <= 0x7E)
8082 )
8083 ) {
8084 bytes += 1;
8085 continue;
8086 }
8087
8088 if( (// non-overlong 2-byte
8089 (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
8090 (0x80 <= bytes[1] && bytes[1] <= 0xBF)
8091 )
8092 ) {
8093 bytes += 2;
8094 continue;
8095 }
8096
8097 if( (// excluding overlongs
8098 bytes[0] == 0xE0 &&
8099 (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
8100 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8101 ) ||
8102 (// straight 3-byte
8103 ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
8104 bytes[0] == 0xEE ||
8105 bytes[0] == 0xEF) &&
8106 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8107 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8108 ) ||
8109 (// excluding surrogates
8110 bytes[0] == 0xED &&
8111 (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
8112 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8113 )
8114 ) {
8115 bytes += 3;
8116 continue;
8117 }
8118
8119 if( (// planes 1-3
8120 bytes[0] == 0xF0 &&
8121 (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
8122 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8123 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8124 ) ||
8125 (// planes 4-15
8126 (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
8127 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8128 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8129 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8130 ) ||
8131 (// plane 16
8132 bytes[0] == 0xF4 &&
8133 (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
8134 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8135 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8136 )
8137 ) {
8138 bytes += 4;
8139 continue;
8140 }
8141
8142 //printf("ss_is_valid_utf8(): string [%s], not utf8 at offset %d, byte %d, [%s]\n", string, (int)((char*)bytes-(char*)string), (int)(0xFF&bytes[0]), bytes);
8143 //abort();
8144
8145 return false;
8146 }
8147
8148 return true;
8149}
Here is the caller graph for this function:

◆ ss_isfin()

int EXPRT ss_isfin ( double  x)

Definition at line 7966 of file system.cxx.

7967{
7968#ifdef FP_INFINITE
7969 /* new-style finite() */
7970 return isfinite(x);
7971#else
7972 /* old-style finite() */
7973 return finite(x);
7974#endif
7975}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_isnan()

int EXPRT ss_isnan ( double  x)

Definition at line 7961 of file system.cxx.

7962{
7963 return isnan(x);
7964}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_kbhit()

BOOL EXPRT ss_kbhit ( )

Definition at line 3664 of file system.cxx.

3682{
3683#ifdef OS_MSDOS
3684
3685 return kbhit();
3686
3687#endif /* OS_MSDOS */
3688#ifdef OS_WINNT
3689
3690 return kbhit();
3691
3692#endif /* OS_WINNT */
3693#ifdef OS_VMS
3694
3695 return FALSE;
3696
3697#endif /* OS_VMS */
3698#ifdef OS_UNIX
3699
3700 int n;
3701
3702 if (_daemon_flag)
3703 return 0;
3704
3705 ioctl(0, FIONREAD, &n);
3706 return (n > 0);
3707
3708#endif /* OS_UNIX */
3709#ifdef OS_VXWORKS
3710
3711 int n;
3712 ioctl(0, FIONREAD, (long) &n);
3713 return (n > 0);
3714
3715#endif /* OS_UNIX */
3716}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_kill()

void ss_kill ( int  pid)

Definition at line 1471 of file system.cxx.

1472{
1473#ifdef SIGKILL
1474 kill(pid, SIGKILL);
1475#else
1476#warning Missing SIGKILL for ss_kill()
1477#endif
1478}
Here is the call graph for this function:

◆ ss_match_thread()

static bool ss_match_thread ( midas_thread_t  tid1,
midas_thread_t  tid2 
)
static

Definition at line 3993 of file system.cxx.

3994{
3995 if (tid1 == 0)
3996 return true;
3997 if (tid1 == tid2)
3998 return true;
3999 return false;
4000}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_millitime()

DWORD EXPRT ss_millitime ( )

Returns the actual time in milliseconds with an arbitrary origin. This time may only be used to calculate relative times.

Overruns in the 32 bit value don't hurt since in a subtraction calculated with 32 bit accuracy this overrun cancels (you may think about!)..

...
DWORD start, stop:
start = ss_millitime();
< do operations >
printf("Operation took %1.3lf seconds\n",(stop-start)/1000.0);
...
DWORD ss_millitime()
Definition system.cxx:3393
Returns
millisecond time stamp.

Definition at line 3393 of file system.cxx.

3394{
3395#ifdef OS_WINNT
3396
3397 return (int) GetTickCount();
3398
3399#endif /* OS_WINNT */
3400#ifdef OS_MSDOS
3401
3402 return clock() * 55;
3403
3404#endif /* OS_MSDOS */
3405#ifdef OS_VMS
3406
3407 {
3408 char time[8];
3409 DWORD lo, hi;
3410
3411 sys$gettim(time);
3412
3413 lo = *((DWORD *) time);
3414 hi = *((DWORD *) (time + 4));
3415
3416/* return *lo / 10000; */
3417
3418 return lo / 10000 + hi * 429496.7296;
3419
3420 }
3421
3422#endif /* OS_VMS */
3423#ifdef OS_UNIX
3424 {
3425 struct timeval tv;
3426
3427 gettimeofday(&tv, NULL);
3428
3429 DWORD m = tv.tv_sec * 1000 + tv.tv_usec / 1000;
3430 //m += 0x137e0000; // adjust milltime for testing 32-bit wrap-around
3431 return m;
3432 }
3433
3434#endif /* OS_UNIX */
3435#ifdef OS_VXWORKS
3436 {
3437 int count;
3438 static int ticks_per_msec = 0;
3439
3440 if (ticks_per_msec == 0)
3441 ticks_per_msec = 1000 / sysClkRateGet();
3442
3443 return tickGet() * ticks_per_msec;
3444 }
3445#endif /* OS_VXWORKS */
3446}
int gettimeofday(struct timeval *tp, void *tzp)
timeval tv
Definition msysmon.cxx:1095
Here is the call graph for this function:

◆ ss_mktime()

time_t EXPRT ss_mktime ( struct tm tms)

Definition at line 3365 of file system.cxx.

3366{
3367 std::lock_guard<std::mutex> lock(gTzMutex);
3368 //defeat mktime() error trap from msystem.h
3369 //#ifdef mktime
3370 //#undef mktime
3371 //#endif
3372 return mktime(tms);
3373}
static std::mutex gTzMutex
Definition system.cxx:3353
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_mutex_create()

INT EXPRT ss_mutex_create ( MUTEX_T **  mutex,
BOOL  recursive 
)

Definition at line 2941 of file system.cxx.

2956{
2957#ifdef OS_VXWORKS
2958
2959 /* semBCreate is a Binary semaphore which is under VxWorks a optimized mutex
2960 refering to the programmer's Guide 5.3.1 */
2962 return SS_NO_MUTEX;
2963 return SS_CREATED;
2964
2965#endif /* OS_VXWORKS */
2966
2967#ifdef OS_WINNT
2968
2969 *mutex = (MUTEX_T *)malloc(sizeof(HANDLE));
2970 **mutex = CreateMutex(NULL, FALSE, NULL);
2971
2972 if (**mutex == 0)
2973 return SS_NO_MUTEX;
2974
2975 return SS_CREATED;
2976
2977#endif /* OS_WINNT */
2978#ifdef OS_UNIX
2979
2980 {
2981 int status;
2983
2984 attr = (pthread_mutexattr_t*)malloc(sizeof(*attr));
2985 assert(attr);
2986
2988 if (status != 0) {
2989 fprintf(stderr, "ss_mutex_create: pthread_mutexattr_init() returned errno %d (%s)\n", status, strerror(status));
2990 }
2991
2992 if (recursive) {
2994 if (status != 0) {
2995 fprintf(stderr, "ss_mutex_create: pthread_mutexattr_settype() returned errno %d (%s)\n", status, strerror(status));
2996 }
2997 }
2998
2999 *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
3000 assert(*mutex);
3001
3002 status = pthread_mutex_init(*mutex, attr);
3003 if (status != 0) {
3004 fprintf(stderr, "ss_mutex_create: pthread_mutex_init() returned errno %d (%s), aborting...\n", status, strerror(status));
3005 abort(); // does not return
3006 return SS_NO_MUTEX;
3007 }
3008
3009 free(attr);
3010
3011 if (recursive) {
3012 // test recursive locks
3013
3014 status = pthread_mutex_trylock(*mutex);
3015 assert(status == 0);
3016
3017 status = pthread_mutex_trylock(*mutex);
3018 assert(status == 0); // EBUSY if PTHREAD_MUTEX_RECURSIVE does not work
3019
3020 status = pthread_mutex_unlock(*mutex);
3021 assert(status == 0);
3022
3023 status = pthread_mutex_unlock(*mutex);
3024 assert(status == 0);
3025 }
3026
3027 return SS_SUCCESS;
3028 }
3029#endif /* OS_UNIX */
3030
3031#ifdef OS_MSDOS
3032 return SS_NO_SEMAPHORE;
3033#endif
3034}
#define SS_NO_MUTEX
Definition midas.h:691
#define SS_NO_SEMAPHORE
Definition midas.h:670
#define SS_CREATED
Definition midas.h:664
INT MUTEX_T
Definition midas.h:237
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_mutex_delete()

INT EXPRT ss_mutex_delete ( MUTEX_T mutex)

Definition at line 3211 of file system.cxx.

3229{
3230#ifdef OS_WINNT
3231
3232 if (CloseHandle(*mutex) == FALSE)
3233 return SS_NO_SEMAPHORE;
3234
3235 free(mutex);
3236
3237 return SS_SUCCESS;
3238
3239#endif /* OS_WINNT */
3240#ifdef OS_VXWORKS
3241 /* no code for VxWorks destroy yet */
3243 return SS_NO_MUTEX;
3244 return SS_SUCCESS;
3245#endif /* OS_VXWORKS */
3246
3247#ifdef OS_UNIX
3248 {
3249 int status;
3250
3252 if (status != 0) {
3253 fprintf(stderr, "ss_mutex_delete: pthread_mutex_destroy() returned errno %d (%s), aborting...\n", status, strerror(status));
3254 abort(); // do not return
3255 return SS_NO_MUTEX;
3256 }
3257
3258 free(mutex);
3259 return SS_SUCCESS;
3260 }
3261#endif /* OS_UNIX */
3262}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_mutex_release()

INT EXPRT ss_mutex_release ( MUTEX_T mutex)

Definition at line 3157 of file system.cxx.

3175{
3176 INT status;
3177
3178#ifdef OS_WINNT
3179
3180 status = ReleaseMutex(*mutex);
3181 if (status == FALSE)
3182 return SS_NO_SEMAPHORE;
3183
3184 return SS_SUCCESS;
3185
3186#endif /* OS_WINNT */
3187#ifdef OS_VXWORKS
3188
3189 if (semGive((SEM_ID) mutes_handle) == ERROR)
3190 return SS_NO_MUTEX;
3191 return SS_SUCCESS;
3192#endif /* OS_VXWORKS */
3193#ifdef OS_UNIX
3194
3196 if (status != 0) {
3197 fprintf(stderr, "ss_mutex_release: pthread_mutex_unlock() returned error %d (%s), aborting...\n", status, strerror(status));
3198 abort(); // does not return
3199 return SS_NO_MUTEX;
3200 }
3201
3202 return SS_SUCCESS;
3203#endif /* OS_UNIX */
3204
3205#ifdef OS_MSDOS
3206 return SS_NO_MUTEX;
3207#endif
3208}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_mutex_wait_for()

INT EXPRT ss_mutex_wait_for ( MUTEX_T mutex,
INT  timeout 
)

Definition at line 3037 of file system.cxx.

3057{
3058 INT status;
3059
3060#ifdef OS_WINNT
3061
3062 status = WaitForSingleObject(*mutex, timeout == 0 ? INFINITE : timeout);
3063
3064 if (status == WAIT_TIMEOUT) {
3065 return SS_TIMEOUT;
3066 }
3067
3068 if (status == WAIT_FAILED) {
3069 fprintf(stderr, "ss_mutex_wait_for: WaitForSingleObject() failed, status = %d", status);
3070 abort(); // does not return
3071 return SS_NO_MUTEX;
3072 }
3073
3074 return SS_SUCCESS;
3075#endif /* OS_WINNT */
3076#ifdef OS_VXWORKS
3077 /* convert timeout in ticks (1/60) = 1000/60 ~ 1/16 = >>4 */
3078 status = semTake((SEM_ID) mutex, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
3079 if (status == ERROR)
3080 return SS_NO_MUTEX;
3081 return SS_SUCCESS;
3082
3083#endif /* OS_VXWORKS */
3084#if defined(OS_UNIX)
3085
3086#if defined(OS_DARWIN)
3087
3088 if (timeout > 0) {
3089 // emulate pthread_mutex_timedlock under OS_DARWIN
3090 DWORD wait = 0;
3091 while (1) {
3093 if (status == 0) {
3094 return SS_SUCCESS;
3095 } else if (status == EBUSY) {
3096 ss_sleep(10);
3097 wait += 10;
3098 } else {
3099 fprintf(stderr, "ss_mutex_wait_for: fatal error: pthread_mutex_trylock() returned errno %d (%s), aborting...\n", status, strerror(status));
3100 abort(); // does not return
3101 }
3102 if (wait > timeout) {
3103 fprintf(stderr, "ss_mutex_wait_for: fatal error: timeout waiting for mutex, timeout was %d millisec, aborting...\n", timeout);
3104 abort(); // does not return
3105 }
3106 }
3107 } else {
3108 status = pthread_mutex_lock(mutex);
3109 }
3110
3111 if (status != 0) {
3112 fprintf(stderr, "ss_mutex_wait_for: pthread_mutex_lock() returned errno %d (%s), aborting...\n", status, strerror(status));
3113 abort(); // does not return
3114 }
3115
3116 return SS_SUCCESS;
3117
3118#else // OS_DARWIN
3119 if (timeout > 0) {
3121 struct timespec st;
3122
3124 st.tv_sec += timeout / 1000;
3125 st.tv_nsec += (timeout % 1000) * 1000000;
3127
3128 if (status == ETIMEDOUT) {
3129 fprintf(stderr, "ss_mutex_wait_for: fatal error: timeout waiting for mutex, timeout was %d millisec, aborting...\n", timeout);
3130 abort();
3131 }
3132
3133 // Make linux timeout do same as MacOS timeout: abort() the program
3134 //if (status == ETIMEDOUT)
3135 // return SS_TIMEOUT;
3136 //return SS_SUCCESS;
3137 } else {
3138 status = pthread_mutex_lock(mutex);
3139 }
3140
3141 if (status != 0) {
3142 fprintf(stderr, "ss_mutex_wait_for: pthread_mutex_lock() returned errno %d (%s), aborting...\n", status, strerror(status));
3143 abort();
3144 }
3145
3146 return SS_SUCCESS;
3147#endif
3148
3149#endif /* OS_UNIX */
3150
3151#ifdef OS_MSDOS
3152 return SS_NO_MUTEX;
3153#endif
3154}
INT ss_sleep(INT millisec)
Definition system.cxx:3628
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_nan()

double EXPRT ss_nan ( )

Definition at line 7940 of file system.cxx.

7941{
7942 double nan;
7943
7944 nan = 0;
7945 nan = 0 / nan;
7946 return nan;
7947}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_pid_exists()

BOOL ss_pid_exists ( int  pid)

Definition at line 1440 of file system.cxx.

1441{
1442#ifdef ESRCH
1443 /* Only enable this for systems that define ESRCH and hope that they also support kill(pid,0) */
1444 int status = kill(pid, 0);
1445 //printf("kill(%d,0) returned %d, errno %d\n", pid, status, errno);
1446 if ((status != 0) && (errno == ESRCH)) {
1447 return FALSE;
1448 }
1449#else
1450#warning Missing ESRCH for ss_pid_exists()
1451#endif
1452 return TRUE;
1453}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_printf()

void EXPRT ss_printf ( INT  x,
INT  y,
const char format,
  ... 
)

Definition at line 7382 of file system.cxx.

7403{
7404 char str[256];
7406
7407 va_start(argptr, format);
7408 vsprintf(str, (char *) format, argptr);
7409 va_end(argptr);
7410
7411#ifdef OS_WINNT
7412 {
7416
7418
7419 dwWriteCoord.X = (short) x;
7420 dwWriteCoord.Y = (short) y;
7421
7423 }
7424
7425#endif /* OS_WINNT */
7426
7427#if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7428 printf("\033[%1d;%1dH", y + 1, x + 1);
7429 printf("%s", str);
7430 fflush(stdout);
7431#endif
7432
7433#ifdef OS_MSDOS
7434 gotoxy(x + 1, y + 1);
7435 cputs(str);
7436#endif
7437}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_recv_net_command()

INT EXPRT ss_recv_net_command ( int  sock,
DWORD routine_id,
DWORD param_size,
char **  param_ptr,
int  timeout_ms 
)

Definition at line 5629 of file system.cxx.

5652{
5654 size_t n;
5655
5656 /* first receive header */
5657 n = recv_tcp2(sock, (char*)&ncbuf, sizeof(ncbuf), timeout_ms);
5658
5659 if (n == 0) {
5660 cm_msg(MERROR, "ss_recv_net_command", "timeout receiving network command header");
5661 return SS_TIMEOUT;
5662 }
5663
5664 if (n != sizeof(ncbuf)) {
5665 cm_msg(MERROR, "ss_recv_net_command", "error receiving network command header, see messages");
5666 return SS_SOCKET_ERROR;
5667 }
5668
5669 // FIXME: where is the big-endian/little-endian conversion?
5670 *routine_id = ncbuf.routine_id;
5671 *param_size = ncbuf.param_size;
5672
5673 if (*param_size == 0) {
5674 *param_ptr = NULL;
5675 return SS_SUCCESS;
5676 }
5677
5678 *param_ptr = (char *)malloc(*param_size);
5679
5680 if (*param_ptr == NULL) {
5681 cm_msg(MERROR, "ss_recv_net_command", "error allocating %d bytes for network command data", *param_size);
5682 return SS_NO_MEMORY;
5683 }
5684
5685 /* first receive header */
5686 n = recv_tcp2(sock, *param_ptr, *param_size, timeout_ms);
5687
5688 if (n == 0) {
5689 cm_msg(MERROR, "ss_recv_net_command", "timeout receiving network command data");
5690 free(*param_ptr);
5691 *param_ptr = NULL;
5692 return SS_TIMEOUT;
5693 }
5694
5695 if (n != *param_size) {
5696 cm_msg(MERROR, "ss_recv_net_command", "error receiving network command data, see messages");
5697 free(*param_ptr);
5698 *param_ptr = NULL;
5699 return SS_SOCKET_ERROR;
5700 }
5701
5702 return SS_SUCCESS;
5703}
#define SS_NO_MEMORY
Definition midas.h:665
#define SS_SOCKET_ERROR
Definition midas.h:673
INT recv_tcp2(int sock, char *net_buffer, int buffer_size, int timeout_ms)
Definition system.cxx:5556
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_repair_utf8() [1/2]

bool ss_repair_utf8 ( char string)

Definition at line 8151 of file system.cxx.

8152{
8153 assert(string);
8154
8155 bool modified = false;
8156
8157 //std::string original = string;
8158
8159 // FIXME: this function over-reads the input array. K.O. May 2021
8160
8161 unsigned char * bytes = (unsigned char *)string;
8162 while(*bytes) {
8163 if( (// ASCII
8164 // use bytes[0] <= 0x7F to allow ASCII control characters
8165 bytes[0] == 0x09 ||
8166 bytes[0] == 0x0A ||
8167 bytes[0] == 0x0D ||
8168 (0x20 <= bytes[0] && bytes[0] <= 0x7E)
8169 )
8170 ) {
8171 bytes += 1;
8172 continue;
8173 }
8174
8175 if( (// non-overlong 2-byte
8176 (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
8177 (0x80 <= bytes[1] && bytes[1] <= 0xBF)
8178 )
8179 ) {
8180 bytes += 2;
8181 continue;
8182 }
8183
8184 if( (// excluding overlongs
8185 bytes[0] == 0xE0 &&
8186 (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
8187 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8188 ) ||
8189 (// straight 3-byte
8190 ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
8191 bytes[0] == 0xEE ||
8192 bytes[0] == 0xEF) &&
8193 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8194 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8195 ) ||
8196 (// excluding surrogates
8197 bytes[0] == 0xED &&
8198 (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
8199 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8200 )
8201 ) {
8202 bytes += 3;
8203 continue;
8204 }
8205
8206 if( (// planes 1-3
8207 bytes[0] == 0xF0 &&
8208 (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
8209 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8210 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8211 ) ||
8212 (// planes 4-15
8213 (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
8214 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8215 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8216 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8217 ) ||
8218 (// plane 16
8219 bytes[0] == 0xF4 &&
8220 (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
8221 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8222 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8223 )
8224 ) {
8225 bytes += 4;
8226 continue;
8227 }
8228
8229 if (bytes[0] == 0) // end of string
8230 break;
8231
8232 bytes[0] = '?';
8233 bytes += 1;
8234
8235 modified = true;
8236 }
8237
8238 //if (modified) {
8239 // printf("ss_repair_utf8(): invalid UTF8 string [%s] changed to [%s]\n", original.c_str(), string);
8240 //} else {
8241 // //printf("ss_repair_utf8(): string [%s] is ok\n", string);
8242 //}
8243
8244 return modified;
8245}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_repair_utf8() [2/2]

bool ss_repair_utf8 ( std::string &  s)

Definition at line 8247 of file system.cxx.

8248{
8249 // C++11 std::string data() is same as c_str(), NUL-terminated.
8250 // C++17 std::string data() is not "const".
8251 // https://en.cppreference.com/w/cpp/string/basic_string/data
8252 return ss_repair_utf8((char*)s.data()); // FIXME: C++17 or newer, do not need to drop the "const". K.O. May 2021
8253}
bool ss_repair_utf8(char *string)
Definition system.cxx:8151
Here is the call graph for this function:

◆ ss_replace_env_variables()

std::string EXPRT ss_replace_env_variables ( const std::string &  inputPath)

Definition at line 2212 of file system.cxx.

2212 {
2213 std::string result;
2214 size_t startPos = 0;
2215 size_t dollarPos;
2216
2217 while ((dollarPos = inputPath.find('$', startPos)) != std::string::npos) {
2218 result.append(inputPath, startPos, dollarPos - startPos);
2219
2220 size_t varEndPos = inputPath.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", dollarPos + 1);
2221 size_t varLength = varEndPos - dollarPos - 1;
2222 std::string varName = inputPath.substr(dollarPos + 1, varLength);
2223
2224 char* varValue = std::getenv(varName.c_str());
2225 if (varValue != nullptr) {
2226 result.append(varValue);
2227 }
2228
2230 }
2231
2232 result.append(inputPath.c_str(), startPos, std::string::npos);
2233 return result;
2234}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_resume()

INT ss_resume ( INT  port,
const char message 
)

Definition at line 4844 of file system.cxx.

4867{
4868 assert(_ss_suspend_odb);
4869
4870 struct sockaddr_in bind_addr;
4871
4872 memcpy(&bind_addr, &_ss_suspend_odb->bind_addr, sizeof(struct sockaddr_in));
4873 bind_addr.sin_port = htons((short) port);
4874
4875 size_t message_size = strlen(message) + 1;
4876
4877 ssize_t wr = sendto(_ss_suspend_odb->ipc_send_socket, message, message_size, 0, (struct sockaddr *) &bind_addr, sizeof(struct sockaddr_in));
4878
4879 if (wr < 0) {
4880 return SS_SOCKET_ERROR;
4881 }
4882
4883 if (((size_t)wr) != message_size) {
4884 return SS_SOCKET_ERROR;
4885 }
4886
4887 return SS_SUCCESS;
4888}
static SUSPEND_STRUCT * _ss_suspend_odb
Definition system.cxx:3980
#define message(type, str)
struct sockaddr_in bind_addr
Definition system.cxx:3974
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_semaphore_create()

INT EXPRT ss_semaphore_create ( const char name,
HNDLE semaphore_handle 
)

Definition at line 2460 of file system.cxx.

2489{
2490 char semaphore_name[256];
2491
2492 /* Add a leading MX_ to the semaphore name */
2493 sprintf(semaphore_name, "MX_%s", name);
2494
2495#ifdef OS_VXWORKS
2496
2497 /* semBCreate is a Binary semaphore which is under VxWorks a optimized mutex
2498 refering to the programmer's Guide 5.3.1 */
2500 return SS_NO_MUTEX;
2501 return SS_CREATED;
2502
2503#endif /* OS_VXWORKS */
2504
2505#ifdef OS_WINNT
2506
2508
2509 if (*semaphore_handle == 0)
2510 return SS_NO_SEMAPHORE;
2511
2512 return SS_CREATED;
2513
2514#endif /* OS_WINNT */
2515#ifdef OS_VMS
2516
2517 /* VMS has to use lock manager... */
2518
2519 {
2520 INT status;
2522 semaphorename_dsc.dsc$w_length = strlen(semaphore_name);
2523 semaphorename_dsc.dsc$a_pointer = semaphore_name;
2524
2526
2527 status = sys$enqw(0, LCK$K_NLMODE, *semaphore_handle, 0, &semaphorename_dsc, 0, 0, 0, 0, 0, 0);
2528
2529 if (status != SS$_NORMAL) {
2530 free((void *) *semaphore_handle);
2531 *semaphore_handle = 0;
2532 }
2533
2534 if (*semaphore_handle == 0)
2535 return SS_NO_SEMAPHORE;
2536
2537 return SS_CREATED;
2538 }
2539
2540#endif /* OS_VMS */
2541#ifdef OS_UNIX
2542
2543 {
2545 int status;
2546 struct semid_ds buf;
2547
2548 if (name[0] != 0) {
2549 int fh;
2550 char cwd[256];
2551 std::string file_name;
2552
2553 /* Build the filename out of the path and the name of the semaphore */
2554 std::string path = cm_get_path();
2555 if (path.empty()) {
2556 if (getcwd(cwd, sizeof(cwd)))
2557 path = std::string(cwd);
2558#if defined(OS_VMS)
2559#elif defined(OS_UNIX)
2560 path += "/";
2561#elif defined(OS_WINNT)
2562 path += "\\";
2563#endif
2564 }
2565
2566 file_name = path;
2567 file_name += ".";
2568 file_name += std::string(name);
2569 file_name += ".SHM";
2570
2571 /* create a unique key from the file name */
2572 key = ftok(file_name.c_str(), 'M');
2573 if (key < 0) {
2574 fh = open(file_name.c_str(), O_CREAT, 0644);
2575 close(fh);
2576 key = ftok(file_name.c_str(), 'M');
2578 }
2579 }
2580
2581#if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
2582 union semun arg;
2583#else
2584 union semun {
2585 INT val;
2586 struct semid_ds *buf;
2587 ushort *array;
2588 } arg;
2589#endif
2590
2592
2593 /* create or get semaphore */
2594 *semaphore_handle = (HNDLE) semget(key, 1, 0);
2595 //printf("create1 key 0x%x, id %d, errno %d (%s)\n", key, *semaphore_handle, errno, strerror(errno));
2596 if (*semaphore_handle < 0) {
2598 //printf("create2 key 0x%x, id %d, errno %d (%s)\n", key, *semaphore_handle, errno, strerror(errno));
2600 }
2601
2602 if (*semaphore_handle < 0) {
2603 cm_msg(MERROR, "ss_semaphore_create", "Cannot create semaphore \'%s\', semget(0x%x) failed, errno %d (%s)", name, key, errno, strerror(errno));
2604
2605 fprintf(stderr, "ss_semaphore_create: Cannot create semaphore \'%s\', semget(0x%x) failed, errno %d (%s)", name, key, errno, strerror(errno));
2606 abort(); // does not return
2607 return SS_NO_SEMAPHORE;
2608 }
2609
2610 memset(&buf, 0, sizeof(buf));
2611 buf.sem_perm.uid = getuid();
2612 buf.sem_perm.gid = getgid();
2613 buf.sem_perm.mode = 0666;
2614 arg.buf = &buf;
2615
2616 semctl(*semaphore_handle, 0, IPC_SET, arg);
2617
2618 /* if semaphore was created, set value to one */
2619 if (key == IPC_PRIVATE || status == SS_CREATED) {
2620 arg.val = 1;
2621 if (semctl(*semaphore_handle, 0, SETVAL, arg) < 0)
2622 return SS_NO_SEMAPHORE;
2623 }
2624
2625 if (s_semaphore_trace) {
2626 fprintf(stderr, "name %d %d %d %s\n", *semaphore_handle, (int)time(NULL), getpid(), name);
2627 }
2628
2629 return SS_SUCCESS;
2630 }
2631#endif /* OS_UNIX */
2632
2633#ifdef OS_MSDOS
2634 return SS_NO_SEMAPHORE;
2635#endif
2636}
static std::atomic_bool s_semaphore_trace
Definition system.cxx:2457
KEY key
Definition mdump.cxx:34
INT HNDLE
Definition midas.h:132
#define name(x)
Definition midas_macro.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_semaphore_delete()

INT EXPRT ss_semaphore_delete ( HNDLE  semaphore_handle,
INT  destroy_flag 
)

Definition at line 2869 of file system.cxx.

2887{
2888#ifdef OS_WINNT
2889
2891 return SS_NO_SEMAPHORE;
2892
2893 return SS_SUCCESS;
2894
2895#endif /* OS_WINNT */
2896#ifdef OS_VMS
2897
2898 free((void *) semaphore_handle);
2899 return SS_SUCCESS;
2900
2901#endif /* OS_VMS */
2902
2903#ifdef OS_VXWORKS
2904 /* no code for VxWorks destroy yet */
2906 return SS_NO_SEMAPHORE;
2907 return SS_SUCCESS;
2908#endif /* OS_VXWORKS */
2909
2910#ifdef OS_UNIX
2911#if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
2912 union semun arg;
2913#else
2914 union semun {
2915 INT val;
2916 struct semid_ds *buf;
2917 ushort *array;
2918 } arg;
2919#endif
2920
2921 memset(&arg, 0, sizeof(arg));
2922
2923 if (destroy_flag) {
2924 int status = semctl(semaphore_handle, 0, IPC_RMID, arg);
2925 //printf("semctl(ID=%d, IPC_RMID) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
2926 if (status < 0)
2927 return SS_NO_SEMAPHORE;
2928 }
2929
2930 return SS_SUCCESS;
2931
2932#endif /* OS_UNIX */
2933
2934#ifdef OS_MSDOS
2935 return SS_NO_SEMAPHORE;
2936#endif
2937}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_semaphore_release()

INT EXPRT ss_semaphore_release ( HNDLE  semaphore_handle)

Definition at line 2781 of file system.cxx.

2799{
2800 INT status;
2801
2802#ifdef OS_WINNT
2803
2805
2806 if (status == FALSE)
2807 return SS_NO_SEMAPHORE;
2808
2809 return SS_SUCCESS;
2810
2811#endif /* OS_WINNT */
2812#ifdef OS_VMS
2813
2814 status = sys$enqw(0, LCK$K_NLMODE, semaphore_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
2815
2816 if (status != SS$_NORMAL)
2817 return SS_NO_SEMAPHORE;
2818
2819 return SS_SUCCESS;
2820
2821#endif /* OS_VMS */
2822
2823#ifdef OS_VXWORKS
2824
2826 return SS_NO_SEMAPHORE;
2827 return SS_SUCCESS;
2828#endif /* OS_VXWORKS */
2829
2830#ifdef OS_UNIX
2831 {
2832 struct sembuf sb;
2833
2834 sb.sem_num = 0;
2835 sb.sem_op = 1; /* increment semaphore */
2836 sb.sem_flg = SEM_UNDO;
2837
2838 if (s_semaphore_trace) {
2839 fprintf(stderr, "unlock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int(s_semaphore_nest_level));
2840 assert(s_semaphore_nest_level > 0);
2842 }
2843
2844 do {
2846
2847 /* return on success */
2848 if (status == 0)
2849 break;
2850
2851 /* retry if interrupted by a ss_wake signal */
2852 if (errno == EINTR)
2853 continue;
2854
2855 fprintf(stderr, "ss_semaphore_release: semop/semtimedop(%d) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
2856 return SS_NO_SEMAPHORE;
2857 } while (1);
2858
2859 return SS_SUCCESS;
2860 }
2861#endif /* OS_UNIX */
2862
2863#ifdef OS_MSDOS
2864 return SS_NO_SEMAPHORE;
2865#endif
2866}
static std::atomic_int s_semaphore_nest_level
Definition system.cxx:2458
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_semaphore_wait_for()

INT EXPRT ss_semaphore_wait_for ( HNDLE  semaphore_handle,
DWORD  timeout_millisec 
)

Definition at line 2639 of file system.cxx.

2659{
2660 INT status;
2661
2662#ifdef OS_WINNT
2663
2665 if (status == WAIT_FAILED)
2666 return SS_NO_SEMAPHORE;
2667 if (status == WAIT_TIMEOUT)
2668 return SS_TIMEOUT;
2669
2670 return SS_SUCCESS;
2671#endif /* OS_WINNT */
2672#ifdef OS_VMS
2673 status = sys$enqw(0, LCK$K_EXMODE, semaphore_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
2674 if (status != SS$_NORMAL)
2675 return SS_NO_SEMAPHORE;
2676 return SS_SUCCESS;
2677
2678#endif /* OS_VMS */
2679#ifdef OS_VXWORKS
2680 /* convert timeout in ticks (1/60) = 1000/60 ~ 1/16 = >>4 */
2682 if (status == ERROR)
2683 return SS_NO_SEMAPHORE;
2684 return SS_SUCCESS;
2685
2686#endif /* OS_VXWORKS */
2687#ifdef OS_UNIX
2688 {
2689 struct sembuf sb;
2690
2691#if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
2692 union semun arg;
2693#else
2694 union semun {
2695 INT val;
2696 struct semid_ds *buf;
2697 ushort *array;
2698 } arg;
2699#endif
2700
2701 sb.sem_num = 0;
2702 sb.sem_op = -1; /* decrement semaphore */
2703 sb.sem_flg = SEM_UNDO;
2704
2705 memset(&arg, 0, sizeof(arg));
2706
2707 DWORD start_time = ss_millitime();
2708
2709 if (s_semaphore_trace) {
2710 fprintf(stderr, "waitlock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int(s_semaphore_nest_level));
2711 }
2712
2713 do {
2714#if defined(OS_DARWIN)
2716#elif defined(OS_LINUX)
2717 struct timespec ts;
2718 if (timeout_millisec >= 1000 || timeout_millisec == 0) {
2719 ts.tv_sec = 1;
2720 ts.tv_nsec = 0;
2721 } else {
2722 ts.tv_sec = 0;
2723 ts.tv_nsec = (timeout_millisec+10)*1000*1000;
2724 }
2725
2727#else
2729#endif
2730
2731 /* return on success */
2732 if (status == 0) {
2733 //DWORD milli_now = ss_millitime();
2734 //DWORD dt = milli_now - start_time;
2735 //fprintf(stderr, "ss_semaphore_wait_for: locked ok, start time 0x%08x, now 0x%08x, dt 0x%08x, timeout 0x%08x ms\n", start_time, milli_now, dt, timeout_millisec);
2736 //ss_sleep(100);
2737 break;
2738 }
2739
2740 /* retry if interrupted by a ss_wake signal */
2741 if (errno == EINTR || errno == EAGAIN) {
2742 //if (1) {
2743 // DWORD milli_now = ss_millitime();
2744 // DWORD dt = milli_now - start_time;
2745 // fprintf(stderr, "ss_semaphore_wait_for: semop/semtimedop(%d) returned %d, errno %d (%s), start time 0x%08x, now 0x%08x, dt 0x%08x, timeout 0x%08x ms\n", semaphore_handle, status, errno, strerror(errno), start_time, milli_now, dt, timeout_millisec);
2746 // abort();
2747 //}
2748
2749 /* return if timeout expired */
2750 if (timeout_millisec > 0) {
2752 DWORD dt = milli_now - start_time;
2753 if (dt > timeout_millisec) {
2754 fprintf(stderr, "ss_semaphore_wait_for: semop/semtimedop(%d) returned %d, errno %d (%s), start time 0x%08x, now 0x%08x, dt 0x%08x, timeout 0x%08x ms, SEMAPHORE TIMEOUT!\n", semaphore_handle, status, errno, strerror(errno), start_time, milli_now, dt, timeout_millisec);
2755 return SS_TIMEOUT;
2756 }
2757 }
2758
2759 continue;
2760 }
2761
2762 fprintf(stderr, "ss_semaphore_wait_for: semop/semtimedop(%d) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
2763 return SS_NO_SEMAPHORE;
2764 } while (1);
2765
2766 if (s_semaphore_trace) {
2768 fprintf(stderr, "lock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int( s_semaphore_nest_level));
2769 }
2770
2771 return SS_SUCCESS;
2772 }
2773#endif /* OS_UNIX */
2774
2775#ifdef OS_MSDOS
2776 return SS_NO_SEMAPHORE;
2777#endif
2778}
TRIGGER_SETTINGS ts
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_set_screen_size()

void ss_set_screen_size ( int  x,
int  y 
)

Definition at line 7349 of file system.cxx.

7366{
7367#ifdef OS_WINNT
7368
7371
7372 coordSize.X = (short) x;
7373 coordSize.Y = (short) y;
7376
7377#else /* OS_WINNT */
7378#endif
7379}
Here is the call graph for this function:

◆ ss_settime()

DWORD EXPRT ss_settime ( DWORD  seconds)

Definition at line 3475 of file system.cxx.

3491{
3492#if defined(OS_WINNT)
3493 SYSTEMTIME st;
3494 struct tm ltm;
3495
3496 ss_tzset();
3497 localtime_r((time_t *) & seconds, &ltm);
3498
3499 st.wYear = ltm.tm_year + 1900;
3500 st.wMonth = ltm.tm_mon + 1;
3501 st.wDay = ltm.tm_mday;
3502 st.wHour = ltm.tm_hour;
3503 st.wMinute = ltm.tm_min;
3504 st.wSecond = ltm.tm_sec;
3505 st.wMilliseconds = 0;
3506
3507 SetLocalTime(&st);
3508
3509#elif defined(OS_DARWIN) && defined(CLOCK_REALTIME)
3510
3511 struct timespec ltm;
3512
3513 ltm.tv_sec = seconds;
3514 ltm.tv_nsec = 0;
3516
3517#elif defined(OS_CYGWIN) && defined(CLOCK_REALTIME)
3518
3519 struct timespec ltm;
3520
3521 ltm.tv_sec = seconds;
3522 ltm.tv_nsec = 0;
3524 return SS_NO_DRIVER;
3525
3526#elif defined(OS_UNIX) && defined(CLOCK_REALTIME)
3527
3528 struct timespec ltm;
3529
3530 ltm.tv_sec = seconds;
3531 ltm.tv_nsec = 0;
3533
3534#elif defined(OS_VXWORKS)
3535
3536 struct timespec ltm;
3537
3538 ltm.tv_sec = seconds;
3539 ltm.tv_nsec = 0;
3541
3542#else
3543#warning ss_settime() is not supported!
3544#endif
3545 return SS_SUCCESS;
3546}
#define SS_NO_DRIVER
Definition midas.h:683
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shell()

INT ss_shell ( int  sock)

Definition at line 1760 of file system.cxx.

1777{
1778#ifdef OS_WINNT
1779
1782
1786 char buffer[256], cmd[256];
1789 struct timeval timeout;
1790
1791 /* Set the bInheritHandle flag so pipe handles are inherited. */
1792 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
1793 saAttr.bInheritHandle = TRUE;
1794 saAttr.lpSecurityDescriptor = NULL;
1795
1796 /* Save the handle to the current STDOUT. */
1798
1799 /* Create a pipe for the child's STDOUT. */
1801 return 0;
1802
1803 /* Set a write handle to the pipe to be STDOUT. */
1805 return 0;
1806
1807
1808 /* Save the handle to the current STDERR. */
1810
1811 /* Create a pipe for the child's STDERR. */
1813 return 0;
1814
1815 /* Set a read handle to the pipe to be STDERR. */
1817 return 0;
1818
1819
1820 /* Save the handle to the current STDIN. */
1822
1823 /* Create a pipe for the child's STDIN. */
1825 return 0;
1826
1827 /* Set a read handle to the pipe to be STDIN. */
1829 return 0;
1830
1831 /* Duplicate the write handle to the pipe so it is not inherited. */
1834 return 0;
1835
1837
1838 /* Now create the child process. */
1839 memset(&siStartInfo, 0, sizeof(siStartInfo));
1840 siStartInfo.cb = sizeof(STARTUPINFO);
1841 siStartInfo.lpReserved = NULL;
1842 siStartInfo.lpReserved2 = NULL;
1843 siStartInfo.cbReserved2 = 0;
1844 siStartInfo.lpDesktop = NULL;
1845 siStartInfo.dwFlags = 0;
1846
1847 if (!CreateProcess(NULL, "cmd /Q", /* command line */
1848 NULL, /* process security attributes */
1849 NULL, /* primary thread security attributes */
1850 TRUE, /* handles are inherited */
1851 0, /* creation flags */
1852 NULL, /* use parent's environment */
1853 NULL, /* use parent's current directory */
1854 &siStartInfo, /* STARTUPINFO pointer */
1855 &piProcInfo)) /* receives PROCESS_INFORMATION */
1856 return 0;
1857
1858 /* After process creation, restore the saved STDIN and STDOUT. */
1862
1863 i_cmd = 0;
1864
1865 do {
1866 /* query stderr */
1867 do {
1868 if (!PeekNamedPipe(hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
1869 break;
1870
1871 if (dwRead > 0) {
1872 ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
1873 send(sock, buffer, dwRead, 0);
1874 }
1875 } while (dwAvail > 0);
1876
1877 /* query stdout */
1878 do {
1879 if (!PeekNamedPipe(hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
1880 break;
1881 if (dwRead > 0) {
1882 ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
1883 send(sock, buffer, dwRead, 0);
1884 }
1885 } while (dwAvail > 0);
1886
1887
1888 /* check if subprocess still alive */
1889 if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
1890 break;
1891 if (i != STILL_ACTIVE)
1892 break;
1893
1894 /* query network socket */
1895 FD_ZERO(&readfds);
1896 FD_SET(sock, &readfds);
1897 timeout.tv_sec = 0;
1898 timeout.tv_usec = 100;
1899 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
1900
1901 if (FD_ISSET(sock, &readfds)) {
1902 i = recv(sock, cmd + i_cmd, 1, 0);
1903 if (i <= 0)
1904 break;
1905
1906 /* backspace */
1907 if (cmd[i_cmd] == 8) {
1908 if (i_cmd > 0) {
1909 send(sock, "\b \b", 3, 0);
1910 i_cmd -= 1;
1911 }
1912 } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
1913 send(sock, cmd + i_cmd, 1, 0);
1914 i_cmd += i;
1915 }
1916 }
1917
1918 /* linefeed triggers new command */
1919 if (cmd[i_cmd - 1] == 10) {
1921 i_cmd = 0;
1922 }
1923
1924 } while (TRUE);
1925
1930
1931 return SS_SUCCESS;
1932
1933#endif /* OS_WINNT */
1934
1935#ifdef OS_UNIX
1936#ifndef NO_PTY
1937 pid_t pid;
1938 int i, p;
1939 char line[32], buffer[1024], shell[32];
1941
1942#ifdef NO_FORK
1943 assert(!"support for forkpty() disabled by NO_FORK");
1944#else
1945 pid = forkpty(&p, line, NULL, NULL);
1946#endif
1947 if (pid < 0)
1948 return 0;
1949 else if (pid > 0) {
1950 /* parent process */
1951
1952 do {
1953 FD_ZERO(&readfds);
1954 FD_SET(sock, &readfds);
1955 FD_SET(p, &readfds);
1956
1958
1959 if (FD_ISSET(sock, &readfds)) {
1960 memset(buffer, 0, sizeof(buffer));
1961 i = recv(sock, buffer, sizeof(buffer), 0);
1962 if (i <= 0)
1963 break;
1964 if (write(p, buffer, i) != i)
1965 break;
1966 }
1967
1968 if (FD_ISSET(p, &readfds)) {
1969 memset(buffer, 0, sizeof(buffer));
1970 i = read(p, buffer, sizeof(buffer));
1971 if (i <= 0)
1972 break;
1973 send(sock, buffer, i, 0);
1974 }
1975
1976 } while (1);
1977 } else {
1978 /* child process */
1979
1980 if (getenv("SHELL"))
1981 mstrlcpy(shell, getenv("SHELL"), sizeof(shell));
1982 else
1983 strcpy(shell, "/bin/sh");
1984 int error = execl(shell, shell, NULL);
1985 // NB: execl() does not return unless there is an error.
1986 fprintf(stderr, "ss_shell: Cannot execute command \"%s\": execl() returned %d, errno %d (%s), aborting!\n", shell, error, errno, strerror(errno));
1987 abort();
1988 }
1989#else
1990 send(sock, "not implemented\n", 17, 0);
1991#endif /* NO_PTY */
1992
1993 return SS_SUCCESS;
1994
1995#endif /* OS_UNIX */
1996}
#define FD_SETSIZE
Definition msystem.h:199
Here is the call graph for this function:

◆ ss_shm_close()

INT ss_shm_close ( const char name,
void adr,
size_t  shm_size,
HNDLE  handle,
INT  destroy_flag 
)

Definition at line 755 of file system.cxx.

780{
781 char mem_name[256], cwd[256];
782 std::string file_name;
783
784 /*
785 append a leading SM_ to the memory name to resolve name conflicts
786 with mutex or semaphore names
787 */
788 sprintf(mem_name, "SM_%s", name);
789
790 /* append .SHM and preceed the path for the shared memory file name */
791 std::string path = cm_get_path();
792 if (path.empty()) {
793 if (getcwd(cwd, sizeof(cwd)))
794 path = std::string(cwd);
795#if defined(OS_VMS)
796#elif defined(OS_UNIX)
797 path += "/";
798#elif defined(OS_WINNT)
799 path += "\\";
800#endif
801 }
802
803 file_name = path;
804#if defined (OS_UNIX)
805 file_name += "."; /* dot file under UNIX */
806#endif
807 file_name += std::string(name);
808 file_name += ".SHM";
809
810 if (shm_trace)
811 printf("ss_shm_close(\"%s\",%p,%.0f,%d,destroy_flag=%d), file_name [%s]\n", name, adr, (double)shm_size, handle, destroy_flag, file_name.c_str());
812
813#ifdef OS_WINNT
814
815 if (!UnmapViewOfFile(adr))
816 return SS_INVALID_ADDRESS;
817
818 CloseHandle((HANDLE) handle);
819
820 return SS_SUCCESS;
821
822#endif /* OS_WINNT */
823#ifdef OS_VMS
824/* outcommented because ppl$delete... makes privilege violation
825 {
826 int addr[2], flags, status;
827 char mem_name[100];
828 $DESCRIPTOR(memname_dsc, mem_name);
829
830 strcpy(mem_name, "SM_");
831 strcat(mem_name, name);
832 memname_dsc.dsc$w_length = strlen(mem_name);
833
834 flags = PPL$M_FLUSH | PPL$M_NOUNI;
835
836 addr[0] = 0;
837 addr[1] = adr;
838
839 status = ppl$delete_shared_memory( &memname_dsc, addr, &flags);
840
841 if (status == PPL$_NORMAL)
842 return SS_SUCCESS;
843
844 return SS_INVALID_ADDRESS;
845 }
846*/
847 return SS_INVALID_ADDRESS;
848
849#endif /* OS_VMS */
850#ifdef OS_UNIX
851
852 if (use_sysv_shm) {
853
854 struct shmid_ds buf;
855
856 /* get info about shared memory */
857 memset(&buf, 0, sizeof(buf));
858 if (shmctl(handle, IPC_STAT, &buf) < 0) {
859 cm_msg(MERROR, "ss_shm_close", "shmctl(shmid=%d,IPC_STAT) failed, errno %d (%s)",
860 handle, errno, strerror(errno));
861 return SS_INVALID_HANDLE;
862 }
863
864 destroy_flag = (buf.shm_nattch == 1);
865
866 if (shm_trace)
867 printf("ss_shm_close(\"%s\"), destroy_flag %d, shmid %d, shm_nattach %d\n", name, destroy_flag, handle, (int)buf.shm_nattch);
868
869 if (shmdt(adr) < 0) {
870 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)", handle, errno, strerror(errno));
871 return SS_INVALID_ADDRESS;
872 }
873
874 if (destroy_flag) {
876 if (status != SS_SUCCESS)
877 return status;
878 }
879
880 return SS_SUCCESS;
881 }
882
884 int status;
885
886 if (shm_trace)
887 printf("ss_shm_close(\"%s\"), destroy_flag %d\n", name, destroy_flag);
888
889 status = munmap(adr, shm_size);
890 if (status != 0) {
891 cm_msg(MERROR, "ss_shm_close", "Cannot unmap shared memory \'%s\', munmap() errno %d (%s)", name, errno, strerror(errno));
892 return SS_INVALID_ADDRESS;
893 }
894
895 if (destroy_flag) {
897 if (status != SS_SUCCESS)
898 return status;
899 }
900
901 return SS_SUCCESS;
902 }
903#endif /* OS_UNIX */
904
905 return SS_FILE_ERROR;
906}
#define SS_FILE_ERROR
Definition midas.h:669
#define SS_INVALID_HANDLE
Definition midas.h:667
#define SS_INVALID_ADDRESS
Definition midas.h:668
INT ss_shm_delete(const char *name)
Definition system.cxx:909
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shm_delete()

INT EXPRT ss_shm_delete ( const char name)

Definition at line 909 of file system.cxx.

927{
928 int status;
929 std::string mem_name;
930 std::string file_name;
931 std::string shm_name;
932
934
935 if (shm_trace)
936 printf("ss_shm_delete(\"%s\") file_name [%s] shm_name [%s]\n", name, file_name.c_str(), shm_name.c_str());
937
938#ifdef OS_WINNT
939 /* no shared memory segments to delete */
940 return SS_SUCCESS;
941#endif /* OS_WINNT */
942
943#ifdef OS_VMS
944 assert(!"not implemented!");
945 return SS_NO_MEMORY;
946#endif /* OS_VMS */
947
948#ifdef OS_UNIX
949
950 if (use_sysv_shm) {
951 int shmid = -1;
952 struct shmid_ds buf;
953
955
956 if (shm_trace)
957 printf("ss_shm_delete(\"%s\") file_name %s, shmid %d\n", name, file_name.c_str(), shmid);
958
959 if (status != SS_SUCCESS)
960 return status;
961
962 status = shmctl(shmid, IPC_RMID, &buf);
963
964 if (status == -1) {
965 cm_msg(MERROR, "ss_shm_delete", "Cannot delete shared memory \'%s\', shmctl(IPC_RMID) failed, errno %d (%s)", name, errno, strerror(errno));
966 return SS_FILE_ERROR;
967 }
968
969 return SS_SUCCESS;
970 }
971
972 if (use_mmap_shm) {
973 /* no shared memory segments to delete */
974
975 if (shm_trace)
976 printf("ss_shm_delete(\"%s\") file_name %s (no-op)\n", name, file_name.c_str());
977
978 return SS_SUCCESS;
979 }
980
981 if (use_posix_shm) {
982
983 if (shm_trace)
984 printf("ss_shm_delete(\"%s\") shm_name %s\n", name, shm_name.c_str());
985
986 status = shm_unlink(shm_name.c_str());
987 if (status < 0) {
988 if (errno != ENOENT) {
989 cm_msg(MERROR, "ss_shm_delete", "shm_unlink(%s) nexpexted error, status %d, errno %d (%s)", shm_name.c_str(), status, errno, strerror(errno));
990 }
991 return SS_NO_MEMORY;
992 }
993
994 return SS_SUCCESS;
995 }
996
997#endif /* OS_UNIX */
998
999 return SS_FILE_ERROR;
1000}
static int ss_shm_name(const char *name, std::string &mem_name, std::string &file_name, std::string &shm_name)
Definition system.cxx:230
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shm_flush()

INT ss_shm_flush ( const char name,
const void adr,
size_t  size,
HNDLE  handle,
bool  wait_for_thread 
)

Definition at line 1176 of file system.cxx.

1197{
1198 std::string mem_name;
1199 std::string file_name;
1200 std::string shm_name;
1201
1203
1204 if (shm_trace)
1205 printf("ss_shm_flush(\"%s\",%p,%.0f,%d), file_name [%s]\n", name, adr, (double)size, handle, file_name.c_str());
1206
1207#ifdef OS_WINNT
1208
1209 if (!FlushViewOfFile(adr, size))
1210 return SS_INVALID_ADDRESS;
1211
1212 return SS_SUCCESS;
1213
1214#endif /* OS_WINNT */
1215#ifdef OS_VMS
1216
1217 return SS_SUCCESS;
1218
1219#endif /* OS_VMS */
1220#ifdef OS_UNIX
1221
1222 if (use_sysv_shm || use_posix_shm) {
1223
1224 assert(size > 0);
1225
1226 int fd = open(file_name.c_str(), O_RDWR | O_CREAT, 0777);
1227 if (fd < 0) {
1228 cm_msg(MERROR, "ss_shm_flush", "Cannot write to file \'%s\', fopen() errno %d (%s)", file_name.c_str(), errno, strerror(errno));
1229 return SS_NO_MEMORY;
1230 }
1231
1232 /* try to make a copy of the shared memory */
1233 void *buffer = malloc(size);
1234 if (buffer != nullptr) {
1235 memcpy(buffer, adr, size);
1236 static std::thread* thread = NULL; // THIS IS NOT THREAD SAFE!
1237 if (thread) { // reap the long finished thread from the previous flush
1238 thread->join();
1239 delete thread;
1240 thread = NULL;
1241 }
1242 static FL_PARAM param; // this is safe, thread is no longer running. K.O.
1244 param.fd = fd;
1245 param.buf = buffer;
1246 param.size = size;
1247
1248 thread = new std::thread(ss_shm_flush_thread, &param);
1249
1250 if (wait_for_thread) {
1251 //fprintf(stderr, "waiting for flush thread!\n");
1252 thread->join();
1253 delete thread;
1254 thread = NULL;
1255 //fprintf(stderr, "thread joined!\n");
1256 }
1257
1258 // buffer gets freed in ss_shm_flush_thread, so we don't have to free() it here...
1259 } else {
1260
1261 /* not enough memory for ODB copy buffer, so write directly */
1262 uint32_t start = ss_time();
1263 ssize_t wr = write(fd, adr, size);
1264 if ((size_t)wr != size) {
1265 cm_msg(MERROR, "ss_shm_flush", "Cannot write to file \'%s\', write() returned %d instead of %d, errno %d (%s)", file_name.c_str(), (int)wr, (int)size, errno, strerror(errno));
1266 close(fd);
1267 return SS_NO_MEMORY;
1268 }
1269
1270 int ret = close(fd);
1271 if (ret < 0) {
1272 cm_msg(MERROR, "ss_shm_flush", "Cannot write to file \'%s\', close() errno %d (%s)",
1273 file_name.c_str(), errno, strerror(errno));
1274 return SS_NO_MEMORY;
1275 }
1276
1277 if (ss_time() - start > 4)
1278 cm_msg(MINFO, "ss_shm_flush", "Flushing shared memory took %d seconds", ss_time() - start);
1279
1280 }
1281
1282 return SS_SUCCESS;
1283 }
1284
1285 if (use_mmap_shm) {
1286
1287 assert(size > 0);
1288
1289 if (shm_trace)
1290 printf("ss_shm_flush(\"%s\") size %.0f, mmap file_name [%s]\n", name, (double)size, file_name.c_str());
1291
1292 int ret = msync((void *)adr, size, MS_ASYNC);
1293 if (ret != 0) {
1294 cm_msg(MERROR, "ss_shm_flush", "Cannot msync(MS_ASYNC): return value %d, errno %d (%s)", ret, errno, strerror(errno));
1295 return SS_INVALID_ADDRESS;
1296 }
1297 return SS_SUCCESS;
1298 }
1299
1300
1301#endif // OS_UNIX
1302
1303 return SS_SUCCESS;
1304}
INT ss_shm_flush_thread(void *p)
Definition system.cxx:1136
char param[10][256]
Definition mana.cxx:250
INT thread(void *p)
Definition odbedit.cxx:43
std::string file_name
Definition system.cxx:1130
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shm_flush_thread()

INT ss_shm_flush_thread ( void p)

Definition at line 1136 of file system.cxx.

1137{
1138 FL_PARAM *param = (FL_PARAM *)p;
1139
1140 //fprintf(stderr, "flush start!\n");
1141
1142 uint32_t start = ss_time();
1143
1144 /* write shared memory to file */
1145 ssize_t wr = write(param->fd, param->buf, param->size);
1146 if ((size_t)wr != (size_t)param->size) {
1147 cm_msg(MERROR, "ss_shm_flush", "Cannot write to file \'%s\', write() returned %d instead of %d, errno %d (%s)",
1148 param->file_name.c_str(), (int)wr, (int)param->size, errno, strerror(errno));
1149 close(param->fd);
1150 free(param->buf);
1151 param->buf = nullptr;
1152 return -1;
1153 }
1154
1155 int ret = close(param->fd);
1156 if (ret < 0) {
1157 cm_msg(MERROR, "ss_shm_flush", "Cannot write to file \'%s\', close() errno %d (%s)",
1158 param->file_name.c_str(), errno, strerror(errno));
1159 free(param->buf);
1160 param->buf = nullptr;
1161 return -1;
1162 }
1163
1164 free(param->buf);
1165 param->buf = nullptr;
1166
1167 if (ss_time() - start > 4)
1168 cm_msg(MINFO, "ss_shm_flush", "Flushing shared memory took %d seconds", ss_time() - start);
1169
1170 //fprintf(stderr, "flush end!\n");
1171
1172 return 0;
1173}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shm_name()

static int ss_shm_name ( const char name,
std::string &  mem_name,
std::string &  file_name,
std::string &  shm_name 
)
static

Definition at line 230 of file system.cxx.

231{
233#if defined(OS_DARWIN)
234 check_shm_type("POSIXv3_SHM"); // uid + expt name + shm name
235#elif defined(OS_UNIX)
236 check_shm_type("POSIXv4_SHM"); // uid + expt name + shm name + expt directory
237#endif
238
239 mem_name = std::string("SM_") + name;
240
241 /* append .SHM and preceed the path for the shared memory file name */
242
243 std::string exptname = cm_get_experiment_name();
244 std::string path = cm_get_path();
245
246 //printf("shm name [%s], expt name [%s], path [%s]\n", name, exptname.c_str(), path.c_str());
247
248 assert(path.length() > 0);
249 assert(exptname.length() > 0);
250
251 file_name = path;
252#if defined (OS_UNIX)
253 file_name += "."; /* dot file under UNIX */
254#endif
255 file_name += name;
256 file_name += ".SHM";
257
258#if defined(OS_UNIX)
259 shm_name = "/";
260 if (use_posix1_shm) {
262 } else if (use_posix2_shm) {
264 shm_name += "_";
265 shm_name += name;
266 shm_name += "_SHM";
267 } else if (use_posix3_shm) {
268 uid_t uid = getuid();
269 char buf[16];
270 sprintf(buf, "%d", uid);
271 shm_name += buf;
272 shm_name += "_";
274 shm_name += "_";
275 shm_name += name;
276 } else if (use_posix4_shm) {
277 uid_t uid = getuid();
278 char buf[16];
279 sprintf(buf, "%d", uid);
280 shm_name += buf;
281 shm_name += "_";
283 shm_name += "_";
284 shm_name += name;
285 shm_name += "_";
287 } else {
288 fprintf(stderr, "check_shm_host: unsupported shared memory type, bye!\n");
289 abort();
290 }
291
292 for (size_t i=1; i<shm_name.length(); i++)
293 if (shm_name[i] == '/')
294 shm_name[i] = '_';
295
296 //printf("ss_shm_name: [%s] generated [%s]\n", name, shm_name.c_str());
297#endif
298
299 return SS_SUCCESS;
300}
std::string cm_get_experiment_name()
Definition midas.cxx:1580
static void check_shm_host()
Definition system.cxx:168
static void check_shm_type(const char *shm_type)
Definition system.cxx:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shm_open()

INT ss_shm_open ( const char name,
INT  size,
void **  adr,
size_t shm_size,
HNDLE handle,
BOOL  get_size 
)

Definition at line 324 of file system.cxx.

352{
353 INT status;
354 std::string mem_name;
355 std::string file_name;
356 std::string shm_name;
357
359
360 if (shm_trace)
361 printf("ss_shm_open(\"%s\",%d,%d), mem_name [%s], file_name [%s], shm_name [%s]\n", name, size, get_size, mem_name.c_str(), file_name.c_str(), shm_name.c_str());
362
363#ifdef OS_WINNT
364
366
367 {
369 char str[256], path[256], *p;
370 DWORD file_size;
371
372 /* make the memory name unique using the pathname. This is necessary
373 because NT doesn't use ftok. So if different experiments are
374 running in different directories, they should not see the same
375 shared memory */
376 cm_get_path(path, sizeof(path));
377 mstrlcpy(str, path, sizeof(path));
378
379 /* replace special chars by '*' */
380 while (strpbrk(str, "\\: "))
381 *strpbrk(str, "\\: ") = '*';
382 mstrlcat(str, mem_name, sizeof(path));
383
384 /* convert to uppercase */
385 p = str;
386 while (*p)
387 *p++ = (char) toupper(*p);
388
390 if (hMap == 0) {
392 if (!hFile) {
393 cm_msg(MERROR, "ss_shm_open", "CreateFile() failed");
394 return SS_FILE_ERROR;
395 }
396
397 file_size = GetFileSize(hFile, NULL);
398 if (get_size) {
399 if (file_size != 0xFFFFFFFF && file_size > 0)
400 size = file_size;
401 } else {
402 if (file_size != 0xFFFFFFFF && file_size > 0 && file_size != size) {
403 cm_msg(MERROR, "ss_shm_open", "Requested size (%d) differs from existing size (%d)", size, file_size);
404 return SS_SIZE_MISMATCH;
405 }
406 }
407
409
410 if (!hMap) {
412 cm_msg(MERROR, "ss_shm_open", "CreateFileMapping() failed, error %d", status);
413 return SS_FILE_ERROR;
414 }
415
418 }
419
420 *adr = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
421 *handle = (HNDLE) hMap;
422 *shm_size = size;
423
424 if (adr == NULL) {
425 cm_msg(MERROR, "ss_shm_open", "MapViewOfFile() failed");
426 return SS_NO_MEMORY;
427 }
428
429 return status;
430 }
431
432#endif /* OS_WINNT */
433#ifdef OS_VMS
434
436
437 {
438 int addr[2];
439 $DESCRIPTOR(memname_dsc, "dummy");
440 $DESCRIPTOR(filename_dsc, "dummy");
441 memname_dsc.dsc$w_length = strlen(mem_name);
442 memname_dsc.dsc$a_pointer = mem_name;
443 filename_dsc.dsc$w_length = file_name.length();
444 filename_dsc.dsc$a_pointer = file_name.c_str();
445
446 addr[0] = size;
447 addr[1] = 0;
448
450
451 if (status == PPL$_CREATED)
453 else if (status != PPL$_NORMAL)
455
456 *adr = (void *) addr[1];
457 *handle = 0; /* not used under VMS */
458 *shm_size = addr[0];
459
460 if (adr == NULL)
461 return SS_NO_MEMORY;
462
463 return status;
464 }
465
466#endif /* OS_VMS */
467#ifdef OS_UNIX
468
469 if (use_sysv_shm) {
470
471 int key, shmid, fh;
472 double file_size = 0;
473 struct shmid_ds buf;
474
476
477 /* create a unique key from the file name */
478 key = ftok(file_name.c_str(), 'M');
479
480 /* if file doesn't exist, create it */
481 if (key == -1) {
482 fh = open(file_name.c_str(), O_CREAT | O_TRUNC | O_BINARY | O_RDWR, 0644);
483 if (fh > 0) {
484 close(fh);
485 }
486 key = ftok(file_name.c_str(), 'M');
487
488 if (key == -1) {
489 cm_msg(MERROR, "ss_shm_open", "ftok() failed");
490 return SS_FILE_ERROR;
491 }
492
494
495 /* delete any previously created memory */
496
497 shmid = shmget(key, 0, 0);
498 shmctl(shmid, IPC_RMID, &buf);
499 } else {
500 /* if file exists, retrieve its size */
501 file_size = ss_file_size(file_name.c_str());
502 if (file_size > 0) {
503 if (get_size) {
504 size = file_size;
505 } else if (size != file_size) {
506 cm_msg(MERROR, "ss_shm_open", "Existing file \'%s\' has size %.0f, different from requested size %d", file_name.c_str(), file_size, size);
507 return SS_SIZE_MISMATCH;
508 }
509 }
510 }
511
512 if (shm_trace)
513 printf("ss_shm_open(\"%s\",%d) get_size %d, file_name %s, size %.0f\n", name, size, get_size, file_name.c_str(), file_size);
514
515 /* get the shared memory, create if not existing */
516 shmid = shmget(key, size, 0);
517 if (shmid == -1) {
518 //cm_msg(MINFO, "ss_shm_open", "Creating shared memory segment, key: 0x%x, size: %d",key,size);
519 shmid = shmget(key, size, IPC_CREAT | IPC_EXCL);
520 if (shmid == -1 && errno == EEXIST) {
521 cm_msg(MERROR, "ss_shm_open",
522 "Shared memory segment with key 0x%x already exists, please remove it manually: ipcrm -M 0x%x",
523 key, key);
524 return SS_NO_MEMORY;
525 }
527 }
528
529 if (shmid == -1) {
530 cm_msg(MERROR, "ss_shm_open", "shmget(key=0x%x,size=%d) failed, errno %d (%s)", key, size, errno, strerror(errno));
531 return SS_NO_MEMORY;
532 }
533
534 memset(&buf, 0, sizeof(buf));
535 buf.shm_perm.uid = getuid();
536 buf.shm_perm.gid = getgid();
537 buf.shm_perm.mode = 0666;
538 shmctl(shmid, IPC_SET, &buf);
539
540 *adr = shmat(shmid, 0, 0);
541
542 if ((*adr) == (void *) (-1)) {
543 cm_msg(MERROR, "ss_shm_open", "shmat(shmid=%d) failed, errno %d (%s)", shmid, errno, strerror(errno));
544 return SS_NO_MEMORY;
545 }
546
547 *handle = (HNDLE) shmid;
548 *shm_size = size;
549
550 /* if shared memory was created, try to load it from file */
551 if (status == SS_CREATED && file_size > 0) {
552 fh = open(file_name.c_str(), O_RDONLY, 0644);
553 if (fh == -1)
554 fh = open(file_name.c_str(), O_CREAT | O_RDWR, 0644);
555 else {
556 int rd = read(fh, *adr, size);
557 if (rd != size)
558 cm_msg(MERROR, "ss_shm_open", "File size mismatch shared memory \'%s\' size %d, file \'%s\' read %d, errno %d (%s)", name, size, file_name.c_str(), rd, errno, strerror(errno));
559 }
560 close(fh);
561 }
562
563 return status;
564 }
565
566 if (use_mmap_shm) {
567
568 int ret;
569 int fh, file_size;
570
571 if (1) {
572 static int once = 1;
573 if (once && strstr(file_name.c_str(), "ODB")) {
574 once = 0;
575 cm_msg(MINFO, "ss_shm_open", "WARNING: This version of MIDAS system.c uses the experimental mmap() based implementation of MIDAS shared memory.");
576 }
577 }
578
579 if (shm_trace)
580 printf("ss_shm_open(\"%s\",%d) get_size %d, file_name %s\n", name, size, get_size, file_name.c_str());
581
583
584 fh = open(file_name.c_str(), O_RDWR | O_BINARY | O_LARGEFILE, 0644);
585
586 if (fh < 0) {
587 if (errno == ENOENT) { // file does not exist
588 fh = open(file_name.c_str(), O_CREAT | O_RDWR | O_BINARY | O_LARGEFILE, 0644);
589 }
590
591 if (fh < 0) {
592 cm_msg(MERROR, "ss_shm_open", "Cannot create shared memory file \'%s\', errno %d (%s)", file_name.c_str(), errno, strerror(errno));
593 return SS_FILE_ERROR;
594 }
595
596 ret = lseek(fh, size - 1, SEEK_SET);
597
598 if (ret == (off_t) - 1) {
599 cm_msg(MERROR, "ss_shm_open",
600 "Cannot create shared memory file \'%s\', size %d, lseek() errno %d (%s)",
601 file_name.c_str(), size, errno, strerror(errno));
602 return SS_FILE_ERROR;
603 }
604
605 ret = 0;
606 ret = write(fh, &ret, 1);
607 assert(ret == 1);
608
609 ret = lseek(fh, 0, SEEK_SET);
610 assert(ret == 0);
611
612 //cm_msg(MINFO, "ss_shm_open", "Created shared memory file \'%s\', size %d", file_name.c_str(), size);
613
615 }
616
617 /* if file exists, retrieve its size */
618 file_size = (INT) ss_file_size(file_name.c_str());
619 if (file_size < size) {
620 cm_msg(MERROR, "ss_shm_open",
621 "Shared memory file \'%s\' size %d is smaller than requested size %d. Please remove it and try again",
622 file_name.c_str(), file_size, size);
623 return SS_NO_MEMORY;
624 }
625
626 size = file_size;
627
628 *adr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fh, 0);
629
630 if ((*adr) == MAP_FAILED) {
631 cm_msg(MERROR, "ss_shm_open", "mmap() failed, errno %d (%s)", errno, strerror(errno));
632 return SS_NO_MEMORY;
633 }
634
635 *handle = ++shm_count;
636 *shm_size = size;
637
638 return status;
639 }
640
641 if (use_posix_shm) {
642
643 int sh;
644 int fh;
645 int created = 0;
646 double file_size = -1;
647
648 fh = open(file_name.c_str(), O_RDONLY | O_BINARY | O_LARGEFILE, 0777);
649
650 if (fh >= 0) {
651 file_size = ss_file_size(file_name.c_str());
652 }
653
654 if (shm_trace)
655 printf("ss_shm_open(\"%s\",%d) get_size %d, file_name %s, size %.0f\n", name, size, get_size, file_name.c_str(), file_size);
656
657 if (file_size > 0) {
658 if (get_size)
659 size = file_size;
660
661 if (file_size != size) {
662 cm_msg(MERROR, "ss_shm_open", "Shared memory file \'%s\' size %.0f is different from requested size %d. Please backup and remove this file and try again", file_name.c_str(), file_size, size);
663 if (fh >= 0)
664 close(fh);
665 return SS_NO_MEMORY;
666 }
667 }
668
669 int mode = 0600; // 0777: full access for everybody (minus umask!), 0600: current user: read+write, others: no permission
670
671 sh = shm_open(shm_name.c_str(), O_RDWR, mode);
672
673 if (sh < 0) {
674 // cannot open, try to create new one
675
676 sh = shm_open(shm_name.c_str(), O_RDWR | O_CREAT, mode);
677
678 //printf("ss_shm_open: name [%s], return %d, errno %d (%s)\n", shm_name, sh, errno, strerror(errno));
679
680 if (sh < 0) {
681#ifdef ENAMETOOLONG
682 if (errno == ENAMETOOLONG) {
683 fprintf(stderr, "ss_shm_open: Cannot create shared memory for \"%s\": shared memory object name \"%s\" is too long for shm_open(), please try to use shorter experiment name or shorter event buffer name or a shared memory type that uses shorter names, in this order: POSIXv3_SHM, POSIXv2_SHM or POSIX_SHM (as specified in config file .SHM_TYPE.TXT). Sorry, bye!\n", name, shm_name.c_str());
684 exit(1);
685 }
686#endif
687#ifdef EACCES
688 if (errno == EACCES) {
689 fprintf(stderr, "ss_shm_open: Cannot create shared memory for \"%s\" with shared memory object name \"%s\", shm_open() errno %d (%s), please inspect file permissions in \"ls -l /dev/shm\", and if this is a conflict with a different user using the same experiment name, please change shared memory type to the POSIXv4_SHM or POSIXv3_SHM (on MacOS) (as specified in config file .SHM_TYPE.TXT). Sorry, bye!\n", name, shm_name.c_str(), errno, strerror(errno));
690 exit(1);
691 }
692#endif
693 cm_msg(MERROR, "ss_shm_open", "Cannot create shared memory segment \'%s\', shm_open() errno %d (%s)", shm_name.c_str(), errno, strerror(errno));
694 if (fh >= 0)
695 close(fh);
696 return SS_NO_MEMORY;
697 }
698
699 status = ftruncate(sh, size);
700 if (status < 0) {
701 cm_msg(MERROR, "ss_shm_open", "Cannot resize shared memory segment \'%s\', ftruncate(%d) errno %d (%s)", shm_name.c_str(), size, errno, strerror(errno));
702 if (fh >= 0)
703 close(fh);
704 return SS_NO_MEMORY;
705 }
706
707 //cm_msg(MINFO, "ss_shm_open", "Created shared memory segment \'%s\', size %d", shm_name.c_str(), size);
708
709 created = 1;
710 }
711
712 *adr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sh, 0);
713
714 if ((*adr) == MAP_FAILED) {
715 cm_msg(MERROR, "ss_shm_open", "Cannot mmap() shared memory \'%s\', errno %d (%s)", shm_name.c_str(), errno, strerror(errno));
716 close(sh);
717 if (fh >= 0)
718 close(fh);
719 return SS_NO_MEMORY;
720 }
721
722 close(sh);
723
724 /* if shared memory was created, try to load it from file */
725
726 if (created && fh >= 0 && file_size > 0) {
727 if (shm_trace)
728 printf("ss_shm_open(\"%s\"), loading contents of file [%s], size %.0f\n", name, file_name.c_str(), file_size);
729
730 status = read(fh, *adr, size);
731 if (status != size) {
732 cm_msg(MERROR, "ss_shm_open", "Cannot read \'%s\', read() returned %d instead of %d, errno %d (%s)", file_name.c_str(), status, size, errno, strerror(errno));
733 close(fh);
734 return SS_NO_MEMORY;
735 }
736 }
737
738 close(fh);
739
740 *handle = ++shm_count;
741 *shm_size = size;
742
743 if (created)
744 return SS_CREATED;
745 else
746 return SS_SUCCESS;
747 }
748
749#endif /* OS_UNIX */
750
751 return SS_FILE_ERROR;
752}
#define SS_SIZE_MISMATCH
Definition midas.h:690
#define O_BINARY
Definition msystem.h:219
double ss_file_size(const char *path)
Definition system.cxx:6972
char addr[128]
Definition mcnaf.cxx:104
#define O_LARGEFILE
Definition midas.h:210
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shm_protect()

INT ss_shm_protect ( HNDLE  handle,
void adr,
size_t  shm_size 
)

Definition at line 1003 of file system.cxx.

1024{
1025 if (shm_trace)
1026 printf("ss_shm_protect() handle %d, adr %p, size %.0f\n", handle, adr, (double)shm_size);
1027
1028#ifdef OS_WINNT
1029
1030 if (!UnmapViewOfFile(adr))
1031 return SS_INVALID_ADDRESS;
1032
1033#endif /* OS_WINNT */
1034#ifdef OS_UNIX
1035
1036 if (use_sysv_shm) {
1037
1038 if (shmdt(adr) < 0) {
1039 cm_msg(MERROR, "ss_shm_protect", "shmdt() failed");
1040 return SS_INVALID_ADDRESS;
1041 }
1042 }
1043
1044 if (use_mmap_shm || use_posix_shm) {
1045 assert(shm_size > 0);
1046
1047 int ret = mprotect(adr, shm_size, PROT_NONE);
1048 if (ret != 0) {
1049 cm_msg(MERROR, "ss_shm_protect", "Cannot mprotect(PROT_NONE): return value %d, errno %d (%s)", ret, errno, strerror(errno));
1050 return SS_INVALID_ADDRESS;
1051 }
1052 }
1053
1054#endif // OS_UNIX
1055
1056 return SS_SUCCESS;
1057}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shm_unprotect()

INT ss_shm_unprotect ( HNDLE  handle,
void **  adr,
size_t  shm_size,
BOOL  read,
BOOL  write,
const char caller_name 
)

Definition at line 1060 of file system.cxx.

1081{
1082 if (shm_trace)
1083 printf("ss_shm_unprotect() handle %d, adr %p, size %.0f, read %d, write %d, caller %s\n", handle, *adr, (double)shm_size, read, write, caller_name);
1084
1085#ifdef OS_WINNT
1086
1087 *adr = MapViewOfFile((HANDLE) handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
1088
1089 if (*adr == NULL) {
1090 cm_msg(MERROR, "ss_shm_unprotect", "MapViewOfFile() failed");
1091 return SS_NO_MEMORY;
1092 }
1093#endif /* OS_WINNT */
1094#ifdef OS_UNIX
1095
1096 if (use_sysv_shm) {
1097
1098 *adr = shmat(handle, 0, 0);
1099
1100 if ((*adr) == (void *) (-1)) {
1101 cm_msg(MERROR, "ss_shm_unprotect", "shmat() failed, errno = %d", errno);
1102 return SS_NO_MEMORY;
1103 }
1104 }
1105
1106 if (use_mmap_shm || use_posix_shm) {
1107 assert(shm_size > 0);
1108
1109 int mode = 0;
1110 if (read)
1111 mode |= PROT_READ;
1112 if (write)
1114
1115 int ret = mprotect(*adr, shm_size, mode);
1116 if (ret != 0) {
1117 cm_msg(MERROR, "ss_shm_unprotect", "Cannot mprotect(%d): return value %d, errno %d (%s)", mode, ret, errno, strerror(errno));
1118 return SS_INVALID_ADDRESS;
1119 }
1120 }
1121
1122#endif // OS_UNIX
1123
1124 return SS_SUCCESS;
1125}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_sleep()

INT EXPRT ss_sleep ( INT  millisec)

Suspend the calling process for a certain time.

The function is similar to the sleep() function, but has a resolution of one milliseconds. Under VxWorks the resolution is 1/60 of a second. It uses the socket select() function with a time-out. See examples in ss_time()

Parameters
millisecTime in milliseconds to sleep. Zero means infinite (until another process calls ss_wake)
Returns
SS_SUCCESS

Definition at line 3628 of file system.cxx.

3629{
3630 if (millisec == 0) {
3631#ifdef OS_WINNT
3633#endif
3634#ifdef OS_VMS
3635 sys$hiber();
3636#endif
3637#ifdef OS_UNIX
3639 pause();
3640#endif
3641 return SS_SUCCESS;
3642 }
3643#ifdef OS_WINNT
3644 Sleep(millisec);
3645#endif
3646#ifdef OS_UNIX
3647 struct timespec ts;
3648 int status;
3649
3650 ts.tv_sec = millisec / 1000;
3651 ts.tv_nsec = (millisec % 1000) * 1E6;
3652
3653 do {
3654 status = nanosleep(&ts, &ts);
3655 if ((int)ts.tv_sec < 0)
3656 break; // can be negative under OSX
3657 } while (status == -1 && errno == EINTR);
3658#endif
3659
3660 return SS_SUCCESS;
3661}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_socket_check()

static int ss_socket_check ( int  sock)
static

Definition at line 4493 of file system.cxx.

4494{
4495 // copied from the old rpc_server_receive()
4496
4497 /* only check if TCP connection is broken */
4498
4499 char test_buffer[256];
4500#ifdef OS_WINNT
4501 int n_received = recv(sock, test_buffer, sizeof(test_buffer), MSG_PEEK);
4502#else
4504
4505 /* check if we caught a signal */
4506 if ((n_received == -1) && (errno == EAGAIN))
4507 return SS_SUCCESS;
4508#endif
4509
4510 if (n_received == -1) {
4511 cm_msg(MERROR, "ss_socket_check", "recv(%d,MSG_PEEK) returned %d, errno: %d (%s)", (int) sizeof(test_buffer), n_received, errno, strerror(errno));
4512 }
4513
4514 if (n_received <= 0)
4515 return SS_ABORT;
4516
4517 return SS_SUCCESS;
4518}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_socket_close()

INT EXPRT ss_socket_close ( int sockp)

Definition at line 5225 of file system.cxx.

5226{
5227 assert(sockp != NULL);
5228 if (gSocketTrace) {
5229 fprintf(stderr, "ss_socket_close: %d\n", *sockp);
5230 }
5231 int err = close(*sockp);
5232 if (err) {
5233 cm_msg(MERROR, "ss_socket_close", "unexpected error, close() returned %d, errno: %d (%s)", err, errno, strerror(errno));
5234 }
5235 *sockp = 0;
5236 return SS_SUCCESS;
5237}
static bool gSocketTrace
Definition system.cxx:4964
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_socket_connect_tcp()

INT EXPRT ss_socket_connect_tcp ( const char hostname,
int  tcp_port,
int sockp,
std::string *  error_msg_p 
)

Definition at line 4967 of file system.cxx.

4968{
4969 assert(sockp != NULL);
4970 assert(error_msg_p != NULL);
4971 *sockp = 0;
4972
4973#ifdef OS_WINNT
4974 {
4976
4977 /* Start windows sockets */
4978 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
4979 return RPC_NET_ERROR;
4980 }
4981#endif
4982
4983 char portname[256];
4984 sprintf(portname, "%d", tcp_port);
4985
4986 struct addrinfo *ainfo = NULL;
4987
4988 int status = getaddrinfo(hostname, portname, NULL, &ainfo);
4989
4990 if (status != 0) {
4991 *error_msg_p = msprintf("cannot resolve hostname \"%s\", getaddrinfo() error %d (%s)", hostname, status, gai_strerror(status));
4992 if (ainfo)
4994 return RPC_NET_ERROR;
4995 }
4996
4997 // NOTE: ainfo must be freeed using freeaddrinfo(ainfo);
4998
4999 int sock = 0;
5000
5001 for (const struct addrinfo *r = ainfo; r != NULL; r = r->ai_next) {
5002 if (gSocketTrace) {
5003 fprintf(stderr, "ss_socket_connect_tcp: hostname [%s] port %d addrinfo: flags %d, family %d, socktype %d, protocol %d, canonname [%s]\n",
5004 hostname,
5005 tcp_port,
5006 r->ai_flags,
5007 r->ai_family,
5008 r->ai_socktype,
5009 r->ai_protocol,
5010 r->ai_canonname);
5011 }
5012
5013 // skip anything but TCP addresses
5014 if (r->ai_socktype != SOCK_STREAM) {
5015 continue;
5016 }
5017
5018 // skip anything but TCP protocol 6
5019 if (r->ai_protocol != 6) {
5020 continue;
5021 }
5022
5023 sock = ::socket(r->ai_family, r->ai_socktype, 0);
5024
5025 if (sock <= 0) {
5026 *error_msg_p = msprintf("cannot create socket, errno %d (%s)", errno, strerror(errno));
5027 continue;
5028 }
5029
5030 status = ::connect(sock, r->ai_addr, r->ai_addrlen);
5031 if (status != 0) {
5032 if (gSocketTrace) {
5033 fprintf(stderr, "ss_socket_connect_tcp: connect() status %d, errno %d (%s)\n", status, errno, strerror(errno));
5034 }
5035 *error_msg_p = msprintf("cannot connect to host \"%s\" port %d, errno %d (%s)", hostname, tcp_port, errno, strerror(errno));
5036 ::close(sock);
5037 sock = 0;
5038 continue;
5039 }
5040 // successfully connected
5041 break;
5042 }
5043
5045 ainfo = NULL;
5046
5047 if (sock == 0) {
5048 // error_msg is already set
5049 return RPC_NET_ERROR;
5050 }
5051
5052 *sockp = sock;
5053
5054 if (gSocketTrace) {
5055 fprintf(stderr, "ss_socket_connect_tcp: hostname [%s] port %d new socket %d\n", hostname, tcp_port, *sockp);
5056 }
5057
5058 return SS_SUCCESS;
5059}
#define RPC_NET_ERROR
Definition midas.h:701
std::string msprintf(const char *format,...)
Definition midas.cxx:410
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_socket_get_peer_name()

INT EXPRT ss_socket_get_peer_name ( int  sock,
std::string *  hostp,
int portp 
)

Definition at line 5240 of file system.cxx.

5241{
5242 char addr[64];
5243
5244 unsigned size = sizeof(addr);
5245 int rv = getpeername(sock, (struct sockaddr *) &addr, &size);
5246
5247 //printf("getpeername() returned %d, size %d, buffer %d\n", rv, size, (int)sizeof(addr));
5248
5249 if (rv != 0) {
5250 cm_msg(MERROR, "ss_socket_get_peer_name", "Error: getpeername() returned %d, errno %d (%s)", rv, errno, strerror(errno));
5251 return SS_SOCKET_ERROR;
5252 }
5253
5254 char hostname[256];
5255 char servname[16];
5256
5257 int ret = getnameinfo((struct sockaddr*)&addr, size,
5258 hostname, sizeof(hostname),
5259 servname, sizeof(servname),
5261
5262 if (ret != 0) {
5263 cm_msg(MERROR, "ss_socket_get_peer_name", "Error: getnameinfo() error %d (%s)", ret, gai_strerror(ret));
5264 return SS_SOCKET_ERROR;
5265 }
5266
5267 //printf("getnameinfo() returned %d, hostname [%s], servname[%s]\n", ret, hostname, servname);
5268
5269 if (hostp)
5270 *hostp = hostname;
5271
5272 if (portp)
5273 *portp = atoi(servname);
5274
5275 return SS_SUCCESS;
5276}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_socket_listen_tcp()

INT EXPRT ss_socket_listen_tcp ( bool  listen_localhost,
int  tcp_port,
int sockp,
int tcp_port_p,
std::string *  error_msg_p 
)

Definition at line 5062 of file system.cxx.

5063{
5064 assert(sockp != NULL);
5065 assert(tcp_port_p != NULL);
5066 assert(error_msg_p != NULL);
5067
5068 *sockp = 0;
5069 *tcp_port_p = 0;
5070
5071#ifdef OS_WINNT
5072 {
5074
5075 /* Start windows sockets */
5076 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
5077 return RPC_NET_ERROR;
5078 }
5079#endif
5080
5081#ifdef AF_INET6
5082 bool use_inet6 = true;
5083#else
5084 bool use_inet6 = false;
5085#endif
5086
5087 if (listen_localhost)
5088 use_inet6 = false;
5089
5090 /* create a socket for listening */
5091 int lsock;
5092 if (use_inet6) {
5093#ifdef AF_INET6
5095#endif
5096 } else {
5098 }
5099
5100 if (lsock == -1) {
5101 *error_msg_p = msprintf("socket(AF_INET, SOCK_STREAM) failed, errno %d (%s)", errno, strerror(errno));
5102 return RPC_NET_ERROR;
5103 }
5104
5105 /* reuse address, needed if previous server stopped (30s timeout!) */
5106 int flag = 1;
5107 int status = setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof(int));
5108 if (status < 0) {
5109 *error_msg_p = msprintf("setsockopt(SO_REUSEADDR) failed, errno %d (%s)", errno, strerror(errno));
5110 return RPC_NET_ERROR;
5111 }
5112
5113#ifdef AF_INET6
5114#ifdef IPV6_V6ONLY
5115 if (use_inet6) {
5116 /* turn off IPV6_V6ONLY, see RFC 3493 */
5117 flag = 0;
5118 status = setsockopt(lsock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flag, sizeof(int));
5119 if (status < 0) {
5120 *error_msg_p = msprintf("setsockopt(IPPROTO_IPV6, IPV6_V6ONLY) failed, errno %d (%s)", errno, strerror(errno));
5121 return RPC_NET_ERROR;
5122 }
5123 }
5124#else
5125#warning strange: AF_INET6 is defined, but IPV6_V6ONLY is not defined
5126#endif
5127#endif
5128
5129 if (use_inet6) {
5130#ifdef AF_INET6
5131 /* bind local node name and port to socket */
5132 struct sockaddr_in6 bind_addr6;
5133 memset(&bind_addr6, 0, sizeof(bind_addr6));
5134 bind_addr6.sin6_family = AF_INET6;
5135
5136 if (listen_localhost) {
5137 bind_addr6.sin6_addr = in6addr_loopback;
5138 } else {
5139 bind_addr6.sin6_addr = in6addr_any;
5140 }
5141
5142 if (tcp_port)
5143 bind_addr6.sin6_port = htons((short) tcp_port);
5144 else
5145 bind_addr6.sin6_port = htons(0); // OS will allocate a port number for us
5146
5147 status = bind(lsock, (struct sockaddr *) &bind_addr6, sizeof(bind_addr6));
5148 if (status < 0) {
5149 *error_msg_p = msprintf("IPv6 bind() to port %d failed, errno %d (%s)", tcp_port, errno, strerror(errno));
5150 return RPC_NET_ERROR;
5151 }
5152#endif
5153 } else {
5154 /* bind local node name and port to socket */
5155 struct sockaddr_in bind_addr;
5156 memset(&bind_addr, 0, sizeof(bind_addr));
5157 bind_addr.sin_family = AF_INET;
5158
5159 if (listen_localhost) {
5160 bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
5161 } else {
5162 bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
5163 }
5164
5165 if (tcp_port)
5166 bind_addr.sin_port = htons((short) tcp_port);
5167 else
5168 bind_addr.sin_port = htons(0); // OS will allocate a port number for us
5169
5170 status = bind(lsock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
5171 if (status < 0) {
5172 *error_msg_p = msprintf("bind() to port %d failed, errno %d (%s)", tcp_port, errno, strerror(errno));
5173 return RPC_NET_ERROR;
5174 }
5175 }
5176
5177 /* listen for connection */
5178#ifdef OS_MSDOS
5179 status = listen(lsock, 1);
5180#else
5182#endif
5183 if (status < 0) {
5184 *error_msg_p = msprintf("listen() failed, errno %d (%s)", errno, strerror(errno));
5185 return RPC_NET_ERROR;
5186 }
5187
5188 if (use_inet6) {
5189#ifdef AF_INET6
5190 struct sockaddr_in6 addr;
5191 socklen_t sosize = sizeof(addr);
5192 status = getsockname(lsock, (struct sockaddr*)&addr, &sosize);
5193 if (status < 0) {
5194 *error_msg_p = msprintf("IPv6 getsockname() failed, errno %d (%s)", errno, strerror(errno));
5195 return RPC_NET_ERROR;
5196 }
5197
5198 *tcp_port_p = ntohs(addr.sin6_port);
5199#endif
5200 } else {
5201 struct sockaddr_in addr;
5202 socklen_t sosize = sizeof(addr);
5203 status = getsockname(lsock, (struct sockaddr*)&addr, &sosize);
5204 if (status < 0) {
5205 *error_msg_p = msprintf("getsockname() failed, errno %d (%s)", errno, strerror(errno));
5206 return RPC_NET_ERROR;
5207 }
5208
5209 *tcp_port_p = ntohs(addr.sin_port);
5210 }
5211
5212 *sockp = lsock;
5213
5214 if (gSocketTrace) {
5215 if (listen_localhost)
5216 fprintf(stderr, "ss_socket_listen_tcp: listening tcp port %d local connections only, new socket %d\n", *tcp_port_p, *sockp);
5217 else
5218 fprintf(stderr, "ss_socket_listen_tcp: listening tcp port %d all internet connections, socket %d\n", *tcp_port_p, *sockp);
5219 }
5220
5221 return SS_SUCCESS;
5222}
#define SOMAXCONN
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_socket_wait()

INT EXPRT ss_socket_wait ( int  sock,
INT  millisec 
)

Definition at line 4898 of file system.cxx.

4915{
4916 INT status;
4918 struct timeval timeout;
4919 struct timeval timeout0;
4920 DWORD start_time = 0; // start_time is only used for BSD select() behaviour (MacOS)
4921 DWORD end_time = 0;
4922
4923 FD_ZERO(&readfds);
4924 FD_SET(sock, &readfds);
4925
4926 timeout.tv_sec = millisec / 1000;
4927 timeout.tv_usec = (millisec % 1000) * 1000;
4928
4929 timeout0 = timeout;
4930
4931 while (1) {
4932 status = select(sock+1, &readfds, NULL, NULL, &timeout);
4933 //printf("ss_socket_wait: millisec %d, tv_sec %d, tv_usec %d, isset %d, status %d, errno %d (%s)\n", millisec, timeout.tv_sec, timeout.tv_usec, FD_ISSET(sock, &readfds), status, errno, strerror(errno));
4934
4935#ifndef OS_WINNT
4936 if (status<0 && errno==EINTR) { /* watchdog alarm signal */
4937 /* need to determine if select() updates "timeout" (Linux) or keeps original value (BSD) */
4938 if (timeout.tv_sec == timeout0.tv_sec) {
4939 DWORD now = ss_time();
4940 if (start_time == 0) {
4941 start_time = now;
4942 end_time = start_time + (millisec+999)/1000;
4943 }
4944 //printf("ss_socket_wait: EINTR: now %d, timeout %d, wait time %d\n", now, end_time, end_time - now);
4945 if (now > end_time)
4946 return SS_TIMEOUT;
4947 }
4948 continue;
4949 }
4950#endif
4951 if (status < 0) { /* select() syscall error */
4952 cm_msg(MERROR, "ss_socket_wait", "unexpected error, select() returned %d, errno: %d (%s)", status, errno, strerror(errno));
4953 return SS_SOCKET_ERROR;
4954 }
4955 if (status == 0) /* timeout */
4956 return SS_TIMEOUT;
4957 if (!FD_ISSET(sock, &readfds))
4958 return SS_TIMEOUT;
4959 return SS_SUCCESS;
4960 }
4961 /* NOT REACHED */
4962}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_spawnv()

INT ss_spawnv ( INT  mode,
const char cmdname,
const char *const  argv[] 
)

Definition at line 1630 of file system.cxx.

1653{
1654#ifdef OS_WINNT
1655
1656 if (spawnvp(mode, cmdname, argv) < 0)
1657 return SS_INVALID_NAME;
1658
1659 return SS_SUCCESS;
1660
1661#endif /* OS_WINNT */
1662
1663#ifdef OS_MSDOS
1664
1665 spawnvp((int) mode, cmdname, argv);
1666
1667 return SS_SUCCESS;
1668
1669#endif /* OS_MSDOS */
1670
1671#ifdef OS_VMS
1672
1673 {
1674 char cmdstring[500], *pc;
1675 INT i, flags, status;
1677
1678 $DESCRIPTOR(cmdstring_dsc, "dummy");
1679
1680 if (mode & P_DETACH) {
1681 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
1682 cmdstring_dsc.dsc$a_pointer = cmdstring;
1683
1684 status = sys$creprc(0, &cmdstring_dsc, 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
1685 } else {
1686 flags = (mode & P_NOWAIT) ? 1 : 0;
1687
1688 for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0]; pc--);
1689 if (*pc == ']')
1690 pc++;
1691
1692 strcpy(cmdstring, pc);
1693
1694 if (strchr(cmdstring, ';'))
1695 *strchr(cmdstring, ';') = 0;
1696
1697 strcat(cmdstring, " ");
1698
1699 for (i = 1; argv[i] != NULL; i++) {
1701 strcat(cmdstring, " ");
1702 }
1703
1704 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
1705 cmdstring_dsc.dsc$a_pointer = cmdstring;
1706
1707 status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
1708 }
1709
1710 return BM_SUCCESS;
1711 }
1712
1713#endif /* OS_VMS */
1714#ifdef OS_UNIX
1716
1717#ifdef OS_ULTRIX
1718 union wait *status;
1719#else
1720 int status;
1721#endif
1722
1723#ifdef NO_FORK
1724 assert(!"support for fork() disabled by NO_FORK");
1725#else
1726 if ((child_pid = fork()) < 0)
1727 return (-1);
1728#endif
1729
1730 if (child_pid == 0) {
1731 /* now we are in the child process ... */
1732 int error = execvp(cmdname, (char*const*)argv);
1733 fprintf(stderr, "ss_spawnv: Cannot execute command \"%s\": execvp() returned %d, errno %d (%s), aborting!\n", cmdname, error, errno, strerror(errno));
1734 // NB: this is the forked() process, if it returns back to the caller, we will have
1735 // a duplicate process for whoever called us. Very bad! So must abort. K.O.
1736 abort();
1737 // NOT REACHED
1738 return SS_SUCCESS;
1739 } else {
1740 /* still in parent process */
1741 if (mode == P_WAIT) {
1742#ifdef OS_ULTRIX
1744#else
1746#endif
1747
1748 } else {
1749 /* catch SIGCHLD signal to avoid <defunc> processes */
1751 }
1752 }
1753
1754 return SS_SUCCESS;
1755
1756#endif /* OS_UNIX */
1757}
#define SS_INVALID_NAME
Definition midas.h:666
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_stack_get()

INT EXPRT ss_stack_get ( char ***  string)

Definition at line 7994 of file system.cxx.

7995{
7996#ifdef OS_LINUX
7997#define MAX_STACK_DEPTH 16
7998
7999 void *trace[MAX_STACK_DEPTH];
8000 int size;
8001
8003 *string = backtrace_symbols(trace, size);
8004 return size;
8005#else
8006 return 0;
8007#endif
8008}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_stack_history_dump()

void EXPRT ss_stack_history_dump ( char filename)

Definition at line 8044 of file system.cxx.

8045{
8046 FILE *f;
8047 int i, j;
8048
8049 f = fopen(filename, "wt");
8050 if (f != NULL) {
8052 for (i = 0; i < N_STACK_HISTORY; i++) {
8053 if (strlen(stack_history[j]) > 0)
8054 fprintf(f, "%s\n", stack_history[j]);
8055 j = (j + 1) % N_STACK_HISTORY;
8056 }
8057 fclose(f);
8058 printf("Stack dump written to %s\n", filename);
8059 } else
8060 printf("Cannot open %s: errno=%d\n", filename, errno);
8061}
#define N_STACK_HISTORY
Definition system.cxx:7990
char stack_history[N_STACK_HISTORY][80]
Definition system.cxx:7991
int stack_history_pointer
Definition system.cxx:7992
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:

◆ ss_stack_history_entry()

void EXPRT ss_stack_history_entry ( char tag)

Definition at line 8022 of file system.cxx.

8023{
8024 char **string;
8025 int i, n;
8026
8027 if (stack_history_pointer == -1) {
8029 memset(stack_history, 0, sizeof(stack_history));
8030 }
8033 n = ss_stack_get(&string);
8034 for (i = 2; i < n; i++) {
8037 }
8038 free(string);
8039
8040 mstrlcpy(stack_history[stack_history_pointer], "=========================", 80);
8042}
INT ss_stack_get(char ***string)
Definition system.cxx:7994
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_stack_print()

void EXPRT ss_stack_print ( )

Definition at line 8010 of file system.cxx.

8011{
8012 char **string;
8013 int i, n;
8014
8015 n = ss_stack_get(&string);
8016 for (i = 0; i < n; i++)
8017 printf("%s\n", string[i]);
8018 if (n > 0)
8019 free(string);
8020}
Here is the call graph for this function:

◆ ss_suspend()

INT EXPRT ss_suspend ( INT  millisec,
INT  msg 
)
  • only watch the event tcp connection belonging to this thread *‍/

Definition at line 4543 of file system.cxx.

4614{
4616
4617 midas_thread_t thread_id = ss_gettid();
4618
4620
4621 //printf("ss_suspend: thread %s\n", ss_tid_to_string(thread_id).c_str());
4622
4624
4625 do {
4627 FD_ZERO(&readfds);
4628
4629 if (ss_match_thread(_ss_listen_thread, thread_id)) {
4630 /* check listen sockets */
4633 //printf("ss_suspend: thread %s listen ss_server socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_listen_socket);
4634 }
4635
4638 //printf("ss_suspend: thread %s listen ss_client socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_client_listen_socket);
4639 }
4640 }
4641
4642 /* check server channels */
4644 //printf("ss_suspend: thread %s server acceptions %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_num_acceptions);
4645 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4646 /* RPC channel */
4647 int sock = (*_ss_server_acceptions)[i]->recv_sock;
4648
4649 if (!sock)
4650 continue;
4651
4653 //if (_suspend_struct[idx].server_acception[i].tid != ss_gettid())
4654 // continue;
4655
4656 /* watch server socket if no data in cache */
4657 if (recv_tcp_check(sock) == 0)
4658 FD_SET(sock, &readfds);
4659 /* set timeout to zero if data in cache (-> just quick check IPC)
4660 and not called from inside bm_send_event (-> wait for IPC) */
4661 else if (msg == 0)
4662 millisec = 0;
4663
4664 if (msg == 0 && msg != MSG_BM) {
4665 /* event channel */
4666 sock = (*_ss_server_acceptions)[i]->event_sock;
4667
4668 if (!sock)
4669 continue;
4670
4671 /* check for buffered event */
4673
4674 if (status == BM_ASYNC_RETURN) {
4675 /* event buffer is full and rpc_server_receive_event() is holding on
4676 * to an event it cannot get rid of. Do not read more events from
4677 * the event socket, they have nowhere to go. K.O. */
4678 } else if (status == RPC_SUCCESS) {
4679 FD_SET(sock, &readfds);
4680 }
4681 }
4682 }
4683 }
4684
4685 /* watch for messages from the mserver */
4686 if (ss_match_thread(_ss_client_thread, thread_id)) {
4689 }
4690 }
4691
4692 /* watch for UDP messages in the IPC socket: buffer and odb notifications */
4693 if (ss_match_thread(_ss_odb_thread, thread_id)) {
4696 }
4697
4698 if (psuspend->ipc_recv_socket)
4699 FD_SET(psuspend->ipc_recv_socket, &readfds);
4700
4701 struct timeval timeout;
4702
4703 timeout.tv_sec = millisec / 1000;
4704 timeout.tv_usec = (millisec % 1000) * 1000;
4705
4706 do {
4707 //printf("select millisec %d, tv_sec %d, tv_usec %d\n", millisec, (int)timeout.tv_sec, (int)timeout.tv_usec);
4708
4709 if (millisec < 0)
4710 status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL); /* blocking */
4711 else
4712 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
4713
4714 /* if an alarm signal was cought, restart select with reduced timeout */
4715 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
4716 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
4717
4718 } while (status == -1); /* dont return if an alarm signal was cought */
4719
4720 /* check listener sockets */
4721
4723 //printf("ss_suspend: thread %s rpc_server_accept socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_listen_socket);
4725 if (status == RPC_SHUTDOWN) {
4726 return status;
4727 }
4728 }
4729
4731 //printf("ss_suspend: thread %s rpc_client_accept socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_client_listen_socket);
4733 if (status == RPC_SHUTDOWN) {
4734 return status;
4735 }
4736 }
4737
4738 /* check server channels */
4740 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4741 /* rpc channel */
4742 int sock = (*_ss_server_acceptions)[i]->recv_sock;
4743
4744 if (!sock)
4745 continue;
4746
4747 //printf("rpc index %d, socket %d, hostname \'%s\', progname \'%s\'\n", i, sock, _suspend_struct[idx].server_acception[i].host_name, _suspend_struct[idx].server_acception[i].prog_name);
4748
4749 if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
4750 //printf("ss_suspend: msg %d\n", msg);
4751 if (msg == MSG_BM) {
4752 status = ss_socket_check(sock);
4753 } else {
4754 //printf("ss_suspend: rpc_server_receive_rpc() call!\n");
4756 //printf("ss_suspend: rpc_server_receive_rpc() status %d\n", status);
4757 }
4758 (*_ss_server_acceptions)[i]->last_activity = ss_millitime();
4759
4760 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN) {
4761 return status;
4762 }
4763
4765 }
4766
4767 /* event channel */
4768 sock = (*_ss_server_acceptions)[i]->event_sock;
4769
4770 if (!sock)
4771 continue;
4772
4773 if (FD_ISSET(sock, &readfds)) {
4774 if (msg != 0) {
4775 status = ss_socket_check(sock);
4776 } else {
4777 //printf("ss_suspend: rpc_server_receive_event() call!\n");
4779 //printf("ss_suspend: rpc_server_receive_event() status %d\n", status);
4780 }
4781 (*_ss_server_acceptions)[i]->last_activity = ss_millitime();
4782
4783 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN) {
4784 return status;
4785 }
4786
4788 }
4789 }
4790 }
4791
4792 /* check for messages from the mserver */
4794 int sock = _ss_client_connection->recv_sock;
4795
4796 if (FD_ISSET(sock, &readfds)) {
4798
4799 if (status == SS_ABORT) {
4800 cm_msg(MINFO, "ss_suspend", "RPC connection to mserver at \'%s\' was broken", _ss_client_connection->host_name.c_str());
4801
4802 /* close client connection if link broken */
4806
4810
4812
4813 /* exit program after broken connection to MIDAS server */
4814 return SS_ABORT;
4815 }
4816
4818 }
4819 }
4820
4821 /* check ODB IPC socket */
4824 if (status) {
4825 return status;
4826 }
4827 }
4828
4829 /* check per-thread IPC socket */
4830 if (psuspend && psuspend->ipc_recv_socket && FD_ISSET(psuspend->ipc_recv_socket, &readfds)) {
4831 status = ss_suspend_process_ipc(millisec, msg, psuspend->ipc_recv_socket);
4832 if (status) {
4833 return status;
4834 }
4835 }
4836
4837
4838 } while (millisec < 0);
4839
4840 return return_status;
4841}
#define SS_SERVER_RECV
Definition midas.h:675
#define SS_CLIENT_RECV
Definition midas.h:676
#define RPC_SHUTDOWN
Definition midas.h:707
#define RPC_SUCCESS
Definition midas.h:698
static midas_thread_t _ss_server_thread
Definition system.cxx:3989
static int _ss_server_listen_socket
Definition system.cxx:3983
static int ss_suspend_process_ipc(INT millisec, INT msg, int ipc_recv_socket)
Definition system.cxx:4386
SUSPEND_STRUCT * ss_suspend_get_struct(midas_thread_t thread_id)
Definition system.cxx:4165
static RPC_SERVER_CONNECTION * _ss_client_connection
Definition system.cxx:3987
static midas_thread_t _ss_odb_thread
Definition system.cxx:3979
static int ss_socket_check(int sock)
Definition system.cxx:4493
static bool ss_match_thread(midas_thread_t tid1, midas_thread_t tid2)
Definition system.cxx:3993
static int _ss_client_listen_socket
Definition system.cxx:3984
static midas_thread_t _ss_listen_thread
Definition system.cxx:3982
midas_thread_t ss_gettid(void)
Definition system.cxx:1519
static midas_thread_t _ss_client_thread
Definition system.cxx:3986
INT recv_tcp_check(int sock)
Definition midas.cxx:14357
INT rpc_server_receive_rpc(int idx, RPC_SERVER_ACCEPTION *sa)
Definition midas.cxx:15871
INT rpc_client_accept(int lsock)
Definition midas.cxx:15598
INT rpc_server_accept(int lsock)
Definition midas.cxx:15341
INT rpc_client_dispatch(int sock)
Definition midas.cxx:11945
#define closesocket(s)
Definition melog.cxx:29
INT midas_thread_t
Definition midas.h:179
#define WATCHDOG_INTERVAL
Definition midas.h:288
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_close()

static void ss_suspend_close ( SUSPEND_STRUCT psuspend)
static

Definition at line 4207 of file system.cxx.

4208{
4209 if (psuspend->ipc_recv_socket) {
4210 closesocket(psuspend->ipc_recv_socket);
4211 psuspend->ipc_recv_socket = 0;
4212 }
4213
4214 if (psuspend->ipc_send_socket) {
4215 closesocket(psuspend->ipc_send_socket);
4216 psuspend->ipc_send_socket = 0;
4217 }
4218
4219 //printf("ss_suspend_close: free thread %s, udp port %d\n", ss_tid_to_string(psuspend->thread_id).c_str(), psuspend->ipc_recv_port);
4220
4221 psuspend->thread_id = 0;
4222 psuspend->ipc_recv_port = 0;
4223}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_exit()

INT ss_suspend_exit ( )

Definition at line 4226 of file system.cxx.

4244{
4245 midas_thread_t thread_id = ss_gettid();
4246
4247 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4248 if (!_ss_suspend_vector[i])
4249 continue;
4250 if (_ss_suspend_vector[i]->thread_id == thread_id) {
4254 delete psuspend;
4255 }
4256 }
4257
4258 if (_ss_suspend_odb) {
4259 bool last = true;
4260 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4261 if (_ss_suspend_vector[i]) {
4262 last = false;
4263 break;
4264 }
4265 }
4266 if (last) {
4270 delete psuspend;
4271 }
4272 }
4273
4274 return SS_SUCCESS;
4275}
static void ss_suspend_close(SUSPEND_STRUCT *psuspend)
Definition system.cxx:4207
static std::vector< SUSPEND_STRUCT * > _ss_suspend_vector
Definition system.cxx:3977
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_get_buffer_port()

INT ss_suspend_get_buffer_port ( midas_thread_t  thread_id,
INT port 
)

Definition at line 4353 of file system.cxx.

4374{
4376
4377 if (!psuspend->ipc_recv_port) {
4379 }
4380
4381 *port = psuspend->ipc_recv_port;
4382
4383 return SS_SUCCESS;
4384}
static INT ss_suspend_init_struct(SUSPEND_STRUCT *psuspend)
Definition system.cxx:4012
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_get_odb_port()

INT ss_suspend_get_odb_port ( INT port)

Definition at line 4327 of file system.cxx.

4344{
4345 assert(_ss_suspend_odb);
4346
4348
4349 return SS_SUCCESS;
4350}
Here is the caller graph for this function:

◆ ss_suspend_get_struct()

SUSPEND_STRUCT * ss_suspend_get_struct ( midas_thread_t  thread_id)

Definition at line 4165 of file system.cxx.

4179{
4180 // find thread_id
4181 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4182 if (!_ss_suspend_vector[i])
4183 continue;
4184 if (_ss_suspend_vector[i]->thread_id == thread_id) {
4185 return _ss_suspend_vector[i];
4186 }
4187 }
4188
4189 // create new one if not found
4191 psuspend->thread_id = thread_id;
4192
4193 // place into empty slot
4194 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4195 if (!_ss_suspend_vector[i]) {
4197 return psuspend;
4198 }
4199 }
4200
4201 // add to vector if no empty slots
4202 _ss_suspend_vector.push_back(psuspend);
4203
4204 return psuspend;
4205}
struct suspend_struct SUSPEND_STRUCT
midas_thread_t thread_id
Definition system.cxx:3970
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_init_odb_port()

INT ss_suspend_init_odb_port ( )

Definition at line 4305 of file system.cxx.

4316{
4317 if (!_ss_suspend_odb) {
4321 }
4322
4323 return SS_SUCCESS;
4324}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_init_struct()

static INT ss_suspend_init_struct ( SUSPEND_STRUCT psuspend)
static

Definition at line 4012 of file system.cxx.

4028{
4029 INT status, sock;
4030 unsigned int size;
4031 struct sockaddr_in bind_addr;
4032 //int udp_bind_hostname = 0; // bind to localhost or bind to hostname or bind to INADDR_ANY?
4033
4034 //printf("ss_suspend_init_struct: thread %s\n", ss_tid_to_string(psuspend->thread_id).c_str());
4035
4036 assert(psuspend->thread_id != 0);
4037
4038#ifdef OS_WINNT
4039 {
4041
4042 /* Start windows sockets */
4043 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
4044 return SS_SOCKET_ERROR;
4045 }
4046#endif
4047
4048 /*--------------- create UDP receive socket -------------------*/
4049 sock = socket(AF_INET, SOCK_DGRAM, 0);
4050 if (sock == -1)
4051 return SS_SOCKET_ERROR;
4052
4053 /* let OS choose port for socket */
4054 memset(&bind_addr, 0, sizeof(bind_addr));
4055 bind_addr.sin_family = AF_INET;
4056 bind_addr.sin_addr.s_addr = 0;
4057 bind_addr.sin_port = 0;
4058
4059 /* decide if UDP sockets are bound to localhost (they are only use for local communications)
4060 or to hostname (for compatibility with old clients - their hotlinks will not work) */
4061 {
4062 std::string path = cm_get_path();
4063 path += ".UDP_BIND_HOSTNAME";
4064
4065 //cm_msg(MERROR, "ss_suspend_init_ipc", "check file [%s]", path.c_str());
4066
4067 FILE *fp = fopen(path.c_str(), "r");
4068 if (fp) {
4069 cm_msg(MERROR, "ss_suspend_init_ipc", "Support for UDP_BIND_HOSTNAME was removed. Please delete file \"%s\"", path.c_str());
4070 //udp_bind_hostname = 1;
4071 fclose(fp);
4072 fp = NULL;
4073 }
4074 }
4075
4076 //#ifdef OS_VXWORKS
4077 //{
4078 // char local_host_name[HOST_NAME_LENGTH];
4079 // INT host_addr;
4080 //
4081 // gethostname(local_host_name, sizeof(local_host_name));
4082 //
4083 //host_addr = hostGetByName(local_host_name);
4084 // memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
4085 //}
4086 //#else
4087 //if (udp_bind_hostname) {
4088 // char local_host_name[HOST_NAME_LENGTH];
4089 // struct hostent *phe = gethostbyname(local_host_name);
4090 // if (phe == NULL) {
4091 // cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get IP address for host name \'%s\'", local_host_name);
4092 // return SS_SOCKET_ERROR;
4093 // }
4094 // memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
4095 //} else {
4096 bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4097 //}
4098 //#endif
4099
4100 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
4101 if (status < 0)
4102 return SS_SOCKET_ERROR;
4103
4104 /* find out which port OS has chosen */
4105 size = sizeof(bind_addr);
4106#ifdef OS_WINNT
4107 getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &size);
4108#else
4109 getsockname(sock, (struct sockaddr *) &bind_addr, &size);
4110#endif
4111
4112 // ipc receive socket must be set to non-blocking mode, see explanation
4113 // in ss_suspend_process_ipc(). K.O. July 2022.
4114
4115 int flags = fcntl(sock, F_GETFL, 0);
4116 status = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
4117
4118 if (status < 0) {
4119 fprintf(stderr, "ss_suspend_init_struct: cannot set non-blocking mode of ipc receive socket, fcntl() returned %d, errno %d (%s)\n", status, errno, strerror(errno));
4120 return SS_SOCKET_ERROR;
4121 }
4122
4123 psuspend->ipc_recv_socket = sock;
4124 psuspend->ipc_recv_port = ntohs(bind_addr.sin_port);
4125
4126 /*--------------- create UDP send socket ----------------------*/
4127 sock = socket(AF_INET, SOCK_DGRAM, 0);
4128
4129 if (sock == -1)
4130 return SS_SOCKET_ERROR;
4131
4132 /* fill out bind struct pointing to local host */
4133 memset(&bind_addr, 0, sizeof(bind_addr));
4134 bind_addr.sin_family = AF_INET;
4135 bind_addr.sin_addr.s_addr = 0;
4136
4137 //#ifdef OS_VXWORKS
4138 //{
4139 // INT host_addr;
4140 //
4141 // host_addr = hostGetByName(local_host_name);
4142 //memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
4143 //}
4144 //#else
4145 //if (udp_bind_hostname) {
4146 // // nothing
4147 //} else {
4148 bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4149
4150 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
4151 if (status < 0)
4152 return SS_SOCKET_ERROR;
4153 //}
4154 //#endif
4155
4156 memcpy(&(psuspend->bind_addr), &bind_addr, sizeof(bind_addr));
4157 psuspend->ipc_send_socket = sock;
4158
4159 //printf("ss_suspend_init_struct: thread %s, udp port %d\n", ss_tid_to_string(psuspend->thread_id).c_str(), psuspend->ipc_recv_port);
4160
4161 return SS_SUCCESS;
4162}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_process_ipc()

static int ss_suspend_process_ipc ( INT  millisec,
INT  msg,
int  ipc_recv_socket 
)
static

Definition at line 4386 of file system.cxx.

4387{
4388 char buffer[80];
4389 buffer[0] = 0;
4390 /* receive IPC message */
4391 struct sockaddr from_addr;
4392 socklen_t from_addr_size = sizeof(struct sockaddr);
4393
4394 // note: ipc_recv_socket must be set in non-blocking mode:
4395 // it looks as if we come here from ss_suspend() only if select() said
4396 // that our socket has data. but this is not true. after that select(),
4397 // ss_suspend() reads other sockets, calls other handlers, which may call
4398 // ss_suspend() recursively (i.e. via bm_receive_event() RPC call to "wait_for_more_data"
4399 // call to ss_suspend()). the recursively called ss_suspend() will
4400 // also so select() and call this function to read from this socket. then it eventually
4401 // returns, all the handlers return back to the original ss_suspend(), which
4402 // happily remembers that the original select() told us we have data. but this data
4403 // was already read by the recursively call ss_suspend(), so the socket is empty
4404 // and our recvfrom() will sleep forever. inside the mserver, this makes mserver
4405 // stop (very bad!). with the socket set to non-blocking mode
4406 // recvfrom() will never sleep and this problem is avoided. K.O. July 2022
4407 // see bug report https://bitbucket.org/tmidas/midas/issues/346/rpc-timeout-in-bm_receive_event
4408
4409 // note2: in midas, there is never a situation where we wait for data
4410 // from the ipc sockets. these sockets are used for "event buffer has data" and "odb has new data"
4411 // notifications. we check them, but we do not wait for them. this setting
4412 // the socket to non-blocking mode is safe. K.O. July 2022.
4413
4414 ssize_t size = recvfrom(ipc_recv_socket, buffer, sizeof(buffer), 0, &from_addr, &from_addr_size);
4415
4416 if (size <= 0) {
4417 //fprintf(stderr, "ss_suspend_process_ipc: recvfrom() returned %zd, errno %d (%s)\n", size, errno, strerror(errno));
4418 // return 0 means we did not do anyting. K.O.
4419 return 0;
4420 }
4421
4422 // NB: ss_suspend(MSG_BM) (and ss_suspend(MSG_ODB)) are needed to break
4423 // recursive calls to the event handler (and db_watch() handler) if these
4424 // handlers call ss_suspend() again. The rootana interactive ROOT graphics
4425 // mode does this. To prevent this recursion, event handlers must always
4426 // call ss_suspend() with MSG_BM (and MSG_ODB). K.O.
4427
4428 /* return if received requested message */
4429 if (msg == MSG_BM && buffer[0] == 'B')
4430 return SS_SUCCESS;
4431 if (msg == MSG_ODB && buffer[0] == 'O')
4432 return SS_SUCCESS;
4433
4434 // NB: do not need to check thread id, the mserver is single-threaded. K.O.
4435 int mserver_client_socket = 0;
4437 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4438 if ((*_ss_server_acceptions)[i]->is_mserver) {
4439 mserver_client_socket = (*_ss_server_acceptions)[i]->send_sock;
4440 }
4441 }
4442 }
4443
4444 time_t tstart = time(NULL);
4445 int return_status = 0;
4446
4447 /* receive further messages to empty UDP queue */
4448 while (1) {
4449 char buffer_tmp[80];
4450 buffer_tmp[0] = 0;
4451 from_addr_size = sizeof(struct sockaddr);
4452
4453 // note: ipc_recv_socket must be in non-blocking mode, see comments above. K.O.
4454
4455 ssize_t size_tmp = recvfrom(ipc_recv_socket, buffer_tmp, sizeof(buffer_tmp), 0, &from_addr, &from_addr_size);
4456
4457 if (size_tmp <= 0) {
4458 //fprintf(stderr, "ss_suspend_process_ipc: second recvfrom() returned %zd, errno %d (%s)\n", size, errno, strerror(errno));
4459 break;
4460 }
4461
4462 /* stop the loop if received requested message */
4463 if (msg == MSG_BM && buffer_tmp[0] == 'B') {
4465 break;
4466 }
4467 if (msg == MSG_ODB && buffer_tmp[0] == 'O') {
4469 break;
4470 }
4471
4472 /* don't forward same MSG_BM as above */
4473 if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0) {
4475 }
4476
4477 if (millisec > 0) {
4478 time_t tnow = time(NULL);
4479 // make sure we do not loop for longer than our timeout
4480 if (tnow - tstart > 1 + millisec/1000) {
4481 //printf("ss_suspend - break out dt %d, %d loops\n", (int)(tnow-tstart), count);
4482 break;
4483 }
4484 }
4485 }
4486
4487 /* call dispatcher */
4489
4490 return return_status;
4491}
INT cm_dispatch_ipc(const char *message, int message_size, int client_socket)
Definition midas.cxx:5385
#define MSG_ODB
Definition msystem.h:296
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_set_client_connection()

INT ss_suspend_set_client_connection ( RPC_SERVER_CONNECTION connection)

Definition at line 4291 of file system.cxx.

4292{
4293 // client side of the mserver connection
4295 return SS_SUCCESS;
4296}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_set_client_listener()

INT ss_suspend_set_client_listener ( int  listen_socket)

Definition at line 4284 of file system.cxx.

4285{
4286 // midas program rpc listener socket (run transitions, etc)
4288 return SS_SUCCESS;
4289}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_set_rpc_thread()

INT ss_suspend_set_rpc_thread ( midas_thread_t  thread_id)

Definition at line 4002 of file system.cxx.

4003{
4004 _ss_listen_thread = thread_id; // this thread handles listen()/accept() activity
4005 _ss_client_thread = thread_id; // this thread reads the mserver connection, handles ODB and event buffer notifications (db_watch->db_update_record_local(), bm_poll_event())
4006 _ss_server_thread = thread_id; // this thread reads and executes RPC requests
4007 _ss_odb_thread = thread_id; // this thread reads and dispatches ODB notifications (db_watch & co)
4008 return SS_SUCCESS;
4009}
Here is the caller graph for this function:

◆ ss_suspend_set_server_acceptions()

INT ss_suspend_set_server_acceptions ( RPC_SERVER_ACCEPTION_LIST acceptions)

Definition at line 4298 of file system.cxx.

4299{
4300 // server side of the RPC connections (run transitions, etc)
4302 return SS_SUCCESS;
4303}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_set_server_listener()

INT ss_suspend_set_server_listener ( int  listen_socket)

Definition at line 4277 of file system.cxx.

4278{
4279 // mserver listener socket
4281 return SS_SUCCESS;
4282}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_system()

INT EXPRT ss_system ( const char command)

Execute command in a separate process, close all open file descriptors invoke ss_exec() and ignore pid.

{ ...
char cmd[256];
sprintf(cmd,"%s %s %i %s/%s %1.3lf %d",lazy.commandAfter,
lazyst.file_size/1000.0/1000.0, blockn);
cm_msg(MINFO,"Lazy","Exec post file write script:%s",cmd);
ss_system(cmd);
}
...
INT ss_system(const char *command)
Definition system.cxx:2116
INT blockn
LAZY_STATISTICS lazyst
LAZY_SETTING lazy
char commandAfter[64]
char path[MAX_FILE_PATH]
char backlabel[MAX_FILE_PATH]
char backfile[MAX_FILE_PATH]
Parameters
commandCommand to execute.
Returns
SS_SUCCESS or ss_exec() return code

Definition at line 2116 of file system.cxx.

2117{
2118#ifdef OS_UNIX
2119 INT childpid;
2120
2121 return ss_exec(command, &childpid);
2122
2123#else
2124
2125 system(command);
2126 return SS_SUCCESS;
2127
2128#endif
2129}
INT ss_exec(const char *command, INT *pid)
Definition system.cxx:2132
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_close()

INT EXPRT ss_tape_close ( INT  channel)

Definition at line 5902 of file system.cxx.

5920{
5921 INT status;
5922
5923#ifdef OS_UNIX
5924
5925 status = close(channel);
5926
5927 if (status < 0) {
5928 cm_msg(MERROR, "ss_tape_close", "close() returned %d, errno %d (%s)", status, errno, strerror(errno));
5929 return errno;
5930 }
5931#endif /* OS_UNIX */
5932
5933#ifdef OS_WINNT
5934
5935 if (!CloseHandle((HANDLE) channel)) {
5936 status = GetLastError();
5937 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
5938 return status;
5939 }
5940#endif /* OS_WINNT */
5941
5942 return SS_SUCCESS;
5943}
INT channel
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_fskip()

INT EXPRT ss_tape_fskip ( INT  channel,
INT  count 
)

Definition at line 6232 of file system.cxx.

6251{
6252#ifdef MTIOCTOP
6253 struct mtop arg;
6254 INT status;
6255
6256 if (count > 0)
6257 arg.mt_op = MTFSF;
6258 else
6259 arg.mt_op = MTBSF;
6260 arg.mt_count = abs(count);
6261
6262 //cm_enable_watchdog(FALSE);
6263
6264 status = ioctl(channel, MTIOCTOP, &arg);
6265
6266 //cm_enable_watchdog(TRUE);
6267
6268 if (status < 0) {
6269 cm_msg(MERROR, "ss_tape_fskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6270 return errno;
6271 }
6272#endif /* OS_UNIX */
6273
6274#ifdef OS_WINNT
6275 INT status;
6276
6278
6280 return SS_END_OF_TAPE;
6281
6282 if (status != NO_ERROR) {
6283 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
6284 return status;
6285 }
6286#endif /* OS_WINNT */
6287
6288 return SS_SUCCESS;
6289}
#define SS_END_OF_TAPE
Definition midas.h:684
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_get_blockn()

INT EXPRT ss_tape_get_blockn ( INT  channel)

Definition at line 6568 of file system.cxx.

6577{
6578#if defined(OS_DARWIN)
6579
6580 return 0;
6581
6582#elif defined(OS_UNIX)
6583
6584 INT status;
6585 struct mtpos arg;
6586
6587 //cm_enable_watchdog(FALSE);
6588 status = ioctl(channel, MTIOCPOS, &arg);
6589 //cm_enable_watchdog(TRUE);
6590 if (status < 0) {
6591 if (errno == EIO)
6592 return 0;
6593 else {
6594 cm_msg(MERROR, "ss_tape_get_blockn", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6595 return -errno;
6596 }
6597 }
6598 return (arg.mt_blkno);
6599
6600#elif defined(OS_WINNT)
6601
6602 INT status;
6604 unsigned long size;
6605 /* I'm not sure the partition count corresponds to the block count */
6607 return (media.PartitionCount);
6608
6609#endif
6610}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_mount()

INT EXPRT ss_tape_mount ( INT  channel)

Definition at line 6456 of file system.cxx.

6474{
6475#ifdef MTIOCTOP
6476 struct mtop arg;
6477 INT status;
6478
6479#ifdef MTLOAD
6480 arg.mt_op = MTLOAD;
6481#else
6482 arg.mt_op = MTNOP;
6483#endif
6484 arg.mt_count = 0;
6485
6486 //cm_enable_watchdog(FALSE);
6487
6488 status = ioctl(channel, MTIOCTOP, &arg);
6489
6490 //cm_enable_watchdog(TRUE);
6491
6492 if (status < 0) {
6493 cm_msg(MERROR, "ss_tape_mount", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6494 return errno;
6495 }
6496#endif /* OS_UNIX */
6497
6498#ifdef OS_WINNT
6499 INT status;
6500
6502 if (status != NO_ERROR) {
6503 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
6504 return status;
6505 }
6506#endif /* OS_WINNT */
6507
6508 return CM_SUCCESS;
6509}
#define CM_SUCCESS
Definition midas.h:582
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_open()

INT EXPRT ss_tape_open ( char path,
INT  oflag,
INT channel 
)

Definition at line 5811 of file system.cxx.

5833{
5834#ifdef OS_UNIX
5835 //cm_enable_watchdog(FALSE);
5836
5837 *channel = open(path, oflag, 0644);
5838
5839 //cm_enable_watchdog(TRUE);
5840
5841 if (*channel < 0)
5842 cm_msg(MERROR, "ss_tape_open", "open() returned %d, errno %d (%s)", *channel, errno, strerror(errno));
5843
5844 if (*channel < 0) {
5845 if (errno == EIO)
5846 return SS_NO_TAPE;
5847 if (errno == EBUSY)
5848 return SS_DEV_BUSY;
5849 return errno;
5850 }
5851#ifdef MTSETBLK
5852 {
5853 /* set variable block size */
5854 struct mtop arg;
5855 arg.mt_op = MTSETBLK;
5856 arg.mt_count = 0;
5857
5858 ioctl(*channel, MTIOCTOP, &arg);
5859 }
5860#endif /* MTSETBLK */
5861
5862#endif /* OS_UNIX */
5863
5864#ifdef OS_WINNT
5865 INT status;
5867
5869
5870 if (*channel == (INT) INVALID_HANDLE_VALUE) {
5871 status = GetLastError();
5873 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
5874 return SS_DEV_BUSY;
5875 }
5877 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
5878 return SS_NO_TAPE;
5879 }
5880
5881 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
5882 return status;
5883 }
5884
5887 cm_msg(MERROR, "ss_tape_open", "no media in drive");
5888 return SS_NO_TAPE;
5889 }
5890
5891 /* set block size */
5892 memset(&m, 0, sizeof(m));
5893 m.BlockSize = TAPE_BUFFER_SIZE;
5895
5896#endif
5897
5898 return SS_SUCCESS;
5899}
#define SS_NO_TAPE
Definition midas.h:679
#define SS_DEV_BUSY
Definition midas.h:680
#define TAPE_BUFFER_SIZE
Definition midas.h:264
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_read()

INT EXPRT ss_tape_read ( INT  channel,
void pdata,
INT count 
)

Definition at line 6092 of file system.cxx.

6112{
6113#ifdef OS_UNIX
6114 INT n, status;
6115
6116 do {
6117 n = read(channel, pdata, *count);
6118 } while (n == -1 && errno == EINTR);
6119
6120 if (n == -1) {
6121 if (errno == ENOSPC || errno == EIO)
6123 else {
6124 if (n == 0 && errno == 0)
6126 else {
6127 cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", n, errno);
6128 status = errno;
6129 }
6130 }
6131 } else
6133 *count = n;
6134
6135 return status;
6136
6137#elif defined(OS_WINNT) /* OS_UNIX */
6138
6139 INT status;
6140 DWORD read;
6141
6142 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
6143 status = GetLastError();
6146 else if (status == ERROR_FILEMARK_DETECTED)
6148 else if (status == ERROR_MORE_DATA)
6150 else
6151 cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", read, status);
6152 } else
6154
6155 *count = read;
6156 return status;
6157
6158#else /* OS_WINNT */
6159
6160 return SS_SUCCESS;
6161
6162#endif
6163}
#define SS_END_OF_FILE
Definition midas.h:685
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_rewind()

INT EXPRT ss_tape_rewind ( INT  channel)

Definition at line 6348 of file system.cxx.

6366{
6367#ifdef MTIOCTOP
6368 struct mtop arg;
6369 INT status;
6370
6371 arg.mt_op = MTREW;
6372 arg.mt_count = 0;
6373
6374 //cm_enable_watchdog(FALSE);
6375
6376 status = ioctl(channel, MTIOCTOP, &arg);
6377
6378 //cm_enable_watchdog(TRUE);
6379
6380 if (status < 0) {
6381 cm_msg(MERROR, "ss_tape_rewind", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6382 return errno;
6383 }
6384#endif /* OS_UNIX */
6385
6386#ifdef OS_WINNT
6387 INT status;
6388
6390 if (status != NO_ERROR) {
6391 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
6392 return status;
6393 }
6394#endif /* OS_WINNT */
6395
6396 return CM_SUCCESS;
6397}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_rskip()

INT EXPRT ss_tape_rskip ( INT  channel,
INT  count 
)

Definition at line 6292 of file system.cxx.

6311{
6312#ifdef MTIOCTOP
6313 struct mtop arg;
6314 INT status;
6315
6316 if (count > 0)
6317 arg.mt_op = MTFSR;
6318 else
6319 arg.mt_op = MTBSR;
6320 arg.mt_count = abs(count);
6321
6322 //cm_enable_watchdog(FALSE);
6323
6324 status = ioctl(channel, MTIOCTOP, &arg);
6325
6326 //cm_enable_watchdog(TRUE);
6327
6328 if (status < 0) {
6329 cm_msg(MERROR, "ss_tape_rskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6330 return errno;
6331 }
6332#endif /* OS_UNIX */
6333
6334#ifdef OS_WINNT
6335 INT status;
6336
6338 if (status != NO_ERROR) {
6339 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
6340 return status;
6341 }
6342#endif /* OS_WINNT */
6343
6344 return CM_SUCCESS;
6345}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_spool()

INT EXPRT ss_tape_spool ( INT  channel)

Definition at line 6400 of file system.cxx.

6418{
6419#ifdef MTIOCTOP
6420 struct mtop arg;
6421 INT status;
6422
6423#ifdef MTEOM
6424 arg.mt_op = MTEOM;
6425#else
6426 arg.mt_op = MTSEOD;
6427#endif
6428 arg.mt_count = 0;
6429
6430 //cm_enable_watchdog(FALSE);
6431
6432 status = ioctl(channel, MTIOCTOP, &arg);
6433
6434 //cm_enable_watchdog(TRUE);
6435
6436 if (status < 0) {
6437 cm_msg(MERROR, "ss_tape_rewind", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6438 return errno;
6439 }
6440#endif /* OS_UNIX */
6441
6442#ifdef OS_WINNT
6443 INT status;
6444
6446 if (status != NO_ERROR) {
6447 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
6448 return status;
6449 }
6450#endif /* OS_WINNT */
6451
6452 return CM_SUCCESS;
6453}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_status()

INT EXPRT ss_tape_status ( char path)

Definition at line 5946 of file system.cxx.

5963{
5964#ifdef OS_UNIX
5965 int status;
5966 char str[256];
5967 /* let 'mt' do the job */
5968 sprintf(str, "mt -f %s status", path);
5969 status = system(str);
5970 if (status == -1)
5971 return SS_TAPE_ERROR;
5972 return SS_SUCCESS;
5973#endif /* OS_UNIX */
5974
5975#ifdef OS_WINNT
5977 DWORD size;
5980 double x;
5981
5983
5984 if (channel == (INT) INVALID_HANDLE_VALUE) {
5985 status = GetLastError();
5987 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
5988 return SS_SUCCESS;
5989 }
5991 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
5992 return SS_SUCCESS;
5993 }
5994
5995 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
5996 return status;
5997 }
5998
5999 /* poll media changed messages */
6002
6005 cm_msg(MINFO, "ss_tape_status", "no media in drive");
6007 return SS_SUCCESS;
6008 }
6009
6012
6013 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
6014 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
6015 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
6016
6017 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
6018 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
6019 / 1000.0 / 1000.0;
6020 printf("Tape capacity remaining is %d MB\n", (int) x);
6021 } else
6022 printf("Tape capacity is not reported by tape\n");
6023
6025
6026#endif
6027
6028 return SS_SUCCESS;
6029}
#define SS_TAPE_ERROR
Definition midas.h:682
double d
Definition system.cxx:1311
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_unmount()

INT EXPRT ss_tape_unmount ( INT  channel)

Definition at line 6512 of file system.cxx.

6530{
6531#ifdef MTIOCTOP
6532 struct mtop arg;
6533 INT status;
6534
6535#ifdef MTOFFL
6536 arg.mt_op = MTOFFL;
6537#else
6538 arg.mt_op = MTUNLOAD;
6539#endif
6540 arg.mt_count = 0;
6541
6542 //cm_enable_watchdog(FALSE);
6543
6544 status = ioctl(channel, MTIOCTOP, &arg);
6545
6546 //cm_enable_watchdog(TRUE);
6547
6548 if (status < 0) {
6549 cm_msg(MERROR, "ss_tape_unmount", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6550 return errno;
6551 }
6552#endif /* OS_UNIX */
6553
6554#ifdef OS_WINNT
6555 INT status;
6556
6558 if (status != NO_ERROR) {
6559 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
6560 return status;
6561 }
6562#endif /* OS_WINNT */
6563
6564 return CM_SUCCESS;
6565}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_write()

INT EXPRT ss_tape_write ( INT  channel,
void pdata,
INT  count 
)

Definition at line 6032 of file system.cxx.

6053{
6054#ifdef OS_UNIX
6055 INT status;
6056
6057 do {
6059/*
6060 if (status != count)
6061 printf("count: %d - %d\n", count, status);
6062*/
6063 } while (status == -1 && errno == EINTR);
6064
6065 if (status != count) {
6066 cm_msg(MERROR, "ss_tape_write", "write() returned %d, errno %d (%s)", status, errno, strerror(errno));
6067
6068 if (errno == EIO)
6069 return SS_IO_ERROR;
6070 else
6071 return SS_TAPE_ERROR;
6072 }
6073#endif /* OS_UNIX */
6074
6075#ifdef OS_WINNT
6076 INT status;
6077 DWORD written;
6078
6080 if (written != (DWORD) count) {
6081 status = GetLastError();
6082 cm_msg(MERROR, "ss_tape_write", "error %d", status);
6083
6084 return SS_IO_ERROR;
6085 }
6086#endif /* OS_WINNT */
6087
6088 return SS_SUCCESS;
6089}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_write_eof()

INT EXPRT ss_tape_write_eof ( INT  channel)

Definition at line 6166 of file system.cxx.

6184{
6185#ifdef MTIOCTOP
6186 struct mtop arg;
6187 INT status;
6188
6189 arg.mt_op = MTWEOF;
6190 arg.mt_count = 1;
6191
6192 //cm_enable_watchdog(FALSE);
6193
6194 status = ioctl(channel, MTIOCTOP, &arg);
6195
6196 //cm_enable_watchdog(TRUE);
6197
6198 if (status < 0) {
6199 cm_msg(MERROR, "ss_tape_write_eof", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6200 return errno;
6201 }
6202#endif /* OS_UNIX */
6203
6204#ifdef OS_WINNT
6205
6207 DWORD size;
6208 INT status;
6209
6210 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
6212
6213 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
6215 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
6217 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
6219 else
6220 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
6221
6222 if (status != NO_ERROR) {
6223 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
6224 return status;
6225 }
6226#endif /* OS_WINNT */
6227
6228 return SS_SUCCESS;
6229}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_thread_create()

midas_thread_t EXPRT ss_thread_create ( INT(*)(void *)  thread_func,
void param 
)

Creates and returns a new thread of execution.

Note the difference when calling from vxWorks versus Linux and Windows. The parameter pointer for a vxWorks call is a VX_TASK_SPAWN structure, whereas for Linux and Windows it is a void pointer. Early versions returned SS_SUCCESS or SS_NO_THREAD instead of thread ID.

Example for VxWorks

...
VX_TASK_SPAWN tsWatch = {"Watchdog", 100, 0, 2000, (int) pDevice, 0, 0, 0, 0, 0, 0, 0, 0 ,0};
if (thread_id == 0) {
printf("cannot spawn taskWatch\n");
}
...
midas_thread_t ss_thread_create(INT(*thread_func)(void *), void *param)
Definition system.cxx:2310

Example for Linux

...
midas_thread_t thread_id = ss_thread_create((void *) taskWatch, pDevice);
if (thread_id == 0) {
printf("cannot spawn taskWatch\n");
}
...
Parameters
(*thread_func)Thread function to create.
parama pointer to a VX_TASK_SPAWN structure for vxWorks and a void pointer for Unix and Windows
Returns
the new thread id or zero on error

Definition at line 2310 of file system.cxx.

2311{
2312#if defined(OS_WINNT)
2313
2314 HANDLE status;
2315 DWORD thread_id;
2316
2317 if (thread_func == NULL) {
2318 return 0;
2319 }
2320
2322
2323 return status == NULL ? 0 : (midas_thread_t) thread_id;
2324
2325#elif defined(OS_MSDOS)
2326
2327 return 0;
2328
2329#elif defined(OS_VMS)
2330
2331 return 0;
2332
2333#elif defined(OS_VXWORKS)
2334
2335/* taskSpawn which could be considered as a thread under VxWorks
2336 requires several argument beside the thread args
2337 taskSpawn (taskname, priority, option, stacksize, entry_point
2338 , arg1, arg2, ... , arg9, arg10)
2339 all the arg will have to be retrieved from the param list.
2340 through a structure to be simpler */
2341
2342 INT status;
2344
2345 ts = (VX_TASK_SPAWN *) param;
2346 status =
2347 taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
2348 (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
2349 ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9, ts->arg10);
2350
2351 return status == ERROR ? 0 : status;
2352
2353#elif defined(OS_UNIX)
2354
2355 INT status;
2356 pthread_t thread_id;
2357
2358 status = pthread_create(&thread_id, NULL, (void* (*)(void*))thread_func, param);
2359
2360 return status != 0 ? 0 : thread_id;
2361
2362#endif
2363}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_thread_get_name()

std::string ss_thread_get_name ( )

Definition at line 2444 of file system.cxx.

2445{
2446#if defined(OS_UNIX)
2447 char str[256];
2449 pthread_getname_np(thread, str, sizeof(str));
2450 return std::string(str);
2451#else
2452 return "";
2453#endif
2454}
Here is the call graph for this function:

◆ ss_thread_kill()

INT EXPRT ss_thread_kill ( midas_thread_t  thread_id)

Destroys the thread identified by the passed thread id. The thread id is returned by ss_thread_create() on creation.

...
midas_thread_t thread_id = ss_thread_create((void *) taskWatch, pDevice);
if (thread_id == 0) {
printf("cannot spawn taskWatch\n");
}
...
ss_thread_kill(thread_id);
...
Parameters
thread_idthe thread id of the thread to be killed.
Returns
SS_SUCCESS if no error, else SS_NO_THREAD

Definition at line 2383 of file system.cxx.

2384{
2385#if defined(OS_WINNT)
2386
2387 DWORD status;
2388 HANDLE th;
2389
2390 th = OpenThread(THREAD_TERMINATE, FALSE, (DWORD)thread_id);
2391 if (th == 0)
2392 status = GetLastError();
2393
2395
2396 if (status == 0)
2397 status = GetLastError();
2398
2399 return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
2400
2401#elif defined(OS_MSDOS)
2402
2403 return 0;
2404
2405#elif defined(OS_VMS)
2406
2407 return 0;
2408
2409#elif defined(OS_VXWORKS)
2410
2411 INT status;
2412 status = taskDelete(thread_id);
2413 return status == OK ? 0 : ERROR;
2414
2415#elif defined(OS_UNIX)
2416
2417 INT status;
2418 status = pthread_kill(thread_id, SIGKILL);
2419 return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
2420
2421#endif
2422}
#define SS_NO_THREAD
Definition midas.h:672
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_thread_set_name()

INT EXPRT ss_thread_set_name ( std::string  name)

Definition at line 2426 of file system.cxx.

2427{
2428#if defined(OS_DARWIN)
2429
2430 pthread_setname_np(name.c_str());
2431 return SS_SUCCESS;
2432
2433#elif defined(OS_UNIX)
2434
2436 pthread_setname_np(thread, name.c_str());
2437 return SS_SUCCESS;
2438
2439#else
2440 return 0;
2441#endif
2442}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tid_to_string()

std::string ss_tid_to_string ( midas_thread_t  thread_id)

Definition at line 1571 of file system.cxx.

1572{
1573#if defined OS_MSDOS
1574
1575 return "0";
1576
1577#elif defined OS_WINNT
1578
1579#error Do not know how to do ss_tid_to_string()
1580 return "???";
1581
1582#elif defined OS_VMS
1583
1584 char buf[256];
1585 sprintf(buf, "%d", thread_id);
1586 return buf;
1587
1588#elif defined OS_DARWIN
1589
1590 char buf[256];
1591 sprintf(buf, "%p", thread_id);
1592 return buf;
1593
1594#elif defined OS_CYGWIN
1595
1596 char buf[256];
1597 sprintf(buf, "%p", thread_id);
1598 return buf;
1599
1600#elif defined OS_UNIX
1601
1602 char buf[256];
1603 sprintf(buf, "%lu", thread_id);
1604 return buf;
1605
1606#elif defined OS_VXWORKS
1607
1608 char buf[256];
1609 sprintf(buf, "%d", thread_id);
1610 return buf;
1611
1612#else
1613#error Do not know how to do ss_tid_to_string()
1614#endif
1615}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_time()

DWORD EXPRT ss_time ( )

Returns the actual time in seconds since 1.1.1970 UTC.

...
DWORD start, stop:
start = ss_time();
ss_sleep(12000);
printf("Operation took %1.3lf seconds\n",stop-start);
...
Returns
Time in seconds

Definition at line 3462 of file system.cxx.

3463{
3464 return (DWORD) time(NULL);
3465}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_time_sec()

double EXPRT ss_time_sec ( )

Definition at line 3467 of file system.cxx.

3468{
3469 struct timeval tv;
3470 gettimeofday(&tv, NULL);
3471 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
3472}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_timed_mutex_wait_for_sec()

bool EXPRT ss_timed_mutex_wait_for_sec ( std::timed_mutex &  mutex,
const char mutex_name,
double  timeout_sec 
)

Definition at line 3265 of file system.cxx.

3281{
3282 if (timeout_sec <= 0) {
3283 mutex.lock();
3284 return true;
3285 }
3286
3287 double starttime = ss_time_sec();
3288 double endtime = starttime + timeout_sec;
3289
3290 // NB: per timed mutex try_lock_for(), one must always
3291 // look waiting for successful lock because it is permitted
3292 // to return "false" even if timeout did not yet expire. (cannot
3293 // tell permitted spurious failure from normal timeout). K.O.
3294
3295 double locktime = starttime;
3296
3297 while (1) {
3298 bool ok = mutex.try_lock_for(std::chrono::milliseconds(1000));
3299
3300 if (ok) {
3301 //double now = ss_time_sec();
3302 //fprintf(stderr, "ss_timed_mutex_wait_for_sec: mutex %s locked in %.1f seconds. timeout %.1f seconds\n", mutex_name, now-starttime, timeout_sec);
3303 return true;
3304 }
3305
3306 double now = ss_time_sec();
3307
3308 if (mutex_name) {
3309 if (now-locktime < 0.2) {
3310 // mutex.try_lock_for() is permitted spuriously fail: return false before the 1 sec timeout expires, we should not print any messages about it. K.O.
3311 //fprintf(stderr, "ss_timed_mutex_wait_for_sec: short try_lock_for(1000). %.3f seconds\n", now-locktime);
3312 } else {
3313 fprintf(stderr, "ss_timed_mutex_wait_for_sec: long wait for mutex %s, %.1f seconds. %.1f seconds until timeout\n", mutex_name, now-starttime, endtime-now);
3314 }
3315 }
3316
3317 if (now > endtime)
3318 return false;
3319
3320 locktime = now;
3321 }
3322}
double ss_time_sec()
Definition system.cxx:3467
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_timezone()

INT EXPRT ss_timezone ( )

Definition at line 3580 of file system.cxx.

3598{
3599#if defined(OS_DARWIN) || defined(OS_VXWORKS)
3600 return 0;
3601#else
3602 return (INT) timezone; /* on Linux, comes from "#include <time.h>". */
3603#endif
3604}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tzset()

void EXPRT ss_tzset ( )

Definition at line 3355 of file system.cxx.

3356{
3357 std::lock_guard<std::mutex> lock(gTzMutex);
3358 //defeat tzset() error trap from msystem.h
3359 //#ifdef tzset
3360 //#undef tzset
3361 //#endif
3362 tzset();
3363}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_us_since()

Definition at line 8260 of file system.cxx.

8260 {
8261 auto elapsed = std::chrono::high_resolution_clock::now() - start;
8262 return std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
8263}
Here is the call graph for this function:

◆ ss_us_start()

Definition at line 8255 of file system.cxx.

8256{
8257 return std::chrono::high_resolution_clock::now();
8258}

◆ ss_write_tcp()

INT EXPRT ss_write_tcp ( int  sock,
const char buffer,
size_t  buffer_size 
)

Definition at line 5346 of file system.cxx.

5367{
5368 size_t count = 0;
5369
5370 while (count < buffer_size) {
5371 ssize_t wr = write(sock, buffer + count, buffer_size - count);
5372
5373 if (wr == 0) {
5374 cm_msg(MERROR, "ss_write_tcp", "write(socket=%d,size=%d) returned zero, errno: %d (%s)", sock, (int) (buffer_size - count), errno, strerror(errno));
5375 return SS_SOCKET_ERROR;
5376 } else if (wr < 0) {
5377#ifdef OS_UNIX
5378 if (errno == EINTR)
5379 continue;
5380#endif
5381 cm_msg(MERROR, "ss_write_tcp", "write(socket=%d,size=%d) returned %d, errno: %d (%s)", sock, (int) (buffer_size - count), (int)wr, errno, strerror(errno));
5382 return SS_SOCKET_ERROR;
5383 }
5384
5385 // good write
5386 count += wr;
5387 }
5388
5389 return SS_SUCCESS;
5390}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _daemon_flag

BOOL _daemon_flag
static

Definition at line 1999 of file system.cxx.

◆ _ss_client_connection

RPC_SERVER_CONNECTION* _ss_client_connection = NULL
static

Definition at line 3987 of file system.cxx.

◆ _ss_client_listen_socket

int _ss_client_listen_socket = 0
static

Definition at line 3984 of file system.cxx.

◆ _ss_client_thread

midas_thread_t _ss_client_thread = 0
static

Definition at line 3986 of file system.cxx.

◆ _ss_listen_thread

midas_thread_t _ss_listen_thread = 0
static

Definition at line 3982 of file system.cxx.

◆ _ss_odb_thread

midas_thread_t _ss_odb_thread = 0
static

Definition at line 3979 of file system.cxx.

◆ _ss_server_acceptions

RPC_SERVER_ACCEPTION_LIST* _ss_server_acceptions = NULL
static

Definition at line 3990 of file system.cxx.

◆ _ss_server_listen_socket

int _ss_server_listen_socket = 0
static

Definition at line 3983 of file system.cxx.

◆ _ss_server_thread

midas_thread_t _ss_server_thread = 0
static

Definition at line 3989 of file system.cxx.

◆ _ss_suspend_odb

SUSPEND_STRUCT* _ss_suspend_odb = NULL
static

Definition at line 3980 of file system.cxx.

◆ _ss_suspend_vector

std::vector<SUSPEND_STRUCT*> _ss_suspend_vector
static

Definition at line 3977 of file system.cxx.

◆ [] [1/2]

char { ... } ::c

Definition at line 1310 of file system.cxx.

◆ [] [2/2]

char { ... } ::c

Definition at line 1316 of file system.cxx.

◆ [] [1/2]

double { ... } ::d

Definition at line 1311 of file system.cxx.

◆ [] [2/2]

double { ... } ::d

Definition at line 1315 of file system.cxx.

◆ gSocketTrace

bool gSocketTrace = false
static

Definition at line 4964 of file system.cxx.

◆ gTzMutex

std::mutex gTzMutex
static

Definition at line 3353 of file system.cxx.

◆ MidasExceptionHandler

void(* MidasExceptionHandler) (void) ( void  )

Definition at line 3789 of file system.cxx.

◆ s_semaphore_nest_level

std::atomic_int s_semaphore_nest_level {0}
static

Definition at line 2458 of file system.cxx.

2458{0}; // must be signed int!

◆ s_semaphore_trace

std::atomic_bool s_semaphore_trace {false}
static

Definition at line 2457 of file system.cxx.

2457{false};

◆ stack_history

char stack_history[N_STACK_HISTORY][80]

Definition at line 7991 of file system.cxx.

◆ stack_history_pointer

int stack_history_pointer = -1

Definition at line 7992 of file system.cxx.

◆ [struct]

struct { ... } test_align

◆ [struct]

struct { ... } test_padding