This program is called program.c. When I run ./program echo test, I would expect the program to print test, even if the command is run in a subshell. Why is the output an empty line? Does it have to do with filepath? When I try ./program /bin/echo test I still get an empty line output.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int function(char **argv) {
execl("/bin/bash", "sh", "-c", *argv, argv, (char*)NULL);
}
int main(int argc, char **argv) {
int return2;
function(argv + 1);
}
There are two problems with your program.
The first problem is that the argument argv to execl() does not do what you think it does. The pointer argv is a pointer to a char * (i.e. a char **), and it is only permitted to pass a char * as an argument to execl(). That is, variable argument lists in C do not work how you are expecting them to.
In order to accomplish what you want, consider not using execl() and use execv() instead, passing an array of char *s which you have constructed yourself. You could do this in the following way, for example:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int function(char **argv) {
// Consider passing `argc` as well to eliminate
// the need for this loop.
int len = 0;
while(argv[len]) {
len++;
}
char *new_argv[len + 3];
new_argv[0] = "sh";
new_argv[1] = "-c";
for(int i = 0; i <= len; i++) {
new_argv[i + 2] = argv[i];
}
execv("/bin/bash", new_argv);
}
int main(int argc, char **argv) {
function(argv+1);
}
However, you still have a problem: ./program echo test will still print a blank line because if you execute sh -c echo test in a terminal you just get a blank line! In order to fix this, you need to do ./program 'echo test' (corresponding to sh -c 'echo test' at the terminal), which should then work.
Related
When I compile the following code and run strace on it, I can see that it adds two additional elements to the args[] array.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char *args[2];
args[0] = "/bin/ls";
args[1] = "-lh";
execve(args[0], args, NULL);
return 1;
}
strace says that this is what is actually being called:
execve("/bin/ls", ["/bin/ls", "-lh", "\340\301\361\267", "\1"], NULL)
You need to add a null ptr to the last element of the argument array. Otherwise execve doesn't know where your array ends.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char *args[3];
args[0] = "/bin/ls";
args[1] = "-lh";
args[2] = NULL;
execve(args[0], args, NULL);
return 1;
}
So basically what you are seeing is execv passing random arguments until it found a NULL in the memory you point with the array. Of course it could be crashing as well.
When I using Java, i need to type command likejava -?If user type -? at the end, why the application know this to reply output? Please tell me c code to identify the -?
They are passed as the parameters to main():
#include <stdio.h>
int main(int argc, const char* argv[])
{
for (int i = 0; i < argc; i++) {
printf("Arg %i is %s\n", i, argv[i]);
}
}
When compiled and then executed as
myProgram.exe arg1 stuff ?
It would output
Arg 0 is myProgram.exe
Arg 1 is arg1
Arg 2 is stuff
Arg 3 is ?
In C you have three options for your main signature. The first is the one that does not take any parameters int main(void). The second one int main() as mentioned in the comments takes any number of parameters but they are unnamed. The third one however has two parameters int main(int argc, char **argv) the names of the parameters do not matter they are just commonly used. These two parameters serve the purpose to provide the command line parameters to your program.
argc: Is the counter variable which holds the number of the provided arguments separated by spaces
argv: contains the command line arguments as an array of c-strings
Your program implicitely receives always one argument which is the name of the application (or \0 if the host environment can not provide that). Here a little example on how to iterate over the arguments:
#include <stdio.h>
int main(int argc, char **argv) {
for(int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
}
}
In C, the main is declared as:
int main(int argc, char** argv);
the first argument is the number of parameters while the second one is an array of parameters so, for example in your case you would do:
#include<string.h>
#include<stdio.h>
#define QUESTION_MARK "-?"
int main(int argc, char **argv){
if(argc > 1){
char *qsmark = argv[1];
if(strcmp(qsmark, QUESTION_MARK) == 0){
printf("argv[1] is -?\n");
}
}
return 0;
}
Remember that the first argv is the name of the executable.
Please avoid comparing string by hands though, use the standard library to get if what is pointed by qsmark is actually equal to "-?"
If you can use getopt() or other similar POSIX functions. Then this is one way to go:
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
int main(int argc, char** argv)
{
int opt;
while ((opt = getopt(argc, argv, "h?")) != -1)
{
switch (opt)
{
case '?':
case 'h':
printf("Usage: bla bla\n");
break;
}
}
return EXIT_SUCCESS;
}
Example:
~ # /tmp/temp_test -?
Usage: bla bla
~ # /tmp/temp_test -y
/tmp/temp_test: invalid option -- 'y'
Usage: bla bla
~ #
More information in man page.
Program 1
In program 1 I have attempted to create the sole environment variable envar putting it in the env array which is passed to the execle function for the environments creation which program 2 will be run in.
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[]){
int ret;
char envar[] = "Big ol' environment variable ;D";
char *env[2] = {envar, 0};
ret = execle("./exec_test1.1", "exec_test1.1", 0, env);
printf("my prog failed ret = %d", ret);
return 0;
}
Program 2
I intended this code in the same directory to retrieve the environment variable envar on execution and to print it. However I the output in its place is null "memes and dis (null)" I have searched but can't see my mistake. Program two is almost identical to another I found for the same purpose so I assume my mistake is in program one.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
char *envptr = getenv("envar");
printf("memes and dis %s\n", envptr);
return 0;
}
Thanks
You have wrong envar variable format - it must be NAME=VALUE. So fixing program 1 to:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int ret;
char envar[] = "envar=Big ol' environment variable ;D";
char *env[2] = {envar, 0};
ret = execle("./exec_test1.1", "exec_test1.1", 0, env);
printf("my prog failed ret = %d", ret);
return 0;
}
should make it work.
(I also took some liberty and formatted the code to make it more readable)
I am programming C programs in a Unix environment. I need to take a number from a user before the program is executed like so:
./program.out 60
How do I store the integer value in the C program?
You can use argv[] to get command line parameters, e.g.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n;
if (argc != 2) // check that we have been passed the correct
{ // number of parameters
fprintf(stderr, "Usage: command param\n");
exit(1);
}
n = atoi(argv[1]); // convert first parameter to int
// ... // do whatever you need to with `n`
return 0;
}
int main (int argc, char *argv [ ])
{
//your code
}
argv [1] will then have the address of the numeric string which contains the number.
Then you can change this to an int if needed.
It is quite simple to do and I hope I have got your question right. See below:
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Number of arguments is: %d\n", argc);
printf("The entered value is %s\n", argv[1]);
return 0;
}
And then compile it on Linux as:
gcc file.c
./a.out 32
The program should print the value you require.
Hope this helps.
I'm trying to write a program that takes a string as a command line argument and then runs said argument through a function (str_to_int) that takes a string as an input. However, when I try to compile the program, I get a warning saying
initializing 'char *' with an expression of type 'int' [-Wint
conversion]
char* str = atoi(argv[1]);
^ ~~~~~~~~~~~~~
And when I run the program I get a segmentation fault
I've tested the str_to_int a lot so I'm pretty sure that the issue lies with the command line program. Here's the code for it.
#include "hw3.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
char* str = atoi(argv[1]);
printf("%d\n", str_to_int(str));
return 0;
}
Can anyone tell me what I'm doing wrong? Thanks.
This is all you need, though it will crash if you leave out the command-line argument.
{
printf("%d\n", str_to_int(argv[1]));
return 0;
}
This is more robust:
int main(int argc, char *argv[])
{
if (argc == 1)
printf("missing parameter.");
else
printf("%d\n", str_to_int(argv[1]));
return 0;
}
#include "hw3.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
char* str = argv[1];
printf("%d\n", str_to_int(str));
return 0;
}
just remove atoi function invocation and it should work