Question

I'm new to C. And I'm learning UNIX with Stevens & Rago book. There I have a problem. One of the early figures is not works in my implementation.

#include "apue.h"                                     
#include <sys/wait.h>                                 

int                                                   
main(void)                                            
{                                                     
  char buf[MAXLINE];                                  
  pid_t pid;                                          
  int status;                                         

  printf("%% ");                                      
  while (fgets(buf, MAXLINE, stdin) != NULL) {        
    if (buf[strlen(buf) - 1] == "\n")                 
      buf[strlen(buf) - 1] = 0;                       

    if ((pid = fork()) < 0) {                         
      err_sys("Fork error: %d");                      
    }                                                 
    else if ((pid == 0) && (access(buf, F_OK ) != 1)){ /* Here I have an extra check to ensure, that the binary exists. */
      execlp(buf, buf, (char *)0);                    
      err_ret("Couldn't execute: %s", buf);           
      exit(127);                                      
    }                                                 

    if ((pid = waitpid(pid, &status, 0)) < 0)         
      err_sys("waitpid error");                       
    printf("%% ");                                    
  }                                                   
  exit(0);                                            
}                                                     

When I start the program:

$ ./exec
% /bin/ls
Couldn't execute: /bin/ls
: No such file or directory

I have got several questions about execlp(buf, buf, (char *)0);:

Why execlp can't execute the binary?

int execlp(const char *file, const char *arg, ...);

Why buf passed twice? If second argument must be an arguments for binary. I can't find, what does it mean: (char *)0? What the pointer is this? What for zero in there?

Was it helpful?

Solution

Couldn't execute: /bin/ls
: No such file or directory

Notice that the error message is on a new line, but you tried to remove the end-of-line character from the input. So your removal appears not to be working.

The reason for that is:

if (buf[strlen(buf) - 1] == "\n")

You're comparing a character (buf[x]) with a string ("\n"), i.e. a pointer. Turn on your compiler's warnings and read them carefully.

Try this instead:

if (buf[strlen(buf) - 1] == '\n')

The arguments for execlp are described in its man page:

The first argument, by convention, should point to the filename associated with the file being executed.

Or in POSIX here.

(char *)0 is a null-pointer of type char*. Nothing magic going on here, an integral constant of value 0 is a null-pointer constant. But since execlp is a variadic function, the cast is necessary - the constant zero would be treated as an int otherwise, which might not have the same size as a pointer (and the internal representation of a null-pointer might not be the same as that of the integer 0), leading to undefined behavior.

OTHER TIPS

your code is right I just compiled except that. don't use double quote (") there just use in single quote like this

buf[strlen(buf) - 1] == '\n'

also include this

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

#include<unistd.h>

#include<string.h>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top