Writing to multiple file descriptors with a single function call - c

I had a use case for a group chat server where the server had to write a common string to all clients' socket. I had then addressed this by looping through the list of file descriptors and writing the string to each of the file descriptors.
Now I am thinking of finding a better solution to the problem. Is it possible to do this by a single function call from the server by using the tee system call in linux. I want the output of one tee to go to the next tee as well to a clients socket. I am wondering if I can dup the file descriptor of one end of the tee to the clients socket and get the desired effect.
Please suggest any other implementation for the use case that you know of.
Thanks

The tee(2) system call requires both file descriptors to be pipes - so sockets do not count. The splice(2) and vmsplice(2) system calls also do not seem to meet your requirements, and I don't see how to utilize sendfile(2) either.
I've not come across such a system call. Calls for collecting diverse data and writing it all at once (or the converse for reading) - yes. But for writing to multiple outputs at once - no.
So, your current 'loop around the descriptors' is about as good as it gets, AFAICT.

Related

Is it possible to pipe() within a program in C?

Let's say that there is an existing program that listens on stdin for it's inputs. I want to create a pthread within the same program that is now the one to listen to stdin, and depending on what comes through, let it go through to the original program.
For this, I would create a pipe(), and configure the pthread to write to the input file descriptor, and the original program to listen to the output descriptor. Is this a correct way to have this done? I understand piping between processes, but is it possible to pipe like this within a single process?
Sure, you can use pipe(), but the data has to pass through the kernel even though both the end points are within the same process.
If you have source code for this (which I assume you have) and you don't mind making non-trivial changes, and performance is a priority for you, I would suggest using shared memory to send the data to the original program. It will be much faster than using pipe()

Unix named pipe, multiple writers or multiple pipes

I am currently measuring performance of named pipe to compare with another library.
I need to simulate a clients (n) / server (1) situation where server read messages and do a simple action for every written messages. So clients are writers.
My code now work, but if I add a 2nd writer, the reader (server) will never see the data and will not receive forever. The file is still filled with the non-read data at the end and read method will return 0.
Is it ok for a single named pipe to be written by multiple-process? Do I need to initialize it with a special flag for multiple-process?
I am not sure I can/should use multiple writers on a single pipe. But, I am not sure also it would be a good design to create 1 pipe for each clients.
Would it be a more standard design to use 1 named pipe per client connection?
I know about Unix Domain Name Socket and it will be use later. I need o make the named pipes work.

How to get the file descriptors of TCP socket for a given process in Linux?

I'm trying to find the file descriptors for all TCP sockets of a given process, ie. given its pid, so that I can get the socket option at another process without modifying the original one.
For example, if I know the file descriptor is fd, then I hope to call getsockopt(fd, ...) to retrieve the options at another process. I'm wondering is this doable? If so, how to get the fd I need outside the original process?
I have tried to print out the return value when creating a socket, ie. s = socket(...); printf("%d\n", s);, keeping the original process running and call getsockopt(s, ...) somewhere else but it doesn't work - it seems that such return value is process-dependent.
I have also found the solution with unix domain sockets but I don't want to modify the codes of original process.
As for reading \proc\<PID>\fd directly or leveraging lsof, I'd like to say I don't know how to find what I need from them. My gut feeling is that they could be potential solutions.
Of course any other ideas are welcome as well. To be honest, I'm not very familiar with the file descriptor mechanism in Linux.
No. You simply cannot do what you are asking.
A file descriptor is just an integer, but it refers to an open file object in a given process. That integer value in another process refers to a different, possibly unopened file object.
Without involving the ptrace debugging API, or remote code injection, you are limited to what the kernel exposes to you via /proc.
Check out the man page for ss. If this utility can't show you information about a socket you desire, then nothing can.

Stdout redirecting (to a file for instance) with a static library in C

I know already how to implement methods regarding usual freopen(), popen() or similar stdout/stdin/stderr -based redirecting mechanisms, but I wondered how should I apply the said mechanism to static (own) libraries in C? Say, I want to use a library to capture any program with printf() commands or so into a file (for instance) without letting it appear on the console - are there some things I need to acknowledge before applying simple fd dups and just calling the library in the main program? Even piping seems to be complex seeing as execing here is risky...
thanks in advance.
There's an old-timers' trick to force the entire process, regardless of what library the code comes from, to have one of the standard IO ports connected to a different filehandle. You simply close the filehandle in question, then open a new one. If you close(1), then open('some_file', 'w'), then ALL calls that would result in a write to stdout will go to some_file from that point forward.
This works because open() always uses the first file descriptor that isn't currently in use. Presuming that you haven't closed stdin (fd=0), the call to open will get a file descriptor of 1.
There are some caveats. FILE outputs that haven't flushed their buffers will have undefined behavior, but you probably won't be doing this in the middle of execution. Set it up as your process starts and you'll be golden.

unix domain socket VS named pipes?

After looking at a unix named socket and i thought they were named pipes. I looked at name pipes and didnt see much of a difference. I saw they were initialized differently but thats the only thing i notice. Both use the C write/read function and work alike AFAIK.
Whats the difference between unix domain sockets and named pipes? When would i pick one over the other? Which should i use by default (like how i use use vector by default in C++ than use deque, list or whatever else if i have needs)?
UNIX-domain sockets are generally more flexible than named pipes. Some of their advantages are:
You can use them for more than two processes communicating (eg. a server process with potentially multiple client processes connecting);
They are bidirectional;
They support passing kernel-verified UID / GID credentials between processes;
They support passing file descriptors between processes;
They support packet and sequenced packet modes.
To use many of these features, you need to use the send() / recv() family of system calls rather than write() / read().
One difference is that named pipes are one-way, so you'll need to use two of them in order to do two-way communication. Sockets of course are two way. It seems slightly more complicated to use two variables instead of one (that is, two pipes instead of one socket).
Also, the wikipedia article is pretty clear on the following point: "Unix domain sockets may be created as byte streams or as datagram sequences, while pipes are byte streams only."
Named pipes are, in fact, bi-directional but half-duplex. This means that communication may go either from end A to end B, or B to A, but never both at the same time.

Resources