Re: Shared screen for help with simultaneous debugging
Fernando Vezzosi <[email protected]> Sun, 15 Jun 2008 20:59:24 +0200
| Newsgroups | gmane.comp.gnu.screen |
|---|---|
| Message-ID | <20080615185923.GA16931__38920.3650215224$1238089004$gmane$org@lothlorien.passione> |
Hi, You should not hit the «reply» button, when starting a new thread. On Sun, Jun 15, 2008 at 10:29:27PM +0530, Kumar Rangarajan wrote: > My company works on doing a lot of migration related work, and we do a > lot of unix to unix migrations. While my attached code will not help you on exotic Unices, it definitely works on Linux, and I believe it does on BSD. It uses the TIOCSTI sysctl on the term devices. It may trash the terminal from where you run it. Just `reset`. :) > Here is where I wanted to see if I could improve things. What if the two > screen windows ran on a 'shared keyboard' session. Ie irrespective of > which window I am, the key strokes typed on that window should be made > visible to all its 'shared' sessions. So basically if I type 'next' on > one debugger session, the same command should be made available to the > other window too. > Is there such an option already available under screen ? Not that I know of, but the command «stuff» lets you insert characters/strings into another window's input buffer. I would use that. You might want to look into its implementation. Looping over a series of windows, and calling "stuff" for each of them, sounds like doable. Alternatively, see the attached code. You may need to run it as root. (on pts/5)$ ./cscreen -t /dev/pts/3 -t /dev/pts/4 Whatever you type into cscreen pts/5 (yes also control characters), gets sent to pts/3 and pts/4. Of course if you switch to pts/3 and type something, only pts/3 sees it. I've been using this across clusters, and whatnot. It exits on ^C, so I've never used it for gdb. You may need to tweak signal handling and/or curses interaction. > If not, I would certainly be interested to work on this. But I am a > complete novice on screen development and its source base. Any pointers > on where I should start to understand screen and its source base and also > pointers for this particular enhancement would be really great. comm.c and process.c are the best candidates, IMHO. Cheers, -- Fernando Vezzosi 3F29 4D20 510E E1AE 991D 3B12 D6BE 7C05 B289 97C9
Makefile
(text/plain, 154 B)
CC := $(shell which colorgcc || which cc) CPPFLAGS += CFLAGS += -Wall -ggdb LDFLAGS += -lcurses all: cscreen cscreen: cscreen.c clean: $(RM) cscreen
cscreen.c
(text/x-csrc, 3.4 KB)
#define _GNU_SOURCE 1
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <linux/vt.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <curses.h>
/* #include <menu.h> */
/*REQ_DOWN_ITEM*/
/* if(ioctl(fd, TIOCSTI, str+i) == -1){*/
typedef struct termentry {
int fd;
int active;
char * device_name;
struct termentry * next;
} termentry;
termentry *term_head=NULL;
void dump_termentry(termentry * t){
fprintf(stderr, "{ fd=%d, active=%d, device_name=\"%s\", next=%p }\n",
t->fd, t->active, t->device_name, t->next);
}
/* add a terminal to our linked-list of devices */
int term_add (char * device_name){
termentry * prev, *ptr;
if(!term_head){
ptr = (termentry *) malloc(sizeof(termentry));
term_head = ptr;
}else{
for(ptr=term_head; ptr->next; prev=ptr, ptr=ptr->next)
; /* walk list till last element */
ptr->next = (termentry *) malloc(sizeof(termentry));
ptr = ptr->next;
}
if(!ptr){
fprintf(stderr, "Out of mem\n");
exit (1);
}
ptr->next = NULL;
ptr->fd = open(device_name, O_RDWR);
if(ptr->fd == -1){
fprintf(stderr, "Couldnt add term \"%s\": %s\n",
device_name, strerror(errno));
free (ptr);
return 1;
}
ptr->active = 1;
ptr->device_name = (char *) malloc(strlen(device_name) + 1);
if(!ptr->device_name){
fprintf(stderr, "[2] Couldnt add term \"%s\": %s\n",
device_name, strerror(errno));
free (ptr);
return 1;
}
strncpy(ptr->device_name, device_name, strlen(device_name));
dump_termentry(ptr);
return 0;
}
/* XXX buggy */
int term_del_byname (char * device_name){
termentry * prev=NULL, * ptr=NULL;
if(!term_head){
fprintf(stderr, "No devices were added\n");
return 1;
}
for(ptr=term_head;
ptr && (strcmp(ptr->device_name, device_name) != 0);
prev=ptr, ptr=ptr->next)
; /* walk til the term to remove is ptr */
if(!ptr){
fprintf(stderr, "Device \"%s\" not in my list!\n", device_name);
return 1;
}
dump_termentry(ptr);
/* remove from linked list */
if(prev)
prev->next = ptr->next;
else
term_head = ptr->next;
close(ptr->fd);
ptr->active = 0;
free(ptr->device_name);
free(ptr);
printf(" removed %s\n", device_name);
return 0;
}
int term_del_all(){
termentry * prev, * ptr;
if(!term_head){
fprintf(stderr, "No devices were added\n");
return 1;
}
for(ptr=term_head; ptr; prev=ptr, ptr=ptr->next)
term_del_byname(ptr->device_name);
return 0;
}
void write_term(int fd, const char * str, unsigned int size){
int i=0;
for(i=0; i<size; i++){
if(ioctl(fd, TIOCSTI, str+i) == -1){
fprintf(stderr, "couldnt ioctl (%d:%s)\n", errno, strerror(errno));
exit(1);
}
}
}
int send_key (char key){
termentry * ptr=NULL;
for(ptr=term_head; ptr; ptr=ptr->next){
/* printf("sending %s to %s..\n", key, ptr->device_name);*/
write_term(ptr->fd, &key, 1);
}
return 0;
}
int main(int argc, char ** argv){
char c='\0';
while( (c=getopt(argc, argv, "t:h")) != -1 )
switch(c){
case 't':
term_add(optarg);
break;
case 'h':
printf("yuo need help\n");
break;
default:
exit(1);
break;
}
initscr();
while((c=(char)getch()) != ERR)
send_key(c);
term_del_all();
return 0;
}
signature.asc
(application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFIVWaL1r58BbKJl8kRAhzEAJ9+CO3LDhuNwXDMCoKhOc0+2A6SwwCaAntb 2dNI8iqHf9/zh85994NfRmQ= =Q9m/ -----END PGP SIGNATURE-----