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))
 
voidss_ctrlc_handler (void(*func)(int))
 
static bool ss_match_thread (midas_thread_t tid1, midas_thread_t tid2)
 
INT ss_suspend_set_rpc_thread (midas_thread_t thread_id)
 
static INT ss_suspend_init_struct (SUSPEND_STRUCT *psuspend)
 
SUSPEND_STRUCTss_suspend_get_struct (midas_thread_t thread_id)
 
static void ss_suspend_close (SUSPEND_STRUCT *psuspend)
 
INT ss_suspend_exit ()
 
INT ss_suspend_set_server_listener (int listen_socket)
 
INT ss_suspend_set_client_listener (int listen_socket)
 
INT ss_suspend_set_client_connection (RPC_SERVER_CONNECTION *connection)
 
INT ss_suspend_set_server_acceptions (RPC_SERVER_ACCEPTION_LIST *acceptions)
 
INT ss_suspend_init_odb_port ()
 
INT ss_suspend_get_odb_port (INT *port)
 
INT ss_suspend_get_buffer_port (midas_thread_t thread_id, INT *port)
 
static int ss_suspend_process_ipc (INT millisec, INT msg, int ipc_recv_socket)
 
static int ss_socket_check (int sock)
 
bool ss_event_socket_has_data ()
 
INT ss_suspend (INT millisec, INT msg)
 
INT ss_resume (INT port, const char *message)
 
int ss_socket_wait (int sock, INT millisec)
 
INT ss_socket_connect_tcp (const char *hostname, int tcp_port, int *sockp, std::string *error_msg_p)
 
INT ss_socket_listen_tcp (bool listen_localhost, int tcp_port, int *sockp, int *tcp_port_p, std::string *error_msg_p)
 
INT ss_socket_close (int *sockp)
 
INT ss_socket_get_peer_name (int sock, std::string *hostp, int *portp)
 
INT send_tcp (int sock, char *buffer, DWORD buffer_size, INT flags)
 
INT ss_write_tcp (int sock, const char *buffer, size_t buffer_size)
 
INT recv_string (int sock, char *buffer, DWORD buffer_size, INT millisec)
 
INT recv_tcp (int sock, char *net_buffer, DWORD buffer_size, INT flags)
 
INT recv_tcp2 (int sock, char *net_buffer, int buffer_size, int timeout_ms)
 
INT ss_recv_net_command (int sock, DWORD *routine_id, DWORD *param_size, char **param_ptr, int timeout_ms)
 
std::string ss_gethostname ()
 
INT ss_gethostname (char *buffer, int buffer_size)
 
std::string ss_getcwd ()
 
INT ss_tape_open (char *path, INT oflag, INT *channel)
 
INT ss_tape_close (INT channel)
 
INT ss_tape_status (char *path)
 
INT ss_tape_write (INT channel, void *pdata, INT count)
 
INT ss_tape_read (INT channel, void *pdata, INT *count)
 
INT ss_tape_write_eof (INT channel)
 
INT ss_tape_fskip (INT channel, INT count)
 
INT ss_tape_rskip (INT channel, INT count)
 
INT ss_tape_rewind (INT channel)
 
INT ss_tape_spool (INT channel)
 
INT ss_tape_mount (INT channel)
 
INT ss_tape_unmount (INT channel)
 
INT ss_tape_get_blockn (INT channel)
 
double ss_disk_free (const char *path)
 
INT ss_file_find (const char *path, const char *pattern, char **plist)
 
INT ss_file_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_dir_find (const char *path, const char *pattern, char **plist)
 
INT ss_dir_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_dirlink_find (const char *path, const char *pattern, char **plist)
 
INT ss_dirlink_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_file_remove (const char *path)
 
double ss_file_size (const char *path)
 
time_t ss_file_time (const char *path)
 
double ss_disk_size (const char *path)
 
int ss_file_exist (const char *path)
 
int ss_file_link_exist (const char *path)
 
int ss_dir_exist (const char *path)
 
int ss_file_copy (const char *src, const char *dst, bool append)
 
void ss_clear_screen ()
 
void ss_set_screen_size (int x, int y)
 
void ss_printf (INT x, INT y, const char *format,...)
 
charss_getpass (const char *prompt)
 
INT ss_getchar (BOOL reset)
 
charss_gets (char *string, int size)
 
INT ss_directio_give_port (INT start, INT end)
 
INT ss_directio_lock_port (INT start, INT end)
 
charss_crypt (const char *buf, const char *salt)
 
double ss_nan ()
 
int ss_isnan (double x)
 
int ss_isfin (double x)
 
INT ss_stack_get (char ***string)
 
void ss_stack_print ()
 
void ss_stack_history_entry (char *tag)
 
void ss_stack_history_dump (char *filename)
 
bool ss_is_valid_utf8 (const char *string)
 
bool ss_repair_utf8 (char *string)
 
bool ss_repair_utf8 (std::string &s)
 
std::chrono::time_point< std::chrono::high_resolution_clockss_us_start ()
 
unsigned int ss_us_since (std::chrono::time_point< std::chrono::high_resolution_clock > start)
 
int rpc_flush_event_socket (int timeout_msec)
 

Variables

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

Detailed Description

dox


Macro Definition Documentation

◆ bin_to_ascii

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

Definition at line 7967 of file system.cxx.

◆ N_STACK_HISTORY

#define N_STACK_HISTORY   500

Definition at line 8068 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:1551
#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:929
static FILE * fp
char file_name[256]
Definition odbhist.cxx:41
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_shm_type()

static void check_shm_type ( const char shm_type)
static

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

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

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

5660{
5661 int n_received = 0;
5662 int flags = 0;
5663 int n;
5664
5665 //printf("recv_tcp2: %p+%d bytes, timeout %d ms!\n", net_buffer + n_received, buffer_size - n_received, timeout_ms);
5666
5667 while (n_received != buffer_size) {
5668
5669 if (timeout_ms > 0) {
5670 int status = ss_socket_wait(sock, timeout_ms);
5671 if (status == SS_TIMEOUT)
5672 return n_received;
5673 if (status != SS_SUCCESS)
5674 return -1;
5675 }
5676
5677 n = recv(sock, net_buffer + n_received, buffer_size - n_received, flags);
5678
5679 //printf("recv_tcp2: %p+%d bytes, returned %d, errno %d (%s)\n", net_buffer + n_received, buffer_size - n_received, n, errno, strerror(errno));
5680
5681#ifdef EINTR
5682 /* don't return if an alarm signal was cought */
5683 if (n == -1 && errno == EINTR)
5684 continue;
5685#endif
5686
5687 if (n == 0) {
5688 // socket closed
5689 cm_msg(MERROR, "recv_tcp2", "unexpected connection closure");
5690 return -1;
5691 }
5692
5693 if (n < 0) {
5694 // socket error
5695 cm_msg(MERROR, "recv_tcp2", "unexpected connection error, recv() errno %d (%s)", errno, strerror(errno));
5696 return -1;
5697 }
5698
5699 n_received += n;
5700 }
5701
5702 return n_received;
5703}
#define SS_TIMEOUT
Definition midas.h:674
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 16158 of file midas.cxx.

16172{
16174
16175 //printf("ss_event_socket_has_data() returned %d\n", has_data);
16176
16177 if (has_data) {
16178 if (timeout_msec == BM_NO_WAIT) {
16179 return BM_ASYNC_RETURN;
16180 } else if (timeout_msec == BM_WAIT) {
16181 return BM_ASYNC_RETURN;
16182 } else {
16184 if (status == SS_ABORT || status == SS_EXIT)
16185 return status;
16186 return BM_ASYNC_RETURN;
16187 }
16188 }
16189
16191
16192 //printf("rpc_server_receive_event() status %d\n", status);
16193
16194 if (status == BM_ASYNC_RETURN) {
16195 return BM_ASYNC_RETURN;
16196 }
16197
16198 if (status == SS_ABORT || status == SS_EXIT)
16199 return status;
16200
16201 return BM_SUCCESS;
16202}
#define BM_ASYNC_RETURN
Definition midas.h:613
#define BM_SUCCESS
Definition midas.h:605
#define SS_ABORT
Definition midas.h:677
#define SS_EXIT
Definition midas.h:678
#define BM_NO_WAIT
Definition midas.h:366
#define BM_WAIT
Definition midas.h:365
#define MSG_BM
Definition msystem.h:302
INT ss_suspend(INT millisec, INT msg)
Definition system.cxx:4615
bool ss_event_socket_has_data()
Definition system.cxx:4592
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition midas.cxx:16003
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 5357 of file system.cxx.

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

3829{
3830#ifdef OS_WINNT
3831
3832 UserCallback = func;
3833 if (millitime > 0)
3835 else {
3836 if (_timer_id)
3838 _timer_id = 0;
3839 }
3840
3841 return SS_SUCCESS;
3842
3843#endif /* OS_WINNT */
3844#ifdef OS_VMS
3845
3846 signal(SIGALRM, func);
3847 alarm(millitime / 1000);
3848 return SS_SUCCESS;
3849
3850#endif /* OS_VMS */
3851#ifdef OS_UNIX
3852
3853 signal(SIGALRM, func);
3854 alarm(millitime / 1000);
3855 return SS_SUCCESS;
3856
3857#endif /* OS_UNIX */
3858}
Here is the call graph for this function:

◆ ss_asctime()

std::string EXPRT ss_asctime ( )

Definition at line 3621 of file system.cxx.

3638{
3639 ss_tzset(); // required for localtime_t()
3641 struct tm tms;
3643 char str[32];
3644 asctime_r(&tms, str);
3645 /* strip new line */
3646 str[24] = 0;
3647
3648 return str;
3649}
void ss_tzset()
Definition system.cxx:3427
DWORD ss_time()
Definition system.cxx:3534
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 7377 of file system.cxx.

7394{
7395#ifdef OS_WINNT
7396
7398 COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */
7399 BOOL bSuccess;
7401 CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
7402 DWORD dwConSize; /* number of character cells in the current buffer */
7403
7405
7406 /* get the number of character cells in the current buffer */
7408 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
7409
7410 /* fill the entire screen with blanks */
7412
7413 /* put the cursor at (0, 0) */
7415 return;
7416
7417#endif /* OS_WINNT */
7418#if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7419 printf("\033[2J");
7420#endif
7421#ifdef OS_MSDOS
7422 clrscr();
7423#endif
7424}
DWORD BOOL
Definition midas.h:105
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_crypt()

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

Definition at line 7969 of file system.cxx.

7989{
7990 int i, seed;
7991 static char enc_pw[13];
7992
7993 memset(enc_pw, 0, sizeof(enc_pw));
7994 enc_pw[0] = salt[0];
7995 enc_pw[1] = salt[1];
7996
7997 for (i = 0; i < 8 && buf[i]; i++)
7998 enc_pw[i + 2] = buf[i];
7999 for (; i < 8; i++)
8000 enc_pw[i + 2] = 0;
8001
8002 seed = 123;
8003 for (i = 2; i < 13; i++) {
8004 seed = 5 * seed + 27 + enc_pw[i];
8005 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
8006 }
8007
8008 return enc_pw;
8009}
#define bin_to_ascii(c)
Definition system.cxx:7967
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_ctrlc_handler()

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

Definition at line 3971 of file system.cxx.

3991{
3992#ifdef OS_WINNT
3993
3994 if (func == NULL) {
3996 return signal(SIGINT, SIG_DFL);
3997 } else {
3998 signal(SIGBREAK, func);
3999 return signal(SIGINT, func);
4000 }
4001 return NULL;
4002
4003#endif /* OS_WINNT */
4004#ifdef OS_VMS
4005
4006 return signal(SIGINT, func);
4007
4008#endif /* OS_WINNT */
4009
4010#ifdef OS_UNIX
4011
4012 if (func == NULL) {
4014 return (void *) signal(SIGINT, SIG_DFL);
4015 } else {
4016 signal(SIGTERM, func);
4017 return (void *) signal(SIGINT, func);
4018 }
4019
4020#endif /* OS_UNIX */
4021}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_daemon_init()

INT EXPRT ss_daemon_init ( BOOL  keep_stdout)

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

7281{
7282#ifdef OS_UNIX
7283 struct stat buf;
7284
7285 int retval = stat(path, &buf);
7286 //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7287 if (retval < 0)
7288 return 0;
7289 if (!S_ISDIR(buf.st_mode))
7290 return 0;
7291#else
7292#warning ss_dir_exist() is not implemented!
7293#endif
7294 return 1;
7295}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_dir_find() [1/2]

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

Definition at line 6874 of file system.cxx.

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

6910{
6911 assert(plist);
6912#ifdef OS_UNIX
6914 struct dirent *dp;
6915
6916 if ((dir_pointer = opendir(path)) == NULL)
6917 return 0;
6918 plist->clear();
6919 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6920 if (fnmatch(pattern, dp->d_name, 0) == 0 && dp->d_type == DT_DIR) {
6921 plist->push_back(dp->d_name);
6923 }
6924 }
6926#endif
6927#ifdef OS_WINNT
6928 char str[255];
6929 int first;
6930
6931 strcpy(str, path);
6932 strcat(str, "\\");
6933 strcat(str, pattern);
6934 first = 1;
6935 plist->clear();
6939 return 0;
6940 first = 0;
6941 plist->push_back(lpfdata->cFileName);
6942 while (FindNextFile(pffile, lpfdata)) {
6943 plist->push_back(lpfdata->cFileName);
6944 }
6945 free(lpfdata);
6946#endif
6947 return plist->size();
6948}
@ DIR
Definition test_init.cxx:7
Here is the call graph for this function:

◆ ss_directio_give_port()

INT EXPRT ss_directio_give_port ( INT  start,
INT  end 
)

Definition at line 7889 of file system.cxx.

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

◆ ss_directio_lock_port()

INT EXPRT ss_directio_lock_port ( INT  start,
INT  end 
)

Definition at line 7925 of file system.cxx.

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

◆ ss_dirlink_find() [1/2]

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

Definition at line 6950 of file system.cxx.

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

