117 lines
3.0 KiB
C
117 lines
3.0 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <sys/select.h>
|
|
|
|
#define STATUS_FIFO "/tmp/looper_status"
|
|
#define CMD_FIFO "/tmp/looper_cmd"
|
|
|
|
static pid_t start_looper(void) {
|
|
pid_t pid = fork();
|
|
if (pid < 0) { perror("fork"); return -1; }
|
|
if (pid == 0) {
|
|
close(2);
|
|
open("/dev/null", O_WRONLY);
|
|
execl("./looper", "looper", NULL);
|
|
perror("execl");
|
|
_exit(1);
|
|
}
|
|
return pid;
|
|
}
|
|
|
|
/* Drain any stale data from the status FIFO */
|
|
static void drain_fifo(void) {
|
|
int fd = open(STATUS_FIFO, O_RDONLY | O_NONBLOCK);
|
|
if (fd < 0) return;
|
|
char buf[4096];
|
|
while (read(fd, buf, sizeof(buf)) > 0);
|
|
close(fd);
|
|
}
|
|
|
|
/* Read the first status line with a timeout (milliseconds).
|
|
* Returns 0 on success, -1 on timeout/error. */
|
|
static int read_status_line_timeout(char *buf, size_t bufsize, int timeout_ms) {
|
|
int fd = open(STATUS_FIFO, O_RDONLY | O_NONBLOCK);
|
|
if (fd < 0) return -1;
|
|
|
|
fd_set set;
|
|
struct timeval tv;
|
|
FD_ZERO(&set);
|
|
FD_SET(fd, &set);
|
|
tv.tv_sec = timeout_ms / 1000;
|
|
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
|
|
|
int ret = select(fd + 1, &set, NULL, NULL, &tv);
|
|
if (ret <= 0) {
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
|
|
int n = read(fd, buf, bufsize - 1);
|
|
close(fd);
|
|
if (n <= 0) return -1;
|
|
buf[n] = '\0';
|
|
|
|
/* keep only the first line */
|
|
char *nl = strchr(buf, '\n');
|
|
if (nl) *nl = '\0';
|
|
return 0;
|
|
}
|
|
|
|
static int test_status_after_record(void) {
|
|
printf("Test: status FIFO reports RECORD state after record command\n");
|
|
pid_t pid = start_looper();
|
|
if (pid < 0) return 1;
|
|
|
|
/* Give looper time to start main loop and begin writing status */
|
|
usleep(1500000);
|
|
drain_fifo();
|
|
|
|
/* Send record 0 command via FIFO */
|
|
int fd_cmd = open(CMD_FIFO, O_WRONLY);
|
|
if (fd_cmd < 0) {
|
|
fprintf(stderr, " FAIL: cannot open command FIFO\n");
|
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
|
return 1;
|
|
}
|
|
write(fd_cmd, "record 0\n", 9);
|
|
close(fd_cmd);
|
|
|
|
/* Keep reading status lines until we see RECORD or timeout (5 seconds) */
|
|
int found = 0;
|
|
int ch, sc;
|
|
char state[32];
|
|
char line[256];
|
|
for (int tries = 0; tries < 50; tries++) {
|
|
if (read_status_line_timeout(line, sizeof(line), 100) != 0) {
|
|
usleep(100000);
|
|
continue;
|
|
}
|
|
if (sscanf(line, "CH=%d SC=%d STATE=%31s", &ch, &sc, state) != 3)
|
|
continue;
|
|
if (ch == 0 && sc == 0 && strcmp(state, "RECORD") == 0) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
fprintf(stderr, " FAIL: did not see STATE=RECORD for CH=0 SC=0 within 5 seconds\n");
|
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
|
return 1;
|
|
}
|
|
printf(" PASS\n");
|
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
|
return 0;
|
|
}
|
|
|
|
int main(void) {
|
|
int fail = 0;
|
|
fail += test_status_after_record();
|
|
return fail;
|
|
}
|