# default port of vi opens directory for reading/writing



## nedry (Jul 30, 2016)

hello i made a typo while trying to open a txt file in vi i gave vi a directory, vi to my amazement opened the directory on the console filled with garbage characters, instead of saying cant open a directory. anyone had this?
nedry


----------



## Murph (Jul 30, 2016)

nedry said:


> hello i made a typo while trying to open a txt file in vi i gave vi a directory, vi to my amazement opened the directory on the console filled with garbage characters, instead of saying cant open a directory. anyone had this?
> nedry



That's normal and nothing to be concerned about.  Directories are just a special type of file which is normally only directly read and written by the filesystem code.  The system prevents you directly writing to it (writes fail with EISDIR), but will allow you to read the raw data (subject to normal permissions rules).  E.g. try `od /usr/bin`.  Normally you would only read it using readdir(3) and similar.

A small note of a pedantic nature.  If you are referring to /usr/bin/vi, that is not a port.  It is a base system command/tool/utility.


----------



## Oko (Jul 30, 2016)

What is the "default port of vi"? vi from the base should be nvi version 1.79 due to licensing differences between Berkeley Database1.85 and the later versions by Sleepycat Software. That version has some bugs which are mostly gone from the OpenBSD version but I am not sure if FreeBSD got the same attention as they kept pushing *ee* and PC-BSD even defaults to *nano*. Anyhow if I try to open directory on my OpenBSD 5.9 stable this is what I get.


```
Warning: test is not a regular file; test: unmodified: line 1
```

FreeBSD port version of nvi is nvi-1.81.6_9 which is the unmaintained, multilingual version by the late Jun-ichiro itojun. OpenBSD version in ports is 2.1.3 which is nvi2 derivative of nvi with UTF and multilingual support. nvi2 is  maintained by OpenBSD developer Anthony Bentley.

https://github.com/lichray/nvi2

I have no idea why nvi2 is not ported to FreeBSD. Itojun was first and foremost OpenBSD developer although contributed to other BSDs so the fact that nvi2 is maintained by OpenBSD should not be a problem.


P.S. I hope nobody is crazy in FreeBSD camp to link vi to vim binaries like Linux does.


----------



## Murph (Jul 30, 2016)

Oko said:


> P.S. I hope nobody is crazy in FreeBSD camp to link vi to vim binaries like Linux does.



Yeah, OS X passes off /usr/bin/vim as /usr/bin/vi, and I'd much prefer that they didn't do that.  I don't mind if they also want to ship vim, that's fine and choice is great, but I'd like a basic traditional vi by default.


----------



## kpa (Jul 31, 2016)

nedry said:


> hello i made a typo while trying to open a txt file in vi i gave vi a directory, vi to my amazement opened the directory on the console filled with garbage characters, instead of saying cant open a directory. anyone had this?
> nedry



Like others already noted the directory is just another file. This methodology is called "everything is a file" -methodology. In this case a directory is presented as a file with special semantics when handled with proper tools like ls(1) but will show the raw binary data when handled with tools that don't understand the underlying structure such as cat(1). UNIX and UNIX-like OSes tend to do this alot, just look at the how the /dev/* devices work. The only exceptions have been the network interfaces that for some arcane reasons never were presented as /dev devices although I'm sure it wouldn't have been a big leap to implement them that way.


----------



## kpa (Jul 31, 2016)

kpa said:


> I'm sure it wouldn't have been a big leap to implement them that way.



Responding to myself, I think the reason is that it's much harder to handle cloning of the interfaces when the controlling node is a file on a filesystem than treating the interfaces as separate entities outside any filesystems.


----------



## tobik@ (Jul 31, 2016)

kpa said:


> Like others already noted the directory is just another file. This methodology is called "everything is a file" -methodology. In this case a directory is presented as a file with special semantics when handled with proper tools like ls(1) but will show the raw binary data when handled with tools that don't understand the underlying structure such as cat(1). UNIX and UNIX-like OSes tend to do this alot, just look at the how the /dev/* devices work. The only exceptions have been the network interfaces that for some arcane reasons never were presented as /dev devices although I'm sure it wouldn't have been a big leap to implement them that way.



Ppre 4.4BSD getdirentries(2) and getdents(2) weren't syscalls and they implemented readdir(3) using read(2).

You can see this here in libc's readdir from 4.3BSD where it's using read(2): https://github.com/dspinellis/unix-...ef-BSD-4_3/usr/src/lib/libc/gen/readdir.c#L25

Compare that with 4.4BSD's version: https://github.com/sergev/4.4BSD-Lite2/blob/master/usr/src/lib/libc/gen/readdir.c#L57
or FreeBSD's current version: https://github.com/freebsd/freebsd/blob/master/lib/libc/gen/readdir.c#L69
or OpenBSD: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gen/readdir.c?rev=1.22

On FreeBSD read(2)-ing directories is only allowed on some filesystems.  For
example UFS and ZFS support it but tmpfs does not. Try it:

```
# mount -t tmpfs none /mnt
# mkdir /mnt/blablabla
# cat /mnt/blablabla
cat: /mnt/blablabla: Is a directory
```
On OpenBSD reads on directories work too, but AFAICT they always return 0 bytes.

But that all begs the question: Why are read operations on directories still allowed?


----------

