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 7895 of file system.cxx.

◆ N_STACK_HISTORY

#define N_STACK_HISTORY   500

Definition at line 7996 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 5399 of file system.cxx.

5424{
5425 INT i, status;
5426 DWORD n;
5427
5428 n = 0;
5429 memset(buffer, 0, buffer_size);
5430
5431 do {
5432 if (millisec > 0) {
5434 if (status != SS_SUCCESS)
5435 break;
5436 }
5437
5438 i = recv(sock, buffer + n, 1, 0);
5439
5440 if (i <= 0)
5441 break;
5442
5443 n++;
5444
5445 if (n >= buffer_size)
5446 break;
5447
5448 } while (buffer[n - 1] && buffer[n - 1] != 10);
5449
5450 return n - 1;
5451}
#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 5454 of file system.cxx.

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

5588{
5589 int n_received = 0;
5590 int flags = 0;
5591 int n;
5592
5593 //printf("recv_tcp2: %p+%d bytes, timeout %d ms!\n", net_buffer + n_received, buffer_size - n_received, timeout_ms);
5594
5595 while (n_received != buffer_size) {
5596
5597 if (timeout_ms > 0) {
5598 int status = ss_socket_wait(sock, timeout_ms);
5599 if (status == SS_TIMEOUT)
5600 return n_received;
5601 if (status != SS_SUCCESS)
5602 return -1;
5603 }
5604
5605 n = recv(sock, net_buffer + n_received, buffer_size - n_received, flags);
5606
5607 //printf("recv_tcp2: %p+%d bytes, returned %d, errno %d (%s)\n", net_buffer + n_received, buffer_size - n_received, n, errno, strerror(errno));
5608
5609#ifdef EINTR
5610 /* don't return if an alarm signal was cought */
5611 if (n == -1 && errno == EINTR)
5612 continue;
5613#endif
5614
5615 if (n == 0) {
5616 // socket closed
5617 cm_msg(MERROR, "recv_tcp2", "unexpected connection closure");
5618 return -1;
5619 }
5620
5621 if (n < 0) {
5622 // socket error
5623 cm_msg(MERROR, "recv_tcp2", "unexpected connection error, recv() errno %d (%s)", errno, strerror(errno));
5624 return -1;
5625 }
5626
5627 n_received += n;
5628 }
5629
5630 return n_received;
5631}
#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 16144 of file midas.cxx.

16158{
16160
16161 //printf("ss_event_socket_has_data() returned %d\n", has_data);
16162
16163 if (has_data) {
16164 if (timeout_msec == BM_NO_WAIT) {
16165 return BM_ASYNC_RETURN;
16166 } else if (timeout_msec == BM_WAIT) {
16167 return BM_ASYNC_RETURN;
16168 } else {
16170 if (status == SS_ABORT || status == SS_EXIT)
16171 return status;
16172 return BM_ASYNC_RETURN;
16173 }
16174 }
16175
16177
16178 //printf("rpc_server_receive_event() status %d\n", status);
16179
16180 if (status == BM_ASYNC_RETURN) {
16181 return BM_ASYNC_RETURN;
16182 }
16183
16184 if (status == SS_ABORT || status == SS_EXIT)
16185 return status;
16186
16187 return BM_SUCCESS;
16188}
#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:15989
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 5285 of file system.cxx.

5306{
5307 DWORD count;
5308 INT status;
5309 //int net_tcp_size = NET_TCP_SIZE;
5310 int net_tcp_size = 1024 * 1024;
5311
5312 /* transfer fragments until complete buffer is transferred */
5313
5314 for (count = 0; (INT) count < (INT) buffer_size - net_tcp_size;) {
5315 status = send(sock, buffer + count, net_tcp_size, flags & 0xFFFF);
5316 if (status != -1)
5317 count += status;
5318 else {
5319#ifdef OS_UNIX
5320 if (errno == EINTR)
5321 continue;
5322#endif
5323 if ((flags & 0x10000) == 0)
5324 cm_msg(MERROR, "send_tcp",
5325 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
5327 return status;
5328 }
5329 }
5330
5331 while (count < buffer_size) {
5332 status = send(sock, buffer + count, buffer_size - count, flags & 0xFFFF);
5333 if (status != -1)
5334 count += status;
5335 else {
5336#ifdef OS_UNIX
5337 if (errno == EINTR)
5338 continue;
5339#endif
5340 if ((flags & 0x10000) == 0)
5341 cm_msg(MERROR, "send_tcp",
5342 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
5343 sock, (int) (buffer_size - count), status, errno, strerror(errno));
5344 return status;
5345 }
5346 }
5347
5348 return count;
5349}
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 7305 of file system.cxx.

7322{
7323#ifdef OS_WINNT
7324
7326 COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */
7327 BOOL bSuccess;
7329 CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
7330 DWORD dwConSize; /* number of character cells in the current buffer */
7331
7333
7334 /* get the number of character cells in the current buffer */
7336 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
7337
7338 /* fill the entire screen with blanks */
7340
7341 /* put the cursor at (0, 0) */
7343 return;
7344
7345#endif /* OS_WINNT */
7346#if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7347 printf("\033[2J");
7348#endif
7349#ifdef OS_MSDOS
7350 clrscr();
7351#endif
7352}
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 7897 of file system.cxx.

7917{
7918 int i, seed;
7919 static char enc_pw[13];
7920
7921 memset(enc_pw, 0, sizeof(enc_pw));
7922 enc_pw[0] = salt[0];
7923 enc_pw[1] = salt[1];
7924
7925 for (i = 0; i < 8 && buf[i]; i++)
7926 enc_pw[i + 2] = buf[i];
7927 for (; i < 8; i++)
7928 enc_pw[i + 2] = 0;
7929
7930 seed = 123;
7931 for (i = 2; i < 13; i++) {
7932 seed = 5 * seed + 27 + enc_pw[i];
7933 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
7934 }
7935
7936 return enc_pw;
7937}
#define bin_to_ascii(c)
Definition system.cxx:7895
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 7192 of file system.cxx.

7209{
7210#ifdef OS_UNIX
7211 struct stat buf;
7212
7213 int retval = stat(path, &buf);
7214 //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7215 if (retval < 0)
7216 return 0;
7217 if (!S_ISDIR(buf.st_mode))
7218 return 0;
7219#else
7220#warning ss_dir_exist() is not implemented!
7221#endif
7222 return 1;
7223}
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 6802 of file system.cxx.

6803{
6805
6806 int count = ss_dir_find(path, pattern, &list);
6807 if (count <= 0)
6808 return count;
6809
6810 size_t size = list.size();
6811 *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6812 for (size_t i=0; i<size; i++) {
6813 //printf("file %d [%s]\n", (int)i, list[i].c_str());
6815 }
6816
6817 return size;
6818}
#define MAX_STRING_LENGTH
Definition msystem.h:113
INT ss_dir_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6802
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 6820 of file system.cxx.

6838{
6839 assert(plist);
6840#ifdef OS_UNIX
6842 struct dirent *dp;
6843
6844 if ((dir_pointer = opendir(path)) == NULL)
6845 return 0;
6846 plist->clear();
6847 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6848 if (fnmatch(pattern, dp->d_name, 0) == 0 && dp->d_type == DT_DIR) {
6849 plist->push_back(dp->d_name);
6851 }
6852 }
6854#endif
6855#ifdef OS_WINNT
6856 char str[255];
6857 int first;
6858
6859 strcpy(str, path);
6860 strcat(str, "\\");
6861 strcat(str, pattern);
6862 first = 1;
6863 plist->clear();
6867 return 0;
6868 first = 0;
6869 plist->push_back(lpfdata->cFileName);
6870 while (FindNextFile(pffile, lpfdata)) {
6871 plist->push_back(lpfdata->cFileName);
6872 }
6873 free(lpfdata);
6874#endif
6875 return plist->size();
6876}
@ 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 7817 of file system.cxx.

