Input Port vs file - io

Is a Scheme input port the same thing as a C FILE* or a python file? Is that the same thing as the unix file descriptor concept? If not, how does an Input Port differe from the others (and why is it it called that way and not just a 'file')?

It's approximately, but only approximately equivalent: ports are objects to and from which you can write or read other objects: bytes or characters (usually).
But the approximation is not terribly close. Ports from which you can read or write characters rather than bytes are, well, ports which handle characters. That means that before they can, for instance, write some octets down on the TCP connection underlying the port, they have to translate those characters into octets using (with luck) some standard encoding. I don't think the mechanism for controlling this encoding & decoding is specified in Scheme, but it must exist. So a port is, at least sometimes, a complicated thing.
(As for why they're called 'ports': well, C made a choice to call communication endpoints 'file descriptors' which makes sense in the context of the Unix 'everything's a file' idea (calling bytes chars was always just a mistake though). But Scheme doesn't come from a Unix/C background so there's really no reason to do that. Given what we call communication endpoints in TCP/IP, 'port' seems quite a good choice of name.)

Related

Benefits on using UNIX named pipes instead of TCP sockets, in Linux?

Everywhere I read about named pipes vs sockets, I see that a socket can do what a named pipe can, and more. I am guessing that pipes may be faster because they are simpler, but I haven't find it explicitly anywhere.
In Linux, is there any advantage in using named pipes instead of sockets?
Thanks for your help and time.
EDIT: I found some comparisons here, but these are UNIX-sockets (a.k.a. UNIX domain sockets), which based on this, I understand they are a different creature.
Therefore, I clarify: I am asking about TCP sockets versus Unix named pipes (because MS Windows has another thing called "named pipes", but they seem to be functionally more similar to UNIX domain sockets).
At this point, it looks more likely to me that UNIX named pipes are faster than TCP sockets, but I would like to know some technicalities on why that would the case, and other potential benefits.
This is likely an imperfect answer, but here's what I know.
Sending data over a TCP socket means that the transmission needs to through your networking system, will get a source & destination IP, split up in a maximum of 64K packets. Packaged in both a TCP and IP envelope, potentially go through firewall rules. The receiver also needs to acknowledge packages, make sure they arrive in order and there needs to be a negotation in place in case packages get lost and need to be re-sent.
Sending data in a named pipe more or less works like just writing to a file descriptor like STDOUT, and reading from STDIN.
Going through the network stack (even if it's just localhost) simply has a lot more layers and complexity. The system that can send a message reliably to the other side of the world needs that, but a simple local named pipe does not.
Everywhere I read about named pipes vs sockets, I see that a socket can do what a named pipe can, and more.
Named pipes are used like files.
This is a large benefit if you want to do something that works with a file but it does not work with a socket.
Examples:
ls > /dev/lp1
ls > ./myNamedPipe
# Not possible: ls > 127.0.0.1:9323
dd if=myFile bs=1 count=100 of=/dev/lp1
dd if=myFile bs=1 count=100 of=./myNamedPipe
# Not possible: dd if=myFile bs=1 count=100 of=127.0.0.1:9323
MS Windows has another thing called "named pipes", but they seem to be functionally more similar to UNIX domain sockets
The truth is that MS Windows has additional API functions for accessing named pipes. However, the standard Windows file API (that is used by C functions like open(), read() and write()) also works with named pipes.
For this reason you can also use a named pipe as file in Windows. I already did that to emulate a serial port with a certain device connected.
... and other potential benefits.
One obvious benefit (of both named pipes and Unix sockets) is the naming itself:
If some program foobarSimpleProgram wants to communicate to another program named foobarOtherProgram, it can simply create a Unix socket or a named pipe named /tmp/foobarProgramSuite.
It's very unlikely that any other program uses this name.
In the case of a TCP socket listening on localhost, the program must either use a fixed TCP port; in this case there is the risk that another program uses the same TCP port so only one of the two programs can be used.
Or the program binds to TCP port 0 so the OS assigns some free TCP port. Then the program writes the port number to a file /tmp/foobarProgramSuite which is read by the other program, which is then doing the connect().
This is more complicated than directly connecting to the pipe or socket with the given name.

How to use unix domain socket without creating a socket file

In Linux, is there any example of using AF_LOCAL (unix domain sockets) to communicate between processes (IPC) without using a file? (on a read only filesystem)
I must use a Unix Domain socket, but I don't have file create/write access on the system.
Thank you in advance.
You can create a unix domain socket with an "abstract socket address". Simply make the first character of the sun_path string in the sockaddr_un you pass to bind be '\0'. After this initial NUL, write a string to the remainder of sun_path and pad it out to UNIX_PATH_MAX with NULs (or anything else).
Sockets created this way will not have any filesystem entry, but instead will be placed into an invisible system-wide socket namespace. The socket name is not a null-terminated string; it's a UNIX_PATH_MAX length string starting with a NUL, and any other NULs have no special significance. So it's vitally important to pad out that name, or you'll put extra uninitialized memory garbage into that name, with unexpected results. By convention, this is generally done with NUL pads, but it's up to you.
For more information, consult unix(7), and specifically the part on abstract socket addresses. A fully worked example can also be found here.

File handling in tinyos or tossim

I need to read data from a text file in a tinyos file (nesc file). I searched lot on Internet but couldn't find a way.
Is there any way?
I don't know about TOSSIM, but using a real sensor board its possible to do so.
What you could do, is to write a program using Java, C#, etc that reads the file and passes the acquired data to the serial/usb port as a SERIAL PACKET. But you are limited to maximum of 255 byte for each packet.
So you should make a simple protocol that takes care of data chunks.
Of course you should know that how you can create a serial packet to be readable by sensor boards.
For that you need to read the TEP#113. But short story, a serial packet is consisted of:
HEADER + CONTENT + FOOTER
header contains protocol byte, destination and source address etc...
content is your message_t struct
footer has CRC and some other stuff
You have to take care of CRC calculation and also escaping start/end delimeters (I believe byte 126 or 127 is the delimiter, I mean indicator of starting and ending a packet).

linux socket programming with the consideration of real size of char

I'm writing a client and server program with Linux socket programming. I'm confused about something. Although sizeof(char) is guaranteed to be 1, I know the real size of char may be different in different computer. It may be 8bits,16bits or some other size. The problem is that what if client and server have different size of char. For example client char size is 8bits and server char size is 16bits. Client call write(socket_fd, *c, sizeof(char)) and Server call read(socket_fd, *c, sizeof(char)). Does Client sends 8bits and Server wants to receive 16bits? If it is true, what will happen?
Another question: Is it good for me to pass text between client and server because I don't need to consider the big endian and little endian problem?
Thanks in advance.
What system are you communicating with that has 16bits in a byte? In any case, if you want to know exactly how many bits you have - use int8 instead.
#Basile is right. A char is always eight bits in linux. I found this in the book Linux Kernel Development. This book also states some other rules:
Although there is no rule that the int type be 32 bits, it is in Linux on all currently supported architectures.
The same goes for the short type, which is 16 bits on all current architectures, although no rule explicitly decrees that.
Never assume the size of a pointer or a long, which can be either 32 or 64 bits on the currently supported machines in Linux.
Because the size of a long varies on different architectures, never assume that sizeof(int) is equal to sizeof(long).
Likewise, do not assume that a pointer and an int are the same size.
For the choice of pass by binary data or text data through the network, the book UNIX Network Programming Volume1 gives the two solutions:
Pass all numeric data as text strings.
Explicitly define the binary formats of the supported datatypes (number of bits, big- or little-endian) and pass all data between the client and server in this format. RPC packages normally use this technique. RFC 1832 [Srinivasan 1995] describes the External Data Representation (XDR) standard that is used with the Sun RPC package.
The c definition of char as the size of a memory cell is different from the definition used in Unicode.
A Unicode code-point can, depending on the encoding used, require up to 6 bytes of storage.
This is a slightly different problem than byte order and word size differences between different architectures, etc.
If you wish to express complex structures (containing unicode text), it's probably a
good idea to implement a message protocol, that encode messages to a byte array, that can be send over any communication channel.
A simple client/server mechanism is to send a fixed size header containing the length of the following message. It's a nice exercise to build something like this in c... :-)
Depending on what you are trying to do, it may be worthwhile to look at existing technologies for the message interface; Look at Etch, Thrift, SWIG, *-rpc, asn1, soap, xml, json, corba, etc.

How can I monitor data on a serial port in Linux?

I'm debugging communications with a serial device, and I need to see all the data flowing both directions.
It seems like this should be easy on Linux, where the serial port is represented by a file. Is there some way that I can do a sort of "bi-directional tee", where I tell my program to connect to a pipe that copies the data to a file and also shuffles it to/from the actual serial port device?
I think I might even know how to write such a beast, but it seems non-trivial, especially to get all of the ioctls passed through for port configuration, etc.
Has anyone already built such a thing? It seems too useful (for people debugging serial device drivers) not to exist already.
strace is very useful for this. You have a visualisation of all ioctl calls, with the corresponding structure decoded. The following options seems particularly useful in your case:
-e read=set
Perform a full hexadecimal and ASCII dump of all the data read from
file descriptors listed in the
specified set. For example, to see all
input activity on file descriptors 3
and 5 use -e read=3,5. Note that this
is independent from the normal tracing
of the read(2) system call which is
controlled by the option -e
trace=read.
-e write=set
Perform a full hexadecimal and ASCII
dump of all the data written to file
descriptors listed in the specified
set. For example, to see all output
activity on file descriptors 3 and 5
use -e write=3,5. Note that this is
independent from the normal tracing of
the write(2) system call which is
controlled by the option -e
trace=write.
I have found pyserial to be quite usable, so if you're into Python it shouldn't be too hard to write such a thing.
A simple method would be to write an application which opened
the master side of a pty and the tty under test. You would then
pass your tty application the slave side of the pty as the 'tty device'.
You would have to monitor the pty attributes with tcgetattr() on the pty
master and call tcsetattr() on the real tty, if the attributes changed.
The rest would be a simple select() on both fd's copying data bi-directionally and copying it to a log.
I looked at a lot of serial sniffers. All of them are based on the idea of making a virtual serial port and sniff data from that port. However, any baud/parity/flow changes will break connection.
So, I wrote my own sniffer :). Most of the serial ports now are just USB-to-serial converters. My sniffer collects data from USB through debugfs, parse it and output to the console. Also any baudrate changes, flow control, line events, and serial errors are also recorded. The project is in the early stage of development and for now, only FTDI is supported.
http://code.google.com/p/uscmon/
Much like #MBR, I was looking into serial sniffers, but the ptys broke the parity check. However, his sniffer was not helping me, as I'm using a CP2102, and not a FT232. So I wrote my own sniffer, by following this, and now I have one that can record file I/O on arbitrary files: I called it tracie.

Resources