system calls in C - c

I have a function in C that calls another software to execute and generate a file then its manipulates the data e.g.
void main()
{
function();
//manipulate data in output.txt
}
void execute()
{
system("./test input.txt output.txt");
}
for some reason the output.txt file is not being generated by full...how does the system call work? will execute return to main before system call ends? if yes how can I solve this? Im working on ubuntu using gcc

Check the result of system() ALWAYS. Ensure that it executed successfully(ie. returns 0 or whatever is a successful result for 'test')
When system executes it runs through /bin/sh (on unix/linux anyway). However since you're specifying it with './test' make sure that you're operating in the working directory that you THINK you are. Complex systems(and poorly designed ones) change directories like underwear.

Related

Why is this C program doing nothing in Ubuntu?

My very simple C program just hangs and I don’t know why.
I am trying to make a simple executable to handle multiple monotonous actions for me every time I start a new programming session.
So I decided with something simple (below) yet every time I run it, the app just hangs, never returns. So I have to Ctrl-C out of it. I have added printf commands to see if it goes anywhere, but those never appear.
My build command returns no error messages:
gcc -o tail tail.c
Just curious what I am missing.
#include <stdio.h>
#include <unistd.h>
int main() {
chdir("\\var\\www");
return 0;
}
There are at least two problems with the source code:
It is unlikely that you have a sub-directory called \var\www in your current directory — Ubuntu uses / and not \ for path separators.
Even if there was a sub-directory with the right name, your program would change directory to it but that wouldn't affect the calling program.
You should check the return value from chdir() — at minimum:
if (chdir("/var/www") != 0)
{
perror("chdir");
exit(EXIT_FAILURE);
}
And, as Max pointed out, calling your program by the name of a well-known utility such as tail is likely to lead to confusion. Use a different name.
Incidentally, don't use test as a program name either. That, too, will lead to confusion as it is a shell built-in as well as an executable in either /bin or /usr/bin. There is also a program /bin/cd or /usr/bin/cd on your machine — it will check that it can change directory, but won't affect the current directory of your shell. You have to invoke it explicitly by the full pathname to get it to run at all because cd is another shell built-in.
Two things:
First, that's not what Linux paths look like
Second, check the return value from chdir()
ie
if (chdir("/var/www") != 0)
printf("failed to change directory");
Finally, the effect of chdir() lasts for the duration of the program. It will not change the current directory of your shell once this program finishes.
The other answers adequately cover the issues in your C code. However, the reason you are seeing it hang is because you chose the name tail for your program.
In Linux, tail is a command in /usr/bin in most setups, and if you just type tail at the command line, the shell searches the $PATH first, and runs this. Without any parameters, it waits for input on its stdin. You can end it by pressing control-d to mark the end of file.
You can bypass the $PATH lookup by typing ./tail instead.
$ tail
[system tail]
$ ./tail
[tail in your current directory]
It is a good idea to use ./ as a habit, but you can also avoid confusion by not naming your program the same as common commands. Another name to avoid is test which is a shell built-in for testing various aspects of files, but appears to do nothing as it reports results in its system return code.

Change system calls function pointers at runtime in Linux

