diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-24 04:52:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-24 04:52:22 +0000 |
commit | 3d08cd331c1adcf0d917392f7e527b3f00511748 (patch) | |
tree | 312f0d1e1632f48862f044b8bb87e602dcffb5f9 /man/man2/execve.2 | |
parent | Adding debian version 6.7-2. (diff) | |
download | manpages-3d08cd331c1adcf0d917392f7e527b3f00511748.tar.xz manpages-3d08cd331c1adcf0d917392f7e527b3f00511748.zip |
Merging upstream version 6.8.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'man/man2/execve.2')
-rw-r--r-- | man/man2/execve.2 | 889 |
1 files changed, 889 insertions, 0 deletions
diff --git a/man/man2/execve.2 b/man/man2/execve.2 new file mode 100644 index 0000000..d318d80 --- /dev/null +++ b/man/man2/execve.2 @@ -0,0 +1,889 @@ +.\" Copyright (c) 1992 Drew Eckhardt (drew@cs.colorado.edu), March 28, 1992 +.\" and Copyright (c) 2006 Michael Kerrisk <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.\" Modified by Michael Haardt <michael@moria.de> +.\" Modified 1993-07-21 by Rik Faith <faith@cs.unc.edu> +.\" Modified 1994-08-21 by Michael Chastain <mec@shell.portal.com>: +.\" Modified 1997-01-31 by Eric S. Raymond <esr@thyrsus.com> +.\" Modified 1999-11-12 by Urs Thuermann <urs@isnogud.escape.de> +.\" Modified 2004-06-23 by Michael Kerrisk <mtk.manpages@gmail.com> +.\" 2006-09-04 Michael Kerrisk <mtk.manpages@gmail.com> +.\" Added list of process attributes that are not preserved on exec(). +.\" 2007-09-14 Ollie Wild <aaw@google.com>, mtk +.\" Add text describing limits on command-line arguments + environment +.\" +.TH execve 2 2024-05-02 "Linux man-pages (unreleased)" +.SH NAME +execve \- execute program +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include <unistd.h> +.P +.BI "int execve(const char *" pathname ", char *const _Nullable " argv [], +.BI " char *const _Nullable " envp []); +.fi +.SH DESCRIPTION +.BR execve () +executes the program referred to by \fIpathname\fP. +This causes the program that is currently being run by the calling process +to be replaced with a new program, with newly initialized stack, heap, +and (initialized and uninitialized) data segments. +.P +\fIpathname\fP must be either a binary executable, or a script +starting with a line of the form: +.P +.in +4n +.EX +\fB#!\fP\fIinterpreter \fP[optional-arg] +.EE +.in +.P +For details of the latter case, see "Interpreter scripts" below. +.P +.I argv +is an array of pointers to strings passed to the new program +as its command-line arguments. +By convention, the first of these strings (i.e., +.IR argv[0] ) +should contain the filename associated with the file being executed. +The +.I argv +array must be terminated by a null pointer. +(Thus, in the new program, +.I argv[argc] +will be a null pointer.) +.P +.I envp +is an array of pointers to strings, conventionally of the form +.BR key=value , +which are passed as the environment of the new program. +The +.I envp +array must be terminated by a null pointer. +.P +This manual page describes the Linux system call in detail; +for an overview of the nomenclature and the many, often preferable, +standardised variants of this function provided by libc, +including ones that search the +.B PATH +environment variable, see +.BR exec (3). +.P +The argument vector and environment can be accessed by the +new program's main function, when it is defined as: +.P +.in +4n +.EX +int main(int argc, char *argv[], char *envp[]) +.EE +.in +.P +Note, however, that the use of a third argument to the main function +is not specified in POSIX.1; +according to POSIX.1, +the environment should be accessed via the external variable +.BR environ (7). +.P +.BR execve () +does not return on success, and the text, initialized data, +uninitialized data (bss), and stack of the calling process are overwritten +according to the contents of the newly loaded program. +.P +If the current program is being ptraced, a \fBSIGTRAP\fP signal is sent to it +after a successful +.BR execve (). +.P +If the set-user-ID bit is set on the program file referred to by +\fIpathname\fP, +then the effective user ID of the calling process is changed +to that of the owner of the program file. +Similarly, if the set-group-ID bit is set on the program file, +then the effective group ID of the calling +process is set to the group of the program file. +.P +The aforementioned transformations of the effective IDs are +.I not +performed (i.e., the set-user-ID and set-group-ID bits are ignored) +if any of the following is true: +.IP \[bu] 3 +the +.I no_new_privs +attribute is set for the calling thread (see +.BR prctl (2)); +.IP \[bu] +the underlying filesystem is mounted +.I nosuid +(the +.B MS_NOSUID +flag for +.BR mount (2)); +or +.IP \[bu] +the calling process is being ptraced. +.P +The capabilities of the program file (see +.BR capabilities (7)) +are also ignored if any of the above are true. +.P +The effective user ID of the process is copied to the saved set-user-ID; +similarly, the effective group ID is copied to the saved set-group-ID. +This copying takes place after any effective ID changes that occur +because of the set-user-ID and set-group-ID mode bits. +.P +The process's real UID and real GID, as well as its supplementary group IDs, +are unchanged by a call to +.BR execve (). +.P +If the executable is an a.out dynamically linked +binary executable containing +shared-library stubs, the Linux dynamic linker +.BR ld.so (8) +is called at the start of execution to bring +needed shared objects into memory +and link the executable with them. +.P +If the executable is a dynamically linked ELF executable, the +interpreter named in the PT_INTERP segment is used to load the needed +shared objects. +This interpreter is typically +.I /lib/ld\-linux.so.2 +for binaries linked with glibc (see +.BR ld\-linux.so (8)). +.\" +.SS Effect on process attributes +All process attributes are preserved during an +.BR execve (), +except the following: +.IP \[bu] 3 +The dispositions of any signals that are being caught are +reset to the default +.RB ( signal (7)). +.IP \[bu] +Any alternate signal stack is not preserved +.RB ( sigaltstack (2)). +.IP \[bu] +Memory mappings are not preserved +.RB ( mmap (2)). +.IP \[bu] +Attached System\ V shared memory segments are detached +.RB ( shmat (2)). +.IP \[bu] +POSIX shared memory regions are unmapped +.RB ( shm_open (3)). +.IP \[bu] +Open POSIX message queue descriptors are closed +.RB ( mq_overview (7)). +.IP \[bu] +Any open POSIX named semaphores are closed +.RB ( sem_overview (7)). +.IP \[bu] +POSIX timers are not preserved +.RB ( timer_create (2)). +.IP \[bu] +Any open directory streams are closed +.RB ( opendir (3)). +.IP \[bu] +Memory locks are not preserved +.RB ( mlock (2), +.BR mlockall (2)). +.IP \[bu] +Exit handlers are not preserved +.RB ( atexit (3), +.BR on_exit (3)). +.IP \[bu] +The floating-point environment is reset to the default (see +.BR fenv (3)). +.P +The process attributes in the preceding list are all specified +in POSIX.1. +The following Linux-specific process attributes are also +not preserved during an +.BR execve (): +.IP \[bu] 3 +The process's "dumpable" attribute is set to the value 1, +unless a set-user-ID program, a set-group-ID program, +or a program with capabilities is being executed, +in which case the dumpable flag may instead be reset to the value in +.IR /proc/sys/fs/suid_dumpable , +in the circumstances described under +.B PR_SET_DUMPABLE +in +.BR prctl (2). +Note that changes to the "dumpable" attribute may cause ownership +of files in the process's +.IR /proc/ pid +directory to change to +.IR root:root , +as described in +.BR proc (5). +.IP \[bu] +The +.BR prctl (2) +.B PR_SET_KEEPCAPS +flag is cleared. +.IP \[bu] +(Since Linux 2.4.36 / 2.6.23) +If a set-user-ID or set-group-ID program is being executed, +then the parent death signal set by +.BR prctl (2) +.B PR_SET_PDEATHSIG +flag is cleared. +.IP \[bu] +The process name, as set by +.BR prctl (2) +.B PR_SET_NAME +(and displayed by +.IR "ps\ \-o comm" ), +is reset to the name of the new executable file. +.IP \[bu] +The +.B SECBIT_KEEP_CAPS +.I securebits +flag is cleared. +See +.BR capabilities (7). +.IP \[bu] +The termination signal is reset to +.B SIGCHLD +(see +.BR clone (2)). +.IP \[bu] +The file descriptor table is unshared, undoing the effect of the +.B CLONE_FILES +flag of +.BR clone (2). +.P +Note the following further points: +.IP \[bu] 3 +All threads other than the calling thread are destroyed during an +.BR execve (). +Mutexes, condition variables, and other pthreads objects are not preserved. +.IP \[bu] +The equivalent of \fIsetlocale(LC_ALL, "C")\fP +is executed at program start-up. +.IP \[bu] +POSIX.1 specifies that the dispositions of any signals that +are ignored or set to the default are left unchanged. +POSIX.1 specifies one exception: if +.B SIGCHLD +is being ignored, +then an implementation may leave the disposition unchanged or +reset it to the default; Linux does the former. +.IP \[bu] +Any outstanding asynchronous I/O operations are canceled +.RB ( aio_read (3), +.BR aio_write (3)). +.IP \[bu] +For the handling of capabilities during +.BR execve (), +see +.BR capabilities (7). +.IP \[bu] +By default, file descriptors remain open across an +.BR execve (). +File descriptors that are marked close-on-exec are closed; +see the description of +.B FD_CLOEXEC +in +.BR fcntl (2). +(If a file descriptor is closed, this will cause the release +of all record locks obtained on the underlying file by this process. +See +.BR fcntl (2) +for details.) +POSIX.1 says that if file descriptors 0, 1, and 2 would +otherwise be closed after a successful +.BR execve (), +and the process would gain privilege because the set-user-ID or +set-group-ID mode bit was set on the executed file, +then the system may open an unspecified file for each of these +file descriptors. +As a general principle, no portable program, whether privileged or not, +can assume that these three file descriptors will remain +closed across an +.BR execve (). +.\" On Linux it appears that these file descriptors are +.\" always open after an execve(), and it looks like +.\" Solaris 8 and FreeBSD 6.1 are the same. -- mtk, 30 Apr 2007 +.SS Interpreter scripts +An interpreter script is a text file that has execute +permission enabled and whose first line is of the form: +.P +.in +4n +.EX +\fB#!\fP\fIinterpreter \fP[optional-arg] +.EE +.in +.P +The +.I interpreter +must be a valid pathname for an executable file. +.P +If the +.I pathname +argument of +.BR execve () +specifies an interpreter script, then +.I interpreter +will be invoked with the following arguments: +.P +.in +4n +.EX +\fIinterpreter\fP [optional-arg] \fIpathname\fP arg... +.EE +.in +.P +where +.I pathname +is the pathname of the file specified as the first argument of +.BR execve (), +and +.I arg... +is the series of words pointed to by the +.I argv +argument of +.BR execve (), +starting at +.IR argv[1] . +Note that there is no way to get the +.I argv[0] +that was passed to the +.BR execve () +call. +.\" See the P - preserve-argv[0] option. +.\" Documentation/admin-guide/binfmt-misc.rst +.\" https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html +.P +For portable use, +.I optional-arg +should either be absent, or be specified as a single word (i.e., it +should not contain white space); see NOTES below. +.P +Since Linux 2.6.28, +.\" commit bf2a9a39639b8b51377905397a5005f444e9a892 +the kernel permits the interpreter of a script to itself be a script. +This permission is recursive, up to a limit of four recursions, +so that the interpreter may be a script which is interpreted by a script, +and so on. +.SS Limits on size of arguments and environment +Most UNIX implementations impose some limit on the total size +of the command-line argument +.RI ( argv ) +and environment +.RI ( envp ) +strings that may be passed to a new program. +POSIX.1 allows an implementation to advertise this limit using the +.B ARG_MAX +constant (either defined in +.I <limits.h> +or available at run time using the call +.IR "sysconf(_SC_ARG_MAX)" ). +.P +Before Linux 2.6.23, the memory used to store the +environment and argument strings was limited to 32 pages +(defined by the kernel constant +.BR MAX_ARG_PAGES ). +On architectures with a 4-kB page size, +this yields a maximum size of 128\ kB. +.P +On Linux 2.6.23 and later, most architectures support a size limit +derived from the soft +.B RLIMIT_STACK +resource limit (see +.BR getrlimit (2)) +that is in force at the time of the +.BR execve () +call. +(Architectures with no memory management unit are excepted: +they maintain the limit that was in effect before Linux 2.6.23.) +This change allows programs to have a much larger +argument and/or environment list. +.\" For some background on the changes to ARG_MAX in Linux 2.6.23 and +.\" Linux 2.6.25, see: +.\" http://sourceware.org/bugzilla/show_bug.cgi?id=5786 +.\" http://bugzilla.kernel.org/show_bug.cgi?id=10095 +.\" http://thread.gmane.org/gmane.linux.kernel/646709/focus=648101, +.\" checked into Linux 2.6.25 as commit a64e715fc74b1a7dcc5944f848acc38b2c4d4ee2. +For these architectures, the total size is limited to 1/4 of the allowed +stack size. +(Imposing the 1/4-limit +ensures that the new program always has some stack space.) +.\" Ollie: That doesn't include the lists of pointers, though, +.\" so the actual usage is a bit higher (1 pointer per argument). +Additionally, the total size is limited to 3/4 of the value +of the kernel constant +.B _STK_LIM +(8 MiB). +Since Linux 2.6.25, +the kernel also places a floor of 32 pages on this size limit, +so that, even when +.B RLIMIT_STACK +is set very low, +applications are guaranteed to have at least as much argument and +environment space as was provided by Linux 2.6.22 and earlier. +(This guarantee was not provided in Linux 2.6.23 and 2.6.24.) +Additionally, the limit per string is 32 pages (the kernel constant +.BR MAX_ARG_STRLEN ), +and the maximum number of strings is 0x7FFFFFFF. +.SH RETURN VALUE +On success, +.BR execve () +does not return, on error \-1 is returned, and +.I errno +is set to indicate the error. +.SH ERRORS +.TP +.B E2BIG +The total number of bytes in the environment +.RI ( envp ) +and argument list +.RI ( argv ) +is too large, +an argument or environment string is too long, +or the full +.I pathname +of the executable is too long. +The terminating null byte is counted as part of the string length. +.TP +.B EACCES +Search permission is denied on a component of the path prefix of +.I pathname +or the name of a script interpreter. +(See also +.BR path_resolution (7).) +.TP +.B EACCES +The file or a script interpreter is not a regular file. +.TP +.B EACCES +Execute permission is denied for the file or a script or ELF interpreter. +.TP +.B EACCES +The filesystem is mounted +.IR noexec . +.TP +.BR EAGAIN " (since Linux 3.1)" +.\" commit 72fa59970f8698023045ab0713d66f3f4f96945c +Having changed its real UID using one of the +.BR set*uid () +calls, the caller was\[em]and is now still\[em]above its +.B RLIMIT_NPROC +resource limit (see +.BR setrlimit (2)). +For a more detailed explanation of this error, see NOTES. +.TP +.B EFAULT +.I pathname +or one of the pointers in the vectors +.I argv +or +.I envp +points outside your accessible address space. +.TP +.B EINVAL +An ELF executable had more than one PT_INTERP segment (i.e., tried to +name more than one interpreter). +.TP +.B EIO +An I/O error occurred. +.TP +.B EISDIR +An ELF interpreter was a directory. +.TP +.B ELIBBAD +An ELF interpreter was not in a recognized format. +.TP +.B ELOOP +Too many symbolic links were encountered in resolving +.I pathname +or the name of a script or ELF interpreter. +.TP +.B ELOOP +The maximum recursion limit was reached during recursive script +interpretation (see "Interpreter scripts", above). +Before Linux 3.8, +.\" commit d740269867021faf4ce38a449353d2b986c34a67 +the error produced for this case was +.BR ENOEXEC . +.TP +.B EMFILE +The per-process limit on the number of open file descriptors has been reached. +.TP +.B ENAMETOOLONG +.I pathname +is too long. +.TP +.B ENFILE +The system-wide limit on the total number of open files has been reached. +.TP +.B ENOENT +The file +.I pathname +or a script or ELF interpreter does not exist. +.TP +.B ENOEXEC +An executable is not in a recognized format, is for the wrong +architecture, or has some other format error that means it cannot be +executed. +.TP +.B ENOMEM +Insufficient kernel memory was available. +.TP +.B ENOTDIR +A component of the path prefix of +.I pathname +or a script or ELF interpreter is not a directory. +.TP +.B EPERM +The filesystem is mounted +.IR nosuid , +the user is not the superuser, +and the file has the set-user-ID or set-group-ID bit set. +.TP +.B EPERM +The process is being traced, the user is not the superuser and the +file has the set-user-ID or set-group-ID bit set. +.TP +.B EPERM +A "capability-dumb" applications would not obtain the full set of +permitted capabilities granted by the executable file. +See +.BR capabilities (7). +.TP +.B ETXTBSY +The specified executable was open for writing by one or more processes. +.SH VERSIONS +POSIX does not document the #! behavior, but it exists +(with some variations) on other UNIX systems. +.P +On Linux, +.I argv +and +.I envp +can be specified as NULL. +In both cases, this has the same effect as specifying the argument +as a pointer to a list containing a single null pointer. +.B "Do not take advantage of this nonstandard and nonportable misfeature!" +On many other UNIX systems, specifying +.I argv +as NULL will result in an error +.RB ( EFAULT ). +.I Some +other UNIX systems treat the +.I envp==NULL +case the same as Linux. +.\" e.g., EFAULT on Solaris 8 and FreeBSD 6.1; but +.\" HP-UX 11 is like Linux -- mtk, Apr 2007 +.\" Bug filed 30 Apr 2007: http://bugzilla.kernel.org/show_bug.cgi?id=8408 +.\" Bug rejected (because fix would constitute an ABI change). +.\" +.P +POSIX.1 says that values returned by +.BR sysconf (3) +should be invariant over the lifetime of a process. +However, since Linux 2.6.23, if the +.B RLIMIT_STACK +resource limit changes, then the value reported by +.B _SC_ARG_MAX +will also change, +to reflect the fact that the limit on space for holding +command-line arguments and environment variables has changed. +.\" +.SS Interpreter scripts +The kernel imposes a maximum length on the text that follows the +"#!" characters at the start of a script; +characters beyond the limit are ignored. +Before Linux 5.1, the limit is 127 characters. +Since Linux 5.1, +.\" commit 6eb3c3d0a52dca337e327ae8868ca1f44a712e02 +the limit is 255 characters. +.P +The semantics of the +.I optional-arg +argument of an interpreter script vary across implementations. +On Linux, the entire string following the +.I interpreter +name is passed as a single argument to the interpreter, +and this string can include white space. +However, behavior differs on some other systems. +Some systems +.\" e.g., Solaris 8 +use the first white space to terminate +.IR optional-arg . +On some systems, +.\" e.g., FreeBSD before 6.0, but not FreeBSD 6.0 onward +an interpreter script can have multiple arguments, +and white spaces in +.I optional-arg +are used to delimit the arguments. +.P +Linux (like most other modern UNIX systems) +ignores the set-user-ID and set-group-ID bits on scripts. +.SH STANDARDS +POSIX.1-2008. +.SH HISTORY +POSIX.1-2001, SVr4, 4.3BSD. +.\" SVr4 documents additional error +.\" conditions EAGAIN, EINTR, ELIBACC, ENOLINK, EMULTIHOP; POSIX does not +.\" document ETXTBSY, EPERM, EFAULT, ELOOP, EIO, ENFILE, EMFILE, EINVAL, +.\" EISDIR or ELIBBAD error conditions. +.P +With UNIX\ V6, the argument list of an +.BR exec () +call was ended by 0, +while the argument list of +.I main +was ended by \-1. +Thus, this argument list was not directly usable in a further +.BR exec () +call. +Since UNIX\ V7, both are NULL. +.SH NOTES +One sometimes sees +.BR execve () +(and the related functions described in +.BR exec (3)) +described as "executing a +.I new +process" (or similar). +This is a highly misleading description: +there is no new process; +many attributes of the calling process remain unchanged +(in particular, its PID). +All that +.BR execve () +does is arrange for an existing process (the calling process) +to execute a new program. +.P +Set-user-ID and set-group-ID processes can not be +.BR ptrace (2)d. +.P +The result of mounting a filesystem +.I nosuid +varies across Linux kernel versions: +some will refuse execution of set-user-ID and set-group-ID +executables when this would +give the user powers they did not have already (and return +.BR EPERM ), +some will just ignore the set-user-ID and set-group-ID bits and +.BR exec () +successfully. +.P +In most cases where +.BR execve () +fails, control returns to the original executable image, +and the caller of +.BR execve () +can then handle the error. +However, in (rare) cases (typically caused by resource exhaustion), +failure may occur past the point of no return: +the original executable image has been torn down, +but the new image could not be completely built. +In such cases, the kernel kills the process with a +.\" commit 19d860a140beac48a1377f179e693abe86a9dac9 +.B SIGSEGV +.RB ( SIGKILL +until Linux 3.17) +signal. +.SS execve() and EAGAIN +A more detailed explanation of the +.B EAGAIN +error that can occur (since Linux 3.1) when calling +.BR execve () +is as follows. +.P +The +.B EAGAIN +error can occur when a +.I preceding +call to +.BR setuid (2), +.BR setreuid (2), +or +.BR setresuid (2) +caused the real user ID of the process to change, +and that change caused the process to exceed its +.B RLIMIT_NPROC +resource limit (i.e., the number of processes belonging +to the new real UID exceeds the resource limit). +From Linux 2.6.0 to Linux 3.0, this caused the +.BR set*uid () +call to fail. +(Before Linux 2.6, +.\" commit 909cc4ae86f3380152a18e2a3c44523893ee11c4 +the resource limit was not imposed on processes that +changed their user IDs.) +.P +Since Linux 3.1, the scenario just described no longer causes the +.BR set*uid () +call to fail, +because it too often led to security holes where buggy applications +didn't check the return status and assumed +that\[em]if the caller had root privileges\[em]the call would always succeed. +Instead, the +.BR set*uid () +calls now successfully change the real UID, +but the kernel sets an internal flag, named +.BR PF_NPROC_EXCEEDED , +to note that the +.B RLIMIT_NPROC +resource limit has been exceeded. +If the +.B PF_NPROC_EXCEEDED +flag is set and the resource limit is still +exceeded at the time of a subsequent +.BR execve () +call, that call fails with the error +.BR EAGAIN . +This kernel logic ensures that the +.B RLIMIT_NPROC +resource limit is still enforced for the +common privileged daemon workflow\[em]namely, +.BR fork (2) ++ +.BR set*uid () ++ +.BR execve (). +.P +If the resource limit was not still exceeded at the time of the +.BR execve () +call +(because other processes belonging to this real UID terminated between the +.BR set*uid () +call and the +.BR execve () +call), then the +.BR execve () +call succeeds and the kernel clears the +.B PF_NPROC_EXCEEDED +process flag. +The flag is also cleared if a subsequent call to +.BR fork (2) +by this process succeeds. +.\" +.\" .SH BUGS +.\" Some Linux versions have failed to check permissions on ELF +.\" interpreters. This is a security hole, because it allows users to +.\" open any file, such as a rewinding tape device, for reading. Some +.\" Linux versions have also had other security holes in +.\" .BR execve () +.\" that could be exploited for denial of service by a suitably crafted +.\" ELF binary. There are no known problems with Linux 2.0.34 or Linux 2.2.15. +.SH EXAMPLES +The following program is designed to be execed by the second program below. +It just echoes its command-line arguments, one per line. +.P +.in +4n +.\" SRC BEGIN (myecho.c) +.EX +/* myecho.c */ +\& +#include <stdio.h> +#include <stdlib.h> +\& +int +main(int argc, char *argv[]) +{ + for (size_t j = 0; j < argc; j++) + printf("argv[%zu]: %s\en", j, argv[j]); +\& + exit(EXIT_SUCCESS); +} +.EE +.\" SRC END +.in +.P +This program can be used to exec the program named in its command-line +argument: +.P +.in +4n +.\" SRC BEGIN (execve.c) +.EX +/* execve.c */ +\& +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +\& +int +main(int argc, char *argv[]) +{ + static char *newargv[] = { NULL, "hello", "world", NULL }; + static char *newenviron[] = { NULL }; +\& + if (argc != 2) { + fprintf(stderr, "Usage: %s <file\-to\-exec>\en", argv[0]); + exit(EXIT_FAILURE); + } +\& + newargv[0] = argv[1]; +\& + execve(argv[1], newargv, newenviron); + perror("execve"); /* execve() returns only on error */ + exit(EXIT_FAILURE); +} +.EE +.\" SRC END +.in +.P +We can use the second program to exec the first as follows: +.P +.in +4n +.EX +.RB "$" " cc myecho.c \-o myecho" +.RB "$" " cc execve.c \-o execve" +.RB "$" " ./execve ./myecho" +argv[0]: ./myecho +argv[1]: hello +argv[2]: world +.EE +.in +.P +We can also use these programs to demonstrate the use of a script +interpreter. +To do this we create a script whose "interpreter" is our +.I myecho +program: +.P +.in +4n +.EX +.RB "$" " cat > script" +.B #!./myecho script\-arg +.B \[ha]D +.RB "$" " chmod +x script" +.EE +.in +.P +We can then use our program to exec the script: +.P +.in +4n +.EX +.RB "$" " ./execve ./script" +argv[0]: ./myecho +argv[1]: script\-arg +argv[2]: ./script +argv[3]: hello +argv[4]: world +.EE +.in +.SH SEE ALSO +.BR chmod (2), +.BR execveat (2), +.BR fork (2), +.BR get_robust_list (2), +.BR ptrace (2), +.BR exec (3), +.BR fexecve (3), +.BR getauxval (3), +.BR getopt (3), +.BR system (3), +.BR capabilities (7), +.BR credentials (7), +.BR environ (7), +.BR path_resolution (7), +.BR ld.so (8) |