Skip to content

Instantly share code, notes, and snippets.

@semireg
Created March 13, 2013 20:52
Show Gist options
  • Select an option

  • Save semireg/5156040 to your computer and use it in GitHub Desktop.

Select an option

Save semireg/5156040 to your computer and use it in GitHub Desktop.
The goal is to make the screen printcmd bidirectional. That is, the output from printcmd should be sent back to the remote (host) terminal.
Open 4 terminals, A (host), B (client), C (print log), and D (socat).
Create file ~/.screenrc and include line:
printcmd "/tmp/screenprint.sh"
Create file /tmp/screenprint.sh and make executable with contents:
#!/bin/bash
echo "Started"
cat >> /tmp/screenprint.out
echo "Finished"
From terminal D, type:
cd /tmp; socat -b 1024 pty,raw,echo=0,link=a pty,raw,echo=0,link=b
From terminal C, type:
cd /tmp; touch screenprint.out; tail -f screenprint.out
From terminal B, type:
cd /tmp; screen -m -S b ./b
From terminal A, type:
cd /tmp; screen -m -S a ./a
Verify:
Type "Hello" on terminal A and terminal B should display: Hello
Type "Hello" on terminal B and terminal A should display: Hello
Test from Terminal A:
Press ESC key and type text: [5i
Type "Testing Printing"
Press ESC key and type text: [4i
Type "Done"
Current Results:
Terminal A: Nothing
Terminal B: Done
Terminal C: Testing Printing
Ideal Results:
Terminal A: Started\nFinished (output from screenprint.sh)
Terminal B: Done
Terminal C: Testing Printing
Proposed changes:
1) STDOUT of printcmd needs to be sent to the originating terminal (host).
2) Print data from host --> client/printcmd should not be buffered. Print data should be sent immediately to printcmd instead of waiting for buffer to fill or ESC[4i.
3) printcmd should terminate when ESC[4i is received
4) client input should be buffered until control is restored (ESC[4i)
As you know, I can barely breathe in a C environment. Here are some source files of note.
fileio.c
printpipe(p, cmd)
struct win *p;
char *cmd;
{
int pi[2];
if (pipe(pi))
{
WMsg(p, errno, "printing pipe");
return -1;
}
switch (fork())
{
case -1:
WMsg(p, errno, "printing fork");
return -1;
case 0:
display = p->w_pdisplay;
displays = 0;
#ifdef DEBUG
if (dfp && dfp != stderr)
fclose(dfp);
#endif
close(0);
dup(pi[0]);
closeallfiles(0);
if (setgid(real_gid) || setuid(real_uid))
Panic(errno, "printpipe setuid");
#ifdef SIGPIPE
signal(SIGPIPE, SIG_DFL);
#endif
execl("/bin/sh", "sh", "-c", cmd, (char *)0);
Panic(errno, "/bin/sh");
default:
break;
}
close(pi[0]);
return pi[1];
}
and … ansi.c
switch (curr->w_state)
{
case PRIN:
switch (c)
{
case '\033':
curr->w_state = PRINESC;
break;
default:
PrintChar(c);
}
break;
case PRINESC:
switch (c)
{
case '[':
curr->w_state = PRINCSI;
break;
default:
PrintChar('\033');
PrintChar(c);
curr->w_state = PRIN;
}
break;
case PRINCSI:
switch (c)
{
case '4':
curr->w_state = PRIN4;
break;
default:
PrintChar('\033');
PrintChar('[');
PrintChar(c);
curr->w_state = PRIN;
}
break;
case PRIN4:
switch (c)
{
case 'i':
curr->w_state = LIT;
PrintFlush();
if (curr->w_pdisplay && curr->w_pdisplay->d_printfd >= 0)
{
close(curr->w_pdisplay->d_printfd);
curr->w_pdisplay->d_printfd = -1;
}
curr->w_pdisplay = 0;
break;
default:
PrintChar('\033');
PrintChar('[');
PrintChar('4');
PrintChar(c);
curr->w_state = PRIN;
}
break;
@PaulCapestany

Copy link
Copy Markdown

I'm not sure I totally get the goal here, but I'm intrigued.

What would be an example of a practical use case for what you're trying to do?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment