system() 函数本身和系统调用没有直接关系

Posted Li-Yongjun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了system() 函数本身和系统调用没有直接关系相关的知识,希望对你有一定的参考价值。

前言

在网上经常看到 “system系统调用” 的说法,其实 system 函数本身和系统调用并没有直接关系。

是库函数


system 出现在 man 手册第 3 页,说明其是一个库函数。

源码

下面是 system 的源码实现,摘自 uClibc-0.9.33.2

int __libc_system(const char *command)

	int wait_val, pid;
	struct sigaction sa, save_quit, save_int;
	sigset_t save_mask;

	if (command == 0)
		return 1;

	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = SIG_IGN;
	/* __sigemptyset(&sa.sa_mask); - done by memset() */
	/* sa.sa_flags = 0; - done by memset() */

	sigaction(SIGQUIT, &sa, &save_quit);
	sigaction(SIGINT, &sa, &save_int);
	__sigaddset(&sa.sa_mask, SIGCHLD);
	sigprocmask(SIG_BLOCK, &sa.sa_mask, &save_mask);

	if ((pid = vfork()) < 0) 
		wait_val = -1;
		goto out;
	
	if (pid == 0) 
		sigaction(SIGQUIT, &save_quit, NULL);
		sigaction(SIGINT, &save_int, NULL);
		sigprocmask(SIG_SETMASK, &save_mask, NULL);

		execl("/bin/sh", "sh", "-c", command, (char *) 0);
		_exit(127);
	

#if 0
	__printf("Waiting for child %d\\n", pid);
#endif

	if (wait4(pid, &wait_val, 0, 0) == -1)
		wait_val = -1;

out:
	sigaction(SIGQUIT, &save_quit, NULL);
	sigaction(SIGINT, &save_int, NULL);
	sigprocmask(SIG_SETMASK, &save_mask, NULL);
	return wait_val;

可以看到,system() 函数实现的流程是,调用 fork 系统调用,fork 出一个子进程,在子进程中调用 exec 系统调用,执行传入的命令,父进程则等待子进程退出。
可以看到,system() 函数调用了 fork、exec、wait 系统调用,但在内核中,没有与 system 相对应的系统调用
arch/arm/tools/syscall.tbl

#
# Linux system call numbers and entry vectors
#
# The format is:
# <num>	<abi>	<name>			[<entry point>			[<oabi compat entry point>]]
#
# Where abi is:
#  common - for system calls shared between oabi and eabi (may have compat)
#  oabi   - for oabi-only system calls (may have compat)
#  eabi   - for eabi-only system calls
#
# For each syscall number, "common" is mutually exclusive with oabi and eabi
#
0	common	restart_syscall		sys_restart_syscall
1	common	exit			sys_exit
2	common	fork			sys_fork
3	common	read			sys_read
4	common	write			sys_write
5	common	open			sys_open
6	common	close			sys_close
# 7 was sys_waitpid
8	common	creat			sys_creat
9	common	link			sys_link
10	common	unlink			sys_unlink
11	common	execve			sys_execve
12	common	chdir			sys_chdir
13	oabi	time			sys_time32
14	common	mknod			sys_mknod
15	common	chmod			sys_chmod
16	common	lchown			sys_lchown16
# 17 was sys_break
# 18 was sys_stat
19	common	lseek			sys_lseek
20	common	getpid			sys_getpid
21	common	mount			sys_mount
22	oabi	umount			sys_oldumount
23	common	setuid			sys_setuid16
24	common	getuid			sys_getuid16
25	oabi	stime			sys_stime32
26	common	ptrace			sys_ptrace
27	oabi	alarm			sys_alarm
# 28 was sys_fstat
29	common	pause			sys_pause
30	oabi	utime			sys_utime32
# 31 was sys_stty
# 32 was sys_gtty
33	common	access			sys_access
34	common	nice			sys_nice
# 35 was sys_ftime
36	common	sync			sys_sync
37	common	kill			sys_kill
38	common	rename			sys_rename
39	common	mkdir			sys_mkdir
40	common	rmdir			sys_rmdir
41	common	dup			sys_dup
42	common	pipe			sys_pipe
43	common	times			sys_times
# 44 was sys_prof
45	common	brk			sys_brk
46	common	setgid			sys_setgid16
47	common	getgid			sys_getgid16
# 48 was sys_signal
49	common	geteuid			sys_geteuid16
50	common	getegid			sys_getegid16
51	common	acct			sys_acct
52	common	umount2			sys_umount
# 53 was sys_lock
54	common	ioctl			sys_ioctl
55	common	fcntl			sys_fcntl
...

以上是关于system() 函数本身和系统调用没有直接关系的主要内容,如果未能解决你的问题,请参考以下文章

C库函数和系统调用的区别

递归函数

标准C库函数和系统调用的关系

linux内核系统调用和标准C库函数的关系分析

Python调用外部程序——os.system()和subprocess.call()

系统调用和标准库函数的关联