I have a huge project that is creating a lot of files and folders that I want to track them.
In order to debug the code, I would like to replace a system call behavior to check what is going on.
My idea is to hook a new function in the same place where the system call is being used and see the behavior of the application, after it has started. To be more clear, here is an example of what I need:
The application is creating a annoying folder like /tmp/annoying_folder. So I would like to intercept every mkdir system call and check if the it's argument is the annoying_folder and if it is the case, force it to return an error, so I can locate which process is doing this and also know it's stack call.
What I have tried up to now is using LD_PRELOAD, which is not working in the case of this application, because it is doing direct system calls, instead of going through libc.
I'm having trouble using gdb, because I'm not sure which process is doing these calls, because the application is started by a script that calls multiple other processes.
Through strace I'm able to see the mkdir call that I'm looking for, but it doesn't help me much, because I need to also know the stack trace call of the application to figure out where is the code that is generating this.
So one option that thought to be interesting is to use LD_PRELOAD to load a library with a constructor function that would change the hook point of mkdir and redirect it to my custom function. But I need directions on how to do that for Linux system calls.
Do someone knows how to change System calls function pointers at runtime?
I wasn't able to intercept those system calls as I expected, but I've found an interesting workaround with stap utility.
I've created the following script:
#! /bin/stap -g
probe nd_syscall.mkdir.return {
folder_name = user_string(#entry(pointer_arg(1)), "-");
folder_name_prefix = substr(folder_name, 0, 9);
if(folder_name_prefix == "/tmp/test") {
printf("[%d] [%d] [%16s] [%s]\n", uid(), pid(), execname(), folder_name);
raise(%{ SIGSTOP %});
}
Then I was able to send a signal stop to the process and after that connect gdb to analyze the application stack trace.

run a C program at startup [Red Pitaya]

I have a C program that needs to run when I turn on my machine (Red Pitaya).
the beginning of the program presented here:
//my_test program
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "redpitaya/rp.h"
int main(int argc, char **argv){
int jj=1;
while(1) {
printf("Ready for experiment number %i\n",jj);
int i, D;
int32_t TrigDly;
and so on...
the program is executable with a run.sh file called uri_test.sh, that contains the following:
cat /opt/redpitaya/fpga/fpga_0.94.bit>/dev/xdevcfg
LD_LIBRARY_PATH=/opt/redpitaya/lib ./my_test
both files are located in a directory under /root. the program is working perfectly when run manually on PuTTY terminal-
/RedPitaya/Examples/C/Uri# ./my_test
or
/RedPitaya/Examples/C/Uri# ./uri_test.sh
I tried to follow the solution presented here :
https://askubuntu.com/questions/9853/how-can-i-make-rc-local-run-on-startup
without success.
any suggestions? Thank you.
There are several ways to have a program running at startup, and it depends upon your init subsystem (are you using systemd or a SysV-style init?).
BTW, a source program in C is not a script and you generally compile it (using gcc -Wall -Wextra -g) into some executable. In your case, you probably want to set up its rpath at build time (in particular to avoid the LD_LIBRARY_PATH madness), perhaps by passing something like -Wl,-rpath,/opt/redpitaya/lib to your linking gcc command.
Perhaps a crontab(5) entry with #reboot could be enough.
Whatever way you are starting your program at startup time, it generally is the case that its stdin, stdout, stderr streams are redirected (e.g. to /dev/null, see null(4)) or not available. So it is likely that your printf output go nowhere. You might redirect stdout in your script, and I would recommend using syslog(3) in your C program, and logger(1) in your shell script (then look also into some *.log file under /var/log/). BTW, its environment is not the same as in some interactive shell (see environ(7)...), so your program is probably failing very early (perhaps at dynamic linking time, see ld-linux.so(8), since LD_LIBRARY_PATH might not be set to what you want it to be...).
You should consider handing program arguments in your C program (perhaps with getopt_long(3)) and might perhaps have some option (e.g. --daemonize) which would call daemon(3).
You certainly should read Advanced Linux Programming or something similar.
I recommend to first be able to successfully build then run some "hello-world" like program at startup which uses syslog(3). Later on, you could improve that program to make it work with your Red Pitaya thing.

Read a line of c code from file and execute in a c program

I have a C program which calculates f(x) for some x values (main.c). I need to get a line of c code from file and that code is my function to execute (function.dot). For example function.dot will contain:
pow((1-x), 0.333);
I need to read this file, get that function and execute in my code (main.c). How can I do that?
Basic steps would be:
Read the line from the file.
Generate a new source file which wraps the line of code inside appropriate code.
Invoke a compiler to compile that code into a shared object/dll.
Load the library.
Call the function in the library.
If the single line of code in the file could be any language, it would be far easier to use something like Lua that can be linked into your main executable.
I will provide some options:
Switch to another interpreted language including python, ruby, perl, ...
If you are working on small project, I recommend this option.
Implement your own interpreter in C.
Parse your input, analyze it, execute it. You might find open source implementations: one choice is slang
http://www.jedsoft.org/slang/doc/html/slang.html
Call C compiler and dynamically link it.
It depends on your operating system but system or exec functions help you to call your compiler to handle your input file. If you are using Linux, dlsym can open a shared-object compiled from your input file.
You might need to convert your input file into C program.
Very slow to compile but fastest to run.
You have several options I can think of:
1) Switch to any number of interpreted langauges (python, perl, etc.) which support this as an easy mechanism. (Example: in python
data = open("function.dot").read()
x = 5
eval(data) #note that this is unsafe if you can't trust data, and you might also need to play with environment
)
2) You could wrap the code in it's own c file... something like (but with more error checking etc... you probably don't want to do this)
void generate_c_program(char *line)
{
FILE *fp = fopen("myfile.c","wt");
fprintf(fp,"#include <math.h>\nint main(char *argv, int argc) {\n double x = atof(argv[1]); printf(\"%f\",(%s));}\n");",line); //this is also unsafe if you can't trust data
fclose(fp);
//now execute gcc myfile.c
//now execute a.out
//optionally cleanup by deleting a.out and myfile.c
}
3) Effectively write your own compiler / parser (which may be fairly easy IF you've done this before and the number of functions / operations you need to support is small or may be a much bigger deal and will rather not fit in this answer)... the extensible way would be to use LEX/YACC or similar)

Send Linux command from C program

I'm writing a C program to run in Linux shell.
Now I got a problem with such command.
#include <stdio.h>
void main()
{
char* command="history>>history";
system(command);
}
I want it to write the result of command "history" into a document, but it failed with a blank one.
If I change it to "date>>history", current system time will be written into the document.
Is there any problem with "history>>history"?
What should I do if I want to get that work?
Thanks!
The problem is that history is not a real command but a shell builtin. Thus you can't call it from a C program[1].
Depending on the shell the user is using, you can instead get the history from ~/.bash_history, ~/.zsh_history and so on. Note however that zsh only write to this file at the end of a session.
[1] Well, you could theorically try system("bash -c history"), but you won't get the actual history because the builtin isn't run in the context of the current session.

Resources