New command -named_pipe_loop

This commit is contained in:
2013-06-30 16:00:40 +00:00
parent 138098bda3
commit 4c6fa3a86a
13 changed files with 298 additions and 35 deletions

View File

@ -87,11 +87,14 @@ int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize,
get_single:;
#ifdef Xorriso_with_readlinE
if(xorriso->use_stdin || xorriso->dev_fd_1>=0) {
if(xorriso->use_stdin || xorriso->dev_fd_1>=0 ||
xorriso->tolerate_stdin_eof) {
if(flag&2)
{ret= 1; goto ex;}
if(Sfile_fgets_n(linept,linesize - base_length - 1, stdin,
(xorriso->dialog == 2)) == NULL) {
if(xorriso->tolerate_stdin_eof)
{ret= -2; goto ex;}
/* need a very dramatic end */
kill(getpid(),SIGHUP);
{ret= -1; goto ex;}
@ -126,6 +129,8 @@ process_single:;
{ret= 1; goto ex;}
if(Sfile_fgets_n(linept, linesize - base_length - 1, stdin,
(xorriso->dialog == 2)) == NULL) {
if(xorriso->tolerate_stdin_eof)
{ret= -2; goto ex;}
/* need a very dramatic end */
kill(getpid(),SIGHUP);
{ret= -1; goto ex;}
@ -3949,3 +3954,168 @@ ex:;
return(ret);
}
int Xorriso_open_named_pipe(struct XorrisO *xorriso, char fd_names[3][20],
int mem_fds[], char *pipe_paths[], int pipe_fds[],
int i, int flag)
{
if(mem_fds[i] == -1)
return(2);
pipe_fds[i]= open(pipe_paths[i], i == 0 ? O_RDONLY : O_WRONLY);
if(pipe_fds[i] == -1) {
sprintf(xorriso->info_text,
"-named_pipe_loop: Failed to open %s pipe ", fd_names[i]);
Text_shellsafe(pipe_paths[i], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
return(0);
}
close(i);
dup2(pipe_fds[i], i);
return(1);
}
/* Usage example via bash:
xorriso_cmd() {
echo "$@" >/u/test/xorriso_stdin
cat </u/test/xorriso_stdout
}
# Transport safety of filenames by wrapping in quotes and escaping quotes
xorriso_esc() {
echo -n "'"
echo -n "$1" | sed -e "s/'/'"'"'"'"'"'"'/g"
echo -n "'"
}
disk_path=...arbitrary.characters...
iso_path=...arbitrary.characters...
xorriso_cmd map $(xorriso_esc "$disk_path") $(xorriso_esc "$iso_path")
*/
int Xorriso_named_pipe_loop(struct XorrisO *xorriso,
char *pipe_paths[3], int flag)
{
char *line= NULL;
int i, ret, mem_fds[3], pipe_fds[3], first_line, hret;
struct stat stbuf;
static char fd_names[3][20] = {
"standard input", "standard output", "standard error" };
if(xorriso->tolerate_stdin_eof) {
sprintf(xorriso->info_text,
"Already in -named_pipe_loop. Ignoring further -named_pipe_loop command.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
return(0); /* intentionally not goto ex */
}
Xorriso_alloc_meM(line, char, SfileadrL);
for(i= 0; i < 3; i++ )
mem_fds[i]= pipe_fds[i]= -1;
/* Memorize stdin, stdout, and stderr. Close originals. */
for(i= 0; i < 3; i++ ) {
if(pipe_paths[i][0] == 0 || strcmp(pipe_paths[i], "-") == 0)
continue;
if(stat(pipe_paths[i], &stbuf) == -1) {
sprintf(xorriso->info_text,
"-named_pipe_loop: Cannot determine properties of file ");
Text_shellsafe(pipe_paths[i], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex;
}
if(!S_ISFIFO(stbuf.st_mode)) {
sprintf(xorriso->info_text,
"-named_pipe_loop: File is not a named pipe: ");
Text_shellsafe(pipe_paths[i], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
mem_fds[i]= dup(i);
if(mem_fds[i] == -1) {
sprintf(xorriso->info_text,
"-named_pipe_loop: Cannot duplicate original %s", fd_names[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex;
}
}
while(1) {
/* Open input pipe */
ret= Xorriso_open_named_pipe(xorriso, fd_names, mem_fds, pipe_paths,
pipe_fds, 0, 0);
if(ret <= 0)
goto ex;
/* As long as the input connection exists */
xorriso->tolerate_stdin_eof= 1;
first_line= 1;
while(1) {
/* Fetch input line */
ret= Xorriso_dialog_input(xorriso, line, SfileadrL, 1);
/* Open output pipes late to allow the sender to open them after
the first (and usually only) input line was transmitted:
echo ... >stdin_pipe
res=$(cat <stdout_pipe)
This will work independently of the stdin_pipe buffer size.
*/
if(first_line) {
first_line= 0;
for(i= 1; i < 3; i++) {
hret= Xorriso_open_named_pipe(xorriso, fd_names, mem_fds, pipe_paths,
pipe_fds, i, 0);
if(hret <= 0 && ret > 0)
{ret= hret; goto ex;}
}
}
/* Now evaluate outcome of Xorriso_dialog_input() */
if(ret == -2) /* EOF at stdin */
break;
if(ret <= 0) /* Other error */
goto ex;
/* Regular end of command */
if(strcmp(line, "end_named_pipe_loop") == 0)
{ret= 1; goto ex;}
/* Perform xorriso command */
ret= Xorriso_execute_option(xorriso, line, (1 << 16));
if(ret <= 0)
goto ex;
if(ret == 3) /* e.g. -end command */
goto ex;
Xorriso_mark(xorriso,0);
}
/* Restore stdin, stdout and stderr */
for(i= 0; i < 3; i++) {
if(mem_fds[i] != -1) {
if(pipe_fds[i] != -1)
close(pipe_fds[i]);
pipe_fds[i]= -1;
close(i);
dup2(mem_fds[i], i);
}
}
}
ret= 1;
ex:;
xorriso->tolerate_stdin_eof= 0;
/* Close any open pipes. Restore stdin, stdout and stderr. */
for(i= 0; i < 3; i++) {
if(pipe_fds[i] != -1)
close(pipe_fds[i]);
if(mem_fds[i] != -1) {
close(i);
dup2(mem_fds[i], i);
close(mem_fds[i]);
}
}
Xorriso_free_meM(line);
return(ret);
}