exec function only running some commands, won't run echo

I'm trying to run command line arguments (specifically echo) through the exec family of functions. I can get the execv function to run if I write my own executable and run it, but if I try to run touch or echo it returns -1

#include <stdio.h>
#include <unistd.h> // exec functions
#include <sys/types.h> // pid_t
#include <sys/wait.h>

#define HIGH 1
#define LOW 0

int digitalWrite(int pin, short type) {

    pid_t pid = fork();
    if (pid == 0) {
        printf("pid == %i\n", pid);
        if (type == HIGH) {
            char* args[] = {"echo", "1", ">", "/sys/class/gpio/gpio67/value", NULL};
            int val = execv(args[0], args);
            printf("ran function execl, %i\n", val);
        } else {
            printf("Unable to do anything but set pin to HIGH\n");
        }
    } else if (pid < 0) { // pid < 0
        printf("fork failed\n");
    }

    wait(NULL);
}

int main() {

    printf("Starting digitalWrite\n");

    digitalWrite(0, HIGH);

    printf("Completed digitalWrite()\n");

    return 0;
}

Just for context here's my build:

$ gcc wiringbeagle.c 
$ ./a.out 
Starting digitalWrite
pid == 0
ran function execl, -1
Completed digitalWrite()
Completed digitalWrite()
$ ls
a.out  wiringbeagle.c

The command echo 1 > /sys/class/gpio/gpio67/value runs fine in the terminal on it's own, and if I create a local file (i.e. touch tmpfile.txt) and try to run echo hi > tmpfile.txt it runs as expected in my command line but doesn't run in the program.

I must be not understanding something with execv, and any assistance would be greatly appreciated!

The first argument to execv is the file to be executed. Unlike your shell, execv does not search through the directories indicated by the PATH environment variable, so you need to give it the complete path to the executable. Unless there is an executable file called echo in your current working directory, execv("echo",...) will fail with a "file not found" error. (Use perror to get better error messages).

If you want to search for the executable as the shell does, use execvp. But note that your shell probably executes echo as a built-in command, so it won't be the same echo as your shell uses. In this case, that's fine.

Once you fix that, you will encounter a different problem. Since you are just invoking a command-line utility with arguments, rather than using a shell, the argument ">" is just an argument. It is the shell which handles redirections (as well as pipes, quoting, and a bunch of other useful stuff). So all you will accomplish is to send the three arguments to stdout.

You could use the system function to execute a command using the shell, or you could set up the redirection yourself by freopening stdout in your child before doing the execvp.

You can get quite a lot of information about system interfaces using the man command. For example, to learn what freopen does, use man freopen. You can also read manpages on the internet, eg. http://man7.org/linux/man-pages/man3/freopen.3.html, but the documentation on your own system is right there, and also applies to the actual version of the software installed on your system (assuming you installed the documentation).

exec - Manual, Note that if the array already contains some elements, exec() will append to the If a program is started with this function, in order for it to continue running in the On Unix, to execute a command $cmd in the background, the one and only� The exec family of functions replaces the current running process with a new process. It can be used to run a C program by using another C program. It comes under the header file unistd.h. There are many members in the exec family which are shown below with examples.

Resource Type: exec, The exec has refreshonly => true , which allows Puppet to run the command only when some other resource is changed. (See the notes on refreshing below.). The exec has refreshonly => true, which allows Puppet to run the command only when some other resource is changed. (See the notes on refreshing below.) (See the notes on refreshing below.) The state managed by an exec resource represents whether the specified command needs to be executed during the catalog run.

execv() does not search the PATH environment variable in order to find an executable file. Per the Linux execv() man page (bolded text added):

...

Special semantics for execlp(), execvp(), and execvpe()

The execlp(), execvp(), and execvpe() functions duplicate the actions of the shell in searching for an executable file if the specified filename does not contain a slash (/) character. ...

...

So, those three will search the PATH environment variable if the filename passed does not contain a / character.

You're using execv(), which is not one of those three. Therefore, execv() will not search the PATH environment variable.

Since your current working directory doesn't contain an executable file called echo, execv() fails.

You need to use execvp() per the man page.

How To Execute Shell Commands with PHP Exec and Examples , We can list the created directory with Linux file command like below. We will also provide the directory name because exec() function will only� On Windows-Apache-PHP servers there is a problem with using the exec command more than once at the same time. If a script (with the exec command) is loaded more than once by the same user at the same time the server will freeze. In my case the PHP script using the exec command was used as the source of an image tag.

exec, string exec ( string $command [, array &$output [, int &$return_var ]] ) Note: When safe mode is enabled, you can only execute files within the safe_mode_exec_dir. If you're having problems with any of the exec(), system() etc. functions not SELinux won't let apache change the group id of the process by default. To run Python script using a Python Text Editor you can use the default “run” command or use hot keys like Function + F5 or simply F5(depending on your OS). Here’s an example of Python script being executed in IDLE.

When Runtime.exec() won't, This month, I'll discuss the traps lurking in the Runtime.exec() method. That is the only way to obtain a reference to the Runtime object. public Process exec( String command);; public Process exec(String [] cmdArray);; public Process A single string that represents both the program to execute and any arguments to that� a name: Used to pass a name as the zeroth argument of the command. l: Used to pass dash as the zeroth argument of the command. Note: exec command does not create a new process. When we run the exec command from the terminal, the ongoing terminal process is replaced by the command that is provided as the argument for the exec command.

Using the Perl system() function, Every manual documents the Perl system() function slightly differently, each leaving If the operating system command you're trying to execute uses any of these, you The builtin shell commands and the order of commands on $PATH won't be the Only use shell operations that are common to all Unix shells (like simple� The backup command was only available up to MS-DOS 5.00 but the restore command was included by default with later versions of MS-DOS to provide a way to restore files that were backed up in previous versions of MS-DOS. Rexec: The rexec command is used to run commands on remote computers running the rexec daemon.

Comments
  • I'm curious as to why you're even using exec to do this for you. C provides file I/O built in to the standard library.
  • @rici, I suspect that's covered by my weasel-word use of "may" :-)