Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Aug 2002 15:23:57 +0000 (UTC)
From:      naddy@mips.inka.de (Christian Weisgerber)
To:        freebsd-current@freebsd.org
Subject:   devfs, fdescfs: /dev/fd problems
Message-ID:  <aim5ad$1tpa$1@kemoauc.mips.inka.de>

next in thread | raw e-mail | index | archive | help
The starting point is the observation that on -CURRENT with devfs
bash's process substitution doesn't work (this has been true for
months):

$ cat <(head /etc/rc)
cat: /dev/fd/63: No such file or directory

If you replace cat with a little program that just sleeps

$ ./s <( : )
62807

you can verify that the file descriptor is correctly associated
with a pipe:

$ fstat -p 62807
naddy    s          62807 root /        26878976 ?---------  1196525  r
naddy    s          62807   wd /home    27309056 ?--S------  2769389  r
naddy    s          62807 text /home    27309056 ?---------   98797  r
naddy    s          62807    0 /dev        101 crw--w----  #C:255:0x-65281 rw
naddy    s          62807    1 /dev        101 crw--w----  #C:255:0x-65281 rw
naddy    s          62807    2 /dev        101 crw--w----  #C:255:0x-65281 rw
naddy    s          62807   63* pipe fffffe0002b4d188 <->        0      0 rw

Now let's try a program that lists the directory entries under
/dev/fd:

$ ./t <( : )
0
1
2

No entry 63.  But there is something else amiss.  readdir() is
reading from a file descriptor too, and that one doesn't show up
either.


Mounting fdescfs on /dev/fd improves things.  bash's process
substitution works:

$ cat <(head /etc/rc)
#!/bin/sh
#
# Copyright (c) 2000  The FreeBSD Project
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.

File descriptor assignment is still the same:

$ echo <( : )
/dev/fd/63

$ ./s <( : )
62853

$ fstat -p 62853
naddy    s          62853 root /        26878976 ?---------  1196525  r
naddy    s          62853   wd /home    27309056 ?--S------  2769389  r
naddy    s          62853 text /home    27309056 ?---------   98797  r
naddy    s          62853    0 /dev        101 crw--w----  #C:255:0x-65281 rw
naddy    s          62853    1 /dev        101 crw--w----  #C:255:0x-65281 rw
naddy    s          62853    2 /dev        101 crw--w----  #C:255:0x-65281 rw
naddy    s          62853   63* pipe fffffe0002b4c528 <->        0      0 rw

Listing the entries under /dev/fd gives something of a surprise:

$ ./t <( : )
0
1
2
3

The descriptor used by readdir() is there, but the pipe on 63 is
still missing, although open()ing it obviously works.

Altogether I get the impression that /dev/fd doesn't quite work as
expected, for both plain devfs as well as for fdescfs.


---- s.c -------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
	int p = getpid();

	printf("%d\n", p);
	sleep(3600);
	exit(0);
}

---- t.c -------------------------------------------------------
#include <sys/types.h>
#include <dirent.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
	DIR *dirp;
	struct dirent *dp;

	if ((dirp = opendir("/dev/fd")) == NULL)
		err(1, NULL);

	while ((dp = readdir(dirp)) != NULL)
		if (strcmp(".", dp->d_name) && strcmp("..", dp->d_name))
			printf("%s\n", dp->d_name);

	closedir(dirp);

	exit(0);
}

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?aim5ad$1tpa$1>