C Program Standard Input File Name Access - c

I was wondering if there is a way to access the name of the standard input file within a C program. I've looked around, and haven't found anything. For example
./a.out < file.txt
Is there a way within the C program to print out the name of the file (file.txt)?

If you are using Linux, you could accomplish what you want by reading /proc/[pid]/fd/0 or parsing the out of lsof -p [pid], where [pid] is the process ID of your process.
See proce(5) and lsof(8).

printf("%s", argv[1]);
Make sure you have your main set up to accept command line arguments
int main(int argc, char** argv)

Related

How to parse a pipe or redirection operator in unix?

I am currently working on a cat program. The problem I am having is that whenever I execute the unix command:
./catpr file1 file2 file3 | grep string
I don't know how to mark the end of the parsing by pointing out there exists a pipe operator. I am currently developing this cat program in C by using system calls, so I use argv to keep track of the arguments; however, whenever I look at the content in the array that corresponds to '|', something really weird shows up.
So what you basically need is you need to search a pattern in three files.
Since you have specified that you are using system calls to perform what you can do is give the string as input argument to program. Just do the following for compiling
./catpr file1 file2 file3 string
Just inside the program give the system call with grep. I am providing the complete program for you. I hope this is what you need.
#include <stdio.h>
#include <string.h>
int main(int a,char *argv[])
{
char com[256]="";
strcat(com,"cat ");
strcat(com,argv[1]);
strcat(com," ");
strcat(com,argv[2]);
strcat(com," ");
strcat(com,argv[3]);
strcat(com," | grep ");
strcat(com,argv[4]); //this is your search pattern
system(com);
}

how to run execlp with arguments from command

I am trying to create simple program which will run shell commands from arguments, for example
./run date +"%r"
07:56:05 PM
but I cant figure how. I try this, but it not working. I am pretty confused and absolutely cant figure how exec works..
#include <unistd.h>
#include <stdio.h>
int main (int argc, char *argv[]){
execlp("bash","bash", "argv[1]", (char*)0);
return 0;
}
You probably meant (note the lack of quotes around argv[1]):
execlp("bash", "myprogram", argv[1], NULL);
Note that I assume here that myprogram is a shell script. In case it's a binary, you should remove the preceding "bash" parameter.
One good troubleshooting technique could be replacing bash with echo to confirm the command line.

How can a C program determine and print the location of its own executable?

I want to write a a C program that prints its location.
For example if i put the program exe file to D:\myfolder\myc_prog, it should print the same location D:\myfolder\myc_prog and if I put that exe file to the location E:\mynewfold\ , it should print the updated location E:\mynewfold.
Actually, I have no idea how to do it that's why I'm not able to provide much details for this question.
Since you're using Windows, GetModuleFileName should do the trick. Just pass NULL for the hModule parameter. Be sure to read the documentation carefully if you want to handle long file names (and you typically do). You'll also have to strip the name of the executable to get the directory path. A quick-and-dirty way to do so is to remove everything after the last \.
#include <Windows.h>
#include <stdio.h>
int main(int argc, char *argv[]){
char buff[256];
if(GetCurrentDirectory(256, buff)){//get current directory
printf("%s\n", buff);
}
return 0;
}

Handling command line flags in C/C++

I am looking for a very simple explanation/tutorial on what flags are. I understand that flags work indicate a command what to do. For example:
rm -Rf test
I know that the rm command will remove the test folder and that the -Rf flags will force the command to erase not just the folder but the files in it.
But, where are the flags read/compiled??? What handles the flags? Can I, for example, write my own C/C++ program and designate different flags so that the program does different things? I hope I am asking the right questions. If not, please let me know.
At the C level, command line arguments to a program appear in the parameters to the main function. For instance, if you compile this program:
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
for (i = 0; i < argc; i++)
printf("argv[%d] = %s\n", i, argv[i]);
return 0;
}
and invoke it with the same arguments as your example 'rm' command, you get this:
$ ./a.out -Rf test
argv[0] = ./a.out
argv[1] = -Rf
argv[2] = test
As you can see, the first entry in argv is the name of the program itself, and the rest of the array entries are the command line arguments.
The operating system does not care at all what the arguments are; it is up to your program to interpret them. However, there are conventions for how they work, of which the following are the most important:
Arguments are divided into options and non-options. Options start with a dash, non-options don't.
Options, as the name implies, are supposed to be optional. If your program requires some command-line arguments to do anything at all useful, those arguments should be non-options (i.e. they should not start with a dash).
Options can be further divided into short options, which are a single dash followed by a single letter (-r, -f), and long options, which are two dashes followed by one or more dash-separated words (--recursive, --frobnicate-the-gourds). Short options can be glommed together into one argument (-rf) as long as none of them takes arguments (see below).
Options may themselves take arguments.
The argument to a short option -x is either the remainder of the argv entry, or if there is no further text in that entry, the very next argv entry whether or not it starts with a dash.
The argument to a long option is set off with an equals sign: --output=outputfile.txt.
If at all possible, the relative ordering of distinct options (with their arguments) should have no observable effect.
The special option -- means "do not treat anything after this point on the command line as an option, even if it looks like one." This is so, for instance, you can remove a file named '-f' by typing rm -- -f.
The special option - means "read standard input".
There are a number of short option letters reserved by convention: the most important are
-v = be verbose
-q = be quiet
-h = print some help text
-o file = output to file
-f = force (don't prompt for confirmation of dangerous actions, just do them)
There are a bunch of libraries for helping you parse command line arguments. The most portable, but also the most limited, of these is getopt, which is built into the C library on most systems nowadays. I recommend you read all of the documentation for GNU argp even if you don't want to use that particular one, because it'll further educate you in the conventions.
It's also worth mentioning that wildcard expansion (rm -rf *) is done before your program is ever invoked. If you ran the above sample program as ./a.out * in a directory containing only the binary and its source code you would get
argv[0] = ./a.out
argv[1] = a.out
argv[2] = test.c
This simple program should demonstrate the arguments passed to the program (including the program name itself.)
Parsing, interpreting and using those arguments is up to the programmer (you), although there are libraries available to help:
int main(int argc, char* argv[])
{
int i;
for(i=0; i<argc; ++i)
{ printf("Argument %d : %s\n", i, argv[i]);
}
return 0;
}
If you compile this program into a.out, and run it as:
prompt$> ./a.out ParamOne ParamTwo -rf x.c
You should see output:
Argument 0 : a.out
Argument 1 : ParamOne
Argument 2 : ParamTwo
Argument 3 : -rf
Argument 4 : x.c
Actually you can write your own C++ programm which accepts commandline parameters like this:
int main(int argc, char* argv[]){}
The variable argc will contain the number of parameters, while the char* will contain the parameters itself.
You can dispatch the parameters like this:
for (int i = 1; i < argc; i++)
{
if (i + 1 != argc)
{
if (strcmp(argv[i], "-filename") == 0) // This is your parameter name
{
char* filename = argv[i + 1]; // The next value in the array is your value
i++; // Move to the next flag
}
}
}
In your own C program you can process command line options in any way you see fit.
Command line parameters in C come in the parameters of the main(int argc, char *argv[]) method as strings.
And if you'd like to process command line parameters in a way similar to most UNIX commands, the function you're probably looking for is getopt()
Good luck!
The easiest thing is to write your main() like so:
int main(int argc, char* argv[]) { ...
Then inside that main you decide what happens to the command line arguments or "flags". You find them in argv and their number is argc.
flags are arguments passed into the main entry point of the program. For example, in a C++ program you can have
int main(int arc, char* argv[]){
return 0;
}
your arc is the # of arguments passed in, and the pointer gives u the list of actual arguments. so for
rm -Rf test
argc would be 3, and the argv array would contain your arguments. Notice argc >= 1 because the program name itself counts (rm). -RF is your 2nd parameter and test is your third.
So whenever you are typing commands in unix, you essentially are executing programs and passing them parameters that they operate on.
If you are really REALLY interested in the unix OS, you should look up forks and how they work. This can get pretty confusing to a newcomer though, so only if you are really interested in OS and how programs are executed.
GNU libc, which is very likely available on your system, has a library for this called getopt that can be used to parse the options in a sensible fashion. There are examples to get you started in the documentation linked below.
http://www.gnu.org/software/libc/manual/html_node/Getopt.html#Getopt

How to control the execution flow of c program through a config file. This file is passed using redirection operator (<)

I have a c program running. I want to make the program sleep for certain period say 5 sec. I want this sleep to be induced from a text file containing command "sleep(5)". I want to pass this file through redirection operator (<) while executing the program
say ./a.out < samplefile.txt
This samplefile.txt contains sleep(5) command in it. I tried the above scenario but the c program is reading it as stream of characters like s,l,e,e,p which is not our intention.
could some one please help me on this issue.
You may make your program read the commands from the text file, parse them and behave as the commands say.
Instead of parsing, you may use the environment variables.
In your program, call to getenv in any place requires configuration. When calling to the program, make sure the environment is set with the required variables, or use this notation:
VAR1=VALUE1 VAR2=VALUE2 ./a.out
I'm not very clear what you want to achieve, but this may be a prompt.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char buf[512];
scanf("%s", buf);
if (!strcmp(buf, "sleep(5)")) {
printf("sleep...\n");
sleep(5);
}
printf("over\n");
return 0;
}

Resources