Cant pass pipe's write-end as file desctiptor - c++

Pipe's write-end file descriptor is int but some functions such Tcl_MakeFileChannel accepts void* as file handle. I need to pass pipe write-end to it. How can one convert one type of file handle to another?

Reading this reference it seems that you simply pass the file descriptor:
Tcl_MakeFileChannel(reinterpret_cast<void*>(fd), ...);
Also you might want to read this thread.

Related

Write to a file steam without a file existing on the hard drive in C

Is this possible in the C language? Or even C++? I prefer to know for C.
For example, say I had a function that reads a text file and does something with it. If the user did not specify an input text file and I wanted to use that function for stdin; Is it possible to write stdin to a file stream as if it were coming from a file read so it can be used in the same method that normally just takes input files?
A way around this of course is that I could take stdin, write it to a temp file, then pass the temp file to the function that normally would take an input file. I've searched online and asked tutors at university but am not getting any solutions. Has anyone ever accomplished this?
If your function has a prototype say
void add(FILE *fp,<rest of the argument>)
{
}
The you can directly pass
add(stdin,<rest of the arguments>);
Because stdin is of type FILE *
FILE *stdin;
No need to read from stdin and store it in some file and and later send that file pointer to your API.
STDIN is open for you automatically, so just read from STDIN. There are several ways of doing it, but basically STDIN is file descriptor 0.
int filedes = 0;
if(/* argv[1] is a file name */)
filedes = open(argv[1], flags);
read(filedes, bufr, size);

What does fd represent when typing: int fd = open("file");?

I am looking at I/O operations in C++ and I have a question.
When opening a file like:
#include <fcntl.h>
int main() {
unsigned char buffer[16];
int fd = open (argv[1], O_RDONLY);
read(fd, buffer, sizeof(buffer));
return 0;
}
How can the variable fd represent a file as an integer when passing it to the open method? Is it repesenting a file in current folder? If I print the ´fd´variable, it prints 3. What does that mean?
Ps. I know there are several other ways to handle files, like stdio.h, fstream etc but that is out of the scope of this question. Ds.
How can the variable fd represent a file as an integer when passing it to the open method?
It's a handle that identifies the open file; it's generally called a file descriptor, hence the name fd.
When you open the file, the operating system creates some resources that are needed to access it. These are stored in some kind of data structure (perhaps a simple array) that uses an integer as a key; the call to open returns that integer so that when you pass it read, the operating system can use it to find the resources it needs.
Is it repesenting a file in current folder?
It's representing the file that you opened; its filename was argv[1], the first of the arguments that was passed to the program when it was launched. If that file doesn't exist, or open failed for some reason, then it has the value -1 and doesn't represent any file; you really should check for that before you try to do anything with it.
If I print the fd variable, it prints 3. What does that mean?
It doesn't have any particular meaning; but it has that value because it was the fourth file (or file-like thing) that was opened, after the input (0), output (1) and error (2) streams that are used by cin, cout and cerr in C++.
Because that is the index of the table of resources stored for your current process.
Each process has it own resources table, so you just need to pass the index to read/write/etc function
Generally, a file descriptor is an index for an entry in a kernel-resident data structure containing the details of all open files. In POSIX this data structure is called a file descriptor table, and each process has its own file descriptor table. The user application passes the abstract key to the kernel through a system call, and the kernel will access the file on behalf of the application, based on the key. The application itself cannot read or write the file descriptor table directly.
from: http://en.wikipedia.org/wiki/File_descriptor
open() returns the file descriptor of the file which is the C type int. To know more about File Descriptor refer http://en.wikipedia.org/wiki/File_descriptor.
"fd" stands for file descriptor. It is a value identifying a file. It is often an index (in the global table), an offset, or a pointer. Different APIs use different types. WinAPI, for example, uses different types of handles (HANDLE, HGDI, etc.), which are essentially typedefs for int/void*/long, and so on.
Using naked types like "int" is usually not a good idea, but if the implementation tells you to do so (like POSIX in this case), you should keep it.
The simplified answer is that fd is just an index into some array of file descriptors.
When most processes are started, they are given three open file descriptors to begin with: stdin (0), stdout (1), and stderr (2). So when you open your first file, the next available array entry is 3.

How close pipe handle in unix? (fclose() of pclose())?

If I create pipe in unix this way:
int fds[] = {0, 0};
pipe(fds);
Then make FILE * from fds[0] this way:
FILE *pipe_read = fdopen(fds[0], "rt");
Then how should I close this file (pipe_read)?
fclose(pipe_read)
pclose(pipe_read)
close(fileno(pipe_read))
fdopen returns a FILE* so you should fclose it. This will also close the underlying file descriptor as well.
The pclose call is meant for closing a handle created with popen, a function you use for running a command and connecting to it with pipes.
The close call will close the underlying file descriptor but, unfortunately, before the file handle has had a chance to flush its data out - in other words, you're likely to lose data.
You should use fclose(pipe_read).
close() closes the file descriptor in the kernel. It's not enough because the file pointer is not free. So you should use fclose() on pipe_read, which will also take care of closing the file descriptor.

atomic append on a file descriptor, but at what offset?

in unistd.h
using open() with the O_APPEND flag gives atomic writes always to the end of the file...
this is great and all, but what if i need to know the offset at which it atomically appended to the file...?
i realize O_APPEND is often used for log files, but I'd actually like to know at what offset in the file it atomically appended.
I don't see any obvious way to do this..? Does anyone know?
Thanks
To get the current position in a file descriptor, use lseek() with offset 0 and whence SEEK_CUR.
int fd = open(...);
if (fd) {
off_t positionWhereAppendingBegins = lseek(fd, 0, SEEK_CUR);
write(...);
close(fd);
}
Note that this will not give you reliable results if the descriptor was opened some other way, i.e. via socket().
The file is written to at the file offset as obtained by the process when the file was opened. If another process writes to the file between the open and the write, then contents of the file are indeterminate.
The correct method of handling multiple process writing to a single file is for all processes to open the file with the O_APPEND flag, obtain an exclusive lock and once the lock is obtained, seek to the end of the file before writing to the file, and finally close the file to release the lock.
If you want to keep the file open between writes, initiate the process by opening the file with the O_APPEND flag. The writing loop in this case is obtain the exclusive lock, seek to the end of the file, write to the file and release the lock.
If you really need the file position, lseek will return the file offset of the callers file descriptor at the time of the call.

Question about STDIN STDOUT STDERR

I'm designing a MIPS simulator in c++ and my simplified OS must be able to run stat() occasionally (when a program being executed on my simulator requires an input or an output or something.)
The problem is, I need to be able to assert STDIN, STDOUT, and STDERR as parameters to stat "stat("stdin",buff)" where buff is the pointer to the insertion point, for the struct data returned, in memory. In reality I'll be using fstat() which uses file descriptors to point to the file to be stat-ed. My file descriptor table in my simple OS reserves 0, 1, and 2 for stdin, stdout, and stderr. I'm a bit confused about what STDIN, etc are. They're streams, I realize that, they're defined in stdio.h, but how in the world do I get a stat struct with all of the relevant information about the file for each of these streams?
On a POSIX system, you can use fileno() to convert from a FILE* (e.g. stdin, stdout, stderr) to an integer file descriptor. That file descriptor can be sent to fstat().
Here is a very well known example of how to determine if the standard terminal output is redirected to a file to illustrate the usage of POSIX's fileno function
if (!isatty(fileno(stdout))){
fprintf(stdout, "argv, argc, someone is redirecting me elsewhere...\n");
return 1;
}
If using the above code in a program and that said program was executed like this
foobar_program > foobar_program.output
'foobar_program.output' will contain
argv, argc, someone is redirecting me elsewhere...\n
A file stream pointer is nothing more than a structure of a pointer type to FILE, i.e. FILE *, fileno takes that structure and converts it to its relevant file descriptor, accordingly to the manual page for fileno here
The function fileno() examines the argument stream and returns
its integer descriptor.
and also here on the posix manual pages, and I'll quote fileno - map a stream pointer to a file descriptor....