7818{
7819#ifdef OS_WINNT
7820
7821 /* under Windows NT, use DirectIO driver to open ports */
7822
7824 HANDLE hdio = 0;
7825 DWORD buffer[] = { 6, 0, 0, 0 };
7826 DWORD size;
7827
7828 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7829 GetVersionEx(&vi);
7830
7831 /* use DirectIO driver under NT to gain port access */
7832 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
7833 hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7834 if (hdio == INVALID_HANDLE_VALUE) {
7835 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
7836 return -1;
7837 }
7838
7839 /* open ports */
7840 buffer[1] = start;
7841 buffer[2] = end;
7842 if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
7843 return -1;
7844 }
7845
7846 return SS_SUCCESS;
7847#else
7848 return SS_SUCCESS;
7849#endif
7850}
#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 7853 of file system.cxx.

7854{
7855#ifdef OS_WINNT
7856
7857 /* under Windows NT, use DirectIO driver to lock ports */
7858
7860 HANDLE hdio;
7861 DWORD buffer[] = { 7, 0, 0, 0 };
7862 DWORD size;
7863
7864 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7865 GetVersionEx(&vi);
7866
7867 /* use DirectIO driver under NT to gain port access */
7868 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
7869 hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7870 if (hdio == INVALID_HANDLE_VALUE) {
7871 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
7872 return -1;
7873 }
7874
7875 /* lock ports */
7876 buffer[1] = start;
7877 buffer[2] = end;
7878 if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
7879 return -1;
7880 }
7881
7882 return SS_SUCCESS;
7883#else
7884 return SS_SUCCESS;
7885#endif
7886}
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 6878 of file system.cxx.

6879{
6881
6882 int count = ss_dirlink_find(path, pattern, &list);
6883 if (count <= 0)
6884 return count;
6885
6886 size_t size = list.size();
6887 *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6888 for (size_t i=0; i<size; i++) {
6889 //printf("file %d [%s]\n", (int)i, list[i].c_str());
6891 }
6892
6893 return size;
6894}
INT ss_dirlink_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6878
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 6896 of file system.cxx.

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

◆ ss_disk_free()

double EXPRT ss_disk_free ( const char path)

Definition at line 6626 of file system.cxx.

6642{
6643#ifdef OS_UNIX
6644#if defined(OS_OSF1)
6645 struct statfs st;
6646 statfs(path, &st, sizeof(st));
6647 return (double) st.f_bavail * st.f_bsize;
6648#elif defined(OS_LINUX)
6649 struct statfs st;
6650 int status;
6651 status = statfs(path, &st);
6652 if (status != 0)
6653 return -1;
6654 return (double) st.f_bavail * st.f_bsize;
6655#elif defined(OS_SOLARIS)
6656 struct statvfs st;
6657 statvfs(path, &st);
6658 return (double) st.f_bavail * st.f_bsize;
6659#elif defined(OS_IRIX)
6660 struct statfs st;
6661 statfs(path, &st, sizeof(struct statfs), 0);
6662 return (double) st.f_bfree * st.f_bsize;
6663#else
6664 struct fs_data st;
6665 statfs(path, &st);
6666 return (double) st.fd_otsize * st.fd_bfree;
6667#endif
6668
6669#elif defined(OS_WINNT) /* OS_UNIX */
6674 char str[80];
6675
6676 strcpy(str, path);
6677 if (strchr(str, ':') != NULL) {
6678 *(strchr(str, ':') + 1) = 0;
6681 } else
6683
6685#else /* OS_WINNT */
6686
6687 return 1e9;
6688
6689#endif
6690}
#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 7054 of file system.cxx.

