Sponsored Content
Top Forums Programming terminal device control through a C/C++ program Post 302118687 by porter on Wednesday 23rd of May 2007 01:44:17 PM
Old 05-23-2007
I've looked thought my own code that does something similar and I note that after you set up the controlling terminal for a process, fds 0,1 and 2 are setup from an open of /dev/tty.

I'm not sure why you want to pass the terminal device on the command line.

This is a dump of code I was playing with a while ago.

Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ioctl.h>

#ifndef TIOCNOTTY
#include <termios.h>
#endif

static char pty_name[12];

int pty_master();
int pty_slave();
int reaper;

void handler(i)
int i;
{
	if (i==
#ifdef SIGCHLD
		SIGCHLD
#else
		SIGCLD
#endif
		)
	{
/*		reaper++;*/
	}	
}

int main(argc,argv)
int argc;
char **argv;
{
	int master=-1;
	int fd=-1;
	int pid=-1;
	int pipes[2];

	pipe(pipes);
	
	master=pty_master();

	if (master < 0) return 1;

/* disconnect */


/*	if (setpgrp(getpid(),getpid()) < 0)
	{
		perror("setpgrp");
		return 1;
	}
*/
/*	if (setsid()==-1)
	{
		perror("setsid");
		return 1;
	}
*/
/* end disconnect */	

/*	if (ioctl(master,TIOCSCTTY,NULL))
	{
		perror("TIOCSCTTY master initial");
	}
*/
	pid=fork();

	if (pid)
	{
		int status=0;
		char buf[1];
		/* master */
		buf[0]=0;
		close(pipes[1]);
		read(pipes[0],buf,sizeof(buf));
		close(pipes[0]);

		if (buf[0]==0)
		{
			printf("child reported error\n");
			return 1;
		}

#ifdef SIGCHLD
		signal(SIGCHLD,handler);
#else
		signal(SIGCLD,handler);
#endif

		while (!reaper)
		{
			fd_set fds;

			FD_ZERO(&fds);
			FD_SET(master,&fds);
			FD_SET(0,&fds);

			if (select(master+1,&fds,NULL,NULL,NULL) > 0)
			{
				if (FD_ISSET(master,&fds))
				{
					char buf[256];
					int i=read(master,buf,sizeof(buf));
					if (i > 0)
					{
						write(1,buf,i);
					}
					else
					{
						i=errno;
						break;
					}
				}

				if (FD_ISSET(0,&fds))
				{
					char buf[256];
					int i=read(0,buf,sizeof(buf));
					if (i > 0)
					{
						write(master,buf,i);
					}
					else
					{
						kill(pid,SIGHUP);
						break;
					}
				}
			}
		}

		printf("out of loop, reaper=%d\n",reaper);

		kill(pid,SIGTERM);
	}
	else
	{
		/* child */
		int slave;

/*		signal(SIGHUP,handler);
		signal(SIGTERM,handler);
		signal(SIGINT,handler);
*/
		fd=open("/dev/tty",O_RDWR);

		if (fd >= 0)
		{
			if (ioctl(fd,TIOCNOTTY,(char *)0) < 0)
			{
				perror("TIOCNOTTY /dev/tty");
			}

			close(fd);
		}
		else
		{
			perror("/dev/tty");
		}

		if (setsid() < 0)
		{
			perror("setsid");
		}

		slave=pty_slave(master);

		if (slave < 0) 
		{
			perror("pty_slave");
			return 1;
		}

/*		if (setsid()==-1)
		{
			perror("setsid(2)");
		}
*/
		if (ioctl(slave,TIOCSCTTY,NULL))
		{
			perror("slave TIOCSCTTY");
			if (ioctl(master,TIOCSCTTY,NULL))
			{
				perror("master TIOCSCTTY");
			}
		}

		{
			pid_t grp=getpgrp();
			if (ioctl(master,TIOCSPGRP,&grp))
			{
				perror("TIOCSPGRP master");
			}
			if (ioctl(slave,TIOCSPGRP,&grp))
			{
				perror("TIOCSPGRP slave");
			}
		}

		if (dup2(slave,0)==-1) { perror("dup 0") ; return 1; }
		if (dup2(slave,2)==-1) { perror("dup 2") ; return 1; }
		if (dup2(slave,1)==-1) { perror("dup 1"); return 1; }

		close(slave); 
		close(master);

		printf("[%d] on %s\n",getpid(),ttyname(0));

		fflush(stdout);

		fd=open("/dev/tty",O_RDWR);

		if (fd >= 0)
		{
			close(fd);
		}
		else
		{
			perror("open /dev/tty for TIOCSPGRP");
			return 1;
		}

		write(pipes[1],"1",1);

		close(pipes[0]);
		close(pipes[1]);

		if (argc==1)
		{
			char *argv2[2];
			char *p=getenv("SHELL");
			if (!p) p="/bin/sh";
			argv2[0]=p;
			argv2[1]=NULL;
			execvp(p,argv2);
			printf("exec(%s) failed\n",p);
			return 1;
		}
		else
		{
			execvp(argv[1],argv+1);
			printf("exec(%s) failed\n",argv[1]);
			return 1;
		}
	}

	return 0;
}


