Demonstration program of xorriso at two pipes: test/frontend_pipes_xorriso.c
This commit is contained in:
parent
63130b2211
commit
b84c80ab11
@ -244,6 +244,7 @@ EXTRA_DIST = \
|
||||
doc/partition_offset.wiki \
|
||||
doc/qemu_xorriso.wiki \
|
||||
doc/startup_file.txt \
|
||||
test/frontend_pipes_xorriso.c \
|
||||
README \
|
||||
AUTHORS \
|
||||
CONTRIBUTORS \
|
||||
|
230
test/frontend_pipes_xorriso.c
Normal file
230
test/frontend_pipes_xorriso.c
Normal file
@ -0,0 +1,230 @@
|
||||
|
||||
/* Beefed-up example from man 2 pipe
|
||||
to illustrate how xorriso is to be used by frontend programs via two pipes.
|
||||
|
||||
Build:
|
||||
cc -g -o frontend_pipes_xorriso frontend_pipes_xorriso.c
|
||||
|
||||
Usage:
|
||||
./frontend_pipes_xorriso [path_to_xorriso_binary]
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Local helpers of parent process */
|
||||
int await_all_replies(int fd, char *pending_mark);
|
||||
int prompt_for_command(char *line, int line_size);
|
||||
|
||||
|
||||
/* Parent and child */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int command_pipe[2], reply_pipe[2];
|
||||
pid_t cpid;
|
||||
char *xorriso_path = "/usr/bin/xorriso";
|
||||
|
||||
if (argc > 1)
|
||||
xorriso_path = argv[1];
|
||||
|
||||
if (pipe(command_pipe) == -1)
|
||||
{ perror("pipe"); exit(1); }
|
||||
if (pipe(reply_pipe) == -1)
|
||||
{ perror("pipe"); exit(1); }
|
||||
|
||||
cpid = fork();
|
||||
if (cpid == -1)
|
||||
{ perror("fork"); exit(2); }
|
||||
|
||||
if (cpid == 0) {
|
||||
/* Child redirects stdin and stdout. Then it becomes xorriso. */
|
||||
|
||||
char *xargv[8];
|
||||
|
||||
close(command_pipe[1]); /* Close unused write end */
|
||||
close(reply_pipe[0]); /* Close unused read end */
|
||||
|
||||
/* Attach pipe ends to stdin and stdout */
|
||||
close(0);
|
||||
if (dup2(command_pipe[0], 0) == -1)
|
||||
{ perror("dup2(,0)"); exit(1); }
|
||||
close(1);
|
||||
if (dup2(reply_pipe[1], 1) == -1)
|
||||
{ perror("dup2(,1)"); exit(1); }
|
||||
|
||||
xargv[0] = xorriso_path;
|
||||
xargv[1] = "-dialog";
|
||||
xargv[2] = "on";
|
||||
xargv[3] = "-pkt_output";
|
||||
xargv[4] = "on";
|
||||
xargv[5] = "-mark";
|
||||
xargv[6] = "0"; /* corresponds to mark_count = 0 in parent */
|
||||
xargv[7] = NULL;
|
||||
execv(xorriso_path, xargv);
|
||||
perror("execv"); exit(1);
|
||||
|
||||
} else {
|
||||
/* Parent prompts user for command lines and prints xorriso replies.
|
||||
It knows when all reply text of the pending command line has arrived
|
||||
by watching for -mark reply pending_mark.
|
||||
*/
|
||||
|
||||
int mark_count = 0, ret;
|
||||
char pending_mark[16], line[4096];
|
||||
|
||||
close(command_pipe[0]); /* Close unused read end */
|
||||
close(reply_pipe[1]); /* Close unused write end */
|
||||
|
||||
/* Dialog loop */
|
||||
sprintf(pending_mark, "%d", mark_count);
|
||||
while (1) {
|
||||
|
||||
/* Wait for pending mark and print all replies */
|
||||
ret = await_all_replies(reply_pipe[0], pending_mark);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
/* Prompt for command line */
|
||||
ret = prompt_for_command(line, sizeof(line));
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
/* Send line and -mark command */
|
||||
ret = write(command_pipe[1], line, strlen(line));
|
||||
if (ret == -1) {
|
||||
perror("write");
|
||||
break;
|
||||
}
|
||||
/* Produce new unique -mark text to watch for */
|
||||
mark_count++;
|
||||
sprintf(pending_mark, "%d", mark_count);
|
||||
sprintf(line, "-mark %s\n", pending_mark);
|
||||
ret = write(command_pipe[1], line, strlen(line));
|
||||
if (ret == -1) {
|
||||
perror("write");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* >>> if child is still operational: send -rollback_end */;
|
||||
|
||||
/* >>> wait a short while */;
|
||||
|
||||
/* >>> if not yet ended: kill child */;
|
||||
|
||||
wait(NULL); /* Wait for child */
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Local helpers of parent process */
|
||||
|
||||
|
||||
int await_all_replies(int fd, char *pending_mark)
|
||||
{
|
||||
int count, remainder = 0;
|
||||
char buf[32769], *line, *npt;
|
||||
|
||||
while (1) {
|
||||
count = read(fd, buf + remainder, sizeof(buf) - 1 - remainder);
|
||||
if (count == -1) {
|
||||
perror("read");
|
||||
return(-1);
|
||||
}
|
||||
if (count == 0) {
|
||||
fprintf(stderr, "+++ EOF encounterd by Master process\n");
|
||||
return(-2);
|
||||
}
|
||||
for (npt = buf + remainder; npt < buf + count; npt++) {
|
||||
if (*npt == 0) {
|
||||
fprintf(stderr,
|
||||
"+++ Protocol error : Reply contains 0-chars\n");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Split buf into lines */
|
||||
buf[remainder + count] = 0; /* for convenience */
|
||||
line = buf;
|
||||
while (1) {
|
||||
npt = strchr(line, '\n');
|
||||
if (npt == NULL) {
|
||||
/* Move line to start of buffer and set remainder */
|
||||
if (line != buf) {
|
||||
remainder = 0;
|
||||
for (npt = line; *npt; npt++)
|
||||
buf[remainder++] = *npt;
|
||||
}
|
||||
/* Now read more data in the hope to get a newline char */
|
||||
break;
|
||||
}
|
||||
/* Interpret line */
|
||||
*npt = 0;
|
||||
if (line[0] == 'M') {
|
||||
/* M-replies will be outdated until the pending command line
|
||||
is completely done and the appended -mark command gets
|
||||
into effect.
|
||||
*/
|
||||
if (strlen(line) < 6) {
|
||||
fprintf(stderr,
|
||||
"+++ Protocol error : M-channel line shorter than 6 chars\n");
|
||||
return(-1);
|
||||
}
|
||||
if (strcmp(line + 5, pending_mark) == 0) {
|
||||
if ((line - buf) + strlen(line) + 1 < count) {
|
||||
fprintf(stderr,
|
||||
"+++ Protocol error : Surplus reply data after M-match\n");
|
||||
fprintf(stderr, "%s\n", line + strlen(line) + 1);
|
||||
return(-1);
|
||||
}
|
||||
return (1); /* Expected mark has arrived */
|
||||
}
|
||||
} else if (line[0] == 'R') {
|
||||
/* R-replies are result lines of inquiry commands, like -ls.
|
||||
They should be handled by specialized code which knows
|
||||
how to parse and interpret them.
|
||||
*/
|
||||
printf("%s\n", line);
|
||||
} else {
|
||||
/* I-replies are pacifiers, notifications, warnings, or
|
||||
error messages. They should be handled by a general
|
||||
message interpreter which determines their severity
|
||||
and decides whether to bother the user.
|
||||
*/
|
||||
fprintf(stderr, "%s\n", line);
|
||||
}
|
||||
line = npt + 1;
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int prompt_for_command(char *line, int line_size)
|
||||
{
|
||||
int l;
|
||||
char *line_res;
|
||||
|
||||
fprintf(stderr, "+++ Enter a command and its parameters :\n");
|
||||
line_res = fgets(line, line_size - 1, stdin);
|
||||
if (line_res == NULL)
|
||||
return(0);
|
||||
l = strlen(line);
|
||||
if (l == 0) {
|
||||
line[0] = '\n';
|
||||
line[1] = 0;
|
||||
} else if (line[l - 1] != '\n') {
|
||||
line[l] = '\n';
|
||||
line[l + 1] = 0;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
@ -231,7 +231,8 @@ copy_files doc/partition_offset.wiki \
|
||||
create_dir "$lone_dir"/test
|
||||
copy_files \
|
||||
test/compare_file.c \
|
||||
"$lone_dir"/test/compare_file.c
|
||||
test/frontend_pipes_xorriso.c \
|
||||
"$lone_dir"/test
|
||||
|
||||
|
||||
# releng
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
# Copyright (c) 2007 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||
# Copyright (c) 2007 - 2012 Thomas Schmitt <scdbackup@gmx.net>
|
||||
# Provided under GPL version 2 or later.
|
||||
|
||||
# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4
|
||||
@ -328,6 +328,7 @@ EXTRA_DIST = \
|
||||
doc/susp_aaip_isofs_names.txt \
|
||||
doc/zisofs_format.txt \
|
||||
doc/startup_file.txt \
|
||||
test/frontend_pipes_xorriso.c \
|
||||
libisofs/aaip-os-dummy.c \
|
||||
libisofs/aaip-os-linux.c \
|
||||
libisofs/aaip-os-freebsd.c \
|
||||
|
@ -1 +1 @@
|
||||
#define Xorriso_timestamP "2012.09.08.181144"
|
||||
#define Xorriso_timestamP "2012.09.09.181723"
|
||||
|
Loading…
Reference in New Issue
Block a user