7070{
7071#ifdef OS_UNIX
7072#if defined(OS_OSF1)
7073 struct statfs st;
7074 statfs(path, &st, sizeof(st));
7075 return (double) st.f_blocks * st.f_fsize;
7076#elif defined(OS_LINUX)
7077 int status;
7078 struct statfs st;
7079 status = statfs(path, &st);
7080 if (status != 0)
7081 return -1;
7082 return (double) st.f_blocks * st.f_bsize;
7083#elif defined(OS_SOLARIS)
7084 struct statvfs st;
7085 statvfs(path, &st);
7086 if (st.f_frsize > 0)
7087 return (double) st.f_blocks * st.f_frsize;
7088 else
7089 return (double) st.f_blocks * st.f_bsize;
7090#elif defined(OS_ULTRIX)
7091 struct fs_data st;
7092 statfs(path, &st);
7093 return (double) st.fd_btot * 1024;
7094#elif defined(OS_IRIX)
7095 struct statfs st;
7096 statfs(path, &st, sizeof(struct statfs), 0);
7097 return (double) st.f_blocks * st.f_bsize;
7098#else
7099#error ss_disk_size not defined for this OS
7100#endif
7101#endif /* OS_UNIX */
7102
7103#ifdef OS_WINNT
7108 char str[80];
7109
7110 strcpy(str, path);
7111 if (strchr(str, ':') != NULL) {
7112 *(strchr(str, ':') + 1) = 0;
7115 } else
7117
7119#endif /* OS_WINNT */
7120
7121 return 1e9;
7122}
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 7225 of file system.cxx.

7242{
7243 int fd_to, fd_from;
7244 char buf[4096];
7245 ssize_t nread;
7246 int saved_errno;
7247
7248 fd_from = open(src, O_RDONLY);
7249 if (fd_from < 0)
7250 return -1;
7251
7252 if (append)
7253 fd_to = open(dst, O_WRONLY | O_CREAT | O_EXCL | O_APPEND, 0666);
7254 else
7255 fd_to = open(dst, O_WRONLY | O_CREAT | O_EXCL, 0666);
7256 if (fd_to < 0)
7257 goto out_error;
7258
7259 while (nread = read(fd_from, buf, sizeof(buf)), nread > 0) {
7260 char *out_ptr = buf;
7262
7263 do {
7265
7266 if (nwritten >= 0) {
7267 nread -= nwritten;
7268 out_ptr += nwritten;
7269 } else if (errno != EINTR) {
7270 goto out_error;
7271 }
7272 } while (nread > 0);
7273 }
7274
7275 if (nread == 0) {
7276 if (close(fd_to) < 0) {
7277 fd_to = -1;
7278 goto out_error;
7279 }
7280 close(fd_from);
7281
7282 /* Success! */
7283 return 0;
7284 }
7285
7286 out_error:
7288
7289 close(fd_from);
7290 if (fd_to >= 0)
7291 close(fd_to);
7292
7294 return -1;
7295}
#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 7124 of file system.cxx.

7141{
7142#ifdef OS_UNIX
7143 struct stat buf;
7144
7145 int retval = stat(path, &buf);
7146 //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7147 if (retval < 0)
7148 return 0;
7149 if (S_ISDIR(buf.st_mode))
7150 return 0;
7151#endif
7152
7153 int fd = open(path, O_RDONLY, 0);
7154 if (fd < 0)
7155 return 0;
7156 close(fd);
7157 return 1;
7158}
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 6719 of file system.cxx.

6720{
6722
6723 int count = ss_file_find(path, pattern, &list);
6724 if (count <= 0)
6725 return count;
6726
6727 size_t size = list.size();
6728 *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6729 for (size_t i=0; i<size; i++) {
6730 //printf("file %d [%s]\n", (int)i, list[i].c_str());
6732 }
6733
6734 return size;
6735}
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6719
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 6737 of file system.cxx.

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

◆ ss_file_link_exist()

INT EXPRT ss_file_link_exist ( const char path)

Definition at line 7160 of file system.cxx.

7177{
7178#ifdef OS_UNIX
7179 struct stat buf;
7180
7181 int retval = lstat(path, &buf);
7182 if (retval < 0)
7183 return 0;
7184 if (S_ISLNK(buf.st_mode))
7185 return 1;
7186 return 0;
7187#endif
7188
7189 return 0;
7190}
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 6958 of file system.cxx.

6974{
6975 return remove(path);
6976}
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 6978 of file system.cxx.

6994{
6995#ifdef _LARGEFILE64_SOURCE
6996 struct stat64 stat_buf;
6997 int status;
6998
6999 /* allocate buffer with file size */
7000 status = stat64(path, &stat_buf);
7001 if (status != 0)
7002 return -1;
7003 return (double) stat_buf.st_size;
7004#else
7005 struct stat stat_buf;
7006 int status;
7007
7008 /* allocate buffer with file size */
7009 status = stat(path, &stat_buf);
7010 if (status != 0)
7011 return -1;
7012 return (double) stat_buf.st_size;
7013#endif
7014}
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 7016 of file system.cxx.

7032{
7033#ifdef _LARGEFILE64_SOURCE
7034 struct stat64 stat_buf;
7035 int status;
7036
7037 /* allocate buffer with file size */
7038 status = stat64(path, &stat_buf);
7039 if (status != 0)
7040 return -1;
7041 return stat_buf.st_mtime;
7042#else
7043 struct stat stat_buf;
7044 int status;
7045
7046 /* allocate buffer with file size */
7047 status = stat(path, &stat_buf);
7048 if (status != 0)
7049 return -1;
7050 return stat_buf.st_mtime;
7051#endif
7052}
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 7509 of file system.cxx.

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

5777{
5778 char *s = getcwd(NULL, 0);
5779 if (s) {
5780 std::string cwd = s;
5781 free(s);
5782 //printf("ss_getcwd: %s\n", cwd.c_str());
5783 return cwd;
5784 } else {
5785 return "/GETCWD-FAILED-ON-US";
5786 }
5787}
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 5712 of file system.cxx.

5729{
5730 char buf[256];
5731 memset(buf, 0, sizeof(buf));
5732
5733 int status = gethostname(buf, sizeof(buf)-1);
5734
5735 //printf("gethostname %d (%s)\n", status, buffer);
5736
5737 if (status != 0) {
5738 cm_msg(MERROR, "ss_gethostname", "gethostname() errno %d (%s)", errno, strerror(errno));
5739 return "";
5740 }
5741
5742 return buf;
5743}
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 5746 of file system.cxx.

