MIDAS
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)
 
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, INT timeout)
 
INT ss_semaphore_release (HNDLE semaphore_handle)
 
INT ss_semaphore_delete (HNDLE semaphore_handle, INT destroy_flag)
 
INT ss_mutex_create (MUTEX_T **mutex, BOOL recursive)
 
INT ss_mutex_wait_for (MUTEX_T *mutex, INT timeout)
 
INT ss_mutex_release (MUTEX_T *mutex)
 
INT ss_mutex_delete (MUTEX_T *mutex)
 
bool ss_timed_mutex_wait_for_sec (std::timed_mutex &mutex, const char *mutex_name, double timeout_sec)
 
void ss_tzset ()
 
time_t ss_mktime (struct tm *tms)
 
DWORD ss_millitime ()
 
DWORD ss_time ()
 
double ss_time_sec ()
 
DWORD ss_settime (DWORD seconds)
 
std::string ss_asctime ()
 
INT ss_timezone ()
 
INT ss_sleep (INT millisec)
 
BOOL ss_kbhit ()
 
INT ss_alarm (INT millitime, void(*func)(int))
 
INT ss_exception_handler (void(*func)(void))
 
void * ss_ctrlc_handler (void(*func)(int))
 
static bool ss_match_thread (midas_thread_t tid1, midas_thread_t tid2)
 
INT ss_suspend_set_rpc_thread (midas_thread_t thread_id)
 
static INT ss_suspend_init_struct (SUSPEND_STRUCT *psuspend)
 
SUSPEND_STRUCTss_suspend_get_struct (midas_thread_t thread_id)
 
static void ss_suspend_close (SUSPEND_STRUCT *psuspend)
 
INT ss_suspend_exit ()
 
INT ss_suspend_set_server_listener (int listen_socket)
 
INT ss_suspend_set_client_listener (int listen_socket)
 
INT ss_suspend_set_client_connection (RPC_SERVER_CONNECTION *connection)
 
INT ss_suspend_set_server_acceptions (RPC_SERVER_ACCEPTION_LIST *acceptions)
 
INT ss_suspend_init_odb_port ()
 
INT ss_suspend_get_odb_port (INT *port)
 
INT ss_suspend_get_buffer_port (midas_thread_t thread_id, INT *port)
 
static int ss_suspend_process_ipc (INT millisec, INT msg, int ipc_recv_socket)
 
static int ss_socket_check (int sock)
 
bool ss_event_socket_has_data ()
 
INT ss_suspend (INT millisec, INT msg)
 
INT ss_resume (INT port, const char *message)
 
int ss_socket_wait (int sock, INT millisec)
 
INT ss_socket_connect_tcp (const char *hostname, int tcp_port, int *sockp, std::string *error_msg_p)
 
INT ss_socket_listen_tcp (bool listen_localhost, int tcp_port, int *sockp, int *tcp_port_p, std::string *error_msg_p)
 
INT ss_socket_close (int *sockp)
 
INT ss_socket_get_peer_name (int sock, std::string *hostp, int *portp)
 
INT send_tcp (int sock, char *buffer, DWORD buffer_size, INT flags)
 
INT ss_write_tcp (int sock, const char *buffer, size_t buffer_size)
 
INT recv_string (int sock, char *buffer, DWORD buffer_size, INT millisec)
 
INT recv_tcp (int sock, char *net_buffer, DWORD buffer_size, INT flags)
 
INT recv_tcp2 (int sock, char *net_buffer, int buffer_size, int timeout_ms)
 
INT ss_recv_net_command (int sock, DWORD *routine_id, DWORD *param_size, char **param_ptr, int timeout_ms)
 
std::string ss_gethostname ()
 
INT ss_gethostname (char *buffer, int buffer_size)
 
std::string ss_getcwd ()
 
INT ss_tape_open (char *path, INT oflag, INT *channel)
 
INT ss_tape_close (INT channel)
 
INT ss_tape_status (char *path)
 
INT ss_tape_write (INT channel, void *pdata, INT count)
 
INT ss_tape_read (INT channel, void *pdata, INT *count)
 
INT ss_tape_write_eof (INT channel)
 
INT ss_tape_fskip (INT channel, INT count)
 
INT ss_tape_rskip (INT channel, INT count)
 
INT ss_tape_rewind (INT channel)
 
INT ss_tape_spool (INT channel)
 
INT ss_tape_mount (INT channel)
 
INT ss_tape_unmount (INT channel)
 
INT ss_tape_get_blockn (INT channel)
 
double ss_disk_free (const char *path)
 
INT ss_file_find (const char *path, const char *pattern, char **plist)
 
INT ss_file_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_dir_find (const char *path, const char *pattern, char **plist)
 
INT ss_dir_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_dirlink_find (const char *path, const char *pattern, char **plist)
 
INT ss_dirlink_find (const char *path, const char *pattern, STRING_LIST *plist)
 
INT ss_file_remove (const char *path)
 
double ss_file_size (const char *path)
 
time_t ss_file_time (const char *path)
 
double ss_disk_size (const char *path)
 
int ss_file_exist (const char *path)
 
int ss_file_link_exist (const char *path)
 
int ss_dir_exist (const char *path)
 
int ss_file_copy (const char *src, const char *dst, bool append)
 
void ss_clear_screen ()
 
void ss_set_screen_size (int x, int y)
 
void ss_printf (INT x, INT y, const char *format,...)
 
char * ss_getpass (const char *prompt)
 
INT ss_getchar (BOOL reset)
 
char * ss_gets (char *string, int size)
 
INT ss_directio_give_port (INT start, INT end)
 
INT ss_directio_lock_port (INT start, INT end)
 
char * ss_crypt (const char *buf, const char *salt)
 
double ss_nan ()
 
int ss_isnan (double x)
 
int ss_isfin (double x)
 
INT ss_stack_get (char ***string)
 
void ss_stack_print ()
 
void ss_stack_history_entry (char *tag)
 
void ss_stack_history_dump (char *filename)
 
bool ss_is_valid_utf8 (const char *string)
 
bool ss_repair_utf8 (char *string)
 
bool ss_repair_utf8 (std::string &s)
 
std::chrono::time_point< std::chrono::high_resolution_clock > ss_us_start ()
 
unsigned int ss_us_since (std::chrono::time_point< std::chrono::high_resolution_clock > start)
 
int rpc_flush_event_socket (int timeout_msec)
 

Variables

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

Detailed Description

dox


Macro Definition Documentation

◆ bin_to_ascii

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

Definition at line 7828 of file system.cxx.

◆ N_STACK_HISTORY

#define N_STACK_HISTORY   500

Definition at line 7929 of file system.cxx.

Typedef Documentation

◆ SUSPEND_STRUCT

Function Documentation

◆ check_shm_host()

static void check_shm_host ( )
static

Definition at line 174 of file system.cxx.

175 {
176  char file_name[256];
177  const int file_name_size = sizeof(file_name);
178  char path[256];
179  char buf[256];
180  char hostname[256];
181  char* s;
182  FILE *fp;
183 
184  gethostname(hostname, sizeof(hostname));
185 
186  //printf("hostname [%s]\n", hostname);
187 
188  cm_get_path(path, sizeof(path));
189  if (path[0] == 0) {
190  if (!getcwd(path, sizeof(path)))
191  path[0] = 0;
192 #if defined(OS_VMS)
193 #elif defined(OS_UNIX)
194  strlcat(path, "/", sizeof(path));
195 #elif defined(OS_WINNT)
196  strlcat(path, "\\", sizeof(path));
197 #endif
198  }
199 
200  strlcpy(file_name, path, file_name_size);
201 #if defined (OS_UNIX)
202  strlcat(file_name, ".", file_name_size); /* dot file under UNIX */
203 #endif
204  strlcat(file_name, "SHM_HOST", file_name_size);
205  strlcat(file_name, ".TXT", file_name_size);
206 
207  fp = fopen(file_name, "r");
208  if (!fp) {
209  fp = fopen(file_name, "w");
210  if (!fp)
211  cm_msg(MERROR, "check_shm_host", "Cannot write to \'%s\', errno %d (%s)", file_name, errno, strerror(errno));
212  assert(fp != NULL);
213  fprintf(fp, "%s\n", hostname);
214  fclose(fp);
215  return;
216  }
217 
218  buf[0] = 0;
219 
220  if (!fgets(buf, sizeof(buf), fp))
221  buf[0] = 0;
222 
223  fclose(fp);
224 
225  s = strchr(buf, '\n');
226  if (s)
227  *s = 0;
228 
229  if (strlen(buf) < 1)
230  return; // success - provide user with a way to defeat this check
231 
232  if (strcmp(buf, hostname) == 0)
233  return; // success!
234 
235  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, buf);
236  exit(1);
237 }
INT cm_get_path(char *path, int path_size)
Definition: midas.cxx:1520
#define MERROR
Definition: midas.h:565
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition: midas.cxx:917
size_t EXPRT strlcat(char *dst, const char *src, size_t size)
size_t EXPRT strlcpy(char *dst, const char *src, size_t size)
static FILE * fp
Definition: mlxspeaker.cxx:24
char file_name[256]
Definition: odbhist.cxx:41
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_shm_type()

static void check_shm_type ( const char *  shm_type)
static

Definition at line 83 of file system.cxx.

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

5357 {
5358  INT i, status;
5359  DWORD n;
5360 
5361  n = 0;
5362  memset(buffer, 0, buffer_size);
5363 
5364  do {
5365  if (millisec > 0) {
5366  status = ss_socket_wait(sock, millisec);
5367  if (status != SS_SUCCESS)
5368  break;
5369  }
5370 
5371  i = recv(sock, buffer + n, 1, 0);
5372 
5373  if (i <= 0)
5374  break;
5375 
5376  n++;
5377 
5378  if (n >= buffer_size)
5379  break;
5380 
5381  } while (buffer[n - 1] && buffer[n - 1] != 10);
5382 
5383  return n - 1;
5384 }
#define SS_SUCCESS
Definition: midas.h:669
unsigned int DWORD
Definition: mcstd.h:51
int ss_socket_wait(int sock, INT millisec)
Definition: system.cxx:4837
DWORD n[4]
Definition: mana.cxx:247
INT i
Definition: mdump.cxx:35
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 5387 of file system.cxx.

5417 {
5418  INT param_size, n_received, n;
5419  NET_COMMAND *nc;
5420 
5421  if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
5422  cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
5423  return -1;
5424  }
5425 
5426  /* first receive header */
5427  n_received = 0;
5428  do {
5429 #ifdef OS_UNIX
5430  do {
5431  n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
5432 
5433  /* don't return if an alarm signal was cought */
5434  } while (n == -1 && errno == EINTR);
5435 #else
5436  n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
5437 #endif
5438 
5439  if (n == 0) {
5440  cm_msg(MERROR, "recv_tcp", "header: recv(%d) returned %d, n_received = %d, unexpected connection closure", (int)sizeof(NET_COMMAND_HEADER), n, n_received);
5441  return n;
5442  }
5443 
5444  if (n < 0) {
5445  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));
5446  return n;
5447  }
5448 
5449  n_received += n;
5450 
5451  } while (n_received < (int) sizeof(NET_COMMAND_HEADER));
5452 
5453  /* now receive parameters */
5454 
5455  nc = (NET_COMMAND *) net_buffer;
5456  param_size = nc->header.param_size;
5457  n_received = 0;
5458 
5459  if (param_size == 0)
5460  return sizeof(NET_COMMAND_HEADER);
5461 
5462  if (param_size > (INT)buffer_size) {
5463  cm_msg(MERROR, "recv_tcp", "param: receive buffer size %d is too small for received data size %d", buffer_size, param_size);
5464  return -1;
5465  }
5466 
5467  do {
5468 #ifdef OS_UNIX
5469  do {
5470  n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received, param_size - n_received, flags);
5471 
5472  /* don't return if an alarm signal was cought */
5473  } while (n == -1 && errno == EINTR);
5474 #else
5475  n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received, param_size - n_received, flags);
5476 #endif
5477 
5478  if (n == 0) {
5479  cm_msg(MERROR, "recv_tcp", "param: recv() returned %d, n_received = %d, unexpected connection closure", n, n_received);
5480  return n;
5481  }
5482 
5483  if (n < 0) {
5484  cm_msg(MERROR, "recv_tcp", "param: recv() returned %d, n_received = %d, errno: %d (%s)", n, n_received, errno, strerror(errno));
5485  return n;
5486  }
5487 
5488  n_received += n;
5489  } while (n_received < param_size);
5490 
5491  return sizeof(NET_COMMAND_HEADER) + param_size;
5492 }
NET_COMMAND_HEADER header
Definition: msystem.h:286
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_tcp2()

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

Definition at line 5495 of file system.cxx.

5521 {
5522  int n_received = 0;
5523  int flags = 0;
5524  int n;
5525 
5526  //printf("recv_tcp2: %p+%d bytes, timeout %d ms!\n", net_buffer + n_received, buffer_size - n_received, timeout_ms);
5527 
5528  while (n_received != buffer_size) {
5529 
5530  if (timeout_ms > 0) {
5531  int status = ss_socket_wait(sock, timeout_ms);
5532  if (status == SS_TIMEOUT)
5533  return n_received;
5534  if (status != SS_SUCCESS)
5535  return -1;
5536  }
5537 
5538  n = recv(sock, net_buffer + n_received, buffer_size - n_received, flags);
5539 
5540  //printf("recv_tcp2: %p+%d bytes, returned %d, errno %d (%s)\n", net_buffer + n_received, buffer_size - n_received, n, errno, strerror(errno));
5541 
5542 #ifdef EINTR
5543  /* don't return if an alarm signal was cought */
5544  if (n == -1 && errno == EINTR)
5545  continue;
5546 #endif
5547 
5548  if (n == 0) {
5549  // socket closed
5550  cm_msg(MERROR, "recv_tcp2", "unexpected connection closure");
5551  return -1;
5552  }
5553 
5554  if (n < 0) {
5555  // socket error
5556  cm_msg(MERROR, "recv_tcp2", "unexpected connection error, recv() errno %d (%s)", errno, strerror(errno));
5557  return -1;
5558  }
5559 
5560  n_received += n;
5561  }
5562 
5563  return n_received;
5564 }
#define SS_TIMEOUT
Definition: midas.h:680
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 16103 of file midas.cxx.

16117 {
16118  bool has_data = ss_event_socket_has_data();
16119 
16120  //printf("ss_event_socket_has_data() returned %d\n", has_data);
16121 
16122  if (has_data) {
16123  if (timeout_msec == BM_NO_WAIT) {
16124  return BM_ASYNC_RETURN;
16125  } else if (timeout_msec == BM_WAIT) {
16126  return BM_ASYNC_RETURN;
16127  } else {
16128  int status = ss_suspend(timeout_msec, MSG_BM);
16129  if (status == SS_ABORT || status == SS_EXIT)
16130  return status;
16131  return BM_ASYNC_RETURN;
16132  }
16133  }
16134 
16135  int status = rpc_server_receive_event(0, NULL, timeout_msec);
16136 
16137  //printf("rpc_server_receive_event() status %d\n", status);
16138 
16139  if (status == BM_ASYNC_RETURN) {
16140  return BM_ASYNC_RETURN;
16141  }
16142 
16143  if (status == SS_ABORT || status == SS_EXIT)
16144  return status;
16145 
16146  return BM_SUCCESS;
16147 }
#define BM_ASYNC_RETURN
Definition: midas.h:619
#define BM_SUCCESS
Definition: midas.h:611
#define SS_ABORT
Definition: midas.h:683
#define SS_EXIT
Definition: midas.h:684
#define BM_NO_WAIT
Definition: midas.h:373
#define BM_WAIT
Definition: midas.h:372
#define MSG_BM
Definition: msystem.h:295
INT ss_suspend(INT millisec, INT msg)
Definition: system.cxx:4482
bool ss_event_socket_has_data()
Definition: system.cxx:4459
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition: midas.cxx:15948
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 5218 of file system.cxx.

5239 {
5240  DWORD count;
5241  INT status;
5242  //int net_tcp_size = NET_TCP_SIZE;
5243  int net_tcp_size = 1024 * 1024;
5244 
5245  /* transfer fragments until complete buffer is transferred */
5246 
5247  for (count = 0; (INT) count < (INT) buffer_size - net_tcp_size;) {
5248  status = send(sock, buffer + count, net_tcp_size, flags & 0xFFFF);
5249  if (status != -1)
5250  count += status;
5251  else {
5252 #ifdef OS_UNIX
5253  if (errno == EINTR)
5254  continue;
5255 #endif
5256  if ((flags & 0x10000) == 0)
5257  cm_msg(MERROR, "send_tcp",
5258  "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
5259  sock, net_tcp_size, status, errno, strerror(errno));
5260  return status;
5261  }
5262  }
5263 
5264  while (count < buffer_size) {
5265  status = send(sock, buffer + count, buffer_size - count, flags & 0xFFFF);
5266  if (status != -1)
5267  count += status;
5268  else {
5269 #ifdef OS_UNIX
5270  if (errno == EINTR)
5271  continue;
5272 #endif
5273  if ((flags & 0x10000) == 0)
5274  cm_msg(MERROR, "send_tcp",
5275  "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
5276  sock, (int) (buffer_size - count), status, errno, strerror(errno));
5277  return status;
5278  }
5279  }
5280 
5281  return count;
5282 }
double count
Definition: mdump.cxx:36
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 3676 of file system.cxx.

3696 {
3697 #ifdef OS_WINNT
3698 
3699  UserCallback = func;
3700  if (millitime > 0)
3701  _timer_id = timeSetEvent(millitime, 100, (LPTIMECALLBACK) _timeCallback, 0, TIME_ONESHOT);
3702  else {
3703  if (_timer_id)
3704  timeKillEvent(_timer_id);
3705  _timer_id = 0;
3706  }
3707 
3708  return SS_SUCCESS;
3709 
3710 #endif /* OS_WINNT */
3711 #ifdef OS_VMS
3712 
3713  signal(SIGALRM, func);
3714  alarm(millitime / 1000);
3715  return SS_SUCCESS;
3716 
3717 #endif /* OS_VMS */
3718 #ifdef OS_UNIX
3719 
3720  signal(SIGALRM, func);
3721  alarm(millitime / 1000);
3722  return SS_SUCCESS;
3723 
3724 #endif /* OS_UNIX */
3725 }

◆ ss_asctime()

std::string EXPRT ss_asctime ( )

Definition at line 3488 of file system.cxx.

3505 {
3506  ss_tzset(); // required for localtime_t()
3507  time_t seconds = (time_t) ss_time();
3508  struct tm tms;
3509  localtime_r(&seconds, &tms);
3510  char str[32];
3511  asctime_r(&tms, str);
3512  /* strip new line */
3513  str[24] = 0;
3514 
3515  return str;
3516 }
void ss_tzset()
Definition: system.cxx:3294
DWORD ss_time()
Definition: system.cxx:3401
MUTEX_T * tm
Definition: odbedit.cxx:42
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 7238 of file system.cxx.

7255 {
7256 #ifdef OS_WINNT
7257 
7258  HANDLE hConsole;
7259  COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */
7260  BOOL bSuccess;
7261  DWORD cCharsWritten;
7262  CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
7263  DWORD dwConSize; /* number of character cells in the current buffer */
7264 
7265  hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
7266 
7267  /* get the number of character cells in the current buffer */
7268  bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
7269  dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
7270 
7271  /* fill the entire screen with blanks */
7272  bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ', dwConSize, coordScreen, &cCharsWritten);
7273 
7274  /* put the cursor at (0, 0) */
7275  bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
7276  return;
7277 
7278 #endif /* OS_WINNT */
7279 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7280  printf("\033[2J");
7281 #endif
7282 #ifdef OS_MSDOS
7283  clrscr();
7284 #endif
7285 }
DWORD BOOL
Definition: midas.h:105
Here is the caller graph for this function:

◆ ss_crypt()

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

Definition at line 7830 of file system.cxx.

7850 {
7851  int i, seed;
7852  static char enc_pw[13];
7853 
7854  memset(enc_pw, 0, sizeof(enc_pw));
7855  enc_pw[0] = salt[0];
7856  enc_pw[1] = salt[1];
7857 
7858  for (i = 0; i < 8 && buf[i]; i++)
7859  enc_pw[i + 2] = buf[i];
7860  for (; i < 8; i++)
7861  enc_pw[i + 2] = 0;
7862 
7863  seed = 123;
7864  for (i = 2; i < 13; i++) {
7865  seed = 5 * seed + 27 + enc_pw[i];
7866  enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
7867  }
7868 
7869  return enc_pw;
7870 }
#define bin_to_ascii(c)
Definition: system.cxx:7828
Here is the caller graph for this function:

◆ ss_ctrlc_handler()

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

Definition at line 3838 of file system.cxx.

3858 {
3859 #ifdef OS_WINNT
3860 
3861  if (func == NULL) {
3862  signal(SIGBREAK, SIG_DFL);
3863  return signal(SIGINT, SIG_DFL);
3864  } else {
3865  signal(SIGBREAK, func);
3866  return signal(SIGINT, func);
3867  }
3868  return NULL;
3869 
3870 #endif /* OS_WINNT */
3871 #ifdef OS_VMS
3872 
3873  return signal(SIGINT, func);
3874 
3875 #endif /* OS_WINNT */
3876 
3877 #ifdef OS_UNIX
3878 
3879  if (func == NULL) {
3880  signal(SIGTERM, SIG_DFL);
3881  return (void *) signal(SIGINT, SIG_DFL);
3882  } else {
3883  signal(SIGTERM, func);
3884  return (void *) signal(SIGINT, func);
3885  }
3886 
3887 #endif /* OS_UNIX */
3888 }
Here is the caller graph for this function:

◆ ss_daemon_init()

INT EXPRT ss_daemon_init ( BOOL  keep_stdout)

Definition at line 1972 of file system.cxx.

1990 {
1991 #ifdef OS_UNIX
1992 
1993  /* only implemented for UNIX */
1994  int i, fd, pid;
1995 
1996 #ifdef NO_FORK
1997  assert(!"support for fork() disabled by NO_FORK");
1998 #else
1999  if ((pid = fork()) < 0)
2000  return SS_ABORT;
2001  else if (pid != 0)
2002  exit(0); /* parent finished */
2003 #endif
2004 
2005  /* child continues here */
2006 
2007  _daemon_flag = TRUE;
2008 
2009  /* try and use up stdin, stdout and stderr, so other
2010  routines writing to stdout etc won't cause havoc. Copied from smbd */
2011  for (i = 0; i < 3; i++) {
2012  if (keep_stdout && ((i == 1) || (i == 2)))
2013  continue;
2014 
2015  close(i);
2016  fd = open("/dev/null", O_RDWR, 0);
2017  if (fd < 0)
2018  fd = open("/dev/null", O_WRONLY, 0);
2019  if (fd < 0) {
2020  cm_msg(MERROR, "ss_daemon_init", "Can't open /dev/null");
2021  return SS_ABORT;
2022  }
2023  if (fd != i) {
2024  cm_msg(MERROR, "ss_daemon_init", "Did not get file descriptor");
2025  return SS_ABORT;
2026  }
2027  }
2028 
2029  setsid(); /* become session leader */
2030 
2031 #endif
2032 
2033  return SS_SUCCESS;
2034 }
static BOOL _daemon_flag
Definition: system.cxx:1970
#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 7125 of file system.cxx.

7142 {
7143 #ifdef OS_UNIX
7144  struct stat buf;
7145 
7146  int retval = stat(path, &buf);
7147  //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7148  if (retval < 0)
7149  return 0;
7150  if (!S_ISDIR(buf.st_mode))
7151  return 0;
7152 #else
7153 #warning ss_dir_exist() is not implemented!
7154 #endif
7155  return 1;
7156 }
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 6735 of file system.cxx.

6736 {
6737  STRING_LIST list;
6738 
6739  int count = ss_dir_find(path, pattern, &list);
6740  if (count <= 0)
6741  return count;
6742 
6743  size_t size = list.size();
6744  *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6745  for (size_t i=0; i<size; i++) {
6746  //printf("file %d [%s]\n", (int)i, list[i].c_str());
6747  strlcpy((*plist)+i*MAX_STRING_LENGTH, list[i].c_str(), MAX_STRING_LENGTH);
6748  }
6749 
6750  return size;
6751 }
#define MAX_STRING_LENGTH
Definition: msystem.h:113
INT ss_dir_find(const char *path, const char *pattern, char **plist)
Definition: system.cxx:6735
std::vector< std::string > STRING_LIST
Definition: midas.h:253
static te_expr * list(state *s)
Definition: tinyexpr.c:567
Here is the call graph for this function:

◆ ss_dir_find() [2/2]

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

Definition at line 6753 of file system.cxx.

6771 {
6772  assert(plist);
6773 #ifdef OS_UNIX
6774  DIR *dir_pointer;
6775  struct dirent *dp;
6776 
6777  if ((dir_pointer = opendir(path)) == NULL)
6778  return 0;
6779  plist->clear();
6780  for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6781  if (fnmatch(pattern, dp->d_name, 0) == 0 && dp->d_type == DT_DIR) {
6782  plist->push_back(dp->d_name);
6783  seekdir(dir_pointer, telldir(dir_pointer));
6784  }
6785  }
6786  closedir(dir_pointer);
6787 #endif
6788 #ifdef OS_WINNT
6789  char str[255];
6790  int first;
6791 
6792  strcpy(str, path);
6793  strcat(str, "\\");
6794  strcat(str, pattern);
6795  first = 1;
6796  plist->clear();
6797  lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
6798  pffile = FindFirstFile(str, lpfdata);
6799  if (pffile == INVALID_HANDLE_VALUE)
6800  return 0;
6801  first = 0;
6802  plist->push_back(lpfdata->cFileName);
6803  while (FindNextFile(pffile, lpfdata)) {
6804  plist->push_back(lpfdata->cFileName);
6805  }
6806  free(lpfdata);
6807 #endif
6808  return plist->size();
6809 }
@ DIR
Definition: test_init.cxx:7

◆ ss_directio_give_port()

INT EXPRT ss_directio_give_port ( INT  start,
INT  end 
)

Definition at line 7750 of file system.cxx.

7751 {
7752 #ifdef OS_WINNT
7753 
7754  /* under Windows NT, use DirectIO driver to open ports */
7755 
7756  OSVERSIONINFO vi;
7757  HANDLE hdio = 0;
7758  DWORD buffer[] = { 6, 0, 0, 0 };
7759  DWORD size;
7760 
7761  vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7762  GetVersionEx(&vi);
7763 
7764  /* use DirectIO driver under NT to gain port access */
7765  if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
7766  hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7767  if (hdio == INVALID_HANDLE_VALUE) {
7768  printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
7769  return -1;
7770  }
7771 
7772  /* open ports */
7773  buffer[1] = start;
7774  buffer[2] = end;
7775  if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
7776  return -1;
7777  }
7778 
7779  return SS_SUCCESS;
7780 #else
7781  return SS_SUCCESS;
7782 #endif
7783 }
#define end
Definition: midas_macro.h:283

◆ ss_directio_lock_port()

INT EXPRT ss_directio_lock_port ( INT  start,
INT  end 
)

Definition at line 7786 of file system.cxx.

7787 {
7788 #ifdef OS_WINNT
7789 
7790  /* under Windows NT, use DirectIO driver to lock ports */
7791 
7792  OSVERSIONINFO vi;
7793  HANDLE hdio;
7794  DWORD buffer[] = { 7, 0, 0, 0 };
7795  DWORD size;
7796 
7797  vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7798  GetVersionEx(&vi);
7799 
7800  /* use DirectIO driver under NT to gain port access */
7801  if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
7802  hdio = CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
7803  if (hdio == INVALID_HANDLE_VALUE) {
7804  printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
7805  return -1;
7806  }
7807 
7808  /* lock ports */
7809  buffer[1] = start;
7810  buffer[2] = end;
7811  if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
7812  return -1;
7813  }
7814 
7815  return SS_SUCCESS;
7816 #else
7817  return SS_SUCCESS;
7818 #endif
7819 }

◆ ss_dirlink_find() [1/2]

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

Definition at line 6811 of file system.cxx.

6812 {
6813  STRING_LIST list;
6814 
6815  int count = ss_dirlink_find(path, pattern, &list);
6816  if (count <= 0)
6817  return count;
6818 
6819  size_t size = list.size();
6820  *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6821  for (size_t i=0; i<size; i++) {
6822  //printf("file %d [%s]\n", (int)i, list[i].c_str());
6823  strlcpy((*plist)+i*MAX_STRING_LENGTH, list[i].c_str(), MAX_STRING_LENGTH);
6824  }
6825 
6826  return size;
6827 }
INT ss_dirlink_find(const char *path, const char *pattern, char **plist)
Definition: system.cxx:6811
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_dirlink_find() [2/2]

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

Definition at line 6829 of file system.cxx.

6847 {
6848  assert(plist);
6849 #ifdef OS_UNIX
6850  DIR *dir_pointer;
6851  struct dirent *dp;
6852 
6853  if ((dir_pointer = opendir(path)) == NULL)
6854  return 0;
6855  plist->clear();
6856  for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6857  if (fnmatch(pattern, dp->d_name, 0) == 0) {
6858  /* must have a "/" at the end, otherwise also links to files are accepted */
6859  std::string full_path = std::string(path) + "/" + dp->d_name + "/";
6860  struct stat st;
6861  if (lstat(full_path.c_str(), &st) == 0 && (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) {
6862  plist->push_back(dp->d_name);
6863  }
6864  }
6865  }
6866  closedir(dir_pointer);
6867 #endif
6868 #ifdef OS_WINNT
6869  char str[255];
6870  int first;
6871 
6872  strcpy(str, path);
6873  strcat(str, "\\");
6874  strcat(str, pattern);
6875  first = 1;
6876  plist->clear();
6877  lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
6878  pffile = FindFirstFile(str, lpfdata);
6879  if (pffile == INVALID_HANDLE_VALUE)
6880  return 0;
6881  first = 0;
6882  plist->push_back(lpfdata->cFileName);
6883  while (FindNextFile(pffile, lpfdata)) {
6884  plist->push_back(lpfdata->cFileName);
6885  }
6886  free(lpfdata);
6887 #endif
6888  return plist->size();
6889 }

◆ ss_disk_free()

double EXPRT ss_disk_free ( const char *  path)

Definition at line 6559 of file system.cxx.

6575 {
6576 #ifdef OS_UNIX
6577 #if defined(OS_OSF1)
6578  struct statfs st;
6579  statfs(path, &st, sizeof(st));
6580  return (double) st.f_bavail * st.f_bsize;
6581 #elif defined(OS_LINUX)
6582  struct statfs st;
6583  int status;
6584  status = statfs(path, &st);
6585  if (status != 0)
6586  return -1;
6587  return (double) st.f_bavail * st.f_bsize;
6588 #elif defined(OS_SOLARIS)
6589  struct statvfs st;
6590  statvfs(path, &st);
6591  return (double) st.f_bavail * st.f_bsize;
6592 #elif defined(OS_IRIX)
6593  struct statfs st;
6594  statfs(path, &st, sizeof(struct statfs), 0);
6595  return (double) st.f_bfree * st.f_bsize;
6596 #else
6597  struct fs_data st;
6598  statfs(path, &st);
6599  return (double) st.fd_otsize * st.fd_bfree;
6600 #endif
6601 
6602 #elif defined(OS_WINNT) /* OS_UNIX */
6603  DWORD SectorsPerCluster;
6604  DWORD BytesPerSector;
6605  DWORD NumberOfFreeClusters;
6606  DWORD TotalNumberOfClusters;
6607  char str[80];
6608 
6609  strcpy(str, path);
6610  if (strchr(str, ':') != NULL) {
6611  *(strchr(str, ':') + 1) = 0;
6612  strcat(str, DIR_SEPARATOR_STR);
6613  GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
6614  } else
6615  GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
6616 
6617  return (double) NumberOfFreeClusters *SectorsPerCluster * BytesPerSector;
6618 #else /* OS_WINNT */
6619 
6620  return 1e9;
6621 
6622 #endif
6623 }
#define DIR_SEPARATOR_STR
Definition: midas.h:194
Here is the caller graph for this function:

◆ ss_disk_size()

double EXPRT ss_disk_size ( const char *  path)

Definition at line 6987 of file system.cxx.

7003 {
7004 #ifdef OS_UNIX
7005 #if defined(OS_OSF1)
7006  struct statfs st;
7007  statfs(path, &st, sizeof(st));
7008  return (double) st.f_blocks * st.f_fsize;
7009 #elif defined(OS_LINUX)
7010  int status;
7011  struct statfs st;
7012  status = statfs(path, &st);
7013  if (status != 0)
7014  return -1;
7015  return (double) st.f_blocks * st.f_bsize;
7016 #elif defined(OS_SOLARIS)
7017  struct statvfs st;
7018  statvfs(path, &st);
7019  if (st.f_frsize > 0)
7020  return (double) st.f_blocks * st.f_frsize;
7021  else
7022  return (double) st.f_blocks * st.f_bsize;
7023 #elif defined(OS_ULTRIX)
7024  struct fs_data st;
7025  statfs(path, &st);
7026  return (double) st.fd_btot * 1024;
7027 #elif defined(OS_IRIX)
7028  struct statfs st;
7029  statfs(path, &st, sizeof(struct statfs), 0);
7030  return (double) st.f_blocks * st.f_bsize;
7031 #else
7032 #error ss_disk_size not defined for this OS
7033 #endif
7034 #endif /* OS_UNIX */
7035 
7036 #ifdef OS_WINNT
7037  DWORD SectorsPerCluster;
7038  DWORD BytesPerSector;
7039  DWORD NumberOfFreeClusters;
7040  DWORD TotalNumberOfClusters;
7041  char str[80];
7042 
7043  strcpy(str, path);
7044  if (strchr(str, ':') != NULL) {
7045  *(strchr(str, ':') + 1) = 0;
7046  strcat(str, DIR_SEPARATOR_STR);
7047  GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
7048  } else
7049  GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
7050 
7051  return (double) TotalNumberOfClusters *SectorsPerCluster * BytesPerSector;
7052 #endif /* OS_WINNT */
7053 
7054  return 1e9;
7055 }
Here is the caller graph for this function:

◆ ss_event_socket_has_data()

bool ss_event_socket_has_data ( )

Definition at line 4459 of file system.cxx.

4460 {
4461  if (_ss_server_acceptions) {
4462  for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4463  /* event channel */
4464  int sock = (*_ss_server_acceptions)[i]->event_sock;
4465 
4466  if (!sock)
4467  continue;
4468 
4469  /* check for buffered event */
4470  int status = ss_socket_wait(sock, 1);
4471 
4472  if (status == SS_SUCCESS)
4473  return true;
4474  }
4475  }
4476 
4477  /* no event socket or no data in event socket */
4478  return false;
4479 }
static RPC_SERVER_ACCEPTION_LIST * _ss_server_acceptions
Definition: system.cxx:3929
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 3783 of file system.cxx.

3802 {
3803 #ifdef OS_WINNT
3804 
3805  MidasExceptionHandler = func;
3806 /* SetUnhandledExceptionFilter(
3807  (LPTOP_LEVEL_EXCEPTION_FILTER) MidasExceptionFilter);
3808 
3809  signal(SIGINT, MidasExceptionSignal);
3810  signal(SIGILL, MidasExceptionSignal);
3811  signal(SIGFPE, MidasExceptionSignal);
3812  signal(SIGSEGV, MidasExceptionSignal);
3813  signal(SIGTERM, MidasExceptionSignal);
3814  signal(SIGBREAK, MidasExceptionSignal);
3815  signal(SIGABRT, MidasExceptionSignal); */
3816 
3817 #elif defined (OS_VMS)
3818 
3819  MidasExceptionHandler = func;
3820  lib$establish(MidasExceptionFilter);
3821 
3822  signal(SIGINT, MidasExceptionSignal);
3823  signal(SIGILL, MidasExceptionSignal);
3824  signal(SIGQUIT, MidasExceptionSignal);
3825  signal(SIGFPE, MidasExceptionSignal);
3826  signal(SIGSEGV, MidasExceptionSignal);
3827  signal(SIGTERM, MidasExceptionSignal);
3828 
3829 #else /* OS_VMS */
3830 #endif
3831 
3832  return SS_SUCCESS;
3833 }
void(* MidasExceptionHandler)(void)
Definition: system.cxx:3728

◆ ss_exec()

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

Definition at line 2103 of file system.cxx.

2122 {
2123 #ifdef OS_UNIX
2124 
2125  /* only implemented for UNIX */
2126  int i, fd;
2127 
2128 #ifdef NO_FORK
2129  assert(!"support for fork() disabled by NO_FORK");
2130 #else
2131  *pid = fork();
2132 #endif
2133  if (*pid < 0)
2134  return SS_ABORT;
2135  else if (*pid != 0) {
2136  /* avoid <defunc> parent processes */
2137  signal(SIGCHLD, catch_sigchld);
2138  return SS_SUCCESS; /* parent returns */
2139  }
2140 
2141  /* child continues here... */
2142 
2143  /* close all open file descriptors */
2144  for (i = 0; i < 256; i++)
2145  close(i);
2146 
2147  /* try and use up stdin, stdout and stderr, so other
2148  routines writing to stdout etc won't cause havoc */
2149  for (i = 0; i < 3; i++) {
2150  fd = open("/dev/null", O_RDWR, 0);
2151  if (fd < 0)
2152  fd = open("/dev/null", O_WRONLY, 0);
2153  if (fd < 0) {
2154  cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
2155  return SS_ABORT;
2156  }
2157  if (fd != i) {
2158  cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
2159  return SS_ABORT;
2160  }
2161  }
2162 
2163  setsid(); /* become session leader */
2164  /* chdir("/"); *//* change working directory (not on NFS!) */
2165 
2166  /* execute command */
2167  int error = execl("/bin/sh", "sh", "-c", command, NULL);
2168  // NB: execl() does not return unless there is an error. K.O.
2169  fprintf(stderr, "ss_shell: Cannot execute /bin/sh for command \"%s\": execl() returned %d, errno %d (%s), aborting!\n", command, error, errno, strerror(errno));
2170  abort();
2171 
2172 #else
2173 
2174  system(command);
2175 
2176 #endif
2177 
2178  return SS_SUCCESS;
2179 }
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 2208 of file system.cxx.

2223 {
2224 #ifdef OS_UNIX
2225  std::array<char, 256> buffer{};
2226  std::string result;
2227  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
2228 
2229  if (!pipe) {
2230  throw std::runtime_error("popen() failed!");
2231  }
2232 
2233  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
2234  result += buffer.data();
2235  }
2236 
2237  return result;
2238 #else
2239  fprintf(stderr, "ss_execs: Function not supported on this OS, aborting!\n");
2240  abort();
2241 #endif
2242 }
Here is the caller graph for this function:

◆ ss_existpid()

BOOL EXPRT ss_existpid ( INT  pid)

Definition at line 2039 of file system.cxx.

2057 {
2058 #ifdef OS_UNIX
2059  /* only implemented for UNIX */
2060  return (kill(pid, 0) == 0 ? TRUE : FALSE);
2061 #else
2062  cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
2063  return FALSE;
2064 #endif
2065 }
#define FALSE
Definition: cfortran.h:309
#define MINFO
Definition: midas.h:566
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 7158 of file system.cxx.

7175 {
7176  int fd_to, fd_from;
7177  char buf[4096];
7178  ssize_t nread;
7179  int saved_errno;
7180 
7181  fd_from = open(src, O_RDONLY);
7182  if (fd_from < 0)
7183  return -1;
7184 
7185  if (append)
7186  fd_to = open(dst, O_WRONLY | O_CREAT | O_EXCL | O_APPEND, 0666);
7187  else
7188  fd_to = open(dst, O_WRONLY | O_CREAT | O_EXCL, 0666);
7189  if (fd_to < 0)
7190  goto out_error;
7191 
7192  while (nread = read(fd_from, buf, sizeof(buf)), nread > 0) {
7193  char *out_ptr = buf;
7194  ssize_t nwritten;
7195 
7196  do {
7197  nwritten = write(fd_to, out_ptr, nread);
7198 
7199  if (nwritten >= 0) {
7200  nread -= nwritten;
7201  out_ptr += nwritten;
7202  } else if (errno != EINTR) {
7203  goto out_error;
7204  }
7205  } while (nread > 0);
7206  }
7207 
7208  if (nread == 0) {
7209  if (close(fd_to) < 0) {
7210  fd_to = -1;
7211  goto out_error;
7212  }
7213  close(fd_from);
7214 
7215  /* Success! */
7216  return 0;
7217  }
7218 
7219  out_error:
7220  saved_errno = errno;
7221 
7222  close(fd_from);
7223  if (fd_to >= 0)
7224  close(fd_to);
7225 
7226  errno = saved_errno;
7227  return -1;
7228 }
#define read(n, a, f)
Definition: midas_macro.h:242
#define write(n, a, f, d)
Definition: midas_macro.h:245
Here is the caller graph for this function:

◆ ss_file_exist()

INT EXPRT ss_file_exist ( const char *  path)

Definition at line 7057 of file system.cxx.

7074 {
7075 #ifdef OS_UNIX
7076  struct stat buf;
7077 
7078  int retval = stat(path, &buf);
7079  //printf("retval %d, errno %d (%s)\n", retval, errno, strerror(errno));
7080  if (retval < 0)
7081  return 0;
7082  if (S_ISDIR(buf.st_mode))
7083  return 0;
7084 #endif
7085 
7086  int fd = open(path, O_RDONLY, 0);
7087  if (fd < 0)
7088  return 0;
7089  close(fd);
7090  return 1;
7091 }
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 6652 of file system.cxx.

6653 {
6654  STRING_LIST list;
6655 
6656  int count = ss_file_find(path, pattern, &list);
6657  if (count <= 0)
6658  return count;
6659 
6660  size_t size = list.size();
6661  *plist = (char *) malloc(size*MAX_STRING_LENGTH);
6662  for (size_t i=0; i<size; i++) {
6663  //printf("file %d [%s]\n", (int)i, list[i].c_str());
6664  strlcpy((*plist)+i*MAX_STRING_LENGTH, list[i].c_str(), MAX_STRING_LENGTH);
6665  }
6666 
6667  return size;
6668 }
INT ss_file_find(const char *path, const char *pattern, char **plist)
Definition: system.cxx:6652
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_file_find() [2/2]

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

Definition at line 6670 of file system.cxx.

6688 {
6689  assert(plist);
6690  // Check if the directory exists
6691  if (access(path, F_OK) != 0) {
6692  return -1; // Return -1 files if directory doesn't exist
6693  }
6694 
6695 #ifdef OS_UNIX
6696  DIR *dir_pointer;
6697  struct dirent *dp;
6698 
6699  plist->clear();
6700  if ((dir_pointer = opendir(path)) == NULL)
6701  return 0;
6702  for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
6703  if (fnmatch(pattern, dp->d_name, 0) == 0 && (dp->d_type == DT_REG || dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN)) {
6704  plist->push_back(dp->d_name);
6705  seekdir(dir_pointer, telldir(dir_pointer));
6706  }
6707  }
6708  closedir(dir_pointer);
6709 #endif
6710 #ifdef OS_WINNT
6711  char str[255];
6712  int first;
6713 
6714  strcpy(str, path);
6715  strcat(str, "\\");
6716  strcat(str, pattern);
6717  first = 1;
6718  lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
6719  *plist->clear();
6720  pffile = FindFirstFile(str, lpfdata);
6721  if (pffile == INVALID_HANDLE_VALUE)
6722  return 0;
6723  first = 0;
6724  plist->push_back(lpfdata->cFileName);
6725  i++;
6726  while (FindNextFile(pffile, lpfdata)) {
6727  plist->push_back(lpfdata->cFileName);
6728  i++;
6729  }
6730  free(lpfdata);
6731 #endif
6732  return plist->size();
6733 }

◆ ss_file_link_exist()

INT EXPRT ss_file_link_exist ( const char *  path)

Definition at line 7093 of file system.cxx.

7110 {
7111 #ifdef OS_UNIX
7112  struct stat buf;
7113 
7114  int retval = lstat(path, &buf);
7115  if (retval < 0)
7116  return 0;
7117  if (S_ISLNK(buf.st_mode))
7118  return 1;
7119  return 0;
7120 #endif
7121 
7122  return 0;
7123 }
Here is the caller graph for this function:

◆ ss_file_remove()

INT EXPRT ss_file_remove ( const char *  path)

Definition at line 6891 of file system.cxx.

6907 {
6908  return remove(path);
6909 }
static std::string remove(const std::string s, char c)
Definition: mjsonrpc.cxx:252
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 6911 of file system.cxx.

