1

I'm supposed to create a linux shell using C. Below is my code:

#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define SHELL "/bin/sh"
#include "extern.h"

int mysystem (char *command)
{
  int status;
  pid_t pid;

  pid = fork ();
  if (pid == 0)
    {

      execl (SHELL, SHELL, "-c", command, NULL);
      _exit (EXIT_FAILURE);
    }
  else if (pid < 0)

    status = -1;
  else

    if (waitpid (pid, &status, 0) != pid)
      status = -1;
  return status;
}

Everything is right when I test the code using different commands like "ls", "man", etc. but when I use notepad to create a testfile containing the following:

echo "hello"
exit 2

the return code come out to be 512 when it's supposed to be just 2. Can anyone help me fix my code?

3
  • can anyone help me edit my question. there are things missing. thx Commented Nov 24, 2010 at 21:52
  • Does it work when you put a semicolon after echo "hello" ? Commented Nov 24, 2010 at 21:55
  • @Amir Afghani: no, it doesn't work Commented Nov 24, 2010 at 21:57

4 Answers 4

4

status is not the exit code; it contains other information as well. Normally the return value is in bits 8-15 of status, but you should be using the macros in wait.h to extract the return value from status in a portable way.

Note that 512 is 2<<8.

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

Comments

4

Make sure you're using the macros like WIFEXITED and WEXITSTATUS on your status value. See your operating system's man page for waitpid. Here is a description of the POSIX requirements on waitpid.

Comments

0

By notepad do you mean you're using a Windows program to create a Unix shell script? That doesn't work because you end up with CRLF at the end of each line instead of LF. Try the "dos2unix" command on the script to convert it to Unix format and then run it.

I assume you're aware that code is already available in the system() library call? Judging by your function name, I'd guess you're just trying to learn how to do it with system calls.

1 Comment

what do u mean that the code is already available in the system()library call? can you show me?
0

Try enclosing your command string you supply to /bin/sh with quotes, because otherwise the space character makes /bin/sh think you are supplying another option to the shell itself, not to the command you are calling. For example, try this in a terminal:

/bin/sh -c exit 2
echo $?

and

/bin/sh -c "exit 2"
echo $?

The first one gives 0, and the second one gives the desired 2.

2 Comments

but when I do ./mysystem in the terminal, it still prints out 512.
It prints 512 because you don't use the WEXITSTATUS macro, as others have noted. Try changing the last line of your function to be return WEXITSTATUS(status).

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.