What is the usage of execl command?
excel("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127);
Can anyone explain each statement used in execl command?
And why only _exit(127) and not exit(0).
What is 127 number indicating?
execl is one of the several functions (exec*) that let you replace the current code of your process with the one provided by the file (an executable one) specified as the first argument. The whole space of your process is replaced by a fresh one... Other arguments serve as arguments to the command. A process is a kind of system structure controlling execution of some code. exec lets you mutate that code.
In the case exec succeed then the old code is forgotten, you will never be able to get back into it. This is not a function call.
In the case exec fails then execution continues, and in your case a call to _exit is made. _exit is a system function designed to stop execution of the current process, leading to its death. exit is a C-function that does the same at C-level, roughly closing C-streams and calling _exit.
The value provided (127) is used to communicate some information about the termination of this process to the process that launched it (process are launched by the use of fork, a call that clones a process). The value can be any eight bit value, but 0 is used to denote a process that terminated correctly, and any other non 0 value to denote a process that terminated in some abnormal condition.
You can type
man execl
in the terminal for more information on the execl command.
Related
the man page says that "The exec() family of functions replaces the current process image with a new process image." but I am not quite understand the meaning of "replaces the current process image with a new process image". For example, if exec succeed, perror would not be reached
execl("/bin/ls", /* Remaining items sent to ls*/ "/bin/ls", ".", (char *) NULL);
perror("exec failed");
Correct. If the exec works, the perror will not be called, simply because the call to perror no longer exists.
I find it's sometimes easier when educating newcomers to these concepts, to think of the UNIX execution model as being comprised of processes, programs and program instances.
Programs are executable files such as /bin/ls or /sbin/fdisk (note that this doesn't include things like bash or Python scripts since, in that case, the actual executable would be the bash or python interpreter, not the script).
Program instances are programs that have been loaded into memory and are basically running. While there is only one program like /bin/ls, there may be multiple instances of it running at any given time if, for example, both you and I run it concurrently.
That "loaded into memory" phrase is where processes come into the picture. Processes are just "containers" in which instances of programs can run.
So, when you fork a process, you end up with two distinct processes but they're still each running distinct instances of the same program. The fork call is often referred to as one which one process calls but two processes return from.
Likewise, exec will not have an effect on the process itself but it will discard the current program instance in that process and start a new instance of the requested program.
This discard in a successful exec call is what dictates that the code following it (perror in this case) will not be called.
It means your current process becomes the new process instead of what it was. You stop doing what you're doing and start doing,really being, something else instead, never to rebecome what that process once was.
Instead of starting a whole new process, however, your current pid and environment become the new process instead. That let's you setup things the way the new process will need it before doing the exec
You are correct. perror will not be called unless the execl fails. The exec functions are the means for starting new processes in a POSIX compliant OS (typically combined with a fork call). Maybe an example will help. Suppose your program, call it programX, is running. It then calls one of the exec functions like the one you have above. programX will no longer exist as a running process. Instead, ls will be running. It will have the same exact PID as programX, but pretty much be a whole new process otherwise.
the man page says that "The exec() family of functions replaces the current process image with a new process image." but I am not quite understand the meaning of "replaces the current process image with a new process image". For example, if exec succeed, perror would not be reached
execl("/bin/ls", /* Remaining items sent to ls*/ "/bin/ls", ".", (char *) NULL);
perror("exec failed");
Correct. If the exec works, the perror will not be called, simply because the call to perror no longer exists.
I find it's sometimes easier when educating newcomers to these concepts, to think of the UNIX execution model as being comprised of processes, programs and program instances.
Programs are executable files such as /bin/ls or /sbin/fdisk (note that this doesn't include things like bash or Python scripts since, in that case, the actual executable would be the bash or python interpreter, not the script).
Program instances are programs that have been loaded into memory and are basically running. While there is only one program like /bin/ls, there may be multiple instances of it running at any given time if, for example, both you and I run it concurrently.
That "loaded into memory" phrase is where processes come into the picture. Processes are just "containers" in which instances of programs can run.
So, when you fork a process, you end up with two distinct processes but they're still each running distinct instances of the same program. The fork call is often referred to as one which one process calls but two processes return from.
Likewise, exec will not have an effect on the process itself but it will discard the current program instance in that process and start a new instance of the requested program.
This discard in a successful exec call is what dictates that the code following it (perror in this case) will not be called.
It means your current process becomes the new process instead of what it was. You stop doing what you're doing and start doing,really being, something else instead, never to rebecome what that process once was.
Instead of starting a whole new process, however, your current pid and environment become the new process instead. That let's you setup things the way the new process will need it before doing the exec
You are correct. perror will not be called unless the execl fails. The exec functions are the means for starting new processes in a POSIX compliant OS (typically combined with a fork call). Maybe an example will help. Suppose your program, call it programX, is running. It then calls one of the exec functions like the one you have above. programX will no longer exist as a running process. Instead, ls will be running. It will have the same exact PID as programX, but pretty much be a whole new process otherwise.
the man page says that "The exec() family of functions replaces the current process image with a new process image." but I am not quite understand the meaning of "replaces the current process image with a new process image". For example, if exec succeed, perror would not be reached
execl("/bin/ls", /* Remaining items sent to ls*/ "/bin/ls", ".", (char *) NULL);
perror("exec failed");
Correct. If the exec works, the perror will not be called, simply because the call to perror no longer exists.
I find it's sometimes easier when educating newcomers to these concepts, to think of the UNIX execution model as being comprised of processes, programs and program instances.
Programs are executable files such as /bin/ls or /sbin/fdisk (note that this doesn't include things like bash or Python scripts since, in that case, the actual executable would be the bash or python interpreter, not the script).
Program instances are programs that have been loaded into memory and are basically running. While there is only one program like /bin/ls, there may be multiple instances of it running at any given time if, for example, both you and I run it concurrently.
That "loaded into memory" phrase is where processes come into the picture. Processes are just "containers" in which instances of programs can run.
So, when you fork a process, you end up with two distinct processes but they're still each running distinct instances of the same program. The fork call is often referred to as one which one process calls but two processes return from.
Likewise, exec will not have an effect on the process itself but it will discard the current program instance in that process and start a new instance of the requested program.
This discard in a successful exec call is what dictates that the code following it (perror in this case) will not be called.
It means your current process becomes the new process instead of what it was. You stop doing what you're doing and start doing,really being, something else instead, never to rebecome what that process once was.
Instead of starting a whole new process, however, your current pid and environment become the new process instead. That let's you setup things the way the new process will need it before doing the exec
You are correct. perror will not be called unless the execl fails. The exec functions are the means for starting new processes in a POSIX compliant OS (typically combined with a fork call). Maybe an example will help. Suppose your program, call it programX, is running. It then calls one of the exec functions like the one you have above. programX will no longer exist as a running process. Instead, ls will be running. It will have the same exact PID as programX, but pretty much be a whole new process otherwise.
I am trying to run a new process in background so it will be possible to continue working with parent process.
I used fork then execl. I tried to add to the execl command the argument & but it doesn't work:
execl("newproc","newproc","arg1","&",NULL);
Is there any solution?
The child will run in the background since you used fork. The child will keep running in parallel with the parent (if exec succeeded). If you care about whether the child process succeeded or not (and your code should) you should eventually call waitpid to collect its exit status. Otherwise you should call fork twice and have the intermediate process exit without waiting for the child, so that init adopts the grandchild process.
As #mah said, the & is unnecessary. But another change is needed to that line; execl is a variadic function, and function prototypes therefore don't take care of converting arguments to the correct type. Therefore the final argument should be passed as the correct type - just change it to (char*)NULL.
You mention that your code didn't work. While that could just be because of the spurious &, it may also be because of the first argument. The execl function does not search $PATH for the named program, so unless newproc is actually in the current directory, this execl() invocation will return. When execl returns, that always indicates that there is a problem. The simplest way to solve this is to use execlp() instead of execl(). The alternative approach is to specify an absolute path as the first argument. You can even specify a relative path as the first argument, but this is rarely useful.
The problem is that & is not a command line option to programs. Instead, it is merely special shell syntax which puts a command in the background. The distinguishing feature of background programs is that they are not connected to a terminal, and the terminal is not waiting for the process to complete. The proper function is daemon(). Do a man daemon to read up on how it is used.
& is not a command argument, its a flag that the shell uses to know to run the command in the background. In this case, you're performing the work of the shell... remove the &. Since you state you've called fork(), as long as you're only performing execl() in the child process after fork returns, you're already running in the background.
The system() function will launch a new process from C and a Perl script.
What exactly are the differences between processes called by system() in C and from Perl scripts, in terms of representation of error codes?
A little research brings up:
The return value is the exit status of
the program as returned by the wait
call. To get the actual exit value,
shift right by eight (see below). See
also "exec". This is not what you want
to use to capture the output from a
command, for that you should use
merely backticks or qx//, as described
in "STRING" in perlop. Return value
of -1 indicates a failure to start the
program or an error of the wait(2)
system call (inspect $! for the
reason).
And the docs of wait say:
Behaves like the wait(2) system call
on your system: it waits for a child
process to terminate and returns the
pid of the deceased process, or -1 if
there are no child processes. The
status is returned in $? and
${^CHILD_ERROR_NATIVE} . Note that a
return value of -1 could mean that
child processes are being
automatically reaped, as described in
perlipc.
Sources: This was taken from perldoc. Here's a tutorial on system in Perl.