6927 {
6928 #ifdef _LARGEFILE64_SOURCE
6929  struct stat64 stat_buf;
6930  int status;
6931 
6932  /* allocate buffer with file size */
6933  status = stat64(path, &stat_buf);
6934  if (status != 0)
6935  return -1;
6936  return (double) stat_buf.st_size;
6937 #else
6938  struct stat stat_buf;
6939  int status;
6940 
6941  /* allocate buffer with file size */
6942  status = stat(path, &stat_buf);
6943  if (status != 0)
6944  return -1;
6945  return (double) stat_buf.st_size;
6946 #endif
6947 }
Here is the caller graph for this function:

◆ ss_file_time()

time_t EXPRT ss_file_time ( const char *  path)

Definition at line 6949 of file system.cxx.

6965 {
6966 #ifdef _LARGEFILE64_SOURCE
6967  struct stat64 stat_buf;
6968  int status;
6969 
6970  /* allocate buffer with file size */
6971  status = stat64(path, &stat_buf);
6972  if (status != 0)
6973  return -1;
6974  return stat_buf.st_mtime;
6975 #else
6976  struct stat stat_buf;
6977  int status;
6978 
6979  /* allocate buffer with file size */
6980  status = stat(path, &stat_buf);
6981  if (status != 0)
6982  return -1;
6983  return stat_buf.st_mtime;
6984 #endif
6985 }
Here is the caller graph for this function:

◆ ss_get_struct_align()

INT EXPRT ss_get_struct_align ( )

Definition at line 1325 of file system.cxx.

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

1372 {
1373  return (INT) sizeof(test_padding) - 8;
1374 }
static struct @4 test_padding

◆ ss_getchar()

INT EXPRT ss_getchar ( BOOL  reset)

Definition at line 7442 of file system.cxx.

7462 {
7463 #ifdef OS_UNIX
7464 
7465  static BOOL init = FALSE;
7466  static struct termios save_termios;
7467  struct termios buf;
7468  int i, fd;
7469  char c[3];
7470 
7471  if (_daemon_flag)
7472  return 0;
7473 
7474  fd = fileno(stdin);
7475 
7476  if (reset) {
7477  if (init)
7478  tcsetattr(fd, TCSAFLUSH, &save_termios);
7479  init = FALSE;
7480  return 0;
7481  }
7482 
7483  if (!init) {
7484  tcgetattr(fd, &save_termios);
7485  memcpy(&buf, &save_termios, sizeof(buf));
7486 
7487  buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
7488 
7489  buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
7490 
7491  buf.c_cflag &= ~(CSIZE | PARENB);
7492  buf.c_cflag |= CS8;
7493  /* buf.c_oflag &= ~(OPOST); */
7494  buf.c_cc[VMIN] = 0;
7495  buf.c_cc[VTIME] = 0;
7496 
7497  tcsetattr(fd, TCSAFLUSH, &buf);
7498  init = TRUE;
7499  }
7500 
7501  memset(c, 0, 3);
7502  i = read(fd, c, 1);
7503 
7504  if (i == 0)
7505  return 0;
7506 
7507  /* check if ESC */
7508  if (c[0] == 27) {
7509  i = read(fd, c, 2);
7510  if (i == 0) /* return if only ESC */
7511  return 27;
7512 
7513  /* cursor keys return 2 chars, others 3 chars */
7514  if (c[1] < 65) {
7515  i = read(fd, c, 1);
7516  }
7517 
7518  /* convert ESC sequence to CH_xxx */
7519  switch (c[1]) {
7520  case 49:
7521  return CH_HOME;
7522  case 50:
7523  return CH_INSERT;
7524  case 51:
7525  return CH_DELETE;
7526  case 52:
7527  return CH_END;
7528  case 53:
7529  return CH_PUP;
7530  case 54:
7531  return CH_PDOWN;
7532  case 65:
7533  return CH_UP;
7534  case 66:
7535  return CH_DOWN;
7536  case 67:
7537  return CH_RIGHT;
7538  case 68:
7539  return CH_LEFT;
7540  }
7541  }
7542 
7543  /* BS/DEL -> BS */
7544  if (c[0] == 127)
7545  return CH_BS;
7546 
7547  return c[0];
7548 
7549 #elif defined(OS_WINNT)
7550 
7551  static BOOL init = FALSE;
7552  static INT repeat_count = 0;
7553  static INT repeat_char;
7554  HANDLE hConsole;
7555  DWORD nCharsRead;
7556  INPUT_RECORD ir;
7557  OSVERSIONINFO vi;
7558 
7559  /* find out if we are under W95 */
7560  vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
7561  GetVersionEx(&vi);
7562 
7563  if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
7564  /* under W95, console doesn't work properly */
7565  int c;
7566 
7567  if (!kbhit())
7568  return 0;
7569 
7570  c = getch();
7571  if (c == 224) {
7572  c = getch();
7573  switch (c) {
7574  case 71:
7575  return CH_HOME;
7576  case 72:
7577  return CH_UP;
7578  case 73:
7579  return CH_PUP;
7580  case 75:
7581  return CH_LEFT;
7582  case 77:
7583  return CH_RIGHT;
7584  case 79:
7585  return CH_END;
7586  case 80:
7587  return CH_DOWN;
7588  case 81:
7589  return CH_PDOWN;
7590  case 82:
7591  return CH_INSERT;
7592  case 83:
7593  return CH_DELETE;
7594  }
7595  }
7596  return c;
7597  }
7598 
7599  hConsole = GetStdHandle(STD_INPUT_HANDLE);
7600 
7601  if (reset) {
7602  SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
7603  init = FALSE;
7604  return 0;
7605  }
7606 
7607  if (!init) {
7608  SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
7609  init = TRUE;
7610  }
7611 
7612  if (repeat_count) {
7613  repeat_count--;
7614  return repeat_char;
7615  }
7616 
7617  PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
7618 
7619  if (nCharsRead == 0)
7620  return 0;
7621 
7622  ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
7623 
7624  if (ir.EventType != KEY_EVENT)
7625  return ss_getchar(0);
7626 
7627  if (!ir.Event.KeyEvent.bKeyDown)
7628  return ss_getchar(0);
7629 
7630  if (ir.Event.KeyEvent.wRepeatCount > 1) {
7631  repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
7632  repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
7633  return repeat_char;
7634  }
7635 
7636  if (ir.Event.KeyEvent.uChar.AsciiChar)
7637  return ir.Event.KeyEvent.uChar.AsciiChar;
7638 
7639  if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
7640  switch (ir.Event.KeyEvent.wVirtualKeyCode) {
7641  case 33:
7642  return CH_PUP;
7643  case 34:
7644  return CH_PDOWN;
7645  case 35:
7646  return CH_END;
7647  case 36:
7648  return CH_HOME;
7649  case 37:
7650  return CH_LEFT;
7651  case 38:
7652  return CH_UP;
7653  case 39:
7654  return CH_RIGHT;
7655  case 40:
7656  return CH_DOWN;
7657  case 45:
7658  return CH_INSERT;
7659  case 46:
7660  return CH_DELETE;
7661  }
7662 
7663  return ir.Event.KeyEvent.wVirtualKeyCode;
7664  }
7665 
7666  return ss_getchar(0);
7667 
7668 #elif defined(OS_MSDOS)
7669 
7670  int c;
7671 
7672  if (!kbhit())
7673  return 0;
7674 
7675  c = getch();
7676  if (!c) {
7677  c = getch();
7678  switch (c) {
7679  case 71:
7680  return CH_HOME;
7681  case 72:
7682  return CH_UP;
7683  case 73:
7684  return CH_PUP;
7685  case 75:
7686  return CH_LEFT;
7687  case 77:
7688  return CH_RIGHT;
7689  case 79:
7690  return CH_END;
7691  case 80:
7692  return CH_DOWN;
7693  case 81:
7694  return CH_PDOWN;
7695  case 82:
7696  return CH_INSERT;
7697  case 83:
7698  return CH_DELETE;
7699  }
7700  }
7701  return c;
7702 
7703 #else
7704  return -1;
7705 #endif
7706 }
INT ss_getchar(BOOL reset)
Definition: system.cxx:7442
#define CH_END
Definition: midas.h:461
#define CH_DOWN
Definition: midas.h:465
#define CH_PUP
Definition: midas.h:462
#define CH_DELETE
Definition: midas.h:460
#define CH_RIGHT
Definition: midas.h:466
#define CH_INSERT
Definition: midas.h:459
#define CH_LEFT
Definition: midas.h:467
#define CH_HOME
Definition: midas.h:458
#define CH_UP
Definition: midas.h:464
#define CH_BS
Definition: midas.h:452
#define CH_PDOWN
Definition: midas.h:463
char c
Definition: system.cxx:1316
Here is the caller graph for this function:

◆ ss_getcwd()

std::string EXPRT ss_getcwd ( )

Definition at line 5709 of file system.cxx.

5710 {
5711  char *s = getcwd(NULL, 0);
5712  if (s) {
5713  std::string cwd = s;
5714  free(s);
5715  //printf("ss_getcwd: %s\n", cwd.c_str());
5716  return cwd;
5717  } else {
5718  return "/GETCWD-FAILED-ON-US";
5719  }
5720 }
Here is the caller graph for this function:

◆ ss_gethostname() [1/2]

std::string ss_gethostname ( )

Definition at line 5645 of file system.cxx.

5662 {
5663  char buf[256];
5664  memset(buf, 0, sizeof(buf));
5665 
5666  int status = gethostname(buf, sizeof(buf)-1);
5667 
5668  //printf("gethostname %d (%s)\n", status, buffer);
5669 
5670  if (status != 0) {
5671  cm_msg(MERROR, "ss_gethostname", "gethostname() errno %d (%s)", errno, strerror(errno));
5672  return "";
5673  }
5674 
5675  return buf;
5676 }
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 5679 of file system.cxx.

5696 {
5697  std::string h = ss_gethostname();
5698 
5699  if (h.length() == 0) {
5700  return SS_IO_ERROR;
5701  } else {
5702  strlcpy(buffer, h.c_str(), buffer_size);
5703  return SS_SUCCESS;
5704  }
5705 }
#define SS_IO_ERROR
Definition: midas.h:687
std::string ss_gethostname()
Definition: system.cxx:5645
Here is the call graph for this function:

◆ ss_getpass()

char EXPRT * ss_getpass ( const char *  prompt)

Definition at line 7379 of file system.cxx.

7396 {
7397  static char password[32];
7398 
7399  fprintf(stdout, "%s", prompt);
7400  fflush(stdout);
7401  memset(password, 0, sizeof(password));
7402 
7403 #ifdef OS_UNIX
7404  return (char *) getpass("");
7405 #elif defined(OS_WINNT)
7406  {
7407  HANDLE hConsole;
7408  DWORD nCharsRead;
7409 
7410  hConsole = GetStdHandle(STD_INPUT_HANDLE);
7411  SetConsoleMode(hConsole, ENABLE_LINE_INPUT);
7412  ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
7413  SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
7414  printf("\n");
7415 
7416  if (password[strlen(password) - 1] == '\r')
7417  password[strlen(password) - 1] = 0;
7418 
7419  return password;
7420  }
7421 #elif defined(OS_MSDOS)
7422  {
7423  char c, *ptr;
7424 
7425  ptr = password;
7426  while ((c = getchar()) != EOF && c != '\n')
7427  *ptr++ = c;
7428  *ptr = 0;
7429 
7430  printf("\n");
7431  return password;
7432  }
7433 #else
7434  {
7435  ss_gets(password, 32);
7436  return password;
7437  }
7438 #endif
7439 }
char * ss_gets(char *string, int size)
Definition: system.cxx:7709
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 1383 of file system.cxx.

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

◆ ss_gets()

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

Definition at line 7709 of file system.cxx.

7728 {
7729  char *p;
7730 
7731  do {
7732  p = fgets(string, size, stdin);
7733  } while (p == NULL);
7734 
7735 
7736  if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
7737  p[strlen(p) - 1] = 0;
7738 
7739  return p;
7740 }
Here is the caller graph for this function:

◆ ss_gettid()

midas_thread_t EXPRT ss_gettid ( void  )

Definition at line 1490 of file system.cxx.

1507 {
1508 #if defined OS_MSDOS
1509 
1510  return 0;
1511 
1512 #elif defined OS_WINNT
1513 
1514  return GetCurrentThreadId();
1515 
1516 #elif defined OS_VMS
1517 
1518  return ss_getpid();
1519 
1520 #elif defined OS_DARWIN
1521 
1522  return pthread_self();
1523 
1524 #elif defined OS_CYGWIN
1525 
1526  return pthread_self();
1527 
1528 #elif defined OS_UNIX
1529 
1530  return pthread_self();
1531  //return syscall(SYS_gettid);
1532 
1533 #elif defined OS_VXWORKS
1534 
1535  return ss_getpid();
1536 
1537 #else
1538 #error Do not know how to do ss_gettid()
1539 #endif
1540 }
INT ss_getpid(void)
Definition: system.cxx:1383
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 8007 of file system.cxx.

