00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if !defined(WIN32) || defined(__CYGWIN__)
00021
00022 #ifdef PTHREAD_WIN32 // Added by JE - 13-02-2010
00023 #include <ptw32/pthread.h>
00024 #endif // consistency - even though we won't need it !
00025
00026 #include "JackConstants.h"
00027 #include "JackChannel.h"
00028 #include "JackLibGlobals.h"
00029 #include "JackServerLaunch.h"
00030 #include "JackPlatformPlug.h"
00031
00032 #include <sys/wait.h>
00033
00034 using namespace Jack;
00035
00036 #if defined(USE_LIBDBUS_AUTOLAUNCH)
00037
00038 #include <dbus/dbus.h>
00039
00040 static int start_server_dbus(const char* server_name)
00041 {
00042 DBusError err;
00043 DBusConnection *conn;
00044 DBusMessage *msg;
00045
00046
00047 dbus_error_init(&err);
00048
00049
00050 conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
00051 if (dbus_error_is_set(&err)) {
00052 fprintf(stderr, "Connection Error (%s)\n", err.message);
00053 dbus_error_free(&err);
00054 }
00055 if (NULL == conn) {
00056 return 1;
00057 }
00058
00059 msg = dbus_message_new_method_call(
00060 "org.jackaudio.service",
00061 "/org/jackaudio/Controller",
00062 "org.jackaudio.JackControl",
00063 "StartServer");
00064 if (NULL == msg) {
00065 fprintf(stderr, "Message Null\n");
00066 return 1;
00067 }
00068
00069
00070 if (!dbus_connection_send(conn, msg, NULL))
00071 {
00072 fprintf(stderr, "Out Of Memory!\n");
00073 return 1;
00074 }
00075
00076 dbus_message_unref(msg);
00077 dbus_connection_flush(conn);
00078 dbus_error_free(&err);
00079
00080 return 0;
00081 }
00082
00083 #elif defined(USE_CLASSIC_AUTOLAUNCH)
00084
00085
00086 static void start_server_classic_aux(const char* server_name)
00087 {
00088 FILE* fp = 0;
00089 char filename[255];
00090 char arguments[255];
00091 char buffer[255];
00092 char* command = 0;
00093 size_t pos = 0;
00094 size_t result = 0;
00095 char** argv = 0;
00096 int i = 0;
00097 int good = 0;
00098 int res;
00099
00100 snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
00101 fp = fopen(filename, "r");
00102
00103 if (!fp) {
00104 fp = fopen("/etc/jackdrc", "r");
00105 }
00106
00107 if (!fp) {
00108 fp = fopen("/etc/jackd.conf", "r");
00109 }
00110
00111 if (fp) {
00112 arguments[0] = '\0';
00113 res = fscanf(fp, "%s", buffer);
00114 while (res != 0 && res != EOF) {
00115 strcat(arguments, buffer);
00116 strcat(arguments, " ");
00117 res = fscanf(fp, "%s", buffer);
00118 }
00119 if (strlen(arguments) > 0) {
00120 good = 1;
00121 }
00122 fclose(fp);
00123 }
00124
00125 if (!good) {
00126 command = (char*)(JACK_LOCATION "/jackd");
00127 strncpy(arguments, JACK_LOCATION "/jackd -T -d "JACK_DEFAULT_DRIVER, 255);
00128 } else {
00129 result = strcspn(arguments, " ");
00130 command = (char*)malloc(result + 1);
00131 strncpy(command, arguments, result);
00132 command[result] = '\0';
00133 }
00134
00135 argv = (char**)malloc(255);
00136
00137 while (1) {
00138
00139 if (i == 1) {
00140 argv[i] = (char*)malloc(strlen ("-T") + 1);
00141 strcpy (argv[i++], "-T");
00142 if (server_name) {
00143 size_t optlen = strlen("-n");
00144 char* buf = (char*)malloc(optlen + strlen(server_name) + 1);
00145 strcpy(buf, "-n");
00146 strcpy(buf + optlen, server_name);
00147 argv[i++] = buf;
00148 }
00149 }
00150
00151 result = strcspn(arguments + pos, " ");
00152 if (result == 0) {
00153 break;
00154 }
00155 argv[i] = (char*)malloc(result + 1);
00156 strncpy(argv[i], arguments + pos, result);
00157 argv[i][result] = '\0';
00158 pos += result + 1;
00159 ++i;
00160 }
00161 argv[i] = 0;
00162 execv(command, argv);
00163
00164
00165
00166 fprintf(stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror(errno));
00167 }
00168
00169 static int start_server_classic(const char* server_name)
00170 {
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 int status;
00182 pid_t first_child_pid;
00183
00184 first_child_pid = fork();
00185 switch (first_child_pid) {
00186 case 0:
00187 switch (fork()) {
00188 case 0:
00189 start_server_classic_aux(server_name);
00190 _exit(99);
00191 case - 1:
00192 _exit(98);
00193 default:
00194 _exit(0);
00195 }
00196 case - 1:
00197 return 1;
00198 }
00199 waitpid(first_child_pid, &status, 0);
00200
00201
00202 return 0;
00203 }
00204
00205 #endif
00206
00207 static int start_server(const char* server_name, jack_options_t options)
00208 {
00209 if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) {
00210 return 1;
00211 }
00212
00213 #if defined(USE_LIBDBUS_AUTOLAUNCH)
00214 return start_server_dbus(server_name);
00215 #elif defined(USE_CLASSIC_AUTOLAUNCH)
00216 return start_server_classic(server_name);
00217 #else
00218 fprintf(stderr, "Automatic start of JACK server is disabled at configure time\n");
00219 return 1;
00220 #endif
00221 }
00222
00223 static int server_connect(char* server_name)
00224 {
00225 JackClientChannel channel;
00226 int res = channel.ServerCheck(server_name);
00227 channel.Close();
00228 JackSleep(2000);
00229
00230 return res;
00231 }
00232
00233 int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status)
00234 {
00235 if (server_connect(va->server_name) < 0) {
00236 int trys;
00237 if (start_server(va->server_name, options)) {
00238 int my_status1 = *status | JackFailure | JackServerFailed;
00239 *status = (jack_status_t)my_status1;
00240 return -1;
00241 }
00242 trys = 5;
00243 do {
00244 sleep(1);
00245 if (--trys < 0) {
00246 int my_status1 = *status | JackFailure | JackServerFailed;
00247 *status = (jack_status_t)my_status1;
00248 return -1;
00249 }
00250 } while (server_connect(va->server_name) < 0);
00251 int my_status1 = *status | JackServerStarted;
00252 *status = (jack_status_t)my_status1;
00253 }
00254
00255 return 0;
00256 }
00257
00258 #endif // !defined(WIN32) || defined(__CYGWIN__)