int pty_master()
{
	int i,master_fd=-1;
	char *ptr;
	struct stat statbuff;
	static char ptychar[]="pqrs";
	static char hexdigit[]="0123456789abcdef";

	for (ptr=ptychar; *ptr!=0; ptr++)
	{
		strcpy(pty_name,"/dev/ptyXY");
		pty_name[8]=*ptr;
		pty_name[9]='0';

		if (stat(pty_name,&statbuff) < 0) break;

		for (i=0;i<16;i++)
		{
			pty_name[9]=hexdigit[i];
			if ((master_fd=open(pty_name,O_RDWR))>=0)
			{
				return master_fd;
			}
		}
	}

	return master_fd;
}

int pty_slave(master_fd)
int master_fd;
{
	int slave_fd=-1;

	pty_name[5]='t';

	printf("pty_slave(%s)\n",pty_name);

	if ((slave_fd=open(pty_name,O_RDWR))<0)
	{
		close(master_fd);
		return -1;
	}

	return slave_fd;
}

 

9 More Discussions You Might Find Interesting

1. SCO

Terminal Control Database Entry

Hi, can someone pls help resolves this problem. I have an Openserver 5.0.4 running but had this error after having a power failure problem. error: cannot access termainl control database entry I have a arnetport also install with wyse 60 terminals, non of the users can have access on... (2 Replies)
Discussion started by: kayode
2 Replies

2. Shell Programming and Scripting

Terminal control from rsh

I call "rsh -l username HOSTMANE myscript.sh" from the script on TRU64 OSF1 cluster. The myscript.sh does some logic one the different cluster node and output requested info on my terminal. If I try to use commands to control output (clear, tput etc..) it just does not work. Obviously the rsh... (2 Replies)
Discussion started by: zam
2 Replies

3. UNIX for Advanced & Expert Users

Control process from different terminal (over SSH)

I pressed CTRL Z and suspended the job. then I pressed bg, The process re-started to throw output on the terminal and its not allowing me to access the prompt. its not even accepting CTRL Z. The process has been running for about 2 hours now and I want to suspend it by opening another terminal.... (3 Replies)
Discussion started by: rakeshou
3 Replies

4. Shell Programming and Scripting

Problems installing a program in Terminal

Hey First of all: I'm on a Mac. I'm quite new to this, so forgive me if i sound like a newb :-) I wish to install the Deluge BitTorrent client. First of all I installed Macports and made it run smooth. But then I ran into a problem when I should install Deluge. I can post the log, and maybe... (4 Replies)
Discussion started by: Sixmax
4 Replies

5. OS X (Apple)

Not mounted, no-driver USB device in terminal (how to access?)

hi, i am on a quest to access and even mount if possible a drive on os x. there is no driver for the device, but it lists fine in the system profiler. can i access its location from the terminal? how? here is what i get on the system profiler: Speed: Up to 480 Mb/sec Manufacturer: SAMSUNG ... (3 Replies)
Discussion started by: sontarieh
3 Replies

6. What is on Your Mind?

Any ideas on child-control program

My auntie told me that she has been suspecting that her little kids are looking at some "illegal" sites online. She put a free web blocker on the computer, but they might be finding loopholes. She wanna install some child-control program to see what's going on. There are so many since I searched... (5 Replies)
Discussion started by: Bluerosen
5 Replies

7. Fedora

How to use terminal while keeping a program open?

hi all, I open Matlab program from terminal. However, when I go back to terminal I can't do anything in it , only until Matlab is closed. Can someone please advise me on how I can oversome this problem ? thanks peter (2 Replies)
Discussion started by: peter_071
2 Replies

8. Slackware

X terminal: Redirecting remote sound to my local audio device

Hello everybody, I'm testing some aspects of X Terminal implementation and it's going great. I can use remote applications on my local slow workstation at remote's processor speed by redirecting the remote DISPLAY variable to "my_local_ip:0.0"; but i'm having troubles to get remote audio and... (2 Replies)
Discussion started by: semash!
2 Replies

9. Shell Programming and Scripting

Control from UNIX script is not returning to the Parent program

Hi All, My program flow is as below Windows batch -- > Cygwin batch --> zsh script There are multiple Cygwin batch scripts that are called from Windows batch file . But when i am executing the first cygwin batch script the control goes to the zsh file and executes and stoping from... (1 Reply)
Discussion started by: Hypesslearner
1 Replies
All times are GMT -4. The time now is 05:53 PM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy