lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Jorge once stated:
> On 18/10/12 14:30, Sam Roberts wrote:
> >/dev/ttyUSB0 isn't a file. 
> Aaaaaah, I see.
> 
> As a user application, where i'm standing, they ARE files. I find them 
> in folders, "ls" shows them, and i have to open them, getting a file 
> descriptor. "File" for me is the abstraction so named by the unix 
> designers ("everything is a file, etc.").

  As Joel Spolsky said, "all abstractions leak." [1]

> I do recognize that there are several types of files, and i can check it 
> doing "ls -l".
> My perspective is from outside, and finishes at the API. And for me that 
> means that there are files, sockets and pipes, and that's it.

  Here's a file:

-rw-r--r--    1 spc spc  25288 Oct 18 15:50 urls.check

  Here's a socket:

srw-rw-rw-  1 root root 0 Aug 28 08:11 /dev/log

  And here's a pipe:

prw-r--r--  1 spc spc 0 Oct 19 05:24 foo

  Further more, to open the socket, you can't use open() (which is what you
would normally use to open a file), but socket(), followed by bind() (even
for "/dev/log").  Trying to do otherwise results in:

[spc]lucy:/tmp>cat >/dev/log
-bash: /dev/log: No such device or address

  You can, however, do

[spc]luch:/tmp>cat >foo

  But it will stop accepting input after a set amount, blocking the writing
process (that is, until something else does a read on the pipe).  Most pipes
used under Unix are the anonmous types, something like:

	find . -name '*.c' | xargs grep foo

That vertical bar there is the anonymous pipe.  You make pipes with two
function calls, pipe() for the anonymous type, mknod() for the named type. 
It's only the named type which can be opened with open() (in fact, that's
the only way to read or write a named pipe---with open(); pipe() creates two
file descriptors, one for reading, one for writing).

  You also forgot directories, which are special files under Unix that map
inodes (the information about a file except its name) to names.  There's an
API to open a directory and read the contents, different from open() and
read().  There are also symbolic links, which are normally invisible, but
there is a way to read a symbolic link (that is, the name of the link, not
the target).  

  Going back to sockets, you can use read() and write() on them [2], but you
also have recv(), recvfrom(), recvmsg(), send(), sendto() and sendmsg()
which also work only for sockets, not for pipes, files, or directories.

  It's a lie that "everything is a file" under Unix (it's a useful lie, but
a lie nonetheless).  Perhaps it's better to say, "nearly every device has a
file interface to some degree."

  -spc (And don't forget the duct tape---it's quite leaky)

[1]	http://www.joelonsoftware.com/articles/LeakyAbstractions.html

[2]	For the most part.  Again, it's a leaky abstraction.