git-svn-id: svn+ssh://jackaudio.org/trunk/jack@651 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
| @@ -14,8 +14,8 @@ dnl micro version = incremented when implementation-only | |||
| dnl changes are made | |||
| dnl --- | |||
| JACK_MAJOR_VERSION=0 | |||
| JACK_MINOR_VERSION=94 | |||
| JACK_MICRO_VERSION=4 | |||
| JACK_MINOR_VERSION=95 | |||
| JACK_MICRO_VERSION=0 | |||
| dnl --- | |||
| dnl HOWTO: updating the jack protocal version | |||
| @@ -112,6 +112,7 @@ struct _jack_engine { | |||
| int rtpriority; | |||
| char freewheeling; | |||
| char verbose; | |||
| char temporary; | |||
| int reordered; | |||
| int watchdog_check; | |||
| pid_t wait_pid; | |||
| @@ -147,7 +148,7 @@ struct _jack_engine { | |||
| /* public functions */ | |||
| jack_engine_t *jack_engine_new (int real_time, int real_time_priority, | |||
| int verbose, int client_timeout, | |||
| int temporary, int verbose, int client_timeout, | |||
| pid_t waitpid, JSList * drivers); | |||
| int jack_engine_delete (jack_engine_t *); | |||
| int jack_run (jack_engine_t *engine); | |||
| @@ -39,6 +39,7 @@ extern "C" { | |||
| * | |||
| * @param client_name of at most jack_client_name_size() characters. | |||
| * | |||
| * @param client_name The name for the new client | |||
| * @return opaque client handle if successful, otherwise NULL. | |||
| * | |||
| * @note Failure generally means that the JACK server is not running. | |||
| @@ -21,7 +21,7 @@ endif | |||
| bin_PROGRAMS = jackd $(CAP_PROGS) | |||
| AM_CFLAGS = $(JACK_CFLAGS) -DJACKD_LOCATION=\"$(bindir)/jackd\" | |||
| AM_CFLAGS = $(JACK_CFLAGS) -DJACK_LOCATION=\"$(bindir)\" | |||
| jackd_SOURCES = jackd.c engine.c transengine.c | |||
| jackd_LDADD = ../libjack/libjack.la -lm -ldl -lrt -lpthread $(CAP_LIBS) | |||
| @@ -875,7 +875,7 @@ jack_remove_clients (jack_engine_t* engine) | |||
| node = tmp; | |||
| } | |||
| if (need_sort) { | |||
| jack_sort_graph (engine); | |||
| } | |||
| @@ -1916,7 +1916,7 @@ jack_server_thread (void *arg) | |||
| } | |||
| jack_engine_t * | |||
| jack_engine_new (int realtime, int rtpriority, int verbose, | |||
| jack_engine_new (int realtime, int rtpriority, int temporary, int verbose, | |||
| int client_timeout, pid_t wait_pid, JSList * drivers) | |||
| { | |||
| jack_engine_t *engine; | |||
| @@ -1948,6 +1948,7 @@ jack_engine_new (int realtime, int rtpriority, int verbose, | |||
| engine->rtpriority = rtpriority; | |||
| engine->silent_buffer = 0; | |||
| engine->verbose = verbose; | |||
| engine->temporary = temporary; | |||
| engine->freewheeling = 0; | |||
| engine->wait_pid = wait_pid; | |||
| @@ -2646,6 +2647,12 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client) | |||
| } | |||
| jack_client_delete (engine, client); | |||
| /* ignore the driver, which counts as a client. */ | |||
| if (engine->temporary && (jack_slist_length(engine->clients) <= 1)) { | |||
| exit(0); | |||
| } | |||
| } | |||
| @@ -54,6 +54,9 @@ requires a kernel with "POSIX draft capabilities" enabled (see the | |||
| invoke the daemon using \fBjackstart\fR, and later launch JACK clients | |||
| without running as root. | |||
| .TP | |||
| \fB\-T, \-\-temporary | |||
| Will exit once all clients have closed their connections. | |||
| .TP | |||
| \fB\-P, \-\-realtime\-priority \fIint\fR | |||
| When running \fB\-\-realtime\fR, set the scheduler priority to | |||
| \fIint\fR. | |||
| @@ -56,6 +56,7 @@ static sigset_t signals; | |||
| static jack_engine_t *engine = 0; | |||
| static int realtime = 0; | |||
| static int realtime_priority = 10; | |||
| static int temporary = 0; | |||
| static int verbose = 0; | |||
| static int client_timeout = 500; /* msecs */ | |||
| @@ -132,7 +133,7 @@ jack_main (jack_driver_desc_t * driver_desc, JSList * driver_params) | |||
| /* get the engine/driver started */ | |||
| if ((engine = jack_engine_new (realtime, realtime_priority, | |||
| if ((engine = jack_engine_new (realtime, realtime_priority, temporary, | |||
| verbose, client_timeout, | |||
| getpid(), drivers)) == 0) { | |||
| fprintf (stderr, "cannot create engine\n"); | |||
| @@ -374,8 +375,8 @@ int | |||
| main (int argc, char *argv[]) | |||
| { | |||
| jack_driver_desc_t * desc; | |||
| const char *options = "-ad:P:vshVRFl:t:"; | |||
| jack_driver_desc_t * desc; | |||
| const char *options = "-ad:P:vshVRTFl:t:"; | |||
| struct option long_options[] = | |||
| { | |||
| { "driver", 1, 0, 'd' }, | |||
| @@ -384,12 +385,13 @@ main (int argc, char *argv[]) | |||
| { "realtime", 0, 0, 'R' }, | |||
| { "realtime-priority", 1, 0, 'P' }, | |||
| { "timeout", 1, 0, 't' }, | |||
| { "temporary", 0, 0, 'T' }, | |||
| { "version", 0, 0, 'V' }, | |||
| { "silent", 0, 0, 's' }, | |||
| { 0, 0, 0, 0 } | |||
| }; | |||
| int option_index; | |||
| int opt; | |||
| int opt = 0; | |||
| int option_index = 0; | |||
| int seen_driver = 0; | |||
| char *driver_name = 0; | |||
| char **driver_args = 0; | |||
| @@ -436,10 +438,10 @@ main (int argc, char *argv[]) | |||
| } | |||
| } | |||
| #endif | |||
| opterr = 0; | |||
| while (!seen_driver && (opt = getopt_long (argc, argv, options, | |||
| long_options, | |||
| &option_index)) != EOF) { | |||
| long_options, &option_index)) != EOF) { | |||
| switch (opt) { | |||
| case 'd': | |||
| @@ -463,6 +465,10 @@ main (int argc, char *argv[]) | |||
| realtime = 1; | |||
| break; | |||
| case 'T': | |||
| temporary = 1; | |||
| break; | |||
| case 't': | |||
| client_timeout = atoi (optarg); | |||
| break; | |||
| @@ -43,8 +43,8 @@ | |||
| #define READ_BLOCKSIZE 4096 | |||
| /* JACKD_LOCATION must be passed on the gcc command line */ | |||
| static char *jackd_bin_path = JACKD_LOCATION; | |||
| /* JACK_LOCATION must be passed on the gcc command line */ | |||
| static char *jackd_bin_path = JACK_LOCATION "/jackd"; | |||
| static char *jackd_md5_sum = JACKD_MD5_SUM; | |||
| @@ -14,7 +14,7 @@ lib_LTLIBRARIES = libjack.la | |||
| noinst_HEADERS = local.h | |||
| AM_CFLAGS = $(JACK_CFLAGS) | |||
| AM_CFLAGS = $(JACK_CFLAGS) -DJACK_LOCATION=\"$(bindir)\" | |||
| AM_CXXFLAGS = $(JACK_CFLAGS) | |||
| libjack_la_CFLAGS = $(AM_CFLAGS) | |||
| @@ -23,4 +23,3 @@ libjack_la_SOURCES = $(SOURCE_FILES) | |||
| libjack_la_LIBADD = -lm -lpthread -lrt | |||
| libjack_la_LDFLAGS = -export-dynamic -version-info @JACK_SO_VERSION@ | |||
| @@ -40,6 +40,7 @@ | |||
| #include <stdio.h> | |||
| #include <stdint.h> | |||
| #include <regex.h> | |||
| #include <signal.h> | |||
| #include <config.h> | |||
| @@ -392,6 +393,102 @@ server_event_connect (jack_client_t *client) | |||
| return fd; | |||
| } | |||
| static void | |||
| _start_server (void) | |||
| { | |||
| FILE* fp = 0; | |||
| char filename[255]; | |||
| char arguments[255]; | |||
| char buffer[255]; | |||
| char* command = 0; | |||
| size_t pos = 0; | |||
| size_t result = 0; | |||
| char** argv = 0; | |||
| int i = 0; | |||
| int good = 0; | |||
| int ret; | |||
| snprintf(filename, 255, "%s/.jackdrc", getenv("HOME")); | |||
| fp = fopen(filename, "r"); | |||
| if (!fp) { | |||
| fp = fopen("/etc/jackd.conf", "r"); | |||
| } | |||
| if (fp) { | |||
| ret = fscanf(fp, "%s", buffer); | |||
| while(ret != 0 && ret != EOF) { | |||
| strcat(arguments, buffer); | |||
| strcat(arguments, " "); | |||
| ret = fscanf(fp, "%s", buffer); | |||
| } | |||
| if (strlen(arguments) > 0) { | |||
| good = 1; | |||
| } | |||
| } | |||
| if (!good) { | |||
| #if defined(__APPLE__) && defined(__POWERPC__) | |||
| command = JACK_LOCATION "/jackd"; | |||
| strncpy(arguments, JACK_LOCATION "/jackd -T -d portaudio -p 512", 255); | |||
| #elif defined(USE_CAPABILITIES) | |||
| command = JACK_LOCATION "/jackstart"; | |||
| strncpy(arguments, JACK_LOCATION "/jackstart -T -R -d alsa -d hw:0 -p 512", 255); | |||
| #else | |||
| command = JACK_LOCATION "/jackd"; | |||
| strncpy(arguments, JACK_LOCATION "/jackd -T -d alsa -d hw:0 -p 2048", 255); | |||
| #endif | |||
| } else { | |||
| result = strcspn(arguments, " "); | |||
| command = (char*)malloc(result+1); | |||
| strncpy(command, arguments, result); | |||
| command[result] = '\0'; | |||
| } | |||
| argv = (char**)malloc(255); | |||
| while(1) { | |||
| result = strcspn(arguments+pos, " "); | |||
| if (result == 0) { | |||
| break; | |||
| } | |||
| argv[i] = (char*)malloc(result+1); | |||
| strncpy(argv[i], arguments+pos, result); | |||
| argv[i][result] = '\0'; | |||
| pos += result+1; | |||
| ++i; | |||
| } | |||
| execv (command, argv); | |||
| } | |||
| int | |||
| start_server (void) | |||
| { | |||
| pid_t pid1, pid2; | |||
| if (getenv("JACK_NO_START_SERVER")) { | |||
| return 1; | |||
| } | |||
| switch (pid1 = fork()) { | |||
| case -1: | |||
| return 1; | |||
| case 0: | |||
| switch (pid2 = fork()) { | |||
| case -1: | |||
| return 1; | |||
| case 0: | |||
| _start_server(); | |||
| } | |||
| _exit(0); | |||
| } | |||
| return 0; | |||
| } | |||
| static int | |||
| jack_request_client (ClientType type, const char* client_name, | |||
| const char* so_name, const char* so_data, | |||
| @@ -428,7 +525,14 @@ jack_request_client (ClientType type, const char* client_name, | |||
| } | |||
| if ((*req_fd = server_connect (0)) < 0) { | |||
| goto fail; | |||
| if (start_server() == 0) { | |||
| sleep(2); | |||
| if ((*req_fd = server_connect (0)) < 0) { | |||
| goto fail; | |||
| } | |||
| } else { | |||
| goto fail; | |||
| } | |||
| } | |||
| req.load = TRUE; | |||
| @@ -1667,7 +1771,6 @@ jack_get_process_done_fd (jack_client_t *client) | |||
| return client->graph_next_fd; | |||
| } | |||
| void | |||
| jack_on_shutdown (jack_client_t *client, void (*function)(void *arg), void *arg) | |||
| { | |||
| @@ -227,7 +227,7 @@ jack_get_current_transport_frame (const jack_client_t *client) | |||
| usecs = jack_get_microseconds() - position.usecs; | |||
| elapsed = (jack_nframes_t) floor ((((float) position.frame_rate) / 1000000.0f) * usecs); | |||
| /* return the estimated transport frame position | |||
| */ | |||