File that hasn't been created - c

I am doing a c programming assignment where I am working with command-line arguments. One of the notes says that if the file you work with (to my understanding, it will always be "list.csv") is not yet created to create one. Just like vim does when you write "vim new.txt" and new.txt does not exist yet.
I am just wondering if there is a function that tests for the existence of a file? Or do I use some sort of try/catch block?

you can use fopen(). the second parameter says, what to do. Read, create+write, append+create(if not existent)
one way is to use fstat() on the filename.
under UNIX try 'man fstat'

Typically when you want to write to a file the library or operating system API will automatically try to create it for you if it does not already exist. Exactly how you can control this depends on the API that you will be using.

Related

Finding file type in Linux programmatically

I am trying to find the file type of a file like .pdf, .doc, .docx etc. but programmatically not using shell command. Actually i have to make an application which blocks access to files of a particular extension. I have already hooked sys_call_table in LKM and now i want that when an open/read system call is triggered then my LKM checks the file type.
I know that we have a current pointer which gives access to current process structure and we can use it to find the file name stored in dentry structure and also in Linux a file type is identified by a magic number stored in starting bytes of file. But i don't know that how to find file type and exactly where it is stored ?
Linux doesn't "store" the file type for its files (unlike Mac OS' resource fork, which I think is the most well-known platform to do this). Files are just named streams of bytes, they have no structure implied by the operating system.
Either you just tell programs which file to use (and then it Does What You Say), or programs use higher-level features to figure it out.
There are programs that re-invent this particular wheel (I'm responsible for one of those), but you can also use e.g. file(1). Of course that requires your program to parse and "understand" the textual output you'll get, which in a sense only moves the problem.
However, I don't think calling into file from kernel space is very wise, so it's probably best to re-create the test for whatever set of types you need, to keep it small.
In other words, I mean you should simply re-implement the required tests. This is quite complicated in general, so if you really need to do it for as a large a set of types as possible, it might not be a very good idea. :/
Actually i have to make an application which blocks access to files of a particular extension.
that's a flawed requirement. If you check by file extension, then you'll miss files that doesn't use the extension which is quite common in Linux since it does not use file extension.
The officially sanctioned way of detecting file type in Linux is by their magic number. The shell command file is basically just a wrapper for libmagic, so you have the option of linking to that library

Call a function or a program when using the C-function fopen

I have a situation in C where I would like to call a c-function when calling fopen. This means I would like to have a "virtual file" of some sort. When I use fopen on this "virtual file" I would like to call a function to produce the data in the file.
Is this possible?
Thanks!
There isn't a direct way to call a function to produce output. However, you can call another process using popen(), which may be sufficient for your needs.
This means I would like to have a "virtual file" of some sort. When I
use fopen on this "virtual file" I would like to call a function to
produce the data in the file.
To do that, you'd need to write your own file system. Lucky for you, other people have done the hard part: take a look at FUSE. For example, you could write a file system where the "files" are really RSS feeds. You could then use standard file calls to read the data form those feeds.
Now, whether you should take this approach is a different question. If you have control of the code that's reading the file, it'd probably be easier to just have it call the appropraite data-providing function than to require installing a custom file system.
In standard C that is not possible, AFAIK,
If you use a system with the GNU Glibc (such as GNU/Linux) you can have custom streams, notably thru fopencookie.
Notice that the standard C++ library also provides (its own variant of) streams, and you could have your own.
On GNU/Linux, the kernel enables you also to provide a file-system in user space with FUSE

How to check if given argument for file reading is valid?

I am taking in an argument using fopen. What are some checks I can do to make sure that fopen actually takes in the string to a valid filename?
The number one method is to try opening the file. If fopen() returns NULL, there was an error. Check the errno variable or function to find out the problem.
Trying to preprocess a file specification is an exercise in futility. The operating system will do every relevant check for you, including those which are hard for you to do, like checking file protection ACLs, etc.
The question isn't clear, but if you want to know if the file name you have points to an existing file, you can use access (Linux documentation) (Windows documentation).

Suppress warning: the use of `mktemp' is dangerous

How can I suppress following warning from gcc linker:
warning: the use of 'mktemp' is dangerous, better use 'mkstemp'
I do know that it's better to use mkstemp() but for some reason I have to use mktemp() function.
I guess you need the path because you pass it to a library that only accepts path names as argument and not file descriptors or FILE pointers. If so you can create a temp dir with mkdtemp and place your file there, the actual name is then unimportant because the path is already unique because of the directory.
If you have to use mktemp then there is not anything you can do to suppress that warning short of removing the section that uses mktemp from libc.so.6.
Why do you have to use mktemp?
Two things:
mktemp is not a standard function
the warning is a special one implemented in the linker as .gnu.warning.mktemp section
Use a native OS API if you really need to write to the disk. Or mkstemp() as suggested.
If you are statically linking the runtime, then the other option is to write your own version of mktemp in an object file. The linker should prefer your version over the runtime version.
Edit: Thanks to Jason Coco for pointing out a major misunderstanding that I had in mktemp and its relatives. This one is a little easier to solve now. Since the linker will prefer a version in an object file, you just need to write mktemp in terms of mkstemp.
The only difficulties are cleaning up the file descriptors that mkstemp will return to you and making everything thread safe. You could use a static array of descriptors and an atexit-registered function for cleanup if you can put a cap on how many temporary files you need. If not, just use a linked list instead.
Use mkstemp:
int fd = mkstemp(template);
After this call, template will be replaced with the actual file name. You will have the file descriptor and the file's path.

Problem replacing Linux system calls using LD_PRELOAD

I am trying to write a program that allows a binary to be run, substituting a certain file when requested with another. It is a library with simple replacements for the system call functions, that is used with LD_PRELOAD. The problem is that it catches opens for reading (the substitute file is read instead), but writes always go back to the actual, specified file. Are there any other "open" system calls I should know about?
Nevermind -- stupid mistake.
Wasn't checking both absolute and relative paths...
I am not sure what the cause of your problem is, but using strace on your program might give some insight. It should be part of any sane Linux distribution.
If it's open for writing, it's most likely going through the creat function (I'm guessing fopen would be redirecting you there). Check your fcntl.h for a complete list.
substituting a certain file when requested with another
Sounds like you check only for the input file (do you check by filename?). You need to check and substitute the output file, too.
If you output goes to one of the standard outputs, then you need to close and reopen them with your output substitute) before you fork into the executable.
To find all system calls that your executable makes you can use strace.
To find all library calls that your executable makes you can use ltrace.

Resources