6986{
6987 assert(plist);
6988#ifdef OS_UNIX
6990 struct dirent *dp;
6991
6992 if ((dir_pointer = opendir(path)) == NULL)
6993 return 0;
6994 plist->clear();
6995 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6996 if (fnmatch(pattern, dp->d_name, 0) == 0) {
6997 /* must have a "/" at the end, otherwise also links to files are accepted */
6998 std::string full_path = std::string(path) + "/" + dp->d_name + "/";
6999 struct stat st;
7000 if (lstat(full_path.c_str(), &st) == 0 && (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) {
7001 plist->push_back(dp->d_name);
7002 }
7003 }
7004 }
7006#endif
7007#ifdef OS_WINNT
7008 char str[255];
7009 int first;
7010
7011 strcpy(str, path);
7012 strcat(str, "\\");
7013 strcat(str, pattern);
7014 first = 1;
7015 plist->clear();
7019 return 0;
7020 first = 0;
7021 plist->push_back(lpfdata->cFileName);
7022 while (FindNextFile(pffile, lpfdata)) {
7023 plist->push_back(lpfdata->cFileName);
7024 }
7025 free(lpfdata);
7026#endif
7027 return plist->size();
7028}
Here is the call graph for this function:

◆ ss_disk_free()

double EXPRT ss_disk_free ( const char path)

Definition at line 6698 of file system.cxx.

6714{
6715#ifdef OS_UNIX
6716#if defined(OS_OSF1)
6717 struct statfs st;
6718 statfs(path, &st, sizeof(st));
6719 return (double) st.f_bavail * st.f_bsize;
6720#elif defined(OS_LINUX)
6721 struct statfs st;
6722 int status;
6723 status = statfs(path, &st);
6724 if (status != 0)
6725 return -1;
6726 return (double) st.f_bavail * st.f_bsize;
6727#elif defined(OS_SOLARIS)
6728 struct statvfs st;
6729 statvfs(path, &st);
6730 return (double) st.f_bavail * st.f_bsize;
6731#elif defined(OS_IRIX)
6732 struct statfs st;
6733 statfs(path, &st, sizeof(struct statfs), 0);
6734 return (double) st.f_bfree * st.f_bsize;
6735#else
6736 struct fs_data st;
6737 statfs(path, &st);
6738 return (double) st.fd_otsize * st.fd_bfree;
6739#endif
6740
6741#elif defined(OS_WINNT) /* OS_UNIX */
6746 char str[80];
6747
6748 strcpy(str, path);
6749 if (strchr(str, ':') != NULL) {
6750 *(strchr(str, ':') + 1) = 0;
6753 } else
6755
6757#else /* OS_WINNT */
6758
6759 return 1e9;
6760
6761#endif
6762}
#define DIR_SEPARATOR_STR
Definition midas.h:194
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_disk_size()

double EXPRT ss_disk_size ( const char path)

Definition at line 7126 of file system.cxx.

7142{
7143#ifdef OS_UNIX
7144#if defined(OS_OSF1)
7145 struct statfs st;
7146 statfs(path, &st, sizeof(st));
7147 return (double) st.f_blocks * st.f_fsize;
7148#elif defined(OS_LINUX)
7149 int status;
7150 struct statfs st;
7151 status = statfs(path, &st);
7152 if (status != 0)
7153 return -1;
7154 return (double) st.f_blocks * st.f_bsize;
7155#elif defined(OS_SOLARIS)
7156 struct statvfs st;
7157 statvfs(path, &st);
7158 if (st.f_frsize > 0)
7159 return (double) st.f_blocks * st.f_frsize;
7160 else
7161 return (double) st.f_blocks * st.f_bsize;
7162#elif defined(OS_ULTRIX)
7163 struct fs_data st;
7164 statfs(path, &st);
7165 return (double) st.fd_btot * 1024;
7166#elif defined(OS_IRIX)
7167 struct statfs st;
7168 statfs(path, &st, sizeof(struct statfs), 0);
7169 return (double) st.f_blocks * st.f_bsize;
7170#else
7171#error ss_disk_size not defined for this OS
7172#endif
7173#endif /* OS_UNIX */
7174
7175#ifdef OS_WINNT
7180 char str[80];
7181
7182 strcpy(str, path);
7183 if (strchr(str, ':') != NULL) {
7184 *(strchr(str, ':') + 1) = 0;
7187 } else
7189
7191#endif /* OS_WINNT */
7192
7193 return 1e9;
7194}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_event_socket_has_data()

bool ss_event_socket_has_data ( )

Definition at line 4592 of file system.cxx.

4593{
4595 for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4596 /* event channel */
4597 int sock = (*_ss_server_acceptions)[i]->event_sock;
4598
4599 if (!sock)
4600 continue;
4601
4602 /* check for buffered event */
4603 int status = ss_socket_wait(sock, 1);
4604
4605 if (status == SS_SUCCESS)
4606 return true;
4607 }
4608 }
4609
4610 /* no event socket or no data in event socket */
4611 return false;
4612}
static RPC_SERVER_ACCEPTION_LIST * _ss_server_acceptions
Definition system.cxx:4062
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 3916 of file system.cxx.

3935{
3936#ifdef OS_WINNT
3937
3938 MidasExceptionHandler = func;
3939/* SetUnhandledExceptionFilter(
3940 (LPTOP_LEVEL_EXCEPTION_FILTER) MidasExceptionFilter);
3941
3942 signal(SIGINT, MidasExceptionSignal);
3943 signal(SIGILL, MidasExceptionSignal);
3944 signal(SIGFPE, MidasExceptionSignal);
3945 signal(SIGSEGV, MidasExceptionSignal);
3946 signal(SIGTERM, MidasExceptionSignal);
3947 signal(SIGBREAK, MidasExceptionSignal);
3948 signal(SIGABRT, MidasExceptionSignal); */
3949
3950#elif defined (OS_VMS)
3951
3952 MidasExceptionHandler = func;
3954
3961
3962#else /* OS_VMS */
3963#endif
3964
3965 return SS_SUCCESS;
3966}
void(* MidasExceptionHandler)(void)
Definition system.cxx:3861
Here is the call graph for this function:

◆ 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 */
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"),
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 call graph for this function:
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 7297 of file system.cxx.

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

◆ ss_file_exist()

INT EXPRT ss_file_exist ( const char path)

Definition at line 7196 of file system.cxx.

7213{
7214#ifdef OS_UNIX
7215 struct stat buf;
7216
7217 int retval = stat(path, &buf);
7218 //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7219 if (retval < 0)
7220 return 0;
7221 if (S_ISDIR(buf.st_mode))
7222 return 0;
7223#endif
7224
7225 int fd = open(path, O_RDONLY, 0);
7226 if (fd < 0)
7227 return 0;
7228 close(fd);
7229 return 1;
7230}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_find() [1/2]

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

Definition at line 6791 of file system.cxx.

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

6827{
6828 assert(plist);
6829 // Check if the directory exists
6830 if (access(path, F_OK) != 0) {
6831 return -1; // Return -1 files if directory doesn't exist
6832 }
6833
6834#ifdef OS_UNIX
6836 struct dirent *dp;
6837
6838 plist->clear();
6839 if ((dir_pointer = opendir(path)) == NULL)
6840 return 0;
6841 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6842 if (fnmatch(pattern, dp->d_name, 0) == 0 && (dp->d_type == DT_REG || dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN)) {
6843 plist->push_back(dp->d_name);
6845 }
6846 }
6848#endif
6849#ifdef OS_WINNT
6850 char str[255];
6851 int first;
6852
6853 strcpy(str, path);
6854 strcat(str, "\\");
6855 strcat(str, pattern);
6856 first = 1;
6858 *plist->clear();
6861 return 0;
6862 first = 0;
6863 plist->push_back(lpfdata->cFileName);
6864 i++;
6865 while (FindNextFile(pffile, lpfdata)) {
6866 plist->push_back(lpfdata->cFileName);
6867 i++;
6868 }
6869 free(lpfdata);
6870#endif
6871 return plist->size();
6872}
Here is the call graph for this function:

◆ ss_file_link_exist()

INT EXPRT ss_file_link_exist ( const char path)

Definition at line 7232 of file system.cxx.

7249{
7250#ifdef OS_UNIX
7251 struct stat buf;
7252
7253 int retval = lstat(path, &buf);
7254 if (retval < 0)
7255 return 0;
7256 if (S_ISLNK(buf.st_mode))
7257 return 1;
7258 return 0;
7259#endif
7260
7261 return 0;
7262}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_remove()

INT EXPRT ss_file_remove ( const char path)

Definition at line 7030 of file system.cxx.

7046{
7047 return remove(path);
7048}
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 7050 of file system.cxx.

7066{
7067#ifdef _LARGEFILE64_SOURCE
7068 struct stat64 stat_buf;
7069 int status;
7070
7071 /* allocate buffer with file size */
7072 status = stat64(path, &stat_buf);
7073 if (status != 0)
7074 return -1;
7075 return (double) stat_buf.st_size;
7076#else
7077 struct stat stat_buf;
7078 int status;
7079
7080 /* allocate buffer with file size */
7081 status = stat(path, &stat_buf);
7082 if (status != 0)
7083 return -1;
7084 return (double) stat_buf.st_size;
7085#endif
7086}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_time()

time_t EXPRT ss_file_time ( const char path)

Definition at line 7088 of file system.cxx.

7104{
7105#ifdef _LARGEFILE64_SOURCE
7106 struct stat64 stat_buf;
7107 int status;
7108
7109 /* allocate buffer with file size */
7110 status = stat64(path, &stat_buf);
7111 if (status != 0)
7112 return -1;
7113 return stat_buf.st_mtime;
7114#else
7115 struct stat stat_buf;
7116 int status;
7117
7118 /* allocate buffer with file size */
7119 status = stat(path, &stat_buf);
7120 if (status != 0)
7121 return -1;
7122 return stat_buf.st_mtime;
7123#endif
7124}
Here is the call graph for this function:
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 call graph for this function:
Here is the caller graph for this function:

◆ ss_get_executable()

std::string ss_get_executable ( void  )

Definition at line 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
Here is the call graph for this function:

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

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

5849{
5850 char *s = getcwd(NULL, 0);
5851 if (s) {
5852 std::string cwd = s;
5853 free(s);
5854 //printf("ss_getcwd: %s\n", cwd.c_str());
5855 return cwd;
5856 } else {
5857 return "/GETCWD-FAILED-ON-US";
5858 }
5859}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_gethostname() [1/2]

std::string ss_gethostname ( )

Definition at line 5784 of file system.cxx.

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

5835{
5836 std::string h = ss_gethostname();
5837
5838 if (h.length() == 0) {
5839 return SS_IO_ERROR;
5840 } else {
5841 mstrlcpy(buffer, h.c_str(), buffer_size);
5842 return SS_SUCCESS;
5843 }
5844}
#define SS_IO_ERROR
Definition midas.h:681
std::string ss_gethostname()
Definition system.cxx:5784
Here is the call graph for this function:

◆ ss_getpass()

char EXPRT * ss_getpass ( const char prompt)

Definition at line 7518 of file system.cxx.

7535{
7536 static char password[32];
7537
7538 fprintf(stdout, "%s", prompt);
7539 fflush(stdout);
7540 memset(password, 0, sizeof(password));
7541
7542#ifdef OS_UNIX
7543 return (char *) getpass("");
7544#elif defined(OS_WINNT)
7545 {
7548
7551 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
7553 printf("\n");
7554
7555 if (password[strlen(password) - 1] == '\r')
7556 password[strlen(password) - 1] = 0;
7557
7558 return password;
7559 }
7560#elif defined(OS_MSDOS)
7561 {
7562 char c, *ptr;
7563
7564 ptr = password;
7565 while ((c = getchar()) != EOF && c != '\n')
7566 *ptr++ = c;
7567 *ptr = 0;
7568
7569 printf("\n");
7570 return password;
7571 }
7572#else
7573 {
7574 ss_gets(password, 32);
7575 return password;
7576 }
7577#endif
7578}
char * ss_gets(char *string, int size)
Definition system.cxx:7848
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 call graph for this function:
Here is the caller graph for this function:

◆ ss_gets()

char EXPRT * ss_gets ( char string,
int  size 
)

Definition at line 7848 of file system.cxx.

7867{
7868 char *p;
7869
7870 do {
7871 p = fgets(string, size, stdin);
7872 } while (p == NULL);
7873
7874
7875 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
7876 p[strlen(p) - 1] = 0;
7877
7878 return p;
7879}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_gettid()

midas_thread_t EXPRT ss_gettid ( void  )

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

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

◆ ss_isfin()

int EXPRT ss_isfin ( double  x)

Definition at line 8044 of file system.cxx.

8045{
8046#ifdef FP_INFINITE
8047 /* new-style finite() */
8048 return isfinite(x);
8049#else
8050 /* old-style finite() */
8051 return finite(x);
8052#endif
8053}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_isnan()

int EXPRT ss_isnan ( double  x)

Definition at line 8039 of file system.cxx.

8040{
8041 return isnan(x);
8042}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_kbhit()

BOOL EXPRT ss_kbhit ( )

Definition at line 3736 of file system.cxx.

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

◆ ss_kill()

void ss_kill ( int  pid)

Definition at line 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}
Here is the call graph for this function:

◆ ss_match_thread()

static bool ss_match_thread ( midas_thread_t  tid1,
midas_thread_t  tid2 
)
static

Definition at line 4065 of file system.cxx.

4066{
4067 if (tid1 == 0)
4068 return true;
4069 if (tid1 == tid2)
4070 return true;
4071 return false;
4072}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_millitime()

DWORD EXPRT ss_millitime ( )

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

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

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

Definition at line 3465 of file system.cxx.

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

3438{
3439 std::lock_guard<std::mutex> lock(gTzMutex);
3440 //defeat mktime() error trap from msystem.h
3441 //#ifdef mktime
3442 //#undef mktime
3443 //#endif
3444 return mktime(tms);
3445}
static std::mutex gTzMutex
Definition system.cxx:3425
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_mutex_create()

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

Definition at line 3013 of file system.cxx.

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

◆ ss_mutex_delete()

INT EXPRT ss_mutex_delete ( MUTEX_T mutex)

Definition at line 3283 of file system.cxx.

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

◆ ss_mutex_release()

INT EXPRT ss_mutex_release ( MUTEX_T mutex)

Definition at line 3229 of file system.cxx.

3247{
3248 INT status;
3249
3250#ifdef OS_WINNT
3251
3252 status = ReleaseMutex(*mutex);
3253 if (status == FALSE)
3254 return SS_NO_SEMAPHORE;
3255
3256 return SS_SUCCESS;
3257
3258#endif /* OS_WINNT */
3259#ifdef OS_VXWORKS
3260
3261 if (semGive((SEM_ID) mutes_handle) == ERROR)
3262 return SS_NO_MUTEX;
3263 return SS_SUCCESS;
3264#endif /* OS_VXWORKS */
3265#ifdef OS_UNIX
3266
3268 if (status != 0) {
3269 fprintf(stderr, "ss_mutex_release: pthread_mutex_unlock() returned error %d (%s), aborting...\n", status, strerror(status));
3270 abort(); // does not return
3271 return SS_NO_MUTEX;
3272 }
3273
3274 return SS_SUCCESS;
3275#endif /* OS_UNIX */
3276
3277#ifdef OS_MSDOS
3278 return SS_NO_MUTEX;
3279#endif
3280}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_mutex_wait_for()

INT EXPRT ss_mutex_wait_for ( MUTEX_T mutex,
INT  timeout 
)

Definition at line 3109 of file system.cxx.

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

8019{
8020 double nan;
8021
8022 nan = 0;
8023 nan = 0 / nan;
8024 return nan;
8025}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_pid_exists()

BOOL ss_pid_exists ( int  pid)

Definition at line 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 call graph for this function:
Here is the caller graph for this function:

◆ ss_printf()

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

Definition at line 7460 of file system.cxx.

7481{
7482 char str[256];
7484
7485 va_start(argptr, format);
7486 vsprintf(str, (char *) format, argptr);
7487 va_end(argptr);
7488
7489#ifdef OS_WINNT
7490 {
7494
7496
7497 dwWriteCoord.X = (short) x;
7498 dwWriteCoord.Y = (short) y;
7499
7501 }
7502
7503#endif /* OS_WINNT */
7504
7505#if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7506 printf("\033[%1d;%1dH", y + 1, x + 1);
7507 printf("%s", str);
7508 fflush(stdout);
7509#endif
7510
7511#ifdef OS_MSDOS
7512 gotoxy(x + 1, y + 1);
7513 cputs(str);
7514#endif
7515}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_recv_net_command()

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

Definition at line 5707 of file system.cxx.

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

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

◆ ss_repair_utf8() [2/2]

bool ss_repair_utf8 ( std::string &  s)

Definition at line 8325 of file system.cxx.

8326{
8327 // C++11 std::string data() is same as c_str(), NUL-terminated.
8328 // C++17 std::string data() is not "const".
8329 // https://en.cppreference.com/w/cpp/string/basic_string/data
8330 return ss_repair_utf8((char*)s.data()); // FIXME: C++17 or newer, do not need to drop the "const". K.O. May 2021
8331}
bool ss_repair_utf8(char *string)
Definition system.cxx:8229
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
2302 }
2303
2304 result.append(inputPath.c_str(), startPos, std::string::npos);
2305 return result;
2306}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_resume()

INT ss_resume ( INT  port,
const char message 
)

Definition at line 4916 of file system.cxx.

4939{
4940 assert(_ss_suspend_odb);
4941
4942 struct sockaddr_in bind_addr;
4943
4944 memcpy(&bind_addr, &_ss_suspend_odb->bind_addr, sizeof(struct sockaddr_in));
4945 bind_addr.sin_port = htons((short) port);
4946
4947 size_t message_size = strlen(message) + 1;
4948
4949 ssize_t wr = sendto(_ss_suspend_odb->ipc_send_socket, message, message_size, 0, (struct sockaddr *) &bind_addr, sizeof(struct sockaddr_in));
4950
4951 if (wr < 0) {
4952 return SS_SOCKET_ERROR;
4953 }
4954
4955 if (((size_t)wr) != message_size) {
4956 return SS_SOCKET_ERROR;
4957 }
4958
4959 return SS_SUCCESS;
4960}
static SUSPEND_STRUCT * _ss_suspend_odb
Definition system.cxx:4052
#define message(type, str)
struct sockaddr_in bind_addr
Definition system.cxx:4046
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_semaphore_create()

INT EXPRT ss_semaphore_create ( const char name,
HNDLE semaphore_handle 
)

Definition at line 2532 of file system.cxx.

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

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

◆ ss_semaphore_release()

INT EXPRT ss_semaphore_release ( HNDLE  semaphore_handle)

Definition at line 2853 of file system.cxx.

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

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

7444{
7445#ifdef OS_WINNT
7446
7449
7450 coordSize.X = (short) x;
7451 coordSize.Y = (short) y;
7454
7455#else /* OS_WINNT */
7456#endif
7457}
Here is the call graph for this function:

◆ ss_settime()

DWORD EXPRT ss_settime ( DWORD  seconds)

Definition at line 3547 of file system.cxx.

3563{
3564#if defined(OS_WINNT)
3565 SYSTEMTIME st;
3566 struct tm ltm;
3567
3568 ss_tzset();
3569 localtime_r((time_t *) & seconds, &ltm);
3570
3571 st.wYear = ltm.tm_year + 1900;
3572 st.wMonth = ltm.tm_mon + 1;
3573 st.wDay = ltm.tm_mday;
3574 st.wHour = ltm.tm_hour;
3575 st.wMinute = ltm.tm_min;
3576 st.wSecond = ltm.tm_sec;
3577 st.wMilliseconds = 0;
3578
3579 SetLocalTime(&st);
3580
3581#elif defined(OS_DARWIN) && defined(CLOCK_REALTIME)
3582
3583 struct timespec ltm;
3584
3585 ltm.tv_sec = seconds;
3586 ltm.tv_nsec = 0;
3588
3589#elif defined(OS_CYGWIN) && defined(CLOCK_REALTIME)
3590
3591 struct timespec ltm;
3592
3593 ltm.tv_sec = seconds;
3594 ltm.tv_nsec = 0;
3596 return SS_NO_DRIVER;
3597
3598#elif defined(OS_UNIX) && defined(CLOCK_REALTIME)
3599
3600 struct timespec ltm;
3601
3602 ltm.tv_sec = seconds;
3603 ltm.tv_nsec = 0;
3605
3606#elif defined(OS_VXWORKS)
3607
3608 struct timespec ltm;
3609
3610 ltm.tv_sec = seconds;
3611 ltm.tv_nsec = 0;
3613
3614#else
3615#warning ss_settime() is not supported!
3616#endif
3617 return SS_SUCCESS;
3618}
#define SS_NO_DRIVER
Definition midas.h:683
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_shell()

INT ss_shell ( int  sock)

Definition at line 1832 of file system.cxx.

1849{
1850#ifdef OS_WINNT
1851
1854
1858 char buffer[256], cmd[256];
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. */
1870
1871 /* Create a pipe for the child's STDOUT. */
1873 return 0;
1874
1875 /* Set a write handle to the pipe to be STDOUT. */
1877 return 0;
1878
1879
1880 /* Save the handle to the current STDERR. */
1882
1883 /* Create a pipe for the child's STDERR. */
1885 return 0;
1886
1887 /* Set a read handle to the pipe to be STDERR. */
1889 return 0;
1890
1891
1892 /* Save the handle to the current STDIN. */
1894
1895 /* Create a pipe for the child's STDIN. */
1897 return 0;
1898
1899 /* Set a read handle to the pipe to be STDIN. */
1901 return 0;
1902
1903 /* Duplicate the write handle to the pipe so it is not inherited. */
1906 return 0;
1907
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. */
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) {
1993 i_cmd = 0;
1994 }
1995
1996 } while (TRUE);
1997
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];
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
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
Here is the call graph for this function:

◆ ss_shm_close()

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

Definition at line 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
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:669
#define SS_INVALID_HANDLE
Definition midas.h:667
#define SS_INVALID_ADDRESS
Definition midas.h:668
INT ss_shm_delete(const char *name)
Definition system.cxx: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
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
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
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) {
264 } else if (use_posix2_shm) {
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 += "_";
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 += "_";
285 shm_name += "_";
286 shm_name += name;
287 shm_name += "_";
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:1594
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
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 {
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
392 if (hMap == 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
411
412 if (!hMap) {
414 cm_msg(MERROR, "ss_shm_open", "CreateFileMapping() failed, error %d", status);
415 return SS_FILE_ERROR;
416 }
417
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
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:690
#define O_BINARY
Definition msystem.h:226
double ss_file_size(const char *path)
Definition system.cxx:7050
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)
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 3700 of file system.cxx.

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

◆ ss_socket_check()

static int ss_socket_check ( int  sock)
static

Definition at line 4565 of file system.cxx.

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

5304{
5305 assert(sockp != NULL);
5306 if (gSocketTrace) {
5307 fprintf(stderr, "ss_socket_close: %d\n", *sockp);
5308 }
5309 int err = close(*sockp);
5310 if (err) {
5311 cm_msg(MERROR, "ss_socket_close", "unexpected error, close() returned %d, errno: %d (%s)", err, errno, strerror(errno));
5312 }
5313 *sockp = 0;
5314 return SS_SUCCESS;
5315}
static bool gSocketTrace
Definition system.cxx:5036
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 5039 of file system.cxx.

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

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

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

4987{
4988 INT status;
4990 struct timeval timeout;
4991 struct timeval timeout0;
4992 DWORD start_time = 0; // start_time is only used for BSD select() behaviour (MacOS)
4993 DWORD end_time = 0;
4994
4995 FD_ZERO(&readfds);
4996 FD_SET(sock, &readfds);
4997
4998 timeout.tv_sec = millisec / 1000;
4999 timeout.tv_usec = (millisec % 1000) * 1000;
5000
5001 timeout0 = timeout;
5002
5003 while (1) {
5004 status = select(sock+1, &readfds, NULL, NULL, &timeout);
5005 //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));
5006
5007#ifndef OS_WINNT
5008 if (status<0 && errno==EINTR) { /* watchdog alarm signal */
5009 /* need to determine if select() updates "timeout" (Linux) or keeps original value (BSD) */
5010 if (timeout.tv_sec == timeout0.tv_sec) {
5011 DWORD now = ss_time();
5012 if (start_time == 0) {
5013 start_time = now;
5014 end_time = start_time + (millisec+999)/1000;
5015 }
5016 //printf("ss_socket_wait: EINTR: now %d, timeout %d, wait time %d\n", now, end_time, end_time - now);
5017 if (now > end_time)
5018 return SS_TIMEOUT;
5019 }
5020 continue;
5021 }
5022#endif
5023 if (status < 0) { /* select() syscall error */
5024 cm_msg(MERROR, "ss_socket_wait", "unexpected error, select() returned %d, errno: %d (%s)", status, errno, strerror(errno));
5025 return SS_SOCKET_ERROR;
5026 }
5027 if (status == 0) /* timeout */
5028 return SS_TIMEOUT;
5029 if (!FD_ISSET(sock, &readfds))
5030 return SS_TIMEOUT;
5031 return SS_SUCCESS;
5032 }
5033 /* NOT REACHED */
5034}
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;
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++) {
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
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
1816#else
1818#endif
1819
1820 } else {
1821 /* catch SIGCHLD signal to avoid <defunc> processes */
1823 }
1824 }
1825
1826 return SS_SUCCESS;
1827
1828#endif /* OS_UNIX */
1829}
#define SS_INVALID_NAME
Definition midas.h:666
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_stack_get()

INT EXPRT ss_stack_get ( char ***  string)

Definition at line 8072 of file system.cxx.

8073{
8074#ifdef OS_LINUX
8075#define MAX_STACK_DEPTH 16
8076
8077 void *trace[MAX_STACK_DEPTH];
8078 int size;
8079
8081 *string = backtrace_symbols(trace, size);
8082 return size;
8083#else
8084 return 0;
8085#endif
8086}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_stack_history_dump()

void EXPRT ss_stack_history_dump ( char filename)

Definition at line 8122 of file system.cxx.

8123{
8124 FILE *f;
8125 int i, j;
8126
8127 f = fopen(filename, "wt");
8128 if (f != NULL) {
8130 for (i = 0; i < N_STACK_HISTORY; i++) {
8131 if (strlen(stack_history[j]) > 0)
8132 fprintf(f, "%s\n", stack_history[j]);
8133 j = (j + 1) % N_STACK_HISTORY;
8134 }
8135 fclose(f);
8136 printf("Stack dump written to %s\n", filename);
8137 } else
8138 printf("Cannot open %s: errno=%d\n", filename, errno);
8139}
#define N_STACK_HISTORY
Definition system.cxx:8068
char stack_history[N_STACK_HISTORY][80]
Definition system.cxx:8069
int stack_history_pointer
Definition system.cxx:8070
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:

◆ ss_stack_history_entry()

void EXPRT ss_stack_history_entry ( char tag)

Definition at line 8100 of file system.cxx.

8101{
8102 char **string;
8103 int i, n;
8104
8105 if (stack_history_pointer == -1) {
8107 memset(stack_history, 0, sizeof(stack_history));
8108 }
8111 n = ss_stack_get(&string);
8112 for (i = 2; i < n; i++) {
8115 }
8116 free(string);
8117
8118 mstrlcpy(stack_history[stack_history_pointer], "=========================", 80);
8120}
INT ss_stack_get(char ***string)
Definition system.cxx:8072
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 8088 of file system.cxx.

8089{
8090 char **string;
8091 int i, n;
8092
8093 n = ss_stack_get(&string);
8094 for (i = 0; i < n; i++)
8095 printf("%s\n", string[i]);
8096 if (n > 0)
8097 free(string);
8098}
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 4615 of file system.cxx.

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

4280{
4281 if (psuspend->ipc_recv_socket) {
4282 closesocket(psuspend->ipc_recv_socket);
4283 psuspend->ipc_recv_socket = 0;
4284 }
4285
4286 if (psuspend->ipc_send_socket) {
4287 closesocket(psuspend->ipc_send_socket);
4288 psuspend->ipc_send_socket = 0;
4289 }
4290
4291 //printf("ss_suspend_close: free thread %s, udp port %d\n", ss_tid_to_string(psuspend->thread_id).c_str(), psuspend->ipc_recv_port);
4292
4293 psuspend->thread_id = 0;
4294 psuspend->ipc_recv_port = 0;
4295}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_exit()

INT ss_suspend_exit ( )

Definition at line 4298 of file system.cxx.

