Problem replacing Linux system calls using LD_PRELOAD - c

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.

Related

Stata: Call a do file containing loop from a program in the other do file

I am trying to call a do file which has loops from a program in other do file. I am getting an error.
Now, if I use do instead of include, it runs fine but I don't get to use local macros created. I used include so I can use the macros further in the program. I don't want to use global.
First do file (test.do).
forval i = 1/5 {
local val`i' = `i'
}
Second do file(call-test.do)
capture program drop test
program test
include "test.do"
di `val1'
end
test
I got error r(9611);
I using version 16.1
Response from Stata support
The -include- is designed to let you share definitions. It will not
work correctly within a program as documented in -help include-
The short answer is that -include- is usually ok to use in programs,
but not with looping commands, and if you use -include- in a program,
it probably isn't working the way you think it is.
Here's the long version of exactly what is going on:
When you use -include- in a program, your program literally includes
the -include- command in it. The program does NOT have the contents
of the include file substituted in place. That's the start of the
problem for looping commands.
In any case, when a program executes the -include- command, Stata gets
confused about whether to define a loop program on the behalf of a
looping command globally or within the program, and things go downhill
from there. Given how the code is structured, it is unlikely we could
fix -include- to behave differently, so our documentation really
should simply recommend against using -include- in programs. In
addition, at the point at which the failure occurs, Stata simply knows
that it cannot call a program that it thinks should already be in
memory, hence the 9611 return code. It has no idea at that point that
this was because it was called with -include-, unfortunately.
We could in the future introduce a true C-like "#include" for use in
programs which would simply substitute in-line the lines from whatever
was included into your program

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

File that hasn't been created

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.

Where to find logs left by Find/Sed run from C program

If a C program was used to send a combination of Find/Sed instructions to system, where would a system admin best find evidence of this happening, and is it possible to find the exact arguments passed to these programs? Just to say that I am mentioning that it is a C program doing this to exclude the bash history. Would really appreciate someone to give me a list of places to look. Thank you.
pseudo code:
Way in which Find/Sed invoked:
Command= find .... exec Sed.....
sprintf(command,....
system(command);
That would depend entirely on how the C program invoked find/sed, and whether or not it redirected the I/O. There may not be any record of the process having been run unless some kind of process accounting is enabled.
Either use absolute paths or use the function getcwd to get the current working directory and work it out from there where the files will be stored from the redirection.

following symbolic links in C

I'm looking to write a C program which, given the name of symbolic link, will print the name of the file or directory the link points to. Any suggestions on how to start?
The readlink() function that has been mentioned is part of the answer. However, you should be aware of its horrid interface (it does not null terminate the response string!).
You might also want to look at the realpath() function, the use of which was discussed in SO 1563186. You could also look at the code for 'linkpath' at the IIUG Software Archive. It analyzes the security of all the directories encountered as a symbolic link is resolved - it uses readlink() and lstat() and stat(); one of the checks when testing the program was to ensure that realpath() resolved the name to the same file.
Make sure that you have an environment which supports POSIX functions, include unistd.h and then use the readlink function.
Depending on the platform, stat() or fstat() are probably the first things to try out. If you're on Linux or cygwin then the stat program will give you a reasonable idea of what to expect from the system API call (it pretty much gives you a text dump of it).
The system call you want is readlink(). Takes a path to the link, returns the string (not always a valid path in the filesystem!) stored in the link. Check the man page ("man 2 readlink") for details.
Note there is some ambiguity to your question. You might be asking for how to tell the "real" path in the filesystem, which is a little more complicated.

Resources