RTS API Documentation  1.10.11
switch.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Michael Jerris <mike@jerris.com>
28  * Pawel Pierscionek <pawel@voiceworks.pl>
29  * Bret McDanel <trixter AT 0xdecafbad.com>
30  *
31  *
32  * switch.c -- Main
33  *
34  */
35 
36 #ifndef _XOPEN_SOURCE
37 #define _XOPEN_SOURCE 600
38 #endif
39 
40 #ifndef WIN32
41 #include <poll.h>
42 #ifdef HAVE_SETRLIMIT
43 #include <sys/resource.h>
44 #endif
45 #endif
46 
47 #ifdef __linux__
48 #include <sys/prctl.h>
49 #endif
50 
51 #include <switch.h>
52 #include "private/switch_apr_pvt.h"
54 
55 /* pid filename: Stores the process id of the freeswitch process */
56 #define PIDFILE "freeswitch.pid"
57 static char *pfile = PIDFILE;
58 static int system_ready = 0;
59 
60 /* Picky compiler */
61 #ifdef __ICC
62 #pragma warning (disable:167)
63 #endif
64 
65 #ifdef WIN32
66 /* If we are a windows service, what should we be called */
67 #define SERVICENAME_DEFAULT "FreeSWITCH"
68 #define SERVICENAME_MAXLEN 256
69 static char service_name[SERVICENAME_MAXLEN];
70 static switch_core_flag_t service_flags = SCF_NONE;
71 #include <winsock2.h>
72 #include <windows.h>
73 
74 /* event to signal shutdown (for you unix people, this is like a pthread_cond) */
75 static HANDLE shutdown_event;
76 
77 #ifndef PATH_MAX
78 #define PATH_MAX 256
79 #endif
80 #endif
81 
82 /* signal handler for when freeswitch is running in background mode.
83  * signal triggers the shutdown of freeswitch
84 # */
85 static void handle_SIGILL(int sig)
86 {
87  int32_t arg = 0;
88  if (sig) {}
89  /* send shutdown signal to the freeswitch core */
91  return;
92 }
93 
94 static void handle_SIGTERM(int sig)
95 {
96  int32_t arg = 0;
97  if (sig) {}
98  /* send shutdown signal to the freeswitch core */
100  return;
101 }
102 
103 /* kill a freeswitch process running in background mode */
105 {
106  FILE *f; /* FILE handle to open the pid file */
107  char path[PATH_MAX] = ""; /* full path of the PID file */
108  pid_t pid = 0; /* pid from the pid file */
109 
110  /* set the globals so we can use the global paths. */
112 
113  /* get the full path of the pid file. */
114  switch_snprintf(path, sizeof(path), "%s%s%s", SWITCH_GLOBAL_dirs.run_dir, SWITCH_PATH_SEPARATOR, pfile);
115 
116  /* open the pid file */
117  if ((f = fopen(path, "r")) == 0) {
118  /* pid file does not exist */
119  fprintf(stderr, "Cannot open pid file %s.\n", path);
120  return 255;
121  }
122 
123  /* pull the pid from the file */
124  if (fscanf(f, "%d", (int *) (intptr_t) & pid) != 1) {
125  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to get the pid!\n");
126  }
127 
128  /* if we have a valid pid */
129  if (pid > 0) {
130 
131  /* kill the freeswitch running at the pid we found */
132  fprintf(stderr, "Killing: %d\n", (int) pid);
133 #ifdef WIN32
134  /* for windows we need the event to signal for shutting down a background FreeSWITCH */
135  snprintf(path, sizeof(path), "Global\\Freeswitch.%d", pid);
136 
137  /* open the event so we can signal it */
138  shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path);
139 
140  /* did we successfully open the event */
141  if (!shutdown_event) {
142  /* we can't get the event, so we can't signal the process to shutdown */
143  fprintf(stderr, "ERROR: Can't Shutdown: %d\n", (int) pid);
144  } else {
145  /* signal the event to shutdown */
146  SetEvent(shutdown_event);
147  /* cleanup */
148  CloseHandle(shutdown_event);
149  }
150 #else
151  /* for unix, send the signal to kill. */
152  kill(pid, SIGTERM);
153 #endif
154  }
155 
156  /* be nice and close the file handle to the pid file */
157  fclose(f);
158 
159  return 0;
160 }
161 
162 #ifdef WIN32
163 
164 /* we need these vars to handle the service */
165 SERVICE_STATUS_HANDLE hStatus;
166 SERVICE_STATUS status;
167 
168 /* Handler function for service start/stop from the service */
169 void WINAPI ServiceCtrlHandler(DWORD control)
170 {
171  switch (control) {
172  case SERVICE_CONTROL_SHUTDOWN:
173  case SERVICE_CONTROL_STOP:
174  /* Shutdown freeswitch */
176  /* set service status values */
177  status.dwCurrentState = SERVICE_STOPPED;
178  status.dwWin32ExitCode = 0;
179  status.dwCheckPoint = 0;
180  status.dwWaitHint = 0;
181  break;
182  case SERVICE_CONTROL_INTERROGATE:
183  /* we already set the service status every time it changes. */
184  /* if there are other times we change it and don't update, we should do so here */
185  break;
186  }
187 
188  SetServiceStatus(hStatus, &status);
189 }
190 
191 /* the main service entry point */
192 void WINAPI service_main(DWORD numArgs, char **args)
193 {
195  const char *err = NULL; /* error value for return from freeswitch initialization */
196 
197  /* Override flags if they have been set earlier */
198  if (service_flags != SCF_NONE)
199  flags = service_flags;
200 
201  /* we have to initialize the service-specific stuff */
202  memset(&status, 0, sizeof(SERVICE_STATUS));
203  status.dwServiceType = SERVICE_WIN32;
204  status.dwCurrentState = SERVICE_START_PENDING;
205  status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
206 
207  /* register our handler for service control messages */
208  hStatus = RegisterServiceCtrlHandler(service_name, &ServiceCtrlHandler);
209 
210  /* update the service status */
211  SetServiceStatus(hStatus, &status);
212 
214 
215  /* attempt to initialize freeswitch and load modules */
217  /* freeswitch did not start successfully */
218  status.dwCurrentState = SERVICE_STOPPED;
219  } else {
220  /* freeswitch started */
221  status.dwCurrentState = SERVICE_RUNNING;
222  }
223 
224  /* update the service status */
225  SetServiceStatus(hStatus, &status);
226 }
227 
228 #else
229 
230 static int check_fd(int fd, int ms)
231 {
232  struct pollfd pfds[2] = { { 0 } };
233  int s, r = 0;
234 
235  pfds[0].fd = fd;
236  pfds[0].events = POLLIN | POLLERR;
237  s = poll(pfds, 1, ms);
238 
239  if (s == 0 || s == -1) {
240  r = s;
241  } else {
242  r = -1;
243 
244  if ((pfds[0].revents & POLLIN)) {
245  if (read(fd, &r, sizeof(r)) > -1) {
246  (void)write(fd, &r, sizeof(r));
247  }
248  }
249  }
250 
251  return r;
252 }
253 
254 static void daemonize(int *fds)
255 {
256  int fd;
257  pid_t pid;
258  unsigned int sanity = 60;
259 
260  if (!fds) {
261  switch (fork()) {
262  case 0: /* child process */
263  break;
264  case -1:
265  fprintf(stderr, "Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno));
266  exit(EXIT_SUCCESS);
267  break;
268  default: /* parent process */
269  exit(EXIT_SUCCESS);
270  }
271 
272  if (setsid() < 0) {
273  fprintf(stderr, "Error Backgrounding (setsid)! %d - %s\n", errno, strerror(errno));
274  exit(EXIT_SUCCESS);
275  }
276  }
277 
278  pid = switch_fork();
279 
280  switch (pid) {
281  case 0: /* child process */
282  if (fds) {
283  close(fds[0]);
284  }
285  break;
286  case -1:
287  fprintf(stderr, "Error Backgrounding (fork2)! %d - %s\n", errno, strerror(errno));
288  exit(EXIT_SUCCESS);
289  break;
290  default: /* parent process */
291  fprintf(stderr, "%d Backgrounding.\n", (int) pid);
292 
293  if (fds) {
294  char *o;
295 
296  close(fds[1]);
297 
298  if ((o = getenv("FREESWITCH_BG_TIMEOUT"))) {
299  int tmp = atoi(o);
300  if (tmp > 0) {
301  sanity = tmp;
302  }
303  }
304 
305  do {
306  system_ready = check_fd(fds[0], 2000);
307 
308  if (system_ready == 0) {
309  printf("FreeSWITCH[%d] Waiting for background process pid:%d to be ready.....\n", (int)getpid(), (int) pid);
310  }
311 
312  } while (--sanity && system_ready == 0);
313 
314  shutdown(fds[0], 2);
315  close(fds[0]);
316  fds[0] = -1;
317 
318 
319  if (system_ready < 0) {
320  printf("FreeSWITCH[%d] Error starting system! pid:%d\n", (int)getpid(), (int) pid);
321  kill(pid, 9);
322  exit(EXIT_FAILURE);
323  }
324 
325  printf("FreeSWITCH[%d] System Ready pid:%d\n", (int) getpid(), (int) pid);
326  }
327 
328  exit(EXIT_SUCCESS);
329  }
330 
331  if (fds) {
332  setsid();
333  }
334  /* redirect std* to null */
335  fd = open("/dev/null", O_RDONLY);
336  switch_assert( fd >= 0 );
337  if (fd != 0) {
338  dup2(fd, 0);
339  close(fd);
340  }
341 
342  fd = open("/dev/null", O_WRONLY);
343  switch_assert( fd >= 0 );
344  if (fd != 1) {
345  dup2(fd, 1);
346  close(fd);
347  }
348 
349  fd = open("/dev/null", O_WRONLY);
350  switch_assert( fd >= 0 );
351  if (fd != 2) {
352  dup2(fd, 2);
353  close(fd);
354  }
355  return;
356 }
357 
358 static pid_t reincarnate_child = 0;
359 static void reincarnate_handle_sigterm (int sig) {
360  if (!sig) return;
361  if (reincarnate_child) kill(reincarnate_child, sig);
362  return;
363 }
364 
365 static void reincarnate_protect(char **argv) {
366  int i; struct sigaction sa, sa_dfl, sa4_prev, sa15_prev, sa17_prev;
367  memset(&sa, 0, sizeof(sa)); memset(&sa_dfl, 0, sizeof(sa_dfl));
368  sa.sa_handler = reincarnate_handle_sigterm;
369  sa_dfl.sa_handler = SIG_DFL;
370  refork:
371  if ((i=fork())) { /* parent */
372  int s; pid_t r;
373  reincarnate_child = i;
374  sigaction(SIGILL, &sa, &sa4_prev);
375  sigaction(SIGTERM, &sa, &sa15_prev);
376  sigaction(SIGCHLD, &sa_dfl, &sa17_prev);
377  rewait:
378  r = waitpid(i, &s, 0);
379  if (r == (pid_t)-1) {
380  if (errno == EINTR) goto rewait;
381  exit(EXIT_FAILURE);
382  }
383  if (r != i) goto rewait;
384  if (WIFEXITED(s)
385  && (WEXITSTATUS(s) == EXIT_SUCCESS
386  || WEXITSTATUS(s) == EXIT_FAILURE)) {
387  exit(WEXITSTATUS(s));
388  }
389  if (WIFEXITED(s) || WIFSIGNALED(s)) {
390  sigaction(SIGILL, &sa4_prev, NULL);
391  sigaction(SIGTERM, &sa15_prev, NULL);
392  sigaction(SIGCHLD, &sa17_prev, NULL);
393  if (argv) {
394  if (argv[0] && execv(argv[0], argv) == -1) {
395  char buf[256];
396  fprintf(stderr, "Reincarnate execv() failed: %d %s\n", errno,
397  switch_strerror_r(errno, buf, sizeof(buf)));
398  }
399  fprintf(stderr, "Trying reincarnate-reexec plan B...\n");
400  if (argv[0] && execvp(argv[0], argv) == -1) {
401  char buf[256];
402  fprintf(stderr, "Reincarnate execvp() failed: %d %s\n", errno,
403  switch_strerror_r(errno, buf, sizeof(buf)));
404  }
405  fprintf(stderr, "Falling back to normal reincarnate behavior...\n");
406  goto refork;
407  } else goto refork;
408  }
409  goto rewait;
410  } else { /* child */
411 #ifdef __linux__
412  prctl(PR_SET_PDEATHSIG, SIGTERM);
413 #endif
414  }
415 }
416 
417 #endif
418 
419 static const char usage[] =
420  "Usage: freeswitch [OPTIONS]\n\n"
421  "These are the optional arguments you can pass to freeswitch:\n"
422 #ifdef WIN32
423  "\t-service [name] -- start freeswitch as a service, cannot be used if loaded as a console app\n"
424  "\t-install [name] -- install freeswitch as a service, with optional service name\n"
425  "\t-uninstall -- remove freeswitch as a service\n"
426  "\t-monotonic-clock -- use monotonic clock as timer source\n"
427 #else
428  "\t-nf -- no forking\n"
429  "\t-reincarnate -- restart the switch on an uncontrolled exit\n"
430  "\t-reincarnate-reexec -- run execv on a restart (helpful for upgrades)\n"
431  "\t-u [user] -- specify user to switch to\n"
432  "\t-g [group] -- specify group to switch to\n"
433 #endif
434 #ifdef HAVE_SETRLIMIT
435 #ifndef FS_64BIT
436  "\t-waste -- allow memory waste\n"
437 #endif
438  "\t-core -- dump cores\n"
439 #endif
440  "\t-help -- this message\n"
441  "\t-version -- print the version and exit\n"
442  "\t-rp -- enable high(realtime) priority settings\n"
443  "\t-lp -- enable low priority settings\n"
444  "\t-np -- enable normal priority settings\n"
445  "\t-vg -- run under valgrind\n"
446  "\t-nosql -- disable internal sql scoreboard\n"
447  "\t-heavy-timer -- Heavy Timer, possibly more accurate but at a cost\n"
448  "\t-nat -- enable auto nat detection\n"
449  "\t-nonat -- disable auto nat detection\n"
450  "\t-nonatmap -- disable auto nat port mapping\n"
451  "\t-nocal -- disable clock calibration\n"
452  "\t-nort -- disable clock clock_realtime\n"
453  "\t-stop -- stop freeswitch\n"
454  "\t-nc -- do not output to a console and background\n"
455 #ifndef WIN32
456  "\t-ncwait -- do not output to a console and background but wait until the system is ready before exiting (implies -nc)\n"
457 #endif
458  "\t-c -- output to a console and stay in the foreground\n"
459  "\n\tOptions to control locations of files:\n"
460  "\t-base [basedir] -- alternate prefix directory\n"
461  "\t-cfgname [filename] -- alternate filename for FreeSWITCH main configuration file\n"
462  "\t-conf [confdir] -- alternate directory for FreeSWITCH configuration files\n"
463  "\t-log [logdir] -- alternate directory for logfiles\n"
464  "\t-run [rundir] -- alternate directory for runtime files\n"
465  "\t-db [dbdir] -- alternate directory for the internal database\n"
466  "\t-mod [moddir] -- alternate directory for modules\n"
467  "\t-htdocs [htdocsdir] -- alternate directory for htdocs\n"
468  "\t-scripts [scriptsdir] -- alternate directory for scripts\n"
469  "\t-temp [directory] -- alternate directory for temporary files\n"
470  "\t-grammar [directory] -- alternate directory for grammar files\n"
471  "\t-certs [directory] -- alternate directory for certificates\n"
472  "\t-recordings [directory] -- alternate directory for recordings\n"
473  "\t-storage [directory] -- alternate directory for voicemail storage\n"
474  "\t-cache [directory] -- alternate directory for cache files\n"
475  "\t-sounds [directory] -- alternate directory for sound files\n";
476 
477 
478 /**
479  * Check if value string starts with "-"
480  */
481 static switch_bool_t is_option(const char *p)
482 {
483  /* skip whitespaces */
484  while ((*p == 13) || (*p == 10) || (*p == 9) || (*p == 32) || (*p == 11)) p++;
485  return (p[0] == '-');
486 }
487 
488 
489 /* the main application entry point */
490 int main(int argc, char *argv[])
491 {
492  char pid_path[PATH_MAX] = ""; /* full path to the pid file */
493  char pid_buffer[32] = ""; /* pid string */
494  char old_pid_buffer[32] = { 0 }; /* pid string */
495  switch_size_t pid_len, old_pid_len;
496  const char *err = NULL; /* error value for return from freeswitch initialization */
497 #ifndef WIN32
498  switch_bool_t nf = SWITCH_FALSE; /* TRUE if we are running in nofork mode */
499  switch_bool_t do_wait = SWITCH_FALSE;
500  char *runas_user = NULL;
501  char *runas_group = NULL;
502  switch_bool_t reincarnate = SWITCH_FALSE, reincarnate_reexec = SWITCH_FALSE;
503  int fds[2] = { 0, 0 };
504 #else
505  const switch_bool_t nf = SWITCH_TRUE; /* On Windows, force nf to true*/
506  switch_bool_t win32_service = SWITCH_FALSE;
507 #endif
508  switch_bool_t nc = SWITCH_FALSE; /* TRUE if we are running in noconsole mode */
509  switch_bool_t elegant_term = SWITCH_FALSE;
510  pid_t pid = 0;
511  int i, x;
512  char *opts;
513  char opts_str[1024] = "";
514  char *local_argv[1024] = { 0 };
515  int local_argc = argc;
516  char *arg_argv[128] = { 0 };
517  int alt_dirs = 0, alt_base = 0, log_set = 0, run_set = 0, do_kill = 0;
518  int priority = 0;
519 #if (defined(__SVR4) && defined(__sun))
521 #else
523 #endif
524  int ret = 0;
525  switch_status_t destroy_status;
526  switch_file_t *fd;
527  switch_memory_pool_t *pool = NULL;
528 #ifdef HAVE_SETRLIMIT
529 #ifndef FS_64BIT
530  switch_bool_t waste = SWITCH_FALSE;
531 #endif
532 #endif
533 
534  for (x = 0; x < argc; x++) {
535  local_argv[x] = argv[x];
536  }
537 
538  if ((opts = getenv("FREESWITCH_OPTS"))) {
539  strncpy(opts_str, opts, sizeof(opts_str) - 1);
540  i = switch_separate_string(opts_str, ' ', arg_argv, (sizeof(arg_argv) / sizeof(arg_argv[0])));
541  for (x = 0; x < i; x++) {
542  local_argv[local_argc++] = arg_argv[x];
543  }
544  }
545 
546  if (local_argv[0] && strstr(local_argv[0], "freeswitchd")) {
547  nc = SWITCH_TRUE;
548  }
549 
550  // disable auto nat, use -nat to enable it
551  flags &= ~SCF_USE_AUTO_NAT;
552 
553  for (x = 1; x < local_argc; x++) {
554 
555  if (switch_strlen_zero(local_argv[x]))
556  continue;
557 
558  if (!strcmp(local_argv[x], "-help") || !strcmp(local_argv[x], "-h") || !strcmp(local_argv[x], "-?")) {
559  printf("%s\n", usage);
560  exit(EXIT_SUCCESS);
561  }
562 #ifdef WIN32
563  if (x == 1 && !strcmp(local_argv[x], "-service")) {
564  /* New installs will always have the service name specified, but keep a default for compat */
565  x++;
566  if (!switch_strlen_zero(local_argv[x])) {
567  switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
568  } else {
569  switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
570  }
571 
572  win32_service = SWITCH_TRUE;
573  continue;
574  }
575 
576  else if (x == 1 && !strcmp(local_argv[x], "-install")) {
577  char servicePath[PATH_MAX];
578  char exePath[PATH_MAX];
579  SC_HANDLE hService;
580  SC_HANDLE hSCManager;
581  SERVICE_DESCRIPTION desc;
582  desc.lpDescription = "The FreeSWITCH service.";
583 
584  x++;
585  if (!switch_strlen_zero(local_argv[x])) {
586  switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
587  } else {
588  switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
589  }
590 
591  GetModuleFileName(NULL, exePath, sizeof(exePath));
592  snprintf(servicePath, sizeof(servicePath), "%s -service %s", exePath, service_name);
593 
594  /* Perform service installation */
595 
596  hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
597  if (!hSCManager) {
598  fprintf(stderr, "Could not open service manager (%u).\n", GetLastError());
599  exit(EXIT_FAILURE);
600  }
601 
602  hService = CreateService(hSCManager, service_name, service_name, GENERIC_READ | GENERIC_EXECUTE | SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
603  servicePath, NULL, NULL, NULL, NULL, /* Service start name */ NULL);
604  if (!hService) {
605  fprintf(stderr, "Error creating freeswitch service (%u).\n", GetLastError());
606  CloseServiceHandle(hSCManager);
607  exit(EXIT_FAILURE);
608  }
609 
610  /* Set desc, and don't care if it succeeds */
611  if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc)) {
612  fprintf(stderr, "FreeSWITCH installed, but could not set the service description (%u).\n", GetLastError());
613  }
614 
615  CloseServiceHandle(hService);
616  CloseServiceHandle(hSCManager);
617  exit(EXIT_SUCCESS);
618  }
619 
620  else if (x == 1 && !strcmp(local_argv[x], "-uninstall")) {
621  SC_HANDLE hService;
622  SC_HANDLE hSCManager;
623  BOOL deleted;
624 
625  x++;
626  if (!switch_strlen_zero(local_argv[x])) {
627  switch_copy_string(service_name, local_argv[x], SERVICENAME_MAXLEN);
628  } else {
629  switch_copy_string(service_name, SERVICENAME_DEFAULT, SERVICENAME_MAXLEN);
630  }
631 
632  /* Do the uninstallation */
633  hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
634  if (!hSCManager) {
635  fprintf(stderr, "Could not open service manager (%u).\n", GetLastError());
636  exit(EXIT_FAILURE);
637  }
638 
639  hService = OpenService(hSCManager, service_name, DELETE);
640  if (!hService) {
641  fprintf(stderr, "Error opening service (%u).\n", GetLastError());
642  CloseServiceHandle(hSCManager);
643  exit(EXIT_FAILURE);
644  }
645 
646  /* remove the service! */
647  deleted = DeleteService(hService);
648  if (!deleted) {
649  fprintf(stderr, "Error deleting service (%u).\n", GetLastError());
650  }
651 
652  CloseServiceHandle(hService);
653  CloseServiceHandle(hSCManager);
654  exit(deleted ? EXIT_SUCCESS : EXIT_FAILURE);
655  }
656 
657  else if (!strcmp(local_argv[x], "-monotonic-clock")) {
658  flags |= SCF_USE_WIN32_MONOTONIC;
659  }
660 #else
661  else if (!strcmp(local_argv[x], "-u")) {
662  x++;
663  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
664  fprintf(stderr, "Option '%s' requires an argument!\n", local_argv[x - 1]);
665  exit(EXIT_FAILURE);
666  }
667  runas_user = local_argv[x];
668  }
669 
670  else if (!strcmp(local_argv[x], "-g")) {
671  x++;
672  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
673  fprintf(stderr, "Option '%s' requires an argument!\n", local_argv[x - 1]);
674  exit(EXIT_FAILURE);
675  }
676  runas_group = local_argv[x];
677  }
678 
679  else if (!strcmp(local_argv[x], "-nf")) {
680  nf = SWITCH_TRUE;
681  }
682 
683  else if (!strcmp(local_argv[x], "-elegant-term")) {
684  elegant_term = SWITCH_TRUE;
685  }
686 
687  else if (!strcmp(local_argv[x], "-reincarnate")) {
688  reincarnate = SWITCH_TRUE;
689  }
690  else if (!strcmp(local_argv[x], "-reincarnate-reexec")) {
691  reincarnate = SWITCH_TRUE;
692  reincarnate_reexec = SWITCH_TRUE;
693  }
694 #endif
695 #ifdef HAVE_SETRLIMIT
696  else if (!strcmp(local_argv[x], "-core")) {
697  struct rlimit rlp;
698  memset(&rlp, 0, sizeof(rlp));
699  rlp.rlim_cur = RLIM_INFINITY;
700  rlp.rlim_max = RLIM_INFINITY;
701  setrlimit(RLIMIT_CORE, &rlp);
702  }
703 
704  else if (!strcmp(local_argv[x], "-waste")) {
705 #ifndef FS_64BIT
706  fprintf(stderr, "WARNING: Wasting up to 8 megs of memory per thread.\n");
707  sleep(2);
708  waste = SWITCH_TRUE;
709 #endif
710  }
711 
712  else if (!strcmp(local_argv[x], "-no-auto-stack")) {
713 #ifndef FS_64BIT
714  waste = SWITCH_TRUE;
715 #endif
716  }
717 #endif
718  else if (!strcmp(local_argv[x], "-version")) {
719  fprintf(stdout, "FreeSWITCH version: %s (%s)\n", switch_version_full(), switch_version_revision_human());
720  exit(EXIT_SUCCESS);
721  }
722 
723  else if (!strcmp(local_argv[x], "-hp") || !strcmp(local_argv[x], "-rp")) {
724  priority = 2;
725  }
726 
727  else if (!strcmp(local_argv[x], "-lp")) {
728  priority = -1;
729  }
730 
731  else if (!strcmp(local_argv[x], "-np")) {
732  priority = 1;
733  }
734 
735  else if (!strcmp(local_argv[x], "-nosql")) {
736  flags &= ~SCF_USE_SQL;
737  }
738 
739  else if (!strcmp(local_argv[x], "-nonat")) {
740  flags &= ~SCF_USE_AUTO_NAT;
741  }
742 
743  else if (!strcmp(local_argv[x], "-nat")) {
744  flags |= SCF_USE_AUTO_NAT;
745  }
746 
747  else if (!strcmp(local_argv[x], "-nonatmap")) {
748  flags &= ~SCF_USE_NAT_MAPPING;
749  }
750 
751  else if (!strcmp(local_argv[x], "-heavy-timer")) {
752  flags |= SCF_USE_HEAVY_TIMING;
753  }
754 
755  else if (!strcmp(local_argv[x], "-nort")) {
756  flags &= ~SCF_USE_CLOCK_RT;
757  }
758 
759  else if (!strcmp(local_argv[x], "-nocal")) {
760  flags &= ~SCF_CALIBRATE_CLOCK;
761  }
762 
763  else if (!strcmp(local_argv[x], "-vg")) {
764  flags |= SCF_VG;
765  }
766 
767  else if (!strcmp(local_argv[x], "-stop")) {
768  do_kill = SWITCH_TRUE;
769  }
770 
771  else if (!strcmp(local_argv[x], "-nc")) {
772  nc = SWITCH_TRUE;
773  }
774 #ifndef WIN32
775  else if (!strcmp(local_argv[x], "-ncwait")) {
776  nc = SWITCH_TRUE;
777  do_wait = SWITCH_TRUE;
778  }
779 #endif
780  else if (!strcmp(local_argv[x], "-c")) {
781  nc = SWITCH_FALSE;
782  }
783 
784  else if (!strcmp(local_argv[x], "-conf")) {
785  x++;
786  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
787  fprintf(stderr, "When using -conf you must specify a config directory\n");
788  return 255;
789  }
790 
791  SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(strlen(local_argv[x]) + 1);
793  fprintf(stderr, "Allocation error\n");
794  return 255;
795  }
796  strcpy(SWITCH_GLOBAL_dirs.conf_dir, local_argv[x]);
797  alt_dirs++;
798  }
799 
800  else if (!strcmp(local_argv[x], "-mod")) {
801  x++;
802  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
803  fprintf(stderr, "When using -mod you must specify a module directory\n");
804  return 255;
805  }
806 
807  SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(strlen(local_argv[x]) + 1);
809  fprintf(stderr, "Allocation error\n");
810  return 255;
811  }
812  strcpy(SWITCH_GLOBAL_dirs.mod_dir, local_argv[x]);
813  }
814 
815  else if (!strcmp(local_argv[x], "-log")) {
816  x++;
817  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
818  fprintf(stderr, "When using -log you must specify a log directory\n");
819  return 255;
820  }
821 
822  SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(strlen(local_argv[x]) + 1);
824  fprintf(stderr, "Allocation error\n");
825  return 255;
826  }
827  strcpy(SWITCH_GLOBAL_dirs.log_dir, local_argv[x]);
828  alt_dirs++;
829  log_set = SWITCH_TRUE;
830  }
831 
832  else if (!strcmp(local_argv[x], "-run")) {
833  x++;
834  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
835  fprintf(stderr, "When using -run you must specify a pid directory\n");
836  return 255;
837  }
838 
839  SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(local_argv[x]) + 1);
841  fprintf(stderr, "Allocation error\n");
842  return 255;
843  }
844  strcpy(SWITCH_GLOBAL_dirs.run_dir, local_argv[x]);
845  run_set = SWITCH_TRUE;
846  }
847 
848  else if (!strcmp(local_argv[x], "-db")) {
849  x++;
850  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
851  fprintf(stderr, "When using -db you must specify a db directory\n");
852  return 255;
853  }
854 
855  SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(strlen(local_argv[x]) + 1);
856  if (!SWITCH_GLOBAL_dirs.db_dir) {
857  fprintf(stderr, "Allocation error\n");
858  return 255;
859  }
860  strcpy(SWITCH_GLOBAL_dirs.db_dir, local_argv[x]);
861  alt_dirs++;
862  }
863 
864  else if (!strcmp(local_argv[x], "-scripts")) {
865  x++;
866  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
867  fprintf(stderr, "When using -scripts you must specify a scripts directory\n");
868  return 255;
869  }
870 
871  SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(strlen(local_argv[x]) + 1);
873  fprintf(stderr, "Allocation error\n");
874  return 255;
875  }
876  strcpy(SWITCH_GLOBAL_dirs.script_dir, local_argv[x]);
877  }
878 
879  else if (!strcmp(local_argv[x], "-htdocs")) {
880  x++;
881  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
882  fprintf(stderr, "When using -htdocs you must specify a htdocs directory\n");
883  return 255;
884  }
885 
886  SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(strlen(local_argv[x]) + 1);
888  fprintf(stderr, "Allocation error\n");
889  return 255;
890  }
891  strcpy(SWITCH_GLOBAL_dirs.htdocs_dir, local_argv[x]);
892  }
893 
894  else if (!strcmp(local_argv[x], "-base")) {
895  x++;
896  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
897  fprintf(stderr, "When using -base you must specify a base directory\n");
898  return 255;
899  }
900 
901  SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(strlen(local_argv[x]) + 1);
903  fprintf(stderr, "Allocation error\n");
904  return 255;
905  }
906  strcpy(SWITCH_GLOBAL_dirs.base_dir, local_argv[x]);
907  alt_base = 1;
908  }
909 
910  else if (!strcmp(local_argv[x], "-temp")) {
911  x++;
912  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
913  fprintf(stderr, "When using -temp you must specify a temp directory\n");
914  return 255;
915  }
916 
917  SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(strlen(local_argv[x]) + 1);
919  fprintf(stderr, "Allocation error\n");
920  return 255;
921  }
922  strcpy(SWITCH_GLOBAL_dirs.temp_dir, local_argv[x]);
923  }
924 
925  else if (!strcmp(local_argv[x], "-storage")) {
926  x++;
927  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
928  fprintf(stderr, "When using -storage you must specify a storage directory\n");
929  return 255;
930  }
931 
932  SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(strlen(local_argv[x]) + 1);
934  fprintf(stderr, "Allocation error\n");
935  return 255;
936  }
937  strcpy(SWITCH_GLOBAL_dirs.storage_dir, local_argv[x]);
938  }
939 
940  else if (!strcmp(local_argv[x], "-cache")) {
941  x++;
942  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
943  fprintf(stderr, "When using -cache you must specify a cache directory\n");
944  return 255;
945  }
946 
947  SWITCH_GLOBAL_dirs.cache_dir = (char *) malloc(strlen(local_argv[x]) + 1);
949  fprintf(stderr, "Allocation error\n");
950  return 255;
951  }
952  strcpy(SWITCH_GLOBAL_dirs.cache_dir, local_argv[x]);
953  }
954 
955  else if (!strcmp(local_argv[x], "-recordings")) {
956  x++;
957  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
958  fprintf(stderr, "When using -recordings you must specify a recording directory\n");
959  return 255;
960  }
961 
962  SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(strlen(local_argv[x]) + 1);
964  fprintf(stderr, "Allocation error\n");
965  return 255;
966  }
967  strcpy(SWITCH_GLOBAL_dirs.recordings_dir, local_argv[x]);
968  }
969 
970  else if (!strcmp(local_argv[x], "-grammar")) {
971  x++;
972  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
973  fprintf(stderr, "When using -grammar you must specify a grammar directory\n");
974  return 255;
975  }
976 
977  SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(strlen(local_argv[x]) + 1);
979  fprintf(stderr, "Allocation error\n");
980  return 255;
981  }
982  strcpy(SWITCH_GLOBAL_dirs.grammar_dir, local_argv[x]);
983  }
984 
985  else if (!strcmp(local_argv[x], "-certs")) {
986  x++;
987  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
988  fprintf(stderr, "When using -certs you must specify a certificates directory\n");
989  return 255;
990  }
991 
992  SWITCH_GLOBAL_dirs.certs_dir = (char *) malloc(strlen(local_argv[x]) + 1);
994  fprintf(stderr, "Allocation error\n");
995  return 255;
996  }
997  strcpy(SWITCH_GLOBAL_dirs.certs_dir, local_argv[x]);
998  }
999 
1000  else if (!strcmp(local_argv[x], "-sounds")) {
1001  x++;
1002  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
1003  fprintf(stderr, "When using -sounds you must specify a sounds directory\n");
1004  return 255;
1005  }
1006 
1007  SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(strlen(local_argv[x]) + 1);
1009  fprintf(stderr, "Allocation error\n");
1010  return 255;
1011  }
1012  strcpy(SWITCH_GLOBAL_dirs.sounds_dir, local_argv[x]);
1013  }
1014 
1015  else if (!strcmp(local_argv[x], "-cfgname")) {
1016  x++;
1017  if (switch_strlen_zero(local_argv[x]) || is_option(local_argv[x])) {
1018  fprintf(stderr, "When using -cfgname you must specify a filename\n");
1019  return 255;
1020  }
1021 
1022  SWITCH_GLOBAL_filenames.conf_name = (char *) malloc(strlen(local_argv[x]) + 1);
1024  fprintf(stderr, "Allocation error\n");
1025  return 255;
1026  }
1027  strcpy(SWITCH_GLOBAL_filenames.conf_name, local_argv[x]);
1028  }
1029 
1030  /* Unknown option (always last!) */
1031  else {
1032  fprintf(stderr, "Unknown option '%s', see '%s -help' for a list of valid options\n",
1033  local_argv[x], local_argv[0]);
1034  exit(EXIT_FAILURE);
1035  }
1036  }
1037 
1038  if (log_set && !run_set) {
1039  SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(strlen(SWITCH_GLOBAL_dirs.log_dir) + 1);
1040  if (!SWITCH_GLOBAL_dirs.run_dir) {
1041  fprintf(stderr, "Allocation error\n");
1042  return 255;
1043  }
1045  }
1046 
1047  if (do_kill) {
1048  return freeswitch_kill_background();
1049  }
1050 
1051  if (fspr_initialize() != SWITCH_STATUS_SUCCESS) {
1052  fprintf(stderr, "FATAL ERROR! Could not initialize APR\n");
1053  return 255;
1054  }
1055 
1056  if (alt_dirs && alt_dirs != 3 && !alt_base) {
1057  fprintf(stderr, "You must specify all or none of -conf, -log, and -db\n");
1058  return 255;
1059  }
1060 
1061 #ifndef FS_64BIT
1062 #if defined(HAVE_SETRLIMIT) && !defined(__sun)
1063  if (!waste && !(flags & SCF_VG)) {
1064  struct rlimit rlp;
1065 
1066  memset(&rlp, 0, sizeof(rlp));
1067  getrlimit(RLIMIT_STACK, &rlp);
1068 
1069  if (rlp.rlim_cur != SWITCH_THREAD_STACKSIZE) {
1070  char buf[1024] = "";
1071  int i = 0;
1072 
1073  memset(&rlp, 0, sizeof(rlp));
1074  rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;
1075  rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE;
1076  setrlimit(RLIMIT_STACK, &rlp);
1077 
1078  fspr_terminate();
1079  if (argv) ret = (int) execv(argv[0], argv);
1080 
1081  for (i = 0; i < argc; i++) {
1082  switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]);
1083  }
1084 
1085  return system(buf);
1086  }
1087  }
1088 #endif
1089 #endif
1090  signal(SIGILL, handle_SIGILL);
1091  if (elegant_term) {
1092  signal(SIGTERM, handle_SIGTERM);
1093  } else {
1094  signal(SIGTERM, handle_SIGILL);
1095  }
1096 
1097 #ifndef WIN32
1098  if (do_wait) {
1099  if (pipe(fds)) {
1100  fprintf(stderr, "System Error!\n");
1101  exit(-1);
1102  }
1103  }
1104 #endif
1105 
1106  if (nc) {
1107 #ifdef WIN32
1108  FreeConsole();
1109 #else
1110  if (!nf) {
1111  daemonize(do_wait ? fds : NULL);
1112  }
1113 #endif
1114  }
1115 #ifndef WIN32
1116  if (reincarnate)
1117  reincarnate_protect(reincarnate_reexec ? argv : NULL);
1118 #endif
1119 
1121  return 255;
1122  }
1123 
1124  switch (priority) {
1125  case 2:
1127  break;
1128  case 1:
1130  break;
1131  case -1:
1132  set_low_priority();
1133  break;
1134  default:
1136  break;
1137  }
1138 
1140 
1141 
1142 #ifndef WIN32
1143  if (runas_user || runas_group) {
1144  if (change_user_group(runas_user, runas_group) < 0) {
1145  fprintf(stderr, "Failed to switch user [%s] / group [%s]\n",
1146  switch_strlen_zero(runas_user) ? "-" : runas_user,
1147  switch_strlen_zero(runas_group) ? "-" : runas_group);
1148  return 255;
1149  }
1150  }
1151 #else
1152  if (win32_service) {
1153  /* Attempt to start service */
1154  SERVICE_TABLE_ENTRY dispatchTable[] = {
1155  {service_name, &service_main}
1156  ,
1157  {NULL, NULL}
1158  };
1159  service_flags = flags; /* copy parsed flags for service startup */
1160 
1161  if (StartServiceCtrlDispatcher(dispatchTable) == 0) {
1162  /* Not loaded as a service */
1163  fprintf(stderr, "Error Freeswitch loaded as a console app with -service option\n");
1164  fprintf(stderr, "To install the service load freeswitch with -install\n");
1165  }
1166  exit(EXIT_SUCCESS);
1167  }
1168 #endif
1169 
1171 
1172  pid = getpid();
1173 
1174  memset(pid_buffer, 0, sizeof(pid_buffer));
1175  switch_snprintf(pid_path, sizeof(pid_path), "%s%s%s", SWITCH_GLOBAL_dirs.run_dir, SWITCH_PATH_SEPARATOR, pfile);
1176  switch_snprintf(pid_buffer, sizeof(pid_buffer), "%d", pid);
1177  pid_len = strlen(pid_buffer);
1178 
1179  fspr_pool_create(&pool, NULL);
1180 
1182 
1184 
1185  old_pid_len = sizeof(old_pid_buffer) -1;
1186  switch_file_read(fd, old_pid_buffer, &old_pid_len);
1187  switch_file_close(fd);
1188  }
1189 
1190  if (switch_file_open(&fd,
1191  pid_path,
1194  fprintf(stderr, "Cannot open pid file %s.\n", pid_path);
1195  return 255;
1196  }
1197 
1199  fprintf(stderr, "Cannot lock pid file %s.\n", pid_path);
1200  old_pid_len = strlen(old_pid_buffer);
1201  if (strlen(old_pid_buffer)) {
1202  switch_file_write(fd, old_pid_buffer, &old_pid_len);
1203  }
1204  return 255;
1205  }
1206 
1207  switch_file_write(fd, pid_buffer, &pid_len);
1208 
1210  fprintf(stderr, "Cannot Initialize [%s]\n", err);
1211  return 255;
1212  }
1213 
1214 #ifndef WIN32
1215  if (do_wait) {
1216  if (fds[1] > -1) {
1217  int v = 1;
1218 
1219  if (write(fds[1], &v, sizeof(v)) < 0) {
1220  fprintf(stderr, "System Error [%s]\n", strerror(errno));
1221  } else {
1222  (void)read(fds[1], &v, sizeof(v));
1223  }
1224 
1225  shutdown(fds[1], 2);
1226  close(fds[1]);
1227  fds[1] = -1;
1228  }
1229  }
1230 #endif
1231 
1232  if (nc && nf) {
1233  signal(SIGINT, handle_SIGILL);
1234  }
1235 
1237 
1238  destroy_status = switch_core_destroy();
1239 
1240  switch_file_close(fd);
1241  fspr_pool_destroy(pool);
1242 
1243  if (unlink(pid_path) != 0) {
1244  fprintf(stderr, "Failed to delete pid file [%s]\n", pid_path);
1245  }
1246 
1247  if (destroy_status == SWITCH_STATUS_RESTART) {
1248  char buf[1024] = { 0 };
1249  int j = 0;
1250 
1251  switch_sleep(1000000);
1252  if (!argv || !argv[0] || execv(argv[0], argv) == -1) {
1253  fprintf(stderr, "Restart Failed [%s] resorting to plan b\n", strerror(errno));
1254  for (j = 0; j < argc; j++) {
1255  switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[j]);
1256  }
1257  ret = system(buf);
1258  }
1259  }
1260 
1261  return ret;
1262 }
1263 
1264 
1265 /* For Emacs:
1266  * Local Variables:
1267  * mode:c
1268  * indent-tabs-mode:t
1269  * tab-width:4
1270  * c-basic-offset:4
1271  * End:
1272  * For VIM:
1273  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
1274  */
int32_t change_user_group(const char *user, const char *group)
Change user and/or group of the running process.
Definition: switch_core.c:1083
#define SWITCH_FOPEN_TRUNCATE
Definition: switch_apr.h:773
switch_status_t switch_file_write(switch_file_t *thefile, const void *buf, switch_size_t *nbytes)
Definition: switch_apr.c:462
#define SWITCH_CHANNEL_LOG
static void handle_SIGILL(int sig)
Definition: switch.c:85
const char * switch_version_full(void)
#define SWITCH_FOPEN_READ
Definition: switch_apr.h:769
static void reincarnate_handle_sigterm(int sig)
Definition: switch.c:359
void switch_sleep(switch_interval_time_t t)
Definition: switch_time.c:640
int32_t set_low_priority(void)
Definition: switch_core.c:945
switch_bool_t
Definition: switch_types.h:437
#define SWITCH_FLOCK_EXCLUSIVE
Definition: switch_apr.h:749
static void handle_SIGTERM(int sig)
Definition: switch.c:94
switch_memory_pool_t * pool
static int freeswitch_kill_background(void)
Definition: switch.c:104
static void reincarnate_protect(char **argv)
Definition: switch.c:365
void switch_core_set_globals(void)
Initiate Globals.
Definition: switch_core.c:633
switch_status_t switch_core_destroy(void)
Destroy the core.
Definition: switch_core.c:3020
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
uint32_t switch_core_flag_t
Definition: switch_types.h:395
static switch_bool_t is_option(const char *p)
Definition: switch.c:481
static const char usage[]
Definition: switch.c:419
int32_t set_auto_priority(void)
Definition: switch_core.c:1065
static void daemonize(int *fds)
Definition: switch.c:254
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:124
switch_byte_t switch_byte_t * buf
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
static int system_ready
Definition: switch.c:58
switch_status_t switch_core_init_and_modload(_In_ switch_core_flag_t flags, _In_ switch_bool_t console, _Out_ const char **err)
Initilize the core and load modules.
#define switch_strlen_zero(x)
Definition: switch_utils.h:316
void switch_core_setrlimits(void)
Definition: switch_core.c:1322
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:584
#define SWITCH_SYSTEM_THREAD_STACKSIZE
Definition: switch_types.h:585
int32_t set_normal_priority(void)
Set the maximum priority the process can obtain.
Definition: switch_core.c:1060
static pid_t reincarnate_child
Definition: switch.c:358
#define SWITCH_FPROT_UWRITE
Definition: switch_apr.h:713
char * switch_strerror_r(int errnum, char *buf, switch_size_t buflen)
uintptr_t switch_size_t
switch_filenames SWITCH_GLOBAL_filenames
Definition: switch_core.c:83
void switch_core_runtime_loop(int bg)
Run endlessly until the system is shutdown.
Definition: switch_core.c:1187
int main(int argc, char *argv[])
Definition: switch.c:490
#define PIDFILE
Definition: switch.c:56
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
#define SWITCH_FPROT_UREAD
Definition: switch_apr.h:712
switch_status_t switch_file_read(switch_file_t *thefile, void *buf, switch_size_t *nbytes)
Definition: switch_apr.c:457
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:82
int32_t set_realtime_priority(void)
Definition: switch_core.c:981
#define SWITCH_DEFAULT_DIR_PERMS
Definition: switch_types.h:120
switch_status_t
Common return values.
const char *const const char *const path
switch_status_t switch_dir_make_recursive(const char *path, switch_fileperms_t perm, switch_memory_pool_t *pool)
Definition: switch_apr.c:551
#define FALSE
Main Library Header.
struct fspr_file_t switch_file_t
Definition: switch_apr.h:685
#define SWITCH_FLOCK_NONBLOCK
Definition: switch_apr.h:758
switch_status_t switch_file_lock(switch_file_t *thefile, int type)
Definition: switch_apr.c:442
static int check_fd(int fd, int ms)
Definition: switch.c:230
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static char * pfile
Definition: switch.c:57
struct fspr_pool_t switch_memory_pool_t
switch_status_t switch_file_open(switch_file_t **newf, const char *fname, int32_t flag, switch_fileperms_t perm, switch_memory_pool_t *pool)
Definition: switch_apr.c:411
int32_t switch_core_set_process_privileges(void)
Switch on the privilege awareness for the process and request required privileges.
Definition: switch_core.c:910
#define SWITCH_FOPEN_CREATE
Definition: switch_apr.h:771
const char * switch_version_revision_human(void)
int32_t switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
send a control message to the core
Definition: switch_core.c:2651
switch_status_t switch_file_close(switch_file_t *thefile)
Definition: switch_apr.c:432
#define switch_assert(expr)
pid_t switch_fork(void)
Definition: switch_core.c:3282
#define SWITCH_FOPEN_WRITE
Definition: switch_apr.h:770
memset(buf, 0, buflen)