![]() |
|
|
|
|
|||||||
| Forums | Portal | Register | Forum Rules | FAQ | Contribute | Members List | Arcade | Search | Today's Posts | Mark Forums Read |
| High Level Programming Post questions about C, C++, Java, SQL, and other programming languages here. |
|
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Problems installing a program through Terminal in Mac OS X | Sixmax | UNIX for Dummies Questions & Answers | 1 | 05-12-2008 08:52 AM |
| Problems installing a program in Terminal | Sixmax | Shell Programming and Scripting | 4 | 04-10-2008 09:05 AM |
| Control process from different terminal (over SSH) | rakeshou | UNIX for Advanced & Expert Users | 3 | 12-19-2007 04:48 PM |
| Terminal control from rsh | zam | Shell Programming and Scripting | 2 | 09-22-2005 04:07 PM |
| Terminal Control Database Entry | kayode | SCO | 2 | 10-23-2003 02:58 AM |
|
|
Submit Tools | LinkBack | Thread Tools | Display Modes |
|
|||
|
terminal device control through a C/C++ program
Hi,
I want to fork a new process from a daemon that needs terminal attachment to some ttyN or pts/N device. Here is the code #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <string.h> int main(int argc, char **args) { char *con = args[1]; printf("\nStart demonizing ...\n"); int i = fork(); if (i == 0) { close (0); close (1); close (2); setsid(); int j = fork(); if (j == 0) { setsid(); //int in = open(con, O_RDWR); int in = open(con, O_RDONLY); int ou = open(con, O_WRONLY); dup2(in, fileno(stdin)); dup2(ou, fileno(stdout)); dup2(ou, fileno(stderr)); printf("\n input :"); stdin = fdopen(0, "r"); stdout = fdopen(1, "w"); stderr = fdopen(2, "w"); char tmp[100]; strcpy(tmp, ""); //gets(tmp); fread(tmp, sizeof(tmp), 1, stdin); printf("\n output : %s\n", tmp); } exit(0); } } The program takes a single command line argument - the name of the terminal device special file, in my case that will be /dev/"pts/1". The problem is that, the inner most spawned child does the output on the pts/1 terminal successfully, but it fails to take input from it. Anyone can help here. Last edited by ku@ntum; 05-23-2007 at 04:28 AM. |
| Forum Sponsor | ||
|
|
|
|||
|
1. Use one descriptor opened read/write and use it for stdin/stdout/stderr rather than opening twice.
as in the single "open(con,O_RDWR)" 2, try using write and read to confirm input/output before using the stdio APIs. 3. Also, check that you actually need the dup2s, as you have already done close(0/1/2) try fd=open(con,O_RDWR); dup2(1,fd); dup2(2,fd); |
|
|||
|
Not working
The dup2() system call takes the oldfd as first argument. According to that, int in = open(con, O_RDWR); However I have change the code to int main(int argc, char **args) But the problem remains. The same. Please help. |
|
|||
|
I disagree. This is referring to psuedo terminals not serial ports.
This is exactly the procedure that W. Richard Stevens describes in his UNIX Network Programming volume. I think you need some error checking in the code to see what is failing. What operating system is this for? |
|
|||
|
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;
}
|
|||
| Google The UNIX and Linux Forums |