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)
 
std::string ss_get_cmdline (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))
 
void * ss_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,...)
 
char * ss_getpass (const char *prompt)
 
INT ss_getchar (BOOL reset)
 
char * ss_gets (char *string, int size)
 
INT ss_directio_give_port (INT start, INT end)
 
INT ss_directio_lock_port (INT start, INT end)
 
char * ss_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_clock > ss_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 7974 of file system.cxx.

◆ N_STACK_HISTORY

#define N_STACK_HISTORY   500

Definition at line 8075 of file system.cxx.

Typedef Documentation

◆ SUSPEND_STRUCT

Function Documentation

◆ check_shm_host()

static void check_shm_host ( )
static

Definition at line 170 of file system.cxx.

171{
172 std::string file_name;
173 char buf[256], cwd[256];
174 char hostname[256];
175 char* s;
176 FILE *fp;
177
178 gethostname(hostname, sizeof(hostname));
179
180 //printf("hostname [%s]\n", hostname);
181
182 std::string path = cm_get_path();
183 if (path.empty()) {
184 if (getcwd(cwd, sizeof(cwd)))
185 path = std::string(cwd);
186#if defined(OS_VMS)
187#elif defined(OS_UNIX)
188 path += "/";
189#elif defined(OS_WINNT)
190 path += "\\";
191#endif
192 }
193
194 file_name = path;
195#if defined (OS_UNIX)
196 file_name += "."; /* dot file under UNIX */
197#endif
198 file_name += "SHM_HOST.TXT";
199
200 fp = fopen(file_name.c_str(), "r");
201 if (!fp) {
202 fp = fopen(file_name.c_str(), "w");
203 if (!fp)
204 cm_msg(MERROR, "check_shm_host", "Cannot write to \'%s\', errno %d (%s)", file_name.c_str(), errno, strerror(errno));
205 assert(fp != NULL);
206 fprintf(fp, "%s\n", hostname);
207 fclose(fp);
208 return;
209 }
210
211 buf[0] = 0;
212
213 if (!fgets(buf, sizeof(buf), fp))
214 buf[0] = 0;
215
216 fclose(fp);
217
218 s = strchr(buf, '\n');
219 if (s)
220 *s = 0;
221
222 if (strlen(buf) < 1)
223 return; // success - provide user with a way to defeat this check
224
225 if (strcmp(buf, hostname) == 0)
226 return; // success!
227
228 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);
229 exit(1);
230}
std::string cm_get_path()
Definition midas.cxx:1553
#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:931
static FILE * fp
char file_name[256]
Definition odbhist.cxx:41
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 82 of file system.cxx.

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

5503{
5504 INT i, status;
5505 DWORD n;
5506
5507 n = 0;
5508 memset(buffer, 0, buffer_size);
5509
5510 do {
5511 if (millisec > 0) {
5512 status = ss_socket_wait(sock, millisec);
5513 if (status != SS_SUCCESS)
5514 break;
5515 }
5516
5517 i = recv(sock, buffer + n, 1, 0);
5518
5519 if (i <= 0)
5520 break;
5521
5522 n++;
5523
5524 if (n >= buffer_size)
5525 break;
5526
5527 } while (buffer[n - 1] && buffer[n - 1] != 10);
5528
5529 return n - 1;
5530}
#define SS_SUCCESS
Definition midas.h:664
unsigned int DWORD
Definition mcstd.h:51
int ss_socket_wait(int sock, INT millisec)
Definition system.cxx:4977
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 5533 of file system.cxx.

5563{
5564 INT param_size, n_received, n;
5565 NET_COMMAND *nc;
5566
5567 if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
5568 cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
5569 return -1;
5570 }
5571
5572 /* first receive header */
5573 n_received = 0;
5574 do {
5575#ifdef OS_UNIX
5576 do {
5577 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
5578
5579 /* don't return if an alarm signal was cought */
5580 } while (n == -1 && errno == EINTR);
5581#else
5582 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
5583#endif
5584
5585 if (n == 0) {
5586 cm_msg(MERROR, "recv_tcp", "header: recv(%d) returned %d, n_received = %d, unexpected connection closure", (int)sizeof(NET_COMMAND_HEADER), n, n_received);
5587 return n;
5588 }
5589
5590 if (n < 0) {
5591 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));
5592 return n;
5593 }
5594
5595 n_received += n;
5596
5597 } while (n_received < (int) sizeof(NET_COMMAND_HEADER));
5598
5599 /* now receive parameters */
5600
5601 nc = (NET_COMMAND *) net_buffer;
5602 param_size = nc->header.param_size;
5603 n_received = 0;
5604
5605 if (param_size == 0)
5606 return sizeof(NET_COMMAND_HEADER);
5607
5608 if (param_size > (INT)buffer_size) {
5609 cm_msg(MERROR, "recv_tcp", "param: receive buffer size %d is too small for received data size %d", buffer_size, param_size);
5610 return -1;
5611 }
5612
5613 do {
5614#ifdef OS_UNIX
5615 do {
5616 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received, param_size - n_received, flags);
5617
5618 /* don't return if an alarm signal was cought */
5619 } while (n == -1 && errno == EINTR);
5620#else
5621 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received, param_size - n_received, flags);
5622#endif
5623
5624 if (n == 0) {
5625 cm_msg(MERROR, "recv_tcp", "param: recv() returned %d, n_received = %d, unexpected connection closure", n, n_received);
5626 return n;
5627 }
5628
5629 if (n < 0) {
5630 cm_msg(MERROR, "recv_tcp", "param: recv() returned %d, n_received = %d, errno: %d (%s)", n, n_received, errno, strerror(errno));
5631 return n;
5632 }
5633
5634 n_received += n;
5635 } while (n_received < param_size);
5636
5637 return sizeof(NET_COMMAND_HEADER) + param_size;
5638}
NET_COMMAND_HEADER header
Definition msystem.h:293
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 5641 of file system.cxx.

5667{
5668 int n_received = 0;
5669 int flags = 0;
5670 int n;
5671
5672 //printf("recv_tcp2: %p+%d bytes, timeout %d ms!\n", net_buffer + n_received, buffer_size - n_received, timeout_ms);
5673
5674 while (n_received != buffer_size) {
5675
5676 if (timeout_ms > 0) {
5677 int status = ss_socket_wait(sock, timeout_ms);
5678 if (status == SS_TIMEOUT)
5679 return n_received;
5680 if (status != SS_SUCCESS)
5681 return -1;
5682 }
5683
5684 n = recv(sock, net_buffer + n_received, buffer_size - n_received, flags);
5685
5686 //printf("recv_tcp2: %p+%d bytes, returned %d, errno %d (%s)\n", net_buffer + n_received, buffer_size - n_received, n, errno, strerror(errno));
5687
5688#ifdef EINTR
5689 /* don't return if an alarm signal was cought */
5690 if (n == -1 && errno == EINTR)
5691 continue;
5692#endif
5693
5694 if (n == 0) {
5695 // socket closed
5696 cm_msg(MERROR, "recv_tcp2", "unexpected connection closure");
5697 return -1;
5698 }
5699
5700 if (n < 0) {
5701 // socket error
5702 cm_msg(MERROR, "recv_tcp2", "unexpected connection error, recv() errno %d (%s)", errno, strerror(errno));
5703 return -1;
5704 }
5705
5706 n_received += n;
5707 }
5708
5709 return n_received;
5710}
#define SS_TIMEOUT
Definition midas.h:675
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 17534 of file midas.cxx.

17548{
17549 bool has_data = ss_event_socket_has_data();
17550
17551 //printf("ss_event_socket_has_data() returned %d\n", has_data);
17552
17553 if (has_data) {
17554 if (timeout_msec == BM_NO_WAIT) {
17555 return BM_ASYNC_RETURN;
17556 } else if (timeout_msec == BM_WAIT) {
17557 return BM_ASYNC_RETURN;
17558 } else {
17559 int status = ss_suspend(timeout_msec, MSG_BM);
17560 if (status == SS_ABORT || status == SS_EXIT)
17561 return status;
17562 return BM_ASYNC_RETURN;
17563 }
17564 }
17565
17566 int status = rpc_server_receive_event(0, NULL, timeout_msec);
17567
17568 //printf("rpc_server_receive_event() status %d\n", status);
17569
17570 if (status == BM_ASYNC_RETURN) {
17571 return BM_ASYNC_RETURN;
17572 }
17573
17574 if (status == SS_ABORT || status == SS_EXIT)
17575 return status;
17576
17577 return BM_SUCCESS;
17578}
#define BM_ASYNC_RETURN
Definition midas.h:613
#define BM_SUCCESS
Definition midas.h:605
#define SS_ABORT
Definition midas.h:678
#define SS_EXIT
Definition midas.h:679
#define BM_NO_WAIT
Definition midas.h:366
#define BM_WAIT
Definition midas.h:365
#define MSG_BM
Definition msystem.h:302
INT ss_suspend(INT millisec, INT msg)
Definition system.cxx:4622
bool ss_event_socket_has_data()
Definition system.cxx:4599
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition midas.cxx:17379
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 5364 of file system.cxx.

5385{
5386 DWORD count;
5387 INT status;
5388 //int net_tcp_size = NET_TCP_SIZE;
5389 int net_tcp_size = 1024 * 1024;
5390
5391 /* transfer fragments until complete buffer is transferred */
5392
5393 for (count = 0; (INT) count < (INT) buffer_size - net_tcp_size;) {
5394 status = send(sock, buffer + count, net_tcp_size, flags & 0xFFFF);
5395 if (status != -1)
5396 count += status;
5397 else {
5398#ifdef OS_UNIX
5399 if (errno == EINTR)
5400 continue;
5401#endif
5402 if ((flags & 0x10000) == 0)
5403 cm_msg(MERROR, "send_tcp",
5404 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
5405 sock, net_tcp_size, status, errno, strerror(errno));
5406 return status;
5407 }
5408 }
5409
5410 while (count < buffer_size) {
5411 status = send(sock, buffer + count, buffer_size - count, flags & 0xFFFF);
5412 if (status != -1)
5413 count += status;
5414 else {
5415#ifdef OS_UNIX
5416 if (errno == EINTR)
5417 continue;
5418#endif
5419 if ((flags & 0x10000) == 0)
5420 cm_msg(MERROR, "send_tcp",
5421 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
5422 sock, (int) (buffer_size - count), status, errno, strerror(errno));
5423 return status;
5424 }
5425 }
5426
5427 return count;
5428}
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 3816 of file system.cxx.

3836{
3837#ifdef OS_WINNT
3838
3839 UserCallback = func;
3840 if (millitime > 0)
3841 _timer_id = timeSetEvent(millitime, 100, (LPTIMECALLBACK) _timeCallback, 0, TIME_ONESHOT);
3842 else {
3843 if (_timer_id)
3844 timeKillEvent(_timer_id);
3845 _timer_id = 0;
3846 }
3847
3848 return SS_SUCCESS;
3849
3850#endif /* OS_WINNT */
3851#ifdef OS_VMS
3852
3853 signal(SIGALRM, func);
3854 alarm(millitime / 1000);
3855 return SS_SUCCESS;
3856
3857#endif /* OS_VMS */
3858#ifdef OS_UNIX
3859
3860 signal(SIGALRM, func);
3861 alarm(millitime / 1000);
3862 return SS_SUCCESS;
3863
3864#endif /* OS_UNIX */
3865}

◆ ss_asctime()

std::string EXPRT ss_asctime ( )

Definition at line 3628 of file system.cxx.

3645{
3646 ss_tzset(); // required for localtime_t()
3647 time_t seconds = (time_t) ss_time();
3648 struct tm tms;
3649 localtime_r(&seconds, &tms);
3650 char str[32];
3651 asctime_r(&tms, str);
3652 /* strip new line */
3653 str[24] = 0;
3654
3655 return str;
3656}
void ss_tzset()
Definition system.cxx:3434
DWORD ss_time()
Definition system.cxx:3541
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 7384 of file system.cxx.

7401{
7402#ifdef OS_WINNT
7403
7404 HANDLE hConsole;
7405 COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */
7406 BOOL bSuccess;
7407 DWORD cCharsWritten;
7408 CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
7409 DWORD dwConSize; /* number of character cells in the current buffer */
7410
7411 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
7412
7413 /* get the number of character cells in the current buffer */
7414 bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
7415 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
7416
7417 /* fill the entire screen with blanks */
7418 bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ', dwConSize, coordScreen, &cCharsWritten);
7419
7420 /* put the cursor at (0, 0) */
7421 bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
7422 return;
7423
7424#endif /* OS_WINNT */
7425#if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7426 printf("\033[2J");
7427#endif
7428#ifdef OS_MSDOS
7429 clrscr();
7430#endif
7431}
DWORD BOOL
Definition midas.h:105
Here is the caller graph for this function:

◆ ss_crypt()

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

Definition at line 7976 of file system.cxx.

7996{
7997 int i, seed;
7998 static char enc_pw[13];
7999
8000 memset(enc_pw, 0, sizeof(enc_pw));
8001 enc_pw[0] = salt[0];
8002 enc_pw[1] = salt[1];
8003
8004 for (i = 0; i < 8 && buf[i]; i++)
8005 enc_pw[i + 2] = buf[i];
8006 for (; i < 8; i++)
8007 enc_pw[i + 2] = 0;
8008
8009 seed = 123;
8010 for (i = 2; i < 13; i++) {
8011 seed = 5 * seed + 27 + enc_pw[i];
8012 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
8013 }
8014
8015 return enc_pw;
8016}
#define bin_to_ascii(c)
Definition system.cxx:7974
Here is the caller graph for this function:

◆ ss_ctrlc_handler()

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

Definition at line 3978 of file system.cxx.

3998{
3999#ifdef OS_WINNT
4000
4001 if (func == NULL) {
4002 signal(SIGBREAK, SIG_DFL);
4003 return signal(SIGINT, SIG_DFL);
4004 } else {
4005 signal(SIGBREAK, func);
4006 return signal(SIGINT, func);
4007 }
4008 return NULL;
4009
4010#endif /* OS_WINNT */
4011#ifdef OS_VMS
4012
4013 return signal(SIGINT, func);
4014
4015#endif /* OS_WINNT */
4016
4017#ifdef OS_UNIX
4018
4019 if (func == NULL) {
4020 signal(SIGTERM, SIG_DFL);
4021 return (void *) signal(SIGINT, SIG_DFL);
4022 } else {
4023 signal(SIGTERM, func);
4024 return (void *) signal(SIGINT, func);
4025 }
4026
4027#endif /* OS_UNIX */
4028}
Here is the caller graph for this function:

◆ ss_daemon_init()

INT EXPRT ss_daemon_init ( BOOL  keep_stdout)

Definition at line 2073 of file system.cxx.

2091{
2092#ifdef OS_UNIX
2093
2094 /* only implemented for UNIX */
2095 int i, fd, pid;
2096
2097#ifdef NO_FORK
2098 assert(!"support for fork() disabled by NO_FORK");
2099#else
2100 if ((pid = fork()) < 0)
2101 return SS_ABORT;
2102 else if (pid != 0)
2103 exit(0); /* parent finished */
2104#endif
2105
2106 /* child continues here */
2107
2109
2110 /* try and use up stdin, stdout and stderr, so other
2111 routines writing to stdout etc won't cause havoc. Copied from smbd */
2112 for (i = 0; i < 3; i++) {
2113 if (keep_stdout && ((i == 1) || (i == 2)))
2114 continue;
2115
2116 close(i);
2117 fd = open("/dev/null", O_RDWR, 0);
2118 if (fd < 0)
2119 fd = open("/dev/null", O_WRONLY, 0);
2120 if (fd < 0) {
2121 cm_msg(MERROR, "ss_daemon_init", "Can't open /dev/null");
2122 return SS_ABORT;
2123 }
2124 if (fd != i) {
2125 cm_msg(MERROR, "ss_daemon_init", "Did not get file descriptor");
2126 return SS_ABORT;
2127 }
2128 }
2129
2130 setsid(); /* become session leader */
2131
2132#endif
2133
2134 return SS_SUCCESS;
2135}
static BOOL _daemon_flag
Definition system.cxx:2071
#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 7271 of file system.cxx.

7288{
7289#ifdef OS_UNIX
7290 struct stat buf;
7291
7292 int retval = stat(path, &buf);
7293 //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7294 if (retval < 0)
7295 return 0;
7296 if (!S_ISDIR(buf.st_mode))
7297 return 0;
7298#else
7299#warning ss_dir_exist() is not implemented!
7300#endif
7301 return 1;
7302}
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 6881 of file system.cxx.

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

6917{
6918 assert(plist);
6919#ifdef OS_UNIX
6920 DIR *dir_pointer;
6921 struct dirent *dp;
6922
6923 if ((dir_pointer = opendir(path)) == NULL)
6924 return 0;
6925 plist->clear();
6926 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6927 if (fnmatch(pattern, dp->d_name, 0) == 0 && dp->d_type == DT_DIR) {
6928 plist->push_back(dp->d_name);
6929 seekdir(dir_pointer, telldir(dir_pointer));
6930 }
6931 }
6932 closedir(dir_pointer);
6933#endif
6934#ifdef OS_WINNT
6935 char str[255];
6936 int first;
6937
6938 strcpy(str, path);
6939 strcat(str, "\\");
6940 strcat(str, pattern);
6941 first = 1;
6942 plist->clear();
6943 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
6944 pffile = FindFirstFile(str, lpfdata);
6945 if (pffile == INVALID_HANDLE_VALUE)
6946 return 0;
6947 first = 0;
6948 plist->push_back(lpfdata->cFileName);
6949 while (FindNextFile(pffile, lpfdata)) {
6950 plist->push_back(lpfdata->cFileName);
6951 }
6952 free(lpfdata);
6953#endif
6954 return plist->size();
6955}
@ DIR
Definition test_init.cxx:7

◆ ss_directio_give_port()

INT EXPRT ss_directio_give_port ( INT  start,
INT  end 
)

Definition at line 7896 of file system.cxx.

7897{
7898#ifdef OS_WINNT
7899
7900 /* under Windows NT, use DirectIO driver to open ports */
7901
7902 OSVERSIONINFO vi;
7903 HANDLE hdio = 0;
7904 DWORD buffer[] = { 6, 0, 0, 0 };
7905 DWORD size;
7906
7907 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7908 GetVersionEx(&vi);
7909
7910 /* use DirectIO driver under NT to gain port access */
7911 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
7912 hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7913 if (hdio == INVALID_HANDLE_VALUE) {
7914 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
7915 return -1;
7916 }
7917
7918 /* open ports */
7919 buffer[1] = start;
7920 buffer[2] = end;
7921 if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
7922 return -1;
7923 }
7924
7925 return SS_SUCCESS;
7926#else
7927 return SS_SUCCESS;
7928#endif
7929}
#define end

◆ ss_directio_lock_port()

INT EXPRT ss_directio_lock_port ( INT  start,
INT  end 
)

Definition at line 7932 of file system.cxx.

7933{
7934#ifdef OS_WINNT
7935
7936 /* under Windows NT, use DirectIO driver to lock ports */
7937
7938 OSVERSIONINFO vi;
7939 HANDLE hdio;
7940 DWORD buffer[] = { 7, 0, 0, 0 };
7941 DWORD size;
7942
7943 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7944 GetVersionEx(&vi);
7945
7946 /* use DirectIO driver under NT to gain port access */
7947 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
7948 hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7949 if (hdio == INVALID_HANDLE_VALUE) {
7950 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
7951 return -1;
7952 }
7953
7954 /* lock ports */
7955 buffer[1] = start;
7956 buffer[2] = end;
7957 if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
7958 return -1;
7959 }
7960
7961 return SS_SUCCESS;
7962#else
7963 return SS_SUCCESS;
7964#endif
7965}

◆ ss_dirlink_find() [1/2]

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

Definition at line 6957 of file system.cxx.

6958{
6960
6961 int count = ss_dirlink_find(path, pattern, &list);
6962 if (count <= 0)
6963 return count;
6964
6965 size_t size = list.size();
6966 *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6967 for (size_t i=0; i<size; i++) {
6968 //printf("file %d [%s]\n", (int)i, list[i].c_str());
6969 mstrlcpy((*plist)+i*MAX_STRING_LENGTH, list[i].c_str(), MAX_STRING_LENGTH);
6970 }
6971
6972 return size;
6973}
INT ss_dirlink_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6957
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 6975 of file system.cxx.

6993{
6994 assert(plist);
6995#ifdef OS_UNIX
6996 DIR *dir_pointer;
6997 struct dirent *dp;
6998
6999 if ((dir_pointer = opendir(path)) == NULL)
7000 return 0;
7001 plist->clear();
7002 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
7003 if (fnmatch(pattern, dp->d_name, 0) == 0) {
7004 /* must have a "/" at the end, otherwise also links to files are accepted */
7005 std::string full_path = std::string(path) + "/" + dp->d_name + "/";
7006 struct stat st;
7007 if (lstat(full_path.c_str(), &st) == 0 && (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) {
7008 plist->push_back(dp->d_name);
7009 }
7010 }
7011 }
7012 closedir(dir_pointer);
7013#endif
7014#ifdef OS_WINNT
7015 char str[255];
7016 int first;
7017
7018 strcpy(str, path);
7019 strcat(str, "\\");
7020 strcat(str, pattern);
7021 first = 1;
7022 plist->clear();
7023 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
7024 pffile = FindFirstFile(str, lpfdata);
7025 if (pffile == INVALID_HANDLE_VALUE)
7026 return 0;
7027 first = 0;
7028 plist->push_back(lpfdata->cFileName);
7029 while (FindNextFile(pffile, lpfdata)) {
7030 plist->push_back(lpfdata->cFileName);
7031 }
7032 free(lpfdata);
7033#endif
7034 return plist->size();
7035}

◆ ss_disk_free()

double EXPRT ss_disk_free ( const char *  path)

Definition at line 6705 of file system.cxx.

6721{
6722#ifdef OS_UNIX
6723#if defined(OS_OSF1)
6724 struct statfs st;
6725 statfs(path, &st, sizeof(st));
6726 return (double) st.f_bavail * st.f_bsize;
6727#elif defined(OS_LINUX)
6728 struct statfs st;
6729 int status;
6730 status = statfs(path, &st);
6731 if (status != 0)
6732 return -1;
6733 return (double) st.f_bavail * st.f_bsize;
6734#elif defined(OS_SOLARIS)
6735 struct statvfs st;
6736 statvfs(path, &st);
6737 return (double) st.f_bavail * st.f_bsize;
6738#elif defined(OS_IRIX)
6739 struct statfs st;
6740 statfs(path, &st, sizeof(struct statfs), 0);
6741 return (double) st.f_bfree * st.f_bsize;
6742#else
6743 struct fs_data st;
6744 statfs(path, &st);
6745 return (double) st.fd_otsize * st.fd_bfree;
6746#endif
6747
6748#elif defined(OS_WINNT) /* OS_UNIX */
6749 DWORD SectorsPerCluster;
6750 DWORD BytesPerSector;
6751 DWORD NumberOfFreeClusters;
6752 DWORD TotalNumberOfClusters;
6753 char str[80];
6754
6755 strcpy(str, path);
6756 if (strchr(str, ':') != NULL) {
6757 *(strchr(str, ':') + 1) = 0;
6758 strcat(str, DIR_SEPARATOR_STR);
6759 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
6760 } else
6761 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
6762
6763 return (double) NumberOfFreeClusters *SectorsPerCluster * BytesPerSector;
6764#else /* OS_WINNT */
6765
6766 return 1e9;
6767
6768#endif
6769}
#define DIR_SEPARATOR_STR
Definition midas.h:194
Here is the caller graph for this function:

◆ ss_disk_size()

double EXPRT ss_disk_size ( const char *  path)

Definition at line 7133 of file system.cxx.

7149{
7150#ifdef OS_UNIX
7151#if defined(OS_OSF1)
7152 struct statfs st;
7153 statfs(path, &st, sizeof(st));
7154 return (double) st.f_blocks * st.f_fsize;
7155#elif defined(OS_LINUX)
7156 int status;
7157 struct statfs st;
7158 status = statfs(path, &st);
7159 if (status != 0)
7160 return -1;
7161 return (double) st.f_blocks * st.f_bsize;
7162#elif defined(OS_SOLARIS)
7163 struct statvfs st;
7164 statvfs(path, &st);
7165 if (st.f_frsize > 0)
7166 return (double) st.f_blocks * st.f_frsize;
7167 else
7168 return (double) st.f_blocks * st.f_bsize;
7169#elif defined(OS_ULTRIX)
7170 struct fs_data st;
7171 statfs(path, &st);
7172 return (double) st.fd_btot * 1024;
7173#elif defined(OS_IRIX)
7174 struct statfs st;
7175 statfs(path, &st, sizeof(struct statfs), 0);
7176 return (double) st.f_blocks * st.f_bsize;
7177#else
7178#error ss_disk_size not defined for this OS
7179#endif
7180#endif /* OS_UNIX */
7181
7182#ifdef OS_WINNT
7183 DWORD SectorsPerCluster;
7184 DWORD BytesPerSector;
7185 DWORD NumberOfFreeClusters;
7186 DWORD TotalNumberOfClusters;
7187 char str[80];
7188
7189 strcpy(str, path);
7190 if (strchr(str, ':') != NULL) {
7191 *(strchr(str, ':') + 1) = 0;
7192 strcat(str, DIR_SEPARATOR_STR);
7193 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
7194 } else
7195 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
7196
7197 return (double) TotalNumberOfClusters *SectorsPerCluster * BytesPerSector;
7198#endif /* OS_WINNT */
7199
7200 return 1e9;
7201}
Here is the caller graph for this function:

◆ ss_event_socket_has_data()

bool ss_event_socket_has_data ( )

Definition at line 4599 of file system.cxx.

4600{
4602 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4603 /* event channel */
4604 int sock = (*_ss_server_acceptions)[i]->event_sock;
4605
4606 if (!sock)
4607 continue;
4608
4609 /* check for buffered event */
4610 int status = ss_socket_wait(sock, 1);
4611
4612 if (status == SS_SUCCESS)
4613 return true;
4614 }
4615 }
4616
4617 /* no event socket or no data in event socket */
4618 return false;
4619}
static RPC_SERVER_ACCEPTION_LIST * _ss_server_acceptions
Definition system.cxx:4069
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 3923 of file system.cxx.

3942{
3943#ifdef OS_WINNT
3944
3945 MidasExceptionHandler = func;
3946/* SetUnhandledExceptionFilter(
3947 (LPTOP_LEVEL_EXCEPTION_FILTER) MidasExceptionFilter);
3948
3949 signal(SIGINT, MidasExceptionSignal);
3950 signal(SIGILL, MidasExceptionSignal);
3951 signal(SIGFPE, MidasExceptionSignal);
3952 signal(SIGSEGV, MidasExceptionSignal);
3953 signal(SIGTERM, MidasExceptionSignal);
3954 signal(SIGBREAK, MidasExceptionSignal);
3955 signal(SIGABRT, MidasExceptionSignal); */
3956
3957#elif defined (OS_VMS)
3958
3959 MidasExceptionHandler = func;
3960 lib$establish(MidasExceptionFilter);
3961
3962 signal(SIGINT, MidasExceptionSignal);
3963 signal(SIGILL, MidasExceptionSignal);
3964 signal(SIGQUIT, MidasExceptionSignal);
3965 signal(SIGFPE, MidasExceptionSignal);
3966 signal(SIGSEGV, MidasExceptionSignal);
3967 signal(SIGTERM, MidasExceptionSignal);
3968
3969#else /* OS_VMS */
3970#endif
3971
3972 return SS_SUCCESS;
3973}
void(* MidasExceptionHandler)(void)
Definition system.cxx:3868

◆ ss_exec()

INT EXPRT ss_exec ( const char *  command,
INT pid 
)

Definition at line 2204 of file system.cxx.

2223{
2224#ifdef OS_UNIX
2225
2226 /* only implemented for UNIX */
2227 int i, fd;
2228
2229#ifdef NO_FORK
2230 assert(!"support for fork() disabled by NO_FORK");
2231#else
2232 *pid = fork();
2233#endif
2234 if (*pid < 0)
2235 return SS_ABORT;
2236 else if (*pid != 0) {
2237 /* avoid <defunc> parent processes */
2238 signal(SIGCHLD, catch_sigchld);
2239 return SS_SUCCESS; /* parent returns */
2240 }
2241
2242 /* child continues here... */
2243
2244 /* close all open file descriptors */
2245 for (i = 0; i < 256; i++)
2246 close(i);
2247
2248 /* try and use up stdin, stdout and stderr, so other
2249 routines writing to stdout etc won't cause havoc */
2250 for (i = 0; i < 3; i++) {
2251 fd = open("/dev/null", O_RDWR, 0);
2252 if (fd < 0)
2253 fd = open("/dev/null", O_WRONLY, 0);
2254 if (fd < 0) {
2255 cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
2256 return SS_ABORT;
2257 }
2258 if (fd != i) {
2259 cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
2260 return SS_ABORT;
2261 }
2262 }
2263
2264 setsid(); /* become session leader */
2265 /* chdir("/"); *//* change working directory (not on NFS!) */
2266
2267 /* execute command */
2268 int error = execl("/bin/sh", "sh", "-c", command, NULL);
2269 // NB: execl() does not return unless there is an error. K.O.
2270 fprintf(stderr, "ss_shell: Cannot execute /bin/sh for command \"%s\": execl() returned %d, errno %d (%s), aborting!\n", command, error, errno, strerror(errno));
2271 abort();
2272
2273#else
2274
2275 system(command);
2276
2277#endif
2278
2279 return SS_SUCCESS;
2280}
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 2309 of file system.cxx.

2324{
2325#ifdef OS_UNIX
2326 std::array<char, 256> buffer{};
2327 std::string result;
2328 auto pclose_deleter = [](FILE* f) { pclose(f); };
2329 auto pipe = std::unique_ptr<FILE, decltype(pclose_deleter)>(
2330 popen(cmd, "r"),
2331 pclose_deleter
2332 );
2333
2334 if (!pipe) {
2335 throw std::runtime_error("popen() failed!");
2336 }
2337
2338 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
2339 result += buffer.data();
2340 }
2341
2342 return result;
2343#else
2344 fprintf(stderr, "ss_execs: Function not supported on this OS, aborting!\n");
2345 abort();
2346#endif
2347}
Here is the caller graph for this function:

◆ ss_existpid()

BOOL EXPRT ss_existpid ( INT  pid)

Definition at line 2140 of file system.cxx.

2158{
2159#ifdef OS_UNIX
2160 /* only implemented for UNIX */
2161 return (kill(pid, 0) == 0 ? TRUE : FALSE);
2162#else
2163 cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
2164 return FALSE;
2165#endif
2166}
#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 7304 of file system.cxx.

7321{
7322 int fd_to, fd_from;
7323 char buf[4096];
7324 ssize_t nread;
7325 int saved_errno;
7326
7327 fd_from = open(src, O_RDONLY);
7328 if (fd_from < 0)
7329 return -1;
7330
7331 if (append)
7332 fd_to = open(dst, O_WRONLY | O_CREAT | O_EXCL | O_APPEND, 0666);
7333 else
7334 fd_to = open(dst, O_WRONLY | O_CREAT | O_EXCL, 0666);
7335 if (fd_to < 0)
7336 goto out_error;
7337
7338 while (nread = read(fd_from, buf, sizeof(buf)), nread > 0) {
7339 char *out_ptr = buf;
7340 ssize_t nwritten;
7341
7342 do {
7343 nwritten = write(fd_to, out_ptr, nread);
7344
7345 if (nwritten >= 0) {
7346 nread -= nwritten;
7347 out_ptr += nwritten;
7348 } else if (errno != EINTR) {
7349 goto out_error;
7350 }
7351 } while (nread > 0);
7352 }
7353
7354 if (nread == 0) {
7355 if (close(fd_to) < 0) {
7356 fd_to = -1;
7357 goto out_error;
7358 }
7359 close(fd_from);
7360
7361 /* Success! */
7362 return 0;
7363 }
7364
7365 out_error:
7366 saved_errno = errno;
7367
7368 close(fd_from);
7369 if (fd_to >= 0)
7370 close(fd_to);
7371
7372 errno = saved_errno;
7373 return -1;
7374}
#define read(n, a, f)
#define write(n, a, f, d)
Here is the caller graph for this function:

◆ ss_file_exist()

INT EXPRT ss_file_exist ( const char *  path)

Definition at line 7203 of file system.cxx.

7220{
7221#ifdef OS_UNIX
7222 struct stat buf;
7223
7224 int retval = stat(path, &buf);
7225 //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7226 if (retval < 0)
7227 return 0;
7228 if (S_ISDIR(buf.st_mode))
7229 return 0;
7230#endif
7231
7232 int fd = open(path, O_RDONLY, 0);
7233 if (fd < 0)
7234 return 0;
7235 close(fd);
7236 return 1;
7237}
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 6798 of file system.cxx.

6799{
6801
6802 int count = ss_file_find(path, pattern, &list);
6803 if (count <= 0)
6804 return count;
6805
6806 size_t size = list.size();
6807 *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6808 for (size_t i=0; i<size; i++) {
6809 //printf("file %d [%s]\n", (int)i, list[i].c_str());
6810 mstrlcpy((*plist)+i*MAX_STRING_LENGTH, list[i].c_str(), MAX_STRING_LENGTH);
6811 }
6812
6813 return size;
6814}
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition system.cxx:6798
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 6816 of file system.cxx.

6834{
6835 assert(plist);
6836 // Check if the directory exists
6837 if (access(path, F_OK) != 0) {
6838 return -1; // Return -1 files if directory doesn't exist
6839 }
6840
6841#ifdef OS_UNIX
6842 DIR *dir_pointer;
6843 struct dirent *dp;
6844
6845 plist->clear();
6846 if ((dir_pointer = opendir(path)) == NULL)
6847 return 0;
6848 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6849 if (fnmatch(pattern, dp->d_name, 0) == 0 && (dp->d_type == DT_REG || dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN)) {
6850 plist->push_back(dp->d_name);
6851 seekdir(dir_pointer, telldir(dir_pointer));
6852 }
6853 }
6854 closedir(dir_pointer);
6855#endif
6856#ifdef OS_WINNT
6857 char str[255];
6858 int first;
6859
6860 strcpy(str, path);
6861 strcat(str, "\\");
6862 strcat(str, pattern);
6863 first = 1;
6864 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
6865 *plist->clear();
6866 pffile = FindFirstFile(str, lpfdata);
6867 if (pffile == INVALID_HANDLE_VALUE)
6868 return 0;
6869 first = 0;
6870 plist->push_back(lpfdata->cFileName);
6871 i++;
6872 while (FindNextFile(pffile, lpfdata)) {
6873 plist->push_back(lpfdata->cFileName);
6874 i++;
6875 }
6876 free(lpfdata);
6877#endif
6878 return plist->size();
6879}

◆ ss_file_link_exist()

INT EXPRT ss_file_link_exist ( const char *  path)

Definition at line 7239 of file system.cxx.

7256{
7257#ifdef OS_UNIX
7258 struct stat buf;
7259
7260 int retval = lstat(path, &buf);
7261 if (retval < 0)
7262 return 0;
7263 if (S_ISLNK(buf.st_mode))
7264 return 1;
7265 return 0;
7266#endif
7267
7268 return 0;
7269}
Here is the caller graph for this function:

◆ ss_file_remove()

INT EXPRT ss_file_remove ( const char *  path)

Definition at line 7037 of file system.cxx.

7053{
7054 return remove(path);
7055}
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 7057 of file system.cxx.

7073{
7074#ifdef _LARGEFILE64_SOURCE
7075 struct stat64 stat_buf;
7076 int status;
7077
7078 /* allocate buffer with file size */
7079 status = stat64(path, &stat_buf);
7080 if (status != 0)
7081 return -1;
7082 return (double) stat_buf.st_size;
7083#else
7084 struct stat stat_buf;
7085 int status;
7086
7087 /* allocate buffer with file size */
7088 status = stat(path, &stat_buf);
7089 if (status != 0)
7090 return -1;
7091 return (double) stat_buf.st_size;
7092#endif
7093}
Here is the caller graph for this function:

◆ ss_file_time()

time_t EXPRT ss_file_time ( const char *  path)

Definition at line 7095 of file system.cxx.

7111{
7112#ifdef _LARGEFILE64_SOURCE
7113 struct stat64 stat_buf;
7114 int status;
7115
7116 /* allocate buffer with file size */
7117 status = stat64(path, &stat_buf);
7118 if (status != 0)
7119 return -1;
7120 return stat_buf.st_mtime;
7121#else
7122 struct stat stat_buf;
7123 int status;
7124
7125 /* allocate buffer with file size */
7126 status = stat(path, &stat_buf);
7127 if (status != 0)
7128 return -1;
7129 return stat_buf.st_mtime;
7130#endif
7131}
Here is the caller graph for this function:

◆ ss_get_cmdline()

std::string ss_get_cmdline ( void  )

Definition at line 1519 of file system.cxx.

1530{
1531#if defined(OS_DARWIN)
1532 int mib[3] = {CTL_KERN, KERN_PROCARGS2, getpid()};
1533 size_t len;
1534
1535 if (sysctl(mib, 3, nullptr, &len, nullptr, 0) == -1) {
1536 perror("sysctl (size)");
1537 return {};
1538 }
1539
1540 std::vector<char> buf(len);
1541 if (sysctl(mib, 3, buf.data(), &len, nullptr, 0) == -1) {
1542 perror("sysctl (data)");
1543 return {};
1544 }
1545
1546 int argc = *reinterpret_cast<int*>(buf.data());
1547 char* ptr = buf.data() + sizeof(int);
1548 char* end = buf.data() + len;
1549
1550 // Skip the executable path
1551 while (ptr < end && *ptr != '\0') {
1552 ptr++;
1553 }
1554 // Skip over any trailing NULs until the real argv[1] begins
1555 while (ptr < end && *ptr == '\0') {
1556 ptr++;
1557 }
1558
1559 std::string result;
1560 for (int i = 1; i <= argc && ptr < end; i++) {
1561 std::string s(ptr);
1562 if (!result.empty()) result += " ";
1563 result += s;
1564 ptr += s.size() + 1;
1565 }
1566
1567 return result;
1568#elif defined(OS_LINUX)
1569 std::ifstream in("/proc/self/cmdline", std::ios::binary);
1570 if (!in)
1571 return {};
1572
1573 std::string data((std::istreambuf_iterator<char>(in)),
1574 std::istreambuf_iterator<char>());
1575 if (data.empty())
1576 return {};
1577
1578 // Replace NULs with spaces and trim a trailing space if present
1579 for (char &c : data)
1580 if (c == '\0')
1581 c = ' ';
1582 if (!data.empty() && data.back() == ' ')
1583 data.pop_back();
1584 return data;
1585#endif
1586 return {};
1587}
void * data
Definition mana.cxx:268
char c
Definition system.cxx:1312
Here is the caller graph for this function:

◆ ss_get_executable()

std::string ss_get_executable ( void  )

Definition at line 1490 of file system.cxx.

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

◆ ss_get_struct_align()

INT EXPRT ss_get_struct_align ( )

Definition at line 1321 of file system.cxx.

1343{
1344 return (POINTER_T) (&test_align.d) - (POINTER_T) & test_align.c;
1345}
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 1347 of file system.cxx.

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

◆ ss_getchar()

INT EXPRT ss_getchar ( BOOL  reset)

Definition at line 7588 of file system.cxx.

7608{
7609#ifdef OS_UNIX
7610
7611 static BOOL init = FALSE;
7612 static struct termios save_termios;
7613 struct termios buf;
7614 int i, fd;
7615 char c[3];
7616
7617 if (_daemon_flag)
7618 return 0;
7619
7620 fd = fileno(stdin);
7621
7622 if (reset) {
7623 if (init)
7624 tcsetattr(fd, TCSAFLUSH, &save_termios);
7625 init = FALSE;
7626 return 0;
7627 }
7628
7629 if (!init) {
7630 tcgetattr(fd, &save_termios);
7631 memcpy(&buf, &save_termios, sizeof(buf));
7632
7633 buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
7634
7635 buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
7636
7637 buf.c_cflag &= ~(CSIZE | PARENB);
7638 buf.c_cflag |= CS8;
7639 /* buf.c_oflag &= ~(OPOST); */
7640 buf.c_cc[VMIN] = 0;
7641 buf.c_cc[VTIME] = 0;
7642
7643 tcsetattr(fd, TCSAFLUSH, &buf);
7644 init = TRUE;
7645 }
7646
7647 memset(c, 0, 3);
7648 i = read(fd, c, 1);
7649
7650 if (i == 0)
7651 return 0;
7652
7653 /* check if ESC */
7654 if (c[0] == 27) {
7655 i = read(fd, c, 2);
7656 if (i == 0) /* return if only ESC */
7657 return 27;
7658
7659 /* cursor keys return 2 chars, others 3 chars */
7660 if (c[1] < 65) {
7661 i = read(fd, c, 1);
7662 }
7663
7664 /* convert ESC sequence to CH_xxx */
7665 switch (c[1]) {
7666 case 49:
7667 return CH_HOME;
7668 case 50:
7669 return CH_INSERT;
7670 case 51:
7671 return CH_DELETE;
7672 case 52:
7673 return CH_END;
7674 case 53:
7675 return CH_PUP;
7676 case 54:
7677 return CH_PDOWN;
7678 case 65:
7679 return CH_UP;
7680 case 66:
7681 return CH_DOWN;
7682 case 67:
7683 return CH_RIGHT;
7684 case 68:
7685 return CH_LEFT;
7686 }
7687 }
7688
7689 /* BS/DEL -> BS */
7690 if (c[0] == 127)
7691 return CH_BS;
7692
7693 return c[0];
7694
7695#elif defined(OS_WINNT)
7696
7697 static BOOL init = FALSE;
7698 static INT repeat_count = 0;
7699 static INT repeat_char;
7700 HANDLE hConsole;
7701 DWORD nCharsRead;
7702 INPUT_RECORD ir;
7703 OSVERSIONINFO vi;
7704
7705 /* find out if we are under W95 */
7706 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7707 GetVersionEx(&vi);
7708
7709 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
7710 /* under W95, console doesn't work properly */
7711 int c;
7712
7713 if (!kbhit())
7714 return 0;
7715
7716 c = getch();
7717 if (c == 224) {
7718 c = getch();
7719 switch (c) {
7720 case 71:
7721 return CH_HOME;
7722 case 72:
7723 return CH_UP;
7724 case 73:
7725 return CH_PUP;
7726 case 75:
7727 return CH_LEFT;
7728 case 77:
7729 return CH_RIGHT;
7730 case 79:
7731 return CH_END;
7732 case 80:
7733 return CH_DOWN;
7734 case 81:
7735 return CH_PDOWN;
7736 case 82:
7737 return CH_INSERT;
7738 case 83:
7739 return CH_DELETE;
7740 }
7741 }
7742 return c;
7743 }
7744
7745 hConsole = GetStdHandle(STD_INPUT_HANDLE);
7746
7747 if (reset) {
7748 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
7749 init = FALSE;
7750 return 0;
7751 }
7752
7753 if (!init) {
7754 SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
7755 init = TRUE;
7756 }
7757
7758 if (repeat_count) {
7759 repeat_count--;
7760 return repeat_char;
7761 }
7762
7763 PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
7764
7765 if (nCharsRead == 0)
7766 return 0;
7767
7768 ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
7769
7770 if (ir.EventType != KEY_EVENT)
7771 return ss_getchar(0);
7772
7773 if (!ir.Event.KeyEvent.bKeyDown)
7774 return ss_getchar(0);
7775
7776 if (ir.Event.KeyEvent.wRepeatCount > 1) {
7777 repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
7778 repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
7779 return repeat_char;
7780 }
7781
7782 if (ir.Event.KeyEvent.uChar.AsciiChar)
7783 return ir.Event.KeyEvent.uChar.AsciiChar;
7784
7785 if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
7786 switch (ir.Event.KeyEvent.wVirtualKeyCode) {
7787 case 33:
7788 return CH_PUP;
7789 case 34:
7790 return CH_PDOWN;
7791 case 35:
7792 return CH_END;
7793 case 36:
7794 return CH_HOME;
7795 case 37:
7796 return CH_LEFT;
7797 case 38:
7798 return CH_UP;
7799 case 39:
7800 return CH_RIGHT;
7801 case 40:
7802 return CH_DOWN;
7803 case 45:
7804 return CH_INSERT;
7805 case 46:
7806 return CH_DELETE;
7807 }
7808
7809 return ir.Event.KeyEvent.wVirtualKeyCode;
7810 }
7811
7812 return ss_getchar(0);
7813
7814#elif defined(OS_MSDOS)
7815
7816 int c;
7817
7818 if (!kbhit())
7819 return 0;
7820
7821 c = getch();
7822 if (!c) {
7823 c = getch();
7824 switch (c) {
7825 case 71:
7826 return CH_HOME;
7827 case 72:
7828 return CH_UP;
7829 case 73:
7830 return CH_PUP;
7831 case 75:
7832 return CH_LEFT;
7833 case 77:
7834 return CH_RIGHT;
7835 case 79:
7836 return CH_END;
7837 case 80:
7838 return CH_DOWN;
7839 case 81:
7840 return CH_PDOWN;
7841 case 82:
7842 return CH_INSERT;
7843 case 83:
7844 return CH_DELETE;
7845 }
7846 }
7847 return c;
7848
7849#else
7850 return -1;
7851#endif
7852}
INT ss_getchar(BOOL reset)
Definition system.cxx:7588
#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
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 5855 of file system.cxx.

5856{
5857 char *s = getcwd(NULL, 0);
5858 if (s) {
5859 std::string cwd = s;
5860 free(s);
5861 //printf("ss_getcwd: %s\n", cwd.c_str());
5862 return cwd;
5863 } else {
5864 return "/GETCWD-FAILED-ON-US";
5865 }
5866}
Here is the caller graph for this function:

◆ ss_gethostname() [1/2]

std::string ss_gethostname ( )

Definition at line 5791 of file system.cxx.

5808{
5809 char buf[256];
5810 memset(buf, 0, sizeof(buf));
5811
5812 int status = gethostname(buf, sizeof(buf)-1);
5813
5814 //printf("gethostname %d (%s)\n", status, buffer);
5815
5816 if (status != 0) {
5817 cm_msg(MERROR, "ss_gethostname", "gethostname() errno %d (%s)", errno, strerror(errno));
5818 return "";
5819 }
5820
5821 return buf;
5822}
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 5825 of file system.cxx.

5842{
5843 std::string h = ss_gethostname();
5844
5845 if (h.length() == 0) {
5846 return SS_IO_ERROR;
5847 } else {
5848 mstrlcpy(buffer, h.c_str(), buffer_size);
5849 return SS_SUCCESS;
5850 }
5851}
#define SS_IO_ERROR
Definition midas.h:682
std::string ss_gethostname()
Definition system.cxx:5791
Here is the call graph for this function:

◆ ss_getpass()

char EXPRT * ss_getpass ( const char *  prompt)

Definition at line 7525 of file system.cxx.

7542{
7543 static char password[32];
7544
7545 fprintf(stdout, "%s", prompt);
7546 fflush(stdout);
7547 memset(password, 0, sizeof(password));
7548
7549#ifdef OS_UNIX
7550 return (char *) getpass("");
7551#elif defined(OS_WINNT)
7552 {
7553 HANDLE hConsole;
7554 DWORD nCharsRead;
7555
7556 hConsole = GetStdHandle(STD_INPUT_HANDLE);
7557 SetConsoleMode(hConsole, ENABLE_LINE_INPUT);
7558 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
7559 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
7560 printf("\n");
7561
7562 if (password[strlen(password) - 1] == '\r')
7563 password[strlen(password) - 1] = 0;
7564
7565 return password;
7566 }
7567#elif defined(OS_MSDOS)
7568 {
7569 char c, *ptr;
7570
7571 ptr = password;
7572 while ((c = getchar()) != EOF && c != '\n')
7573 *ptr++ = c;
7574 *ptr = 0;
7575
7576 printf("\n");
7577 return password;
7578 }
7579#else
7580 {
7581 ss_gets(password, 32);
7582 return password;
7583 }
7584#endif
7585}
char * ss_gets(char *string, int size)
Definition system.cxx:7855
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 1379 of file system.cxx.

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

◆ ss_gets()

char EXPRT * ss_gets ( char *  string,
int  size 
)

Definition at line 7855 of file system.cxx.

7874{
7875 char *p;
7876
7877 do {
7878 p = fgets(string, size, stdin);
7879 } while (p == NULL);
7880
7881
7882 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
7883 p[strlen(p) - 1] = 0;
7884
7885 return p;
7886}
Here is the caller graph for this function:

◆ ss_gettid()

midas_thread_t EXPRT ss_gettid ( void  )

Definition at line 1591 of file system.cxx.

1608{
1609#if defined OS_MSDOS
1610
1611 return 0;
1612
1613#elif defined OS_WINNT
1614
1615 return GetCurrentThreadId();
1616
1617#elif defined OS_VMS
1618
1619 return ss_getpid();
1620
1621#elif defined OS_DARWIN
1622
1623 return pthread_self();
1624
1625#elif defined OS_CYGWIN
1626
1627 return pthread_self();
1628
1629#elif defined OS_UNIX
1630
1631 return pthread_self();
1632 //return syscall(SYS_gettid);
1633
1634#elif defined OS_VXWORKS
1635
1636 return ss_getpid();
1637
1638#else
1639#error Do not know how to do ss_gettid()
1640#endif
1641}
INT ss_getpid(void)
Definition system.cxx:1379
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 8153 of file system.cxx.

8154{
8155 assert(string);
8156
8157 // FIXME: this function over-reads the input array. K.O. May 2021
8158
8159 const unsigned char * bytes = (const unsigned char *)string;
8160 while(*bytes) {
8161 if( (// ASCII
8162 // use bytes[0] <= 0x7F to allow ASCII control characters
8163 bytes[0] == 0x09 ||
8164 bytes[0] == 0x0A ||
8165 bytes[0] == 0x0D ||
8166 (0x20 <= bytes[0] && bytes[0] <= 0x7E)
8167 )
8168 ) {
8169 bytes += 1;
8170 continue;
8171 }
8172
8173 if( (// non-overlong 2-byte
8174 (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
8175 (0x80 <= bytes[1] && bytes[1] <= 0xBF)
8176 )
8177 ) {
8178 bytes += 2;
8179 continue;
8180 }
8181
8182 if( (// excluding overlongs
8183 bytes[0] == 0xE0 &&
8184 (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
8185 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8186 ) ||
8187 (// straight 3-byte
8188 ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
8189 bytes[0] == 0xEE ||
8190 bytes[0] == 0xEF) &&
8191 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8192 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8193 ) ||
8194 (// excluding surrogates
8195 bytes[0] == 0xED &&
8196 (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
8197 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8198 )
8199 ) {
8200 bytes += 3;
8201 continue;
8202 }
8203
8204 if( (// planes 1-3
8205 bytes[0] == 0xF0 &&
8206 (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
8207 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8208 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8209 ) ||
8210 (// planes 4-15
8211 (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
8212 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8213 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8214 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8215 ) ||
8216 (// plane 16
8217 bytes[0] == 0xF4 &&
8218 (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
8219 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8220 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8221 )
8222 ) {
8223 bytes += 4;
8224 continue;
8225 }
8226
8227 //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);
8228 //abort();
8229
8230 return false;
8231 }
8232
8233 return true;
8234}
Here is the caller graph for this function:

◆ ss_isfin()

int EXPRT ss_isfin ( double  x)

Definition at line 8051 of file system.cxx.

8052{
8053#ifdef FP_INFINITE
8054 /* new-style finite() */
8055 return isfinite(x);
8056#else
8057 /* old-style finite() */
8058 return finite(x);
8059#endif
8060}
Here is the caller graph for this function:

◆ ss_isnan()

int EXPRT ss_isnan ( double  x)

Definition at line 8046 of file system.cxx.

8047{
8048 return isnan(x);
8049}
Here is the caller graph for this function:

◆ ss_kbhit()

BOOL EXPRT ss_kbhit ( )

Definition at line 3743 of file system.cxx.

3761{
3762#ifdef OS_MSDOS
3763
3764 return kbhit();
3765
3766#endif /* OS_MSDOS */
3767#ifdef OS_WINNT
3768
3769 return kbhit();
3770
3771#endif /* OS_WINNT */
3772#ifdef OS_VMS
3773
3774 return FALSE;
3775
3776#endif /* OS_VMS */
3777#ifdef OS_UNIX
3778
3779 int n;
3780
3781 if (_daemon_flag)
3782 return 0;
3783
3784 ioctl(0, FIONREAD, &n);
3785 return (n > 0);
3786
3787#endif /* OS_UNIX */
3788#ifdef OS_VXWORKS
3789
3790 int n;
3791 ioctl(0, FIONREAD, (long) &n);
3792 return (n > 0);
3793
3794#endif /* OS_UNIX */
3795}
Here is the caller graph for this function:

◆ ss_kill()

void ss_kill ( int  pid)

Definition at line 1473 of file system.cxx.

1474{
1475#ifdef SIGKILL
1476 kill(pid, SIGKILL);
1477#else
1478#warning Missing SIGKILL for ss_kill()
1479#endif
1480}

◆ ss_match_thread()

static bool ss_match_thread ( midas_thread_t  tid1,
midas_thread_t  tid2 
)
static

Definition at line 4072 of file system.cxx.

4073{
4074 if (tid1 == 0)
4075 return true;
4076 if (tid1 == tid2)
4077 return true;
4078 return false;
4079}
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 >
stop = ss_millitime();
printf("Operation took %1.3lf seconds\n",(stop-start)/1000.0);
...
DWORD ss_millitime()
Definition system.cxx:3472
Returns
millisecond time stamp.

Definition at line 3472 of file system.cxx.

3473{
3474#ifdef OS_WINNT
3475
3476 return (int) GetTickCount();
3477
3478#endif /* OS_WINNT */
3479#ifdef OS_MSDOS
3480
3481 return clock() * 55;
3482
3483#endif /* OS_MSDOS */
3484#ifdef OS_VMS
3485
3486 {
3487 char time[8];
3488 DWORD lo, hi;
3489
3490 sys$gettim(time);
3491
3492 lo = *((DWORD *) time);
3493 hi = *((DWORD *) (time + 4));
3494
3495/* return *lo / 10000; */
3496
3497 return lo / 10000 + hi * 429496.7296;
3498
3499 }
3500
3501#endif /* OS_VMS */
3502#ifdef OS_UNIX
3503 {
3504 struct timeval tv;
3505
3506 gettimeofday(&tv, NULL);
3507
3508 DWORD m = tv.tv_sec * 1000 + tv.tv_usec / 1000;
3509 //m += 0x137e0000; // adjust milltime for testing 32-bit wrap-around
3510 return m;
3511 }
3512
3513#endif /* OS_UNIX */
3514#ifdef OS_VXWORKS
3515 {
3516 int count;
3517 static int ticks_per_msec = 0;
3518
3519 if (ticks_per_msec == 0)
3520 ticks_per_msec = 1000 / sysClkRateGet();
3521
3522 return tickGet() * ticks_per_msec;
3523 }
3524#endif /* OS_VXWORKS */
3525}
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 3444 of file system.cxx.

3445{
3446 std::lock_guard<std::mutex> lock(gTzMutex);
3447 //defeat mktime() error trap from msystem.h
3448 //#ifdef mktime
3449 //#undef mktime
3450 //#endif
3451 return mktime(tms);
3452}
static std::mutex gTzMutex
Definition system.cxx:3432
Here is the caller graph for this function:

◆ ss_mutex_create()

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

Definition at line 3020 of file system.cxx.

3035{
3036#ifdef OS_VXWORKS
3037
3038 /* semBCreate is a Binary semaphore which is under VxWorks a optimized mutex
3039 refering to the programmer's Guide 5.3.1 */
3040 if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
3041 return SS_NO_MUTEX;
3042 return SS_CREATED;
3043
3044#endif /* OS_VXWORKS */
3045
3046#ifdef OS_WINNT
3047
3048 *mutex = (MUTEX_T *)malloc(sizeof(HANDLE));
3049 **mutex = CreateMutex(NULL, FALSE, NULL);
3050
3051 if (**mutex == 0)
3052 return SS_NO_MUTEX;
3053
3054 return SS_CREATED;
3055
3056#endif /* OS_WINNT */
3057#ifdef OS_UNIX
3058
3059 {
3060 int status;
3061 pthread_mutexattr_t *attr;
3062
3063 attr = (pthread_mutexattr_t*)malloc(sizeof(*attr));
3064 assert(attr);
3065
3066 status = pthread_mutexattr_init(attr);
3067 if (status != 0) {
3068 fprintf(stderr, "ss_mutex_create: pthread_mutexattr_init() returned errno %d (%s)\n", status, strerror(status));
3069 }
3070
3071 if (recursive) {
3072 status = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
3073 if (status != 0) {
3074 fprintf(stderr, "ss_mutex_create: pthread_mutexattr_settype() returned errno %d (%s)\n", status, strerror(status));
3075 }
3076 }
3077
3078 *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
3079 assert(*mutex);
3080
3081 status = pthread_mutex_init(*mutex, attr);
3082 if (status != 0) {
3083 fprintf(stderr, "ss_mutex_create: pthread_mutex_init() returned errno %d (%s), aborting...\n", status, strerror(status));
3084 abort(); // does not return
3085 return SS_NO_MUTEX;
3086 }
3087
3088 free(attr);
3089
3090 if (recursive) {
3091 // test recursive locks
3092
3093 status = pthread_mutex_trylock(*mutex);
3094 assert(status == 0);
3095
3096 status = pthread_mutex_trylock(*mutex);
3097 assert(status == 0); // EBUSY if PTHREAD_MUTEX_RECURSIVE does not work
3098
3099 status = pthread_mutex_unlock(*mutex);
3100 assert(status == 0);
3101
3102 status = pthread_mutex_unlock(*mutex);
3103 assert(status == 0);
3104 }
3105
3106 return SS_SUCCESS;
3107 }
3108#endif /* OS_UNIX */
3109
3110#ifdef OS_MSDOS
3111 return SS_NO_SEMAPHORE;
3112#endif
3113}
#define SS_NO_MUTEX
Definition midas.h:692
#define SS_NO_SEMAPHORE
Definition midas.h:671
#define SS_CREATED
Definition midas.h:665
INT MUTEX_T
Definition midas.h:237
Here is the caller graph for this function:

◆ ss_mutex_delete()

INT EXPRT ss_mutex_delete ( MUTEX_T mutex)

Definition at line 3290 of file system.cxx.

3308{
3309#ifdef OS_WINNT
3310
3311 if (CloseHandle(*mutex) == FALSE)
3312 return SS_NO_SEMAPHORE;
3313
3314 free(mutex);
3315
3316 return SS_SUCCESS;
3317
3318#endif /* OS_WINNT */
3319#ifdef OS_VXWORKS
3320 /* no code for VxWorks destroy yet */
3321 if (semDelete((SEM_ID) mutex_handle) == ERROR)
3322 return SS_NO_MUTEX;
3323 return SS_SUCCESS;
3324#endif /* OS_VXWORKS */
3325
3326#ifdef OS_UNIX
3327 {
3328 int status;
3329
3330 status = pthread_mutex_destroy(mutex);
3331 if (status != 0) {
3332 fprintf(stderr, "ss_mutex_delete: pthread_mutex_destroy() returned errno %d (%s), aborting...\n", status, strerror(status));
3333 abort(); // do not return
3334 return SS_NO_MUTEX;
3335 }
3336
3337 free(mutex);
3338 return SS_SUCCESS;
3339 }
3340#endif /* OS_UNIX */
3341}
Here is the caller graph for this function:

◆ ss_mutex_release()

INT EXPRT ss_mutex_release ( MUTEX_T mutex)

Definition at line 3236 of file system.cxx.

3254{
3255 INT status;
3256
3257#ifdef OS_WINNT
3258
3259 status = ReleaseMutex(*mutex);
3260 if (status == FALSE)
3261 return SS_NO_SEMAPHORE;
3262
3263 return SS_SUCCESS;
3264
3265#endif /* OS_WINNT */
3266#ifdef OS_VXWORKS
3267
3268 if (semGive((SEM_ID) mutes_handle) == ERROR)
3269 return SS_NO_MUTEX;
3270 return SS_SUCCESS;
3271#endif /* OS_VXWORKS */
3272#ifdef OS_UNIX
3273
3274 status = pthread_mutex_unlock(mutex);
3275 if (status != 0) {
3276 fprintf(stderr, "ss_mutex_release: pthread_mutex_unlock() returned error %d (%s), aborting...\n", status, strerror(status));
3277 abort(); // does not return
3278 return SS_NO_MUTEX;
3279 }
3280
3281 return SS_SUCCESS;
3282#endif /* OS_UNIX */
3283
3284#ifdef OS_MSDOS
3285 return SS_NO_MUTEX;
3286#endif
3287}
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 3116 of file system.cxx.

3136{
3137 INT status;
3138
3139#ifdef OS_WINNT
3140
3141 status = WaitForSingleObject(*mutex, timeout == 0 ? INFINITE : timeout);
3142
3143 if (status == WAIT_TIMEOUT) {
3144 return SS_TIMEOUT;
3145 }
3146
3147 if (status == WAIT_FAILED) {
3148 fprintf(stderr, "ss_mutex_wait_for: WaitForSingleObject() failed, status = %d", status);
3149 abort(); // does not return
3150 return SS_NO_MUTEX;
3151 }
3152
3153 return SS_SUCCESS;
3154#endif /* OS_WINNT */
3155#ifdef OS_VXWORKS
3156 /* convert timeout in ticks (1/60) = 1000/60 ~ 1/16 = >>4 */
3157 status = semTake((SEM_ID) mutex, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
3158 if (status == ERROR)
3159 return SS_NO_MUTEX;
3160 return SS_SUCCESS;
3161
3162#endif /* OS_VXWORKS */
3163#if defined(OS_UNIX)
3164
3165#if defined(OS_DARWIN)
3166
3167 if (timeout > 0) {
3168 // emulate pthread_mutex_timedlock under OS_DARWIN
3169 DWORD wait = 0;
3170 while (1) {
3171 status = pthread_mutex_trylock(mutex);
3172 if (status == 0) {
3173 return SS_SUCCESS;
3174 } else if (status == EBUSY) {
3175 ss_sleep(10);
3176 wait += 10;
3177 } else {
3178 fprintf(stderr, "ss_mutex_wait_for: fatal error: pthread_mutex_trylock() returned errno %d (%s), aborting...\n", status, strerror(status));
3179 abort(); // does not return
3180 }
3181 if (wait > timeout) {
3182 fprintf(stderr, "ss_mutex_wait_for: fatal error: timeout waiting for mutex, timeout was %d millisec, aborting...\n", timeout);
3183 abort(); // does not return
3184 }
3185 }
3186 } else {
3187 status = pthread_mutex_lock(mutex);
3188 }
3189
3190 if (status != 0) {
3191 fprintf(stderr, "ss_mutex_wait_for: pthread_mutex_lock() returned errno %d (%s), aborting...\n", status, strerror(status));
3192 abort(); // does not return
3193 }
3194
3195 return SS_SUCCESS;
3196
3197#else // OS_DARWIN
3198 if (timeout > 0) {
3199 extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex, __const struct timespec *__restrict __abstime) __THROW;
3200 struct timespec st;
3201
3202 clock_gettime(CLOCK_REALTIME, &st);
3203 st.tv_sec += timeout / 1000;
3204 st.tv_nsec += (timeout % 1000) * 1000000;
3205 status = pthread_mutex_timedlock(mutex, &st);
3206
3207 if (status == ETIMEDOUT) {
3208 fprintf(stderr, "ss_mutex_wait_for: fatal error: timeout waiting for mutex, timeout was %d millisec, aborting...\n", timeout);
3209 abort();
3210 }
3211
3212 // Make linux timeout do same as MacOS timeout: abort() the program
3213 //if (status == ETIMEDOUT)
3214 // return SS_TIMEOUT;
3215 //return SS_SUCCESS;
3216 } else {
3217 status = pthread_mutex_lock(mutex);
3218 }
3219
3220 if (status != 0) {
3221 fprintf(stderr, "ss_mutex_wait_for: pthread_mutex_lock() returned errno %d (%s), aborting...\n", status, strerror(status));
3222 abort();
3223 }
3224
3225 return SS_SUCCESS;
3226#endif
3227
3228#endif /* OS_UNIX */
3229
3230#ifdef OS_MSDOS
3231 return SS_NO_MUTEX;
3232#endif
3233}
INT ss_sleep(INT millisec)
Definition system.cxx:3707
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 8025 of file system.cxx.

8026{
8027 double nan;
8028
8029 nan = 0;
8030 nan = 0 / nan;
8031 return nan;
8032}
Here is the caller graph for this function:

◆ ss_pid_exists()

BOOL ss_pid_exists ( int  pid)

Definition at line 1442 of file system.cxx.

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

◆ ss_printf()

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

Definition at line 7467 of file system.cxx.

7488{
7489 char str[256];
7490 va_list argptr;
7491
7492 va_start(argptr, format);
7493 vsprintf(str, (char *) format, argptr);
7494 va_end(argptr);
7495
7496#ifdef OS_WINNT
7497 {
7498 HANDLE hConsole;
7499 COORD dwWriteCoord;
7500 DWORD cCharsWritten;
7501
7502 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
7503
7504 dwWriteCoord.X = (short) x;
7505 dwWriteCoord.Y = (short) y;
7506
7507 WriteConsoleOutputCharacter(hConsole, str, strlen(str), dwWriteCoord, &cCharsWritten);
7508 }
7509
7510#endif /* OS_WINNT */
7511
7512#if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7513 printf("\033[%1d;%1dH", y + 1, x + 1);
7514 printf("%s", str);
7515 fflush(stdout);
7516#endif
7517
7518#ifdef OS_MSDOS
7519 gotoxy(x + 1, y + 1);
7520 cputs(str);
7521#endif
7522}
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 5714 of file system.cxx.

5737{
5738 NET_COMMAND_HEADER ncbuf;
5739 size_t n;
5740
5741 /* first receive header */
5742 n = recv_tcp2(sock, (char*)&ncbuf, sizeof(ncbuf), timeout_ms);
5743
5744 if (n == 0) {
5745 cm_msg(MERROR, "ss_recv_net_command", "timeout receiving network command header");
5746 return SS_TIMEOUT;
5747 }
5748
5749 if (n != sizeof(ncbuf)) {
5750 cm_msg(MERROR, "ss_recv_net_command", "error receiving network command header, see messages");
5751 return SS_SOCKET_ERROR;
5752 }
5753
5754 // FIXME: where is the big-endian/little-endian conversion?
5755 *routine_id = ncbuf.routine_id;
5756 *param_size = ncbuf.param_size;
5757
5758 if (*param_size == 0) {
5759 *param_ptr = NULL;
5760 return SS_SUCCESS;
5761 }
5762
5763 *param_ptr = (char *)malloc(*param_size);
5764
5765 if (*param_ptr == NULL) {
5766 cm_msg(MERROR, "ss_recv_net_command", "error allocating %d bytes for network command data", *param_size);
5767 return SS_NO_MEMORY;
5768 }
5769
5770 /* first receive header */
5771 n = recv_tcp2(sock, *param_ptr, *param_size, timeout_ms);
5772
5773 if (n == 0) {
5774 cm_msg(MERROR, "ss_recv_net_command", "timeout receiving network command data");
5775 free(*param_ptr);
5776 *param_ptr = NULL;
5777 return SS_TIMEOUT;
5778 }
5779
5780 if (n != *param_size) {
5781 cm_msg(MERROR, "ss_recv_net_command", "error receiving network command data, see messages");
5782 free(*param_ptr);
5783 *param_ptr = NULL;
5784 return SS_SOCKET_ERROR;
5785 }
5786
5787 return SS_SUCCESS;
5788}
#define SS_NO_MEMORY
Definition midas.h:666
#define SS_SOCKET_ERROR
Definition midas.h:674
INT recv_tcp2(int sock, char *net_buffer, int buffer_size, int timeout_ms)
Definition system.cxx:5641
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 8236 of file system.cxx.

8237{
8238 assert(string);
8239
8240 bool modified = false;
8241
8242 //std::string original = string;
8243
8244 // FIXME: this function over-reads the input array. K.O. May 2021
8245
8246 unsigned char * bytes = (unsigned char *)string;
8247 while(*bytes) {
8248 if( (// ASCII
8249 // use bytes[0] <= 0x7F to allow ASCII control characters
8250 bytes[0] == 0x09 ||
8251 bytes[0] == 0x0A ||
8252 bytes[0] == 0x0D ||
8253 (0x20 <= bytes[0] && bytes[0] <= 0x7E)
8254 )
8255 ) {
8256 bytes += 1;
8257 continue;
8258 }
8259
8260 if( (// non-overlong 2-byte
8261 (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
8262 (0x80 <= bytes[1] && bytes[1] <= 0xBF)
8263 )
8264 ) {
8265 bytes += 2;
8266 continue;
8267 }
8268
8269 if( (// excluding overlongs
8270 bytes[0] == 0xE0 &&
8271 (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
8272 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8273 ) ||
8274 (// straight 3-byte
8275 ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
8276 bytes[0] == 0xEE ||
8277 bytes[0] == 0xEF) &&
8278 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8279 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8280 ) ||
8281 (// excluding surrogates
8282 bytes[0] == 0xED &&
8283 (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
8284 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8285 )
8286 ) {
8287 bytes += 3;
8288 continue;
8289 }
8290
8291 if( (// planes 1-3
8292 bytes[0] == 0xF0 &&
8293 (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
8294 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8295 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8296 ) ||
8297 (// planes 4-15
8298 (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
8299 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8300 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8301 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8302 ) ||
8303 (// plane 16
8304 bytes[0] == 0xF4 &&
8305 (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
8306 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8307 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8308 )
8309 ) {
8310 bytes += 4;
8311 continue;
8312 }
8313
8314 if (bytes[0] == 0) // end of string
8315 break;
8316
8317 bytes[0] = '?';
8318 bytes += 1;
8319
8320 modified = true;
8321 }
8322
8323 //if (modified) {
8324 // printf("ss_repair_utf8(): invalid UTF8 string [%s] changed to [%s]\n", original.c_str(), string);
8325 //} else {
8326 // //printf("ss_repair_utf8(): string [%s] is ok\n", string);
8327 //}
8328
8329 return modified;
8330}
Here is the caller graph for this function:

◆ ss_repair_utf8() [2/2]

bool ss_repair_utf8 ( std::string &  s)

Definition at line 8332 of file system.cxx.

8333{
8334 // C++11 std::string data() is same as c_str(), NUL-terminated.
8335 // C++17 std::string data() is not "const".
8336 // https://en.cppreference.com/w/cpp/string/basic_string/data
8337 return ss_repair_utf8((char*)s.data()); // FIXME: C++17 or newer, do not need to drop the "const". K.O. May 2021
8338}
bool ss_repair_utf8(char *string)
Definition system.cxx:8236
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 2284 of file system.cxx.

2284 {
2285 std::string result;
2286 size_t startPos = 0;
2287 size_t dollarPos;
2288
2289 while ((dollarPos = inputPath.find('$', startPos)) != std::string::npos) {
2290 result.append(inputPath, startPos, dollarPos - startPos);
2291
2292 size_t varEndPos = inputPath.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", dollarPos + 1);
2293 size_t varLength = varEndPos - dollarPos - 1;
2294 std::string varName = inputPath.substr(dollarPos + 1, varLength);
2295
2296 char* varValue = std::getenv(varName.c_str());
2297 if (varValue != nullptr) {
2298 result.append(varValue);
2299 }
2300
2301 startPos = varEndPos;
2302 }
2303
2304 result.append(inputPath.c_str(), startPos, std::string::npos);
2305 return result;
2306}
Here is the caller graph for this function:

◆ ss_resume()

INT ss_resume ( INT  port,
const char *  message 
)

Definition at line 4923 of file system.cxx.

4946{
4947 assert(_ss_suspend_odb);
4948
4949 struct sockaddr_in bind_addr;
4950
4951 memcpy(&bind_addr, &_ss_suspend_odb->bind_addr, sizeof(struct sockaddr_in));
4952 bind_addr.sin_port = htons((short) port);
4953
4954 size_t message_size = strlen(message) + 1;
4955
4956 ssize_t wr = sendto(_ss_suspend_odb->ipc_send_socket, message, message_size, 0, (struct sockaddr *) &bind_addr, sizeof(struct sockaddr_in));
4957
4958 if (wr < 0) {
4959 return SS_SOCKET_ERROR;
4960 }
4961
4962 if (((size_t)wr) != message_size) {
4963 return SS_SOCKET_ERROR;
4964 }
4965
4966 return SS_SUCCESS;
4967}
static SUSPEND_STRUCT * _ss_suspend_odb
Definition system.cxx:4059
#define message(type, str)
struct sockaddr_in bind_addr
Definition system.cxx:4053
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 2532 of file system.cxx.

2561{
2562#ifdef OS_VXWORKS
2563
2564 /* semBCreate is a Binary semaphore which is under VxWorks a optimized mutex
2565 refering to the programmer's Guide 5.3.1 */
2566 if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
2567 return SS_NO_MUTEX;
2568 return SS_CREATED;
2569
2570#endif /* OS_VXWORKS */
2571
2572#ifdef OS_WINNT
2573 std::string semaphore_name;
2574
2575 /* Add a leading MX_ to the semaphore name */
2576 semaphore_name += "MX_";
2577 semaphore_name += name;
2578 //sprintf(semaphore_name, "MX_%s", name);
2579
2580 *semaphore_handle = (HNDLE) CreateMutex(NULL, FALSE, semaphore_name.c_str());
2581
2582 if (*semaphore_handle == 0)
2583 return SS_NO_SEMAPHORE;
2584
2585 return SS_CREATED;
2586
2587#endif /* OS_WINNT */
2588#ifdef OS_VMS
2589 std::string semaphore_name;
2590
2591 /* Add a leading MX_ to the semaphore name */
2592 semaphore_name += "MX_";
2593 semaphore_name += name;
2594 //sprintf(semaphore_name, "MX_%s", name);
2595
2596 /* VMS has to use lock manager... */
2597
2598 {
2599 INT status;
2600 $DESCRIPTOR(semaphorename_dsc, "dummy");
2601 semaphorename_dsc.dsc$w_length = semaphore_name.length();
2602 semaphorename_dsc.dsc$a_pointer = semaphore_name.c_str();
2603
2604 *semaphore_handle = (HNDLE) malloc(8);
2605
2606 status = sys$enqw(0, LCK$K_NLMODE, *semaphore_handle, 0, &semaphorename_dsc, 0, 0, 0, 0, 0, 0);
2607
2608 if (status != SS$_NORMAL) {
2609 free((void *) *semaphore_handle);
2610 *semaphore_handle = 0;
2611 }
2612
2613 if (*semaphore_handle == 0)
2614 return SS_NO_SEMAPHORE;
2615
2616 return SS_CREATED;
2617 }
2618
2619#endif /* OS_VMS */
2620#ifdef OS_UNIX
2621
2622 {
2623 INT key = IPC_PRIVATE;
2624 int status;
2625 struct semid_ds buf;
2626
2627 if (name[0] != 0) {
2628 int fh;
2629 char cwd[256];
2630 std::string file_name;
2631
2632 /* Build the filename out of the path and the name of the semaphore */
2633 std::string path = cm_get_path();
2634 if (path.empty()) {
2635 if (getcwd(cwd, sizeof(cwd)))
2636 path = std::string(cwd);
2637#if defined(OS_VMS)
2638#elif defined(OS_UNIX)
2639 path += "/";
2640#elif defined(OS_WINNT)
2641 path += "\\";
2642#endif
2643 }
2644
2645 file_name = path;
2646 file_name += ".";
2647 file_name += std::string(name);
2648 file_name += ".SHM";
2649
2650 /* create a unique key from the file name */
2651 key = ftok(file_name.c_str(), 'M');
2652 if (key < 0) {
2653 fh = open(file_name.c_str(), O_CREAT, 0644);
2654 close(fh);
2655 key = ftok(file_name.c_str(), 'M');
2657 }
2658 }
2659
2660#if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
2661 union semun arg;
2662#else
2663 union semun {
2664 INT val;
2665 struct semid_ds *buf;
2666 ushort *array;
2667 } arg;
2668#endif
2669
2671
2672 /* create or get semaphore */
2673 *semaphore_handle = (HNDLE) semget(key, 1, 0);
2674 //printf("create1 key 0x%x, id %d, errno %d (%s)\n", key, *semaphore_handle, errno, strerror(errno));
2675 if (*semaphore_handle < 0) {
2676 *semaphore_handle = (HNDLE) semget(key, 1, IPC_CREAT);
2677 //printf("create2 key 0x%x, id %d, errno %d (%s)\n", key, *semaphore_handle, errno, strerror(errno));
2679 }
2680
2681 if (*semaphore_handle < 0) {
2682 cm_msg(MERROR, "ss_semaphore_create", "Cannot create semaphore \'%s\', semget(0x%x) failed, errno %d (%s)", name, key, errno, strerror(errno));
2683
2684 fprintf(stderr, "ss_semaphore_create: Cannot create semaphore \'%s\', semget(0x%x) failed, errno %d (%s)", name, key, errno, strerror(errno));
2685 abort(); // does not return
2686 return SS_NO_SEMAPHORE;
2687 }
2688
2689 memset(&buf, 0, sizeof(buf));
2690 buf.sem_perm.uid = getuid();
2691 buf.sem_perm.gid = getgid();
2692 buf.sem_perm.mode = 0666;
2693 arg.buf = &buf;
2694
2695 semctl(*semaphore_handle, 0, IPC_SET, arg);
2696
2697 /* if semaphore was created, set value to one */
2698 if (key == IPC_PRIVATE || status == SS_CREATED) {
2699 arg.val = 1;
2700 if (semctl(*semaphore_handle, 0, SETVAL, arg) < 0)
2701 return SS_NO_SEMAPHORE;
2702 }
2703
2704 if (s_semaphore_trace) {
2705 fprintf(stderr, "name %d %d %d %s\n", *semaphore_handle, (int)time(NULL), getpid(), name);
2706 }
2707
2708 return SS_SUCCESS;
2709 }
2710#endif /* OS_UNIX */
2711
2712#ifdef OS_MSDOS
2713 return SS_NO_SEMAPHORE;
2714#endif
2715}
static std::atomic_bool s_semaphore_trace
Definition system.cxx:2529
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 2948 of file system.cxx.

2966{
2967#ifdef OS_WINNT
2968
2969 if (CloseHandle((HANDLE) semaphore_handle) == FALSE)
2970 return SS_NO_SEMAPHORE;
2971
2972 return SS_SUCCESS;
2973
2974#endif /* OS_WINNT */
2975#ifdef OS_VMS
2976
2977 free((void *) semaphore_handle);
2978 return SS_SUCCESS;
2979
2980#endif /* OS_VMS */
2981
2982#ifdef OS_VXWORKS
2983 /* no code for VxWorks destroy yet */
2984 if (semDelete((SEM_ID) semaphore_handle) == ERROR)
2985 return SS_NO_SEMAPHORE;
2986 return SS_SUCCESS;
2987#endif /* OS_VXWORKS */
2988
2989#ifdef OS_UNIX
2990#if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
2991 union semun arg;
2992#else
2993 union semun {
2994 INT val;
2995 struct semid_ds *buf;
2996 ushort *array;
2997 } arg;
2998#endif
2999
3000 memset(&arg, 0, sizeof(arg));
3001
3002 if (destroy_flag) {
3003 int status = semctl(semaphore_handle, 0, IPC_RMID, arg);
3004 //printf("semctl(ID=%d, IPC_RMID) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
3005 if (status < 0)
3006 return SS_NO_SEMAPHORE;
3007 }
3008
3009 return SS_SUCCESS;
3010
3011#endif /* OS_UNIX */
3012
3013#ifdef OS_MSDOS
3014 return SS_NO_SEMAPHORE;
3015#endif
3016}
Here is the caller graph for this function:

◆ ss_semaphore_release()

INT EXPRT ss_semaphore_release ( HNDLE  semaphore_handle)

Definition at line 2860 of file system.cxx.

2878{
2879 INT status;
2880
2881#ifdef OS_WINNT
2882
2883 status = ReleaseMutex((HANDLE) semaphore_handle);
2884
2885 if (status == FALSE)
2886 return SS_NO_SEMAPHORE;
2887
2888 return SS_SUCCESS;
2889
2890#endif /* OS_WINNT */
2891#ifdef OS_VMS
2892
2893 status = sys$enqw(0, LCK$K_NLMODE, semaphore_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
2894
2895 if (status != SS$_NORMAL)
2896 return SS_NO_SEMAPHORE;
2897
2898 return SS_SUCCESS;
2899
2900#endif /* OS_VMS */
2901
2902#ifdef OS_VXWORKS
2903
2904 if (semGive((SEM_ID) semaphore_handle) == ERROR)
2905 return SS_NO_SEMAPHORE;
2906 return SS_SUCCESS;
2907#endif /* OS_VXWORKS */
2908
2909#ifdef OS_UNIX
2910 {
2911 struct sembuf sb;
2912
2913 sb.sem_num = 0;
2914 sb.sem_op = 1; /* increment semaphore */
2915 sb.sem_flg = SEM_UNDO;
2916
2917 if (s_semaphore_trace) {
2918 fprintf(stderr, "unlock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int(s_semaphore_nest_level));
2919 assert(s_semaphore_nest_level > 0);
2921 }
2922
2923 do {
2924 status = semop(semaphore_handle, &sb, 1);
2925
2926 /* return on success */
2927 if (status == 0)
2928 break;
2929
2930 /* retry if interrupted by a ss_wake signal */
2931 if (errno == EINTR)
2932 continue;
2933
2934 fprintf(stderr, "ss_semaphore_release: semop/semtimedop(%d) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
2935 return SS_NO_SEMAPHORE;
2936 } while (1);
2937
2938 return SS_SUCCESS;
2939 }
2940#endif /* OS_UNIX */
2941
2942#ifdef OS_MSDOS
2943 return SS_NO_SEMAPHORE;
2944#endif
2945}
static std::atomic_int s_semaphore_nest_level
Definition system.cxx:2530
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 2718 of file system.cxx.

2738{
2739 INT status;
2740
2741#ifdef OS_WINNT
2742
2743 status = WaitForSingleObject((HANDLE) semaphore_handle, timeout_millisec == 0 ? INFINITE : timeout_millisec);
2744 if (status == WAIT_FAILED)
2745 return SS_NO_SEMAPHORE;
2746 if (status == WAIT_TIMEOUT)
2747 return SS_TIMEOUT;
2748
2749 return SS_SUCCESS;
2750#endif /* OS_WINNT */
2751#ifdef OS_VMS
2752 status = sys$enqw(0, LCK$K_EXMODE, semaphore_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
2753 if (status != SS$_NORMAL)
2754 return SS_NO_SEMAPHORE;
2755 return SS_SUCCESS;
2756
2757#endif /* OS_VMS */
2758#ifdef OS_VXWORKS
2759 /* convert timeout in ticks (1/60) = 1000/60 ~ 1/16 = >>4 */
2760 status = semTake((SEM_ID) semaphore_handle, timeout_millisec == 0 ? WAIT_FOREVER : timeout_millisec >> 4);
2761 if (status == ERROR)
2762 return SS_NO_SEMAPHORE;
2763 return SS_SUCCESS;
2764
2765#endif /* OS_VXWORKS */
2766#ifdef OS_UNIX
2767 {
2768 struct sembuf sb;
2769
2770#if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
2771 union semun arg;
2772#else
2773 union semun {
2774 INT val;
2775 struct semid_ds *buf;
2776 ushort *array;
2777 } arg;
2778#endif
2779
2780 sb.sem_num = 0;
2781 sb.sem_op = -1; /* decrement semaphore */
2782 sb.sem_flg = SEM_UNDO;
2783
2784 memset(&arg, 0, sizeof(arg));
2785
2786 DWORD start_time = ss_millitime();
2787
2788 if (s_semaphore_trace) {
2789 fprintf(stderr, "waitlock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int(s_semaphore_nest_level));
2790 }
2791
2792 do {
2793#if defined(OS_DARWIN)
2794 status = semop(semaphore_handle, &sb, 1);
2795#elif defined(OS_LINUX)
2796 struct timespec ts;
2797 if (timeout_millisec >= 1000 || timeout_millisec == 0) {
2798 ts.tv_sec = 1;
2799 ts.tv_nsec = 0;
2800 } else {
2801 ts.tv_sec = 0;
2802 ts.tv_nsec = (timeout_millisec+10)*1000*1000;
2803 }
2804
2805 status = semtimedop(semaphore_handle, &sb, 1, &ts);
2806#else
2807 status = semop(semaphore_handle, &sb, 1);
2808#endif
2809
2810 /* return on success */
2811 if (status == 0) {
2812 //DWORD milli_now = ss_millitime();
2813 //DWORD dt = milli_now - start_time;
2814 //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);
2815 //ss_sleep(100);
2816 break;
2817 }
2818
2819 /* retry if interrupted by a ss_wake signal */
2820 if (errno == EINTR || errno == EAGAIN) {
2821 //if (1) {
2822 // DWORD milli_now = ss_millitime();
2823 // DWORD dt = milli_now - start_time;
2824 // 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);
2825 // abort();
2826 //}
2827
2828 /* return if timeout expired */
2829 if (timeout_millisec > 0) {
2830 DWORD milli_now = ss_millitime();
2831 DWORD dt = milli_now - start_time;
2832 if (dt > timeout_millisec) {
2833 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);
2834 return SS_TIMEOUT;
2835 }
2836 }
2837
2838 continue;
2839 }
2840
2841 fprintf(stderr, "ss_semaphore_wait_for: semop/semtimedop(%d) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
2842 return SS_NO_SEMAPHORE;
2843 } while (1);
2844
2845 if (s_semaphore_trace) {
2847 fprintf(stderr, "lock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int( s_semaphore_nest_level));
2848 }
2849
2850 return SS_SUCCESS;
2851 }
2852#endif /* OS_UNIX */
2853
2854#ifdef OS_MSDOS
2855 return SS_NO_SEMAPHORE;
2856#endif
2857}
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 7434 of file system.cxx.

7451{
7452#ifdef OS_WINNT
7453
7454 HANDLE hConsole;
7455 COORD coordSize;
7456
7457 coordSize.X = (short) x;
7458 coordSize.Y = (short) y;
7459 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
7460 SetConsoleScreenBufferSize(hConsole, coordSize);
7461
7462#else /* OS_WINNT */
7463#endif
7464}

◆ ss_settime()

DWORD EXPRT ss_settime ( DWORD  seconds)

Definition at line 3554 of file system.cxx.

3570{
3571#if defined(OS_WINNT)
3572 SYSTEMTIME st;
3573 struct tm ltm;
3574
3575 ss_tzset();
3576 localtime_r((time_t *) & seconds, &ltm);
3577
3578 st.wYear = ltm.tm_year + 1900;
3579 st.wMonth = ltm.tm_mon + 1;
3580 st.wDay = ltm.tm_mday;
3581 st.wHour = ltm.tm_hour;
3582 st.wMinute = ltm.tm_min;
3583 st.wSecond = ltm.tm_sec;
3584 st.wMilliseconds = 0;
3585
3586 SetLocalTime(&st);
3587
3588#elif defined(OS_DARWIN) && defined(CLOCK_REALTIME)
3589
3590 struct timespec ltm;
3591
3592 ltm.tv_sec = seconds;
3593 ltm.tv_nsec = 0;
3594 clock_settime(CLOCK_REALTIME, &ltm);
3595
3596#elif defined(OS_CYGWIN) && defined(CLOCK_REALTIME)
3597
3598 struct timespec ltm;
3599
3600 ltm.tv_sec = seconds;
3601 ltm.tv_nsec = 0;
3602 clock_settime(CLOCK_REALTIME, &ltm);
3603 return SS_NO_DRIVER;
3604
3605#elif defined(OS_UNIX) && defined(CLOCK_REALTIME)
3606
3607 struct timespec ltm;
3608
3609 ltm.tv_sec = seconds;
3610 ltm.tv_nsec = 0;
3611 clock_settime(CLOCK_REALTIME, &ltm);
3612
3613#elif defined(OS_VXWORKS)
3614
3615 struct timespec ltm;
3616
3617 ltm.tv_sec = seconds;
3618 ltm.tv_nsec = 0;
3619 clock_settime(CLOCK_REALTIME, &ltm);
3620
3621#else
3622#warning ss_settime() is not supported!
3623#endif
3624 return SS_SUCCESS;
3625}
#define SS_NO_DRIVER
Definition midas.h:684
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 1832 of file system.cxx.

1849{
1850#ifdef OS_WINNT
1851
1852 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
1853 hChildStdoutRd, hChildStdoutWr, hChildStderrRd, hChildStderrWr, hSaveStdin, hSaveStdout, hSaveStderr;
1854
1855 SECURITY_ATTRIBUTES saAttr;
1856 PROCESS_INFORMATION piProcInfo;
1857 STARTUPINFO siStartInfo;
1858 char buffer[256], cmd[256];
1859 DWORD dwRead, dwWritten, dwAvail, i, i_cmd;
1860 fd_set readfds;
1861 struct timeval timeout;
1862
1863 /* Set the bInheritHandle flag so pipe handles are inherited. */
1864 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
1865 saAttr.bInheritHandle = TRUE;
1866 saAttr.lpSecurityDescriptor = NULL;
1867
1868 /* Save the handle to the current STDOUT. */
1869 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
1870
1871 /* Create a pipe for the child's STDOUT. */
1872 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
1873 return 0;
1874
1875 /* Set a write handle to the pipe to be STDOUT. */
1876 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
1877 return 0;
1878
1879
1880 /* Save the handle to the current STDERR. */
1881 hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
1882
1883 /* Create a pipe for the child's STDERR. */
1884 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
1885 return 0;
1886
1887 /* Set a read handle to the pipe to be STDERR. */
1888 if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
1889 return 0;
1890
1891
1892 /* Save the handle to the current STDIN. */
1893 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
1894
1895 /* Create a pipe for the child's STDIN. */
1896 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
1897 return 0;
1898
1899 /* Set a read handle to the pipe to be STDIN. */
1900 if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
1901 return 0;
1902
1903 /* Duplicate the write handle to the pipe so it is not inherited. */
1904 if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, /* not inherited */
1905 DUPLICATE_SAME_ACCESS))
1906 return 0;
1907
1908 CloseHandle(hChildStdinWr);
1909
1910 /* Now create the child process. */
1911 memset(&siStartInfo, 0, sizeof(siStartInfo));
1912 siStartInfo.cb = sizeof(STARTUPINFO);
1913 siStartInfo.lpReserved = NULL;
1914 siStartInfo.lpReserved2 = NULL;
1915 siStartInfo.cbReserved2 = 0;
1916 siStartInfo.lpDesktop = NULL;
1917 siStartInfo.dwFlags = 0;
1918
1919 if (!CreateProcess(NULL, "cmd /Q", /* command line */
1920 NULL, /* process security attributes */
1921 NULL, /* primary thread security attributes */
1922 TRUE, /* handles are inherited */
1923 0, /* creation flags */
1924 NULL, /* use parent's environment */
1925 NULL, /* use parent's current directory */
1926 &siStartInfo, /* STARTUPINFO pointer */
1927 &piProcInfo)) /* receives PROCESS_INFORMATION */
1928 return 0;
1929
1930 /* After process creation, restore the saved STDIN and STDOUT. */
1931 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
1932 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
1933 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
1934
1935 i_cmd = 0;
1936
1937 do {
1938 /* query stderr */
1939 do {
1940 if (!PeekNamedPipe(hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
1941 break;
1942
1943 if (dwRead > 0) {
1944 ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
1945 send(sock, buffer, dwRead, 0);
1946 }
1947 } while (dwAvail > 0);
1948
1949 /* query stdout */
1950 do {
1951 if (!PeekNamedPipe(hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
1952 break;
1953 if (dwRead > 0) {
1954 ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
1955 send(sock, buffer, dwRead, 0);
1956 }
1957 } while (dwAvail > 0);
1958
1959
1960 /* check if subprocess still alive */
1961 if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
1962 break;
1963 if (i != STILL_ACTIVE)
1964 break;
1965
1966 /* query network socket */
1967 FD_ZERO(&readfds);
1968 FD_SET(sock, &readfds);
1969 timeout.tv_sec = 0;
1970 timeout.tv_usec = 100;
1971 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
1972
1973 if (FD_ISSET(sock, &readfds)) {
1974 i = recv(sock, cmd + i_cmd, 1, 0);
1975 if (i <= 0)
1976 break;
1977
1978 /* backspace */
1979 if (cmd[i_cmd] == 8) {
1980 if (i_cmd > 0) {
1981 send(sock, "\b \b", 3, 0);
1982 i_cmd -= 1;
1983 }
1984 } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
1985 send(sock, cmd + i_cmd, 1, 0);
1986 i_cmd += i;
1987 }
1988 }
1989
1990 /* linefeed triggers new command */
1991 if (cmd[i_cmd - 1] == 10) {
1992 WriteFile(hChildStdinWrDup, cmd, i_cmd, &dwWritten, NULL);
1993 i_cmd = 0;
1994 }
1995
1996 } while (TRUE);
1997
1998 CloseHandle(hChildStdinWrDup);
1999 CloseHandle(hChildStdinRd);
2000 CloseHandle(hChildStderrRd);
2001 CloseHandle(hChildStdoutRd);
2002
2003 return SS_SUCCESS;
2004
2005#endif /* OS_WINNT */
2006
2007#ifdef OS_UNIX
2008#ifndef NO_PTY
2009 pid_t pid;
2010 int i, p;
2011 char line[32], buffer[1024], shell[32];
2012 fd_set readfds;
2013
2014#ifdef NO_FORK
2015 assert(!"support for forkpty() disabled by NO_FORK");
2016#else
2017 pid = forkpty(&p, line, NULL, NULL);
2018#endif
2019 if (pid < 0)
2020 return 0;
2021 else if (pid > 0) {
2022 /* parent process */
2023
2024 do {
2025 FD_ZERO(&readfds);
2026 FD_SET(sock, &readfds);
2027 FD_SET(p, &readfds);
2028
2029 select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
2030
2031 if (FD_ISSET(sock, &readfds)) {
2032 memset(buffer, 0, sizeof(buffer));
2033 i = recv(sock, buffer, sizeof(buffer), 0);
2034 if (i <= 0)
2035 break;
2036 if (write(p, buffer, i) != i)
2037 break;
2038 }
2039
2040 if (FD_ISSET(p, &readfds)) {
2041 memset(buffer, 0, sizeof(buffer));
2042 i = read(p, buffer, sizeof(buffer));
2043 if (i <= 0)
2044 break;
2045 send(sock, buffer, i, 0);
2046 }
2047
2048 } while (1);
2049 } else {
2050 /* child process */
2051
2052 if (getenv("SHELL"))
2053 mstrlcpy(shell, getenv("SHELL"), sizeof(shell));
2054 else
2055 strcpy(shell, "/bin/sh");
2056 int error = execl(shell, shell, NULL);
2057 // NB: execl() does not return unless there is an error.
2058 fprintf(stderr, "ss_shell: Cannot execute command \"%s\": execl() returned %d, errno %d (%s), aborting!\n", shell, error, errno, strerror(errno));
2059 abort();
2060 }
2061#else
2062 send(sock, "not implemented\n", 17, 0);
2063#endif /* NO_PTY */
2064
2065 return SS_SUCCESS;
2066
2067#endif /* OS_UNIX */
2068}
#define FD_SETSIZE
Definition msystem.h:206

◆ ss_shm_close()

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

Definition at line 757 of file system.cxx.

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

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

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

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

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

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

1026{
1027 if (shm_trace)
1028 printf("ss_shm_protect() handle %d, adr %p, size %.0f\n", handle, adr, (double)shm_size);
1029
1030#ifdef OS_WINNT
1031
1032 if (!UnmapViewOfFile(adr))
1033 return SS_INVALID_ADDRESS;
1034
1035#endif /* OS_WINNT */
1036#ifdef OS_UNIX
1037
1038 if (use_sysv_shm) {
1039
1040 if (shmdt(adr) < 0) {
1041 cm_msg(MERROR, "ss_shm_protect", "shmdt() failed");
1042 return SS_INVALID_ADDRESS;
1043 }
1044 }
1045
1046 if (use_mmap_shm || use_posix_shm) {
1047 assert(shm_size > 0);
1048
1049 int ret = mprotect(adr, shm_size, PROT_NONE);
1050 if (ret != 0) {
1051 cm_msg(MERROR, "ss_shm_protect", "Cannot mprotect(PROT_NONE): return value %d, errno %d (%s)", ret, errno, strerror(errno));
1052 return SS_INVALID_ADDRESS;
1053 }
1054 }
1055
1056#endif // OS_UNIX
1057
1058 return SS_SUCCESS;
1059}
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 1062 of file system.cxx.

1083{
1084 if (shm_trace)
1085 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);
1086
1087#ifdef OS_WINNT
1088
1089 *adr = MapViewOfFile((HANDLE) handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
1090
1091 if (*adr == NULL) {
1092 cm_msg(MERROR, "ss_shm_unprotect", "MapViewOfFile() failed");
1093 return SS_NO_MEMORY;
1094 }
1095#endif /* OS_WINNT */
1096#ifdef OS_UNIX
1097
1098 if (use_sysv_shm) {
1099
1100 *adr = shmat(handle, 0, 0);
1101
1102 if ((*adr) == (void *) (-1)) {
1103 cm_msg(MERROR, "ss_shm_unprotect", "shmat() failed, errno = %d", errno);
1104 return SS_NO_MEMORY;
1105 }
1106 }
1107
1108 if (use_mmap_shm || use_posix_shm) {
1109 assert(shm_size > 0);
1110
1111 int mode = 0;
1112 if (read)
1113 mode |= PROT_READ;
1114 if (write)
1115 mode |= PROT_READ | PROT_WRITE;
1116
1117 int ret = mprotect(*adr, shm_size, mode);
1118 if (ret != 0) {
1119 cm_msg(MERROR, "ss_shm_unprotect", "Cannot mprotect(%d): return value %d, errno %d (%s)", mode, ret, errno, strerror(errno));
1120 return SS_INVALID_ADDRESS;
1121 }
1122 }
1123
1124#endif // OS_UNIX
1125
1126 return SS_SUCCESS;
1127}
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 3707 of file system.cxx.

3708{
3709 if (millisec == 0) {
3710#ifdef OS_WINNT
3711 SuspendThread(GetCurrentThread());
3712#endif
3713#ifdef OS_VMS
3714 sys$hiber();
3715#endif
3716#ifdef OS_UNIX
3717 signal(SIGCONT, ss_cont);
3718 pause();
3719#endif
3720 return SS_SUCCESS;
3721 }
3722#ifdef OS_WINNT
3723 Sleep(millisec);
3724#endif
3725#ifdef OS_UNIX
3726 struct timespec ts;
3727 int status;
3728
3729 ts.tv_sec = millisec / 1000;
3730 ts.tv_nsec = (millisec % 1000) * 1E6;
3731
3732 do {
3733 status = nanosleep(&ts, &ts);
3734 if ((int)ts.tv_sec < 0)
3735 break; // can be negative under OSX
3736 } while (status == -1 && errno == EINTR);
3737#endif
3738
3739 return SS_SUCCESS;
3740}
Here is the caller graph for this function:

◆ ss_socket_check()

static int ss_socket_check ( int  sock)
static

Definition at line 4572 of file system.cxx.

4573{
4574 // copied from the old rpc_server_receive()
4575
4576 /* only check if TCP connection is broken */
4577
4578 char test_buffer[256];
4579#ifdef OS_WINNT
4580 int n_received = recv(sock, test_buffer, sizeof(test_buffer), MSG_PEEK);
4581#else
4582 int n_received = recv(sock, test_buffer, sizeof(test_buffer), MSG_PEEK | MSG_DONTWAIT);
4583
4584 /* check if we caught a signal */
4585 if ((n_received == -1) && (errno == EAGAIN))
4586 return SS_SUCCESS;
4587#endif
4588
4589 if (n_received == -1) {
4590 cm_msg(MERROR, "ss_socket_check", "recv(%d,MSG_PEEK) returned %d, errno: %d (%s)", (int) sizeof(test_buffer), n_received, errno, strerror(errno));
4591 }
4592
4593 if (n_received <= 0)
4594 return SS_ABORT;
4595
4596 return SS_SUCCESS;
4597}
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 5310 of file system.cxx.

5311{
5312 assert(sockp != NULL);
5313 if (gSocketTrace) {
5314 fprintf(stderr, "ss_socket_close: %d\n", *sockp);
5315 }
5316 int err = close(*sockp);
5317 if (err) {
5318 cm_msg(MERROR, "ss_socket_close", "unexpected error, close() returned %d, errno: %d (%s)", err, errno, strerror(errno));
5319 }
5320 *sockp = 0;
5321 return SS_SUCCESS;
5322}
static bool gSocketTrace
Definition system.cxx:5043
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 5046 of file system.cxx.

5047{
5048 assert(sockp != NULL);
5049 assert(error_msg_p != NULL);
5050 *sockp = 0;
5051
5052#ifdef OS_WINNT
5053 {
5054 WSADATA WSAData;
5055
5056 /* Start windows sockets */
5057 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
5058 return RPC_NET_ERROR;
5059 }
5060#endif
5061
5062 char portname[256];
5063 sprintf(portname, "%d", tcp_port);
5064
5065 struct addrinfo *ainfo = NULL;
5066
5067 int status = getaddrinfo(hostname, portname, NULL, &ainfo);
5068
5069 if (status != 0) {
5070 *error_msg_p = msprintf("cannot resolve hostname \"%s\", getaddrinfo() error %d (%s)", hostname, status, gai_strerror(status));
5071 if (ainfo)
5072 freeaddrinfo(ainfo);
5073 return RPC_NET_ERROR;
5074 }
5075
5076 // NOTE: ainfo must be freeed using freeaddrinfo(ainfo);
5077
5078 int sock = 0;
5079
5080 for (const struct addrinfo *r = ainfo; r != NULL; r = r->ai_next) {
5081 if (gSocketTrace) {
5082 fprintf(stderr, "ss_socket_connect_tcp: hostname [%s] port %d addrinfo: flags %d, family %d, socktype %d, protocol %d, canonname [%s]\n",
5083 hostname,
5084 tcp_port,
5085 r->ai_flags,
5086 r->ai_family,
5087 r->ai_socktype,
5088 r->ai_protocol,
5089 r->ai_canonname);
5090 }
5091
5092 // skip anything but TCP addresses
5093 if (r->ai_socktype != SOCK_STREAM) {
5094 continue;
5095 }
5096
5097 // skip anything but TCP protocol 6
5098 if (r->ai_protocol != 6) {
5099 continue;
5100 }
5101
5102 sock = ::socket(r->ai_family, r->ai_socktype, 0);
5103
5104 if (sock <= 0) {
5105 *error_msg_p = msprintf("cannot create socket, errno %d (%s)", errno, strerror(errno));
5106 continue;
5107 }
5108
5109 status = ::connect(sock, r->ai_addr, r->ai_addrlen);
5110 if (status != 0) {
5111 if (gSocketTrace) {
5112 fprintf(stderr, "ss_socket_connect_tcp: connect() status %d, errno %d (%s)\n", status, errno, strerror(errno));
5113 }
5114 *error_msg_p = msprintf("cannot connect to host \"%s\" port %d, errno %d (%s)", hostname, tcp_port, errno, strerror(errno));
5115 ::close(sock);
5116 sock = 0;
5117 continue;
5118 }
5119 // successfully connected
5120 break;
5121 }
5122
5123 freeaddrinfo(ainfo);
5124 ainfo = NULL;
5125
5126 if (sock == 0) {
5127 // error_msg is already set
5128 return RPC_NET_ERROR;
5129 }
5130
5131 *sockp = sock;
5132
5133 if (gSocketTrace) {
5134 fprintf(stderr, "ss_socket_connect_tcp: hostname [%s] port %d new socket %d\n", hostname, tcp_port, *sockp);
5135 }
5136
5137 return SS_SUCCESS;
5138}
#define RPC_NET_ERROR
Definition midas.h:702
std::string msprintf(const char *format,...)
Definition midas.cxx:419
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 5325 of file system.cxx.

5326{
5327 char addr[64];
5328
5329 unsigned size = sizeof(addr);
5330 int rv = getpeername(sock, (struct sockaddr *) &addr, &size);
5331
5332 //printf("getpeername() returned %d, size %d, buffer %d\n", rv, size, (int)sizeof(addr));
5333
5334 if (rv != 0) {
5335 cm_msg(MERROR, "ss_socket_get_peer_name", "Error: getpeername() returned %d, errno %d (%s)", rv, errno, strerror(errno));
5336 return SS_SOCKET_ERROR;
5337 }
5338
5339 char hostname[256];
5340 char servname[16];
5341
5342 int ret = getnameinfo((struct sockaddr*)&addr, size,
5343 hostname, sizeof(hostname),
5344 servname, sizeof(servname),
5345 NI_NUMERICSERV);
5346
5347 if (ret != 0) {
5348 cm_msg(MERROR, "ss_socket_get_peer_name", "Error: getnameinfo() error %d (%s)", ret, gai_strerror(ret));
5349 return SS_SOCKET_ERROR;
5350 }
5351
5352 //printf("getnameinfo() returned %d, hostname [%s], servname[%s]\n", ret, hostname, servname);
5353
5354 if (hostp)
5355 *hostp = hostname;
5356
5357 if (portp)
5358 *portp = atoi(servname);
5359
5360 return SS_SUCCESS;
5361}
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 5141 of file system.cxx.

5142{
5143 assert(sockp != NULL);
5144 assert(tcp_port_p != NULL);
5145 assert(error_msg_p != NULL);
5146
5147 *sockp = 0;
5148 *tcp_port_p = 0;
5149
5150#ifdef OS_WINNT
5151 {
5152 WSADATA WSAData;
5153
5154 /* Start windows sockets */
5155 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
5156 return RPC_NET_ERROR;
5157 }
5158#endif
5159
5160#ifdef AF_INET6
5161 bool use_inet6 = true;
5162#else
5163 bool use_inet6 = false;
5164#endif
5165
5166 if (listen_localhost)
5167 use_inet6 = false;
5168
5169 /* create a socket for listening */
5170 int lsock;
5171 if (use_inet6) {
5172#ifdef AF_INET6
5173 lsock = socket(AF_INET6, SOCK_STREAM, 0);
5174 if (lsock == -1) {
5175 if (errno == EAFNOSUPPORT) {
5176 use_inet6 = false;
5177 lsock = socket(AF_INET, SOCK_STREAM, 0);
5178 }
5179 }
5180#endif
5181 } else {
5182 lsock = socket(AF_INET, SOCK_STREAM, 0);
5183 }
5184
5185 if (lsock == -1) {
5186 *error_msg_p = msprintf("socket(AF_INET, SOCK_STREAM) failed, errno %d (%s)", errno, strerror(errno));
5187 return RPC_NET_ERROR;
5188 }
5189
5190 /* reuse address, needed if previous server stopped (30s timeout!) */
5191 int flag = 1;
5192 int status = setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof(int));
5193 if (status < 0) {
5194 *error_msg_p = msprintf("setsockopt(SO_REUSEADDR) failed, errno %d (%s)", errno, strerror(errno));
5195 return RPC_NET_ERROR;
5196 }
5197
5198#ifdef AF_INET6
5199#ifdef IPV6_V6ONLY
5200 if (use_inet6) {
5201 /* turn off IPV6_V6ONLY, see RFC 3493 */
5202 flag = 0;
5203 status = setsockopt(lsock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flag, sizeof(int));
5204 if (status < 0) {
5205 *error_msg_p = msprintf("setsockopt(IPPROTO_IPV6, IPV6_V6ONLY) failed, errno %d (%s)", errno, strerror(errno));
5206 return RPC_NET_ERROR;
5207 }
5208 }
5209#else
5210#warning strange: AF_INET6 is defined, but IPV6_V6ONLY is not defined
5211#endif
5212#endif
5213
5214 if (use_inet6) {
5215#ifdef AF_INET6
5216 /* bind local node name and port to socket */
5217 struct sockaddr_in6 bind_addr6;
5218 memset(&bind_addr6, 0, sizeof(bind_addr6));
5219 bind_addr6.sin6_family = AF_INET6;
5220
5221 if (listen_localhost) {
5222 bind_addr6.sin6_addr = in6addr_loopback;
5223 } else {
5224 bind_addr6.sin6_addr = in6addr_any;
5225 }
5226
5227 if (tcp_port)
5228 bind_addr6.sin6_port = htons((short) tcp_port);
5229 else
5230 bind_addr6.sin6_port = htons(0); // OS will allocate a port number for us
5231
5232 status = bind(lsock, (struct sockaddr *) &bind_addr6, sizeof(bind_addr6));
5233 if (status < 0) {
5234 *error_msg_p = msprintf("IPv6 bind() to port %d failed, errno %d (%s)", tcp_port, errno, strerror(errno));
5235 return RPC_NET_ERROR;
5236 }
5237#endif
5238 } else {
5239 /* bind local node name and port to socket */
5240 struct sockaddr_in bind_addr;
5241 memset(&bind_addr, 0, sizeof(bind_addr));
5242 bind_addr.sin_family = AF_INET;
5243
5244 if (listen_localhost) {
5245 bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
5246 } else {
5247 bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
5248 }
5249
5250 if (tcp_port)
5251 bind_addr.sin_port = htons((short) tcp_port);
5252 else
5253 bind_addr.sin_port = htons(0); // OS will allocate a port number for us
5254
5255 status = bind(lsock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
5256 if (status < 0) {
5257 *error_msg_p = msprintf("bind() to port %d failed, errno %d (%s)", tcp_port, errno, strerror(errno));
5258 return RPC_NET_ERROR;
5259 }
5260 }
5261
5262 /* listen for connection */
5263#ifdef OS_MSDOS
5264 status = listen(lsock, 1);
5265#else
5266 status = listen(lsock, SOMAXCONN);
5267#endif
5268 if (status < 0) {
5269 *error_msg_p = msprintf("listen() failed, errno %d (%s)", errno, strerror(errno));
5270 return RPC_NET_ERROR;
5271 }
5272
5273 if (use_inet6) {
5274#ifdef AF_INET6
5275 struct sockaddr_in6 addr;
5276 socklen_t sosize = sizeof(addr);
5277 status = getsockname(lsock, (struct sockaddr*)&addr, &sosize);
5278 if (status < 0) {
5279 *error_msg_p = msprintf("IPv6 getsockname() failed, errno %d (%s)", errno, strerror(errno));
5280 return RPC_NET_ERROR;
5281 }
5282
5283 *tcp_port_p = ntohs(addr.sin6_port);
5284#endif
5285 } else {
5286 struct sockaddr_in addr;
5287 socklen_t sosize = sizeof(addr);
5288 status = getsockname(lsock, (struct sockaddr*)&addr, &sosize);
5289 if (status < 0) {
5290 *error_msg_p = msprintf("getsockname() failed, errno %d (%s)", errno, strerror(errno));
5291 return RPC_NET_ERROR;
5292 }
5293
5294 *tcp_port_p = ntohs(addr.sin_port);
5295 }
5296
5297 *sockp = lsock;
5298
5299 if (gSocketTrace) {
5300 if (listen_localhost)
5301 fprintf(stderr, "ss_socket_listen_tcp: listening tcp port %d local connections only, new socket %d\n", *tcp_port_p, *sockp);
5302 else
5303 fprintf(stderr, "ss_socket_listen_tcp: listening tcp port %d all internet connections, socket %d\n", *tcp_port_p, *sockp);
5304 }
5305
5306 return SS_SUCCESS;
5307}
#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 4977 of file system.cxx.

4994{
4995 INT status;
4996 fd_set readfds;
4997 struct timeval timeout;
4998 struct timeval timeout0;
4999 DWORD start_time = 0; // start_time is only used for BSD select() behaviour (MacOS)
5000 DWORD end_time = 0;
5001
5002 FD_ZERO(&readfds);
5003 FD_SET(sock, &readfds);
5004
5005 timeout.tv_sec = millisec / 1000;
5006 timeout.tv_usec = (millisec % 1000) * 1000;
5007
5008 timeout0 = timeout;
5009
5010 while (1) {
5011 status = select(sock+1, &readfds, NULL, NULL, &timeout);
5012 //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));
5013
5014#ifndef OS_WINNT
5015 if (status<0 && errno==EINTR) { /* watchdog alarm signal */
5016 /* need to determine if select() updates "timeout" (Linux) or keeps original value (BSD) */
5017 if (timeout.tv_sec == timeout0.tv_sec) {
5018 DWORD now = ss_time();
5019 if (start_time == 0) {
5020 start_time = now;
5021 end_time = start_time + (millisec+999)/1000;
5022 }
5023 //printf("ss_socket_wait: EINTR: now %d, timeout %d, wait time %d\n", now, end_time, end_time - now);
5024 if (now > end_time)
5025 return SS_TIMEOUT;
5026 }
5027 continue;
5028 }
5029#endif
5030 if (status < 0) { /* select() syscall error */
5031 cm_msg(MERROR, "ss_socket_wait", "unexpected error, select() returned %d, errno: %d (%s)", status, errno, strerror(errno));
5032 return SS_SOCKET_ERROR;
5033 }
5034 if (status == 0) /* timeout */
5035 return SS_TIMEOUT;
5036 if (!FD_ISSET(sock, &readfds))
5037 return SS_TIMEOUT;
5038 return SS_SUCCESS;
5039 }
5040 /* NOT REACHED */
5041}
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 1702 of file system.cxx.

1725{
1726#ifdef OS_WINNT
1727
1728 if (spawnvp(mode, cmdname, argv) < 0)
1729 return SS_INVALID_NAME;
1730
1731 return SS_SUCCESS;
1732
1733#endif /* OS_WINNT */
1734
1735#ifdef OS_MSDOS
1736
1737 spawnvp((int) mode, cmdname, argv);
1738
1739 return SS_SUCCESS;
1740
1741#endif /* OS_MSDOS */
1742
1743#ifdef OS_VMS
1744
1745 {
1746 char cmdstring[500], *pc;
1747 INT i, flags, status;
1748 va_list argptr;
1749
1750 $DESCRIPTOR(cmdstring_dsc, "dummy");
1751
1752 if (mode & P_DETACH) {
1753 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
1754 cmdstring_dsc.dsc$a_pointer = cmdstring;
1755
1756 status = sys$creprc(0, &cmdstring_dsc, 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
1757 } else {
1758 flags = (mode & P_NOWAIT) ? 1 : 0;
1759
1760 for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0]; pc--);
1761 if (*pc == ']')
1762 pc++;
1763
1764 strcpy(cmdstring, pc);
1765
1766 if (strchr(cmdstring, ';'))
1767 *strchr(cmdstring, ';') = 0;
1768
1769 strcat(cmdstring, " ");
1770
1771 for (i = 1; argv[i] != NULL; i++) {
1772 strcat(cmdstring, argv[i]);
1773 strcat(cmdstring, " ");
1774 }
1775
1776 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
1777 cmdstring_dsc.dsc$a_pointer = cmdstring;
1778
1779 status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
1780 }
1781
1782 return BM_SUCCESS;
1783 }
1784
1785#endif /* OS_VMS */
1786#ifdef OS_UNIX
1787 pid_t child_pid;
1788
1789#ifdef OS_ULTRIX
1790 union wait *status;
1791#else
1792 int status;
1793#endif
1794
1795#ifdef NO_FORK
1796 assert(!"support for fork() disabled by NO_FORK");
1797#else
1798 if ((child_pid = fork()) < 0)
1799 return (-1);
1800#endif
1801
1802 if (child_pid == 0) {
1803 /* now we are in the child process ... */
1804 int error = execvp(cmdname, (char*const*)argv);
1805 fprintf(stderr, "ss_spawnv: Cannot execute command \"%s\": execvp() returned %d, errno %d (%s), aborting!\n", cmdname, error, errno, strerror(errno));
1806 // NB: this is the forked() process, if it returns back to the caller, we will have
1807 // a duplicate process for whoever called us. Very bad! So must abort. K.O.
1808 abort();
1809 // NOT REACHED
1810 return SS_SUCCESS;
1811 } else {
1812 /* still in parent process */
1813 if (mode == P_WAIT) {
1814#ifdef OS_ULTRIX
1815 waitpid(child_pid, status, WNOHANG);
1816#else
1817 waitpid(child_pid, &status, WNOHANG);
1818#endif
1819
1820 } else {
1821 /* catch SIGCHLD signal to avoid <defunc> processes */
1822 signal(SIGCHLD, catch_sigchld);
1823 }
1824 }
1825
1826 return SS_SUCCESS;
1827
1828#endif /* OS_UNIX */
1829}
#define SS_INVALID_NAME
Definition midas.h:667
Here is the caller graph for this function:

◆ ss_stack_get()

INT EXPRT ss_stack_get ( char ***  string)

Definition at line 8079 of file system.cxx.

8080{
8081#ifdef OS_LINUX
8082#define MAX_STACK_DEPTH 16
8083
8084 void *trace[MAX_STACK_DEPTH];
8085 int size;
8086
8087 size = backtrace(trace, MAX_STACK_DEPTH);
8088 *string = backtrace_symbols(trace, size);
8089 return size;
8090#else
8091 return 0;
8092#endif
8093}
Here is the caller graph for this function:

◆ ss_stack_history_dump()

void EXPRT ss_stack_history_dump ( char *  filename)

Definition at line 8129 of file system.cxx.

8130{
8131 FILE *f;
8132 int i, j;
8133
8134 f = fopen(filename, "wt");
8135 if (f != NULL) {
8137 for (i = 0; i < N_STACK_HISTORY; i++) {
8138 if (strlen(stack_history[j]) > 0)
8139 fprintf(f, "%s\n", stack_history[j]);
8140 j = (j + 1) % N_STACK_HISTORY;
8141 }
8142 fclose(f);
8143 printf("Stack dump written to %s\n", filename);
8144 } else
8145 printf("Cannot open %s: errno=%d\n", filename, errno);
8146}
#define N_STACK_HISTORY
Definition system.cxx:8075
char stack_history[N_STACK_HISTORY][80]
Definition system.cxx:8076
int stack_history_pointer
Definition system.cxx:8077
INT j
Definition odbhist.cxx:40

◆ ss_stack_history_entry()

void EXPRT ss_stack_history_entry ( char *  tag)

Definition at line 8107 of file system.cxx.

8108{
8109 char **string;
8110 int i, n;
8111
8112 if (stack_history_pointer == -1) {
8114 memset(stack_history, 0, sizeof(stack_history));
8115 }
8116 mstrlcpy(stack_history[stack_history_pointer], tag, 80);
8118 n = ss_stack_get(&string);
8119 for (i = 2; i < n; i++) {
8120 mstrlcpy(stack_history[stack_history_pointer], string[i], 80);
8122 }
8123 free(string);
8124
8125 mstrlcpy(stack_history[stack_history_pointer], "=========================", 80);
8127}
INT ss_stack_get(char ***string)
Definition system.cxx:8079
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 8095 of file system.cxx.

8096{
8097 char **string;
8098 int i, n;
8099
8100 n = ss_stack_get(&string);
8101 for (i = 0; i < n; i++)
8102 printf("%s\n", string[i]);
8103 if (n > 0)
8104 free(string);
8105}
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 4622 of file system.cxx.

4693{
4694 INT status, return_status;
4695
4696 midas_thread_t thread_id = ss_gettid();
4697
4698 SUSPEND_STRUCT* psuspend = ss_suspend_get_struct(thread_id);
4699
4700 //printf("ss_suspend: thread %s\n", ss_tid_to_string(thread_id).c_str());
4701
4702 return_status = SS_TIMEOUT;
4703
4704 do {
4705 fd_set readfds;
4706 FD_ZERO(&readfds);
4707
4708 if (ss_match_thread(_ss_listen_thread, thread_id)) {
4709 /* check listen sockets */
4711 FD_SET(_ss_server_listen_socket, &readfds);
4712 //printf("ss_suspend: thread %s listen ss_server socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_listen_socket);
4713 }
4714
4716 FD_SET(_ss_client_listen_socket, &readfds);
4717 //printf("ss_suspend: thread %s listen ss_client socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_client_listen_socket);
4718 }
4719 }
4720
4721 /* check server channels */
4723 //printf("ss_suspend: thread %s server acceptions %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_num_acceptions);
4724 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4725 /* RPC channel */
4726 int sock = (*_ss_server_acceptions)[i]->recv_sock;
4727
4728 if (!sock)
4729 continue;
4730
4732 //if (_suspend_struct[idx].server_acception[i].tid != ss_gettid())
4733 // continue;
4734
4735 /* watch server socket if no data in cache */
4736 if (recv_tcp_check(sock) == 0)
4737 FD_SET(sock, &readfds);
4738 /* set timeout to zero if data in cache (-> just quick check IPC)
4739 and not called from inside bm_send_event (-> wait for IPC) */
4740 else if (msg == 0)
4741 millisec = 0;
4742
4743 if (msg == 0 && msg != MSG_BM) {
4744 /* event channel */
4745 sock = (*_ss_server_acceptions)[i]->event_sock;
4746
4747 if (!sock)
4748 continue;
4749
4750 /* check for buffered event */
4752
4753 if (status == BM_ASYNC_RETURN) {
4754 /* event buffer is full and rpc_server_receive_event() is holding on
4755 * to an event it cannot get rid of. Do not read more events from
4756 * the event socket, they have nowhere to go. K.O. */
4757 } else if (status == RPC_SUCCESS) {
4758 FD_SET(sock, &readfds);
4759 }
4760 }
4761 }
4762 }
4763
4764 /* watch for messages from the mserver */
4765 if (ss_match_thread(_ss_client_thread, thread_id)) {
4767 FD_SET(_ss_client_connection->recv_sock, &readfds);
4768 }
4769 }
4770
4771 /* watch for UDP messages in the IPC socket: buffer and odb notifications */
4772 if (ss_match_thread(_ss_odb_thread, thread_id)) {
4774 FD_SET(_ss_suspend_odb->ipc_recv_socket, &readfds);
4775 }
4776
4777 if (psuspend->ipc_recv_socket)
4778 FD_SET(psuspend->ipc_recv_socket, &readfds);
4779
4780 struct timeval timeout;
4781
4782 timeout.tv_sec = millisec / 1000;
4783 timeout.tv_usec = (millisec % 1000) * 1000;
4784
4785 do {
4786 //printf("select millisec %d, tv_sec %d, tv_usec %d\n", millisec, (int)timeout.tv_sec, (int)timeout.tv_usec);
4787
4788 if (millisec < 0)
4789 status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL); /* blocking */
4790 else
4791 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
4792
4793 /* if an alarm signal was cought, restart select with reduced timeout */
4794 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
4795 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
4796
4797 } while (status == -1); /* dont return if an alarm signal was cought */
4798
4799 /* check listener sockets */
4800
4801 if (_ss_server_listen_socket && FD_ISSET(_ss_server_listen_socket, &readfds)) {
4802 //printf("ss_suspend: thread %s rpc_server_accept socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_listen_socket);
4804 if (status == RPC_SHUTDOWN) {
4805 return status;
4806 }
4807 }
4808
4809 if (_ss_client_listen_socket && FD_ISSET(_ss_client_listen_socket, &readfds)) {
4810 //printf("ss_suspend: thread %s rpc_client_accept socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_client_listen_socket);
4812 if (status == RPC_SHUTDOWN) {
4813 return status;
4814 }
4815 }
4816
4817 /* check server channels */
4819 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4820 /* rpc channel */
4821 int sock = (*_ss_server_acceptions)[i]->recv_sock;
4822
4823 if (!sock)
4824 continue;
4825
4826 //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);
4827
4828 if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
4829 //printf("ss_suspend: msg %d\n", msg);
4830 if (msg == MSG_BM) {
4831 status = ss_socket_check(sock);
4832 } else {
4833 //printf("ss_suspend: rpc_server_receive_rpc() call!\n");
4835 //printf("ss_suspend: rpc_server_receive_rpc() status %d\n", status);
4836 }
4837 (*_ss_server_acceptions)[i]->last_activity = ss_millitime();
4838
4839 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN) {
4840 return status;
4841 }
4842
4843 return_status = SS_SERVER_RECV;
4844 }
4845
4846 /* event channel */
4847 sock = (*_ss_server_acceptions)[i]->event_sock;
4848
4849 if (!sock)
4850 continue;
4851
4852 if (FD_ISSET(sock, &readfds)) {
4853 if (msg != 0) {
4854 status = ss_socket_check(sock);
4855 } else {
4856 //printf("ss_suspend: rpc_server_receive_event() call!\n");
4858 //printf("ss_suspend: rpc_server_receive_event() status %d\n", status);
4859 }
4860 (*_ss_server_acceptions)[i]->last_activity = ss_millitime();
4861
4862 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN) {
4863 return status;
4864 }
4865
4866 return_status = SS_SERVER_RECV;
4867 }
4868 }
4869 }
4870
4871 /* check for messages from the mserver */
4873 int sock = _ss_client_connection->recv_sock;
4874
4875 if (FD_ISSET(sock, &readfds)) {
4877
4878 if (status == SS_ABORT) {
4879 cm_msg(MINFO, "ss_suspend", "RPC connection to mserver at \'%s\' was broken", _ss_client_connection->host_name.c_str());
4880
4881 /* close client connection if link broken */
4885
4889
4891
4892 /* exit program after broken connection to MIDAS server */
4893 return SS_ABORT;
4894 }
4895
4896 return_status = SS_CLIENT_RECV;
4897 }
4898 }
4899
4900 /* check ODB IPC socket */
4903 if (status) {
4904 return status;
4905 }
4906 }
4907
4908 /* check per-thread IPC socket */
4909 if (psuspend && psuspend->ipc_recv_socket && FD_ISSET(psuspend->ipc_recv_socket, &readfds)) {
4910 status = ss_suspend_process_ipc(millisec, msg, psuspend->ipc_recv_socket);
4911 if (status) {
4912 return status;
4913 }
4914 }
4915
4916
4917 } while (millisec < 0);
4918
4919 return return_status;
4920}
#define SS_SERVER_RECV
Definition midas.h:676
#define SS_CLIENT_RECV
Definition midas.h:677
#define RPC_SHUTDOWN
Definition midas.h:708
#define RPC_SUCCESS
Definition midas.h:699
static midas_thread_t _ss_server_thread
Definition system.cxx:4068
static int _ss_server_listen_socket
Definition system.cxx:4062
static int ss_suspend_process_ipc(INT millisec, INT msg, int ipc_recv_socket)
Definition system.cxx:4465
SUSPEND_STRUCT * ss_suspend_get_struct(midas_thread_t thread_id)
Definition system.cxx:4244
static RPC_SERVER_CONNECTION * _ss_client_connection
Definition system.cxx:4066
static midas_thread_t _ss_odb_thread
Definition system.cxx:4058
static int ss_socket_check(int sock)
Definition system.cxx:4572
static bool ss_match_thread(midas_thread_t tid1, midas_thread_t tid2)
Definition system.cxx:4072
static int _ss_client_listen_socket
Definition system.cxx:4063
static midas_thread_t _ss_listen_thread
Definition system.cxx:4061
midas_thread_t ss_gettid(void)
Definition system.cxx:1591
static midas_thread_t _ss_client_thread
Definition system.cxx:4065
INT recv_tcp_check(int sock)
Definition midas.cxx:14812
INT rpc_server_receive_rpc(RPC_SERVER_ACCEPTION *sa)
Definition midas.cxx:17239
INT rpc_client_accept(int lsock)
Definition midas.cxx:16966
INT rpc_server_accept(int lsock)
Definition midas.cxx:16709
INT rpc_client_dispatch(int sock)
Definition midas.cxx:12085
#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 4286 of file system.cxx.

4287{
4288 if (psuspend->ipc_recv_socket) {
4289 closesocket(psuspend->ipc_recv_socket);
4290 psuspend->ipc_recv_socket = 0;
4291 }
4292
4293 if (psuspend->ipc_send_socket) {
4294 closesocket(psuspend->ipc_send_socket);
4295 psuspend->ipc_send_socket = 0;
4296 }
4297
4298 //printf("ss_suspend_close: free thread %s, udp port %d\n", ss_tid_to_string(psuspend->thread_id).c_str(), psuspend->ipc_recv_port);
4299
4300 psuspend->thread_id = 0;
4301 psuspend->ipc_recv_port = 0;
4302}
midas_thread_t thread_id
Definition system.cxx:4049
Here is the caller graph for this function:

◆ ss_suspend_exit()

INT ss_suspend_exit ( )

Definition at line 4305 of file system.cxx.

4323{
4324 midas_thread_t thread_id = ss_gettid();
4325
4326 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4327 if (!_ss_suspend_vector[i])
4328 continue;
4329 if (_ss_suspend_vector[i]->thread_id == thread_id) {
4330 SUSPEND_STRUCT* psuspend = _ss_suspend_vector[i];
4331 _ss_suspend_vector[i] = NULL;
4332 ss_suspend_close(psuspend);
4333 delete psuspend;
4334 }
4335 }
4336
4337 if (_ss_suspend_odb) {
4338 bool last = true;
4339 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4340 if (_ss_suspend_vector[i]) {
4341 last = false;
4342 break;
4343 }
4344 }
4345 if (last) {
4346 SUSPEND_STRUCT* psuspend = _ss_suspend_odb;
4347 _ss_suspend_odb = NULL;
4348 ss_suspend_close(psuspend);
4349 delete psuspend;
4350 }
4351 }
4352
4353 return SS_SUCCESS;
4354}
static void ss_suspend_close(SUSPEND_STRUCT *psuspend)
Definition system.cxx:4286
static std::vector< SUSPEND_STRUCT * > _ss_suspend_vector
Definition system.cxx:4056
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 4432 of file system.cxx.

4453{
4454 SUSPEND_STRUCT* psuspend = ss_suspend_get_struct(thread_id);
4455
4456 if (!psuspend->ipc_recv_port) {
4457 ss_suspend_init_struct(psuspend);
4458 }
4459
4460 *port = psuspend->ipc_recv_port;
4461
4462 return SS_SUCCESS;
4463}
static INT ss_suspend_init_struct(SUSPEND_STRUCT *psuspend)
Definition system.cxx:4091
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 4406 of file system.cxx.

4423{
4424 assert(_ss_suspend_odb);
4425
4427
4428 return SS_SUCCESS;
4429}
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 4244 of file system.cxx.

4258{
4259 // find thread_id
4260 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4261 if (!_ss_suspend_vector[i])
4262 continue;
4263 if (_ss_suspend_vector[i]->thread_id == thread_id) {
4264 return _ss_suspend_vector[i];
4265 }
4266 }
4267
4268 // create new one if not found
4269 SUSPEND_STRUCT *psuspend = new SUSPEND_STRUCT;
4270 psuspend->thread_id = thread_id;
4271
4272 // place into empty slot
4273 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4274 if (!_ss_suspend_vector[i]) {
4275 _ss_suspend_vector[i] = psuspend;
4276 return psuspend;
4277 }
4278 }
4279
4280 // add to vector if no empty slots
4281 _ss_suspend_vector.push_back(psuspend);
4282
4283 return psuspend;
4284}
struct suspend_struct SUSPEND_STRUCT
Here is the caller graph for this function:

◆ ss_suspend_init_odb_port()

INT ss_suspend_init_odb_port ( )

Definition at line 4384 of file system.cxx.

4395{
4396 if (!_ss_suspend_odb) {
4400 }
4401
4402 return SS_SUCCESS;
4403}
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 4091 of file system.cxx.

4107{
4108 INT status, sock;
4109 unsigned int size;
4110 struct sockaddr_in bind_addr;
4111 //int udp_bind_hostname = 0; // bind to localhost or bind to hostname or bind to INADDR_ANY?
4112
4113 //printf("ss_suspend_init_struct: thread %s\n", ss_tid_to_string(psuspend->thread_id).c_str());
4114
4115 assert(psuspend->thread_id != 0);
4116
4117#ifdef OS_WINNT
4118 {
4119 WSADATA WSAData;
4120
4121 /* Start windows sockets */
4122 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
4123 return SS_SOCKET_ERROR;
4124 }
4125#endif
4126
4127 /*--------------- create UDP receive socket -------------------*/
4128 sock = socket(AF_INET, SOCK_DGRAM, 0);
4129 if (sock == -1)
4130 return SS_SOCKET_ERROR;
4131
4132 /* let OS choose port for socket */
4133 memset(&bind_addr, 0, sizeof(bind_addr));
4134 bind_addr.sin_family = AF_INET;
4135 bind_addr.sin_addr.s_addr = 0;
4136 bind_addr.sin_port = 0;
4137
4138 /* decide if UDP sockets are bound to localhost (they are only use for local communications)
4139 or to hostname (for compatibility with old clients - their hotlinks will not work) */
4140 {
4141 std::string path = cm_get_path();
4142 path += ".UDP_BIND_HOSTNAME";
4143
4144 //cm_msg(MERROR, "ss_suspend_init_ipc", "check file [%s]", path.c_str());
4145
4146 FILE *fp = fopen(path.c_str(), "r");
4147 if (fp) {
4148 cm_msg(MERROR, "ss_suspend_init_ipc", "Support for UDP_BIND_HOSTNAME was removed. Please delete file \"%s\"", path.c_str());
4149 //udp_bind_hostname = 1;
4150 fclose(fp);
4151 fp = NULL;
4152 }
4153 }
4154
4155 //#ifdef OS_VXWORKS
4156 //{
4157 // char local_host_name[HOST_NAME_LENGTH];
4158 // INT host_addr;
4159 //
4160 // gethostname(local_host_name, sizeof(local_host_name));
4161 //
4162 //host_addr = hostGetByName(local_host_name);
4163 // memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
4164 //}
4165 //#else
4166 //if (udp_bind_hostname) {
4167 // char local_host_name[HOST_NAME_LENGTH];
4168 // struct hostent *phe = gethostbyname(local_host_name);
4169 // if (phe == NULL) {
4170 // cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get IP address for host name \'%s\'", local_host_name);
4171 // return SS_SOCKET_ERROR;
4172 // }
4173 // memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
4174 //} else {
4175 bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4176 //}
4177 //#endif
4178
4179 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
4180 if (status < 0)
4181 return SS_SOCKET_ERROR;
4182
4183 /* find out which port OS has chosen */
4184 size = sizeof(bind_addr);
4185#ifdef OS_WINNT
4186 getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &size);
4187#else
4188 getsockname(sock, (struct sockaddr *) &bind_addr, &size);
4189#endif
4190
4191 // ipc receive socket must be set to non-blocking mode, see explanation
4192 // in ss_suspend_process_ipc(). K.O. July 2022.
4193
4194 int flags = fcntl(sock, F_GETFL, 0);
4195 status = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
4196
4197 if (status < 0) {
4198 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));
4199 return SS_SOCKET_ERROR;
4200 }
4201
4202 psuspend->ipc_recv_socket = sock;
4203 psuspend->ipc_recv_port = ntohs(bind_addr.sin_port);
4204
4205 /*--------------- create UDP send socket ----------------------*/
4206 sock = socket(AF_INET, SOCK_DGRAM, 0);
4207
4208 if (sock == -1)
4209 return SS_SOCKET_ERROR;
4210
4211 /* fill out bind struct pointing to local host */
4212 memset(&bind_addr, 0, sizeof(bind_addr));
4213 bind_addr.sin_family = AF_INET;
4214 bind_addr.sin_addr.s_addr = 0;
4215
4216 //#ifdef OS_VXWORKS
4217 //{
4218 // INT host_addr;
4219 //
4220 // host_addr = hostGetByName(local_host_name);
4221 //memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
4222 //}
4223 //#else
4224 //if (udp_bind_hostname) {
4225 // // nothing
4226 //} else {
4227 bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4228
4229 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
4230 if (status < 0)
4231 return SS_SOCKET_ERROR;
4232 //}
4233 //#endif
4234
4235 memcpy(&(psuspend->bind_addr), &bind_addr, sizeof(bind_addr));
4236 psuspend->ipc_send_socket = sock;
4237
4238 //printf("ss_suspend_init_struct: thread %s, udp port %d\n", ss_tid_to_string(psuspend->thread_id).c_str(), psuspend->ipc_recv_port);
4239
4240 return SS_SUCCESS;
4241}
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 4465 of file system.cxx.

4466{
4467 char buffer[80];
4468 buffer[0] = 0;
4469 /* receive IPC message */
4470 struct sockaddr from_addr;
4471 socklen_t from_addr_size = sizeof(struct sockaddr);
4472
4473 // note: ipc_recv_socket must be set in non-blocking mode:
4474 // it looks as if we come here from ss_suspend() only if select() said
4475 // that our socket has data. but this is not true. after that select(),
4476 // ss_suspend() reads other sockets, calls other handlers, which may call
4477 // ss_suspend() recursively (i.e. via bm_receive_event() RPC call to "wait_for_more_data"
4478 // call to ss_suspend()). the recursively called ss_suspend() will
4479 // also so select() and call this function to read from this socket. then it eventually
4480 // returns, all the handlers return back to the original ss_suspend(), which
4481 // happily remembers that the original select() told us we have data. but this data
4482 // was already read by the recursively call ss_suspend(), so the socket is empty
4483 // and our recvfrom() will sleep forever. inside the mserver, this makes mserver
4484 // stop (very bad!). with the socket set to non-blocking mode
4485 // recvfrom() will never sleep and this problem is avoided. K.O. July 2022
4486 // see bug report https://bitbucket.org/tmidas/midas/issues/346/rpc-timeout-in-bm_receive_event
4487
4488 // note2: in midas, there is never a situation where we wait for data
4489 // from the ipc sockets. these sockets are used for "event buffer has data" and "odb has new data"
4490 // notifications. we check them, but we do not wait for them. this setting
4491 // the socket to non-blocking mode is safe. K.O. July 2022.
4492
4493 ssize_t size = recvfrom(ipc_recv_socket, buffer, sizeof(buffer), 0, &from_addr, &from_addr_size);
4494
4495 if (size <= 0) {
4496 //fprintf(stderr, "ss_suspend_process_ipc: recvfrom() returned %zd, errno %d (%s)\n", size, errno, strerror(errno));
4497 // return 0 means we did not do anyting. K.O.
4498 return 0;
4499 }
4500
4501 // NB: ss_suspend(MSG_BM) (and ss_suspend(MSG_ODB)) are needed to break
4502 // recursive calls to the event handler (and db_watch() handler) if these
4503 // handlers call ss_suspend() again. The rootana interactive ROOT graphics
4504 // mode does this. To prevent this recursion, event handlers must always
4505 // call ss_suspend() with MSG_BM (and MSG_ODB). K.O.
4506
4507 /* return if received requested message */
4508 if (msg == MSG_BM && buffer[0] == 'B')
4509 return SS_SUCCESS;
4510 if (msg == MSG_ODB && buffer[0] == 'O')
4511 return SS_SUCCESS;
4512
4513 // NB: do not need to check thread id, the mserver is single-threaded. K.O.
4514 int mserver_client_socket = 0;
4516 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4517 if ((*_ss_server_acceptions)[i]->is_mserver) {
4518 mserver_client_socket = (*_ss_server_acceptions)[i]->send_sock;
4519 }
4520 }
4521 }
4522
4523 time_t tstart = time(NULL);
4524 int return_status = 0;
4525
4526 /* receive further messages to empty UDP queue */
4527 while (1) {
4528 char buffer_tmp[80];
4529 buffer_tmp[0] = 0;
4530 from_addr_size = sizeof(struct sockaddr);
4531
4532 // note: ipc_recv_socket must be in non-blocking mode, see comments above. K.O.
4533
4534 ssize_t size_tmp = recvfrom(ipc_recv_socket, buffer_tmp, sizeof(buffer_tmp), 0, &from_addr, &from_addr_size);
4535
4536 if (size_tmp <= 0) {
4537 //fprintf(stderr, "ss_suspend_process_ipc: second recvfrom() returned %zd, errno %d (%s)\n", size, errno, strerror(errno));
4538 break;
4539 }
4540
4541 /* stop the loop if received requested message */
4542 if (msg == MSG_BM && buffer_tmp[0] == 'B') {
4543 return_status = SS_SUCCESS;
4544 break;
4545 }
4546 if (msg == MSG_ODB && buffer_tmp[0] == 'O') {
4547 return_status = SS_SUCCESS;
4548 break;
4549 }
4550
4551 /* don't forward same MSG_BM as above */
4552 if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0) {
4553 cm_dispatch_ipc(buffer_tmp, size_tmp, mserver_client_socket);
4554 }
4555
4556 if (millisec > 0) {
4557 time_t tnow = time(NULL);
4558 // make sure we do not loop for longer than our timeout
4559 if (tnow - tstart > 1 + millisec/1000) {
4560 //printf("ss_suspend - break out dt %d, %d loops\n", (int)(tnow-tstart), count);
4561 break;
4562 }
4563 }
4564 }
4565
4566 /* call dispatcher */
4567 cm_dispatch_ipc(buffer, size, mserver_client_socket);
4568
4569 return return_status;
4570}
INT cm_dispatch_ipc(const char *message, int message_size, int client_socket)
Definition midas.cxx:5403
#define MSG_ODB
Definition msystem.h:303
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 4370 of file system.cxx.

