On 10/29/25 09:35, Alyssa M via 9fans wrote:
> I have a situation where I want to take an already-open file descriptor, and 
> make it become /dev/cons before I start a shell.
> I can't mount it on /dev/cons because it's not a 9p server - just a simple 
> pipe end.
> If it was a named pipe, I could bind that.
> fd2path on a pipe just produces: '#|/data' - not a unique name I could bind 
> to. So no help there...
> I thought I would put it in /srv with a unique name and then bind it over 
> /dev/cons.
> Starting with a shell that already has the file as fd #2, I tried this:
> 
> term% echo 2 >/srv/foo
> term% bind /srv/foo /dev/cons
> 
> This *almost* works:
> 
> term% echo hello >>/dev/cons
> hello
> term% 
> 
> The problem is that the file in /srv doesn't quite behave like a named pipe 
> end:
> 
> term% echo hello >/dev/cons
> /dev/cons: rc: can't open: '/dev/cons' srv file already exists
> term% 
> 
> I think this is from a check for OTRUNC on open in devsrv in the kernel, 
> which I would guess is being done so people don't accidentally try to use a 
> /srv name that's already in use (I had initially thought it might be a 
> failure from create, or some permissions problem).
> I tried setting the DMAPPEND bit on the /srv file, in the hopes that that 
> would suppress the OTRUNC, but the kernel srv driver masks off that bit of 
> the file mode, unfortunately.
> I still haven't been brave enough to go messing with the plan9 kernel.
> 
> I'm thinking at this point that I could make a very small 9p file server, 
> serving a file that essentially forwards to and from a file descriptor that 
> the server is given when it starts. I'd mount that on /dev/cons, and I think 
> I can probably make that work. But it seems clumsy, given that a more direct 
> solution seems so close.
> 
> So I wondering: is there a better way to do this?
> 
> 


Can you give us some more context about why you're attempting to use an already 
open file descriptor as /dev/cons?
It's hard for me to say without the specifics but typically the expectation is 
that the parent process is responsible
for setting up the environment in the most compatible way before passing the 
buck off to a child (assuming that's what you
have going on here). While pipes do not have unique locations that is because 
new pipes are essentially generated on attach,
each walk to a fresh '#|' gives you a new set of pipes. However you can pin an 
instance by keeping the reference to the root
around. So something roughly like this:

bind '#|' /n/pipe
@{
        rfork n
        bind /n/pipe/data1 /dev/cons
        # start your child program here
}
>/n/pipe/data {
        # Do whatever you want from the parent
}

Keep in mind though that the parent has to keep the pipe open after first 
opening it, or else the program on the child's end
will get an EOF.

Essentially, instead of working backwards from a low context situation (just 
the fd), have the parent or caller do a bit more
work to setup with the environment where they do have the context.


Thanks,
moody


------------------------------------------
9fans: 9fans
Permalink: 
https://9fans.topicbox.com/groups/9fans/T4a173cfd35edc215-Mb18512aecd04b3f12d478416
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

Reply via email to