1 /* -*- mode: c; c-file-style: "bsd"; -*- */
3 Copyright (C) 2001-2005 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <sys/types.h>
36 #include <jack/engine.h>
37 #include <jack/internal.h>
38 #include <jack/driver.h>
40 #include <jack/driver_parse.h>
41 #include <jack/messagebuffer.h>
43 #ifdef USE_CAPABILITIES
46 /* capgetp and capsetp are linux only extensions, not posix */
48 #include <sys/capability.h>
49 #include <jack/start.h>
51 static struct stat pipe_stat
;
53 #endif /* USE_CAPABILITIES */
55 static JSList
*drivers
= NULL
;
56 static sigset_t signals
;
57 static jack_engine_t
*engine
= NULL
;
58 static char *server_name
= NULL
;
59 static int realtime
= 1;
60 static int realtime_priority
= 10;
61 static int do_mlock
= 1;
62 static int temporary
= 0;
63 static int verbose
= 0;
64 static int client_timeout
= 0; /* msecs; if zero, use period size. */
65 static unsigned int port_max
= 256;
66 static int do_unlock
= 0;
67 static jack_nframes_t frame_time_offset
= 0;
68 static int nozombies
= 0;
70 extern int sanitycheck (int, int);
73 do_nothing_handler (int sig
)
75 /* this is used by the child (active) process, but it never
76 gets called unless we are already shutting down after
80 snprintf (buf
, sizeof(buf
),
81 "received signal %d during shutdown (ignored)\n", sig
);
82 write (1, buf
, strlen (buf
));
86 jack_main (jack_driver_desc_t
* driver_desc
, JSList
* driver_params
)
91 struct sigaction action
;
94 /* ensure that we are in our own process group so that
95 kill (SIG, -pgrp) does the right thing.
100 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
);
104 POSIX says that signals are delivered like this:
106 * if a thread has blocked that signal, it is not
107 a candidate to receive the signal.
108 * of all threads not blocking the signal, pick
109 one at random, and deliver the signal.
111 this means that a simple-minded multi-threaded program can
112 expect to get POSIX signals delivered randomly to any one
115 here, we block all signals that we think we might receive
116 and want to catch. all "child" threads will inherit this
117 setting. if we create a thread that calls sigwait() on the
118 same set of signals, implicitly unblocking all those
119 signals. any of those signals that are delivered to the
120 process will be delivered to that thread, and that thread
121 alone. this makes cleanup for a signal-driven exit much
122 easier, since we know which thread is doing it and more
123 importantly, we are free to call async-unsafe functions,
124 because the code is executing in normal thread context
125 after a return from sigwait().
128 sigemptyset (&signals
);
129 sigaddset(&signals
, SIGHUP
);
130 sigaddset(&signals
, SIGINT
);
131 sigaddset(&signals
, SIGQUIT
);
132 sigaddset(&signals
, SIGPIPE
);
133 sigaddset(&signals
, SIGTERM
);
134 sigaddset(&signals
, SIGUSR1
);
135 sigaddset(&signals
, SIGUSR2
);
137 /* all child threads will inherit this mask unless they
138 * explicitly reset it
141 pthread_sigmask (SIG_BLOCK
, &signals
, 0);
143 if (!realtime
&& client_timeout
== 0)
144 client_timeout
= 500; /* 0.5 sec; usable when non realtime. */
146 /* get the engine/driver started */
148 if ((engine
= jack_engine_new (realtime
, realtime_priority
,
149 do_mlock
, do_unlock
, server_name
,
150 temporary
, verbose
, client_timeout
,
151 port_max
, getpid(), frame_time_offset
,
152 nozombies
, drivers
)) == 0) {
153 jack_error ("cannot create engine");
157 jack_info ("loading driver ..");
159 if (jack_engine_load_driver (engine
, driver_desc
, driver_params
)) {
160 jack_error ("cannot load driver module %s",
165 if (engine
->driver
->start (engine
->driver
) != 0) {
166 jack_error ("cannot start driver");
170 /* install a do-nothing handler because otherwise pthreads
171 behaviour is undefined when we enter sigwait.
174 sigfillset (&allsignals
);
175 action
.sa_handler
= do_nothing_handler
;
176 action
.sa_mask
= allsignals
;
177 action
.sa_flags
= SA_RESTART
|SA_RESETHAND
;
179 for (i
= 1; i
< NSIG
; i
++) {
180 if (sigismember (&signals
, i
)) {
181 sigaction (i
, &action
, 0);
186 jack_info ("%d waiting for signals", getpid());
192 sigwait (&signals
, &sig
);
194 jack_info ("jack main caught signal %d", sig
);
198 jack_dump_configuration(engine
, 1);
210 if (sig
!= SIGSEGV
) {
212 /* unblock signals so we can see them during shutdown.
213 this will help prod developers not to lose sight of
214 bugs that cause segfaults etc. during shutdown.
216 sigprocmask (SIG_UNBLOCK
, &signals
, 0);
219 jack_engine_delete (engine
);
223 jack_engine_delete (engine
);
227 static jack_driver_desc_t
*
228 jack_drivers_get_descriptor (JSList
* drivers
, const char * sofile
)
230 jack_driver_desc_t
* descriptor
, * other_descriptor
;
231 JackDriverDescFunction so_get_descriptor
;
239 if ((driver_dir
= getenv("JACK_DRIVER_DIR")) == 0) {
240 driver_dir
= ADDON_DIR
;
242 filename
= malloc (strlen (driver_dir
) + 1 + strlen (sofile
) + 1);
243 sprintf (filename
, "%s/%s", driver_dir
, sofile
);
246 jack_info ("getting driver descriptor from %s", filename
);
249 if ((dlhandle
= dlopen (filename
, RTLD_NOW
|RTLD_GLOBAL
)) == NULL
) {
250 jack_error ("could not open driver .so '%s': %s\n", filename
, dlerror ());
255 so_get_descriptor
= (JackDriverDescFunction
)
256 dlsym (dlhandle
, "driver_get_descriptor");
258 if ((dlerr
= dlerror ()) != NULL
) {
259 jack_error("%s", dlerr
);
265 if ((descriptor
= so_get_descriptor ()) == NULL
) {
266 jack_error ("driver from '%s' returned NULL descriptor\n", filename
);
272 if ((err
= dlclose (dlhandle
)) != 0) {
273 jack_error ("error closing driver .so '%s': %s\n", filename
, dlerror ());
276 /* check it doesn't exist already */
277 for (node
= drivers
; node
; node
= jack_slist_next (node
)) {
278 other_descriptor
= (jack_driver_desc_t
*) node
->data
;
280 if (strcmp (descriptor
->name
, other_descriptor
->name
) == 0) {
281 jack_error ("the drivers in '%s' and '%s' both have the name '%s'; using the first\n",
282 other_descriptor
->file
, filename
, other_descriptor
->name
);
283 /* FIXME: delete the descriptor */
289 snprintf (descriptor
->file
, sizeof(descriptor
->file
), "%s", filename
);
298 struct dirent
* dir_entry
;
302 JSList
* driver_list
= NULL
;
303 jack_driver_desc_t
* desc
;
306 if ((driver_dir
= getenv("JACK_DRIVER_DIR")) == 0) {
307 driver_dir
= ADDON_DIR
;
310 /* search through the driver_dir and add get descriptors
311 from the .so files in it */
312 dir_stream
= opendir (driver_dir
);
314 jack_error ("could not open driver directory %s: %s\n",
315 driver_dir
, strerror (errno
));
319 while ( (dir_entry
= readdir (dir_stream
)) ) {
320 /* check the filename is of the right format */
321 if (strncmp ("jack_", dir_entry
->d_name
, 5) != 0) {
325 ptr
= strrchr (dir_entry
->d_name
, '.');
330 if (strncmp ("so", ptr
, 2) != 0) {
334 desc
= jack_drivers_get_descriptor (drivers
, dir_entry
->d_name
);
336 driver_list
= jack_slist_append (driver_list
, desc
);
340 err
= closedir (dir_stream
);
342 jack_error ("error closing driver directory %s: %s\n",
343 driver_dir
, strerror (errno
));
347 jack_error ("could not find any drivers in %s!\n", driver_dir
);
354 static void copyright (FILE* file
)
356 fprintf (file
, "jackd " VERSION
"\n"
357 "Copyright 2001-2009 Paul Davis, Stephane Letz, Jack O'Quinn, Torben Hohn and others.\n"
358 "jackd comes with ABSOLUTELY NO WARRANTY\n"
359 "This is free software, and you are welcome to redistribute it\n"
360 "under certain conditions; see the file COPYING for details\n\n");
363 static void usage (FILE *file
)
367 "usage: jackd [ --no-realtime OR -r ]\n"
368 " [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n"
369 " (the two previous arguments are mutually exclusive. The default is --realtime)\n"
370 " [ --name OR -n server-name ]\n"
371 " [ --no-mlock OR -m ]\n"
372 " [ --unlock OR -u ]\n"
373 " [ --timeout OR -t client-timeout-in-msecs ]\n"
374 " [ --port-max OR -p maximum-number-of-ports]\n"
375 " [ --debug-timer OR -D ]\n"
376 " [ --no-sanity-checks OR -N ]\n"
377 " [ --verbose OR -v ]\n"
378 " [ --clocksource OR -c [ c(ycle) | h(pet) | s(ystem) ]\n"
379 " [ --replace-registry ]\n"
380 " [ --silent OR -s ]\n"
381 " [ --version OR -V ]\n"
382 " [ --nozombies OR -Z ]\n"
383 " -d backend [ ... backend args ... ]\n"
385 " Available backends may include: coreaudio, dummy, net, portaudio.\n\n"
387 " Available backends may include: alsa, dummy, freebob, firewire, net, oss, sun, or portaudio.\n\n"
389 " jackd -d backend --help\n"
390 " to display options for each backend\n\n");
393 static jack_driver_desc_t
*
394 jack_find_driver_descriptor (const char * name
)
396 jack_driver_desc_t
* desc
= 0;
399 for (node
= drivers
; node
; node
= jack_slist_next (node
)) {
400 desc
= (jack_driver_desc_t
*) node
->data
;
402 if (strcmp (desc
->name
, name
) != 0) {
413 jack_cleanup_files (const char *server_name
)
416 struct dirent
*dirent
;
417 char dir_name
[PATH_MAX
+1] = "";
418 jack_server_dir (server_name
, dir_name
);
420 /* On termination, we remove all files that jackd creates so
421 * subsequent attempts to start jackd will not believe that an
422 * instance is already running. If the server crashes or is
423 * terminated with SIGKILL, this is not possible. So, cleanup
424 * is also attempted when jackd starts.
426 * There are several tricky issues. First, the previous JACK
427 * server may have run for a different user ID, so its files
428 * may be inaccessible. This is handled by using a separate
429 * JACK_TMP_DIR subdirectory for each user. Second, there may
430 * be other servers running with different names. Each gets
431 * its own subdirectory within the per-user directory. The
432 * current process has already registered as `server_name', so
433 * we know there is no other server actively using that name.
436 /* nothing to do if the server directory does not exist */
437 if ((dir
= opendir (dir_name
)) == NULL
) {
441 /* unlink all the files in this directory, they are mine */
442 while ((dirent
= readdir (dir
)) != NULL
) {
444 char fullpath
[PATH_MAX
+1];
446 if ((strcmp (dirent
->d_name
, ".") == 0)
447 || (strcmp (dirent
->d_name
, "..") == 0)) {
451 snprintf (fullpath
, sizeof (fullpath
), "%s/%s",
452 dir_name
, dirent
->d_name
);
454 if (unlink (fullpath
)) {
455 jack_error ("cannot unlink `%s' (%s)", fullpath
,
462 /* now, delete the per-server subdirectory, itself */
463 if (rmdir (dir_name
)) {
464 jack_error ("cannot remove `%s' (%s)", dir_name
,
468 /* finally, delete the per-user subdirectory, if empty */
469 if (rmdir (jack_user_dir ())) {
470 if (errno
!= ENOTEMPTY
) {
471 jack_error ("cannot remove `%s' (%s)",
472 jack_user_dir (), strerror (errno
));
478 maybe_use_capabilities ()
480 #ifdef USE_CAPABILITIES
483 /* check to see if there is a pipe in the right descriptor */
484 if ((status
= fstat (PIPE_WRITE_FD
, &pipe_stat
)) == 0 &&
485 S_ISFIFO(pipe_stat
.st_mode
)) {
487 /* tell jackstart we are up and running */
490 if (write (PIPE_WRITE_FD
, &c
, 1) != 1) {
491 jack_error ("cannot write to jackstart sync "
492 "pipe %d (%s)", PIPE_WRITE_FD
,
496 if (close(PIPE_WRITE_FD
) != 0) {
497 jack_error("jackd: error on startup pipe close: %s",
500 /* wait for jackstart process to set our capabilities */
501 if (wait (&status
) == -1) {
502 jack_error ("jackd: wait for startup "
503 "process exit failed");
505 if (!WIFEXITED (status
) || WEXITSTATUS (status
)) {
506 jack_error ("jackd: jackstart did not "
512 #endif /* USE_CAPABILITIES */
516 main (int argc
, char *argv
[])
519 jack_driver_desc_t
* desc
;
520 int replace_registry
= 0;
521 int do_sanity_checks
= 1;
522 int show_version
= 0;
524 const char *options
= "-d:P:uvshVrRZTFlt:mn:Np:c:";
525 struct option long_options
[] =
527 /* keep ordered by single-letter option code */
529 { "clock-source", 1, 0, 'c' },
530 { "driver", 1, 0, 'd' },
531 { "help", 0, 0, 'h' },
532 { "tmpdir-location", 0, 0, 'l' },
533 { "no-mlock", 0, 0, 'm' },
534 { "name", 1, 0, 'n' },
535 { "no-sanity-checks", 0, 0, 'N' },
536 { "port-max", 1, 0, 'p' },
537 { "realtime-priority", 1, 0, 'P' },
538 { "no-realtime", 0, 0, 'r' },
539 { "realtime", 0, 0, 'R' },
540 { "replace-registry", 0, &replace_registry
, 0 },
541 { "silent", 0, 0, 's' },
542 { "timeout", 1, 0, 't' },
543 { "temporary", 0, 0, 'T' },
544 { "unlock", 0, 0, 'u' },
545 { "version", 0, 0, 'V' },
546 { "verbose", 0, 0, 'v' },
547 { "nozombies", 0, 0, 'Z' },
551 int option_index
= 0;
553 char *driver_name
= NULL
;
554 char **driver_args
= NULL
;
555 JSList
* driver_params
;
556 int driver_nargs
= 1;
560 setvbuf (stdout
, NULL
, _IOLBF
, 0);
562 maybe_use_capabilities ();
565 while (!seen_driver
&&
566 (opt
= getopt_long (argc
, argv
, options
,
567 long_options
, &option_index
)) != EOF
) {
571 if (tolower (optarg
[0]) == 'h') {
572 clock_source
= JACK_TIMER_HPET
;
573 } else if (tolower (optarg
[0]) == 'c') {
574 clock_source
= JACK_TIMER_CYCLE_COUNTER
;
575 } else if (tolower (optarg
[0]) == 's') {
576 clock_source
= JACK_TIMER_SYSTEM_CLOCK
;
585 driver_name
= optarg
;
589 frame_time_offset
= JACK_MAX_FRAMES
- atoi(optarg
);
593 /* special flag to allow libjack to determine jackd's idea of where tmpdir is */
594 printf ("%s\n", jack_tmpdir
);
602 server_name
= optarg
;
606 do_sanity_checks
= 0;
610 port_max
= (unsigned int) atol (optarg
);
614 realtime_priority
= atoi (optarg
);
622 /* this is now the default */
627 jack_set_error_function (silent_jack_error_callback
);
635 client_timeout
= atoi (optarg
);
655 jack_error ("Unknown option character %c",
665 printf ( "jackd version " VERSION
666 " tmpdir " DEFAULT_TMP_DIR
667 " protocol " PROTOCOL_VERSION
674 if (do_sanity_checks
&& (0 < sanitycheck (realtime
, (clock_source
== JACK_TIMER_CYCLE_COUNTER
)))) {
678 if (realtime
&& (client_timeout
>= JACKD_WATCHDOG_TIMEOUT
)) {
680 fprintf (stderr
, "In realtime mode (-R) the client timeout must be smaller than the watchdog timeout (%ims).\n", JACKD_WATCHDOG_TIMEOUT
);
689 drivers
= jack_drivers_load ();
691 fprintf (stderr
, "jackd: no drivers found; exiting\n");
695 desc
= jack_find_driver_descriptor (driver_name
);
697 fprintf (stderr
, "jackd: unknown driver '%s'\n", driver_name
);
702 driver_nargs
= 1 + argc
- optind
;
707 if (driver_nargs
== 0) {
708 fprintf (stderr
, "No driver specified ... hmm. JACK won't do"
709 " anything when run like this.\n");
713 driver_args
= (char **) malloc (sizeof (char *) * driver_nargs
);
714 driver_args
[0] = driver_name
;
716 for (i
= 1; i
< driver_nargs
; i
++) {
717 driver_args
[i
] = argv
[optind
++];
720 if (jack_parse_driver_params (desc
, driver_nargs
,
721 driver_args
, &driver_params
)) {
725 if (server_name
== NULL
)
726 server_name
= jack_default_server_name ();
728 rc
= jack_register_server (server_name
, replace_registry
);
731 fprintf (stderr
, "`%s' server already active\n", server_name
);
734 fprintf (stderr
, "too many servers already active\n");
737 fprintf (stderr
, "no access to shm registry\n");
741 fprintf (stderr
, "server `%s' registered\n",
745 /* clean up shared memory and files from any previous
746 * instance of this server name */
748 jack_cleanup_files (server_name
);
750 /* run the server engine until it terminates */
751 jack_main (desc
, driver_params
);
753 /* clean up shared memory and files from this server instance */
755 fprintf (stderr
, "cleaning up shared memory\n");
758 fprintf (stderr
, "cleaning up files\n");
759 jack_cleanup_files (server_name
);
761 fprintf (stderr
, "unregistering server `%s'\n", server_name
);
762 jack_unregister_server (server_name
);