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 "shm.h"
00027 #include <getopt.h>
00028
00029 #ifndef WIN32
00030 #include <dirent.h>
00031 #endif
00032
00033 #define DEFAULT_TMP_DIR "/tmp"
00034 char* jack_tmpdir = DEFAULT_TMP_DIR;
00035 static char* server_name = "default";
00036 static int realtime = 0;
00037 static int client_timeout = 0;
00038 static int realtime_priority = 10;
00039 static int verbose_aux = 0;
00040 static int do_mlock = 1;
00041 static unsigned int port_max = 128;
00042 static int loopback = 0;
00043 static int do_unlock = 0;
00044 static int temporary = 0;
00045
00046 namespace Jack
00047 {
00048
00049 JackServerGlobals* JackServerGlobals::fGlobals = NULL;
00050 long JackServerGlobals::fClientCount = 0;
00051 JackServer* JackServerGlobals::fServer = NULL;
00052
00053 #ifndef WIN32
00054
00055 static char* jack_default_server_name(void)
00056 {
00057 char *server_name;
00058 if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL)
00059 server_name = "default";
00060 return server_name;
00061 }
00062
00063
00064 static char* jack_user_dir(void)
00065 {
00066 static char user_dir[PATH_MAX] = "";
00067
00068
00069 if (user_dir[0] == '\0') {
00070 snprintf (user_dir, sizeof (user_dir), "%s/jack-%d",
00071 jack_tmpdir, getuid ());
00072 }
00073
00074 return user_dir;
00075 }
00076
00077
00078
00079 static char* get_jack_server_dir(const char* toto)
00080 {
00081 static char server_dir[PATH_MAX] = "";
00082
00083
00084 if (server_dir[0] == '\0') {
00085 snprintf (server_dir, sizeof (server_dir), "%s/%s",
00086 jack_user_dir (), server_name);
00087 }
00088
00089 return server_dir;
00090 }
00091
00092 static void
00093 jack_cleanup_files (const char *server_name)
00094 {
00095 DIR *dir;
00096 struct dirent *dirent;
00097 char *dir_name = get_jack_server_dir (server_name);
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 if ((dir = opendir (dir_name)) == NULL) {
00117 return ;
00118 }
00119
00120
00121 while ((dirent = readdir (dir)) != NULL) {
00122
00123 char fullpath[PATH_MAX];
00124
00125 if ((strcmp (dirent->d_name, ".") == 0)
00126 || (strcmp (dirent->d_name, "..") == 0)) {
00127 continue;
00128 }
00129
00130 snprintf (fullpath, sizeof (fullpath), "%s/%s",
00131 dir_name, dirent->d_name);
00132
00133 if (unlink (fullpath)) {
00134 jack_error ("cannot unlink `%s' (%s)", fullpath,
00135 strerror (errno));
00136 }
00137 }
00138
00139 closedir (dir);
00140
00141
00142 if (rmdir (dir_name)) {
00143 jack_error ("cannot remove `%s' (%s)", dir_name,
00144 strerror (errno));
00145 }
00146
00147
00148 if (rmdir (jack_user_dir ())) {
00149 if (errno != ENOTEMPTY) {
00150 jack_error ("cannot remove `%s' (%s)",
00151 jack_user_dir (), strerror (errno));
00152 }
00153 }
00154 }
00155
00156 #endif
00157
00158 int JackServerGlobals::JackStart(jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, int time_out_ms, int rt, int priority, int loopback, int verbose)
00159 {
00160 JackLog("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld \n", sync, time_out_ms, rt, priority, verbose);
00161 fServer = new JackServer(sync, time_out_ms, rt, priority, loopback, verbose);
00162 int res = fServer->Open(driver_desc, driver_params);
00163 return (res < 0) ? res : fServer->Start();
00164 }
00165
00166 int JackServerGlobals::JackStop()
00167 {
00168 fServer->Stop();
00169 fServer->Close();
00170 JackLog("Jackdmp: server close\n");
00171 delete fServer;
00172 JackLog("Jackdmp: delete server\n");
00173 return 0;
00174 }
00175
00176 int JackServerGlobals::JackDelete()
00177 {
00178 delete fServer;
00179 JackLog("Jackdmp: delete server\n");
00180 return 0;
00181 }
00182
00183
00184
00185 JackServerGlobals::JackServerGlobals()
00186 {
00187 jack_driver_desc_t* driver_desc;
00188 const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:";
00189 struct option long_options[] = {
00190 { "driver", 1, 0, 'd'
00191 },
00192 { "verbose", 0, 0, 'v' },
00193 { "help", 0, 0, 'h' },
00194 { "port-max", 1, 0, 'p' },
00195 { "no-mlock", 0, 0, 'm' },
00196 { "name", 0, 0, 'n' },
00197 { "unlock", 0, 0, 'u' },
00198 { "realtime", 0, 0, 'R' },
00199 { "loopback", 0, 0, 'L' },
00200 { "realtime-priority", 1, 0, 'P' },
00201 { "timeout", 1, 0, 't' },
00202 { "temporary", 0, 0, 'T' },
00203 { "version", 0, 0, 'V' },
00204 { "silent", 0, 0, 's' },
00205 { "sync", 0, 0, 'S' },
00206 { 0, 0, 0, 0 }
00207 };
00208 int opt = 0;
00209 int option_index = 0;
00210 int seen_driver = 0;
00211 char *driver_name = NULL;
00212 char **driver_args = NULL;
00213 JSList* driver_params;
00214 int driver_nargs = 1;
00215 JSList* drivers = NULL;
00216 char* server_name = NULL;
00217 int show_version = 0;
00218 int sync = 0;
00219 int rc, i;
00220
00221 int argc = 8;
00222
00223 char* argv[] = {"jackdmp", "-R", "-S", "-v", "-d", "portaudio", "-p", "512"};
00224
00225 for (i = 0; i < argc; i++) {
00226 printf("arg %i %s\n", i, argv[i]);
00227 }
00228
00229 opterr = 0;
00230 while (!seen_driver &&
00231 (opt = getopt_long(argc, argv, options,
00232 long_options, &option_index)) != EOF) {
00233 switch (opt) {
00234
00235 case 'd':
00236 seen_driver = 1;
00237 driver_name = optarg;
00238 break;
00239
00240 case 'v':
00241 verbose_aux = 1;
00242 break;
00243
00244 case 's':
00245
00246 break;
00247
00248 case 'S':
00249 sync = 1;
00250 break;
00251
00252 case 'n':
00253 server_name = optarg;
00254 break;
00255
00256 case 'm':
00257 do_mlock = 0;
00258 break;
00259
00260 case 'p':
00261 port_max = (unsigned int)atol(optarg);
00262 break;
00263
00264 case 'P':
00265 realtime_priority = atoi(optarg);
00266 break;
00267
00268 case 'R':
00269 realtime = 1;
00270 break;
00271
00272 case 'L':
00273 loopback = atoi(optarg);
00274 break;
00275
00276 case 'T':
00277 temporary = 1;
00278 break;
00279
00280 case 't':
00281 client_timeout = atoi(optarg);
00282 break;
00283
00284 case 'u':
00285 do_unlock = 1;
00286 break;
00287
00288 case 'V':
00289 show_version = 1;
00290 break;
00291
00292 default:
00293 fprintf(stderr, "unknown option character %c\n",
00294 optopt);
00295
00296 case 'h':
00297
00298 return ;
00299 }
00300 }
00301
00302 drivers = jack_drivers_load (drivers);
00303 if (!drivers) {
00304 fprintf (stderr, "jackdmp: no drivers found; exiting\n");
00305 exit (1);
00306 }
00307
00308 driver_desc = jack_find_driver_descriptor (drivers, driver_name);
00309 if (!driver_desc) {
00310 fprintf (stderr, "jackdmp: unknown driver '%s'\n", driver_name);
00311 exit (1);
00312 }
00313
00314 if (optind < argc) {
00315 driver_nargs = 1 + argc - optind;
00316 } else {
00317 driver_nargs = 1;
00318 }
00319
00320 if (driver_nargs == 0) {
00321 fprintf (stderr, "No driver specified ... hmm. JACK won't do"
00322 " anything when run like this.\n");
00323 return ;
00324 }
00325
00326 driver_args = (char **) malloc (sizeof (char *) * driver_nargs);
00327 driver_args[0] = driver_name;
00328
00329 for (i = 1; i < driver_nargs; i++) {
00330 driver_args[i] = argv[optind++];
00331 }
00332
00333 if (jack_parse_driver_params (driver_desc, driver_nargs,
00334 driver_args, &driver_params)) {
00335 return ;
00336 }
00337
00338 #ifndef WIN32
00339 if (server_name == NULL)
00340 server_name = jack_default_server_name ();
00341 #endif
00342
00343 rc = jack_register_server (server_name);
00344
00345
00346
00347 jack_cleanup_shm();
00348 #ifndef WIN32
00349 jack_cleanup_files(server_name);
00350 #endif
00351
00352 if (!realtime && client_timeout == 0)
00353 client_timeout = 500;
00354
00355 int res = JackStart(driver_desc, driver_params, sync, client_timeout, realtime, realtime_priority, loopback, verbose_aux);
00356 if (res < 0) {
00357 jack_error("Cannot start server... exit");
00358 JackDelete();
00359 return ;
00360 }
00361 }
00362
00363 JackServerGlobals::~JackServerGlobals()
00364 {
00365 JackLog("~JackServerGlobals\n");
00366 JackStop();
00367 jack_cleanup_shm();
00368 #ifndef WIN32
00369 jack_cleanup_files(server_name);
00370 #endif
00371 jack_unregister_server(server_name);
00372 }
00373
00374 void JackServerGlobals::Init()
00375 {
00376 if (fClientCount++ == 0 && !fGlobals) {
00377 JackLog("JackServerGlobals Init %x\n", fGlobals);
00378 fGlobals = new JackServerGlobals();
00379 }
00380 }
00381
00382 void JackServerGlobals::Destroy()
00383 {
00384 if (--fClientCount == 0 && fGlobals) {
00385 JackLog("JackServerGlobals Destroy %x\n", fGlobals);
00386 delete fGlobals;
00387 fGlobals = NULL;
00388 }
00389 }
00390
00391 }
00392
00393