A simple fork with an ugly waitpid
You could consider terminating with the exit codes from &lt;sysexits.h&gt;, especially if the client is expecting them.  For instance, if fork() fails, return or call exit() with EX_OSERR.
It may be helpful to make the 127 error code a macro with a relevant name, since it's probably not a very commonly-known error code, especially returned from main().  I assume it's being used correctly (based on this post).
It would look clearer to put execlp()'s return value in a conditional, rather than always printing an error afterwards.  Since the exec functions only return a value (-1) on error, have the error message displayed only if this value gets returned.  Of course, have errno printed out as well.
You should also check to see if the child process has terminated from a signal.  This can be done by calling WTERMSIG() and displaying its returned signal value.  That can be determined by first checking the return value of WIFEXITED() (before doing the other checks).

Example:

int status;

// do checks with waitpid()

if (WIFEXITED(status))
{
    fprintf(stderr, "the process exited with code %d\n", status);   
    exit(WEXITSTATUS(status));
}
else
{
    fprintf(stderr, "the process died with signal %d\n", WTERMSIG(status));
    exit(EX_OSERR);
}

I don't see a need for printerr() when you can just use perror(), which is already provided in &lt;stdio.h&gt; and does more than your function.  Regardless, it's a little redundant to put "failed" into the argument.  Clients receiving such a message should already be able to see that it's some kind of error, and it's automatically printed to stderr.
Instead of just having default provide an ambiguous error message, have it display the current value of errno with perror().  Again, your function doesn't do very much.