4371{
4372 // client side of the mserver connection
4373 _ss_client_connection = connection;
4374 return SS_SUCCESS;
4375}
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 4363 of file system.cxx.

4364{
4365 // midas program rpc listener socket (run transitions, etc)
4366 _ss_client_listen_socket = listen_socket;
4367 return SS_SUCCESS;
4368}
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 4081 of file system.cxx.

4082{
4083 _ss_listen_thread = thread_id; // this thread handles listen()/accept() activity
4084 _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())
4085 _ss_server_thread = thread_id; // this thread reads and executes RPC requests
4086 _ss_odb_thread = thread_id; // this thread reads and dispatches ODB notifications (db_watch & co)
4087 return SS_SUCCESS;
4088}
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 4377 of file system.cxx.

4378{
4379 // server side of the RPC connections (run transitions, etc)
4380 _ss_server_acceptions = acceptions;
4381 return SS_SUCCESS;
4382}
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 4356 of file system.cxx.

4357{
4358 // mserver listener socket
4359 _ss_server_listen_socket = listen_socket;
4360 return SS_SUCCESS;
4361}
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:2188
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 2188 of file system.cxx.

2189{
2190#ifdef OS_UNIX
2191 INT childpid;
2192
2193 return ss_exec(command, &childpid);
2194
2195#else
2196
2197 system(command);
2198 return SS_SUCCESS;
2199
2200#endif
2201}
INT ss_exec(const char *command, INT *pid)
Definition system.cxx:2204
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 5987 of file system.cxx.

6005{
6006 INT status;
6007
6008#ifdef OS_UNIX
6009
6010 status = close(channel);
6011
6012 if (status < 0) {
6013 cm_msg(MERROR, "ss_tape_close", "close() returned %d, errno %d (%s)", status, errno, strerror(errno));
6014 return errno;
6015 }
6016#endif /* OS_UNIX */
6017
6018#ifdef OS_WINNT
6019
6020 if (!CloseHandle((HANDLE) channel)) {
6021 status = GetLastError();
6022 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
6023 return status;
6024 }
6025#endif /* OS_WINNT */
6026
6027 return SS_SUCCESS;
6028}
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 6317 of file system.cxx.

6336{
6337#ifdef MTIOCTOP
6338 struct mtop arg;
6339 INT status;
6340
6341 if (count > 0)
6342 arg.mt_op = MTFSF;
6343 else
6344 arg.mt_op = MTBSF;
6345 arg.mt_count = abs(count);
6346
6347 //cm_enable_watchdog(FALSE);
6348
6349 status = ioctl(channel, MTIOCTOP, &arg);
6350
6351 //cm_enable_watchdog(TRUE);
6352
6353 if (status < 0) {
6354 cm_msg(MERROR, "ss_tape_fskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6355 return errno;
6356 }
6357#endif /* OS_UNIX */
6358
6359#ifdef OS_WINNT
6360 INT status;
6361
6362 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_FILEMARKS, 0, (DWORD) count, 0, FALSE);
6363
6364 if (status == ERROR_END_OF_MEDIA)
6365 return SS_END_OF_TAPE;
6366
6367 if (status != NO_ERROR) {
6368 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
6369 return status;
6370 }
6371#endif /* OS_WINNT */
6372
6373 return SS_SUCCESS;
6374}
#define SS_END_OF_TAPE
Definition midas.h:685
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 6653 of file system.cxx.

6662{
6663#if defined(OS_DARWIN)
6664
6665 return 0;
6666
6667#elif defined(OS_UNIX)
6668
6669 INT status;
6670 struct mtpos arg;
6671
6672 //cm_enable_watchdog(FALSE);
6673 status = ioctl(channel, MTIOCPOS, &arg);
6674 //cm_enable_watchdog(TRUE);
6675 if (status < 0) {
6676 if (errno == EIO)
6677 return 0;
6678 else {
6679 cm_msg(MERROR, "ss_tape_get_blockn", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6680 return -errno;
6681 }
6682 }
6683 return (arg.mt_blkno);
6684
6685#elif defined(OS_WINNT)
6686
6687 INT status;
6688 TAPE_GET_MEDIA_PARAMETERS media;
6689 unsigned long size;
6690 /* I'm not sure the partition count corresponds to the block count */
6691 status = GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &media);
6692 return (media.PartitionCount);
6693
6694#endif
6695}
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 6541 of file system.cxx.

6559{
6560#ifdef MTIOCTOP
6561 struct mtop arg;
6562 INT status;
6563
6564#ifdef MTLOAD
6565 arg.mt_op = MTLOAD;
6566#else
6567 arg.mt_op = MTNOP;
6568#endif
6569 arg.mt_count = 0;
6570
6571 //cm_enable_watchdog(FALSE);
6572
6573 status = ioctl(channel, MTIOCTOP, &arg);
6574
6575 //cm_enable_watchdog(TRUE);
6576
6577 if (status < 0) {
6578 cm_msg(MERROR, "ss_tape_mount", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6579 return errno;
6580 }
6581#endif /* OS_UNIX */
6582
6583#ifdef OS_WINNT
6584 INT status;
6585
6586 status = PrepareTape((HANDLE) channel, TAPE_LOAD, FALSE);
6587 if (status != NO_ERROR) {
6588 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
6589 return status;
6590 }
6591#endif /* OS_WINNT */
6592
6593 return CM_SUCCESS;
6594}
#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 5896 of file system.cxx.

5918{
5919#ifdef OS_UNIX
5920 //cm_enable_watchdog(FALSE);
5921
5922 *channel = open(path, oflag, 0644);
5923
5924 //cm_enable_watchdog(TRUE);
5925
5926 if (*channel < 0)
5927 cm_msg(MERROR, "ss_tape_open", "open() returned %d, errno %d (%s)", *channel, errno, strerror(errno));
5928
5929 if (*channel < 0) {
5930 if (errno == EIO)
5931 return SS_NO_TAPE;
5932 if (errno == EBUSY)
5933 return SS_DEV_BUSY;
5934 return errno;
5935 }
5936#ifdef MTSETBLK
5937 {
5938 /* set variable block size */
5939 struct mtop arg;
5940 arg.mt_op = MTSETBLK;
5941 arg.mt_count = 0;
5942
5943 ioctl(*channel, MTIOCTOP, &arg);
5944 }
5945#endif /* MTSETBLK */
5946
5947#endif /* OS_UNIX */
5948
5949#ifdef OS_WINNT
5950 INT status;
5951 TAPE_GET_MEDIA_PARAMETERS m;
5952
5953 *channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
5954
5955 if (*channel == (INT) INVALID_HANDLE_VALUE) {
5956 status = GetLastError();
5957 if (status == ERROR_SHARING_VIOLATION) {
5958 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
5959 return SS_DEV_BUSY;
5960 }
5961 if (status == ERROR_FILE_NOT_FOUND) {
5962 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
5963 return SS_NO_TAPE;
5964 }
5965
5966 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
5967 return status;
5968 }
5969
5970 status = GetTapeStatus((HANDLE) (*channel));
5971 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
5972 cm_msg(MERROR, "ss_tape_open", "no media in drive");
5973 return SS_NO_TAPE;
5974 }
5975
5976 /* set block size */
5977 memset(&m, 0, sizeof(m));
5978 m.BlockSize = TAPE_BUFFER_SIZE;
5979 SetTapeParameters((HANDLE) (*channel), SET_TAPE_MEDIA_INFORMATION, &m);
5980
5981#endif
5982
5983 return SS_SUCCESS;
5984}
#define SS_NO_TAPE
Definition midas.h:680
#define SS_DEV_BUSY
Definition midas.h:681
#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 6177 of file system.cxx.

