This question already has answers here:
How to execute a program from file descriptor?
(2 answers)
Closed 5 years ago.
Is there any way to run a program and/or file from within a running c program using a file pointer, or would one have to use the normal file name and system/fork etc? If it matters, writing this on linux.
Essentially, I'm asking if something like this is possible:
FILE * fp=fopen("somefile")
//dostuff
run the file pointed to by fp here (with fp, not with the filename)
Is there any way to run a program and/or file from within a running c
program using a file pointer
It is not really clear what you are asking so I'll try to show you some of the way you can do it.
Maybe you're talking about execve():
int execve(const char *filename, char *const argv[], char *const envp[]);
where execve() executes the program pointed to by filename and argv is an array of argument strings passed to the new program. Similarly there is fexecve() that works the same as execve() with the difference that the file to be executed is specified via a file descriptor, fd, rather than via a pathname.
Or, you can use system() for running some program. For example:
int result = system("./myProgram 2 3");
This will wait for myProgram to be executed, then will get the exitcode.
Last but not least, you can use fork() a system call used to create processes.
Related
This question already has answers here:
How do command line arguments work?
(3 answers)
Closed 5 years ago.
I am trying to understand how command line arguments work in details.
This is what I think happens:
When you compile a source code that contains the main() function in C, the generated object file will be linked with the CRT, and the entry point for the program will be the _start() function (which exists in the CRT), and _start() will call main().
Now when you run your program and pass it some command line arguments, the command line arguments will be passed to the _start() function, and then _start() will re-pass the command line arguments to main().
Am I correct?
Am I correct?
Yes and no:
The _start() function is not a C function but an assembler function. The reason for this is that the CPU is not in a "state" which is required by C programs so the _start() function also has to set up the CPU for executing C code.
One difference between the "state" required by C programs and the "state" of the CPU when _start() is called is the way arguments (here: command line arguments) are stored.
Under Linux (at least 32 bit - I don't know about 64 bit) you actually have an array that later represents argv. _start() has to calculate the location of argv and then pass the calculated value to main().
Under Windows there is a function that returns the entire command line as pointer to a single string (const char *)! The _start() function has to call that function and then to split the string into parts that will later become argv...
I have a problem which needs to be solved. I have a string array like :
argv[]={"cat","file1.txt","file2.txt"},then I need to use execvp to execute the execvp(argv[0],argv),but I feel why it doesn't work out in my program. I am not sure whether I can use execvp() functions like this, can someone tell me how to use execvp() or other kinds of exec() functions to run cat command in UNIX or Linus system(using programming C)?
The array has to end with 0:
char *argv[] = {"cat", "file1.txt", "file2.txt", 0};
That's how execvp knows where the end of the arguments is, since C doesn't pass the length of an array to functions.
My question is about the exec family of C system calls. How do I predict what type of input the program I am executing is looking for since the exec family varies between a list of strings arg1, arg2, arg3 ... and a 2d char array for its parameters. Can most Linux command line programs handle both forms of input?
for example:
int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
int execv(const char *path, char *const argv[]);
What would happen if I executed ls:
execl('/bin/ls', 'ls', NULL);
versus:
execv('/bin/ls', lsArgsArray);
Presumably ls can handle both forms of input, but my real question is generic about other utilities in general, is it safe to assume that you can invoke them either way? If it is not safe to invoke with either method how would something like bash distinguish which to use?
Neither the executed program nor the kernel see any difference whatever one you call: It is both converted to the same system call by your C library. The executed program comes one additional step behind the kernel, thus has even less chance to see any difference.
For the exact kernel interface, look in the sources of either the kernel or your platform C library.
The shell (bash/ash/csh/sh/...) is not in any way priviliged. Still, going directly to the API call allows you to pass a bogus program name.
There is this function in the LibAIFF library:
AIFF_Ref AIFF_OpenFile(const char* name, int flags);
It accepts a const char* but for my use, name has to be of type a char* because I need to build it based on the location of my AIFF file on my directory (which I can properly accomplish) - specifically, in my case name is the AIFF file path.
But I think I'm running into some problems because of this (I'm not sure though). What happens when I send the function a char*? The bad behavior I'm noticing occurs with an associated AIFF_CloseFile function which runs into some problems what seems to be randomly based on the file path I send to it. For example, if I have the exact same AIFF file with two names with just one of the letters changed, the error (which has to do with AIFF_CloseFile trying to free a buffer defined within a structure which has either already been freed or hasn't been allocated) occurs with one of them but not the other. If I comment out the call to the close file function, everything works in that the AIFF file is successfully opened and read but I'm not supposed to do that.
Any help will be much appreciated. Thanks
It is fine to use a char * when a const char * is expected.
If a function accepts a const char * it just means that the function won't be changing the string contents at all.
The other way around is not good though.
EDIT:
I don't know the library you are using.. It could be a problem if the library is remembering the string you used, but is not making its own internal copy. This would be an awful library though..
This question already has answers here:
Reading command line parameters
(4 answers)
Closed 8 years ago.
I was doing my programs Python, so not much familiar with C.
I am doing a program on creating a binary tree in C. I am using an "insert" function created by me . The goal is that for typing "insert " in command line, the function should work. But I have not much idea regarding how to get and parse command line arguments in C. Can anyone help?
http://www.cprogramming.com/tutorial/c/lesson14.html
int main( int argc, char *argv[])
This should be the declaration of your main function. argc is the amount of arguments. argv[] is an array that contains each command-line argument as a string, the program name is argv[0] so the first argument will be argv[1]. I'm not a C programmer, so this might not be good info, I highly recommend checking out the link.
Use a library to handle the low-level details, such as getopt. The code is much more involved than with Python's argparse or getopt, but is similar in concept. (the wikipedia article to which I linked contains example C code using getopt)
Command line arguments are passed during run time.
You have to specify the number of arguments and also a char pointer to point to these arguments. This is done in main() syntax itself.
Void main(int argc, char* argv)
In order to compile and generate an executable in CC compiler,
cc -o exec_name program_name.c
In order to run,
exec_name arg1 arg2.........
It is to be noted that the exec_name is also considered as an argument