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 | |||
*/ | |||