5763{
5764 std::string h = ss_gethostname();
5765
5766 if (h.length() == 0) {
5767 return SS_IO_ERROR;
5768 } else {
5769 mstrlcpy(buffer, h.c_str(), buffer_size);
5770 return SS_SUCCESS;
5771 }
5772}
#define SS_IO_ERROR
Definition midas.h:681
std::string ss_gethostname()
Definition system.cxx:5712
Here is the call graph for this function:

◆ ss_getpass()

char EXPRT * ss_getpass ( const char prompt)

Definition at line 7446 of file system.cxx.

7463{
7464 static char password[32];
7465
7466 fprintf(stdout, "%s", prompt);
7467 fflush(stdout);
7468 memset(password, 0, sizeof(password));
7469
7470#ifdef OS_UNIX
7471 return (char *) getpass("");
7472#elif defined(OS_WINNT)
7473 {
7476
7479 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
7481 printf("\n");
7482
7483 if (password[strlen(password) - 1] == '\r')
7484 password[strlen(password) - 1] = 0;
7485
7486 return password;
7487 }
7488#elif defined(OS_MSDOS)
7489 {
7490 char c, *ptr;
7491
7492 ptr = password;
7493 while ((c = getchar()) != EOF && c != '\n')
7494 *ptr++ = c;
7495 *ptr = 0;
7496
7497 printf("\n");
7498 return password;
7499 }
7500#else
7501 {
7502 ss_gets(password, 32);
7503 return password;
7504 }
7505#endif
7506}
char * ss_gets(char *string, int size)
Definition system.cxx:7776
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 7776 of file system.cxx.

7795{
7796 char *p;
7797
7798 do {
7799 p = fgets(string, size, stdin);
7800 } while (p == NULL);
7801
7802
7803 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
7804 p[strlen(p) - 1] = 0;
7805
7806 return p;
7807}
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 8074 of file system.cxx.

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

◆ ss_isfin()

int EXPRT ss_isfin ( double  x)

Definition at line 7972 of file system.cxx.

7973{
7974#ifdef FP_INFINITE
7975 /* new-style finite() */
7976 return isfinite(x);
7977#else
7978 /* old-style finite() */
7979 return finite(x);
7980#endif
7981}
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 7967 of file system.cxx.

7968{
7969 return isnan(x);
7970}
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 7946 of file system.cxx.

7947{
7948 double nan;
7949
7950 nan = 0;
7951 nan = 0 / nan;
7952 return nan;
7953}
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 7388 of file system.cxx.

7409{
7410 char str[256];
7412
7413 va_start(argptr, format);
7414 vsprintf(str, (char *) format, argptr);
7415 va_end(argptr);
7416
7417#ifdef OS_WINNT
7418 {
7422
7424
7425 dwWriteCoord.X = (short) x;
7426 dwWriteCoord.Y = (short) y;
7427
7429 }
7430
7431#endif /* OS_WINNT */
7432
7433#if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7434 printf("\033[%1d;%1dH", y + 1, x + 1);
7435 printf("%s", str);
7436 fflush(stdout);
7437#endif
7438
7439#ifdef OS_MSDOS
7440 gotoxy(x + 1, y + 1);
7441 cputs(str);
7442#endif
7443}
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 5635 of file system.cxx.

5658{
5660 size_t n;
5661
5662 /* first receive header */
5663 n = recv_tcp2(sock, (char*)&ncbuf, sizeof(ncbuf), timeout_ms);
5664
5665 if (n == 0) {
5666 cm_msg(MERROR, "ss_recv_net_command", "timeout receiving network command header");
5667 return SS_TIMEOUT;
5668 }
5669
5670 if (n != sizeof(ncbuf)) {
5671 cm_msg(MERROR, "ss_recv_net_command", "error receiving network command header, see messages");
5672 return SS_SOCKET_ERROR;
5673 }
5674
5675 // FIXME: where is the big-endian/little-endian conversion?
5676 *routine_id = ncbuf.routine_id;
5677 *param_size = ncbuf.param_size;
5678
5679 if (*param_size == 0) {
5680 *param_ptr = NULL;
5681 return SS_SUCCESS;
5682 }
5683
5684 *param_ptr = (char *)malloc(*param_size);
5685
5686 if (*param_ptr == NULL) {
5687 cm_msg(MERROR, "ss_recv_net_command", "error allocating %d bytes for network command data", *param_size);
5688 return SS_NO_MEMORY;
5689 }
5690
5691 /* first receive header */
5692 n = recv_tcp2(sock, *param_ptr, *param_size, timeout_ms);
5693
5694 if (n == 0) {
5695 cm_msg(MERROR, "ss_recv_net_command", "timeout receiving network command data");
5696 free(*param_ptr);
5697 *param_ptr = NULL;
5698 return SS_TIMEOUT;
5699 }
5700
5701 if (n != *param_size) {
5702 cm_msg(MERROR, "ss_recv_net_command", "error receiving network command data, see messages");
5703 free(*param_ptr);
5704 *param_ptr = NULL;
5705 return SS_SOCKET_ERROR;
5706 }
5707
5708 return SS_SUCCESS;
5709}
#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:5562
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 8157 of file system.cxx.

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

8254{
8255 // C++11 std::string data() is same as c_str(), NUL-terminated.
8256 // C++17 std::string data() is not "const".
8257 // https://en.cppreference.com/w/cpp/string/basic_string/data
8258 return ss_repair_utf8((char*)s.data()); // FIXME: C++17 or newer, do not need to drop the "const". K.O. May 2021
8259}
bool ss_repair_utf8(char *string)
Definition system.cxx:8157
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 7355 of file system.cxx.

7372{
7373#ifdef OS_WINNT
7374
7377
7378 coordSize.X = (short) x;
7379 coordSize.Y = (short) y;
7382
7383#else /* OS_WINNT */
7384#endif
7385}
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:6978
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 5231 of file system.cxx.

