37 #define _XOPEN_SOURCE 600
43 #include <sys/resource.h>
48 #include <sys/prctl.h>
55 #define PIDFILE "freeswitch.pid"
61 #pragma warning (disable:167)
66 #define SERVICENAME_DEFAULT "FreeSWITCH"
67 #define SERVICENAME_MAXLEN 256
68 static char service_name[SERVICENAME_MAXLEN];
74 static HANDLE shutdown_event;
97 char path[PATH_MAX] =
"";
107 if ((f = fopen(path,
"r")) == 0) {
109 fprintf(stderr,
"Cannot open pid file %s.\n", path);
114 if (fscanf(f,
"%d", (
int *) (intptr_t) & pid) != 1) {
122 fprintf(stderr,
"Killing: %d\n", (
int) pid);
125 snprintf(path,
sizeof(path),
"Global\\Freeswitch.%d", pid);
128 shutdown_event = OpenEvent(EVENT_MODIFY_STATE,
FALSE, path);
131 if (!shutdown_event) {
133 fprintf(stderr,
"ERROR: Can't Shutdown: %d\n", (
int) pid);
136 SetEvent(shutdown_event);
138 CloseHandle(shutdown_event);
155 SERVICE_STATUS_HANDLE hStatus;
156 SERVICE_STATUS status;
159 void WINAPI ServiceCtrlHandler(DWORD control)
162 case SERVICE_CONTROL_SHUTDOWN:
163 case SERVICE_CONTROL_STOP:
167 status.dwCurrentState = SERVICE_STOPPED;
168 status.dwWin32ExitCode = 0;
169 status.dwCheckPoint = 0;
170 status.dwWaitHint = 0;
172 case SERVICE_CONTROL_INTERROGATE:
178 SetServiceStatus(hStatus, &status);
182 void WINAPI service_main(DWORD numArgs,
char **args)
185 const char *err = NULL;
189 flags = service_flags;
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;
198 hStatus = RegisterServiceCtrlHandler(service_name, &ServiceCtrlHandler);
201 SetServiceStatus(hStatus, &status);
208 status.dwCurrentState = SERVICE_STOPPED;
211 status.dwCurrentState = SERVICE_RUNNING;
215 SetServiceStatus(hStatus, &status);
222 struct pollfd pfds[2] = { { 0 } };
226 pfds[0].events = POLLIN | POLLERR;
227 s = poll(pfds, 1, ms);
229 if (s == 0 || s == -1) {
234 if ((pfds[0].revents & POLLIN)) {
235 if ((i = read(fd, &r,
sizeof(r))) > -1) {
236 (void)write(fd, &r,
sizeof(r));
248 unsigned int sanity = 60;
255 fprintf(stderr,
"Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno));
263 fprintf(stderr,
"Error Backgrounding (setsid)! %d - %s\n", errno, strerror(errno));
277 fprintf(stderr,
"Error Backgrounding (fork2)! %d - %s\n", errno, strerror(errno));
281 fprintf(stderr,
"%d Backgrounding.\n", (
int) pid);
288 if ((o = getenv(
"FREESWITCH_BG_TIMEOUT"))) {
299 printf(
"FreeSWITCH[%d] Waiting for background process pid:%d to be ready.....\n", (
int)getpid(), (
int) pid);
310 printf(
"FreeSWITCH[%d] Error starting system! pid:%d\n", (
int)getpid(), (
int) pid);
315 printf(
"FreeSWITCH[%d] System Ready pid:%d\n", (
int) getpid(), (
int) pid);
325 fd = open(
"/dev/null", O_RDONLY);
332 fd = open(
"/dev/null", O_WRONLY);
339 fd = open(
"/dev/null", O_WRONLY);
351 if (reincarnate_child) kill(reincarnate_child, sig);
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));
359 sa_dfl.sa_handler = SIG_DFL;
363 reincarnate_child = i;
364 sigaction(SIGILL, &sa, &sa4_prev);
365 sigaction(SIGTERM, &sa, &sa15_prev);
366 sigaction(SIGCHLD, &sa_dfl, &sa17_prev);
368 r = waitpid(i, &s, 0);
369 if (r == (pid_t)-1) {
370 if (errno == EINTR)
goto rewait;
373 if (r != i)
goto rewait;
375 && (WEXITSTATUS(s) == EXIT_SUCCESS
376 || WEXITSTATUS(s) == EXIT_FAILURE)) {
377 exit(WEXITSTATUS(s));
379 if (WIFEXITED(s) || WIFSIGNALED(s)) {
380 sigaction(SIGILL, &sa4_prev, NULL);
381 sigaction(SIGTERM, &sa15_prev, NULL);
382 sigaction(SIGCHLD, &sa17_prev, NULL);
384 if (execv(argv[0], argv) == -1) {
386 fprintf(stderr,
"Reincarnate execv() failed: %d %s\n", errno,
389 fprintf(stderr,
"Trying reincarnate-reexec plan B...\n");
390 if (execvp(argv[0], argv) == -1) {
392 fprintf(stderr,
"Reincarnate execvp() failed: %d %s\n", errno,
395 fprintf(stderr,
"Falling back to normal reincarnate behavior...\n");
402 prctl(PR_SET_PDEATHSIG, SIGTERM);
410 "Usage: freeswitch [OPTIONS]\n\n"
411 "These are the optional arguments you can pass to freeswitch:\n"
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"
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"
424 #ifdef HAVE_SETRLIMIT
426 "\t-waste -- allow memory waste\n"
428 "\t-core -- dump cores\n"
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"
445 "\t-ncwait -- do not output to a console and background but wait until the system is ready before exiting (implies -nc)\n"
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";
473 while ((*p == 13) || (*p == 10) || (*p == 9) || (*p == 32) || (*p == 11)) p++;
474 return (p[0] ==
'-');
479 int main(
int argc,
char *argv[])
481 char pid_path[PATH_MAX] =
"";
482 char pid_buffer[32] =
"";
483 char old_pid_buffer[32] = { 0 };
485 const char *err = NULL;
489 char *runas_user = NULL;
490 char *runas_group = NULL;
492 int fds[2] = { 0, 0 };
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;
516 #ifdef HAVE_SETRLIMIT
522 for (x = 0; x < argc; x++) {
523 local_argv[x] = argv[x];
526 if ((opts = getenv(
"FREESWITCH_OPTS"))) {
527 strncpy(opts_str, opts,
sizeof(opts_str) - 1);
529 for (x = 0; x < i; x++) {
530 local_argv[local_argc++] = arg_argv[x];
534 if (local_argv[0] && strstr(local_argv[0],
"freeswitchd")) {
538 for (x = 1; x < local_argc; x++) {
543 if (!strcmp(local_argv[x],
"-help") || !strcmp(local_argv[x],
"-h") || !strcmp(local_argv[x],
"-?")) {
544 printf(
"%s\n", usage);
548 if (x == 1 && !strcmp(local_argv[x],
"-service")) {
561 else if (x == 1 && !strcmp(local_argv[x],
"-install")) {
562 char servicePath[PATH_MAX];
563 char exePath[PATH_MAX];
565 SC_HANDLE hSCManager;
566 SERVICE_DESCRIPTION desc;
567 desc.lpDescription =
"The FreeSWITCH service.";
576 GetModuleFileName(NULL, exePath,
sizeof(exePath));
577 snprintf(servicePath,
sizeof(servicePath),
"%s -service %s", exePath, service_name);
581 hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
583 fprintf(stderr,
"Could not open service manager (%u).\n", GetLastError());
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, NULL);
590 fprintf(stderr,
"Error creating freeswitch service (%u).\n", GetLastError());
591 CloseServiceHandle(hSCManager);
596 if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc)) {
597 fprintf(stderr,
"FreeSWITCH installed, but could not set the service description (%u).\n", GetLastError());
600 CloseServiceHandle(hService);
601 CloseServiceHandle(hSCManager);
605 else if (x == 1 && !strcmp(local_argv[x],
"-uninstall")) {
607 SC_HANDLE hSCManager;
618 hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
620 fprintf(stderr,
"Could not open service manager (%u).\n", GetLastError());
624 hService = OpenService(hSCManager, service_name, DELETE);
626 fprintf(stderr,
"Error opening service (%u).\n", GetLastError());
627 CloseServiceHandle(hSCManager);
632 deleted = DeleteService(hService);
634 fprintf(stderr,
"Error deleting service (%u).\n", GetLastError());
637 CloseServiceHandle(hService);
638 CloseServiceHandle(hSCManager);
639 exit(deleted ? EXIT_SUCCESS : EXIT_FAILURE);
642 else if (!strcmp(local_argv[x],
"-monotonic-clock")) {
646 else if (!strcmp(local_argv[x],
"-u")) {
649 fprintf(stderr,
"Option '%s' requires an argument!\n", local_argv[x - 1]);
652 runas_user = local_argv[x];
655 else if (!strcmp(local_argv[x],
"-g")) {
658 fprintf(stderr,
"Option '%s' requires an argument!\n", local_argv[x - 1]);
661 runas_group = local_argv[x];
664 else if (!strcmp(local_argv[x],
"-nf")) {
668 else if (!strcmp(local_argv[x],
"-reincarnate")) {
671 else if (!strcmp(local_argv[x],
"-reincarnate-reexec")) {
676 else if (!strcmp(local_argv[x],
"-version")) {
681 #ifdef HAVE_SETRLIMIT
682 else if (!strcmp(local_argv[x],
"-core")) {
684 memset(&rlp, 0,
sizeof(rlp));
685 rlp.rlim_cur = RLIM_INFINITY;
686 rlp.rlim_max = RLIM_INFINITY;
687 setrlimit(RLIMIT_CORE, &rlp);
690 else if (!strcmp(local_argv[x],
"-waste")) {
692 fprintf(stderr,
"WARNING: Wasting up to 8 megs of memory per thread.\n");
698 else if (!strcmp(local_argv[x],
"-no-auto-stack")) {
704 else if (!strcmp(local_argv[x],
"-hp") || !strcmp(local_argv[x],
"-rp")) {
708 else if (!strcmp(local_argv[x],
"-lp")) {
712 else if (!strcmp(local_argv[x],
"-np")) {
716 else if (!strcmp(local_argv[x],
"-nosql")) {
720 else if (!strcmp(local_argv[x],
"-nonat")) {
724 else if (!strcmp(local_argv[x],
"-nonatmap")) {
728 else if (!strcmp(local_argv[x],
"-heavy-timer")) {
732 else if (!strcmp(local_argv[x],
"-nort")) {
736 else if (!strcmp(local_argv[x],
"-nocal")) {
740 else if (!strcmp(local_argv[x],
"-vg")) {
744 else if (!strcmp(local_argv[x],
"-stop")) {
748 else if (!strcmp(local_argv[x],
"-nc")) {
752 else if (!strcmp(local_argv[x],
"-ncwait")) {
757 else if (!strcmp(local_argv[x],
"-c")) {
761 else if (!strcmp(local_argv[x],
"-conf")) {
764 fprintf(stderr,
"When using -conf you must specify a config directory\n");
770 fprintf(stderr,
"Allocation error\n");
777 else if (!strcmp(local_argv[x],
"-mod")) {
780 fprintf(stderr,
"When using -mod you must specify a module directory\n");
786 fprintf(stderr,
"Allocation error\n");
792 else if (!strcmp(local_argv[x],
"-log")) {
795 fprintf(stderr,
"When using -log you must specify a log directory\n");
801 fprintf(stderr,
"Allocation error\n");
809 else if (!strcmp(local_argv[x],
"-run")) {
812 fprintf(stderr,
"When using -run you must specify a pid directory\n");
818 fprintf(stderr,
"Allocation error\n");
825 else if (!strcmp(local_argv[x],
"-db")) {
828 fprintf(stderr,
"When using -db you must specify a db directory\n");
834 fprintf(stderr,
"Allocation error\n");
841 else if (!strcmp(local_argv[x],
"-scripts")) {
844 fprintf(stderr,
"When using -scripts you must specify a scripts directory\n");
850 fprintf(stderr,
"Allocation error\n");
856 else if (!strcmp(local_argv[x],
"-htdocs")) {
859 fprintf(stderr,
"When using -htdocs you must specify a htdocs directory\n");
865 fprintf(stderr,
"Allocation error\n");
871 else if (!strcmp(local_argv[x],
"-base")) {
874 fprintf(stderr,
"When using -base you must specify a base directory\n");
880 fprintf(stderr,
"Allocation error\n");
887 else if (!strcmp(local_argv[x],
"-temp")) {
890 fprintf(stderr,
"When using -temp you must specify a temp directory\n");
896 fprintf(stderr,
"Allocation error\n");
902 else if (!strcmp(local_argv[x],
"-storage")) {
905 fprintf(stderr,
"When using -storage you must specify a storage directory\n");
911 fprintf(stderr,
"Allocation error\n");
917 else if (!strcmp(local_argv[x],
"-cache")) {
920 fprintf(stderr,
"When using -cache you must specify a cache directory\n");
926 fprintf(stderr,
"Allocation error\n");
932 else if (!strcmp(local_argv[x],
"-recordings")) {
935 fprintf(stderr,
"When using -recordings you must specify a recording directory\n");
941 fprintf(stderr,
"Allocation error\n");
947 else if (!strcmp(local_argv[x],
"-grammar")) {
950 fprintf(stderr,
"When using -grammar you must specify a grammar directory\n");
956 fprintf(stderr,
"Allocation error\n");
962 else if (!strcmp(local_argv[x],
"-certs")) {
965 fprintf(stderr,
"When using -certs you must specify a certificates directory\n");
971 fprintf(stderr,
"Allocation error\n");
977 else if (!strcmp(local_argv[x],
"-sounds")) {
980 fprintf(stderr,
"When using -sounds you must specify a sounds directory\n");
986 fprintf(stderr,
"Allocation error\n");
992 else if (!strcmp(local_argv[x],
"-cfgname")) {
995 fprintf(stderr,
"When using -cfgname you must specify a filename\n");
1001 fprintf(stderr,
"Allocation error\n");
1009 fprintf(stderr,
"Unknown option '%s', see '%s -help' for a list of valid options\n",
1010 local_argv[x], local_argv[0]);
1015 if (log_set && !run_set) {
1018 fprintf(stderr,
"Allocation error\n");
1029 fprintf(stderr,
"FATAL ERROR! Could not initialize APR\n");
1033 if (alt_dirs && alt_dirs != 3 && !alt_base) {
1034 fprintf(stderr,
"You must specify all or none of -conf, -log, and -db\n");
1039 #if defined(HAVE_SETRLIMIT) && !defined(__sun)
1040 if (!waste && !(flags &
SCF_VG)) {
1043 memset(&rlp, 0,
sizeof(rlp));
1044 getrlimit(RLIMIT_STACK, &rlp);
1047 char buf[1024] =
"";
1050 memset(&rlp, 0,
sizeof(rlp));
1053 setrlimit(RLIMIT_STACK, &rlp);
1056 if (argv) ret = (int) execv(argv[0], argv);
1058 for (i = 0; i < argc; i++) {
1059 switch_snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf),
"%s ", argv[i]);
1072 fprintf(stderr,
"System Error!\n");
1115 if (runas_user || runas_group) {
1117 fprintf(stderr,
"Failed to switch user [%s] / group [%s]\n",
1124 if (win32_service) {
1126 SERVICE_TABLE_ENTRY dispatchTable[] = {
1127 {service_name, &service_main}
1131 service_flags = flags;
1133 if (StartServiceCtrlDispatcher(dispatchTable) == 0) {
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");
1146 memset(pid_buffer, 0,
sizeof(pid_buffer));
1149 pid_len = strlen(pid_buffer);
1151 apr_pool_create(&pool, NULL);
1157 old_pid_len =
sizeof(old_pid_buffer) -1;
1166 fprintf(stderr,
"Cannot open pid file %s.\n", pid_path);
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)) {
1182 fprintf(stderr,
"Cannot Initialize [%s]\n", err);
1191 if ((i = write(fds[1], &v,
sizeof(v))) < 0) {
1192 fprintf(stderr,
"System Error [%s]\n", strerror(errno));
1194 (void)read(fds[1], &v,
sizeof(v));
1197 shutdown(fds[1], 2);
1213 apr_pool_destroy(pool);
1215 if (unlink(pid_path) != 0) {
1216 fprintf(stderr,
"Failed to delete pid file [%s]\n", pid_path);
1220 char buf[1024] = { 0 };
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]);
int32_t change_user_group(const char *user, const char *group)
Change user and/or group of the running process.
#define SWITCH_FOPEN_TRUNCATE
switch_status_t switch_file_write(switch_file_t *thefile, const void *buf, switch_size_t *nbytes)
#define SWITCH_CHANNEL_LOG
static void handle_SIGILL(int sig)
const char * switch_version_full(void)
#define SWITCH_FOPEN_READ
static void reincarnate_handle_sigterm(int sig)
void switch_sleep(switch_interval_time_t t)
int32_t set_low_priority(void)
#define SWITCH_FLOCK_EXCLUSIVE
switch_memory_pool_t * pool
static void reincarnate_protect(char **argv)
void switch_core_set_globals(void)
Initiate Globals.
switch_status_t switch_core_destroy(void)
Destroy the core.
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
static switch_bool_t is_option(const char *p)
static const char usage[]
int32_t set_auto_priority(void)
static void daemonize(int *fds)
#define SWITCH_PATH_SEPARATOR
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.
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)
void switch_core_setrlimits(void)
#define SWITCH_THREAD_STACKSIZE
#define SWITCH_SYSTEM_THREAD_STACKSIZE
int32_t set_normal_priority(void)
Set the maximum priority the process can obtain.
static pid_t reincarnate_child
#define SWITCH_FPROT_UWRITE
char * switch_strerror_r(int errnum, char *buf, switch_size_t buflen)
switch_filenames SWITCH_GLOBAL_filenames
void switch_core_runtime_loop(int bg)
Run endlessly until the system is shutdown.
int main(int argc, char *argv[])
struct apr_file_t switch_file_t
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
switch_status_t switch_file_read(switch_file_t *thefile, void *buf, switch_size_t *nbytes)
switch_directories SWITCH_GLOBAL_dirs
int32_t set_realtime_priority(void)
static int freeswitch_kill_background()
#define SWITCH_DEFAULT_DIR_PERMS
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)
#define SWITCH_FLOCK_NONBLOCK
switch_status_t switch_file_lock(switch_file_t *thefile, int type)
static int check_fd(int fd, int ms)
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.
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)
int32_t switch_core_set_process_privileges(void)
Switch on the privilege awareness for the process and request required privileges.
#define SWITCH_FOPEN_CREATE
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
switch_status_t switch_file_close(switch_file_t *thefile)
#define SWITCH_FOPEN_WRITE