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