1

I am writing a simple chat-room application in c using posix sockets. However I'll have this issue in sending messages.

(client1)say something: Hello folks! what are 

client2 said: xyzabc

client3 said: dsgh

Here above is the client1's terminal window where he was trying to send "Hello folks! what are you doing?" but before he could write his messsage and press enter, client2 and client3 sent something.(separate thread for receiving messages)

I'm trying to tackle this issue by using 2 different terminal windows for each client, one for writing the message and another for displaying the chat messages.

To begin with I've opened a gnome-terminal window by writing

system("gnome-terminal");

but now,

I want to perform some read write operations on the terminal window I've opened and the existing window.

printf("This is existing window"); //want to print this on existing terminal

printf("this is new terminal window"); //want to print this on new terminal

scanf("%d",&a); //take input from existing window

scanf("%d",&b); //take input from new window

I've read here that I can do it by reading/writing from proper /dev/pts/<n> file. But how do I find the n in the /dev/pts/<n> for the current terminal and the new terminal window I just opened? Is there any better way of solving the issue?

Community
  • 1
  • 1
Raman
  • 2,735
  • 1
  • 26
  • 46
  • Look into terminal libraries, such as ncurses. They allow you to have multiple "windows" within a single terminal, which can fix your issue, but require a different io pattern than simple printf/scanf functions. – Smith_61 Sep 25 '16 at 05:56
  • Maybe [this answer](http://unix.stackexchange.com/a/287725) can help – XZ6H Sep 25 '16 at 06:00
  • @Smith_61 I've used curses once before but I don't know how to open multiple windows with it. Can you be a little bit more specific as to which curses function should I use? – Raman Sep 25 '16 at 06:00
  • 1
    @ARBY I should have been more specific. Ncurses doesn't contain the ability to open multiple terminals, at least not that I know of. Instead it allows you to have much more control over where output is written into the terminal buffer. Allowing you to emulate different "sub-windows" in a single terminal instance. – Smith_61 Sep 25 '16 at 06:04
  • @Smith_61 Sounds legit. Thanks. I'm reading more about it. – Raman Sep 25 '16 at 06:07
  • @XYZProgrammer, There also the issue remains unsolved. All they have done is suggested to write a different program that sends back the output of `tty` – Raman Sep 25 '16 at 06:13

1 Answers1

2

One known good way is using the alternate interface to GNU Readline:

Some applications need to interleave keyboard I/O with file, device, or window system I/O, typically by using a main loop to select() on various file descriptors. To accomodate this need, readline can also be invoked as a `callback' function from an event loop.

The pseudocode skeleton is as follows:

  rl_callback_handler_install (prompt, my_handler)

  while true
     wait on stdin and socket (select or poll)
     if stdin is ready            
        rl_callback_read_char();
     if socket is ready
        read message from socket
        save readline state
        print message
        restore readline state

   void my_handler(char* line)            
        send line to socket

Saving and restoring readline state is

  saved_line = rl_copy_text(0, rl_end);
  rl_save_prompt();
  rl_replace_line("", 0);
  rl_redisplay();

  rl_restore_prompt();
  rl_replace_line(saved_line, 0);
  rl_point = saved_point;
  rl_redisplay();
  free(saved_line);

A complete, if rudimentary, chat program that utilises this method can bee found here.

Jongware
  • 22,200
  • 8
  • 54
  • 100
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • I took the liberty of copying a smalll snippet of that page to show *why* this is a good solution. (Nice, by the way. I'm trying to get used to use `readline` in favour of `fgets`, and this is a handy addition!) – Jongware Sep 25 '16 at 12:22
  • I've never used `readline` before. If that will do the job, I'll read it first. Will accept the solution after I've read it. Thank you. – Raman Sep 25 '16 at 18:28