exec.c File Reference

#include "pm.h"
#include <sys/stat.h>
#include <minix/callnr.h>
#include <minix/endpoint.h>
#include <minix/com.h>
#include <a.out.h>
#include <signal.h>
#include <string.h>
#include "mproc.h"
#include "param.h"

Include dependency graph for exec.c:

Go to the source code of this file.

Defines

#define ESCRIPT   (-2000)
#define PTRSIZE   sizeof(char *)
#define PM_CHUNK_SIZE   8192

Functions

int new_mem (struct mproc *sh_mp, vir_bytes text_bytes, vir_bytes data_bytes, vir_bytes bss_bytes, vir_bytes stk_bytes, phys_bytes tot_bytes)
void patch_ptr (char stack[ARG_MAX], vir_bytes base)
int insert_arg (char stack[ARG_MAX], vir_bytes *stk_bytes, char *arg, int replace)
char * patch_stack (int fd, char stack[ARG_MAX], vir_bytes *stk_bytes, char *script)
int read_header (int fd, int *ft, vir_bytes *text_bytes, vir_bytes *data_bytes, vir_bytes *bss_bytes, phys_bytes *tot_bytes, long *sym_bytes, vir_clicks sc, vir_bytes *pc)
int do_exec ()
void rw_seg (int rw, int fd, int proc_e, int seg, phys_bytes seg_bytes0)
mprocfind_share (struct mproc *mp_ign, ino_t ino, dev_t dev, time_t ctime)


Detailed Description

This file handles the EXEC system call. It performs the work as follows:

The entry points into this file are: do_exec: perform the EXEC system call rw_seg: read or write a segment from or to a file find_share: find a process whose text segment can be shared

Definition in file exec.c.


Define Documentation

#define ESCRIPT   (-2000)
 

Returned by read_header for a #! script.

Definition at line 48 of file exec.c.

Referenced by do_exec(), and read_header().

#define PM_CHUNK_SIZE   8192
 

Referenced by rw_seg().

#define PTRSIZE   sizeof(char *)
 

Size of pointers in argv[] and envp[].

Definition at line 49 of file exec.c.


Function Documentation

int do_exec  ) 
 

Perform the execve(name, argv, envp) call. The user library builds a complete stack image, including pointers, args, environ, etc. The stack is copied to a buffer inside PM, and then to the new core image.

Definition at line 56 of file exec.c.

References _NSIG, allowed, ARG_MAX, basename, CHDIR, CLICK_SHIFT, CLICK_SIZE, close, D, EACCES, EINVAL, ENOEXEC, ENOMEM, ESCRIPT, FALSE, find_share(), I_SET_GID_BIT, I_SET_UID_BIT, if(), lseek, m, m_in, mem_map::mem_len, mp, mproc::mp_catch, mproc::mp_ctime, mproc::mp_dev, mproc::mp_effgid, mproc::mp_effuid, mproc::mp_flags, mproc::mp_ino, mproc::mp_procargs, mproc::mp_realgid, mproc::mp_realuid, mproc::mp_seg, mproc::mp_sigact, new_mem(), NULL, OK, panic, patch_ptr(), patch_stack(), PATH_MAX, pc, PM_PROC_NR, r, read_header(), rw_seg(), S, SEEK_CUR, SETGID, SETUID, SIG_DFL, sigdelset, sigemptyset, sigismember, stat::st_ctime, stat::st_dev, stat::st_gid, stat::st_ino, stat::st_mode, stat::st_uid, sys_datacopy, T, tell_fs(), TRACED, who_e, and X_BIT.

struct mproc* find_share struct mproc mp_ign,
ino_t  ino,
dev_t  dev,
time_t  ctime
 

Look for a process that is the file <ino, dev, ctime> in execution. Don't accidentally "find" mp_ign, because it is the process on whose behalf this call is made.

Parameters:
mp_ign process that should not be looked at
ino parameters that uniquely identify a file
dev 
ctime 

Definition at line 586 of file exec.c.

References if(), mproc::mp_ctime, mproc::mp_dev, mproc::mp_flags, mproc::mp_ino, NR_PROCS, and SEPARATE.

Referenced by do_exec(), new_mem(), and pm_exit().

static int insert_arg char  stack[ARG_MAX],
vir_bytes stk_bytes,
char *  arg,
int  replace
 

Patch the stack so that arg will become argv[0]. Be careful, the stack may be filled with garbage, although it normally looks like this: nargs argv[0] ... argv[nargs-1] NULL envp[0] ... NULL followed by the strings "pointed" to by the argv[i] and the envp[i]. The pointers are really offsets from the start of stack. Return true iff the operation succeeded.

Parameters:
stack pointer to stack image within PM
stk_bytes size of initial stack
arg argument to prepend/replace as new argv[0]
replace 

Definition at line 440 of file exec.c.

References FALSE, int(), memmove(), offset, patch_ptr(), PTRSIZE, strcpy(), strlen(), and TRUE.

Referenced by patch_stack().

static int new_mem struct mproc sh_mp,
vir_bytes  text_bytes,
vir_bytes  data_bytes,
vir_bytes  bss_bytes,
vir_bytes  stk_bytes,
phys_bytes  tot_bytes
 

Allocate new memory and release the old memory. Change the map and report the new map to the kernel. Zero the new core image's bss, gap and stack.

