Extended new command -named_pipe_loop by mode parameter

This commit is contained in:
2013-07-04 09:47:13 +00:00
parent 09bdd74148
commit f3a37824a8
12 changed files with 236 additions and 81 deletions

View File

@ -67,6 +67,7 @@ int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize,
bit1= do not read input (but eventually write to history)
bit2= do not write to history line which begin with "-history:" or "-history "
bit3= enforce single line dialog mode
bit4= do not read from xorriso->buffered_dialog
*/
{
char *cpt= NULL, **argv= NULL, *linept, *why_append= "";
@ -77,6 +78,7 @@ int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize,
double tdiff;
struct timeval tv;
struct timezone tz;
struct Xorriso_lsT *next_lst;
gettimeofday(&tv,&tz);
tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec);
@ -85,6 +87,16 @@ int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize,
linept= line;
get_single:;
if(xorriso->buffered_dialog != NULL && !(flag & 16)) {
/* Consume next buffered line */
next_lst= Xorriso_lst_get_next(xorriso->buffered_dialog, 0);
strcpy(line, Xorriso_lst_get_text(xorriso->buffered_dialog, 0));
Xorriso_lst_destroy(&(xorriso->buffered_dialog), 0);
xorriso->buffered_dialog= next_lst;
goto process_single;
}
#ifdef Xorriso_with_readlinE
if(xorriso->use_stdin || xorriso->dev_fd_1>=0 ||
@ -121,8 +133,6 @@ get_single:;
strcpy(linept, cpt);
}
process_single:;
#else /* Xorriso_with_readlinE */
if(flag&2)
@ -138,6 +148,8 @@ process_single:;
#endif /* ! Xorriso_with_readlinE */
process_single:;
if(xorriso->dialog == 2 && !(flag & 8)) {
append_line= 0;
if(linept != line && strcmp(linept, "@@@") == 0) {
@ -3987,7 +3999,14 @@ int Xorriso_open_named_pipe(struct XorrisO *xorriso, char fd_names[3][20],
/* Usage example via bash:
in=/u/test/xorriso_stdin
out=/u/test/xorriso_stdout
mknod "$in" p
mknod "$out" p
xorriso -abort_on NEVER \
-named_pipe_loop cleanup:buffered "$in" "$out" - &
# Send command and receive result
xorriso_cmd() {
echo "$@" >/u/test/xorriso_stdin
cat </u/test/xorriso_stdout
@ -4002,14 +4021,21 @@ int Xorriso_open_named_pipe(struct XorrisO *xorriso, char fd_names[3][20],
iso_path=...arbitrary.characters...
xorriso_cmd map $(xorriso_esc "$disk_path") $(xorriso_esc "$iso_path")
*/
/* @param flag bit0= unlink pipes when the loop ends
bit1= read all lines from pipe until EOF before executing them
*/
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;
int i, ret, mem_fds[3], pipe_fds[3], first_line, hret, pipes_are_valid= 0;
int lst_ret, filling_buffer= 0;
off_t mem_used= 0, mem_needed;
struct stat stbuf;
struct Xorriso_lsT *prev_lst= NULL;
static char fd_names[3][20] = {
"standard input", "standard output", "standard error" };
char mem_text[80], limit_text[80];
if(xorriso->tolerate_stdin_eof) {
sprintf(xorriso->info_text,
@ -4048,6 +4074,7 @@ int Xorriso_named_pipe_loop(struct XorrisO *xorriso,
ret= 0; goto ex;
}
}
pipes_are_valid= 1;
while(1) {
/* Open input pipe */
@ -4059,10 +4086,52 @@ int Xorriso_named_pipe_loop(struct XorrisO *xorriso,
/* As long as the input connection exists */
xorriso->tolerate_stdin_eof= 1;
first_line= 1;
if(flag & 2) {
filling_buffer= 8 | 16; /* single line, no reading from buffered_dialog */
prev_lst= NULL;
mem_used= 0;
}
while(1) {
/* Fetch input line */
ret= Xorriso_dialog_input(xorriso, line, SfileadrL, 1);
if((flag & 2) && xorriso->buffered_dialog == NULL && !filling_buffer) {
ret= -2; /* EOF */
} else {
ret= Xorriso_dialog_input(xorriso, line, SfileadrL, 1 | filling_buffer);
}
if((flag & 2) && filling_buffer) {
/* Fetch and buffer lines before opening output pipes */
if(ret > 0) {
/* Check for excessive memory consumption */;
mem_needed= strlen(line) + 8 + sizeof(struct Xorriso_lsT);
if(mem_used + mem_needed > xorriso->temp_mem_limit) {
Sfile_scale((double) (mem_used + mem_needed), mem_text, 5, 1e4, 0);
Sfile_scale((double) xorriso->temp_mem_limit,
limit_text, 5, 1e4, 0);
sprintf(xorriso->info_text,
"-named_pipe_loop: List of buffered input lines exceeds -temp_mem_limit (%s > %s)",
mem_text, limit_text);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
"FAILURE", 0);
ret= -1; goto ex;
}
mem_used+= mem_needed;
lst_ret= Xorriso_lst_new(&prev_lst, line, prev_lst, 0);
if(lst_ret <= 0) {
Xorriso_msgs_submit(xorriso, 0,
"-named_pipe_loop: Cannot buffer all input lines", 0, "FATAL", 0);
ret= -1;
} else {
if(xorriso->buffered_dialog == NULL)
xorriso->buffered_dialog= prev_lst;
continue;
}
}
filling_buffer= 0; /* start consuming buffer */
continue;
}
/* Open output pipes late to allow the sender to open them after
the first (and usually only) input line was transmitted:
@ -4114,10 +4183,23 @@ int Xorriso_named_pipe_loop(struct XorrisO *xorriso,
ret= 1;
ex:;
xorriso->tolerate_stdin_eof= 0;
if(flag & 2)
Xorriso_lst_destroy_all(&(xorriso->buffered_dialog), 0);
/* Close any open pipes. Restore stdin, stdout and stderr. */
for(i= 0; i < 3; i++) {
if(pipe_fds[i] != -1)
if(pipe_fds[i] != -1) {
if((flag & 1) && pipes_are_valid) {
if(stat(pipe_paths[i], &stbuf) != -1) {
if(S_ISFIFO(stbuf.st_mode)) {
sprintf(xorriso->info_text, "Removing named pipe ");
Text_shellsafe(pipe_paths[i], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
unlink(pipe_paths[i]);
}
}
}
close(pipe_fds[i]);
}
if(mem_fds[i] != -1) {
close(i);
dup2(mem_fds[i], i);