|
Home > Archive > Unix Programming > January 2004 > problem obtaining new controlling terminal
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
problem obtaining new controlling terminal
|
|
| John Milton 2004-01-23, 5:23 pm |
| I'm trying to assign a new controlling terminal to a forked process
under solaris 8 and so far have had only limited success. I can tell
that the process detaches from the original controlling terminal and
creates / connects to a new terminal as it can run a 'who -m' (which
won't work without a terminal).
Trouble is, I don't think the new terminal becomes the controlling
terminal because a) ps shows the tty as "??" b) the output from the
'who -m' doesn't show the tty either, and c) an fuser on the slave's
name shows me that my process has it open but doesn't have the 'y'
indicating that it's the process's controlling terminal.
I'm new to this but from what I understand, there are three things you
need to do to end up with a new controlling terminal:
1) become a process group leader
2) have no current controlling terminal
3) open a terminal device that isn't already another process's
controlling terminal
1 and 2 are guaranteed by forking and then running setsid (or setpgrp)
from the child.
3 can be verified using fuser.
So as far as I can tell, I've met all three criteria but still don't
get a controlling terminal.
Any advice on where I'm going wrong below would be greatly
appreciated! (Actually, I'm also interested to know the difference
between ps reporting ?? as the tty instead of just the single ? - the
man page doesn't say)
Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stropts.h>
void replaceterminal() {
int fdm,fds;
char *slavename;
extern char *ptsname();
if(setsid()==-1) {
perror("setsid failed");
exit(1);
}
if((fdm=open("/dev/ptmx", O_RDWR))==-1) { /* open master */
perror("open failed - master");
exit(1);
}
grantpt(fdm); /* change permission of
slave */
unlockpt(fdm); /* unlock slave */
slavename = ptsname(fdm); /* get name of slave */
if((fds=open(slavename,O_RDWR))==-1) { /* open slave */
perror("open failed - slave");
exit(1);
}
if((ioctl(fds, I_PUSH, "ptem"))==-1) { /* push ptem */
perror("ioctl() ptem");
exit(1);
}
if((ioctl(fds, I_PUSH, "ldterm"))==-1) { /* push ldterm*/
perror("ioctl() ldterm");
exit(1);
}
dup2(fds,0);
dup2(fds,1);
dup2(fds,2);
}
void main(void) {
if(fork()==0) {
replaceterminal();
while(1) {
system("who -m >> output.txt 2>> errors.txt");
sleep(5);
}
} else {
exit(0);
}
}
| |
| Joseph Dionne 2004-01-23, 5:23 pm |
| John Milton wrote:quote:
> I'm trying to assign a new controlling terminal to a forked process
> under solaris 8 and so far have had only limited success. I can tell
> that the process detaches from the original controlling terminal and
> creates / connects to a new terminal as it can run a 'who -m' (which
> won't work without a terminal).
>
> Trouble is, I don't think the new terminal becomes the controlling
> terminal because a) ps shows the tty as "??" b) the output from the
> 'who -m' doesn't show the tty either, and c) an fuser on the slave's
> name shows me that my process has it open but doesn't have the 'y'
> indicating that it's the process's controlling terminal.
>
> I'm new to this but from what I understand, there are three things you
> need to do to end up with a new controlling terminal:
> 1) become a process group leader
> 2) have no current controlling terminal
> 3) open a terminal device that isn't already another process's
> controlling terminal
>
> 1 and 2 are guaranteed by forking and then running setsid (or setpgrp)
> from the child.
> 3 can be verified using fuser.
>
> So as far as I can tell, I've met all three criteria but still don't
> get a controlling terminal.
>
> Any advice on where I'm going wrong below would be greatly
> appreciated! (Actually, I'm also interested to know the difference
> between ps reporting ?? as the tty instead of just the single ? - the
> man page doesn't say)
> Thanks.
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <unistd.h>
> #include <stropts.h>
>
> void replaceterminal() {
>
> int fdm,fds;
> char *slavename;
> extern char *ptsname();
>
> if(setsid()==-1) {
> perror("setsid failed");
> exit(1);
> }
> if((fdm=open("/dev/ptmx", O_RDWR))==-1) { /* open master */
> perror("open failed - master");
> exit(1);
> }
> grantpt(fdm); /* change permission of
> slave */
> unlockpt(fdm); /* unlock slave */
> slavename = ptsname(fdm); /* get name of slave */
> if((fds=open(slavename,O_RDWR))==-1) { /* open slave */
> perror("open failed - slave");
> exit(1);
> }
> if((ioctl(fds, I_PUSH, "ptem"))==-1) { /* push ptem */
> perror("ioctl() ptem");
> exit(1);
> }
> if((ioctl(fds, I_PUSH, "ldterm"))==-1) { /* push ldterm*/
> perror("ioctl() ldterm");
> exit(1);
> }
> dup2(fds,0);
> dup2(fds,1);
> dup2(fds,2);
>
> }
>
> void main(void) {
> if(fork()==0) {
> replaceterminal();
> while(1) {
> system("who -m >> output.txt 2>> errors.txt");
> sleep(5);
> }
> } else {
> exit(0);
> }
> }
Check out fcntl(), and use it to set your process as the owner of the
psuedo terminal
http://mkssoftware.com/docs/man3/fcntl.3.asp
|
|
|
|
|