Parameters:
sh_mp text can be shared with this process
text_bytes text segment size in bytes
data_bytes size of initialized data in bytes
bss_bytes size of bss in bytes
stk_bytes size of initial stack segment in bytes
tot_bytes total memory to allocate, including gap

Definition at line 305 of file exec.c.

References alloc_mem(), base, bytes, CLICK_SHIFT, CLICK_SIZE, D, ENOMEM, find_share(), free_mem(), long(), mem_map::mem_len, mem_map::mem_phys, mem_map::mem_vir, mp, mproc::mp_ctime, mproc::mp_dev, mproc::mp_flags, mproc::mp_ino, mproc::mp_seg, NO_MEM, NULL, OK, ONSWAP, panic, S, s, SWAPIN, sys_memset(), sys_newmap(), T, WAITING, and who_e.

Referenced by do_exec().

static void patch_ptr char  stack[ARG_MAX],
vir_bytes  base
 

When doing an exec(name, argv, envp) call, the user builds up a stack image with arg and env pointers relative to the start of the stack. Now these pointers must be relocated, since the stack is not positioned at address 0 in the user's address space.

Parameters:
stack pointer to stack image within PM
base virtual address of stack base inside user

Definition at line 406 of file exec.c.

References flag, and NULL.

Referenced by do_exec(), and insert_arg().

static char * patch_stack int  fd,
char  stack[ARG_MAX],
vir_bytes stk_bytes,
char *  script
 

Patch the argument vector to include the path name of the script to be interpreted, and all strings on the #! line. Returns the path name of the interpreter.

Parameters:
fd file descriptor to open script file
stack pointer to stack image within PM
stk_bytes size of initial stack
script name of script to interpret

Definition at line 492 of file exec.c.

References FALSE, INSERT, insert_arg(), L, lseek, memchr(), n, NULL, PATH_MAX, read, sp, and TRUE.

Referenced by do_exec().

static int read_header int  fd,
int *  ft,
vir_bytes text_bytes,
vir_bytes data_bytes,
vir_bytes bss_bytes,
phys_bytes tot_bytes,
long *  sym_bytes,
vir_clicks  sc,
vir_bytes pc
 

Read the header and extract the text, data, bss and total sizes from it.

Parameters:
fd file descriptor for reading exec file
ft place to return ft number
text_bytes place to return text size
data_bytes place to return initialized data size
bss_bytes place to return bss size
tot_bytes place to return total size
sym_bytes place to return symbol table size
sc stack size in clicks
pc program entry point (initial PC)
Read the header and check the magic number. The standard MINIX header is defined in <a.out.h>. It consists of 8 chars followed by 6 longs. Then come 4 more longs that are not used here. Byte 0: magic number 0x01 Byte 1: magic number 0x03 Byte 2: normal = 0x10 (not checked, 0 is OK), separate I/D = 0x20 Byte 3: CPU type, Intel 16 bit = 0x04, Intel 32 bit = 0x10, Motorola = 0x0B, Sun SPARC = 0x17 Byte 4: Header length = 0x20 Bytes 5-7 are not used.

Now come the 6 longs Bytes 8-11: size of text segments in bytes Bytes 12-15: size of initialized data segment in bytes Bytes 16-19: size of bss in bytes Bytes 20-23: program entry point Bytes 24-27: total memory allocated to program (text, data + stack) Bytes 28-31: size of symbol table in bytes The longs are represented in a machine dependent order, little-endian on the 8088, big-endian on the 68000. The header is followed directly by the text and data segments, and the symbol table (if any). The sizes are given in the header. Only the text and data segments are copied into memory by exec. The header is used here only. The symbol table is for the benefit of a debugger and is ignored here.

Definition at line 205 of file exec.c.

References A_EXEC, A_I80386, A_I8086, A_MINHDR, A_NSYM, A_SEP, exec::a_text, BADMAG, BYTE, CLICK_SHIFT, CLICK_SIZE, ENOEXEC, ENOMEM, ESCRIPT, if(), long(), lseek, m, OK, read, SEEK_SET, SEPARATE, and tc.

void rw_seg int  rw,
int  fd,
int  proc_e,
int  seg,
phys_bytes  seg_bytes0
 

Transfer text or data from/to a file and copy to/from a process segment. This procedure is a little bit tricky. The logical way to transfer a segment would be block by block and copying each block to/from the user space one at a time. This is too slow, so we do something dirty here, namely send the user space and virtual address to the file system in the upper 10 bits of the file descriptor, and pass it the user virtual address instead of a PM address. The file system extracts these parameters when gets a read or write call from the process manager, which is the only process that is permitted to use this trick. The file system then copies the whole segment directly to/from user space, bypassing PM completely.

The byte count on read is usually smaller than the segment count, because a segment is padded out to a click multiple, and the data segment is only partially initialized.

Parameters:
rw 0 = read, 1 = write
fd file descriptor to read from / write to
proc_e process number (endpoint)
seg T, D, or S
seg_bytes0 how much is to be transferred?

Definition at line 549 of file exec.c.

References _read_pm(), _write_pm(), bytes, CLICK_SHIFT, MIN, OK, PM_CHUNK_SIZE, pm_isokendpt(), r, and sp.

Referenced by do_exec(), and dump_core().


Generated on Fri Apr 14 22:58:34 2006 for minix by  doxygen 1.4.6