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
CC := $(shell which colorgcc || which cc)

CPPFLAGS +=
CFLAGS += -Wall -ggdb
LDFLAGS += -lcurses

all: cscreen

cscreen: cscreen.c

clean:
        $(RM) cscreen
#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;
}

Attachment: signature.asc
Description: Digital signature

Reply via email to