8008 {
8009  assert(string);
8010 
8011  // FIXME: this function over-reads the input array. K.O. May 2021
8012 
8013  const unsigned char * bytes = (const unsigned char *)string;
8014  while(*bytes) {
8015  if( (// ASCII
8016  // use bytes[0] <= 0x7F to allow ASCII control characters
8017  bytes[0] == 0x09 ||
8018  bytes[0] == 0x0A ||
8019  bytes[0] == 0x0D ||
8020  (0x20 <= bytes[0] && bytes[0] <= 0x7E)
8021  )
8022  ) {
8023  bytes += 1;
8024  continue;
8025  }
8026 
8027  if( (// non-overlong 2-byte
8028  (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
8029  (0x80 <= bytes[1] && bytes[1] <= 0xBF)
8030  )
8031  ) {
8032  bytes += 2;
8033  continue;
8034  }
8035 
8036  if( (// excluding overlongs
8037  bytes[0] == 0xE0 &&
8038  (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
8039  (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8040  ) ||
8041  (// straight 3-byte
8042  ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
8043  bytes[0] == 0xEE ||
8044  bytes[0] == 0xEF) &&
8045  (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8046  (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8047  ) ||
8048  (// excluding surrogates
8049  bytes[0] == 0xED &&
8050  (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
8051  (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8052  )
8053  ) {
8054  bytes += 3;
8055  continue;
8056  }
8057 
8058  if( (// planes 1-3
8059  bytes[0] == 0xF0 &&
8060  (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
8061  (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8062  (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8063  ) ||
8064  (// planes 4-15
8065  (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
8066  (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8067  (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8068  (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8069  ) ||
8070  (// plane 16
8071  bytes[0] == 0xF4 &&
8072  (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
8073  (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8074  (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8075  )
8076  ) {
8077  bytes += 4;
8078  continue;
8079  }
8080 
8081  //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);
8082  //abort();
8083 
8084  return false;
8085  }
8086 
8087  return true;
8088 }
Here is the caller graph for this function:

◆ ss_isfin()

int EXPRT ss_isfin ( double  x)

Definition at line 7905 of file system.cxx.

7906 {
7907 #ifdef FP_INFINITE
7908  /* new-style finite() */
7909  return isfinite(x);
7910 #else
7911  /* old-style finite() */
7912  return finite(x);
7913 #endif
7914 }
Here is the caller graph for this function:

◆ ss_isnan()

int EXPRT ss_isnan ( double  x)

Definition at line 7900 of file system.cxx.

7901 {
7902  return isnan(x);
7903 }
Here is the caller graph for this function:

◆ ss_kbhit()

BOOL EXPRT ss_kbhit ( )

Definition at line 3603 of file system.cxx.

3621 {
3622 #ifdef OS_MSDOS
3623 
3624  return kbhit();
3625 
3626 #endif /* OS_MSDOS */
3627 #ifdef OS_WINNT
3628 
3629  return kbhit();
3630 
3631 #endif /* OS_WINNT */
3632 #ifdef OS_VMS
3633 
3634  return FALSE;
3635 
3636 #endif /* OS_VMS */
3637 #ifdef OS_UNIX
3638 
3639  int n;
3640 
3641  if (_daemon_flag)
3642  return 0;
3643 
3644  ioctl(0, FIONREAD, &n);
3645  return (n > 0);
3646 
3647 #endif /* OS_UNIX */
3648 #ifdef OS_VXWORKS
3649 
3650  int n;
3651  ioctl(0, FIONREAD, (long) &n);
3652  return (n > 0);
3653 
3654 #endif /* OS_UNIX */
3655 }
Here is the caller graph for this function:

◆ ss_kill()

void ss_kill ( int  pid)

Definition at line 1477 of file system.cxx.

1478 {
1479 #ifdef SIGKILL
1480  kill(pid, SIGKILL);
1481 #else
1482 #warning Missing SIGKILL for ss_kill()
1483 #endif
1484 }

◆ ss_match_thread()

static bool ss_match_thread ( midas_thread_t  tid1,
midas_thread_t  tid2 
)
static

Definition at line 3932 of file system.cxx.

3933 {
3934  if (tid1 == 0)
3935  return true;
3936  if (tid1 == tid2)
3937  return true;
3938  return false;
3939 }
Here is the caller graph for this function:

◆ ss_millitime()

DWORD EXPRT ss_millitime ( )

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

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

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

Definition at line 3332 of file system.cxx.

3333 {
3334 #ifdef OS_WINNT
3335 
3336  return (int) GetTickCount();
3337 
3338 #endif /* OS_WINNT */
3339 #ifdef OS_MSDOS
3340 
3341  return clock() * 55;
3342 
3343 #endif /* OS_MSDOS */
3344 #ifdef OS_VMS
3345 
3346  {
3347  char time[8];
3348  DWORD lo, hi;
3349 
3350  sys$gettim(time);
3351 
3352  lo = *((DWORD *) time);
3353  hi = *((DWORD *) (time + 4));
3354 
3355 /* return *lo / 10000; */
3356 
3357  return lo / 10000 + hi * 429496.7296;
3358 
3359  }
3360 
3361 #endif /* OS_VMS */
3362 #ifdef OS_UNIX
3363  {
3364  struct timeval tv;
3365 
3366  gettimeofday(&tv, NULL);
3367 
3368  DWORD m = tv.tv_sec * 1000 + tv.tv_usec / 1000;
3369  //m += 0x137e0000; // adjust milltime for testing 32-bit wrap-around
3370  return m;
3371  }
3372 
3373 #endif /* OS_UNIX */
3374 #ifdef OS_VXWORKS
3375  {
3376  int count;
3377  static int ticks_per_msec = 0;
3378 
3379  if (ticks_per_msec == 0)
3380  ticks_per_msec = 1000 / sysClkRateGet();
3381 
3382  return tickGet() * ticks_per_msec;
3383  }
3384 #endif /* OS_VXWORKS */
3385 }
int gettimeofday(struct timeval *tp, void *tzp)
timeval tv
Definition: msysmon.cxx:1094
Here is the call graph for this function:

◆ ss_mktime()

time_t EXPRT ss_mktime ( struct tm tms)

Definition at line 3304 of file system.cxx.

3305 {
3306  std::lock_guard<std::mutex> lock(gTzMutex);
3307  //defeat mktime() error trap from msystem.h
3308  //#ifdef mktime
3309  //#undef mktime
3310  //#endif
3311  return mktime(tms);
3312 }
static std::mutex gTzMutex
Definition: system.cxx:3292
Here is the caller graph for this function:

◆ ss_mutex_create()

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

Definition at line 2880 of file system.cxx.

2895 {
2896 #ifdef OS_VXWORKS
2897 
2898  /* semBCreate is a Binary semaphore which is under VxWorks a optimized mutex
2899  refering to the programmer's Guide 5.3.1 */
2900  if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
2901  return SS_NO_MUTEX;
2902  return SS_CREATED;
2903 
2904 #endif /* OS_VXWORKS */
2905 
2906 #ifdef OS_WINNT
2907 
2908  *mutex = (MUTEX_T *)malloc(sizeof(HANDLE));
2909  **mutex = CreateMutex(NULL, FALSE, NULL);
2910 
2911  if (**mutex == 0)
2912  return SS_NO_MUTEX;
2913 
2914  return SS_CREATED;
2915 
2916 #endif /* OS_WINNT */
2917 #ifdef OS_UNIX
2918 
2919  {
2920  int status;
2921  pthread_mutexattr_t *attr;
2922 
2923  attr = (pthread_mutexattr_t*)malloc(sizeof(*attr));
2924  assert(attr);
2925 
2926  status = pthread_mutexattr_init(attr);
2927  if (status != 0) {
2928  fprintf(stderr, "ss_mutex_create: pthread_mutexattr_init() returned errno %d (%s)\n", status, strerror(status));
2929  }
2930 
2931  if (recursive) {
2932  status = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
2933  if (status != 0) {
2934  fprintf(stderr, "ss_mutex_create: pthread_mutexattr_settype() returned errno %d (%s)\n", status, strerror(status));
2935  }
2936  }
2937 
2938  *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
2939  assert(*mutex);
2940 
2941  status = pthread_mutex_init(*mutex, attr);
2942  if (status != 0) {
2943  fprintf(stderr, "ss_mutex_create: pthread_mutex_init() returned errno %d (%s), aborting...\n", status, strerror(status));
2944  abort(); // does not return
2945  return SS_NO_MUTEX;
2946  }
2947 
2948  free(attr);
2949 
2950  if (recursive) {
2951  // test recursive locks
2952 
2953  status = pthread_mutex_trylock(*mutex);
2954  assert(status == 0);
2955 
2956  status = pthread_mutex_trylock(*mutex);
2957  assert(status == 0); // EBUSY if PTHREAD_MUTEX_RECURSIVE does not work
2958 
2959  status = pthread_mutex_unlock(*mutex);
2960  assert(status == 0);
2961 
2962  status = pthread_mutex_unlock(*mutex);
2963  assert(status == 0);
2964  }
2965 
2966  return SS_SUCCESS;
2967  }
2968 #endif /* OS_UNIX */
2969 
2970 #ifdef OS_MSDOS
2971  return SS_NO_SEMAPHORE;
2972 #endif
2973 }
#define SS_NO_MUTEX
Definition: midas.h:697
#define SS_NO_SEMAPHORE
Definition: midas.h:676
#define SS_CREATED
Definition: midas.h:670
INT MUTEX_T
Definition: midas.h:237
Here is the caller graph for this function:

◆ ss_mutex_delete()

INT EXPRT ss_mutex_delete ( MUTEX_T mutex)

Definition at line 3150 of file system.cxx.

3168 {
3169 #ifdef OS_WINNT
3170 
3171  if (CloseHandle(*mutex) == FALSE)
3172  return SS_NO_SEMAPHORE;
3173 
3174  free(mutex);
3175 
3176  return SS_SUCCESS;
3177 
3178 #endif /* OS_WINNT */
3179 #ifdef OS_VXWORKS
3180  /* no code for VxWorks destroy yet */
3181  if (semDelete((SEM_ID) mutex_handle) == ERROR)
3182  return SS_NO_MUTEX;
3183  return SS_SUCCESS;
3184 #endif /* OS_VXWORKS */
3185 
3186 #ifdef OS_UNIX
3187  {
3188  int status;
3189 
3190  status = pthread_mutex_destroy(mutex);
3191  if (status != 0) {
3192  fprintf(stderr, "ss_mutex_delete: pthread_mutex_destroy() returned errno %d (%s), aborting...\n", status, strerror(status));
3193  abort(); // do not return
3194  return SS_NO_MUTEX;
3195  }
3196 
3197  free(mutex);
3198  return SS_SUCCESS;
3199  }
3200 #endif /* OS_UNIX */
3201 }
Here is the caller graph for this function:

◆ ss_mutex_release()

INT EXPRT ss_mutex_release ( MUTEX_T mutex)

Definition at line 3096 of file system.cxx.

3114 {
3115  INT status;
3116 
3117 #ifdef OS_WINNT
3118 
3119  status = ReleaseMutex(*mutex);
3120  if (status == FALSE)
3121  return SS_NO_SEMAPHORE;
3122 
3123  return SS_SUCCESS;
3124 
3125 #endif /* OS_WINNT */
3126 #ifdef OS_VXWORKS
3127 
3128  if (semGive((SEM_ID) mutes_handle) == ERROR)
3129  return SS_NO_MUTEX;
3130  return SS_SUCCESS;
3131 #endif /* OS_VXWORKS */
3132 #ifdef OS_UNIX
3133 
3134  status = pthread_mutex_unlock(mutex);
3135  if (status != 0) {
3136  fprintf(stderr, "ss_mutex_release: pthread_mutex_unlock() returned error %d (%s), aborting...\n", status, strerror(status));
3137  abort(); // does not return
3138  return SS_NO_MUTEX;
3139  }
3140 
3141  return SS_SUCCESS;
3142 #endif /* OS_UNIX */
3143 
3144 #ifdef OS_MSDOS
3145  return SS_NO_MUTEX;
3146 #endif
3147 }
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 2976 of file system.cxx.

2996 {
2997  INT status;
2998 
2999 #ifdef OS_WINNT
3000 
3001  status = WaitForSingleObject(*mutex, timeout == 0 ? INFINITE : timeout);
3002 
3003  if (status == WAIT_TIMEOUT) {
3004  return SS_TIMEOUT;
3005  }
3006 
3007  if (status == WAIT_FAILED) {
3008  fprintf(stderr, "ss_mutex_wait_for: WaitForSingleObject() failed, status = %d", status);
3009  abort(); // does not return
3010  return SS_NO_MUTEX;
3011  }
3012 
3013  return SS_SUCCESS;
3014 #endif /* OS_WINNT */
3015 #ifdef OS_VXWORKS
3016  /* convert timeout in ticks (1/60) = 1000/60 ~ 1/16 = >>4 */
3017  status = semTake((SEM_ID) mutex, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
3018  if (status == ERROR)
3019  return SS_NO_MUTEX;
3020  return SS_SUCCESS;
3021 
3022 #endif /* OS_VXWORKS */
3023 #if defined(OS_UNIX)
3024 
3025 #if defined(OS_DARWIN)
3026 
3027  if (timeout > 0) {
3028  // emulate pthread_mutex_timedlock under OS_DARWIN
3029  DWORD wait = 0;
3030  while (1) {
3031  status = pthread_mutex_trylock(mutex);
3032  if (status == 0) {
3033  return SS_SUCCESS;
3034  } else if (status == EBUSY) {
3035  ss_sleep(10);
3036  wait += 10;
3037  } else {
3038  fprintf(stderr, "ss_mutex_wait_for: fatal error: pthread_mutex_trylock() returned errno %d (%s), aborting...\n", status, strerror(status));
3039  abort(); // does not return
3040  }
3041  if (wait > timeout) {
3042  fprintf(stderr, "ss_mutex_wait_for: fatal error: timeout waiting for mutex, timeout was %d millisec, aborting...\n", timeout);
3043  abort(); // does not return
3044  }
3045  }
3046  } else {
3047  status = pthread_mutex_lock(mutex);
3048  }
3049 
3050  if (status != 0) {
3051  fprintf(stderr, "ss_mutex_wait_for: pthread_mutex_lock() returned errno %d (%s), aborting...\n", status, strerror(status));
3052  abort(); // does not return
3053  }
3054 
3055  return SS_SUCCESS;
3056 
3057 #else // OS_DARWIN
3058  if (timeout > 0) {
3059  extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex, __const struct timespec *__restrict __abstime) __THROW;
3060  struct timespec st;
3061 
3062  clock_gettime(CLOCK_REALTIME, &st);
3063  st.tv_sec += timeout / 1000;
3064  st.tv_nsec += (timeout % 1000) * 1000000;
3065  status = pthread_mutex_timedlock(mutex, &st);
3066 
3067  if (status == ETIMEDOUT) {
3068  fprintf(stderr, "ss_mutex_wait_for: fatal error: timeout waiting for mutex, timeout was %d millisec, aborting...\n", timeout);
3069  abort();
3070  }
3071 
3072  // Make linux timeout do same as MacOS timeout: abort() the program
3073  //if (status == ETIMEDOUT)
3074  // return SS_TIMEOUT;
3075  //return SS_SUCCESS;
3076  } else {
3077  status = pthread_mutex_lock(mutex);
3078  }
3079 
3080  if (status != 0) {
3081  fprintf(stderr, "ss_mutex_wait_for: pthread_mutex_lock() returned errno %d (%s), aborting...\n", status, strerror(status));
3082  abort();
3083  }
3084 
3085  return SS_SUCCESS;
3086 #endif
3087 
3088 #endif /* OS_UNIX */
3089 
3090 #ifdef OS_MSDOS
3091  return SS_NO_MUTEX;
3092 #endif
3093 }
INT ss_sleep(INT millisec)
Definition: system.cxx:3567
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 7879 of file system.cxx.

7880 {
7881  double nan;
7882 
7883  nan = 0;
7884  nan = 0 / nan;
7885  return nan;
7886 }
Here is the caller graph for this function:

◆ ss_pid_exists()

BOOL ss_pid_exists ( int  pid)

Definition at line 1446 of file system.cxx.

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

◆ ss_printf()

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

Definition at line 7321 of file system.cxx.

7342 {
7343  char str[256];
7344  va_list argptr;
7345 
7346  va_start(argptr, format);
7347  vsprintf(str, (char *) format, argptr);
7348  va_end(argptr);
7349 
7350 #ifdef OS_WINNT
7351  {
7352  HANDLE hConsole;
7353  COORD dwWriteCoord;
7354  DWORD cCharsWritten;
7355 
7356  hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
7357 
7358  dwWriteCoord.X = (short) x;
7359  dwWriteCoord.Y = (short) y;
7360 
7361  WriteConsoleOutputCharacter(hConsole, str, strlen(str), dwWriteCoord, &cCharsWritten);
7362  }
7363 
7364 #endif /* OS_WINNT */
7365 
7366 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
7367  printf("\033[%1d;%1dH", y + 1, x + 1);
7368  printf("%s", str);
7369  fflush(stdout);
7370 #endif
7371 
7372 #ifdef OS_MSDOS
7373  gotoxy(x + 1, y + 1);
7374  cputs(str);
7375 #endif
7376 }
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 5568 of file system.cxx.

5591 {
5592  NET_COMMAND_HEADER ncbuf;
5593  size_t n;
5594 
5595  /* first receive header */
5596  n = recv_tcp2(sock, (char*)&ncbuf, sizeof(ncbuf), timeout_ms);
5597 
5598  if (n == 0) {
5599  cm_msg(MERROR, "ss_recv_net_command", "timeout receiving network command header");
5600  return SS_TIMEOUT;
5601  }
5602 
5603  if (n != sizeof(ncbuf)) {
5604  cm_msg(MERROR, "ss_recv_net_command", "error receiving network command header, see messages");
5605  return SS_SOCKET_ERROR;
5606  }
5607 
5608  // FIXME: where is the big-endian/little-endian conversion?
5609  *routine_id = ncbuf.routine_id;
5610  *param_size = ncbuf.param_size;
5611 
5612  if (*param_size == 0) {
5613  *param_ptr = NULL;
5614  return SS_SUCCESS;
5615  }
5616 
5617  *param_ptr = (char *)malloc(*param_size);
5618 
5619  if (*param_ptr == NULL) {
5620  cm_msg(MERROR, "ss_recv_net_command", "error allocating %d bytes for network command data", *param_size);
5621  return SS_NO_MEMORY;
5622  }
5623 
5624  /* first receive header */
5625  n = recv_tcp2(sock, *param_ptr, *param_size, timeout_ms);
5626 
5627  if (n == 0) {
5628  cm_msg(MERROR, "ss_recv_net_command", "timeout receiving network command data");
5629  free(*param_ptr);
5630  *param_ptr = NULL;
5631  return SS_TIMEOUT;
5632  }
5633 
5634  if (n != *param_size) {
5635  cm_msg(MERROR, "ss_recv_net_command", "error receiving network command data, see messages");
5636  free(*param_ptr);
5637  *param_ptr = NULL;
5638  return SS_SOCKET_ERROR;
5639  }
5640 
5641  return SS_SUCCESS;
5642 }
#define SS_NO_MEMORY
Definition: midas.h:671
#define SS_SOCKET_ERROR
Definition: midas.h:679
INT recv_tcp2(int sock, char *net_buffer, int buffer_size, int timeout_ms)
Definition: system.cxx:5495
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 8090 of file system.cxx.

8091 {
8092  assert(string);
8093 
8094  bool modified = false;
8095 
8096  //std::string original = string;
8097 
8098  // FIXME: this function over-reads the input array. K.O. May 2021
8099 
8100  unsigned char * bytes = (unsigned char *)string;
8101  while(*bytes) {
8102  if( (// ASCII
8103  // use bytes[0] <= 0x7F to allow ASCII control characters
8104  bytes[0] == 0x09 ||
8105  bytes[0] == 0x0A ||
8106  bytes[0] == 0x0D ||
8107  (0x20 <= bytes[0] && bytes[0] <= 0x7E)
8108  )
8109  ) {
8110  bytes += 1;
8111  continue;
8112  }
8113 
8114  if( (// non-overlong 2-byte
8115  (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
8116  (0x80 <= bytes[1] && bytes[1] <= 0xBF)
8117  )
8118  ) {
8119  bytes += 2;
8120  continue;
8121  }
8122 
8123  if( (// excluding overlongs
8124  bytes[0] == 0xE0 &&
8125  (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
8126  (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8127  ) ||
8128  (// straight 3-byte
8129  ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
8130  bytes[0] == 0xEE ||
8131  bytes[0] == 0xEF) &&
8132  (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8133  (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8134  ) ||
8135  (// excluding surrogates
8136  bytes[0] == 0xED &&
8137  (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
8138  (0x80 <= bytes[2] && bytes[2] <= 0xBF)
8139  )
8140  ) {
8141  bytes += 3;
8142  continue;
8143  }
8144 
8145  if( (// planes 1-3
8146  bytes[0] == 0xF0 &&
8147  (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
8148  (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8149  (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8150  ) ||
8151  (// planes 4-15
8152  (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
8153  (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
8154  (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8155  (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8156  ) ||
8157  (// plane 16
8158  bytes[0] == 0xF4 &&
8159  (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
8160  (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
8161  (0x80 <= bytes[3] && bytes[3] <= 0xBF)
8162  )
8163  ) {
8164  bytes += 4;
8165  continue;
8166  }
8167 
8168  if (bytes[0] == 0) // end of string
8169  break;
8170 
8171  bytes[0] = '?';
8172  bytes += 1;
8173 
8174  modified = true;
8175  }
8176 
8177  //if (modified) {
8178  // printf("ss_repair_utf8(): invalid UTF8 string [%s] changed to [%s]\n", original.c_str(), string);
8179  //} else {
8180  // //printf("ss_repair_utf8(): string [%s] is ok\n", string);
8181  //}
8182 
8183  return modified;
8184 }
Here is the caller graph for this function:

◆ ss_repair_utf8() [2/2]

bool ss_repair_utf8 ( std::string &  s)

Definition at line 8186 of file system.cxx.

8187 {
8188  // C++11 std::string data() is same as c_str(), NUL-terminated.
8189  // C++17 std::string data() is not "const".
8190  // https://en.cppreference.com/w/cpp/string/basic_string/data
8191  return ss_repair_utf8((char*)s.data()); // FIXME: C++17 or newer, do not need to drop the "const". K.O. May 2021
8192 }
bool ss_repair_utf8(char *string)
Definition: system.cxx:8090
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 2183 of file system.cxx.

2183  {
2184  std::string result;
2185  size_t startPos = 0;
2186  size_t dollarPos;
2187 
2188  while ((dollarPos = inputPath.find('$', startPos)) != std::string::npos) {
2189  result.append(inputPath, startPos, dollarPos - startPos);
2190 
2191  size_t varEndPos = inputPath.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", dollarPos + 1);
2192  size_t varLength = varEndPos - dollarPos - 1;
2193  std::string varName = inputPath.substr(dollarPos + 1, varLength);
2194 
2195  char* varValue = std::getenv(varName.c_str());
2196  if (varValue != nullptr) {
2197  result.append(varValue);
2198  }
2199 
2200  startPos = varEndPos;
2201  }
2202 
2203  result.append(inputPath.c_str(), startPos, std::string::npos);
2204  return result;
2205 }
Here is the caller graph for this function:

◆ ss_resume()

INT ss_resume ( INT  port,
const char *  message 
)

Definition at line 4783 of file system.cxx.

4806 {
4807  assert(_ss_suspend_odb);
4808 
4809  struct sockaddr_in bind_addr;
4810 
4811  memcpy(&bind_addr, &_ss_suspend_odb->bind_addr, sizeof(struct sockaddr_in));
4812  bind_addr.sin_port = htons((short) port);
4813 
4814  size_t message_size = strlen(message) + 1;
4815 
4816  ssize_t wr = sendto(_ss_suspend_odb->ipc_send_socket, message, message_size, 0, (struct sockaddr *) &bind_addr, sizeof(struct sockaddr_in));
4817 
4818  if (wr < 0) {
4819  return SS_SOCKET_ERROR;
4820  }
4821 
4822  if (((size_t)wr) != message_size) {
4823  return SS_SOCKET_ERROR;
4824  }
4825 
4826  return SS_SUCCESS;
4827 }
static SUSPEND_STRUCT * _ss_suspend_odb
Definition: system.cxx:3919
#define message(type, str)
Definition: midas_macro.h:262
struct sockaddr_in bind_addr
Definition: system.cxx:3913
INT ipc_send_socket
Definition: system.cxx:3912
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 2427 of file system.cxx.

2456 {
2457  char semaphore_name[256];
2458 
2459  /* Add a leading MX_ to the semaphore name */
2460  sprintf(semaphore_name, "MX_%s", name);
2461 
2462 #ifdef OS_VXWORKS
2463 
2464  /* semBCreate is a Binary semaphore which is under VxWorks a optimized mutex
2465  refering to the programmer's Guide 5.3.1 */
2466  if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
2467  return SS_NO_MUTEX;
2468  return SS_CREATED;
2469 
2470 #endif /* OS_VXWORKS */
2471 
2472 #ifdef OS_WINNT
2473 
2474  *semaphore_handle = (HNDLE) CreateMutex(NULL, FALSE, semaphore_name);
2475 
2476  if (*semaphore_handle == 0)
2477  return SS_NO_SEMAPHORE;
2478 
2479  return SS_CREATED;
2480 
2481 #endif /* OS_WINNT */
2482 #ifdef OS_VMS
2483 
2484  /* VMS has to use lock manager... */
2485 
2486  {
2487  INT status;
2488  $DESCRIPTOR(semaphorename_dsc, "dummy");
2489  semaphorename_dsc.dsc$w_length = strlen(semaphore_name);
2490  semaphorename_dsc.dsc$a_pointer = semaphore_name;
2491 
2492  *semaphore_handle = (HNDLE) malloc(8);
2493 
2494  status = sys$enqw(0, LCK$K_NLMODE, *semaphore_handle, 0, &semaphorename_dsc, 0, 0, 0, 0, 0, 0);
2495 
2496  if (status != SS$_NORMAL) {
2497  free((void *) *semaphore_handle);
2498  *semaphore_handle = 0;
2499  }
2500 
2501  if (*semaphore_handle == 0)
2502  return SS_NO_SEMAPHORE;
2503 
2504  return SS_CREATED;
2505  }
2506 
2507 #endif /* OS_VMS */
2508 #ifdef OS_UNIX
2509 
2510  {
2511  INT key = IPC_PRIVATE;
2512  int status;
2513  struct semid_ds buf;
2514 
2515  if (name[0] != 0) {
2516  int fh;
2517  char path[256], file_name[256];
2518 
2519  /* Build the filename out of the path and the name of the semaphore */
2520  cm_get_path(path, sizeof(path));
2521  if (path[0] == 0) {
2522  if (!getcwd(path, sizeof(path)))
2523  path[0] = 0;
2524  strlcat(path, "/", sizeof(path));
2525  }
2526 
2527  strlcpy(file_name, path, sizeof(file_name));
2528  strlcat(file_name, ".", sizeof(file_name));
2529  strlcat(file_name, name, sizeof(file_name));
2530  strlcat(file_name, ".SHM", sizeof(file_name));
2531 
2532  /* create a unique key from the file name */
2533  key = ftok(file_name, 'M');
2534  if (key < 0) {
2535  fh = open(file_name, O_CREAT, 0644);
2536  close(fh);
2537  key = ftok(file_name, 'M');
2538  status = SS_CREATED;
2539  }
2540  }
2541 
2542 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
2543  union semun arg;
2544 #else
2545  union semun {
2546  INT val;
2547  struct semid_ds *buf;
2548  ushort *array;
2549  } arg;
2550 #endif
2551 
2552  status = SS_SUCCESS;
2553 
2554  /* create or get semaphore */
2555  *semaphore_handle = (HNDLE) semget(key, 1, 0);
2556  //printf("create1 key 0x%x, id %d, errno %d (%s)\n", key, *semaphore_handle, errno, strerror(errno));
2557  if (*semaphore_handle < 0) {
2558  *semaphore_handle = (HNDLE) semget(key, 1, IPC_CREAT);
2559  //printf("create2 key 0x%x, id %d, errno %d (%s)\n", key, *semaphore_handle, errno, strerror(errno));
2560  status = SS_CREATED;
2561  }
2562 
2563  if (*semaphore_handle < 0) {
2564  cm_msg(MERROR, "ss_semaphore_create", "Cannot create semaphore \'%s\', semget(0x%x) failed, errno %d (%s)", name, key, errno, strerror(errno));
2565 
2566  fprintf(stderr, "ss_semaphore_create: Cannot create semaphore \'%s\', semget(0x%x) failed, errno %d (%s)", name, key, errno, strerror(errno));
2567  abort(); // does not return
2568  return SS_NO_SEMAPHORE;
2569  }
2570 
2571  memset(&buf, 0, sizeof(buf));
2572  buf.sem_perm.uid = getuid();
2573  buf.sem_perm.gid = getgid();
2574  buf.sem_perm.mode = 0666;
2575  arg.buf = &buf;
2576 
2577  semctl(*semaphore_handle, 0, IPC_SET, arg);
2578 
2579  /* if semaphore was created, set value to one */
2580  if (key == IPC_PRIVATE || status == SS_CREATED) {
2581  arg.val = 1;
2582  if (semctl(*semaphore_handle, 0, SETVAL, arg) < 0)
2583  return SS_NO_SEMAPHORE;
2584  }
2585 
2586  if (s_semaphore_trace) {
2587  fprintf(stderr, "name %d %d %d %s\n", *semaphore_handle, (int)time(NULL), getpid(), name);
2588  }
2589 
2590  return SS_SUCCESS;
2591  }
2592 #endif /* OS_UNIX */
2593 
2594 #ifdef OS_MSDOS
2595  return SS_NO_SEMAPHORE;
2596 #endif
2597 }
static std::atomic_bool s_semaphore_trace
Definition: system.cxx:2424
KEY key
Definition: mdump.cxx:37
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 2808 of file system.cxx.

2826 {
2827 #ifdef OS_WINNT
2828 
2829  if (CloseHandle((HANDLE) semaphore_handle) == FALSE)
2830  return SS_NO_SEMAPHORE;
2831 
2832  return SS_SUCCESS;
2833 
2834 #endif /* OS_WINNT */
2835 #ifdef OS_VMS
2836 
2837  free((void *) semaphore_handle);
2838  return SS_SUCCESS;
2839 
2840 #endif /* OS_VMS */
2841 
2842 #ifdef OS_VXWORKS
2843  /* no code for VxWorks destroy yet */
2844  if (semDelete((SEM_ID) semaphore_handle) == ERROR)
2845  return SS_NO_SEMAPHORE;
2846  return SS_SUCCESS;
2847 #endif /* OS_VXWORKS */
2848 
2849 #ifdef OS_UNIX
2850 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(OS_CYGWIN)) || defined(OS_FREEBSD)
2851  union semun arg;
2852 #else
2853  union semun {
2854  INT val;
2855  struct semid_ds *buf;
2856  ushort *array;
2857  } arg;
2858 #endif
2859 
2860  memset(&arg, 0, sizeof(arg));
2861 
2862  if (destroy_flag) {
2863  int status = semctl(semaphore_handle, 0, IPC_RMID, arg);
2864  //printf("semctl(ID=%d, IPC_RMID) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
2865  if (status < 0)
2866  return SS_NO_SEMAPHORE;
2867  }
2868 
2869  return SS_SUCCESS;
2870 
2871 #endif /* OS_UNIX */
2872 
2873 #ifdef OS_MSDOS
2874  return SS_NO_SEMAPHORE;
2875 #endif
2876 }
Here is the caller graph for this function:

◆ ss_semaphore_release()

INT EXPRT ss_semaphore_release ( HNDLE  semaphore_handle)

Definition at line 2720 of file system.cxx.

2738 {
2739  INT status;
2740 
2741 #ifdef OS_WINNT
2742 
2743  status = ReleaseMutex((HANDLE) semaphore_handle);
2744 
2745  if (status == FALSE)
2746  return SS_NO_SEMAPHORE;
2747 
2748  return SS_SUCCESS;
2749 
2750 #endif /* OS_WINNT */
2751 #ifdef OS_VMS
2752 
2753  status = sys$enqw(0, LCK$K_NLMODE, semaphore_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
2754 
2755  if (status != SS$_NORMAL)
2756  return SS_NO_SEMAPHORE;
2757 
2758  return SS_SUCCESS;
2759 
2760 #endif /* OS_VMS */
2761 
2762 #ifdef OS_VXWORKS
2763 
2764  if (semGive((SEM_ID) semaphore_handle) == ERROR)
2765  return SS_NO_SEMAPHORE;
2766  return SS_SUCCESS;
2767 #endif /* OS_VXWORKS */
2768 
2769 #ifdef OS_UNIX
2770  {
2771  struct sembuf sb;
2772 
2773  sb.sem_num = 0;
2774  sb.sem_op = 1; /* increment semaphore */
2775  sb.sem_flg = SEM_UNDO;
2776 
2777  if (s_semaphore_trace) {
2778  fprintf(stderr, "unlock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int(s_semaphore_nest_level));
2779  assert(s_semaphore_nest_level > 0);
2781  }
2782 
2783  do {
2784  status = semop(semaphore_handle, &sb, 1);
2785 
2786  /* return on success */
2787  if (status == 0)
2788  break;
2789 
2790  /* retry if interrupted by a ss_wake signal */
2791  if (errno == EINTR)
2792  continue;
2793 
2794  fprintf(stderr, "ss_semaphore_release: semop/semtimedop(%d) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
2795  return SS_NO_SEMAPHORE;
2796  } while (1);
2797 
2798  return SS_SUCCESS;
2799  }
2800 #endif /* OS_UNIX */
2801 
2802 #ifdef OS_MSDOS
2803  return SS_NO_SEMAPHORE;
2804 #endif
2805 }
static std::atomic_int s_semaphore_nest_level
Definition: system.cxx:2425
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,
INT  timeout 
)

Definition at line 2600 of file system.cxx.

2620 {
2621  INT status;
2622 
2623 #ifdef OS_WINNT
2624 
2625  status = WaitForSingleObject((HANDLE) semaphore_handle, timeout == 0 ? INFINITE : timeout);
2626  if (status == WAIT_FAILED)
2627  return SS_NO_SEMAPHORE;
2628  if (status == WAIT_TIMEOUT)
2629  return SS_TIMEOUT;
2630 
2631  return SS_SUCCESS;
2632 #endif /* OS_WINNT */
2633 #ifdef OS_VMS
2634  status = sys$enqw(0, LCK$K_EXMODE, semaphore_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
2635  if (status != SS$_NORMAL)
2636  return SS_NO_SEMAPHORE;
2637  return SS_SUCCESS;
2638 
2639 #endif /* OS_VMS */
2640 #ifdef OS_VXWORKS
2641  /* convert timeout in ticks (1/60) = 1000/60 ~ 1/16 = >>4 */
2642  status = semTake((SEM_ID) semaphore_handle, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
2643  if (status == ERROR)
2644  return SS_NO_SEMAPHORE;
2645  return SS_SUCCESS;
2646 
2647 #endif /* OS_VXWORKS */
2648 #ifdef OS_UNIX
2649  {
2650  DWORD start_time;
2651  struct sembuf sb;
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 
2663  sb.sem_num = 0;
2664  sb.sem_op = -1; /* decrement semaphore */
2665  sb.sem_flg = SEM_UNDO;
2666 
2667  memset(&arg, 0, sizeof(arg));
2668 
2669  start_time = ss_millitime();
2670 
2671  if (s_semaphore_trace) {
2672  fprintf(stderr, "waitlock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int(s_semaphore_nest_level));
2673  }
2674 
2675  do {
2676 #if defined(OS_DARWIN)
2677  status = semop(semaphore_handle, &sb, 1);
2678 #elif defined(OS_LINUX)
2679  struct timespec ts;
2680  ts.tv_sec = 1;
2681  ts.tv_nsec = 0;
2682 
2683  status = semtimedop(semaphore_handle, &sb, 1, &ts);
2684 #else
2685  status = semop(semaphore_handle, &sb, 1);
2686 #endif
2687 
2688  /* return on success */
2689  if (status == 0)
2690  break;
2691 
2692  /* retry if interrupted by a ss_wake signal */
2693  if (errno == EINTR || errno == EAGAIN) {
2694  /* return if timeout expired */
2695  if (timeout > 0 && (int) (ss_millitime() - start_time) > timeout)
2696  return SS_TIMEOUT;
2697 
2698  continue;
2699  }
2700 
2701  fprintf(stderr, "ss_semaphore_wait_for: semop/semtimedop(%d) returned %d, errno %d (%s)\n", semaphore_handle, status, errno, strerror(errno));
2702  return SS_NO_SEMAPHORE;
2703  } while (1);
2704 
2705  if (s_semaphore_trace) {
2707  fprintf(stderr, "lock %d %d %d nest %d\n", semaphore_handle, ss_millitime(), getpid(), int( s_semaphore_nest_level));
2708  }
2709 
2710  return SS_SUCCESS;
2711  }
2712 #endif /* OS_UNIX */
2713 
2714 #ifdef OS_MSDOS
2715  return SS_NO_SEMAPHORE;
2716 #endif
2717 }
TRIGGER_SETTINGS ts
Definition: fevmemodules.c:102
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 7288 of file system.cxx.

7305 {
7306 #ifdef OS_WINNT
7307 
7308  HANDLE hConsole;
7309  COORD coordSize;
7310 
7311  coordSize.X = (short) x;
7312  coordSize.Y = (short) y;
7313  hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
7314  SetConsoleScreenBufferSize(hConsole, coordSize);
7315 
7316 #else /* OS_WINNT */
7317 #endif
7318 }

◆ ss_settime()

DWORD EXPRT ss_settime ( DWORD  seconds)

Definition at line 3414 of file system.cxx.

3430 {
3431 #if defined(OS_WINNT)
3432  SYSTEMTIME st;
3433  struct tm ltm;
3434 
3435  ss_tzset();
3436  localtime_r((time_t *) & seconds, &ltm);
3437 
3438  st.wYear = ltm.tm_year + 1900;
3439  st.wMonth = ltm.tm_mon + 1;
3440  st.wDay = ltm.tm_mday;
3441  st.wHour = ltm.tm_hour;
3442  st.wMinute = ltm.tm_min;
3443  st.wSecond = ltm.tm_sec;
3444  st.wMilliseconds = 0;
3445 
3446  SetLocalTime(&st);
3447 
3448 #elif defined(OS_DARWIN) && defined(CLOCK_REALTIME)
3449 
3450  struct timespec ltm;
3451 
3452  ltm.tv_sec = seconds;
3453  ltm.tv_nsec = 0;
3454  clock_settime(CLOCK_REALTIME, &ltm);
3455 
3456 #elif defined(OS_CYGWIN) && defined(CLOCK_REALTIME)
3457 
3458  struct timespec ltm;
3459 
3460  ltm.tv_sec = seconds;
3461  ltm.tv_nsec = 0;
3462  clock_settime(CLOCK_REALTIME, &ltm);
3463  return SS_NO_DRIVER;
3464 
3465 #elif defined(OS_UNIX) && defined(CLOCK_REALTIME)
3466 
3467  struct timespec ltm;
3468 
3469  ltm.tv_sec = seconds;
3470  ltm.tv_nsec = 0;
3471  clock_settime(CLOCK_REALTIME, &ltm);
3472 
3473 #elif defined(OS_VXWORKS)
3474 
3475  struct timespec ltm;
3476 
3477  ltm.tv_sec = seconds;
3478  ltm.tv_nsec = 0;
3479  clock_settime(CLOCK_REALTIME, &ltm);
3480 
3481 #else
3482 #warning ss_settime() is not supported!
3483 #endif
3484  return SS_SUCCESS;
3485 }
#define SS_NO_DRIVER
Definition: midas.h:689
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 1731 of file system.cxx.

1748 {
1749 #ifdef OS_WINNT
1750 
1751  HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
1752  hChildStdoutRd, hChildStdoutWr, hChildStderrRd, hChildStderrWr, hSaveStdin, hSaveStdout, hSaveStderr;
1753 
1754  SECURITY_ATTRIBUTES saAttr;
1755  PROCESS_INFORMATION piProcInfo;
1756  STARTUPINFO siStartInfo;
1757  char buffer[256], cmd[256];
1758  DWORD dwRead, dwWritten, dwAvail, i, i_cmd;
1759  fd_set readfds;
1760  struct timeval timeout;
1761 
1762  /* Set the bInheritHandle flag so pipe handles are inherited. */
1763  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
1764  saAttr.bInheritHandle = TRUE;
1765  saAttr.lpSecurityDescriptor = NULL;
1766 
1767  /* Save the handle to the current STDOUT. */
1768  hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
1769 
1770  /* Create a pipe for the child's STDOUT. */
1771  if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
1772  return 0;
1773 
1774  /* Set a write handle to the pipe to be STDOUT. */
1775  if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
1776  return 0;
1777 
1778 
1779  /* Save the handle to the current STDERR. */
1780  hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
1781 
1782  /* Create a pipe for the child's STDERR. */
1783  if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
1784  return 0;
1785 
1786  /* Set a read handle to the pipe to be STDERR. */
1787  if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
1788  return 0;
1789 
1790 
1791  /* Save the handle to the current STDIN. */
1792  hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
1793 
1794  /* Create a pipe for the child's STDIN. */
1795  if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
1796  return 0;
1797 
1798  /* Set a read handle to the pipe to be STDIN. */
1799  if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
1800  return 0;
1801 
1802  /* Duplicate the write handle to the pipe so it is not inherited. */
1803  if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, /* not inherited */
1804  DUPLICATE_SAME_ACCESS))
1805  return 0;
1806 
1807  CloseHandle(hChildStdinWr);
1808 
1809  /* Now create the child process. */
1810  memset(&siStartInfo, 0, sizeof(siStartInfo));
1811  siStartInfo.cb = sizeof(STARTUPINFO);
1812  siStartInfo.lpReserved = NULL;
1813  siStartInfo.lpReserved2 = NULL;
1814  siStartInfo.cbReserved2 = 0;
1815  siStartInfo.lpDesktop = NULL;
1816  siStartInfo.dwFlags = 0;
1817 
1818  if (!CreateProcess(NULL, "cmd /Q", /* command line */
1819  NULL, /* process security attributes */
1820  NULL, /* primary thread security attributes */
1821  TRUE, /* handles are inherited */
1822  0, /* creation flags */
1823  NULL, /* use parent's environment */
1824  NULL, /* use parent's current directory */
1825  &siStartInfo, /* STARTUPINFO pointer */
1826  &piProcInfo)) /* receives PROCESS_INFORMATION */
1827  return 0;
1828 
1829  /* After process creation, restore the saved STDIN and STDOUT. */
1830  SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
1831  SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
1832  SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
1833 
1834  i_cmd = 0;
1835 
1836  do {
1837  /* query stderr */
1838  do {
1839  if (!PeekNamedPipe(hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
1840  break;
1841 
1842  if (dwRead > 0) {
1843  ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
1844  send(sock, buffer, dwRead, 0);
1845  }
1846  } while (dwAvail > 0);
1847 
1848  /* query stdout */
1849  do {
1850  if (!PeekNamedPipe(hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
1851  break;
1852  if (dwRead > 0) {
1853  ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
1854  send(sock, buffer, dwRead, 0);
1855  }
1856  } while (dwAvail > 0);
1857 
1858 
1859  /* check if subprocess still alive */
1860  if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
1861  break;
1862  if (i != STILL_ACTIVE)
1863  break;
1864 
1865  /* query network socket */
1866  FD_ZERO(&readfds);
1867  FD_SET(sock, &readfds);
1868  timeout.tv_sec = 0;
1869  timeout.tv_usec = 100;
1870  select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
1871 
1872  if (FD_ISSET(sock, &readfds)) {
1873  i = recv(sock, cmd + i_cmd, 1, 0);
1874  if (i <= 0)
1875  break;
1876 
1877  /* backspace */
1878  if (cmd[i_cmd] == 8) {
1879  if (i_cmd > 0) {
1880  send(sock, "\b \b", 3, 0);
1881  i_cmd -= 1;
1882  }
1883  } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
1884  send(sock, cmd + i_cmd, 1, 0);
1885  i_cmd += i;
1886  }
1887  }
1888 
1889  /* linefeed triggers new command */
1890  if (cmd[i_cmd - 1] == 10) {
1891  WriteFile(hChildStdinWrDup, cmd, i_cmd, &dwWritten, NULL);
1892  i_cmd = 0;
1893  }
1894 
1895  } while (TRUE);
1896 
1897  CloseHandle(hChildStdinWrDup);
1898  CloseHandle(hChildStdinRd);
1899  CloseHandle(hChildStderrRd);
1900  CloseHandle(hChildStdoutRd);
1901 
1902  return SS_SUCCESS;
1903 
1904 #endif /* OS_WINNT */
1905 
1906 #ifdef OS_UNIX
1907 #ifndef NO_PTY
1908  pid_t pid;
1909  int i, p;
1910  char line[32], buffer[1024], shell[32];
1911  fd_set readfds;
1912 
1913 #ifdef NO_FORK
1914  assert(!"support for forkpty() disabled by NO_FORK");
1915 #else
1916  pid = forkpty(&p, line, NULL, NULL);
1917 #endif
1918  if (pid < 0)
1919  return 0;
1920  else if (pid > 0) {
1921  /* parent process */
1922 
1923  do {
1924  FD_ZERO(&readfds);
1925  FD_SET(sock, &readfds);
1926  FD_SET(p, &readfds);
1927 
1928  select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
1929 
1930  if (FD_ISSET(sock, &readfds)) {
1931  memset(buffer, 0, sizeof(buffer));
1932  i = recv(sock, buffer, sizeof(buffer), 0);
1933  if (i <= 0)
1934  break;
1935  if (write(p, buffer, i) != i)
1936  break;
1937  }
1938 
1939  if (FD_ISSET(p, &readfds)) {
1940  memset(buffer, 0, sizeof(buffer));
1941  i = read(p, buffer, sizeof(buffer));
1942  if (i <= 0)
1943  break;
1944  send(sock, buffer, i, 0);
1945  }
1946 
1947  } while (1);
1948  } else {
1949  /* child process */
1950 
1951  if (getenv("SHELL"))
1952  strlcpy(shell, getenv("SHELL"), sizeof(shell));
1953  else
1954  strcpy(shell, "/bin/sh");
1955  int error = execl(shell, shell, NULL);
1956  // NB: execl() does not return unless there is an error.
1957  fprintf(stderr, "ss_shell: Cannot execute command \"%s\": execl() returned %d, errno %d (%s), aborting!\n", shell, error, errno, strerror(errno));
1958  abort();
1959  }
1960 #else
1961  send(sock, "not implemented\n", 17, 0);
1962 #endif /* NO_PTY */
1963 
1964  return SS_SUCCESS;
1965 
1966 #endif /* OS_UNIX */
1967 }
#define FD_SETSIZE
Definition: msystem.h:199
Here is the call graph for this function:

◆ ss_shm_close()

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

Definition at line 764 of file system.cxx.

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

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

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

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

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

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

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

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

3568 {
3569  if (millisec == 0) {
3570 #ifdef OS_WINNT
3571  SuspendThread(GetCurrentThread());
3572 #endif
3573 #ifdef OS_VMS
3574  sys$hiber();
3575 #endif
3576 #ifdef OS_UNIX
3577  signal(SIGCONT, ss_cont);
3578  pause();
3579 #endif
3580  return SS_SUCCESS;
3581  }
3582 #ifdef OS_WINNT
3583  Sleep(millisec);
3584 #endif
3585 #ifdef OS_UNIX
3586  struct timespec ts;
3587  int status;
3588 
3589  ts.tv_sec = millisec / 1000;
3590  ts.tv_nsec = (millisec % 1000) * 1E6;
3591 
3592  do {
3593  status = nanosleep(&ts, &ts);
3594  if ((int)ts.tv_sec < 0)
3595  break; // can be negative under OSX
3596  } while (status == -1 && errno == EINTR);
3597 #endif
3598 
3599  return SS_SUCCESS;
3600 }
Here is the caller graph for this function:

◆ ss_socket_check()

static int ss_socket_check ( int  sock)
static

Definition at line 4432 of file system.cxx.

4433 {
4434  // copied from the old rpc_server_receive()
4435 
4436  /* only check if TCP connection is broken */
4437 
4438  char test_buffer[256];
4439 #ifdef OS_WINNT
4440  int n_received = recv(sock, test_buffer, sizeof(test_buffer), MSG_PEEK);
4441 #else
4442  int n_received = recv(sock, test_buffer, sizeof(test_buffer), MSG_PEEK | MSG_DONTWAIT);
4443 
4444  /* check if we caught a signal */
4445  if ((n_received == -1) && (errno == EAGAIN))
4446  return SS_SUCCESS;
4447 #endif
4448 
4449  if (n_received == -1) {
4450  cm_msg(MERROR, "ss_socket_check", "recv(%d,MSG_PEEK) returned %d, errno: %d (%s)", (int) sizeof(test_buffer), n_received, errno, strerror(errno));
4451  }
4452 
4453  if (n_received <= 0)
4454  return SS_ABORT;
4455 
4456  return SS_SUCCESS;
4457 }
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 5164 of file system.cxx.

5165 {
5166  assert(sockp != NULL);
5167  if (gSocketTrace) {
5168  fprintf(stderr, "ss_socket_close: %d\n", *sockp);
5169  }
5170  int err = close(*sockp);
5171  if (err) {
5172  cm_msg(MERROR, "ss_socket_close", "unexpected error, close() returned %d, errno: %d (%s)", err, errno, strerror(errno));
5173  }
5174  *sockp = 0;
5175  return SS_SUCCESS;
5176 }
static bool gSocketTrace
Definition: system.cxx:4903
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 4906 of file system.cxx.

4907 {
4908  assert(sockp != NULL);
4909  assert(error_msg_p != NULL);
4910  *sockp = 0;
4911 
4912 #ifdef OS_WINNT
4913  {
4914  WSADATA WSAData;
4915 
4916  /* Start windows sockets */
4917  if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
4918  return RPC_NET_ERROR;
4919  }
4920 #endif
4921 
4922  char portname[256];
4923  sprintf(portname, "%d", tcp_port);
4924 
4925  struct addrinfo *ainfo = NULL;
4926 
4927  int status = getaddrinfo(hostname, portname, NULL, &ainfo);
4928 
4929  if (status != 0) {
4930  *error_msg_p = msprintf("cannot resolve hostname \"%s\", getaddrinfo() error %d (%s)", hostname, status, gai_strerror(status));
4931  if (ainfo)
4932  freeaddrinfo(ainfo);
4933  return RPC_NET_ERROR;
4934  }
4935 
4936  // NOTE: ainfo must be freeed using freeaddrinfo(ainfo);
4937 
4938  int sock = 0;
4939 
4940  for (const struct addrinfo *r = ainfo; r != NULL; r = r->ai_next) {
4941  if (gSocketTrace) {
4942  fprintf(stderr, "ss_socket_connect_tcp: hostname [%s] port %d addrinfo: flags %d, family %d, socktype %d, protocol %d, canonname [%s]\n",
4943  hostname,
4944  tcp_port,
4945  r->ai_flags,
4946  r->ai_family,
4947  r->ai_socktype,
4948  r->ai_protocol,
4949  r->ai_canonname);
4950  }
4951 
4952  // skip anything but TCP addresses
4953  if (r->ai_socktype != SOCK_STREAM) {
4954  continue;
4955  }
4956 
4957  // skip anything but TCP protocol 6
4958  if (r->ai_protocol != 6) {
4959  continue;
4960  }
4961 
4962  sock = ::socket(r->ai_family, r->ai_socktype, 0);
4963 
4964  if (sock <= 0) {
4965  *error_msg_p = msprintf("cannot create socket, errno %d (%s)", errno, strerror(errno));
4966  continue;
4967  }
4968 
4969  status = ::connect(sock, r->ai_addr, r->ai_addrlen);
4970  if (status != 0) {
4971  if (gSocketTrace) {
4972  fprintf(stderr, "ss_socket_connect_tcp: connect() status %d, errno %d (%s)\n", status, errno, strerror(errno));
4973  }
4974  *error_msg_p = msprintf("cannot connect to host \"%s\" port %d, errno %d (%s)", hostname, tcp_port, errno, strerror(errno));
4975  ::close(sock);
4976  sock = 0;
4977  continue;
4978  }
4979  // successfully connected
4980  break;
4981  }
4982 
4983  freeaddrinfo(ainfo);
4984  ainfo = NULL;
4985 
4986  if (sock == 0) {
4987  // error_msg is already set
4988  return RPC_NET_ERROR;
4989  }
4990 
4991  *sockp = sock;
4992 
4993  if (gSocketTrace) {
4994  fprintf(stderr, "ss_socket_connect_tcp: hostname [%s] port %d new socket %d\n", hostname, tcp_port, *sockp);
4995  }
4996 
4997  return SS_SUCCESS;
4998 }
#define RPC_NET_ERROR
Definition: midas.h:707
std::string msprintf(const char *format,...)
Definition: midas.cxx:412
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 5179 of file system.cxx.

5180 {
5181  char addr[64];
5182 
5183  unsigned size = sizeof(addr);
5184  int rv = getpeername(sock, (struct sockaddr *) &addr, &size);
5185 
5186  //printf("getpeername() returned %d, size %d, buffer %d\n", rv, size, (int)sizeof(addr));
5187 
5188  if (rv != 0) {
5189  cm_msg(MERROR, "ss_socket_get_peer_name", "Error: getpeername() returned %d, errno %d (%s)", rv, errno, strerror(errno));
5190  return SS_SOCKET_ERROR;
5191  }
5192 
5193  char hostname[256];
5194  char servname[16];
5195 
5196  int ret = getnameinfo((struct sockaddr*)&addr, size,
5197  hostname, sizeof(hostname),
5198  servname, sizeof(servname),
5199  NI_NUMERICSERV);
5200 
5201  if (ret != 0) {
5202  cm_msg(MERROR, "ss_socket_get_peer_name", "Error: getnameinfo() error %d (%s)", ret, gai_strerror(ret));
5203  return SS_SOCKET_ERROR;
5204  }
5205 
5206  //printf("getnameinfo() returned %d, hostname [%s], servname[%s]\n", ret, hostname, servname);
5207 
5208  if (hostp)
5209  *hostp = hostname;
5210 
5211  if (portp)
5212  *portp = atoi(servname);
5213 
5214  return SS_SUCCESS;
5215 }
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 5001 of file system.cxx.

5002 {
5003  assert(sockp != NULL);
5004  assert(tcp_port_p != NULL);
5005  assert(error_msg_p != NULL);
5006 
5007  *sockp = 0;
5008  *tcp_port_p = 0;
5009 
5010 #ifdef OS_WINNT
5011  {
5012  WSADATA WSAData;
5013 
5014  /* Start windows sockets */
5015  if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
5016  return RPC_NET_ERROR;
5017  }
5018 #endif
5019 
5020 #ifdef AF_INET6
5021  bool use_inet6 = true;
5022 #else
5023  bool use_inet6 = false;
5024 #endif
5025 
5026  if (listen_localhost)
5027  use_inet6 = false;
5028 
5029  /* create a socket for listening */
5030  int lsock;
5031  if (use_inet6) {
5032 #ifdef AF_INET6
5033  lsock = socket(AF_INET6, SOCK_STREAM, 0);
5034 #endif
5035  } else {
5036  lsock = socket(AF_INET, SOCK_STREAM, 0);
5037  }
5038 
5039  if (lsock == -1) {
5040  *error_msg_p = msprintf("socket(AF_INET, SOCK_STREAM) failed, errno %d (%s)", errno, strerror(errno));
5041  return RPC_NET_ERROR;
5042  }
5043 
5044  /* reuse address, needed if previous server stopped (30s timeout!) */
5045  int flag = 1;
5046  int status = setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof(int));
5047  if (status < 0) {
5048  *error_msg_p = msprintf("setsockopt(SO_REUSEADDR) failed, errno %d (%s)", errno, strerror(errno));
5049  return RPC_NET_ERROR;
5050  }
5051 
5052 #ifdef AF_INET6
5053 #ifdef IPV6_V6ONLY
5054  if (use_inet6) {
5055  /* turn off IPV6_V6ONLY, see RFC 3493 */
5056  flag = 0;
5057  status = setsockopt(lsock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flag, sizeof(int));
5058  if (status < 0) {
5059  *error_msg_p = msprintf("setsockopt(IPPROTO_IPV6, IPV6_V6ONLY) failed, errno %d (%s)", errno, strerror(errno));
5060  return RPC_NET_ERROR;
5061  }
5062  }
5063 #else
5064 #warning strange: AF_INET6 is defined, but IPV6_V6ONLY is not defined
5065 #endif
5066 #endif
5067 
5068  if (use_inet6) {
5069 #ifdef AF_INET6
5070  /* bind local node name and port to socket */
5071  struct sockaddr_in6 bind_addr6;
5072  memset(&bind_addr6, 0, sizeof(bind_addr6));
5073  bind_addr6.sin6_family = AF_INET6;
5074 
5075  if (listen_localhost) {
5076  bind_addr6.sin6_addr = in6addr_loopback;
5077  } else {
5078  bind_addr6.sin6_addr = in6addr_any;
5079  }
5080 
5081  if (tcp_port)
5082  bind_addr6.sin6_port = htons((short) tcp_port);
5083  else
5084  bind_addr6.sin6_port = htons(0); // OS will allocate a port number for us
5085 
5086  status = bind(lsock, (struct sockaddr *) &bind_addr6, sizeof(bind_addr6));
5087  if (status < 0) {
5088  *error_msg_p = msprintf("IPv6 bind() to port %d failed, errno %d (%s)", tcp_port, errno, strerror(errno));
5089  return RPC_NET_ERROR;
5090  }
5091 #endif
5092  } else {
5093  /* bind local node name and port to socket */
5094  struct sockaddr_in bind_addr;
5095  memset(&bind_addr, 0, sizeof(bind_addr));
5096  bind_addr.sin_family = AF_INET;
5097 
5098  if (listen_localhost) {
5099  bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
5100  } else {
5101  bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
5102  }
5103 
5104  if (tcp_port)
5105  bind_addr.sin_port = htons((short) tcp_port);
5106  else
5107  bind_addr.sin_port = htons(0); // OS will allocate a port number for us
5108 
5109  status = bind(lsock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
5110  if (status < 0) {
5111  *error_msg_p = msprintf("bind() to port %d failed, errno %d (%s)", tcp_port, errno, strerror(errno));
5112  return RPC_NET_ERROR;
5113  }
5114  }
5115 
5116  /* listen for connection */
5117 #ifdef OS_MSDOS
5118  status = listen(lsock, 1);
5119 #else
5120  status = listen(lsock, SOMAXCONN);
5121 #endif
5122  if (status < 0) {
5123  *error_msg_p = msprintf("listen() failed, errno %d (%s)", errno, strerror(errno));
5124  return RPC_NET_ERROR;
5125  }
5126 
5127  if (use_inet6) {
5128 #ifdef AF_INET6
5129  struct sockaddr_in6 addr;
5130  socklen_t sosize = sizeof(addr);
5131  status = getsockname(lsock, (struct sockaddr*)&addr, &sosize);
5132  if (status < 0) {
5133  *error_msg_p = msprintf("IPv6 getsockname() failed, errno %d (%s)", errno, strerror(errno));
5134  return RPC_NET_ERROR;
5135  }
5136 
5137  *tcp_port_p = ntohs(addr.sin6_port);
5138 #endif
5139  } else {
5140  struct sockaddr_in addr;
5141  socklen_t sosize = sizeof(addr);
5142  status = getsockname(lsock, (struct sockaddr*)&addr, &sosize);
5143  if (status < 0) {
5144  *error_msg_p = msprintf("getsockname() failed, errno %d (%s)", errno, strerror(errno));
5145  return RPC_NET_ERROR;
5146  }
5147 
5148  *tcp_port_p = ntohs(addr.sin_port);
5149  }
5150 
5151  *sockp = lsock;
5152 
5153  if (gSocketTrace) {
5154  if (listen_localhost)
5155  fprintf(stderr, "ss_socket_listen_tcp: listening tcp port %d local connections only, new socket %d\n", *tcp_port_p, *sockp);
5156  else
5157  fprintf(stderr, "ss_socket_listen_tcp: listening tcp port %d all internet connections, socket %d\n", *tcp_port_p, *sockp);
5158  }
5159 
5160  return SS_SUCCESS;
5161 }
#define SOMAXCONN
Definition: mongoose4.cxx:302
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 4837 of file system.cxx.

4854 {
4855  INT status;
4856  fd_set readfds;
4857  struct timeval timeout;
4858  struct timeval timeout0;
4859  DWORD start_time = 0; // start_time is only used for BSD select() behaviour (MacOS)
4860  DWORD end_time = 0;
4861 
4862  FD_ZERO(&readfds);
4863  FD_SET(sock, &readfds);
4864 
4865  timeout.tv_sec = millisec / 1000;
4866  timeout.tv_usec = (millisec % 1000) * 1000;
4867 
4868  timeout0 = timeout;
4869 
4870  while (1) {
4871  status = select(sock+1, &readfds, NULL, NULL, &timeout);
4872  //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));
4873 
4874 #ifndef OS_WINNT
4875  if (status<0 && errno==EINTR) { /* watchdog alarm signal */
4876  /* need to determine if select() updates "timeout" (Linux) or keeps original value (BSD) */
4877  if (timeout.tv_sec == timeout0.tv_sec) {
4878  DWORD now = ss_time();
4879  if (start_time == 0) {
4880  start_time = now;
4881  end_time = start_time + (millisec+999)/1000;
4882  }
4883  //printf("ss_socket_wait: EINTR: now %d, timeout %d, wait time %d\n", now, end_time, end_time - now);
4884  if (now > end_time)
4885  return SS_TIMEOUT;
4886  }
4887  continue;
4888  }
4889 #endif
4890  if (status < 0) { /* select() syscall error */
4891  cm_msg(MERROR, "ss_socket_wait", "unexpected error, select() returned %d, errno: %d (%s)", status, errno, strerror(errno));
4892  return SS_SOCKET_ERROR;
4893  }
4894  if (status == 0) /* timeout */
4895  return SS_TIMEOUT;
4896  if (!FD_ISSET(sock, &readfds))
4897  return SS_TIMEOUT;
4898  return SS_SUCCESS;
4899  }
4900  /* NOT REACHED */
4901 }
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 1601 of file system.cxx.

1624 {
1625 #ifdef OS_WINNT
1626 
1627  if (spawnvp(mode, cmdname, argv) < 0)
1628  return SS_INVALID_NAME;
1629 
1630  return SS_SUCCESS;
1631 
1632 #endif /* OS_WINNT */
1633 
1634 #ifdef OS_MSDOS
1635 
1636  spawnvp((int) mode, cmdname, argv);
1637 
1638  return SS_SUCCESS;
1639 
1640 #endif /* OS_MSDOS */
1641 
1642 #ifdef OS_VMS
1643 
1644  {
1645  char cmdstring[500], *pc;
1646  INT i, flags, status;
1647  va_list argptr;
1648 
1649  $DESCRIPTOR(cmdstring_dsc, "dummy");
1650 
1651  if (mode & P_DETACH) {
1652  cmdstring_dsc.dsc$w_length = strlen(cmdstring);
1653  cmdstring_dsc.dsc$a_pointer = cmdstring;
1654 
1655  status = sys$creprc(0, &cmdstring_dsc, 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
1656  } else {
1657  flags = (mode & P_NOWAIT) ? 1 : 0;
1658 
1659  for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0]; pc--);
1660  if (*pc == ']')
1661  pc++;
1662 
1663  strcpy(cmdstring, pc);
1664 
1665  if (strchr(cmdstring, ';'))
1666  *strchr(cmdstring, ';') = 0;
1667 
1668  strcat(cmdstring, " ");
1669 
1670  for (i = 1; argv[i] != NULL; i++) {
1671  strcat(cmdstring, argv[i]);
1672  strcat(cmdstring, " ");
1673  }
1674 
1675  cmdstring_dsc.dsc$w_length = strlen(cmdstring);
1676  cmdstring_dsc.dsc$a_pointer = cmdstring;
1677 
1678  status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
1679  }
1680 
1681  return BM_SUCCESS;
1682  }
1683 
1684 #endif /* OS_VMS */
1685 #ifdef OS_UNIX
1686  pid_t child_pid;
1687 
1688 #ifdef OS_ULTRIX
1689  union wait *status;
1690 #else
1691  int status;
1692 #endif
1693 
1694 #ifdef NO_FORK
1695  assert(!"support for fork() disabled by NO_FORK");
1696 #else
1697  if ((child_pid = fork()) < 0)
1698  return (-1);
1699 #endif
1700 
1701  if (child_pid == 0) {
1702  /* now we are in the child process ... */
1703  int error = execvp(cmdname, (char*const*)argv);
1704  fprintf(stderr, "ss_spawnv: Cannot execute command \"%s\": execvp() returned %d, errno %d (%s), aborting!\n", cmdname, error, errno, strerror(errno));
1705  // NB: this is the forked() process, if it returns back to the caller, we will have
1706  // a duplicate process for whoever called us. Very bad! So must abort. K.O.
1707  abort();
1708  // NOT REACHED
1709  return SS_SUCCESS;
1710  } else {
1711  /* still in parent process */
1712  if (mode == P_WAIT) {
1713 #ifdef OS_ULTRIX
1714  waitpid(child_pid, status, WNOHANG);
1715 #else
1716  waitpid(child_pid, &status, WNOHANG);
1717 #endif
1718 
1719  } else {
1720  /* catch SIGCHLD signal to avoid <defunc> processes */
1721  signal(SIGCHLD, catch_sigchld);
1722  }
1723  }
1724 
1725  return SS_SUCCESS;
1726 
1727 #endif /* OS_UNIX */
1728 }
#define SS_INVALID_NAME
Definition: midas.h:672
Here is the caller graph for this function:

◆ ss_stack_get()

INT EXPRT ss_stack_get ( char ***  string)

Definition at line 7933 of file system.cxx.

7934 {
7935 #ifdef OS_LINUX
7936 #define MAX_STACK_DEPTH 16
7937 
7938  void *trace[MAX_STACK_DEPTH];
7939  int size;
7940 
7941  size = backtrace(trace, MAX_STACK_DEPTH);
7942  *string = backtrace_symbols(trace, size);
7943  return size;
7944 #else
7945  return 0;
7946 #endif
7947 }
Here is the caller graph for this function:

◆ ss_stack_history_dump()

void EXPRT ss_stack_history_dump ( char *  filename)

Definition at line 7983 of file system.cxx.

7984 {
7985  FILE *f;
7986  int i, j;
7987 
7988  f = fopen(filename, "wt");
7989  if (f != NULL) {
7991  for (i = 0; i < N_STACK_HISTORY; i++) {
7992  if (strlen(stack_history[j]) > 0)
7993  fprintf(f, "%s\n", stack_history[j]);
7994  j = (j + 1) % N_STACK_HISTORY;
7995  }
7996  fclose(f);
7997  printf("Stack dump written to %s\n", filename);
7998  } else
7999  printf("Cannot open %s: errno=%d\n", filename, errno);
8000 }
#define N_STACK_HISTORY
Definition: system.cxx:7929
char stack_history[N_STACK_HISTORY][80]
Definition: system.cxx:7930
int stack_history_pointer
Definition: system.cxx:7931
INT j
Definition: odbhist.cxx:40

◆ ss_stack_history_entry()

void EXPRT ss_stack_history_entry ( char *  tag)

Definition at line 7961 of file system.cxx.

7962 {
7963  char **string;
7964  int i, n;
7965 
7966  if (stack_history_pointer == -1) {
7968  memset(stack_history, 0, sizeof(stack_history));
7969  }
7972  n = ss_stack_get(&string);
7973  for (i = 2; i < n; i++) {
7976  }
7977  free(string);
7978 
7979  strlcpy(stack_history[stack_history_pointer], "=========================", 80);
7981 }
INT ss_stack_get(char ***string)
Definition: system.cxx:7933
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 7949 of file system.cxx.

7950 {
7951  char **string;
7952  int i, n;
7953 
7954  n = ss_stack_get(&string);
7955  for (i = 0; i < n; i++)
7956  printf("%s\n", string[i]);
7957  if (n > 0)
7958  free(string);
7959 }
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 4482 of file system.cxx.

4553 {
4554  INT status, return_status;
4555 
4556  midas_thread_t thread_id = ss_gettid();
4557 
4558  SUSPEND_STRUCT* psuspend = ss_suspend_get_struct(thread_id);
4559 
4560  //printf("ss_suspend: thread %s\n", ss_tid_to_string(thread_id).c_str());
4561 
4562  return_status = SS_TIMEOUT;
4563 
4564  do {
4565  fd_set readfds;
4566  FD_ZERO(&readfds);
4567 
4568  if (ss_match_thread(_ss_listen_thread, thread_id)) {
4569  /* check listen sockets */
4571  FD_SET(_ss_server_listen_socket, &readfds);
4572  //printf("ss_suspend: thread %s listen ss_server socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_listen_socket);
4573  }
4574 
4576  FD_SET(_ss_client_listen_socket, &readfds);
4577  //printf("ss_suspend: thread %s listen ss_client socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_client_listen_socket);
4578  }
4579  }
4580 
4581  /* check server channels */
4583  //printf("ss_suspend: thread %s server acceptions %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_num_acceptions);
4584  for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4585  /* RPC channel */
4586  int sock = (*_ss_server_acceptions)[i]->recv_sock;
4587 
4588  if (!sock)
4589  continue;
4590 
4592  //if (_suspend_struct[idx].server_acception[i].tid != ss_gettid())
4593  // continue;
4594 
4595  /* watch server socket if no data in cache */
4596  if (recv_tcp_check(sock) == 0)
4597  FD_SET(sock, &readfds);
4598  /* set timeout to zero if data in cache (-> just quick check IPC)
4599  and not called from inside bm_send_event (-> wait for IPC) */
4600  else if (msg == 0)
4601  millisec = 0;
4602 
4603  if (msg == 0 && msg != MSG_BM) {
4604  /* event channel */
4605  sock = (*_ss_server_acceptions)[i]->event_sock;
4606 
4607  if (!sock)
4608  continue;
4609 
4610  /* check for buffered event */
4612 
4613  if (status == BM_ASYNC_RETURN) {
4614  /* event buffer is full and rpc_server_receive_event() is holding on
4615  * to an event it cannot get rid of. Do not read more events from
4616  * the event socket, they have nowhere to go. K.O. */
4617  } else if (status == RPC_SUCCESS) {
4618  FD_SET(sock, &readfds);
4619  }
4620  }
4621  }
4622  }
4623 
4624  /* watch for messages from the mserver */
4625  if (ss_match_thread(_ss_client_thread, thread_id)) {
4626  if (_ss_client_connection) {
4627  FD_SET(_ss_client_connection->recv_sock, &readfds);
4628  }
4629  }
4630 
4631  /* watch for UDP messages in the IPC socket: buffer and odb notifications */
4632  if (ss_match_thread(_ss_odb_thread, thread_id)) {
4634  FD_SET(_ss_suspend_odb->ipc_recv_socket, &readfds);
4635  }
4636 
4637  if (psuspend->ipc_recv_socket)
4638  FD_SET(psuspend->ipc_recv_socket, &readfds);
4639 
4640  struct timeval timeout;
4641 
4642  timeout.tv_sec = millisec / 1000;
4643  timeout.tv_usec = (millisec % 1000) * 1000;
4644 
4645  do {
4646  //printf("select millisec %d, tv_sec %d, tv_usec %d\n", millisec, (int)timeout.tv_sec, (int)timeout.tv_usec);
4647 
4648  if (millisec < 0)
4649  status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL); /* blocking */
4650  else
4651  status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
4652 
4653  /* if an alarm signal was cought, restart select with reduced timeout */
4654  if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
4655  timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
4656 
4657  } while (status == -1); /* dont return if an alarm signal was cought */
4658 
4659  /* check listener sockets */
4660 
4661  if (_ss_server_listen_socket && FD_ISSET(_ss_server_listen_socket, &readfds)) {
4662  //printf("ss_suspend: thread %s rpc_server_accept socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_server_listen_socket);
4664  if (status == RPC_SHUTDOWN) {
4665  return status;
4666  }
4667  }
4668 
4669  if (_ss_client_listen_socket && FD_ISSET(_ss_client_listen_socket, &readfds)) {
4670  //printf("ss_suspend: thread %s rpc_client_accept socket %d\n", ss_tid_to_string(thread_id).c_str(), _ss_client_listen_socket);
4672  if (status == RPC_SHUTDOWN) {
4673  return status;
4674  }
4675  }
4676 
4677  /* check server channels */
4678  if (_ss_server_acceptions) {
4679  for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4680  /* rpc channel */
4681  int sock = (*_ss_server_acceptions)[i]->recv_sock;
4682 
4683  if (!sock)
4684  continue;
4685 
4686  //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);
4687 
4688  if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
4689  //printf("ss_suspend: msg %d\n", msg);
4690  if (msg == MSG_BM) {
4691  status = ss_socket_check(sock);
4692  } else {
4693  //printf("ss_suspend: rpc_server_receive_rpc() call!\n");
4695  //printf("ss_suspend: rpc_server_receive_rpc() status %d\n", status);
4696  }
4697  (*_ss_server_acceptions)[i]->last_activity = ss_millitime();
4698 
4699  if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN) {
4700  return status;
4701  }
4702 
4703  return_status = SS_SERVER_RECV;
4704  }
4705 
4706  /* event channel */
4707  sock = (*_ss_server_acceptions)[i]->event_sock;
4708 
4709  if (!sock)
4710  continue;
4711 
4712  if (FD_ISSET(sock, &readfds)) {
4713  if (msg != 0) {
4714  status = ss_socket_check(sock);
4715  } else {
4716  //printf("ss_suspend: rpc_server_receive_event() call!\n");
4718  //printf("ss_suspend: rpc_server_receive_event() status %d\n", status);
4719  }
4720  (*_ss_server_acceptions)[i]->last_activity = ss_millitime();
4721 
4722  if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN) {
4723  return status;
4724  }
4725 
4726  return_status = SS_SERVER_RECV;
4727  }
4728  }
4729  }
4730 
4731  /* check for messages from the mserver */
4732  if (_ss_client_connection) {
4733  int sock = _ss_client_connection->recv_sock;
4734 
4735  if (FD_ISSET(sock, &readfds)) {
4736  status = rpc_client_dispatch(sock);
4737 
4738  if (status == SS_ABORT) {
4739  cm_msg(MINFO, "ss_suspend", "RPC connection to mserver at \'%s\' was broken", _ss_client_connection->host_name.c_str());
4740 
4741  /* close client connection if link broken */
4745 
4749 
4751 
4752  /* exit program after broken connection to MIDAS server */
4753  return SS_ABORT;
4754  }
4755 
4756  return_status = SS_CLIENT_RECV;
4757  }
4758  }
4759 
4760  /* check ODB IPC socket */
4763  if (status) {
4764  return status;
4765  }
4766  }
4767 
4768  /* check per-thread IPC socket */
4769  if (psuspend && psuspend->ipc_recv_socket && FD_ISSET(psuspend->ipc_recv_socket, &readfds)) {
4770  status = ss_suspend_process_ipc(millisec, msg, psuspend->ipc_recv_socket);
4771  if (status) {
4772  return status;
4773  }
4774  }
4775 
4776 
4777  } while (millisec < 0);
4778 
4779  return return_status;
4780 }
#define SS_SERVER_RECV
Definition: midas.h:681
#define SS_CLIENT_RECV
Definition: midas.h:682
#define RPC_SHUTDOWN
Definition: midas.h:713
#define RPC_SUCCESS
Definition: midas.h:704
static midas_thread_t _ss_server_thread
Definition: system.cxx:3928
static int _ss_server_listen_socket
Definition: system.cxx:3922
static int ss_suspend_process_ipc(INT millisec, INT msg, int ipc_recv_socket)
Definition: system.cxx:4325
static RPC_SERVER_CONNECTION * _ss_client_connection
Definition: system.cxx:3926
static midas_thread_t _ss_odb_thread
Definition: system.cxx:3918
static int ss_socket_check(int sock)
Definition: system.cxx:4432
static bool ss_match_thread(midas_thread_t tid1, midas_thread_t tid2)
Definition: system.cxx:3932
static int _ss_client_listen_socket
Definition: system.cxx:3923
static midas_thread_t _ss_listen_thread
Definition: system.cxx:3921
midas_thread_t ss_gettid(void)
Definition: system.cxx:1490
SUSPEND_STRUCT * ss_suspend_get_struct(midas_thread_t thread_id)
Definition: system.cxx:4104
static midas_thread_t _ss_client_thread
Definition: system.cxx:3925
INT recv_tcp_check(int sock)
Definition: midas.cxx:14324
INT rpc_server_receive_rpc(int idx, RPC_SERVER_ACCEPTION *sa)
Definition: midas.cxx:15838
INT rpc_client_accept(int lsock)
Definition: midas.cxx:15565
INT rpc_server_accept(int lsock)
Definition: midas.cxx:15308
INT rpc_client_dispatch(int sock)
Definition: midas.cxx:11912
#define closesocket(s)
Definition: melog.cxx:29
INT midas_thread_t
Definition: midas.h:179
#define WATCHDOG_INTERVAL
Definition: midas.h:295
INT ipc_recv_socket
Definition: system.cxx:3911
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 4146 of file system.cxx.

4147 {
4148  if (psuspend->ipc_recv_socket) {
4149  closesocket(psuspend->ipc_recv_socket);
4150  psuspend->ipc_recv_socket = 0;
4151  }
4152 
4153  if (psuspend->ipc_send_socket) {
4154  closesocket(psuspend->ipc_send_socket);
4155  psuspend->ipc_send_socket = 0;
4156  }
4157 
4158  //printf("ss_suspend_close: free thread %s, udp port %d\n", ss_tid_to_string(psuspend->thread_id).c_str(), psuspend->ipc_recv_port);
4159 
4160  psuspend->thread_id = 0;
4161  psuspend->ipc_recv_port = 0;
4162 }
midas_thread_t thread_id
Definition: system.cxx:3909
Here is the caller graph for this function:

◆ ss_suspend_exit()

INT ss_suspend_exit ( )

Definition at line 4165 of file system.cxx.

4183 {
4184  midas_thread_t thread_id = ss_gettid();
4185 
4186  for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4187  if (!_ss_suspend_vector[i])
4188  continue;
4189  if (_ss_suspend_vector[i]->thread_id == thread_id) {
4190  SUSPEND_STRUCT* psuspend = _ss_suspend_vector[i];
4191  _ss_suspend_vector[i] = NULL;
4192  ss_suspend_close(psuspend);
4193  delete psuspend;
4194  }
4195  }
4196 
4197  if (_ss_suspend_odb) {
4198  bool last = true;
4199  for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4200  if (_ss_suspend_vector[i]) {
4201  last = false;
4202  break;
4203  }
4204  }
4205  if (last) {
4206  SUSPEND_STRUCT* psuspend = _ss_suspend_odb;
4207  _ss_suspend_odb = NULL;
4208  ss_suspend_close(psuspend);
4209  delete psuspend;
4210  }
4211  }
4212 
4213  return SS_SUCCESS;
4214 }
static void ss_suspend_close(SUSPEND_STRUCT *psuspend)
Definition: system.cxx:4146
static std::vector< SUSPEND_STRUCT * > _ss_suspend_vector
Definition: system.cxx:3916
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 4292 of file system.cxx.

4313 {
4314  SUSPEND_STRUCT* psuspend = ss_suspend_get_struct(thread_id);
4315 
4316  if (!psuspend->ipc_recv_port) {
4317  ss_suspend_init_struct(psuspend);
4318  }
4319 
4320  *port = psuspend->ipc_recv_port;
4321 
4322  return SS_SUCCESS;
4323 }
static INT ss_suspend_init_struct(SUSPEND_STRUCT *psuspend)
Definition: system.cxx:3951
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 4266 of file system.cxx.

4283 {
4284  assert(_ss_suspend_odb);
4285 
4286  *port = _ss_suspend_odb->ipc_recv_port;
4287 
4288  return SS_SUCCESS;
4289 }
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 4104 of file system.cxx.

4118 {
4119  // find thread_id
4120  for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4121  if (!_ss_suspend_vector[i])
4122  continue;
4123  if (_ss_suspend_vector[i]->thread_id == thread_id) {
4124  return _ss_suspend_vector[i];
4125  }
4126  }
4127 
4128  // create new one if not found
4129  SUSPEND_STRUCT *psuspend = new SUSPEND_STRUCT;
4130  psuspend->thread_id = thread_id;
4131 
4132  // place into empty slot
4133  for (unsigned i=0; i<_ss_suspend_vector.size(); i++) {
4134  if (!_ss_suspend_vector[i]) {
4135  _ss_suspend_vector[i] = psuspend;
4136  return psuspend;
4137  }
4138  }
4139 
4140  // add to vector if no empty slots
4141  _ss_suspend_vector.push_back(psuspend);
4142 
4143  return psuspend;
4144 }
struct suspend_struct SUSPEND_STRUCT
Here is the caller graph for this function:

◆ ss_suspend_init_odb_port()

INT ss_suspend_init_odb_port ( )

Definition at line 4244 of file system.cxx.

4255 {
4256  if (!_ss_suspend_odb) {
4260  }
4261 
4262  return SS_SUCCESS;
4263 }
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 3951 of file system.cxx.

3967 {
3968  INT status, sock;
3969  unsigned int size;
3970  struct sockaddr_in bind_addr;
3971  //int udp_bind_hostname = 0; // bind to localhost or bind to hostname or bind to INADDR_ANY?
3972 
3973  //printf("ss_suspend_init_struct: thread %s\n", ss_tid_to_string(psuspend->thread_id).c_str());
3974 
3975  assert(psuspend->thread_id != 0);
3976 
3977 #ifdef OS_WINNT
3978  {
3979  WSADATA WSAData;
3980 
3981  /* Start windows sockets */
3982  if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
3983  return SS_SOCKET_ERROR;
3984  }
3985 #endif
3986 
3987  /*--------------- create UDP receive socket -------------------*/
3988  sock = socket(AF_INET, SOCK_DGRAM, 0);
3989  if (sock == -1)
3990  return SS_SOCKET_ERROR;
3991 
3992  /* let OS choose port for socket */
3993  memset(&bind_addr, 0, sizeof(bind_addr));
3994  bind_addr.sin_family = AF_INET;
3995  bind_addr.sin_addr.s_addr = 0;
3996  bind_addr.sin_port = 0;
3997 
3998  /* decide if UDP sockets are bound to localhost (they are only use for local communications)
3999  or to hostname (for compatibility with old clients - their hotlinks will not work) */
4000  {
4001  std::string path = cm_get_path();
4002  path += ".UDP_BIND_HOSTNAME";
4003 
4004  //cm_msg(MERROR, "ss_suspend_init_ipc", "check file [%s]", path.c_str());
4005 
4006  FILE *fp = fopen(path.c_str(), "r");
4007  if (fp) {
4008  cm_msg(MERROR, "ss_suspend_init_ipc", "Support for UDP_BIND_HOSTNAME was removed. Please delete file \"%s\"", path.c_str());
4009  //udp_bind_hostname = 1;
4010  fclose(fp);
4011  fp = NULL;
4012  }
4013  }
4014 
4015  //#ifdef OS_VXWORKS
4016  //{
4017  // char local_host_name[HOST_NAME_LENGTH];
4018  // INT host_addr;
4019  //
4020  // gethostname(local_host_name, sizeof(local_host_name));
4021  //
4022  //host_addr = hostGetByName(local_host_name);
4023  // memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
4024  //}
4025  //#else
4026  //if (udp_bind_hostname) {
4027  // char local_host_name[HOST_NAME_LENGTH];
4028  // struct hostent *phe = gethostbyname(local_host_name);
4029  // if (phe == NULL) {
4030  // cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get IP address for host name \'%s\'", local_host_name);
4031  // return SS_SOCKET_ERROR;
4032  // }
4033  // memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
4034  //} else {
4035  bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4036  //}
4037  //#endif
4038 
4039  status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
4040  if (status < 0)
4041  return SS_SOCKET_ERROR;
4042 
4043  /* find out which port OS has chosen */
4044  size = sizeof(bind_addr);
4045 #ifdef OS_WINNT
4046  getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &size);
4047 #else
4048  getsockname(sock, (struct sockaddr *) &bind_addr, &size);
4049 #endif
4050 
4051  // ipc receive socket must be set to non-blocking mode, see explanation
4052  // in ss_suspend_process_ipc(). K.O. July 2022.
4053 
4054  int flags = fcntl(sock, F_GETFL, 0);
4055  status = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
4056 
4057  if (status < 0) {
4058  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));
4059  return SS_SOCKET_ERROR;
4060  }
4061 
4062  psuspend->ipc_recv_socket = sock;
4063  psuspend->ipc_recv_port = ntohs(bind_addr.sin_port);
4064 
4065  /*--------------- create UDP send socket ----------------------*/
4066  sock = socket(AF_INET, SOCK_DGRAM, 0);
4067 
4068  if (sock == -1)
4069  return SS_SOCKET_ERROR;
4070 
4071  /* fill out bind struct pointing to local host */
4072  memset(&bind_addr, 0, sizeof(bind_addr));
4073  bind_addr.sin_family = AF_INET;
4074  bind_addr.sin_addr.s_addr = 0;
4075 
4076  //#ifdef OS_VXWORKS
4077  //{
4078  // INT host_addr;
4079  //
4080  // host_addr = hostGetByName(local_host_name);
4081  //memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
4082  //}
4083  //#else
4084  //if (udp_bind_hostname) {
4085  // // nothing
4086  //} else {
4087  bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
4088 
4089  status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
4090  if (status < 0)
4091  return SS_SOCKET_ERROR;
4092  //}
4093  //#endif
4094 
4095  memcpy(&(psuspend->bind_addr), &bind_addr, sizeof(bind_addr));
4096  psuspend->ipc_send_socket = sock;
4097 
4098  //printf("ss_suspend_init_struct: thread %s, udp port %d\n", ss_tid_to_string(psuspend->thread_id).c_str(), psuspend->ipc_recv_port);
4099 
4100  return SS_SUCCESS;
4101 }
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 4325 of file system.cxx.

4326 {
4327  char buffer[80];
4328  buffer[0] = 0;
4329  /* receive IPC message */
4330  struct sockaddr from_addr;
4331  socklen_t from_addr_size = sizeof(struct sockaddr);
4332 
4333  // note: ipc_recv_socket must be set in non-blocking mode:
4334  // it looks as if we come here from ss_suspend() only if select() said
4335  // that our socket has data. but this is not true. after that select(),
4336  // ss_suspend() reads other sockets, calls other handlers, which may call
4337  // ss_suspend() recursively (i.e. via bm_receive_event() RPC call to "wait_for_more_data"
4338  // call to ss_suspend()). the recursively called ss_suspend() will
4339  // also so select() and call this function to read from this socket. then it eventually
4340  // returns, all the handlers return back to the original ss_suspend(), which
4341  // happily remembers that the original select() told us we have data. but this data
4342  // was already read by the recursively call ss_suspend(), so the socket is empty
4343  // and our recvfrom() will sleep forever. inside the mserver, this makes mserver
4344  // stop (very bad!). with the socket set to non-blocking mode
4345  // recvfrom() will never sleep and this problem is avoided. K.O. July 2022
4346  // see bug report https://bitbucket.org/tmidas/midas/issues/346/rpc-timeout-in-bm_receive_event
4347 
4348  // note2: in midas, there is never a situation where we wait for data
4349  // from the ipc sockets. these sockets are used for "event buffer has data" and "odb has new data"
4350  // notifications. we check them, but we do not wait for them. this setting
4351  // the socket to non-blocking mode is safe. K.O. July 2022.
4352 
4353  ssize_t size = recvfrom(ipc_recv_socket, buffer, sizeof(buffer), 0, &from_addr, &from_addr_size);
4354 
4355  if (size <= 0) {
4356  //fprintf(stderr, "ss_suspend_process_ipc: recvfrom() returned %zd, errno %d (%s)\n", size, errno, strerror(errno));
4357  // return 0 means we did not do anyting. K.O.
4358  return 0;
4359  }
4360 
4361  // NB: ss_suspend(MSG_BM) (and ss_suspend(MSG_ODB)) are needed to break
4362  // recursive calls to the event handler (and db_watch() handler) if these
4363  // handlers call ss_suspend() again. The rootana interactive ROOT graphics
4364  // mode does this. To prevent this recursion, event handlers must always
4365  // call ss_suspend() with MSG_BM (and MSG_ODB). K.O.
4366 
4367  /* return if received requested message */
4368  if (msg == MSG_BM && buffer[0] == 'B')
4369  return SS_SUCCESS;
4370  if (msg == MSG_ODB && buffer[0] == 'O')
4371  return SS_SUCCESS;
4372 
4373  // NB: do not need to check thread id, the mserver is single-threaded. K.O.
4374  int mserver_client_socket = 0;
4375  if (_ss_server_acceptions) {
4376  for (unsigned i = 0; i < _ss_server_acceptions->size(); i++) {
4377  if ((*_ss_server_acceptions)[i]->is_mserver) {
4378  mserver_client_socket = (*_ss_server_acceptions)[i]->send_sock;
4379  }
4380  }
4381  }
4382 
4383  time_t tstart = time(NULL);
4384  int return_status = 0;
4385 
4386  /* receive further messages to empty UDP queue */
4387  while (1) {
4388  char buffer_tmp[80];
4389  buffer_tmp[0] = 0;
4390  from_addr_size = sizeof(struct sockaddr);
4391 
4392  // note: ipc_recv_socket must be in non-blocking mode, see comments above. K.O.
4393 
4394  ssize_t size_tmp = recvfrom(ipc_recv_socket, buffer_tmp, sizeof(buffer_tmp), 0, &from_addr, &from_addr_size);
4395 
4396  if (size_tmp <= 0) {
4397  //fprintf(stderr, "ss_suspend_process_ipc: second recvfrom() returned %zd, errno %d (%s)\n", size, errno, strerror(errno));
4398  break;
4399  }
4400 
4401  /* stop the loop if received requested message */
4402  if (msg == MSG_BM && buffer_tmp[0] == 'B') {
4403  return_status = SS_SUCCESS;
4404  break;
4405  }
4406  if (msg == MSG_ODB && buffer_tmp[0] == 'O') {
4407  return_status = SS_SUCCESS;
4408  break;
4409  }
4410 
4411  /* don't forward same MSG_BM as above */
4412  if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0) {
4413  cm_dispatch_ipc(buffer_tmp, size_tmp, mserver_client_socket);
4414  }
4415 
4416  if (millisec > 0) {
4417  time_t tnow = time(NULL);
4418  // make sure we do not loop for longer than our timeout
4419  if (tnow - tstart > 1 + millisec/1000) {
4420  //printf("ss_suspend - break out dt %d, %d loops\n", (int)(tnow-tstart), count);
4421  break;
4422  }
4423  }
4424  }
4425 
4426  /* call dispatcher */
4427  cm_dispatch_ipc(buffer, size, mserver_client_socket);
4428 
4429  return return_status;
4430 }
INT cm_dispatch_ipc(const char *message, int message_size, int client_socket)
Definition: midas.cxx:5381
#define MSG_ODB
Definition: msystem.h:296
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_suspend_set_client_connection()

INT ss_suspend_set_client_connection ( RPC_SERVER_CONNECTION connection)

Definition at line 4230 of file system.cxx.

4231 {
4232  // client side of the mserver connection
4233  _ss_client_connection = connection;
4234  return SS_SUCCESS;
4235 }
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 4223 of file system.cxx.

4224 {
4225  // midas program rpc listener socket (run transitions, etc)
4226  _ss_client_listen_socket = listen_socket;
4227  return SS_SUCCESS;
4228 }
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 3941 of file system.cxx.

3942 {
3943  _ss_listen_thread = thread_id; // this thread handles listen()/accept() activity
3944  _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())
3945  _ss_server_thread = thread_id; // this thread reads and executes RPC requests
3946  _ss_odb_thread = thread_id; // this thread reads and dispatches ODB notifications (db_watch & co)
3947  return SS_SUCCESS;
3948 }
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 4237 of file system.cxx.

4238 {
4239  // server side of the RPC connections (run transitions, etc)
4240  _ss_server_acceptions = acceptions;
4241  return SS_SUCCESS;
4242 }
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 4216 of file system.cxx.

4217 {
4218  // mserver listener socket
4219  _ss_server_listen_socket = listen_socket;
4220  return SS_SUCCESS;
4221 }
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:2087
INT blockn
Definition: lazylogger.cxx:217
LAZY_STATISTICS lazyst
Definition: lazylogger.cxx:193
LAZY_SETTING lazy
Definition: lazylogger.cxx:180
char commandAfter[64]
Definition: lazylogger.cxx:175
char path[MAX_FILE_PATH]
Definition: lazylogger.cxx:171
char backlabel[MAX_FILE_PATH]
Definition: lazylogger.cxx:173
char backfile[MAX_FILE_PATH]
Definition: lazylogger.cxx:183
Parameters
commandCommand to execute.
Returns
SS_SUCCESS or ss_exec() return code

Definition at line 2087 of file system.cxx.

2088 {
2089 #ifdef OS_UNIX
2090  INT childpid;
2091 
2092  return ss_exec(command, &childpid);
2093 
2094 #else
2095 
2096  system(command);
2097  return SS_SUCCESS;
2098 
2099 #endif
2100 }
INT ss_exec(const char *command, INT *pid)
Definition: system.cxx:2103
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 5841 of file system.cxx.

5859 {
5860  INT status;
5861 
5862 #ifdef OS_UNIX
5863 
5864  status = close(channel);
5865 
5866  if (status < 0) {
5867  cm_msg(MERROR, "ss_tape_close", "close() returned %d, errno %d (%s)", status, errno, strerror(errno));
5868  return errno;
5869  }
5870 #endif /* OS_UNIX */
5871 
5872 #ifdef OS_WINNT
5873 
5874  if (!CloseHandle((HANDLE) channel)) {
5875  status = GetLastError();
5876  cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
5877  return status;
5878  }
5879 #endif /* OS_WINNT */
5880 
5881  return SS_SUCCESS;
5882 }
INT channel
Definition: lazylogger.cxx:203
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 6171 of file system.cxx.

6190 {
6191 #ifdef MTIOCTOP
6192  struct mtop arg;
6193  INT status;
6194 
6195  if (count > 0)
6196  arg.mt_op = MTFSF;
6197  else
6198  arg.mt_op = MTBSF;
6199  arg.mt_count = abs(count);
6200 
6201  //cm_enable_watchdog(FALSE);
6202 
6203  status = ioctl(channel, MTIOCTOP, &arg);
6204 
6205  //cm_enable_watchdog(TRUE);
6206 
6207  if (status < 0) {
6208  cm_msg(MERROR, "ss_tape_fskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6209  return errno;
6210  }
6211 #endif /* OS_UNIX */
6212 
6213 #ifdef OS_WINNT
6214  INT status;
6215 
6216  status = SetTapePosition((HANDLE) channel, TAPE_SPACE_FILEMARKS, 0, (DWORD) count, 0, FALSE);
6217 
6218  if (status == ERROR_END_OF_MEDIA)
6219  return SS_END_OF_TAPE;
6220 
6221  if (status != NO_ERROR) {
6222  cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
6223  return status;
6224  }
6225 #endif /* OS_WINNT */
6226 
6227  return SS_SUCCESS;
6228 }
#define SS_END_OF_TAPE
Definition: midas.h:690
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 6507 of file system.cxx.

6516 {
6517 #if defined(OS_DARWIN)
6518 
6519  return 0;
6520 
6521 #elif defined(OS_UNIX)
6522 
6523  INT status;
6524  struct mtpos arg;
6525 
6526  //cm_enable_watchdog(FALSE);
6527  status = ioctl(channel, MTIOCPOS, &arg);
6528  //cm_enable_watchdog(TRUE);
6529  if (status < 0) {
6530  if (errno == EIO)
6531  return 0;
6532  else {
6533  cm_msg(MERROR, "ss_tape_get_blockn", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6534  return -errno;
6535  }
6536  }
6537  return (arg.mt_blkno);
6538 
6539 #elif defined(OS_WINNT)
6540 
6541  INT status;
6542  TAPE_GET_MEDIA_PARAMETERS media;
6543  unsigned long size;
6544  /* I'm not sure the partition count corresponds to the block count */
6545  status = GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &media);
6546  return (media.PartitionCount);
6547 
6548 #endif
6549 }
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 6395 of file system.cxx.

6413 {
6414 #ifdef MTIOCTOP
6415  struct mtop arg;
6416  INT status;
6417 
6418 #ifdef MTLOAD
6419  arg.mt_op = MTLOAD;
6420 #else
6421  arg.mt_op = MTNOP;
6422 #endif
6423  arg.mt_count = 0;
6424 
6425  //cm_enable_watchdog(FALSE);
6426 
6427  status = ioctl(channel, MTIOCTOP, &arg);
6428 
6429  //cm_enable_watchdog(TRUE);
6430 
6431  if (status < 0) {
6432  cm_msg(MERROR, "ss_tape_mount", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6433  return errno;
6434  }
6435 #endif /* OS_UNIX */
6436 
6437 #ifdef OS_WINNT
6438  INT status;
6439 
6440  status = PrepareTape((HANDLE) channel, TAPE_LOAD, FALSE);
6441  if (status != NO_ERROR) {
6442  cm_msg(MERROR, "ss_tape_mount", "error %d", status);
6443  return status;
6444  }
6445 #endif /* OS_WINNT */
6446 
6447  return CM_SUCCESS;
6448 }
#define CM_SUCCESS
Definition: midas.h:588
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 5750 of file system.cxx.

5772 {
5773 #ifdef OS_UNIX
5774  //cm_enable_watchdog(FALSE);
5775 
5776  *channel = open(path, oflag, 0644);
5777 
5778  //cm_enable_watchdog(TRUE);
5779 
5780  if (*channel < 0)
5781  cm_msg(MERROR, "ss_tape_open", "open() returned %d, errno %d (%s)", *channel, errno, strerror(errno));
5782 
5783  if (*channel < 0) {
5784  if (errno == EIO)
5785  return SS_NO_TAPE;
5786  if (errno == EBUSY)
5787  return SS_DEV_BUSY;
5788  return errno;
5789  }
5790 #ifdef MTSETBLK
5791  {
5792  /* set variable block size */
5793  struct mtop arg;
5794  arg.mt_op = MTSETBLK;
5795  arg.mt_count = 0;
5796 
5797  ioctl(*channel, MTIOCTOP, &arg);
5798  }
5799 #endif /* MTSETBLK */
5800 
5801 #endif /* OS_UNIX */
5802 
5803 #ifdef OS_WINNT
5804  INT status;
5805  TAPE_GET_MEDIA_PARAMETERS m;
5806 
5807  *channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
5808 
5809  if (*channel == (INT) INVALID_HANDLE_VALUE) {
5810  status = GetLastError();
5811  if (status == ERROR_SHARING_VIOLATION) {
5812  cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
5813  return SS_DEV_BUSY;
5814  }
5815  if (status == ERROR_FILE_NOT_FOUND) {
5816  cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
5817  return SS_NO_TAPE;
5818  }
5819 
5820  cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
5821  return status;
5822  }
5823 
5824  status = GetTapeStatus((HANDLE) (*channel));
5825  if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
5826  cm_msg(MERROR, "ss_tape_open", "no media in drive");
5827  return SS_NO_TAPE;
5828  }
5829 
5830  /* set block size */
5831  memset(&m, 0, sizeof(m));
5832  m.BlockSize = TAPE_BUFFER_SIZE;
5833  SetTapeParameters((HANDLE) (*channel), SET_TAPE_MEDIA_INFORMATION, &m);
5834 
5835 #endif
5836 
5837  return SS_SUCCESS;
5838 }
#define SS_NO_TAPE
Definition: midas.h:685
#define SS_DEV_BUSY
Definition: midas.h:686
#define TAPE_BUFFER_SIZE
Definition: midas.h:271
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 6031 of file system.cxx.

6051 {
6052 #ifdef OS_UNIX
6053  INT n, status;
6054 
6055  do {
6056  n = read(channel, pdata, *count);
6057  } while (n == -1 && errno == EINTR);
6058 
6059  if (n == -1) {
6060  if (errno == ENOSPC || errno == EIO)
6062  else {
6063  if (n == 0 && errno == 0)
6065  else {
6066  cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", n, errno);
6067  status = errno;
6068  }
6069  }
6070  } else
6071  status = SS_SUCCESS;
6072  *count = n;
6073 
6074  return status;
6075 
6076 #elif defined(OS_WINNT) /* OS_UNIX */
6077 
6078  INT status;
6079  DWORD read;
6080 
6081  if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
6082  status = GetLastError();
6083  if (status == ERROR_NO_DATA_DETECTED)
6085  else if (status == ERROR_FILEMARK_DETECTED)
6087  else if (status == ERROR_MORE_DATA)
6088  status = SS_SUCCESS;
6089  else
6090  cm_msg(MERROR, "ss_tape_read", "unexpected tape error: n=%d, errno=%d\n", read, status);
6091  } else
6092  status = SS_SUCCESS;
6093 
6094  *count = read;
6095  return status;
6096 
6097 #else /* OS_WINNT */
6098 
6099  return SS_SUCCESS;
6100 
6101 #endif
6102 }
#define SS_END_OF_FILE
Definition: midas.h:691
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 6287 of file system.cxx.

6305 {
6306 #ifdef MTIOCTOP
6307  struct mtop arg;
6308  INT status;
6309 
6310  arg.mt_op = MTREW;
6311  arg.mt_count = 0;
6312 
6313  //cm_enable_watchdog(FALSE);
6314 
6315  status = ioctl(channel, MTIOCTOP, &arg);
6316 
6317  //cm_enable_watchdog(TRUE);
6318 
6319  if (status < 0) {
6320  cm_msg(MERROR, "ss_tape_rewind", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6321  return errno;
6322  }
6323 #endif /* OS_UNIX */
6324 
6325 #ifdef OS_WINNT
6326  INT status;
6327 
6328  status = SetTapePosition((HANDLE) channel, TAPE_REWIND, 0, 0, 0, FALSE);
6329  if (status != NO_ERROR) {
6330  cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
6331  return status;
6332  }
6333 #endif /* OS_WINNT */
6334 
6335  return CM_SUCCESS;
6336 }
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 6231 of file system.cxx.

6250 {
6251 #ifdef MTIOCTOP
6252  struct mtop arg;
6253  INT status;
6254 
6255  if (count > 0)
6256  arg.mt_op = MTFSR;
6257  else
6258  arg.mt_op = MTBSR;
6259  arg.mt_count = abs(count);
6260 
6261  //cm_enable_watchdog(FALSE);
6262 
6263  status = ioctl(channel, MTIOCTOP, &arg);
6264 
6265  //cm_enable_watchdog(TRUE);
6266 
6267  if (status < 0) {
6268  cm_msg(MERROR, "ss_tape_rskip", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6269  return errno;
6270  }
6271 #endif /* OS_UNIX */
6272 
6273 #ifdef OS_WINNT
6274  INT status;
6275 
6276  status = SetTapePosition((HANDLE) channel, TAPE_SPACE_RELATIVE_BLOCKS, 0, (DWORD) count, 0, FALSE);
6277  if (status != NO_ERROR) {
6278  cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
6279  return status;
6280  }
6281 #endif /* OS_WINNT */
6282 
6283  return CM_SUCCESS;
6284 }
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 6339 of file system.cxx.

6357 {
6358 #ifdef MTIOCTOP
6359  struct mtop arg;
6360  INT status;
6361 
6362 #ifdef MTEOM
6363  arg.mt_op = MTEOM;
6364 #else
6365  arg.mt_op = MTSEOD;
6366 #endif
6367  arg.mt_count = 0;
6368 
6369  //cm_enable_watchdog(FALSE);
6370 
6371  status = ioctl(channel, MTIOCTOP, &arg);
6372 
6373  //cm_enable_watchdog(TRUE);
6374 
6375  if (status < 0) {
6376  cm_msg(MERROR, "ss_tape_rewind", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6377  return errno;
6378  }
6379 #endif /* OS_UNIX */
6380 
6381 #ifdef OS_WINNT
6382  INT status;
6383 
6384  status = SetTapePosition((HANDLE) channel, TAPE_SPACE_END_OF_DATA, 0, 0, 0, FALSE);
6385  if (status != NO_ERROR) {
6386  cm_msg(MERROR, "ss_tape_spool", "error %d", status);
6387  return status;
6388  }
6389 #endif /* OS_WINNT */
6390 
6391  return CM_SUCCESS;
6392 }
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 5885 of file system.cxx.

5902 {
5903 #ifdef OS_UNIX
5904  int status;
5905  char str[256];
5906  /* let 'mt' do the job */
5907  sprintf(str, "mt -f %s status", path);
5908  status = system(str);
5909  if (status == -1)
5910  return SS_TAPE_ERROR;
5911  return SS_SUCCESS;
5912 #endif /* OS_UNIX */
5913 
5914 #ifdef OS_WINNT
5915  INT status, channel;
5916  DWORD size;
5917  TAPE_GET_MEDIA_PARAMETERS m;
5918  TAPE_GET_DRIVE_PARAMETERS d;
5919  double x;
5920 
5921  channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
5922 
5923  if (channel == (INT) INVALID_HANDLE_VALUE) {
5924  status = GetLastError();
5925  if (status == ERROR_SHARING_VIOLATION) {
5926  cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
5927  return SS_SUCCESS;
5928  }
5929  if (status == ERROR_FILE_NOT_FOUND) {
5930  cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
5931  return SS_SUCCESS;
5932  }
5933 
5934  cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
5935  return status;
5936  }
5937 
5938  /* poll media changed messages */
5939  GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
5940  GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
5941 
5942  status = GetTapeStatus((HANDLE) channel);
5943  if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
5944  cm_msg(MINFO, "ss_tape_status", "no media in drive");
5945  CloseHandle((HANDLE) channel);
5946  return SS_SUCCESS;
5947  }
5948 
5949  GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
5950  GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &m);
5951 
5952  printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
5953  printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
5954  printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
5955 
5956  if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
5957  x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
5958  / 1000.0 / 1000.0;
5959  printf("Tape capacity remaining is %d MB\n", (int) x);
5960  } else
5961  printf("Tape capacity is not reported by tape\n");
5962 
5963  CloseHandle((HANDLE) channel);
5964 
5965 #endif
5966 
5967  return SS_SUCCESS;
5968 }
#define SS_TAPE_ERROR
Definition: midas.h:688
double d
Definition: system.cxx:1317
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 6451 of file system.cxx.

6469 {
6470 #ifdef MTIOCTOP
6471  struct mtop arg;
6472  INT status;
6473 
6474 #ifdef MTOFFL
6475  arg.mt_op = MTOFFL;
6476 #else
6477  arg.mt_op = MTUNLOAD;
6478 #endif
6479  arg.mt_count = 0;
6480 
6481  //cm_enable_watchdog(FALSE);
6482 
6483  status = ioctl(channel, MTIOCTOP, &arg);
6484 
6485  //cm_enable_watchdog(TRUE);
6486 
6487  if (status < 0) {
6488  cm_msg(MERROR, "ss_tape_unmount", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6489  return errno;
6490  }
6491 #endif /* OS_UNIX */
6492 
6493 #ifdef OS_WINNT
6494  INT status;
6495 
6496  status = PrepareTape((HANDLE) channel, TAPE_UNLOAD, FALSE);
6497  if (status != NO_ERROR) {
6498  cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
6499  return status;
6500  }
6501 #endif /* OS_WINNT */
6502 
6503  return CM_SUCCESS;
6504 }
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 5971 of file system.cxx.

5992 {
5993 #ifdef OS_UNIX
5994  INT status;
5995 
5996  do {
5997  status = write(channel, pdata, count);
5998 /*
5999  if (status != count)
6000  printf("count: %d - %d\n", count, status);
6001 */
6002  } while (status == -1 && errno == EINTR);
6003 
6004  if (status != count) {
6005  cm_msg(MERROR, "ss_tape_write", "write() returned %d, errno %d (%s)", status, errno, strerror(errno));
6006 
6007  if (errno == EIO)
6008  return SS_IO_ERROR;
6009  else
6010  return SS_TAPE_ERROR;
6011  }
6012 #endif /* OS_UNIX */
6013 
6014 #ifdef OS_WINNT
6015  INT status;
6016  DWORD written;
6017 
6018  WriteFile((HANDLE) channel, pdata, count, &written, NULL);
6019  if (written != (DWORD) count) {
6020  status = GetLastError();
6021  cm_msg(MERROR, "ss_tape_write", "error %d", status);
6022 
6023  return SS_IO_ERROR;
6024  }
6025 #endif /* OS_WINNT */
6026 
6027  return SS_SUCCESS;
6028 }
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 6105 of file system.cxx.

6123 {
6124 #ifdef MTIOCTOP
6125  struct mtop arg;
6126  INT status;
6127 
6128  arg.mt_op = MTWEOF;
6129  arg.mt_count = 1;
6130 
6131  //cm_enable_watchdog(FALSE);
6132 
6133  status = ioctl(channel, MTIOCTOP, &arg);
6134 
6135  //cm_enable_watchdog(TRUE);
6136 
6137  if (status < 0) {
6138  cm_msg(MERROR, "ss_tape_write_eof", "ioctl() failed, errno %d (%s)", errno, strerror(errno));
6139  return errno;
6140  }
6141 #endif /* OS_UNIX */
6142 
6143 #ifdef OS_WINNT
6144 
6145  TAPE_GET_DRIVE_PARAMETERS d;
6146  DWORD size;
6147  INT status;
6148 
6149  size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
6150  GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
6151 
6152  if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
6153  status = WriteTapemark((HANDLE) channel, TAPE_FILEMARKS, 1, FALSE);
6154  else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
6155  status = WriteTapemark((HANDLE) channel, TAPE_LONG_FILEMARKS, 1, FALSE);
6156  else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
6157  status = WriteTapemark((HANDLE) channel, TAPE_SHORT_FILEMARKS, 1, FALSE);
6158  else
6159  cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
6160 
6161  if (status != NO_ERROR) {
6162  cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
6163  return status;
6164  }
6165 #endif /* OS_WINNT */
6166 
6167  return SS_SUCCESS;
6168 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ss_thread_create()

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

Creates and returns a new thread of execution.

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

Example for VxWorks

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

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

2278 {
2279 #if defined(OS_WINNT)
2280 
2281  HANDLE status;
2282  DWORD thread_id;
2283 
2284  if (thread_func == NULL) {
2285  return 0;
2286  }
2287 
2288  status = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_func, (LPVOID) param, 0, &thread_id);
2289 
2290  return status == NULL ? 0 : (midas_thread_t) thread_id;
2291 
2292 #elif defined(OS_MSDOS)
2293 
2294  return 0;
2295 
2296 #elif defined(OS_VMS)
2297 
2298  return 0;
2299 
2300 #elif defined(OS_VXWORKS)
2301 
2302 /* taskSpawn which could be considered as a thread under VxWorks
2303  requires several argument beside the thread args
2304  taskSpawn (taskname, priority, option, stacksize, entry_point
2305  , arg1, arg2, ... , arg9, arg10)
2306  all the arg will have to be retrieved from the param list.
2307  through a structure to be simpler */
2308 
2309  INT status;
2310  VX_TASK_SPAWN *ts;
2311 
2312  ts = (VX_TASK_SPAWN *) param;
2313  status =
2314  taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
2315  (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
2316  ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9, ts->arg10);
2317 
2318  return status == ERROR ? 0 : status;
2319 
2320 #elif defined(OS_UNIX)
2321 
2322  INT status;
2323  pthread_t thread_id;
2324 
2325  status = pthread_create(&thread_id, NULL, (void* (*)(void*))thread_func, param);
2326 
2327  return status != 0 ? 0 : thread_id;
2328 
2329 #endif
2330 }
Here is the caller graph for this function:

◆ ss_thread_get_name()

std::string ss_thread_get_name ( )

Definition at line 2411 of file system.cxx.

2412 {
2413 #if defined(OS_UNIX)
2414  char str[256];
2415  pthread_t thread = pthread_self();
2416  pthread_getname_np(thread, str, sizeof(str));
2417  return std::string(str);
2418 #else
2419  return "";
2420 #endif
2421 }
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 2350 of file system.cxx.

2351 {
2352 #if defined(OS_WINNT)
2353 
2354  DWORD status;
2355  HANDLE th;
2356 
2357  th = OpenThread(THREAD_TERMINATE, FALSE, (DWORD)thread_id);
2358  if (th == 0)
2359  status = GetLastError();
2360 
2361  status = TerminateThread(th, 0);
2362 
2363  if (status == 0)
2364  status = GetLastError();
2365 
2366  return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
2367 
2368 #elif defined(OS_MSDOS)
2369 
2370  return 0;
2371 
2372 #elif defined(OS_VMS)
2373 
2374  return 0;
2375 
2376 #elif defined(OS_VXWORKS)
2377 
2378  INT status;
2379  status = taskDelete(thread_id);
2380  return status == OK ? 0 : ERROR;
2381 
2382 #elif defined(OS_UNIX)
2383 
2384  INT status;
2385  status = pthread_kill(thread_id, SIGKILL);
2386  return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
2387 
2388 #endif
2389 }
#define SS_NO_THREAD
Definition: midas.h:678
Here is the caller graph for this function:

◆ ss_thread_set_name()

INT EXPRT ss_thread_set_name ( std::string  name)

Definition at line 2393 of file system.cxx.

2394 {
2395 #if defined(OS_DARWIN)
2396 
2397  pthread_setname_np(name.c_str());
2398  return SS_SUCCESS;
2399 
2400 #elif defined(OS_UNIX)
2401 
2402  pthread_t thread = pthread_self();
2403  pthread_setname_np(thread, name.c_str());
2404  return SS_SUCCESS;
2405 
2406 #else
2407  return 0;
2408 #endif
2409 }
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 1542 of file system.cxx.

1543 {
1544 #if defined OS_MSDOS
1545 
1546  return "0";
1547 
1548 #elif defined OS_WINNT
1549 
1550 #error Do not know how to do ss_tid_to_string()
1551  return "???";
1552 
1553 #elif defined OS_VMS
1554 
1555  char buf[256];
1556  sprintf(buf, "%d", thread_id);
1557  return buf;
1558 
1559 #elif defined OS_DARWIN
1560 
1561  char buf[256];
1562  sprintf(buf, "%p", thread_id);
1563  return buf;
1564 
1565 #elif defined OS_CYGWIN
1566 
1567  char buf[256];
1568  sprintf(buf, "%p", thread_id);
1569  return buf;
1570 
1571 #elif defined OS_UNIX
1572 
1573  char buf[256];
1574  sprintf(buf, "%lu", thread_id);
1575  return buf;
1576 
1577 #elif defined OS_VXWORKS
1578 
1579  char buf[256];
1580  sprintf(buf, "%d", thread_id);
1581  return buf;
1582 
1583 #else
1584 #error Do not know how to do ss_tid_to_string()
1585 #endif
1586 }
Here is the caller graph for this function:

◆ ss_time()

DWORD EXPRT ss_time ( )

Returns the actual time in seconds since 1.1.1970 UTC.

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

Definition at line 3401 of file system.cxx.

3402 {
3403  return (DWORD) time(NULL);
3404 }
Here is the caller graph for this function:

◆ ss_time_sec()

double EXPRT ss_time_sec ( )

Definition at line 3406 of file system.cxx.

3407 {
3408  struct timeval tv;
3409  gettimeofday(&tv, NULL);
3410  return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
3411 }
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 3204 of file system.cxx.

3220 {
3221  if (timeout_sec <= 0) {
3222  mutex.lock();
3223  return true;
3224  }
3225 
3226  double starttime = ss_time_sec();
3227  double endtime = starttime + timeout_sec;
3228 
3229  // NB: per timed mutex try_lock_for(), one must always
3230  // look waiting for successful lock because it is permitted
3231  // to return "false" even if timeout did not yet expire. (cannot
3232  // tell permitted spurious failure from normal timeout). K.O.
3233 
3234  double locktime = starttime;
3235 
3236  while (1) {
3237  bool ok = mutex.try_lock_for(std::chrono::milliseconds(1000));
3238 
3239  if (ok) {
3240  //double now = ss_time_sec();
3241  //fprintf(stderr, "ss_timed_mutex_wait_for_sec: mutex %s locked in %.1f seconds. timeout %.1f seconds\n", mutex_name, now-starttime, timeout_sec);
3242  return true;
3243  }
3244 
3245  double now = ss_time_sec();
3246 
3247  if (mutex_name) {
3248  if (now-locktime < 0.2) {
3249  // 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.
3250  //fprintf(stderr, "ss_timed_mutex_wait_for_sec: short try_lock_for(1000). %.3f seconds\n", now-locktime);
3251  } else {
3252  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);
3253  }
3254  }
3255 
3256  if (now > endtime)
3257  return false;
3258 
3259  locktime = now;
3260  }
3261 }
double ss_time_sec()
Definition: system.cxx:3406
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 3519 of file system.cxx.

3537 {
3538 #if defined(OS_DARWIN) || defined(OS_VXWORKS)
3539  return 0;
3540 #else
3541  return (INT) timezone; /* on Linux, comes from "#include <time.h>". */
3542 #endif
3543 }
Here is the caller graph for this function:

◆ ss_tzset()

void EXPRT ss_tzset ( )

Definition at line 3294 of file system.cxx.

3295 {
3296  std::lock_guard<std::mutex> lock(gTzMutex);
3297  //defeat tzset() error trap from msystem.h
3298  //#ifdef tzset
3299  //#undef tzset
3300  //#endif
3301  tzset();
3302 }
Here is the caller graph for this function:

◆ ss_us_since()

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

Definition at line 8199 of file system.cxx.

8199  {
8200  auto elapsed = std::chrono::high_resolution_clock::now() - start;
8201  return std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
8202 }

◆ ss_us_start()

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

Definition at line 8194 of file system.cxx.

8195 {
8196  return std::chrono::high_resolution_clock::now();
8197 }

◆ ss_write_tcp()

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

Definition at line 5285 of file system.cxx.

5306 {
5307  size_t count = 0;
5308 
5309  while (count < buffer_size) {
5310  ssize_t wr = write(sock, buffer + count, buffer_size - count);
5311 
5312  if (wr == 0) {
5313  cm_msg(MERROR, "ss_write_tcp", "write(socket=%d,size=%d) returned zero, errno: %d (%s)", sock, (int) (buffer_size - count), errno, strerror(errno));
5314  return SS_SOCKET_ERROR;
5315  } else if (wr < 0) {
5316 #ifdef OS_UNIX
5317  if (errno == EINTR)
5318  continue;
5319 #endif
5320  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));
5321  return SS_SOCKET_ERROR;
5322  }
5323 
5324  // good write
5325  count += wr;
5326  }
5327 
5328  return SS_SUCCESS;
5329 }
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 1970 of file system.cxx.

◆ _ss_client_connection

RPC_SERVER_CONNECTION* _ss_client_connection = NULL
static

Definition at line 3926 of file system.cxx.

◆ _ss_client_listen_socket

int _ss_client_listen_socket = 0
static

Definition at line 3923 of file system.cxx.

◆ _ss_client_thread

midas_thread_t _ss_client_thread = 0
static

Definition at line 3925 of file system.cxx.

◆ _ss_listen_thread

midas_thread_t _ss_listen_thread = 0
static

Definition at line 3921 of file system.cxx.

◆ _ss_odb_thread

midas_thread_t _ss_odb_thread = 0
static

Definition at line 3918 of file system.cxx.

◆ _ss_server_acceptions

RPC_SERVER_ACCEPTION_LIST* _ss_server_acceptions = NULL
static

Definition at line 3929 of file system.cxx.

◆ _ss_server_listen_socket

int _ss_server_listen_socket = 0
static

Definition at line 3922 of file system.cxx.

◆ _ss_server_thread

midas_thread_t _ss_server_thread = 0
static

Definition at line 3928 of file system.cxx.

◆ _ss_suspend_odb

SUSPEND_STRUCT* _ss_suspend_odb = NULL
static

Definition at line 3919 of file system.cxx.

◆ _ss_suspend_vector

std::vector<SUSPEND_STRUCT*> _ss_suspend_vector
static

Definition at line 3916 of file system.cxx.

◆  [1/2]

char { ... } c

Definition at line 1316 of file system.cxx.

◆  [2/2]

char { ... } c

Definition at line 1322 of file system.cxx.

◆  [1/2]

double { ... } d

Definition at line 1317 of file system.cxx.

◆  [2/2]

double { ... } d

Definition at line 1321 of file system.cxx.

◆ gSocketTrace

bool gSocketTrace = false
static

Definition at line 4903 of file system.cxx.

◆ gTzMutex

std::mutex gTzMutex
static

Definition at line 3292 of file system.cxx.

◆ MidasExceptionHandler

void(* MidasExceptionHandler) (void) ( void  )

Definition at line 3728 of file system.cxx.

◆ s_semaphore_nest_level

std::atomic_int s_semaphore_nest_level {0}
static

Definition at line 2425 of file system.cxx.

◆ s_semaphore_trace

std::atomic_bool s_semaphore_trace {false}
static

Definition at line 2424 of file system.cxx.

◆ stack_history

char stack_history[N_STACK_HISTORY][80]

Definition at line 7930 of file system.cxx.

◆ stack_history_pointer

int stack_history_pointer = -1

Definition at line 7931 of file system.cxx.

◆ 

struct { ... } test_align

◆ 

struct { ... } test_padding