6197{
6198#ifdef OS_UNIX
6199 INT n, status;
6200
6201 do {
6202 n = read(channel, pdata, *count);
6203 } while (n == -1 && errno == EINTR);
6204
6205 if (n == -1) {
6206 if (errno == ENOSPC || errno == EIO)
6208 else {
6209 if (n == 0 && errno == 0)
6211 else {
6212 cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", n, errno);
6213 status = errno;
6214 }
6215 }
6216 } else
6218 *count = n;
6219
6220 return status;
6221
6222#elif defined(OS_WINNT) /* OS_UNIX */
6223
6224 INT status;
6225 DWORD read;
6226
6227 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
6228 status = GetLastError();
6229 if (status == ERROR_NO_DATA_DETECTED)
6231 else if (status == ERROR_FILEMARK_DETECTED)
6233 else if (status == ERROR_MORE_DATA)
6235 else
6236 cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", read, status);
6237 } else
6239
6240 *count = read;
6241 return status;
6242
6243#else /* OS_WINNT */
6244
6245 return SS_SUCCESS;
6246
6247#endif
6248}
#define SS_END_OF_FILE
Definition midas.h:686
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 6433 of file system.cxx.

6451{
6452#ifdef MTIOCTOP
6453 struct mtop arg;
6454 INT status;
6455
6456 arg.mt_op = MTREW;
6457 arg.mt_count = 0;
6458
6459 //cm_enable_watchdog(FALSE);
6460
6461 status = ioctl(channel, MTIOCTOP, &arg);
6462
6463 //cm_enable_watchdog(TRUE);
6464
6465 if (status < 0) {
6466 cm_msg(MERROR, "ss_tape_rewind", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6467 return errno;
6468 }
6469#endif /* OS_UNIX */
6470
6471#ifdef OS_WINNT
6472 INT status;
6473
6474 status = SetTapePosition((HANDLE) channel, TAPE_REWIND, 0, 0, 0, FALSE);
6475 if (status != NO_ERROR) {
6476 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
6477 return status;
6478 }
6479#endif /* OS_WINNT */
6480
6481 return CM_SUCCESS;
6482}
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 6377 of file system.cxx.

6396{
6397#ifdef MTIOCTOP
6398 struct mtop arg;
6399 INT status;
6400
6401 if (count > 0)
6402 arg.mt_op = MTFSR;
6403 else
6404 arg.mt_op = MTBSR;
6405 arg.mt_count = abs(count);
6406
6407 //cm_enable_watchdog(FALSE);
6408
6409 status = ioctl(channel, MTIOCTOP, &arg);
6410
6411 //cm_enable_watchdog(TRUE);
6412
6413 if (status < 0) {
6414 cm_msg(MERROR, "ss_tape_rskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6415 return errno;
6416 }
6417#endif /* OS_UNIX */
6418
6419#ifdef OS_WINNT
6420 INT status;
6421
6422 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_RELATIVE_BLOCKS, 0, (DWORD) count, 0, FALSE);
6423 if (status != NO_ERROR) {
6424 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
6425 return status;
6426 }
6427#endif /* OS_WINNT */
6428
6429 return CM_SUCCESS;
6430}
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 6485 of file system.cxx.

6503{
6504#ifdef MTIOCTOP
6505 struct mtop arg;
6506 INT status;
6507
6508#ifdef MTEOM
6509 arg.mt_op = MTEOM;
6510#else
6511 arg.mt_op = MTSEOD;
6512#endif
6513 arg.mt_count = 0;
6514
6515 //cm_enable_watchdog(FALSE);
6516
6517 status = ioctl(channel, MTIOCTOP, &arg);
6518
6519 //cm_enable_watchdog(TRUE);
6520
6521 if (status < 0) {
6522 cm_msg(MERROR, "ss_tape_rewind", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6523 return errno;
6524 }
6525#endif /* OS_UNIX */
6526
6527#ifdef OS_WINNT
6528 INT status;
6529
6530 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_END_OF_DATA, 0, 0, 0, FALSE);
6531 if (status != NO_ERROR) {
6532 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
6533 return status;
6534 }
6535#endif /* OS_WINNT */
6536
6537 return CM_SUCCESS;
6538}
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 6031 of file system.cxx.

6048{
6049#ifdef OS_UNIX
6050 int status;
6051 char str[256];
6052 /* let 'mt' do the job */
6053 sprintf(str, "mt -f %s status", path);
6054 status = system(str);
6055 if (status == -1)
6056 return SS_TAPE_ERROR;
6057 return SS_SUCCESS;
6058#endif /* OS_UNIX */
6059
6060#ifdef OS_WINNT
6062 DWORD size;
6063 TAPE_GET_MEDIA_PARAMETERS m;
6064 TAPE_GET_DRIVE_PARAMETERS d;
6065 double x;
6066
6067 channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
6068
6069 if (channel == (INT) INVALID_HANDLE_VALUE) {
6070 status = GetLastError();
6071 if (status == ERROR_SHARING_VIOLATION) {
6072 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
6073 return SS_SUCCESS;
6074 }
6075 if (status == ERROR_FILE_NOT_FOUND) {
6076 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
6077 return SS_SUCCESS;
6078 }
6079
6080 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
6081 return status;
6082 }
6083
6084 /* poll media changed messages */
6085 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
6086 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
6087
6088 status = GetTapeStatus((HANDLE) channel);
6089 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
6090 cm_msg(MINFO, "ss_tape_status", "no media in drive");
6091 CloseHandle((HANDLE) channel);
6092 return SS_SUCCESS;
6093 }
6094
6095 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
6096 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &m);
6097
6098 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
6099 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
6100 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
6101
6102 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
6103 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
6104 / 1000.0 / 1000.0;
6105 printf("Tape capacity remaining is %d MB\n", (int) x);
6106 } else
6107 printf("Tape capacity is not reported by tape\n");
6108
6109 CloseHandle((HANDLE) channel);
6110
6111#endif
6112
6113 return SS_SUCCESS;
6114}
#define SS_TAPE_ERROR
Definition midas.h:683
double d
Definition system.cxx:1313
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 6597 of file system.cxx.

6615{
6616#ifdef MTIOCTOP
6617 struct mtop arg;
6618 INT status;
6619
6620#ifdef MTOFFL
6621 arg.mt_op = MTOFFL;
6622#else
6623 arg.mt_op = MTUNLOAD;
6624#endif
6625 arg.mt_count = 0;
6626
6627 //cm_enable_watchdog(FALSE);
6628
6629 status = ioctl(channel, MTIOCTOP, &arg);
6630
6631 //cm_enable_watchdog(TRUE);
6632
6633 if (status < 0) {
6634 cm_msg(MERROR, "ss_tape_unmount", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6635 return errno;
6636 }
6637#endif /* OS_UNIX */
6638
6639#ifdef OS_WINNT
6640 INT status;
6641
6642 status = PrepareTape((HANDLE) channel, TAPE_UNLOAD, FALSE);
6643 if (status != NO_ERROR) {
6644 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
6645 return status;
6646 }
6647#endif /* OS_WINNT */
6648
6649 return CM_SUCCESS;
6650}
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 6117 of file system.cxx.

6138{
6139#ifdef OS_UNIX
6140 INT status;
6141
6142 do {
6143 status = write(channel, pdata, count);
6144/*
6145 if (status != count)
6146 printf("count: %d - %d\n", count, status);
6147*/
6148 } while (status == -1 && errno == EINTR);
6149
6150 if (status != count) {
6151 cm_msg(MERROR, "ss_tape_write", "write() returned %d, errno %d (%s)", status, errno, strerror(errno));
6152
6153 if (errno == EIO)
6154 return SS_IO_ERROR;
6155 else
6156 return SS_TAPE_ERROR;
6157 }
6158#endif /* OS_UNIX */
6159
6160#ifdef OS_WINNT
6161 INT status;
6162 DWORD written;
6163
6164 WriteFile((HANDLE) channel, pdata, count, &written, NULL);
6165 if (written != (DWORD) count) {
6166 status = GetLastError();
6167 cm_msg(MERROR, "ss_tape_write", "error %d", status);
6168
6169 return SS_IO_ERROR;
6170 }
6171#endif /* OS_WINNT */
6172
6173 return SS_SUCCESS;
6174}
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 6251 of file system.cxx.

6269{
6270#ifdef MTIOCTOP
6271 struct mtop arg;
6272 INT status;
6273
6274 arg.mt_op = MTWEOF;
6275 arg.mt_count = 1;
6276
6277 //cm_enable_watchdog(FALSE);
6278
6279 status = ioctl(channel, MTIOCTOP, &arg);
6280
6281 //cm_enable_watchdog(TRUE);
6282
6283 if (status < 0) {
6284 cm_msg(MERROR, "ss_tape_write_eof", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6285 return errno;
6286 }
6287#endif /* OS_UNIX */
6288
6289#ifdef OS_WINNT
6290
6291 TAPE_GET_DRIVE_PARAMETERS d;
6292 DWORD size;
6293 INT status;
6294
6295 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
6296 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
6297
6298 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
6299 status = WriteTapemark((HANDLE) channel, TAPE_FILEMARKS, 1, FALSE);
6300 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
6301 status = WriteTapemark((HANDLE) channel, TAPE_LONG_FILEMARKS, 1, FALSE);
6302 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
6303 status = WriteTapemark((HANDLE) channel, TAPE_SHORT_FILEMARKS, 1, FALSE);
6304 else
6305 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
6306
6307 if (status != NO_ERROR) {
6308 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
6309 return status;
6310 }
6311#endif /* OS_WINNT */
6312
6313 return SS_SUCCESS;
6314}
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};
midas_thread_t thread_id = ss_thread_create((void *) taskWatch, &tsWatch);
if (thread_id == 0) {
printf("cannot spawn taskWatch\n");
}
...
midas_thread_t ss_thread_create(INT(*thread_func)(void *), void *param)
Definition system.cxx:2382

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

2383{
2384#if defined(OS_WINNT)
2385
2386 HANDLE status;
2387 DWORD thread_id;
2388
2389 if (thread_func == NULL) {
2390 return 0;
2391 }
2392
2393 status = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_func, (LPVOID) param, 0, &thread_id);
2394
2395 return status == NULL ? 0 : (midas_thread_t) thread_id;
2396
2397#elif defined(OS_MSDOS)
2398
2399 return 0;
2400
2401#elif defined(OS_VMS)
2402
2403 return 0;
2404
2405#elif defined(OS_VXWORKS)
2406
2407/* taskSpawn which could be considered as a thread under VxWorks
2408 requires several argument beside the thread args
2409 taskSpawn (taskname, priority, option, stacksize, entry_point
2410 , arg1, arg2, ... , arg9, arg10)
2411 all the arg will have to be retrieved from the param list.
2412 through a structure to be simpler */
2413
2414 INT status;
2415 VX_TASK_SPAWN *ts;
2416
2417 ts = (VX_TASK_SPAWN *) param;
2418 status =
2419 taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
2420 (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
2421 ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9, ts->arg10);
2422
2423 return status == ERROR ? 0 : status;
2424
2425#elif defined(OS_UNIX)
2426
2427 INT status;
2428 pthread_t thread_id;
2429
2430 status = pthread_create(&thread_id, NULL, (void* (*)(void*))thread_func, param);
2431
2432 return status != 0 ? 0 : thread_id;
2433
2434#endif
2435}
Here is the caller graph for this function:

◆ ss_thread_get_name()

std::string ss_thread_get_name ( )

Definition at line 2516 of file system.cxx.

2517{
2518#if defined(OS_UNIX)
2519 char str[256];
2520 pthread_t thread = pthread_self();
2521 pthread_getname_np(thread, str, sizeof(str));
2522 return std::string(str);
2523#else
2524 return "";
2525#endif
2526}
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 2455 of file system.cxx.

2456{
2457#if defined(OS_WINNT)
2458
2459 DWORD status;
2460 HANDLE th;
2461
2462 th = OpenThread(THREAD_TERMINATE, FALSE, (DWORD)thread_id);
2463 if (th == 0)
2464 status = GetLastError();
2465
2466 status = TerminateThread(th, 0);
2467
2468 if (status == 0)
2469 status = GetLastError();
2470
2471 return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
2472
2473#elif defined(OS_MSDOS)
2474
2475 return 0;
2476
2477#elif defined(OS_VMS)
2478
2479 return 0;
2480
2481#elif defined(OS_VXWORKS)
2482
2483 INT status;
2484 status = taskDelete(thread_id);
2485 return status == OK ? 0 : ERROR;
2486
2487#elif defined(OS_UNIX)
2488
2489 INT status;
2490 status = pthread_kill(thread_id, SIGKILL);
2491 return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
2492
2493#endif
2494}
#define SS_NO_THREAD
Definition midas.h:673
Here is the caller graph for this function:

◆ ss_thread_set_name()

INT EXPRT ss_thread_set_name ( std::string  name)

Definition at line 2498 of file system.cxx.

2499{
2500#if defined(OS_DARWIN)
2501
2502 pthread_setname_np(name.c_str());
2503 return SS_SUCCESS;
2504
2505#elif defined(OS_UNIX)
2506
2507 pthread_t thread = pthread_self();
2508 pthread_setname_np(thread, name.c_str());
2509 return SS_SUCCESS;
2510
2511#else
2512 return 0;
2513#endif
2514}
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 1643 of file system.cxx.

1644{
1645#if defined OS_MSDOS
1646
1647 return "0";
1648
1649#elif defined OS_WINNT
1650
1651#error Do not know how to do ss_tid_to_string()
1652 return "???";
1653
1654#elif defined OS_VMS
1655
1656 char buf[256];
1657 sprintf(buf, "%d", thread_id);
1658 return buf;
1659
1660#elif defined OS_DARWIN
1661
1662 char buf[256];
1663 sprintf(buf, "%p", thread_id);
1664 return buf;
1665
1666#elif defined OS_CYGWIN
1667
1668 char buf[256];
1669 sprintf(buf, "%p", thread_id);
1670 return buf;
1671
1672#elif defined OS_UNIX
1673
1674 char buf[256];
1675 sprintf(buf, "%lu", thread_id);
1676 return buf;
1677
1678#elif defined OS_VXWORKS
1679
1680 char buf[256];
1681 sprintf(buf, "%d", thread_id);
1682 return buf;
1683
1684#else
1685#error Do not know how to do ss_tid_to_string()
1686#endif
1687}
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);
stop = ss_time();
printf("Operation took %1.3lf seconds\n",stop-start);
...
Returns
Time in seconds

Definition at line 3541 of file system.cxx.

3542{
3543 return (DWORD) time(NULL);
3544}
Here is the caller graph for this function:

◆ ss_time_sec()

double EXPRT ss_time_sec ( )

Definition at line 3546 of file system.cxx.

3547{
3548 struct timeval tv;
3549 gettimeofday(&tv, NULL);
3550 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
3551}
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 3344 of file system.cxx.

3360{
3361 if (timeout_sec <= 0) {
3362 mutex.lock();
3363 return true;
3364 }
3365
3366 double starttime = ss_time_sec();
3367 double endtime = starttime + timeout_sec;
3368
3369 // NB: per timed mutex try_lock_for(), one must always
3370 // look waiting for successful lock because it is permitted
3371 // to return "false" even if timeout did not yet expire. (cannot
3372 // tell permitted spurious failure from normal timeout). K.O.
3373
3374 double locktime = starttime;
3375
3376 while (1) {
3377 bool ok = mutex.try_lock_for(std::chrono::milliseconds(1000));
3378
3379 if (ok) {
3380 //double now = ss_time_sec();
3381 //fprintf(stderr, "ss_timed_mutex_wait_for_sec: mutex %s locked in %.1f seconds. timeout %.1f seconds\n", mutex_name, now-starttime, timeout_sec);
3382 return true;
3383 }
3384
3385 double now = ss_time_sec();
3386
3387 if (mutex_name) {
3388 if (now-locktime < 0.2) {
3389 // 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.
3390 //fprintf(stderr, "ss_timed_mutex_wait_for_sec: short try_lock_for(1000). %.3f seconds\n", now-locktime);
3391 } else {
3392 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);
3393 }
3394 }
3395
3396 if (now > endtime)
3397 return false;
3398
3399 locktime = now;
3400 }
3401}
double ss_time_sec()
Definition system.cxx:3546
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 3659 of file system.cxx.

3677{
3678#if defined(OS_DARWIN) || defined(OS_VXWORKS)
3679 return 0;
3680#else
3681 return (INT) timezone; /* on Linux, comes from "#include <time.h>". */
3682#endif
3683}
Here is the caller graph for this function:

◆ ss_tzset()

void EXPRT ss_tzset ( )

Definition at line 3434 of file system.cxx.

3435{
3436 std::lock_guard<std::mutex> lock(gTzMutex);
3437 //defeat tzset() error trap from msystem.h
3438 //#ifdef tzset
3439 //#undef tzset
3440 //#endif
3441 tzset();
3442}
Here is the caller graph for this function:

◆ ss_us_since()

unsigned int ss_us_since ( std::chrono::time_point< std::chrono::high_resolution_clock >  start)

Definition at line 8345 of file system.cxx.

8345 {
8346 auto elapsed = std::chrono::high_resolution_clock::now() - start;
8347 return std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
8348}

◆ ss_us_start()

std::chrono::time_point< std::chrono::high_resolution_clock > ss_us_start ( )

Definition at line 8340 of file system.cxx.

8341{
8342 return std::chrono::high_resolution_clock::now();
8343}

◆ ss_write_tcp()

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

Definition at line 5431 of file system.cxx.

5452{
5453 size_t count = 0;
5454
5455 while (count < buffer_size) {
5456 ssize_t wr = write(sock, buffer + count, buffer_size - count);
5457
5458 if (wr == 0) {
5459 cm_msg(MERROR, "ss_write_tcp", "write(socket=%d,size=%d) returned zero, errno: %d (%s)", sock, (int) (buffer_size - count), errno, strerror(errno));
5460 return SS_SOCKET_ERROR;
5461 } else if (wr < 0) {
5462#ifdef OS_UNIX
5463 if (errno == EINTR)
5464 continue;
5465#endif
5466 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));
5467 return SS_SOCKET_ERROR;
5468 }
5469
5470 // good write
5471 count += wr;
5472 }
5473
5474 return SS_SUCCESS;
5475}
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 2071 of file system.cxx.

◆ _ss_client_connection

RPC_SERVER_CONNECTION* _ss_client_connection = NULL
static

Definition at line 4066 of file system.cxx.

◆ _ss_client_listen_socket

int _ss_client_listen_socket = 0
static

Definition at line 4063 of file system.cxx.

◆ _ss_client_thread

midas_thread_t _ss_client_thread = 0
static

Definition at line 4065 of file system.cxx.

◆ _ss_listen_thread

midas_thread_t _ss_listen_thread = 0
static

Definition at line 4061 of file system.cxx.

◆ _ss_odb_thread

midas_thread_t _ss_odb_thread = 0
static

Definition at line 4058 of file system.cxx.

◆ _ss_server_acceptions

RPC_SERVER_ACCEPTION_LIST* _ss_server_acceptions = NULL
static

Definition at line 4069 of file system.cxx.

◆ _ss_server_listen_socket

int _ss_server_listen_socket = 0
static

Definition at line 4062 of file system.cxx.

◆ _ss_server_thread

midas_thread_t _ss_server_thread = 0
static

Definition at line 4068 of file system.cxx.

◆ _ss_suspend_odb

SUSPEND_STRUCT* _ss_suspend_odb = NULL
static

Definition at line 4059 of file system.cxx.

◆ _ss_suspend_vector

std::vector<SUSPEND_STRUCT*> _ss_suspend_vector
static

Definition at line 4056 of file system.cxx.

◆ [] [1/2]

char { ... } ::c

Definition at line 1312 of file system.cxx.

◆ [] [2/2]

char { ... } ::c

Definition at line 1318 of file system.cxx.

◆ [] [1/2]

double { ... } ::d

Definition at line 1313 of file system.cxx.

◆ [] [2/2]

double { ... } ::d

Definition at line 1317 of file system.cxx.

◆ gSocketTrace

bool gSocketTrace = false
static

Definition at line 5043 of file system.cxx.

◆ gTzMutex

std::mutex gTzMutex
static

Definition at line 3432 of file system.cxx.

◆ MidasExceptionHandler

void(* MidasExceptionHandler) (void) ( void  )

Definition at line 3868 of file system.cxx.

◆ s_semaphore_nest_level

std::atomic_int s_semaphore_nest_level {0}
static

Definition at line 2530 of file system.cxx.

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

◆ s_semaphore_trace

std::atomic_bool s_semaphore_trace {false}
static

Definition at line 2529 of file system.cxx.

2529{false};

◆ stack_history

char stack_history[N_STACK_HISTORY][80]

Definition at line 8076 of file system.cxx.

◆ stack_history_pointer

int stack_history_pointer = -1

Definition at line 8077 of file system.cxx.

◆ [struct]

struct { ... } test_align

◆ [struct]

struct { ... } test_padding