0

My program accepts many options.
And I have to write a shell script to test my program.

The shell script must run my program multiple times and every time it must pass different options and different arguments for an option.

For example:

    #!/bin/bash
echo "CS111 " > testing.txt
echo "is " >> testing.txt
echo "intersting " >> testing.txt
echo "even " >> testing.txt
echo "though " >> testing.txt
echo "it " >> testing.txt
echo "is " >> testing.txt
echo "time " >> testing.txt
echo "consuming " >> testting.txt
echo "and " >> testing.txt
echo "hard " >> testing.txt

./simpsh \
--verbose \
--rdonly in.txt \
--append --wronly out.txt \
--wronly err.txt \
--command 0 1 2 sort testing

./simpsh \
--verbose\ 
--rdonly in.txt \
--append --wronly out.txt \
--wronly err.txt \
--command 0 1 2 sort

The first test will be executed, but then there is an error 127.

This is my code:

#include <stdio.h>     
#include <stdlib.h>    
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

int main(int argc, char **argv)
{
  int c;
  int oflag = 0;
  int *fd;
  int fdCount = 0;
  int pipefd[2];
  int p;
  int verbose = 0;
  while (1) {
    static struct option long_options[] = {
      {"append",no_argument,0,'a'},
      {"cloexec",no_argument,0,'b'},
      {"creat",  no_argument,0,'c'},
      {"directory",no_argument,0,'d'},
      {"dsync",no_argument,0,'e'},
      {"excl",no_argument,0,'f'},
      {"nofollow",no_argument,0,'g'},
      {"nonblock",no_argument, 0,'h'},
      {"rsync",no_argument,0,'i'},
      {"sync",no_argument,0,'j'},
      {"trunc",no_argument,0,'k'},
      {"rdonly",required_argument,0,'l'},
      {"rdwr",required_argument,0,'m'},
      {"wronly",required_argument,0,'n'},
      {"pipe",no_argument,0,'o'},
      {"command",required_argument,0,'p'},
      {"wait",no_argument,0,'q'},
      {"close",required_argument,0,'r'},
      {"verbose",no_argument,0,'s'},
      {"profile",no_argument,0,'t'},
      {"abort",no_argument,0,'u'},
      {"catch",required_argument,0,'v'},
      {"ignore",required_argument,0,'w'},
      {"default",required_argument,0,'x'},
      {"pause",no_argument,0,'y'},
      };
    c = getopt_long(argc, argv, "abcdefghijkl:m:n:op:qr:stuv:w:x:y", long_options, NULL);
    if (c == -1)
      break;
    switch (c) {
    case 'a':
      if(verbose)
    printf("O_APPEND\n");
      oflag = oflag | O_APPEND;
      break;
    case 'b':
      if(verbose)
    printf("O_CLOEXEC\n");
      oflag = oflag | O_CLOEXEC;
      break;
    case 'c':
      if(verbose)
    printf("O_CREAT\n");
      oflag = oflag | O_CREAT;
      break;
    case 'd':
      if(verbose)
    printf("O_DIRECTORY\n");
      oflag = oflag | O_DIRECTORY;
      break;
    case 'e':
      if(verbose)
    printf("O_DSYNC\n");
      oflag = oflag | O_DSYNC;
      break;
    case 'f':
      if(verbose)
    printf("O_EXCL\n");
      oflag = oflag | O_EXCL;
      break;
    case 'g':
      if(verbose)
    printf("O_NOFOLLOW\n");
      oflag = oflag | O_NOFOLLOW;
      break;
    case 'h':
      if(verbose)
    printf("O_NONBLOCK\n");
      oflag = oflag | O_NONBLOCK;
      break;
    case 'i':
      if(verbose)
    printf("O_RSYNC\n");
      oflag = oflag | O_RSYNC;
      break;
    case 'j':
      if(verbose)
    printf("O_SYNC\n");
      oflag = oflag | O_SYNC;
      break;
    case 'k':
      if(verbose)
    printf("O_TRUNC\n");
      oflag = oflag | O_TRUNC;
      break;
    case 'l':
      if(optarg){
    if(fdCount == 0)
      fd = (int *)malloc(sizeof(int));
    else
      fd = (int *)realloc(fd, (fdCount  + 1)* sizeof(int));
    if(verbose)
      printf("O_RDONLY %s\n", optarg);
    fd[fdCount] = open(optarg, oflag | O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
    oflag = 0;
    if(fd[fdCount] == -1){
      fprintf(stderr, "%s cannot be opened/created", optarg);
      exit(1);
    }
    else
      fdCount++;
      }
      break;
    case 'm':
       if(optarg){
    if(fdCount == 0)
      fd = (int *)malloc(sizeof(int));
    else
      fd = (int *)realloc(fd, (fdCount + 1)* sizeof(int));
    if(verbose)
      printf("O_RDWR %s\n", optarg);
    fd[fdCount] = open(optarg, oflag | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
    oflag = 0;
    if(fd[fdCount] == -1){
      fprintf(stderr, "%s cannot be opened/created", optarg);
      exit(2);
    }
    else
      fdCount++;
       }
      break;
    case 'n':
      if(optarg){
    if(fdCount == 0)
      fd = (int *)malloc(sizeof(int));
    else
      fd = (int *)realloc(fd, (fdCount + 1)* sizeof(int));
    if(verbose)
      printf("O_WRONLY %s\n", optarg);
    fd[fdCount] = open(optarg, oflag | O_WRONLY, S_IRWXU | S_IRWXG | S_IRWXO);
    oflag = 0;
    if(fd[fdCount] == -1){
      fprintf(stderr, "%s cannot be opened/created", optarg);
      exit(3);
    }
    else
      fdCount++;
       }
      break;
    case 'o':
      if(verbose)
    printf("pipe\n");
      p = pipe(pipefd);
      if(p == -1){
    fprintf(stderr, "The pipe wasn't made.\n");
    exit(5);
      }
      else{
    if(fdCount == 0)
      fd = (int *)malloc(2 * sizeof(int));
    else
      fd = (int *)realloc(fd, (fdCount + 2) * sizeof(int));
    fdCount = fdCount + 2;
    fd[fdCount - 2] = pipefd[0];
    fd[fdCount - 1] = pipefd[1];
      }
      break;
    case 'p':
      if(optarg){
    if(verbose){
      printf("command ");
      int vi = optind -1;
      for( vi = optind - 1; vi < argc && *argv[vi] != '-'; vi++)
        printf("%s ", argv[vi]);
      printf("\n");
    }
    pid_t pid = fork();
    if(pid == 0){
      int fdin;
      int fdout;
      int fderr;
      int i = 0;
      char **arg;
      int index;
      for(index = optind-1; index < argc && *argv[index] != '-'; index++, i++){
        switch(i){
        case 0:
          fdin = atoi(argv[index]);
          break;
        case 1:
          fdout = atoi(argv[index]);
          break;
        case 2:
          fderr = atoi(argv[index]);
          break;
        default:
          if(i - 3 == 0)
        arg = (char**)malloc(sizeof(char));
          else
        arg = (char**)realloc(arg, ((i - 3) + 1)* sizeof(char));
          arg[i - 3] = strdup(argv[index]);
        }
      }
      dup2(fd[fdin],0);
      close(fd[fdin]);
      dup2(fd[fdout],1);
      close(fd[fdout]);
      dup2(fd[fderr],2);
      close(fd[fderr]);
      execvp(arg[0], arg);
    }
    else if(pid == -1){
      fprintf(stderr, "The new proccess isn't created by fork()\n");
      exit(6);
    }
      }
      break;
    case 'q':
      break;
    case 'r':
      break;
    case 's':
      verbose = 1;
      break;
    case 't':
      break;
    case 'u':
      break;
    case 'v':
      break;
    case 'w':
      break;
    case 'x':
      break;
    case 'y':
      break;
    default:
      fprintf(stderr, "An option is misstyped or has no argument\n");
      exit(4);
    }
  }
  exit(0);
}
2

1 Answer 1

1

Return code 127 indicates the command was not found.

It is likely myprogram is not found inside the current directory you execute your test script from.

Try changing to the directory where your program is located, or calling it with a full path.

Also, remember bash ignores commands that fail unless you activate the "-e" flag or trap errors and handle them explicitly. When building a test script (or any script for that matter), allowing silent failure could lead to bad surprises down the road.

Sign up to request clarification or add additional context in comments.

18 Comments

it runs the first ./myprogram --a --b --c file.txt --d but then it gives error 127. so the first run is fine and no issue with the myprogram.
If you execute "myprogram" manually with the same arguments as those that cause the 127 return code, do you get a 127 return code also?
if I use ubuntu terminal directly without using shell script file to run myprogram no error. by the way, in terminal I run them separately. I mean like: $ ./myprogram ... then I press enter after the program returns then I do the second test and third test and so on.
If you change the order in which the commands are executed, is it always the same one failing?
if I commented out the other tests, and leave only one test case no matter which one, then no error.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.