I am trying to write a program where it execs itself N times, and each time it execs itself a value x starting from 1 is incremented. N should be the only argument of the program.
For example:
./exec_test.o 4
will print:
Exec: 1
Exec: 2
Exec: 3
Exec: 4
Execs done
I only succeeded in making my values decrease from 4 instead of increase to 4:
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** args){
if (argc<2){ //Argument error handling
fprintf(stderr,"Usage %s number_of_iter",args[0]);
exit(EXIT_FAILURE);
}
int x = atoi(args[1]); //x = the argument used when executing
*args[1]-=1; //decrement the argument value
if (x>0){
printf("Exec : %d \n",x); //printing current argument
execv(args[0],args); //exec itself with argument decremented
perror(args[0]);
exit(1);
}
printf("Execs done \n");
}
and executing it results in this:
Exec: 4
Exec: 3
Exec: 2
Exec: 1
Execs done
Is it possible to make x increment from 1 instead of decrease from N while using only one argument for the program?
Yes. You can hold two information (current and maximum count) in one argument.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** args){
if (argc<2){ //Argument error handling
fprintf(stderr,"Usage %s number_of_iter",args[0]);
exit(EXIT_FAILURE);
}
int max, x = 1; // set x to 1 for the first iteration (it will fail to read x)
char next_argument[128];
char* next_args[3];
sscanf(args[1], "%d_%d", &max, &x);
if (x <= max){
printf("Exec : %d \n",x); //printing current argument
// create next argument
snprintf(next_argument, sizeof(next_argument), "%d_%d", max, x + 1);
next_args[0] = args[0];
next_args[1] = next_argument;
next_args[2] = NULL;
execv(args[0],next_args); //exec itself with argument incremented
perror(args[0]);
exit(1);
}
printf("Execs done \n");
}
Related
I have a problem related to the functioning of gcc for the compilation of different files.
My goal would be to have a program (see script1.c) that would load (compile?) The functions from the script2.c and script3.c file on each run.
This is what my scripts should look like (the names (2 main() and 1 init()) of the functions in the script2.c and script3.c files must not be changed).
script1.c:
int main(int argc, char *argv[]){
printf("loaded main() in script1.c\n");
int ret = main(argc, argv); // main() script2.c
if(ret == 0){
init(argc, argv); // init() script3.c
ret = main(argc, argv); // main() script3.c
if(ret == 0){
ret = main(argc, argv); // main() script3.c
}
}
return(ret);
}
script2.c:
int main(int argc, char *argv[]){
printf("loaded main() in script2.c\n");
return(0);
}
script3.c:
void init(int argc, char *argv[]){
...
argv[0] = (char*)strdup("OK");
printf("loaded init() in script3.c\n");
}
int main(int argc, char *argv[]){
...
if(strcmp(argv[0], "OK") == 0){
printf("loaded init() in script3.c\n");
}
return(0);
}
I would like to return :
loaded main() in script1.c
loaded main() in script2.c
loaded init() in script3.c
loaded main() in script3.c
loaded main() in script3.c
I logically have loops on the main() function.
Here are the different methods I was able to try:
Change the name of the main() function of script1.c to _start(), and use the "-Wl,--allow-multiple-definition -nostartfiles" option during compilation.
Result: Error with the main() function of script2.c is logically initialized 2 times.
Use the system() and exec functions in script1.c to compile/run scripts2.c and script3.c.
Result: Error with script3.c which executes the main() function, before the init() function. I would need, I think, a working equivalent of the "-Wl, -init, init" option for this to work.
Add attribute((constructor)) in the init() function so that it is started before the main() of script3.c. The problem, is that in my example, the init() function will be launched 2 times :
Here is an example of something that may resemble what you are trying to do. I have one main function as well as three helper functions, aptly named func1, func2 and func3. They all reside in the same directory. Each function is in their own source file, named after the function for clarity (but the source file name is arbitrary). main(), the program's "entry point", calls func1, then func2; func2, in turn, calls func3. The parameters to main() are faithfully passed on each time, and output.
In a typical program one would also have a header file that contains the function declarations for all three helper functions; but in this small example one can simply write them manually.
func1.c:
#include <stdio.h>
void func1(int argc, char **argv)
{
printf("func1: Called with the following arguments:\n");
for(int i = 0; i<argc; i++)
{
printf("func1, arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
}
printf("func1: Returning\n");
}
func2.c:
#include <stdio.h>
extern void func3(int, char **);
void func2(int argc, char **argv)
{
printf("func2: Calling func3\n");
func3(argc, argv);
printf("func2: returning\n");
}
func3.c
#include <stdio.h>
void func3(int argc, char **argv)
{
printf("func3: Called with the following arguments:\n");
for(int i = 0; i<argc; i++)
{
printf("func3, Arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
}
printf("func3: Returning\n");
}
And main.c:
#include <stdio.h>
extern void func1(int, char **);
extern void func2(int, char **);
int main(int argc, char **argv)
{
printf("main(): Called with the following arguments:\n");
for(int i = 0; i<argc; i++)
{
printf("Arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
}
printf("********* main(): Calling func1 *********\n");
func1(argc, argv);
printf("********* main(): Calling func2 *********\n");
func2(argc, argv);
}
Sample session: Compile with
$ gcc -Wall -o main main.c func1.c func2.c func3.c
and then execute with e.g.
$ ./main 1 2 3
Output:
Arg. 1 (index 0): ->./main<-
Arg. 2 (index 1): ->1<-
Arg. 3 (index 2): ->2<-
Arg. 4 (index 3): ->3<-
********* main(): Calling func1 *********
func1: Called with the following arguments:
func1, arg. 1 (index 0): ->./main<-
func1, arg. 2 (index 1): ->1<-
func1, arg. 3 (index 2): ->2<-
func1, arg. 4 (index 3): ->3<-
func1: Returning
********* main(): Calling func2 *********
func2: Calling func3
func3: Called with the following arguments:
func3, Arg. 1 (index 0): ->./main<-
func3, Arg. 2 (index 1): ->1<-
func3, Arg. 3 (index 2): ->2<-
func3, Arg. 4 (index 3): ->3<-
func3: Returning
func2: returning
You can see that the first argument to the program is put in their by the command shell and C runtime library: It's the string with which the program was called, which is customary, here "./main". Only after that come the explicit command line arguments "1", "2" and "3".
I am following a source code on my documents, but I encounter an error when I try to use MPI_Send() and MPI_Recv() from Open MPI library.
I have googled and read some threads in this site but I can not find the solution to resolve my error.
This is my error:
mca_oob_tcp_msg_recv: readv faled : Unknown error (108)
Here is details image:
And this is the code that I'm following:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <mpi.h>
int main(int argc, char **argv) {
int rank, size, mesg, tag = 123;
MPI_Status status;
MPI_Init(&argv, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (size < 2) {
printf("Need at least 2 processes!\n");
} else if (rank == 0) {
mesg = 11;
MPI_Send(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Recv(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD,&status);
printf("Rank 0 received %d from rank 1\n",mesg);
} else if (rank == 1) {
MPI_Recv(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
printf("Rank 1 received %d from rank 0/n",mesg);
mesg = 42;
MPI_Send(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
I commented all of MPI_Send(), and MPI_Recv(), and my program worked. In other hand, I commented either MPI_Send() or MPI_Recv(), and I still got that error. So I think the problem are MPI_Send() and MPI_Recv() functions.
P.S.: I'm using Open MPI v1.6 on Windows 8.1 OS.
You pass in the wrong arguments to MPI_Init (two times argv, instead of argc and argv once each).
The sends and receives actually look fine, I think. But there is also one typo in one of your prints with a /n instead of \n.
Here is what works for me (on MacOSX, though):
int main(int argc, char **argv) {
int rank, size, mesg, tag = 123;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (size < 2) {
printf("Need at least 2 processes!\n");
} else if (rank == 0) {
mesg = 11;
MPI_Send(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Recv(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD,&status);
printf("Rank 0 received %d from rank 1\n",mesg);
} else if (rank == 1) {
MPI_Recv(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
printf("Rank 1 received %d from rank 0\n",mesg);
mesg = 42;
MPI_Send(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
If this does not work, I'd guess your OS does not let the processes communicate with each other via the method chosen by OpenMPI.
Set MPI_STATUS_IGNORED instead of &status in MPI_Recv in both places.
I'm trying to add a custom system call into the linux kernel. Here is a simple code:
#include <linux/mysyscall.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <asm/system.h>
asmlinkage int sys_mysyscall(int *data){
int a = 3;
cli();
copy_to_user(data, &a, 1);
sti();
printk(KERN_EMERG "Called with %d\n", a);
return a;
}
I can compile a kernel with mysyscall added and when I try to access it with a user program like:
#include <linux/mysyscall.h>
int main(void){
int *data;
int r;
int a = 0;
data = &a;
r = mysyscall(data);
printf("r is %d and data is %d", r, *data);
}
*data does not equal to 3 it equals to 0.
How should I use copy_to_user to fix it?
The copy to user line of code copies only one byte from 'a'. In case of little endian systems it is going to be 0. Copy all the 4 bytes to get the correct result.
I am using gcc compiler to Implement a random-number generator using only getpid() and gettimeofday(). Here is my code
#include <stdio.h>
#include <sys/time.h>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
struct timeval tv;
int count;
int i;
int INPUT_MAX =10;
int NO_OF_SAMPLES =10;
gettimeofday(&tv, NULL);
printf("Enter Max: \n");
scanf("%d", &INPUT_MAX);
printf("Enter No. of samples needed: \n");
scanf("%d", &NO_OF_SAMPLES);
/*printf("%ld\n",tv.tv_usec);
printf("PID :%d\n", getpid());*/
for (count = 0; count< NO_OF_SAMPLES; count++) {
printf("%ld\n", (getpid() * tv.tv_usec) % INPUT_MAX + 1);
for (i = 0; i < 1000000; ++i)
{
/* code */
}
}
return 0;
}
I gave a inner for loop for delay purpose but the result what i am getting is always same no. like this
./a.out
Enter Max:
10
Enter No. of samples needed:
10
1
1
1
1
1
1
1
1
1
1
Plz correct me what am i doing wrong?
getpid() is constant during the programs execution, so you get constant values, too.
But even if you use gettimeofday() inside the loop, this likely won't help:
gcc will likely optimize away your delay loop.
even it it's not optimized away, the delays will be very similar and your values won't be very random.
I'd suggest you look up "linear congruential generator", for a simple way to generate more random numbers.
Put gettimeofday in the loop. Look if getpid() is divisible by INPUT_MAX + 1 you will get the same answer always. Instead you can add getpid() (not make any sense though()) to tv.tv_usec.
good afternoon.
I got the code below on a book. I'm trying to execute it, but I don't know what is the "first" and "last" parameters on the MakeCodeWritable function, or where I can find them. Someone can help? This code is about C obfuscation method. I'm using Xcode program and LLVM GCC 4.2 compiler.
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
typedef unsigned int uint32;
typedef char* caddr_t;
typedef uint32* waddr_t;
#define Tam_celula 64
#define ALIGN __attribute__((aligned(Tam_celula)))
void makeCodeWritable(char* first, char* last) {
char* firstpage = first - ((int)first % getpagesize());
char* lastpage = last - ((int)last % getpagesize());
int pages = (lastpage-firstpage)/getpagesize()+1;
if (mprotect(firstpage,pages*getpagesize(), PROT_READ|PROT_EXEC|PROT_WRITE)==-1) perror("mprotect");
}
void xor(caddr_t from, caddr_t to, int len){
int i;
for(i=0;i<len;i++){
*to ^= *from; from++; to++;
} }
void swap(caddr_t from, caddr_t to, int len){
int i;
for(i=0;i<len;i++){
char t = *from; *from = *to; *to = t; from++; to++;
} }
#define CELLSIZE 64
#define ALIGN asm volatile (".align 64\n");
void P() {
static int firsttime=1; if (firsttime) {
xor(&&cell5,&&cell2,CELLSIZE);
xor(&&cell0,&&cell3,CELLSIZE);
swap(&&cell1,&&cell4,CELLSIZE);
firsttime = 0; }
char* a[] = {&&align0,&&align1,&&align2,&&align3,&&align4,&&align5};
char*next[] ={&&cell0,&&cell1,&&cell2,&&cell3, &&cell4,&&cell5};
goto *next[0];
align0: ALIGN
cell0: printf("SPGM0\n");
xor(&&cell0,&&cell3,3*CELLSIZE);
goto *next[3];
align1: ALIGN
cell1: printf("SPGM2\n"); xor(&&cell0,&&cell3,3*CELLSIZE);
goto *next[4];
align2: ALIGN
cell2: printf("SPGM4\n"); xor(&&cell0,&&cell3,3*CELLSIZE);
goto *next[5];
align3: ALIGN
cell3: printf("SPGM1\n"); xor(&&cell3,&&cell0,3*CELLSIZE);
goto *next[1];
align4: ALIGN
cell4: printf("SPGM3\n"); xor(&&cell3,&&cell0,3*CELLSIZE);
goto *next[2];
align5: ALIGN
cell5: printf("SPGM5\n");
xor(&&cell3,&&cell0,3*CELLSIZE);
}
int main (int argc, char *argv[]) {
makeCodeWritable(...);
P(); P();
}
The first argument should be (char *)P, because it looks like you want to modify code inside function P. The second argument is the ending address of function P. You can first compile the code, and using objdump -d to see the address of beginning and end of P, then calculate the size of the function, SIZE, then manually specify in the makeCodeWritable( (char *)P, ((char *)P) + SIZE.
The second way is utilizing the as to get the size of function P, but it depends on the assembler language on your platform. This is code snipe I modified from your code, it should be able to compile and run in x86, x86_64 in GCC 4.x on Linux platform.
align5: ALIGN
cell5: printf("SPGM5\n");
xor(&&cell3,&&cell0,3*CELLSIZE);
// adding an label to the end of function P to assembly code
asm ("END_P: \n");
;
}
extern char __sizeof__myfunc[];
int main (int argc, char *argv[]) {
// calculate the code size, ending - starting address of P
asm (" __sizeof__myfunc = END_P-P \n");
// you can see the code size of P
printf("code size is %d\n", (unsigned)__sizeof__myfunc);
makeCodeWritable( (char*)P, ((char *)P) + (unsigned)__sizeof__myfunc);
P(); P();
}
With some modification to support LLVM GCC and as in Mac OS X
int main (int argc, char *argv[]) {
size_t sizeof__myfunc = 0;
asm volatile ("movq $(_END_P - _P),%0;"
: "=r" (sizeof__myfunc)
: );
printf("%d\n", sizeof__myfunc);