output to terminal

How can I write to another user's pseudo tty, but not to its current prompt position (as in open("/dev/pts007", ...) followed by write() ). Instead I would like to write to the top center of the screen using color red, for example. Like curses, but from another console.

There is no way to do that without encountering unsolvable problems.

If you have write permission, you can spit out a sequence of characters and hope for the best. wall does that and the message is sometimes garbled.

You can ask the user to shutdown his program and run a program that you wrote instead. This program can read his environment and learn how to configure his terminal. talk does that and it works fairly well.

And not all terminals can display red characters.

Thank you for your reply
I'm asking because I've seen something along these lines done. The program is writing warnings each minute for a period of time to all the consoles that are running a specific process. From the list of procs it obtains a list of pts. The sending is multithreaded and sincronized by semaphores. I do not know how it actually writes to the other consoles. With nm I get:
...
|FUNC |GLOB |0 |8 |warnuser
|FUNC |GLOB |0 |UNDEF |close
|FUNC |GLOB |0 |UNDEF |strcat
|OBJT |GLOB |0 |ABS |_edata
|FUNC |GLOB |0 |UNDEF |write
|FUNC |GLOB |0 |UNDEF |sleep
|FUNC |GLOB |0 |UNDEF |sema_wait
|FUNC |GLOB |0 |UNDEF |atexit
|FUNC |GLOB |0 |8 |main
|FUNC |GLOB |0 |UNDEF |fputs
|FUNC |GLOB |0 |UNDEF |fgets
|OBJT |GLOB |0 |9 |_lib_version
|OBJT |GLOB |0 |17 |___Argv
|FUNC |GLOB |0 |UNDEF |strlen
|FUNC |GLOB |0 |UNDEF |_cleanup
|FUNC |GLOB |0 |8 |_start
|FUNC |GLOB |0 |UNDEF |strtok
|FUNC |GLOB |0 |UNDEF |thr_create
|OBJT |GLOB |0 |ABS |_etext
|FUNC |GLOB |0 |UNDEF |sprintf
|FUNC |GLOB |0 |UNDEF |open
|FUNC |GLOB |0 |11 |_init
|OBJT |WEAK |0 |14 |environ
|OBJT |GLOB |0 |14 |thr_sync
|FUNC |GLOB |0 |UNDEF |exit
|OBJT |GLOB |0 |ABS |_DYNAMIC
|OBJT |GLOB |0 |ABS |_end
|FUNC |GLOB |0 |12 |_fini
|FUNC |GLOB |0 |UNDEF |fclose
|OBJT |GLOB |0 |UNDEF |errno
|FUNC |GLOB |0 |UNDEF |_fpstart
|FUNC |GLOB |0 |UNDEF |fopen
|FUNC |GLOB |0 |UNDEF |sema_post
|FUNC |GLOB |0 |UNDEF |system
|OBJT |GLOB |0 |ABS |_GLOBAL_OFFSET_TABLE

|OBJT |GLOB |0 |14 |_environ

It sounds like it is contacting that specific process and requesting that a message be displayed. That is similiar to the talk model. Since you're on SunOS, you can use truss to see exactly what it is doing.

Actually it's OpenUnix Caldera but truss works just the same.
Here is the interesting part:

12562:  open("/dev/pts/8", O_WRONLY, 0)                 = 4               
12562:  sigprocmask(SIG_SETMASK, 0xA7F6C2A0, 0x00000000) = 0              
12562:  write(4, 0xA7F4693C, 39)                        = 39              
12562:    1B [ s1B [ 1 ; 3 8 H1B [ 3 1 ; 1 m Y o u   s t i l l   h a v e   
12562:     5 m i n1B [ u    

So I guess these are control sequences at the beginning/end. Are they hex? There is a special .tinfo file but the entries are of the type:
...
kf2=\E[N, kf3=\E[O
...

When truss is displaying a string, it will display the character if it is printable and it puts a space between the letters. If the character is not printable is outputs in hex and in this case it will need two positions, so you lose the space.

1B is an escape character. You can see it (maybe) with "man ascii". Octal is a little more common in the unix world. You can convert hex to octal via bc. Quick example:
echo "obase=8;ibase=16;1B" | bc

Those are usually called escape sequences. Once you know that an escape is 33 in octal, you can model this in ksh:

#! /usr/bin/ksh
print -n '\033[s\033[1;38H\033[31;1mYou still have 5 min\033[u
sleep 5
exit 0

The sleep will delay the printing of your prompt long enough to see what happened. The first and last escape sequences are mysteries to me. The second moves the cursor. The third is an sgr (select graphic rendition) The 1 goes to bold mode. I have no idea what the 31 is supposed to do. It is a nop with my xterm. And this leaves my terminal in bold mode. I had to do a "tput sgr0" to fix it.

But if I was using hpterm instead of xterm, this would not work at all. That is the problem with this sort of thing, you must guess at the user's terminal.

Thanks,
I think they are:
1B [ s sc to save cursor
1B [ 1 ; 3 8 H cup to position cursor
1B [ 3 1 ; 1 m changes color to red
1B [ u rc to restore cursor