흔히 리눅스에서 프로그램은 쉘이라는 환경에서 작동함
- 프로세스
-프로그램
: 파일에 저장된 일련의 기계어 명령어
- 프로그램 실행이란
: 기계어 명령을 메모리에 로드한 후 프로세서(CPU)에서 명령어 하나씩 실행하는 프로그램
- 프로세스
: 실행중인 프로그램
프로세스는 메모리 페이지의 할당 목록을 유지하는 구조가 있음.
프로세스 생성은 디스크 파일 생성과 유사하다.
--> 커널은 프로그램의 기계어 코드와 데이터 바이트를 보관할 수 있는 메모리 페이지를 찾아야한다.
--> 커널은 메모리 할당 정보와 프로세스의 속성을 저장하기 위해 데이터 구조를 설정한다.
- 쉘(Shell)의 작동원리
A. 유저 타입의 a.out
B. 쉘은 프로그램을 실행하기 위한 새로운 프로세스를 생성한다.
C. 셀은 디스크에서 프로세스로 프로그램을 로드한다.
D. 프로그램은 작업이 완료될때까지 프로세스에서 실행한다.
- 어떻게 프로그램이 실행되는가? --> execvp
1. 프로그램은 execvp를 호출한다.
2. 커널은 디스크로 부터 프로세스로 프로그램을 로드한다.
3. 커널은 arglist를 프로세스로 복사한다.
4. 커널은 main(argc, argv)를 호출한다.
/*exec1.c - 프로그램을 실행하는 것이 얼마나 쉬운지를 보여줌
*/
#include <stdio.h>
#include <unistd.h>
int main()
{
char *arglist[3];
arglist[0] = "ls";
arglist[1] = "-l";
arglist[2]=0;
printf("***About to exec ls -l\n");
execvp("ls",arglist);
printf("***ls is done. bye\n");
}
execvp |
목적 PATH Searching 과 함께 파일 실행 |
헤더 #include <unistd.h> |
사용법 result = execvp(const char *file, const char *argv[]) |
인자 file 실행할 파일이름 |
리턴값 -1 실패 |
- execvp를 사용해 간단한 쉘을 만들어보자!
/* psh1.c - prompting shell versin 1
Prompts for the commandand its argments.
Builds the argument vector for the call to execvp.
Uses execvp(), and never returns.
*/
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAXARGS 20 /* cmdline args */
#define ARGLEN 100 /* token length */
char *makestring(char*);
int execute(char*[]);
int main(void)
{
char* arglist[MAXARGS + 1]; /* an array of ptrs */
int numargs = 0; /* index into array */
char argbuf[ARGLEN]; /* read stuff here */
while ( numargs < MAXARGS )
{
printf ("Arg[%d]? ", numargs);
if ( fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n' )
arglist[numargs++] = makestring(argbuf);
else // 입력 첫 문자가 '\n'일 때
{
if ( numargs > 0 ) /* any args? */
{
arglist[numargs] = NULL;/* close list */
execute( arglist ); /* do it */
numargs = 0; /* and reset */
}
}
}
return 0;
}
int execute(char* arglist[])
/*
* use execvp to do it
*/
{
execvp(arglist[0], arglist); /* do it */
perror("execvp failed");
exit(1);
}
char* makestring( char* buf )
/*
* trimoff newline and create storage for thestring
*/
{
char *cp;
buf[strlen(buf) - 1] = '\0'; /*trim newline */
cp = malloc( strlen(buf) + 1 );
if (cp == NULL)
{
fprintf(stderr, "no memory\n");
exit(1);
}
strcpy(cp, buf);
return cp;
}
※ execvp는 실행되면 완전히 새로운 프로세스가 되어 기존 코드는 실행되지않는다는 단점이 있다.
--> 이를 위해 fork 사용
[프로그래밍/시스템 프로그래밍] - [리눅스 시스템 프로그래밍] fork()