5232{
5233 assert(sockp != NULL);
5234 if (gSocketTrace) {
5235 fprintf(stderr, "ss_socket_close: %d\n", *sockp);
5236 }
5237 int err = close(*sockp);
5238 if (err) {
5239 cm_msg(MERROR, "ss_socket_close", "unexpected error, close() returned %d, errno: %d (%s)", err, errno, strerror(errno));
5240 }
5241 *sockp = 0;
5242 return SS_SUCCESS;
5243}
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 5246 of file system.cxx.

5247{
5248 char addr[64];
5249
5250 unsigned size = sizeof(addr);
5251 int rv = getpeername(sock, (struct sockaddr *) &addr, &size);
5252
5253 //printf("getpeername() returned %d, size %d, buffer %d\n", rv, size, (int)sizeof(addr));
5254
5255 if (rv != 0) {
5256 cm_msg(MERROR, "ss_socket_get_peer_name", "Error: getpeername() returned %d, errno %d (%s)", rv, errno, strerror(errno));
5257 return SS_SOCKET_ERROR;
5258 }
5259
5260 char hostname[256];
5261 char servname[16];
5262
5263 int ret = getnameinfo((struct sockaddr*)&addr, size,
5264 hostname, sizeof(hostname),
5265 servname, sizeof(servname),
5267
5268 if (ret != 0) {
5269 cm_msg(MERROR, "ss_socket_get_peer_name", "Error: getnameinfo() error %d (%s)", ret, gai_strerror(ret));
5270 return SS_SOCKET_ERROR;
5271 }
5272
5273 //printf("getnameinfo() returned %d, hostname [%s], servname[%s]\n", ret, hostname, servname);
5274
5275 if (hostp)
5276 *hostp = hostname;
5277
5278 if (portp)
5279 *portp = atoi(servname);
5280
5281 return SS_SUCCESS;
5282}
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 if (lsock == -1) {
5096 if (errno == EAFNOSUPPORT) {
5097 use_inet6 = false;
5099 }
5100 }
5101#endif
5102 } else {
5104 }
5105
5106 if (lsock == -1) {
5107 *error_msg_p = msprintf("socket(AF_INET, SOCK_STREAM) failed, errno %d (%s)", errno, strerror(errno));
5108 return RPC_NET_ERROR;
5109 }
5110
5111 /* reuse address, needed if previous server stopped (30s timeout!) */
5112 int flag = 1;
5113 int status = setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof(int));
5114 if (status < 0) {
5115 *error_msg_p = msprintf("setsockopt(SO_REUSEADDR) failed, errno %d (%s)", errno, strerror(errno));
5116 return RPC_NET_ERROR;
5117 }
5118
5119#ifdef AF_INET6
5120#ifdef IPV6_V6ONLY
5121 if (use_inet6) {
5122 /* turn off IPV6_V6ONLY, see RFC 3493 */
5123 flag = 0;
5124 status = setsockopt(lsock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flag, sizeof(int));
5125 if (status < 0) {
5126 *error_msg_p = msprintf("setsockopt(IPPROTO_IPV6, IPV6_V6ONLY) failed, errno %d (%s)", errno, strerror(errno));
5127 return RPC_NET_ERROR;
5128 }
5129 }
5130#else
5131#warning strange: AF_INET6 is defined, but IPV6_V6ONLY is not defined
5132#endif
5133#endif
5134
5135 if (use_inet6) {
5136#ifdef AF_INET6
5137 /* bind local node name and port to socket */
5138 struct sockaddr_in6 bind_addr6;
5139 memset(&bind_addr6, 0, sizeof(bind_addr6));
5140 bind_addr6.sin6_family = AF_INET6;
5141
5142 if (listen_localhost) {
5143 bind_addr6.sin6_addr = in6addr_loopback;
5144 } else {
5145 bind_addr6.sin6_addr = in6addr_any;
5146 }
5147
5148 if (tcp_port)
5149 bind_addr6.sin6_port = htons((short) tcp_port);
5150 else
5151 bind_addr6.sin6_port = htons(0); // OS will allocate a port number for us
5152
5153 status = bind(lsock, (struct sockaddr *) &bind_addr6, sizeof(bind_addr6));
5154 if (status < 0) {
5155 *error_msg_p = msprintf("IPv6 bind() to port %d failed, errno %d (%s)", tcp_port, errno, strerror(errno));
5156 return RPC_NET_ERROR;
5157 }
5158#endif
5159 } else {
5160 /* bind local node name and port to socket */
5161 struct sockaddr_in bind_addr;
5162 memset(&bind_addr, 0, sizeof(bind_addr));
5163 bind_addr.sin_family = AF_INET;
5164
5165 if (listen_localhost) {
5166 bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
5167 } else {
5168 bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
5169 }
5170
5171 if (tcp_port)
5172 bind_addr.sin_port = htons((short) tcp_port);
5173 else
5174 bind_addr.sin_port = htons(0); // OS will allocate a port number for us
5175
5176 status = bind(lsock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
5177 if (status < 0) {
5178 *error_msg_p = msprintf("bind() to port %d failed, errno %d (%s)", tcp_port, errno, strerror(errno));
5179 return RPC_NET_ERROR;
5180 }
5181 }
5182
5183 /* listen for connection */
5184#ifdef OS_MSDOS
5185 status = listen(lsock, 1);
5186#else
5188#endif
5189 if (status < 0) {
5190 *error_msg_p = msprintf("listen() failed, errno %d (%s)", errno, strerror(errno));
5191 return RPC_NET_ERROR;
5192 }
5193
5194 if (use_inet6) {
5195#ifdef AF_INET6
5196 struct sockaddr_in6 addr;
5197 socklen_t sosize = sizeof(addr);
5198 status = getsockname(lsock, (struct sockaddr*)&addr, &sosize);
5199 if (status < 0) {
5200 *error_msg_p = msprintf("IPv6 getsockname() failed, errno %d (%s)", errno, strerror(errno));
5201 return RPC_NET_ERROR;
5202 }
5203
5204 *tcp_port_p = ntohs(addr.sin6_port);
5205#endif
5206 } else {
5207 struct sockaddr_in addr;
5208 socklen_t sosize = sizeof(addr);
5209 status = getsockname(lsock, (struct sockaddr*)&addr, &sosize);
5210 if (status < 0) {
5211 *error_msg_p = msprintf("getsockname() failed, errno %d (%s)", errno, strerror(errno));
5212 return RPC_NET_ERROR;
5213 }
5214
5215 *tcp_port_p = ntohs(addr.sin_port);
5216 }
5217
5218 *sockp = lsock;
5219
5220 if (gSocketTrace) {
5221 if (listen_localhost)
5222 fprintf(stderr, "ss_socket_listen_tcp: listening tcp port %d local connections only, new socket %d\n", *tcp_port_p, *sockp);
5223 else
5224 fprintf(stderr, "ss_socket_listen_tcp: listening tcp port %d all internet connections, socket %d\n", *tcp_port_p, *sockp);
5225 }
5226
5227 return SS_SUCCESS;
5228}
#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 8000 of file system.cxx.

