valder@gmdzi.UUCP (Wilhelm Valder) (06/21/88)
Does anyone know how to determine the current working directory (CWD) of a son-process in UNIX. Any hints, comments, solutions are appreciated. The problem: In our current implementation of a command listener, we have one process that builds up a command line and sends it to a son process (normally /bin/sh or /bin/sh) that has been forked and exec'd during startup. The two processes communicate via pseudo ttys (pty's). The command listener in turn should provide a set of facilities to ease command formulation. Two of these facilities are: expansion of regular expressions into a string of file names and file name completion. Whenever the user requests the command listener to complete a partial file name, this name is replaced by its completed file name (if such a completion exists). For this purpose the command listener must know the current working directory of the son process. Up to now I have found no solution to this problem. The only thing I have found is an entry in the user-structure of a process that holds some information about the current directory of this process (namely the entry 'u_cdir'). Unfortunately, this entry is actually a pointer to a structure of type 'vnode' and I see no way to get the name of the coresponding directory or to even read the contents of this directory. I would be very grateful if anybody could give me a hint how to solve this problem or to state the problem is unsolvable. BTW, we are implementing on a SUN3/75 running SUN-OS 3.4. Thanks in advance for any assistance. --------------------------------------------------------------------------------- Willi Valder GMD / F2.G2 Schloss Birlinghoven D-5205 Sankt Augustin 1, FRG phone: (+49 2241) 14-2590 email: valder%gmdzi&mcvax
mesard@bbn.com (Wayne Mesard) (06/22/88)
[ N.B. followups to wizards.] From article <579@gmdzi.UUCP>, by valder@gmdzi.UUCP (Wilhelm Valder): > Does anyone know how to determine the current working directory (CWD) of > a son-process in UNIX. Any hints, comments, solutions are appreciated. > > The problem: In our current implementation of a command listener, we > have one process that builds up a command line and sends it to a son > process (normally /bin/sh or /bin/sh) that has been forked and exec'd > during startup. The two processes communicate via pseudo ttys (pty's). Geez, why don't you hack the shell source? Well, none of my business I suppose. Anyway, I was in the same situation when I was writing a UNIX [BSD] tutorial last summer on CMU's Andrew system. I had the tutorial running in one window, and a shell in another. The tutorial had to listen to what the user typed and provid helpful information. The communication worked almost like yours except I had a third program involved. What I did was this: o At startup, the tutorial opens a pipe stream to a "voyeur" program which acts as an intermediary between the shell and the tutorial, and between the user and the shell. Before making the call, the tutorial ensures that its stderr goes to the same place as its stdout (see below) (via dup(2)). o The voyeur then sets up a pty and forks a shell which it could talk and listen to via the pty. ------------ ------------ ------------ | | pipe | | pty | | | Tutorial |<======= | Voyeur | <========> | Shell | | | (V's | | (Shell's | | ------------ stdout) ------------ stdout,in ------------ ^ | & err) stdin | | stderr | V So, in voyeur's main loop: o It does a select to wait for input from the keyboard (the user) or from the pty (the shell). o On shell output, voyeur first sends a copy to its stderr (which is the screen) so that the user can see it (no flames, please). Remember, that the shell is only talking to the pty and voyeur's stdout goes to the tutorial. Next it sends a copy to the tutorial (via it's stdout) along with some control messages to advise the tutorial of where the incoming data came from. o On stdin (keyboard) input it sends a copy down the stdout to both the shell and the tutorial. Now to get to your question: On keyboard input, it checks to see if the typed string is a request for change of directory and if it is, voyeur (1) asks the shell for the new directory name (2) warns the tutorial that important data is on the way and to wait for it: if (!strncmp(buf, "cd", 2) || !strncmp(buf, "chdir", 5) || !strncmp(buf, "pushdir", 7) || !strncmp(buf, "popdir", 6)) { (void) write(ptyfd, "echo \007\007$cwd\001\n", 13); (void) write(1, "\001\001WAIT\n", 7); } Meanwhile, there is a check in voyeur's shell output handler to watch for messages with double Ctrl-G's. It knows that this is the answer to its question, finds the useful information and sends it as a control message to the tutorial. if (sel & (1 << ptyfd)) { /* output from shell */ int n = read (ptyfd, buf, BUFSIZ); [...] if ((newdir = index(buf, '\007')) && *(newdir+1) == '\007') { (void) write(1, "\001\001CWD:",6); (void) write(1, newdir+2, (int)(index(buf, '\001') - newdir - 2)); (void) write(1, "\n", 1); (void) write(2, buf, (int)(newdir - buf)); /* If we didn't get the prompt after $cwd, get it next time. */ okay_to_write = n - (int)(index(newdir,'\n')-buf) - 1; *newdir = '\0'; } else if (okay_to_write) (void) write(2, buf, n); else okay_to_write = 1; } } I wasn't sure whether or not to include the "okay_to_write" nonsense in this article, but since I have, I might as well, explain it: The user should have no idea that we're sneaking that echo command to his/her shell. So of course we don't echo the output. But we also have to make sure that the prompt which gets printed after the "echo" command is also suppressed. Since this stuff comes down the pty asynchronously, it might get read in one packet ("^G^G/usr/newdir^A\nprompt>") which is no problem, or in two packets ("^G^G/usr/newdir^A\n", "prompt>") in which case we have to wait for and suppress the second one. Now, I realize that this routine can be easily defeated, and lose big in some cases, but the general algorithm is a sound and efficient way to preprocess input to and output from a command processor. -- unsigned *Wayne_Mesard(); MESARD@BBN.COM BBN Labs, Cambridge, MA Is it because of the people you hang around with that you say you do not need dan rather? M-x psychoanalyze-pinhead (Gee, whataneditor!!)