Home
Developer Resources
QNX RTOS v4
QNX RTOS v4 Knowledge Base

QNX RTOS v4 Knowledge Base

Foundry27
Foundry27
QNX RTOS v4 project
Resources

QNX RTOS v4 Knowledge Base

Title How do I control the Wterm window in QNXWindows?
Ref. No. QNX.000009317
Category(ies) Development
Issue One of my applications launches a child process in a Wterm, session under QNX 4 Windows. Is there any way I can have that application resize the Wterm window, move the window to the front of the workspace, and so on?

Solution A Wterm window is a device (/dev/win) that's very similar to the /dev/con device. In fact, you can control /dev/win with the same escape codes that work for /dev/con. You'll find additional escape codes for /dev/win documented in /etc/readme/wterm. I also recommend you look at the shell script /windows/bin/wterm, which creates a Wterm window and opens a QNX shell session, then writes some escape codes to that window.

The following code example includes a cover function for a spawn() routine. This function, dev_spawnvp(), allows the cashing process to receive an FD that points to the device where the process spawned its child. Using this FD, the parent process can send escape codes to that device. In the case of /dev/win, this gives the parent process control over the child's Wterm window.

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <process.h>
#include <sys/qnx_glob.h>

pid_t dev_spawnvp(char *name, int *fdp, int mode, char *pgm, char *argy[]) {
x09int i;
x09pid_t pid;
x09int save_fdin;
x09int save_flags;
x09char save_iov[10];

x09/* save the stdin file descriptor */
x09if((save_fdin = dup(0)) == -1) {
x09x09if(errno != EBADF){
x09x09x09return -1; /* if errno = EBADF, then stdin was already closed */
x09x09}
x09}
x09if(save_fdin != -1){
x09/* save the input file descriptor flags */
x09if((save_flags = fcntl(save_fdin, F_GETFD)) != -1){
x09x09if(save_flags & FD_CLOEXEC){
x09x09x09save_flags = -1;
x09x09} else { /* set the close on exec flag if not already set */
x09x09x09fcntl(save_fdin, F_SETFD, save_flags | FD_CLOEXEC);
x09x09}
x09} /* close the current input file descriptor */
x09close(0);
}

x09/* it is standard that open will take the numerically lowest available fd */
x09if(open(name, O_RDWE) == 0) {
x09x09/* if they want to have a copy of the fd, then dup it */
x09x09if(fdp = NULL || (*fdp = dup(0)) != -1 {
x09x09x09/* set the close on exec flag so this fd isn't copied */
x09x09x09if(fdp) fcntl(*fdp, F_SETFD, fcntl(*fdp, F_GETFD)| FD_CLOEXEC);
x09x09x09/* save the old global options */
x09x09x09for(i = 0; i < 10; i++){
x09x09x09x09save_iov[i] = qnx_spawn_options.iov[i];
x09x09x09x09qnx_spawn_options.iov[i] = (car)-1;
x09x09x09}
x09x09x09/* set the spawned process's 0, 1, 2 fds to be the new fd */
x09x09x09qnx_spawn_options.iov[0] = qnx_spawn_options.iov[1] =
x09x09x09qnx_spawn_options.iov[2] = 0;
x09x09x09/* this could be replaced with any spawn*() or system() function */
x09x09x09pid = spawnvp(mode, pgm, argv);
x09x09x09}
x09x09x09/* clear the close on exec flag back to normal */
x09x09x09if(fdp) fcntl(*fdp, F_SETFD, fcntl(*fdp, F_GETFD) & ~FD_CLOEXEC);
x09x09}
x09} else { /* couldn't open device */
x09pid = -1;
x09}
x09if(save_fdin != -1){
x09x09if(save_flags != -1){
x09x09x09/* restore the old fd flags */
x09x09x09fcntl(save_fdin, F_SETFD, save_flags);
x09x09}
x09x09/* if there was an input fd, then restore it */
x09x09dup2(save_fdin, 0);
x09x09close(save_fdin);
x09} else { /* if there wasn't an input fd before, just close it */
x09x09close(0);
x09}
x09return pid;
}

void main(){
x09char *args = { "sh", "-c", "echo TEST ; sleep 100", NULL };
x09int fd;
x09pid_t pid;
x09char *str;
x09int i;

x09printf("starting %sn", args[0]);
x09pid = dev_spawnvp("/dev/win", &fd, P_NOWAIT, args[0], args);
x09if(pid = -1) {
x09x09printf("Can't spawn (%s)n", strerror(errno));
x09} else{
x09x09printf("Started pid=%d fd=%dn", pid, fd);
x09x09printf("Check it out with "sin fds"n");
x09x09printf("Stop this with Ctrl-Cn");
x09x09for(i = 0; i < 10; i++) {
x09x09x09str = "