8001{
8002#ifdef OS_LINUX
8003#define MAX_STACK_DEPTH 16
8004
8005 void *trace[MAX_STACK_DEPTH];
8006 int size;
8007
8009 *string = backtrace_symbols(trace, size);
8010 return size;
8011#else
8012 return 0;
8013#endif
8014}
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 8050 of file system.cxx.

8051{
8052 FILE *f;
8053 int i, j;
8054
8055 f = fopen(filename, "wt");
8056 if (f != NULL) {
8058 for (i = 0; i < N_STACK_HISTORY; i++) {
8059 if (strlen(stack_history[j]) > 0)
8060 fprintf(f, "%s\n", stack_history[j]);
8061 j = (j + 1) % N_STACK_HISTORY;
8062 }
8063 fclose(f);
8064 printf("Stack dump written to %s\n", filename);
8065 } else
8066 printf("Cannot open %s: errno=%d\n", filename, errno);
8067}
#define N_STACK_HISTORY
Definition system.cxx:7996
char stack_history[N_STACK_HISTORY][80]
Definition system.cxx:7997
int stack_history_pointer
Definition system.cxx:7998
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 8028 of file system.cxx.

8029{
8030 char **string;
8031 int i, n;
8032
8033 if (stack_history_pointer == -1) {
8035 memset(stack_history, 0, sizeof(stack_history));
8036 }
8039 n = ss_stack_get(&string);
8040 for (i = 2; i < n; i++) {
8043 }
8044 free(string);
8045
8046 mstrlcpy(stack_history[stack_history_pointer], "=========================", 80);
8048}
INT ss_stack_get(char ***string)
Definition system.cxx:8000
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 8016 of file system.cxx.

8017{
8018 char **string;
8019 int i, n;
8020
8021 n = ss_stack_get(&string);
8022 for (i = 0; i < n; i++)
8023 printf("%s\n", string[i]);
8024 if (n > 0)
8025 free(string);
8026}
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:14365
INT rpc_server_receive_rpc(int idx, RPC_SERVER_ACCEPTION *sa)
Definition midas.cxx:15879
INT rpc_client_accept(int lsock)
Definition midas.cxx:15606
INT rpc_server_accept(int lsock)
Definition midas.cxx:15349
INT rpc_client_dispatch(int sock)
Definition midas.cxx:11953
#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:5393
#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 5908 of file system.cxx.

5926{
5927 INT status;
5928
5929#ifdef OS_UNIX
5930
5931 status = close(channel);
5932
5933 if (status < 0) {
5934 cm_msg(MERROR, "ss_tape_close", "close() returned %d, errno %d (%s)", status, errno, strerror(errno));
5935 return errno;
5936 }
5937#endif /* OS_UNIX */
5938
5939#ifdef OS_WINNT
5940
5941 if (!CloseHandle((HANDLE) channel)) {
5942 status = GetLastError();
5943 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
5944 return status;
5945 }
5946#endif /* OS_WINNT */
5947
5948 return SS_SUCCESS;
5949}
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 6238 of file system.cxx.

