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"
28 #include "interface.c"
30 #define NOTIF_BACKGROUND "continuing to run in the background"
32 volatile sig_atomic_t stop_signaled
= 0;
34 static void stop_handler(int s
)
39 static int tty
= -1; /* controlling terminal or -1 */
41 static void background_handler(int s
)
45 /* setup a child that will stop us then wake us up */
48 /* error, use the default handler */
49 signal(SIGTSTP
, SIG_DFL
);
53 if (tty
>= 0 && verbose
)
54 write( STDOUT_FILENO
, PROGRAM_NAME
": " NOTIF_BACKGROUND
"\n",
55 sizeof(PROGRAM_NAME
)-1 + 2 + sizeof(NOTIF_BACKGROUND
)-1 + 1 );
56 /* make sure the parent is not in the foreground (or has no ctty) */
57 for (i
= 1; tcgetpgrp(tty
) == getpgid(getppid()); i
<<= 1) {
58 kill(getppid(), SIGSTOP
); /* let the shell regain control of the tty */
59 usleep(i
), kill(getppid(), SIGCONT
);
65 int main(int argc
, char *argv
[])
69 tty
= open("/dev/tty", O_NOCTTY
);
74 rc
= !sigemptyset(&act
.sa_mask
);
76 /* SIGINT handler to exit gracefully */
77 act
.sa_handler
= stop_handler
;
78 rc
= !sigaction(SIGINT
, &act
, NULL
) && rc
;
79 /* SIGTTIN handler to avoid being stopped */
80 act
.sa_handler
= SIG_IGN
;
81 rc
= !sigaction(SIGTTIN
, &act
, NULL
) && rc
;
82 /* SIGTSTP handler to go into the background */
83 act
.sa_handler
= background_handler
;
84 rc
= !sigaction(SIGTSTP
, &act
, NULL
) && rc
;
85 /* SIGCHLD handler to avoid a child to become defunct */
86 act
.sa_handler
= SIG_IGN
;
87 rc
= !sigaction(SIGCHLD
, &act
, NULL
) && rc
;
90 fputs(PROGRAM_NAME
": error while setting up the signal handlers\n", stderr
);
92 /* Command line options */
93 GOptionContext
*context
= interface_context();
95 if (!g_option_context_parse(context
, &argc
, &argv
, &error
))
96 return (fprintf(stderr
, "option parsing failed: %s\n", error
->message
), -1);
98 /* Initialize jackspa */
100 if (!jackspa_init(&state
, argc
, argv
))
103 /* Set the default values */
106 if (control_buildall(&c
, &controls
, &state
))
110 if (!isatty(fileno(stdin
)))
111 while (!stop_signaled
) sleep(-1);
113 while (!stop_signaled
&& !feof(stdin
))
114 if (getpgrp() == tcgetpgrp(STDIN_FILENO
))
115 /* we are in the foreground process group */
119 control_cleanupall(c
, &controls
);