0

I have a simple C program that creates an array of arguments as required by the second argument of execv() that executes a program that computes and outputs the Caeser Cipher decoding of the argument. However the file calling execv() seems to ignore the call and moves ahead. What should I do?

The code

execv-test-arg.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (void)
{
        char *argv[3];
        argv[0] = "caesar-cipher";
        argv[1] = "SDQGD";
        argv[2] = "\0";
        execv("caesar-cipher",argv);
        printf("Returned from execv call.\n"); // This is what is being printed
        return 0;
}

caesar-cipher.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
   int i, j;

   for (i=1; i<argc; i++) {
      j=0;
      while (argv[i][j] != '\0') {
         if ((argv[i][j] >= 'A') && (argv[i][j] <= 'Z')) {
            printf ("%c", 'A'+(argv[i][j]-'A'+23)%26); // To be printed
         }
         else if ((argv[i][j] >= 'a') && (argv[i][j] <= 'z')) {
            printf ("%c", 'A'+(argv[i][j]-'a'+23)%26);
         }
         else if ((argv[i][j] >= '0') && (argv[i][j] <= '9')) {
            printf ("%c", '0'+(argv[i][j]-'0'+7)%10);
         }
         else printf ("Invalid input.\n");
         j++;
      }
      printf(" ");
   }
   printf("\n");
   return 0;
}

Required output:

PANDA

Current output:

Returned from execv call.
Panda
  • 19
  • 5
  • The calling program does not wait because [these functions do not return to the calling process](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/execv-wexecv?view=msvc-170). The system simply returns a value to indicate whether the process was launched. It is not like calling a function or subroutine. – Weather Vane Aug 24 '22 at 18:48

2 Answers2

1

You might want to start from printing errno and seeing what it says.

I suspect the cause is that caesar-cipher is not in the current directory and you aren't specifying the full path. There is execvp for taking into account $PATH.

Oh, another feature too: you might want to have NULL instead of "\0" as the end of argv.

juhist
  • 4,210
  • 16
  • 33
  • 3
    *Oh, another feature too: you might want to have NULL instead of "\0" as the end of argv.* There's no "might" about that one... – Andrew Henle Aug 24 '22 at 19:14
1

From the man page:

The array of pointers must be terminated by a null pointer.

So, you shouldn't have a pointer pointing at a null terminated string, like this:

argv[2] = "\0";

It should be:

argv[2] = NULL;

seems to ignore the call

It tries to find the NULL pointer in your array - but it doesn't know where the array ends - and therefore reads out of bounds with undefined behavior as a result. It may return from execv (indicating a failure) but it could also have crashed or done something worse.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108