4316{
4317 midas_thread_t thread_id = ss_gettid();
4318
4319 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4320 if (!_ss_suspend_vector[i])
4321 continue;
4322 if (_ss_suspend_vector[i]->thread_id == thread_id) {
4326 delete psuspend;
4327 }
4328 }
4329
4330 if (_ss_suspend_odb) {
4331 bool last = true;
4332 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4333 if (_ss_suspend_vector[i]) {
4334 last = false;
4335 break;
4336 }
4337 }
4338 if (last) {
4342 delete psuspend;
4343 }
4344 }
4345
4346 return SS_SUCCESS;
4347}
static void ss_suspend_close(SUSPEND_STRUCT *psuspend)
Definition system.cxx:4279
static std::vector< SUSPEND_STRUCT * > _ss_suspend_vector
Definition system.cxx:4049
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 4425 of file system.cxx.

4446{
4448
4449 if (!psuspend->ipc_recv_port) {
4451 }
4452
4453 *port = psuspend->ipc_recv_port;
4454
4455 return SS_SUCCESS;
4456}
static INT ss_suspend_init_struct(SUSPEND_STRUCT *psuspend)
Definition system.cxx:4084
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 4399 of file system.cxx.

4416{
4417 assert(_ss_suspend_odb);
4418
4420
4421 return SS_SUCCESS;
4422}
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 4237 of file system.cxx.

4251{
4252 // find thread_id
4253 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4254 if (!_ss_suspend_vector[i])
4255 continue;
4256 if (_ss_suspend_vector[i]->thread_id == thread_id) {
4257 return _ss_suspend_vector[i];
4258 }
4259 }
4260
4261 // create new one if not found
4263 psuspend->thread_id = thread_id;
4264
4265 // place into empty slot
4266 for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4267 if (!_ss_suspend_vector[i]) {
4269 return psuspend;
4270 }
4271 }
4272
4273 // add to vector if no empty slots
4274 _ss_suspend_vector.push_back(psuspend);
4275
4276 return psuspend;
4277}
struct suspend_struct SUSPEND_STRUCT
midas_thread_t thread_id
Definition system.cxx:4042
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_init_odb_port()

INT ss_suspend_init_odb_port ( )

Definition at line 4377 of file system.cxx.

4388{
4389 if (!_ss_suspend_odb) {
4393 }
4394
4395 return SS_SUCCESS;
4396}
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 4084 of file system.cxx.

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

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

4364{
4365 // client side of the mserver connection
4367 return SS_SUCCESS;
4368}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_set_client_listener()

INT ss_suspend_set_client_listener ( int  listen_socket)

Definition at line 4356 of file system.cxx.

4357{
4358 // midas program rpc listener socket (run transitions, etc)
4360 return SS_SUCCESS;
4361}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_set_rpc_thread()

INT ss_suspend_set_rpc_thread ( midas_thread_t  thread_id)

Definition at line 4074 of file system.cxx.

4075{
4076 _ss_listen_thread = thread_id; // this thread handles listen()/accept() activity
4077 _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())
4078 _ss_server_thread = thread_id; // this thread reads and executes RPC requests
4079 _ss_odb_thread = thread_id; // this thread reads and dispatches ODB notifications (db_watch & co)
4080 return SS_SUCCESS;
4081}
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 4370 of file system.cxx.

4371{
4372 // server side of the RPC connections (run transitions, etc)
4374 return SS_SUCCESS;
4375}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_set_server_listener()

INT ss_suspend_set_server_listener ( int  listen_socket)

Definition at line 4349 of file system.cxx.

4350{
4351 // mserver listener socket
4353 return SS_SUCCESS;
4354}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_system()

INT EXPRT ss_system ( const char command)

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

{ ...
char cmd[256];
sprintf(cmd,"%s %s %i %s/%s %1.3lf %d",lazy.commandAfter,
lazyst.file_size/1000.0/1000.0, blockn);
cm_msg(MINFO,"Lazy","Exec post file write script:%s",cmd);
ss_system(cmd);
}
...
INT ss_system(const char *command)
Definition system.cxx: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 5980 of file system.cxx.

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

6329{
6330#ifdef MTIOCTOP
6331 struct mtop arg;
6332 INT status;
6333
6334 if (count > 0)
6335 arg.mt_op = MTFSF;
6336 else
6337 arg.mt_op = MTBSF;
6338 arg.mt_count = abs(count);
6339
6340 //cm_enable_watchdog(FALSE);
6341
6342 status = ioctl(channel, MTIOCTOP, &arg);
6343
6344 //cm_enable_watchdog(TRUE);
6345
6346 if (status < 0) {
6347 cm_msg(MERROR, "ss_tape_fskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6348 return errno;
6349 }
6350#endif /* OS_UNIX */
6351
6352#ifdef OS_WINNT
6353 INT status;
6354
6356
6358 return SS_END_OF_TAPE;
6359
6360 if (status != NO_ERROR) {
6361 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
6362 return status;
6363 }
6364#endif /* OS_WINNT */
6365
6366 return SS_SUCCESS;
6367}
#define SS_END_OF_TAPE
Definition midas.h:684
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_get_blockn()

INT EXPRT ss_tape_get_blockn ( INT  channel)

Definition at line 6646 of file system.cxx.

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

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

5911{
5912#ifdef OS_UNIX
5913 //cm_enable_watchdog(FALSE);
5914
5915 *channel = open(path, oflag, 0644);
5916
5917 //cm_enable_watchdog(TRUE);
5918
5919 if (*channel < 0)
5920 cm_msg(MERROR, "ss_tape_open", "open() returned %d, errno %d (%s)", *channel, errno, strerror(errno));
5921
5922 if (*channel < 0) {
5923 if (errno == EIO)
5924 return SS_NO_TAPE;
5925 if (errno == EBUSY)
5926 return SS_DEV_BUSY;
5927 return errno;
5928 }
5929#ifdef MTSETBLK
5930 {
5931 /* set variable block size */
5932 struct mtop arg;
5933 arg.mt_op = MTSETBLK;
5934 arg.mt_count = 0;
5935
5936 ioctl(*channel, MTIOCTOP, &arg);
5937 }
5938#endif /* MTSETBLK */
5939
5940#endif /* OS_UNIX */
5941
5942#ifdef OS_WINNT
5943 INT status;
5945
5947
5948 if (*channel == (INT) INVALID_HANDLE_VALUE) {
5949 status = GetLastError();
5951 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
5952 return SS_DEV_BUSY;
5953 }
5955 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
5956 return SS_NO_TAPE;
5957 }
5958
5959 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
5960 return status;
5961 }
5962
5965 cm_msg(MERROR, "ss_tape_open", "no media in drive");
5966 return SS_NO_TAPE;
5967 }
5968
5969 /* set block size */
5970 memset(&m, 0, sizeof(m));
5971 m.BlockSize = TAPE_BUFFER_SIZE;
5973
5974#endif
5975
5976 return SS_SUCCESS;
5977}
#define SS_NO_TAPE
Definition midas.h:679
#define SS_DEV_BUSY
Definition midas.h:680
#define TAPE_BUFFER_SIZE
Definition midas.h:264
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_read()

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

Definition at line 6170 of file system.cxx.