6257{
6258#ifdef MTIOCTOP
6259 struct mtop arg;
6260 INT status;
6261
6262 if (count > 0)
6263 arg.mt_op = MTFSF;
6264 else
6265 arg.mt_op = MTBSF;
6266 arg.mt_count = abs(count);
6267
6268 //cm_enable_watchdog(FALSE);
6269
6270 status = ioctl(channel, MTIOCTOP, &arg);
6271
6272 //cm_enable_watchdog(TRUE);
6273
6274 if (status < 0) {
6275 cm_msg(MERROR, "ss_tape_fskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6276 return errno;
6277 }
6278#endif /* OS_UNIX */
6279
6280#ifdef OS_WINNT
6281 INT status;
6282
6284
6286 return SS_END_OF_TAPE;
6287
6288 if (status != NO_ERROR) {
6289 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
6290 return status;
6291 }
6292#endif /* OS_WINNT */
6293
6294 return SS_SUCCESS;
6295}
#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 6574 of file system.cxx.

6583{
6584#if defined(OS_DARWIN)
6585
6586 return 0;
6587
6588#elif defined(OS_UNIX)
6589
6590 INT status;
6591 struct mtpos arg;
6592
6593 //cm_enable_watchdog(FALSE);
6594 status = ioctl(channel, MTIOCPOS, &arg);
6595 //cm_enable_watchdog(TRUE);
6596 if (status < 0) {
6597 if (errno == EIO)
6598 return 0;
6599 else {
6600 cm_msg(MERROR, "ss_tape_get_blockn", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6601 return -errno;
6602 }
6603 }
6604 return (arg.mt_blkno);
6605
6606#elif defined(OS_WINNT)
6607
6608 INT status;
6610 unsigned long size;
6611 /* I'm not sure the partition count corresponds to the block count */
6613 return (media.PartitionCount);
6614
6615#endif
6616}
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 6462 of file system.cxx.

6480{
6481#ifdef MTIOCTOP
6482 struct mtop arg;
6483 INT status;
6484
6485#ifdef MTLOAD
6486 arg.mt_op = MTLOAD;
6487#else
6488 arg.mt_op = MTNOP;
6489#endif
6490 arg.mt_count = 0;
6491
6492 //cm_enable_watchdog(FALSE);
6493
6494 status = ioctl(channel, MTIOCTOP, &arg);
6495
6496 //cm_enable_watchdog(TRUE);
6497
6498 if (status < 0) {
6499 cm_msg(MERROR, "ss_tape_mount", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6500 return errno;
6501 }
6502#endif /* OS_UNIX */
6503
6504#ifdef OS_WINNT
6505 INT status;
6506
6508 if (status != NO_ERROR) {
6509 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
6510 return status;
6511 }
6512#endif /* OS_WINNT */
6513
6514 return CM_SUCCESS;
6515}
#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 5817 of file system.cxx.

5839{
5840#ifdef OS_UNIX
5841 //cm_enable_watchdog(FALSE);
5842
5843 *channel = open(path, oflag, 0644);
5844
5845 //cm_enable_watchdog(TRUE);
5846
5847 if (*channel < 0)
5848 cm_msg(MERROR, "ss_tape_open", "open() returned %d, errno %d (%s)", *channel, errno, strerror(errno));
5849
5850 if (*channel < 0) {
5851 if (errno == EIO)
5852 return SS_NO_TAPE;
5853 if (errno == EBUSY)
5854 return SS_DEV_BUSY;
5855 return errno;
5856 }
5857#ifdef MTSETBLK
5858 {
5859 /* set variable block size */
5860 struct mtop arg;
5861 arg.mt_op = MTSETBLK;
5862 arg.mt_count = 0;
5863
5864 ioctl(*channel, MTIOCTOP, &arg);
5865 }
5866#endif /* MTSETBLK */
5867
5868#endif /* OS_UNIX */
5869
5870#ifdef OS_WINNT
5871 INT status;
5873
5875
5876 if (*channel == (INT) INVALID_HANDLE_VALUE) {
5877 status = GetLastError();
5879 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
5880 return SS_DEV_BUSY;
5881 }
5883 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
5884 return SS_NO_TAPE;
5885 }
5886
5887 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
5888 return status;
5889 }
5890
5893 cm_msg(MERROR, "ss_tape_open", "no media in drive");
5894 return SS_NO_TAPE;
5895 }
5896
5897 /* set block size */
5898 memset(&m, 0, sizeof(m));
5899 m.BlockSize = TAPE_BUFFER_SIZE;
5901
5902#endif
5903
5904 return SS_SUCCESS;
5905}
#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 6098 of file system.cxx.

6118{
6119#ifdef OS_UNIX
6120 INT n, status;
6121
6122 do {
6123 n = read(channel, pdata, *count);
6124 } while (n == -1 && errno == EINTR);
6125
6126 if (n == -1) {
6127 if (errno == ENOSPC || errno == EIO)
6129 else {
6130 if (n == 0 && errno == 0)
6132 else {
6133 cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", n, errno);
6134 status = errno;
6135 }
6136 }
6137 } else
6139 *count = n;
6140
6141 return status;
6142
6143#elif defined(OS_WINNT) /* OS_UNIX */
6144
6145 INT status;
6146 DWORD read;
6147
6148 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
6149 status = GetLastError();
6152 else if (status == ERROR_FILEMARK_DETECTED)
6154 else if (status == ERROR_MORE_DATA)
6156 else
6157 cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", read, status);
6158 } else
6160
6161 *count = read;
6162 return status;
6163
6164#else /* OS_WINNT */
6165
6166 return SS_SUCCESS;
6167
6168#endif
6169}
#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 6354 of file system.cxx.

6372{
6373#ifdef MTIOCTOP
6374 struct mtop arg;
6375 INT status;
6376
6377 arg.mt_op = MTREW;
6378 arg.mt_count = 0;
6379
6380 //cm_enable_watchdog(FALSE);
6381
6382 status = ioctl(channel, MTIOCTOP, &arg);
6383
6384 //cm_enable_watchdog(TRUE);
6385
6386 if (status < 0) {
6387 cm_msg(MERROR, "ss_tape_rewind", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6388 return errno;
6389 }
6390#endif /* OS_UNIX */
6391
6392#ifdef OS_WINNT
6393 INT status;
6394
6396 if (status != NO_ERROR) {
6397 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
6398 return status;
6399 }
6400#endif /* OS_WINNT */
6401
6402 return CM_SUCCESS;
6403}
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 6298 of file system.cxx.

6317{
6318#ifdef MTIOCTOP
6319 struct mtop arg;
6320 INT status;
6321
6322 if (count > 0)
6323 arg.mt_op = MTFSR;
6324 else
6325 arg.mt_op = MTBSR;
6326 arg.mt_count = abs(count);
6327
6328 //cm_enable_watchdog(FALSE);
6329
6330 status = ioctl(channel, MTIOCTOP, &arg);
6331
6332 //cm_enable_watchdog(TRUE);
6333
6334 if (status < 0) {
6335 cm_msg(MERROR, "ss_tape_rskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6336 return errno;
6337 }
6338#endif /* OS_UNIX */
6339
6340#ifdef OS_WINNT
6341 INT status;
6342
6344 if (status != NO_ERROR) {
6345 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
6346 return status;
6347 }
6348#endif /* OS_WINNT */
6349
6350 return CM_SUCCESS;
6351}
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 6406 of file system.cxx.

6424{
6425#ifdef MTIOCTOP
6426 struct mtop arg;
6427 INT status;
6428
6429#ifdef MTEOM
6430 arg.mt_op = MTEOM;
6431#else
6432 arg.mt_op = MTSEOD;
6433#endif
6434 arg.mt_count = 0;
6435
6436 //cm_enable_watchdog(FALSE);
6437
6438 status = ioctl(channel, MTIOCTOP, &arg);
6439
6440 //cm_enable_watchdog(TRUE);
6441
6442 if (status < 0) {
6443 cm_msg(MERROR, "ss_tape_rewind", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6444 return errno;
6445 }
6446#endif /* OS_UNIX */
6447
6448#ifdef OS_WINNT
6449 INT status;
6450
6452 if (status != NO_ERROR) {
6453 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
6454 return status;
6455 }
6456#endif /* OS_WINNT */
6457
6458 return CM_SUCCESS;
6459}
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 5952 of file system.cxx.

5969{
5970#ifdef OS_UNIX
5971 int status;
5972 char str[256];
5973 /* let 'mt' do the job */
5974 sprintf(str, "mt -f %s status", path);
5975 status = system(str);
5976 if (status == -1)
5977 return SS_TAPE_ERROR;
5978 return SS_SUCCESS;
5979#endif /* OS_UNIX */
5980
5981#ifdef OS_WINNT
5983 DWORD size;
5986 double x;
5987
5989
5990 if (channel == (INT) INVALID_HANDLE_VALUE) {
5991 status = GetLastError();
5993 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
5994 return SS_SUCCESS;
5995 }
5997 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
5998 return SS_SUCCESS;
5999 }
6000
6001 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
6002 return status;
6003 }
6004
6005 /* poll media changed messages */
6008
6011 cm_msg(MINFO, "ss_tape_status", "no media in drive");
6013 return SS_SUCCESS;
6014 }
6015
6018
6019 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
6020 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
6021 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
6022
6023 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
6024 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
6025 / 1000.0 / 1000.0;
6026 printf("Tape capacity remaining is %d MB\n", (int) x);
6027 } else
6028 printf("Tape capacity is not reported by tape\n");
6029
6031
6032#endif
6033
6034 return SS_SUCCESS;
6035}
#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 6518 of file system.cxx.

