01-23-04 10: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
[ Post a follow-up to this message ]
|