1 /* jackspa-cli.c - simple CLI LADSPA host for the Jack Audio Connection Kit
2 * Copyright © 2013 Géraud Meyer <graud@gmx.com>
4 * This file is part of ng-jackspa.
6 * ng-jackspa is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with ng-jackspa. If not, see <http://www.gnu.org/licenses/>.
27 #define PROGRAM_NAME "jackspa-cli"
29 #define NOTIF_BACKGROUND "continuing to run in the background"
31 volatile sig_atomic_t stop_signaled
= 0;
33 static void stop_handler(int s
)
38 static int tty
= -1; /* controlling terminal or -1 */
40 static void background_handler(int s
)
44 /* setup a child that will stop us then wake us up */
47 /* error, use the default handler */
48 signal(SIGTSTP
, SIG_DFL
);
53 write( STDOUT_FILENO
, PROGRAM_NAME
": " NOTIF_BACKGROUND
"\n",
54 sizeof(PROGRAM_NAME
)-1 + 2 + sizeof(NOTIF_BACKGROUND
)-1 + 1 );
55 /* make sure the parent is not in the foreground (or has no ctty) */
56 for (i
= 1; tcgetpgrp(tty
) == getpgid(getppid()); i
<<= 1) {
57 kill(getppid(), SIGSTOP
); /* let the shell regain control of the tty */
58 usleep(i
), kill(getppid(), SIGCONT
);
64 int main(int argc
, char *argv
[])
68 tty
= open("/dev/tty", O_NOCTTY
);
73 rc
= !sigemptyset(&act
.sa_mask
);
75 /* SIGINT handler to exit gracefully */
76 act
.sa_handler
= stop_handler
;
77 rc
= !sigaction(SIGINT
, &act
, NULL
) && rc
;
78 /* SIGTTIN handler to avoid being stopped */
79 act
.sa_handler
= SIG_IGN
;
80 rc
= !sigaction(SIGTTIN
, &act
, NULL
) && rc
;
81 /* SIGTSTP handler to go into the background */
82 act
.sa_handler
= background_handler
;
83 rc
= !sigaction(SIGTSTP
, &act
, NULL
) && rc
;
84 /* SIGCHLD handler to avoid a child to become defunct */
85 act
.sa_handler
= SIG_IGN
;
86 rc
= !sigaction(SIGCHLD
, &act
, NULL
) && rc
;
89 fputs(PROGRAM_NAME
": error while setting up the signal handlers\n", stderr
);
91 /* Initialize jackspa */
93 if (!jackspa_init(&state
, argc
, argv
))
96 /* Set the default values */
99 if (control_buildall(&c
, &controls
, &state
))
103 if (!isatty(fileno(stdin
)))
104 while (!stop_signaled
) sleep(-1);
106 while (!stop_signaled
&& !feof(stdin
))
107 if (getpgrp() == tcgetpgrp(STDIN_FILENO
))
108 /* we are in the foreground process group */
112 control_cleanupall(c
, &controls
);