6536{
6537#ifdef MTIOCTOP
6538 struct mtop arg;
6539 INT status;
6540
6541#ifdef MTOFFL
6542 arg.mt_op = MTOFFL;
6543#else
6544 arg.mt_op = MTUNLOAD;
6545#endif
6546 arg.mt_count = 0;
6547
6548 //cm_enable_watchdog(FALSE);
6549
6550 status = ioctl(channel, MTIOCTOP, &arg);
6551
6552 //cm_enable_watchdog(TRUE);
6553
6554 if (status < 0) {
6555 cm_msg(MERROR, "ss_tape_unmount", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6556 return errno;
6557 }
6558#endif /* OS_UNIX */
6559
6560#ifdef OS_WINNT
6561 INT status;
6562
6564 if (status != NO_ERROR) {
6565 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
6566 return status;
6567 }
6568#endif /* OS_WINNT */
6569
6570 return CM_SUCCESS;
6571}
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 6038 of file system.cxx.

6059{
6060#ifdef OS_UNIX
6061 INT status;
6062
6063 do {
6065/*
6066 if (status != count)
6067 printf("count: %d - %d\n", count, status);
6068*/
6069 } while (status == -1 && errno == EINTR);
6070
6071 if (status != count) {
6072 cm_msg(MERROR, "ss_tape_write", "write() returned %d, errno %d (%s)", status, errno, strerror(errno));
6073
6074 if (errno == EIO)
6075 return SS_IO_ERROR;
6076 else
6077 return SS_TAPE_ERROR;
6078 }
6079#endif /* OS_UNIX */
6080
6081#ifdef OS_WINNT
6082 INT status;
6083 DWORD written;
6084
6086 if (written != (DWORD) count) {
6087 status = GetLastError();
6088 cm_msg(MERROR, "ss_tape_write", "error %d", status);
6089
6090 return SS_IO_ERROR;
6091 }
6092#endif /* OS_WINNT */
6093
6094 return SS_SUCCESS;
6095}
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 6172 of file system.cxx.

6190{
6191#ifdef MTIOCTOP
6192 struct mtop arg;
6193 INT status;
6194
6195 arg.mt_op = MTWEOF;
6196 arg.mt_count = 1;
6197
6198 //cm_enable_watchdog(FALSE);
6199
6200 status = ioctl(channel, MTIOCTOP, &arg);
6201
6202 //cm_enable_watchdog(TRUE);
6203
6204 if (status < 0) {
6205 cm_msg(MERROR, "ss_tape_write_eof", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6206 return errno;
6207 }
6208#endif /* OS_UNIX */
6209
6210#ifdef OS_WINNT
6211
6213 DWORD size;
6214 INT status;
6215
6216 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
6218
6219 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
6221 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
6223 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
6225 else
6226 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
6227
6228 if (status != NO_ERROR) {
6229 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
6230 return status;
6231 }
6232#endif /* OS_WINNT */
6233
6234 return SS_SUCCESS;
6235}
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 8266 of file system.cxx.

8266 {
8267 auto elapsed = std::chrono::high_resolution_clock::now() - start;
8268 return std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
8269}
Here is the call graph for this function:

◆ ss_us_start()

Definition at line 8261 of file system.cxx.

8262{
8263 return std::chrono::high_resolution_clock::now();
8264}

◆ ss_write_tcp()

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

Definition at line 5352 of file system.cxx.

5373{
5374 size_t count = 0;
5375
5376 while (count < buffer_size) {
5377 ssize_t wr = write(sock, buffer + count, buffer_size - count);
5378
5379 if (wr == 0) {
5380 cm_msg(MERROR, "ss_write_tcp", "write(socket=%d,size=%d) returned zero, errno: %d (%s)", sock, (int) (buffer_size - count), errno, strerror(errno));
5381 return SS_SOCKET_ERROR;
5382 } else if (wr < 0) {
5383#ifdef OS_UNIX
5384 if (errno == EINTR)
5385 continue;
5386#endif
5387 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));
5388 return SS_SOCKET_ERROR;
5389 }
5390
5391 // good write
5392 count += wr;
5393 }
5394
5395 return SS_SUCCESS;
5396}
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 7997 of file system.cxx.

◆ stack_history_pointer

int stack_history_pointer = -1

Definition at line 7998 of file system.cxx.

◆ [struct]

struct { ... } test_align

◆ [struct]

struct { ... } test_padding