简体   繁体   中英

The usage of execlp() in a c-program

I have a question regarding execlp() in c.

I have the following programm:

#include <stdio.h>
#include <unistd.h>
#include <sys/unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>
#include <limits.h>
#include <signal.h>

void INThandler(int);

int main(int argc, char* argv[]) {

  struct passwd *pwd;
  char *lgn;
  char *cwd;
  char buff[PATH_MAX + 1];
  char  s1[10], s2[10];

  /*Um den Namen zu bekommen*/
  lgn = getlogin();
  pwd = getpwnam(lgn);

  /*Um den Hostnamen zu bekommen*/
  char hostname[128];
  gethostname(hostname, sizeof hostname);

  /*Um das Arbeitsverzeichnis zu bekommen*/
  cwd = getcwd(buff, PATH_MAX + 1);
  if((cwd!=NULL)&& hostname!=NULL  && ((lgn=getlogin())!=NULL ||
(pwd!=NULL)))
    {
      signal(SIGINT, INThandler);
      while(1)
        {
          printf("%s@%s %s$", pwd->pw_name, hostname, cwd);
          if(scanf("%s %s",s1, s2)<1)
            return 1;
          printf("Befehl: %s\nArgument: %s\n",s1,s2);
          execlp(s1, s1, NULL);
          printf("Zhopa");
          return 1;
        }

    }
  return 0;
}

void INThandler(int sig) {
  char c;

  signal(sig, SIG_IGN);
  printf("Wollen Sie Program Verlassen? [y/n]");

  c = getchar();
  if(c == 'y' || c=='Y')
    exit(0);
  else
    signal(SIGINT, INThandler);
  getchar();
}

it should print the users name@hostname folder$ and take a linux command as an argument "ls -al" after that it should start it with execlp(), but it doesn't work as I think t should.

I read all the articles here regarding this command, but I guess, I still don't understand, how to use it.

I would appreciate someone's help.

You've to create a new process with a fork() and then in the new process (child) use the execlp . Here is the sample code. It doesn't handle any error and it works just with a command with exactly 1 parameter because that's what I've understood(eg ls -all )

#include <stdio.h>
#include <unistd.h>
#include <sys/unistd.h>
#include <sys/wait.h> /*Lib for waitpid*/
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>
#include <limits.h>
#include <signal.h>

void INThandler(int);

int main(int argc, char* argv[]) {

  int pid = 0; /*PROCESS ID*/
  struct passwd *pwd;
  char *lgn;
  char *cwd;
  char buff[PATH_MAX + 1];
  char  s1[10], s2[10];

  /*Um den Namen zu bekommen*/
  lgn = getlogin();
  pwd = getpwnam(lgn);

  /*Um den Hostnamen zu bekommen*/
  char hostname[128];
  gethostname(hostname, sizeof hostname);

  /*Um das Arbeitsverzeichnis zu bekommen*/
  cwd = getcwd(buff, PATH_MAX + 1);
  if((cwd!=NULL)&& hostname!=NULL  && ((lgn=getlogin())!=NULL ||
(pwd!=NULL)))
    {
      signal(SIGINT, INThandler);
      while(1)
        {
          printf("%s@%s %s$", pwd->pw_name, hostname, cwd);
          if(scanf("%s %s",s1, s2)<1)
            return 1;
          printf("Befehl: %s\nArgument: %s\n",s1,s2);
          pid = fork();
          if(pid == 0){ /*Child*/
            execlp(s1, s1, s2,(char*) NULL);
          }else if(pid > 0){ /*Father*/
            /*father waiting for the child*/
            waitpid(pid,NULL,0); 
          }
          printf("Zhopa");
        }

    }
  return 0;
}

void INThandler(int sig) {
  char c;

  signal(sig, SIG_IGN);
  printf("Wollen Sie Program Verlassen? [y/n]");

  c = getchar();
  if(c == 'y' || c=='Y')
    exit(0);
  else
    signal(SIGINT, INThandler);
  getchar();
}

Your signal handler invokes undefined behavior.

You can only call async-signal safe functions from within a signal handler. Per the POSIX standard :

... the behavior is undefined ... if the signal handler calls any function defined in this standard other than one of the functions listed in the following table.

The following table defines a set of functions that shall be async-signal-safe. Therefore, applications can call them, without restriction, from signal-catching functions. ...

[table of async-signal-safe functions]

Any function not in the above table may be unsafe with respect to signals. ...

This signal handler

void INThandler(int sig) {
  char c;

  signal(sig, SIG_IGN);
  printf("Wollen Sie Program Verlassen? [y/n]");

  c = getchar();
  if(c == 'y' || c=='Y')
    exit(0);
  else
    signal(SIGINT, INThandler);
  getchar();
}

has multiple non-async-signal-safe functions in it:

  • printf()
  • getchar()
  • exit()

Those functions can not be safely called from within a signal handler.

Given your code, a likely place for this signal handler to be called would be when the process is blocked in scanf() - trying to read from stdin . That likely involves a lock or mutex of some kind. Yet your signal handler calls getchar() which also tries to read from stdin , which may be locked or in some indeterminate state. If the main thread is blocked in scanf() , the asynchronous call to getchar() in the signal handler may deadlock or corrupt the internal structures used for stdin .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM