00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef WIN32
00021 #pragma warning (disable : 4786)
00022 #endif
00023
00024 #include "JackServerGlobals.h"
00025 #include "JackError.h"
00026 #include "JackTools.h"
00027 #include "shm.h"
00028 #include <getopt.h>
00029
00030 #ifndef WIN32
00031 #include <dirent.h>
00032 #endif
00033
00034 static char* server_name = NULL;
00035
00036 namespace Jack
00037 {
00038
00039 unsigned int JackServerGlobals::fClientCount = 0;
00040 JackServer* JackServerGlobals::fServer = NULL;
00041
00042 int JackServerGlobals::Start(const char* server_name,
00043 jack_driver_desc_t* driver_desc,
00044 JSList* driver_params,
00045 int sync,
00046 int temporary,
00047 int time_out_ms,
00048 int rt,
00049 int priority,
00050 int loopback,
00051 int verbose)
00052 {
00053 JackLog("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld \n", sync, time_out_ms, rt, priority, verbose);
00054 fServer = new JackServer(sync, temporary, time_out_ms, rt, priority, loopback, verbose, server_name);
00055 int res = fServer->Open(driver_desc, driver_params);
00056 return (res < 0) ? res : fServer->Start();
00057 }
00058
00059 int JackServerGlobals::Stop()
00060 {
00061 fServer->Stop();
00062 fServer->Close();
00063 JackLog("Jackdmp: server close\n");
00064 delete fServer;
00065 JackLog("Jackdmp: delete server\n");
00066 return 0;
00067 }
00068
00069 int JackServerGlobals::Delete()
00070 {
00071 delete fServer;
00072 JackLog("Jackdmp: delete server\n");
00073 return 0;
00074 }
00075
00076 bool JackServerGlobals::Init()
00077 {
00078 if (fClientCount++ == 0) {
00079
00080 JackLog("JackServerGlobals Init\n");
00081 int realtime = 0;
00082 int client_timeout = 0;
00083 int realtime_priority = 10;
00084 int verbose_aux = 0;
00085 int do_mlock = 1;
00086 unsigned int port_max = 128;
00087 int loopback = 0;
00088 int do_unlock = 0;
00089 int temporary = 0;
00090
00091 jack_driver_desc_t* driver_desc;
00092 const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:";
00093 static struct option long_options[] = {
00094 { "driver", 1, 0, 'd'},
00095 { "verbose", 0, 0, 'v' },
00096 { "help", 0, 0, 'h' },
00097 { "port-max", 1, 0, 'p' },
00098 { "no-mlock", 0, 0, 'm' },
00099 { "name", 0, 0, 'n' },
00100 { "unlock", 0, 0, 'u' },
00101 { "realtime", 0, 0, 'R' },
00102 { "loopback", 0, 0, 'L' },
00103 { "realtime-priority", 1, 0, 'P' },
00104 { "timeout", 1, 0, 't' },
00105 { "temporary", 0, 0, 'T' },
00106 { "version", 0, 0, 'V' },
00107 { "silent", 0, 0, 's' },
00108 { "sync", 0, 0, 'S' },
00109 { 0, 0, 0, 0 }
00110 };
00111 int opt = 0;
00112 int option_index = 0;
00113 int seen_driver = 0;
00114 char *driver_name = NULL;
00115 char **driver_args = NULL;
00116 JSList* driver_params;
00117 int driver_nargs = 1;
00118 JSList* drivers = NULL;
00119 int show_version = 0;
00120 int sync = 0;
00121 int rc, i;
00122 int ret;
00123
00124 FILE* fp = 0;
00125 char filename[255];
00126 char buffer[255];
00127 int argc = 0;
00128 char* argv[32];
00129
00130 snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
00131 fp = fopen(filename, "r");
00132
00133 if (!fp) {
00134 fp = fopen("/etc/jackdrc", "r");
00135 }
00136
00137 if (!fp) {
00138 fp = fopen("/etc/jackd.conf", "r");
00139 }
00140
00141 argc = 0;
00142 if (fp) {
00143 ret = fscanf(fp, "%s", buffer);
00144 while (ret != 0 && ret != EOF) {
00145 argv[argc] = (char*)malloc(64);
00146 strcpy(argv[argc], buffer);
00147 ret = fscanf(fp, "%s", buffer);
00148 argc++;
00149 }
00150 fclose(fp);
00151 }
00152
00153
00154
00155
00156
00157
00158
00159 opterr = 0;
00160 optind = 1;
00161
00162 while (!seen_driver &&
00163 (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) {
00164
00165 switch (opt) {
00166
00167 case 'd':
00168 seen_driver = 1;
00169 driver_name = optarg;
00170 break;
00171
00172 case 'v':
00173 verbose_aux = 1;
00174 break;
00175
00176 case 'S':
00177 sync = 1;
00178 break;
00179
00180 case 'n':
00181 server_name = optarg;
00182 break;
00183
00184 case 'm':
00185 do_mlock = 0;
00186 break;
00187
00188 case 'p':
00189 port_max = (unsigned int)atol(optarg);
00190 break;
00191
00192 case 'P':
00193 realtime_priority = atoi(optarg);
00194 break;
00195
00196 case 'R':
00197 realtime = 1;
00198 break;
00199
00200 case 'L':
00201 loopback = atoi(optarg);
00202 break;
00203
00204 case 'T':
00205 temporary = 1;
00206 break;
00207
00208 case 't':
00209 client_timeout = atoi(optarg);
00210 break;
00211
00212 case 'u':
00213 do_unlock = 1;
00214 break;
00215
00216 case 'V':
00217 show_version = 1;
00218 break;
00219
00220 default:
00221 fprintf(stderr, "unknown option character %c\n", optopt);
00222 break;
00223 }
00224 }
00225
00226 drivers = jack_drivers_load(drivers);
00227 if (!drivers) {
00228 fprintf(stderr, "jackdmp: no drivers found; exiting\n");
00229 goto error;
00230 }
00231
00232 driver_desc = jack_find_driver_descriptor(drivers, driver_name);
00233 if (!driver_desc) {
00234 fprintf(stderr, "jackdmp: unknown driver '%s'\n", driver_name);
00235 goto error;
00236 }
00237
00238 if (optind < argc) {
00239 driver_nargs = 1 + argc - optind;
00240 } else {
00241 driver_nargs = 1;
00242 }
00243
00244 if (driver_nargs == 0) {
00245 fprintf(stderr, "No driver specified ... hmm. JACK won't do"
00246 " anything when run like this.\n");
00247 goto error;
00248 }
00249
00250 driver_args = (char**)malloc(sizeof(char*) * driver_nargs);
00251 driver_args[0] = driver_name;
00252
00253 for (i = 1; i < driver_nargs; i++) {
00254 driver_args[i] = argv[optind++];
00255 }
00256
00257 if (jack_parse_driver_params(driver_desc, driver_nargs, driver_args, &driver_params)) {
00258 goto error;
00259 }
00260
00261 #ifndef WIN32
00262 if (server_name == NULL)
00263 server_name = (char*)JackTools::DefaultServerName();
00264 #endif
00265
00266 rc = jack_register_server(server_name, false);
00267 switch (rc) {
00268 case EEXIST:
00269 fprintf(stderr, "`%s' server already active\n", server_name);
00270 goto error;
00271 case ENOSPC:
00272 fprintf(stderr, "too many servers already active\n");
00273 goto error;
00274 case ENOMEM:
00275 fprintf(stderr, "no access to shm registry\n");
00276 goto error;
00277 default:
00278 if (jack_verbose)
00279 fprintf(stderr, "server `%s' registered\n", server_name);
00280 }
00281
00282
00283 jack_cleanup_shm();
00284 #ifndef WIN32
00285 JackTools::CleanupFiles(server_name);
00286 #endif
00287
00288 if (!realtime && client_timeout == 0)
00289 client_timeout = 500;
00290
00291 for (i = 0; i < argc; i++) {
00292 free(argv[i]);
00293 }
00294
00295 int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, loopback, verbose_aux);
00296 if (res < 0) {
00297 jack_error("Cannot start server... exit");
00298 Delete();
00299 jack_cleanup_shm();
00300 #ifndef WIN32
00301 JackTools::CleanupFiles(server_name);
00302 #endif
00303 jack_unregister_server(server_name);
00304 goto error;
00305 }
00306 }
00307
00308 return true;
00309
00310 error:
00311 fClientCount--;
00312 return false;
00313 }
00314
00315 void JackServerGlobals::Destroy()
00316 {
00317 if (--fClientCount == 0) {
00318 JackLog("JackServerGlobals Destroy\n");
00319 Stop();
00320 jack_cleanup_shm();
00321 #ifndef WIN32
00322 JackTools::CleanupFiles(server_name);
00323 #endif
00324 jack_unregister_server(server_name);
00325 }
00326 }
00327
00328 }
00329
00330