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
= 0;
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;
71 do_nothing_handler (int sig
)
73 /* this is used by the child (active) process, but it never
74 gets called unless we are already shutting down after
78 snprintf (buf
, sizeof(buf
),
79 "received signal %d during shutdown (ignored)\n", sig
);
80 write (1, buf
, strlen (buf
));
84 jack_main (jack_driver_desc_t
* driver_desc
, JSList
* driver_params
)
89 struct sigaction action
;
92 /* ensure that we are in our own process group so that
93 kill (SIG, -pgrp) does the right thing.
98 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
);
102 POSIX says that signals are delivered like this:
104 * if a thread has blocked that signal, it is not
105 a candidate to receive the signal.
106 * of all threads not blocking the signal, pick
107 one at random, and deliver the signal.
109 this means that a simple-minded multi-threaded program can
110 expect to get POSIX signals delivered randomly to any one
113 here, we block all signals that we think we might receive
114 and want to catch. all "child" threads will inherit this
115 setting. if we create a thread that calls sigwait() on the
116 same set of signals, implicitly unblocking all those
117 signals. any of those signals that are delivered to the
118 process will be delivered to that thread, and that thread
119 alone. this makes cleanup for a signal-driven exit much
120 easier, since we know which thread is doing it and more
121 importantly, we are free to call async-unsafe functions,
122 because the code is executing in normal thread context
123 after a return from sigwait().
126 sigemptyset (&signals
);
127 sigaddset(&signals
, SIGHUP
);
128 sigaddset(&signals
, SIGINT
);
129 sigaddset(&signals
, SIGQUIT
);
130 sigaddset(&signals
, SIGPIPE
);
131 sigaddset(&signals
, SIGTERM
);
132 sigaddset(&signals
, SIGUSR1
);
133 sigaddset(&signals
, SIGUSR2
);
135 /* all child threads will inherit this mask unless they
136 * explicitly reset it
139 pthread_sigmask (SIG_BLOCK
, &signals
, 0);
141 if (!realtime
&& client_timeout
== 0)
142 client_timeout
= 500; /* 0.5 sec; usable when non realtime. */
144 /* get the engine/driver started */
146 if ((engine
= jack_engine_new (realtime
, realtime_priority
,
147 do_mlock
, do_unlock
, server_name
,
148 temporary
, verbose
, client_timeout
,
149 port_max
, getpid(), frame_time_offset
,
150 nozombies
, drivers
)) == 0) {
151 jack_error ("cannot create engine");
155 jack_info ("loading driver ..");
157 if (jack_engine_load_driver (engine
, driver_desc
, driver_params
)) {
158 jack_error ("cannot load driver module %s",
163 if (engine
->driver
->start (engine
->driver
) != 0) {
164 jack_error ("cannot start driver");
168 /* install a do-nothing handler because otherwise pthreads
169 behaviour is undefined when we enter sigwait.
172 sigfillset (&allsignals
);
173 action
.sa_handler
= do_nothing_handler
;
174 action
.sa_mask
= allsignals
;
175 action
.sa_flags
= SA_RESTART
|SA_RESETHAND
;
177 for (i
= 1; i
< NSIG
; i
++) {
178 if (sigismember (&signals
, i
)) {
179 sigaction (i
, &action
, 0);
184 jack_info ("%d waiting for signals", getpid());
190 sigwait (&signals
, &sig
);
192 jack_info ("jack main caught signal %d", sig
);
196 jack_dump_configuration(engine
, 1);
208 if (sig
!= SIGSEGV
) {
210 /* unblock signals so we can see them during shutdown.
211 this will help prod developers not to lose sight of
212 bugs that cause segfaults etc. during shutdown.
214 sigprocmask (SIG_UNBLOCK
, &signals
, 0);
217 jack_engine_delete (engine
);
221 jack_engine_delete (engine
);
225 static jack_driver_desc_t
*
226 jack_drivers_get_descriptor (JSList
* drivers
, const char * sofile
)
228 jack_driver_desc_t
* descriptor
, * other_descriptor
;
229 JackDriverDescFunction so_get_descriptor
;
237 if ((driver_dir
= getenv("JACK_DRIVER_DIR")) == 0) {
238 driver_dir
= ADDON_DIR
;
240 filename
= malloc (strlen (driver_dir
) + 1 + strlen (sofile
) + 1);
241 sprintf (filename
, "%s/%s", driver_dir
, sofile
);
244 jack_info ("getting driver descriptor from %s", filename
);
247 if ((dlhandle
= dlopen (filename
, RTLD_NOW
|RTLD_GLOBAL
)) == NULL
) {
248 jack_error ("could not open driver .so '%s': %s\n", filename
, dlerror ());
253 so_get_descriptor
= (JackDriverDescFunction
)
254 dlsym (dlhandle
, "driver_get_descriptor");
256 if ((dlerr
= dlerror ()) != NULL
) {
257 jack_error("%s", dlerr
);
263 if ((descriptor
= so_get_descriptor ()) == NULL
) {
264 jack_error ("driver from '%s' returned NULL descriptor\n", filename
);
270 if ((err
= dlclose (dlhandle
)) != 0) {
271 jack_error ("error closing driver .so '%s': %s\n", filename
, dlerror ());
274 /* check it doesn't exist already */
275 for (node
= drivers
; node
; node
= jack_slist_next (node
)) {
276 other_descriptor
= (jack_driver_desc_t
*) node
->data
;
278 if (strcmp (descriptor
->name
, other_descriptor
->name
) == 0) {
279 jack_error ("the drivers in '%s' and '%s' both have the name '%s'; using the first\n",
280 other_descriptor
->file
, filename
, other_descriptor
->name
);
281 /* FIXME: delete the descriptor */
287 snprintf (descriptor
->file
, sizeof(descriptor
->file
), "%s", filename
);
296 struct dirent
* dir_entry
;
300 JSList
* driver_list
= NULL
;
301 jack_driver_desc_t
* desc
;
304 if ((driver_dir
= getenv("JACK_DRIVER_DIR")) == 0) {
305 driver_dir
= ADDON_DIR
;
308 /* search through the driver_dir and add get descriptors
309 from the .so files in it */
310 dir_stream
= opendir (driver_dir
);
312 jack_error ("could not open driver directory %s: %s\n",
313 driver_dir
, strerror (errno
));
317 while ( (dir_entry
= readdir (dir_stream
)) ) {
318 /* check the filename is of the right format */
319 if (strncmp ("jack_", dir_entry
->d_name
, 5) != 0) {
323 ptr
= strrchr (dir_entry
->d_name
, '.');
328 if (strncmp ("so", ptr
, 2) != 0) {
332 desc
= jack_drivers_get_descriptor (drivers
, dir_entry
->d_name
);
334 driver_list
= jack_slist_append (driver_list
, desc
);
338 err
= closedir (dir_stream
);
340 jack_error ("error closing driver directory %s: %s\n",
341 driver_dir
, strerror (errno
));
345 jack_error ("could not find any drivers in %s!\n", driver_dir
);
352 static void copyright (FILE* file
)
354 fprintf (file
, "jackd " VERSION
"\n"
355 "Copyright 2001-2005 Paul Davis and others.\n"
356 "jackd comes with ABSOLUTELY NO WARRANTY\n"
357 "This is free software, and you are welcome to redistribute it\n"
358 "under certain conditions; see the file COPYING for details\n\n");
361 static void usage (FILE *file
)
365 "usage: jackd [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n"
366 " [ --name OR -n server-name ]\n"
367 " [ --no-mlock OR -m ]\n"
368 " [ --unlock OR -u ]\n"
369 " [ --timeout OR -t client-timeout-in-msecs ]\n"
370 " [ --port-max OR -p maximum-number-of-ports]\n"
371 " [ --debug-timer OR -D ]\n"
372 " [ --verbose OR -v ]\n"
373 " [ --clocksource OR -c [ c(ycle) | h(pet) | s(ystem) ]\n"
374 " [ --replace-registry OR -r ]\n"
375 " [ --silent OR -s ]\n"
376 " [ --version OR -V ]\n"
377 " [ --nozombies OR -Z ]\n"
378 " -d backend [ ... backend args ... ]\n"
379 " The backend can be `alsa', `coreaudio', `dummy',\n"
380 " `freebob', `oss', `sun', or `portaudio'.\n\n"
381 " jackd -d backend --help\n"
382 " to display options for each backend\n\n");
385 static jack_driver_desc_t
*
386 jack_find_driver_descriptor (const char * name
)
388 jack_driver_desc_t
* desc
= 0;
391 for (node
= drivers
; node
; node
= jack_slist_next (node
)) {
392 desc
= (jack_driver_desc_t
*) node
->data
;
394 if (strcmp (desc
->name
, name
) != 0) {
405 jack_cleanup_files (const char *server_name
)
408 struct dirent
*dirent
;
409 char dir_name
[PATH_MAX
+1] = "";
410 jack_server_dir (server_name
, dir_name
);
412 /* On termination, we remove all files that jackd creates so
413 * subsequent attempts to start jackd will not believe that an
414 * instance is already running. If the server crashes or is
415 * terminated with SIGKILL, this is not possible. So, cleanup
416 * is also attempted when jackd starts.
418 * There are several tricky issues. First, the previous JACK
419 * server may have run for a different user ID, so its files
420 * may be inaccessible. This is handled by using a separate
421 * JACK_TMP_DIR subdirectory for each user. Second, there may
422 * be other servers running with different names. Each gets
423 * its own subdirectory within the per-user directory. The
424 * current process has already registered as `server_name', so
425 * we know there is no other server actively using that name.
428 /* nothing to do if the server directory does not exist */
429 if ((dir
= opendir (dir_name
)) == NULL
) {
433 /* unlink all the files in this directory, they are mine */
434 while ((dirent
= readdir (dir
)) != NULL
) {
436 char fullpath
[PATH_MAX
+1];
438 if ((strcmp (dirent
->d_name
, ".") == 0)
439 || (strcmp (dirent
->d_name
, "..") == 0)) {
443 snprintf (fullpath
, sizeof (fullpath
), "%s/%s",
444 dir_name
, dirent
->d_name
);
446 if (unlink (fullpath
)) {
447 jack_error ("cannot unlink `%s' (%s)", fullpath
,
454 /* now, delete the per-server subdirectory, itself */
455 if (rmdir (dir_name
)) {
456 jack_error ("cannot remove `%s' (%s)", dir_name
,
460 /* finally, delete the per-user subdirectory, if empty */
461 if (rmdir (jack_user_dir ())) {
462 if (errno
!= ENOTEMPTY
) {
463 jack_error ("cannot remove `%s' (%s)",
464 jack_user_dir (), strerror (errno
));
470 maybe_use_capabilities ()
472 #ifdef USE_CAPABILITIES
475 /* check to see if there is a pipe in the right descriptor */
476 if ((status
= fstat (PIPE_WRITE_FD
, &pipe_stat
)) == 0 &&
477 S_ISFIFO(pipe_stat
.st_mode
)) {
479 /* tell jackstart we are up and running */
482 if (write (PIPE_WRITE_FD
, &c
, 1) != 1) {
483 jack_error ("cannot write to jackstart sync "
484 "pipe %d (%s)", PIPE_WRITE_FD
,
488 if (close(PIPE_WRITE_FD
) != 0) {
489 jack_error("jackd: error on startup pipe close: %s",
492 /* wait for jackstart process to set our capabilities */
493 if (wait (&status
) == -1) {
494 jack_error ("jackd: wait for startup "
495 "process exit failed");
497 if (!WIFEXITED (status
) || WEXITSTATUS (status
)) {
498 jack_error ("jackd: jackstart did not "
504 #endif /* USE_CAPABILITIES */
508 main (int argc
, char *argv
[])
511 jack_driver_desc_t
* desc
;
512 const char *options
= "-ad:P:uvshVRZTFlt:mn:p:c:";
513 struct option long_options
[] =
515 { "driver", 1, 0, 'd' },
516 { "verbose", 0, 0, 'v' },
517 { "help", 0, 0, 'h' },
518 { "tmpdir-location", 0, 0, 'l' },
519 { "port-max", 1, 0, 'p' },
520 { "no-mlock", 0, 0, 'm' },
521 { "name", 1, 0, 'n' },
522 { "unlock", 0, 0, 'u' },
523 { "realtime", 0, 0, 'R' },
524 { "replace-registry", 0, 0, 'r' },
525 { "realtime-priority", 1, 0, 'P' },
526 { "timeout", 1, 0, 't' },
527 { "temporary", 0, 0, 'T' },
528 { "version", 0, 0, 'V' },
529 { "silent", 0, 0, 's' },
530 { "clock-source", 1, 0, 'c' },
531 { "nozombies", 0, 0, 'Z' },
535 int option_index
= 0;
537 char *driver_name
= NULL
;
538 char **driver_args
= NULL
;
539 JSList
* driver_params
;
540 int driver_nargs
= 1;
541 int show_version
= 0;
542 int replace_registry
= 0;
546 setvbuf (stdout
, NULL
, _IOLBF
, 0);
548 maybe_use_capabilities ();
551 while (!seen_driver
&&
552 (opt
= getopt_long (argc
, argv
, options
,
553 long_options
, &option_index
)) != EOF
) {
557 if (tolower (optarg
[0]) == 'h') {
558 clock_source
= JACK_TIMER_HPET
;
559 } else if (tolower (optarg
[0]) == 'c') {
560 clock_source
= JACK_TIMER_CYCLE_COUNTER
;
561 } else if (tolower (optarg
[0]) == 's') {
562 clock_source
= JACK_TIMER_SYSTEM_CLOCK
;
571 driver_name
= optarg
;
575 frame_time_offset
= JACK_MAX_FRAMES
- atoi(optarg
);
579 /* special flag to allow libjack to determine jackd's idea of where tmpdir is */
580 printf ("%s\n", jack_tmpdir
);
588 server_name
= optarg
;
592 port_max
= (unsigned int) atol (optarg
);
596 realtime_priority
= atoi (optarg
);
600 replace_registry
= 1;
608 jack_set_error_function (silent_jack_error_callback
);
616 client_timeout
= atoi (optarg
);
636 jack_error ("Unknown option character %c",
646 printf ( "jackd version " VERSION
647 " tmpdir " DEFAULT_TMP_DIR
648 " protocol " PROTOCOL_VERSION
653 if (realtime
&& (client_timeout
>= JACKD_WATCHDOG_TIMEOUT
)) {
655 fprintf (stderr
, "In realtime mode (-R) the client timeout must be smaller than the watchdog timeout (%ims).\n", JACKD_WATCHDOG_TIMEOUT
);
664 drivers
= jack_drivers_load ();
666 fprintf (stderr
, "jackd: no drivers found; exiting\n");
670 desc
= jack_find_driver_descriptor (driver_name
);
672 fprintf (stderr
, "jackd: unknown driver '%s'\n", driver_name
);
677 driver_nargs
= 1 + argc
- optind
;
682 if (driver_nargs
== 0) {
683 fprintf (stderr
, "No driver specified ... hmm. JACK won't do"
684 " anything when run like this.\n");
688 driver_args
= (char **) malloc (sizeof (char *) * driver_nargs
);
689 driver_args
[0] = driver_name
;
691 for (i
= 1; i
< driver_nargs
; i
++) {
692 driver_args
[i
] = argv
[optind
++];
695 if (jack_parse_driver_params (desc
, driver_nargs
,
696 driver_args
, &driver_params
)) {
700 if (server_name
== NULL
)
701 server_name
= jack_default_server_name ();
705 rc
= jack_register_server (server_name
, replace_registry
);
708 fprintf (stderr
, "`%s' server already active\n", server_name
);
711 fprintf (stderr
, "too many servers already active\n");
714 fprintf (stderr
, "no access to shm registry\n");
718 fprintf (stderr
, "server `%s' registered\n",
722 /* clean up shared memory and files from any previous
723 * instance of this server name */
725 jack_cleanup_files (server_name
);
727 /* run the server engine until it terminates */
728 jack_main (desc
, driver_params
);
730 /* clean up shared memory and files from this server instance */
732 fprintf (stderr
, "cleaning up shared memory\n");
735 fprintf (stderr
, "cleaning up files\n");
736 jack_cleanup_files (server_name
);
738 fprintf (stderr
, "unregistering server `%s'\n", server_name
);
739 jack_unregister_server (server_name
);