6190{
6191#ifdef OS_UNIX
6192 INT n, status;
6193
6194 do {
6195 n = read(channel, pdata, *count);
6196 } while (n == -1 && errno == EINTR);
6197
6198 if (n == -1) {
6199 if (errno == ENOSPC || errno == EIO)
6201 else {
6202 if (n == 0 && errno == 0)
6204 else {
6205 cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", n, errno);
6206 status = errno;
6207 }
6208 }
6209 } else
6211 *count = n;
6212
6213 return status;
6214
6215#elif defined(OS_WINNT) /* OS_UNIX */
6216
6217 INT status;
6218 DWORD read;
6219
6220 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
6221 status = GetLastError();
6224 else if (status == ERROR_FILEMARK_DETECTED)
6226 else if (status == ERROR_MORE_DATA)
6228 else
6229 cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", read, status);
6230 } else
6232
6233 *count = read;
6234 return status;
6235
6236#else /* OS_WINNT */
6237
6238 return SS_SUCCESS;
6239
6240#endif
6241}
#define SS_END_OF_FILE
Definition midas.h:685
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tape_rewind()

INT EXPRT ss_tape_rewind ( INT  channel)

Definition at line 6426 of file system.cxx.

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

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

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

6041{
6042#ifdef OS_UNIX
6043 int status;
6044 char str[256];
6045 /* let 'mt' do the job */
6046 sprintf(str, "mt -f %s status", path);
6047 status = system(str);
6048 if (status == -1)
6049 return SS_TAPE_ERROR;
6050 return SS_SUCCESS;
6051#endif /* OS_UNIX */
6052
6053#ifdef OS_WINNT
6055 DWORD size;
6058 double x;
6059
6061
6062 if (channel == (INT) INVALID_HANDLE_VALUE) {
6063 status = GetLastError();
6065 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
6066 return SS_SUCCESS;
6067 }
6069 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
6070 return SS_SUCCESS;
6071 }
6072
6073 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
6074 return status;
6075 }
6076
6077 /* poll media changed messages */
6080
6083 cm_msg(MINFO, "ss_tape_status", "no media in drive");
6085 return SS_SUCCESS;
6086 }
6087
6090
6091 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
6092 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
6093 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
6094
6095 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
6096 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
6097 / 1000.0 / 1000.0;
6098 printf("Tape capacity remaining is %d MB\n", (int) x);
6099 } else
6100 printf("Tape capacity is not reported by tape\n");
6101
6103
6104#endif
6105
6106 return SS_SUCCESS;
6107}
#define SS_TAPE_ERROR
Definition midas.h:682
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 6590 of file system.cxx.

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

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

6262{
6263#ifdef MTIOCTOP
6264 struct mtop arg;
6265 INT status;
6266
6267 arg.mt_op = MTWEOF;
6268 arg.mt_count = 1;
6269
6270 //cm_enable_watchdog(FALSE);
6271
6272 status = ioctl(channel, MTIOCTOP, &arg);
6273
6274 //cm_enable_watchdog(TRUE);
6275
6276 if (status < 0) {
6277 cm_msg(MERROR, "ss_tape_write_eof", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6278 return errno;
6279 }
6280#endif /* OS_UNIX */
6281
6282#ifdef OS_WINNT
6283
6285 DWORD size;
6286 INT status;
6287
6288 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
6290
6291 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
6293 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
6295 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
6297 else
6298 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
6299
6300 if (status != NO_ERROR) {
6301 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
6302 return status;
6303 }
6304#endif /* OS_WINNT */
6305
6306 return SS_SUCCESS;
6307}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_thread_create()

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

Creates and returns a new thread of execution.

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

Example for VxWorks

...
VX_TASK_SPAWN tsWatch = {"Watchdog", 100, 0, 2000, (int) pDevice, 0, 0, 0, 0, 0, 0, 0, 0 ,0};
if (thread_id == 0) {
printf("cannot spawn taskWatch\n");
}
...
midas_thread_t ss_thread_create(INT(*thread_func)(void *), void *param)
Definition system.cxx: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
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;
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 call graph for this function:
Here is the caller graph for this function:

◆ ss_thread_get_name()

std::string ss_thread_get_name ( )

Definition at line 2516 of file system.cxx.

2517{
2518#if defined(OS_UNIX)
2519 char str[256];
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
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:672
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_thread_set_name()

INT EXPRT ss_thread_set_name ( std::string  name)

Definition at line 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
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 call graph for this function:
Here is the caller graph for this function:

◆ ss_time()

DWORD EXPRT ss_time ( )

Returns the actual time in seconds since 1.1.1970 UTC.

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

Definition at line 3534 of file system.cxx.

3535{
3536 return (DWORD) time(NULL);
3537}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_time_sec()

double EXPRT ss_time_sec ( )

Definition at line 3539 of file system.cxx.

3540{
3541 struct timeval tv;
3542 gettimeofday(&tv, NULL);
3543 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
3544}
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 3337 of file system.cxx.

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

3670{
3671#if defined(OS_DARWIN) || defined(OS_VXWORKS)
3672 return 0;
3673#else
3674 return (INT) timezone; /* on Linux, comes from "#include <time.h>". */
3675#endif
3676}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_tzset()

void EXPRT ss_tzset ( )

Definition at line 3427 of file system.cxx.

3428{
3429 std::lock_guard<std::mutex> lock(gTzMutex);
3430 //defeat tzset() error trap from msystem.h
3431 //#ifdef tzset
3432 //#undef tzset
3433 //#endif
3434 tzset();
3435}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_us_since()

Definition at line 8338 of file system.cxx.

8338 {
8339 auto elapsed = std::chrono::high_resolution_clock::now() - start;
8340 return std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
8341}
Here is the call graph for this function:

◆ ss_us_start()

Definition at line 8333 of file system.cxx.

8334{
8335 return std::chrono::high_resolution_clock::now();
8336}

◆ ss_write_tcp()

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

Definition at line 5424 of file system.cxx.

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

◆ _ss_client_listen_socket

int _ss_client_listen_socket = 0
static

Definition at line 4056 of file system.cxx.

◆ _ss_client_thread

midas_thread_t _ss_client_thread = 0
static

Definition at line 4058 of file system.cxx.

◆ _ss_listen_thread

midas_thread_t _ss_listen_thread = 0
static

Definition at line 4054 of file system.cxx.

◆ _ss_odb_thread

midas_thread_t _ss_odb_thread = 0
static

Definition at line 4051 of file system.cxx.

◆ _ss_server_acceptions

RPC_SERVER_ACCEPTION_LIST* _ss_server_acceptions = NULL
static

Definition at line 4062 of file system.cxx.

◆ _ss_server_listen_socket

int _ss_server_listen_socket = 0
static

Definition at line 4055 of file system.cxx.

◆ _ss_server_thread

midas_thread_t _ss_server_thread = 0
static

Definition at line 4061 of file system.cxx.

◆ _ss_suspend_odb

SUSPEND_STRUCT* _ss_suspend_odb = NULL
static

Definition at line 4052 of file system.cxx.

◆ _ss_suspend_vector

std::vector<SUSPEND_STRUCT*> _ss_suspend_vector
static

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

◆ gTzMutex

std::mutex gTzMutex
static

Definition at line 3425 of file system.cxx.

◆ MidasExceptionHandler

void(* MidasExceptionHandler) (void) ( void  )

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

◆ stack_history_pointer

int stack_history_pointer = -1

Definition at line 8070 of file system.cxx.

◆ [struct]

struct { ... } test_align

◆ [struct]

struct { ... } test_padding