inux 下system函数原型:http://blog.chinaunix.net/uid-29191363-id-4020441.html
来源:互联网 发布:淘宝付款自动关闭订单 编辑:程序博客网 时间:2024/05/19 18:38
inux 下system函数原型:
#include
int system(const char *command);
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.
system函数的返回值比较多,且存在相同的值却代表着不同的意思,针对以上问题对源码进行分析。
Libc-2.9 下sysdeps\posi\system.c源码:
#include
int system(const char *command);
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.
system函数的返回值比较多,且存在相同的值却代表着不同的意思,针对以上问题对源码进行分析。
Libc-2.9 下sysdeps\posi\system.c源码:
点击(此处)折叠或打开
- int system (const char *line)
- {
- return __libc_system (line);
- }
- int __libc_system (const char *line) /*system函数实际上调用的是do_system函数*/
- {
- if (line == NULL)
- /* Check that we have a command processor available. It might
- ?not be available after a chroot(), for example. */
- return do_system ("exit 0") == 0; /* 当line为NULL时,返回值为0,及执行bash –c exit 0*/
- if (SINGLE_THREAD_P)
- return do_system (line);
- /*GCC cleanup exception range can cover the
- LIBC_CANCEL_ASYNC() and LIBC_CANCEL_RESET():http://sourceware.org/ml/libc-alpha/2011-08/msg00063.html */
- int oldtype = LIBC_CANCEL_ASYNC ();
- int result = do_system (line);
- LIBC_CANCEL_RESET (oldtype);
- return result;
- }
- weak_alias (__libc_system, system) /* weak_alias 别名 */
- /*通过以上分析system函数实际上调用的是do_system函数, 以下对do_system函数进行分析,以下列出主要函数:*/
- /* Execute LINE as a shell command, returning its status. */
- do_system (const char *line)
- {
- int status, save;
- pid_t pid;
- struct sigaction sa;
- #ifndef _LIBC_REENTRANT
- struct sigaction intr, quit;
- #endif
- sigset_t omask;
- sa.sa_handler = SIG_IGN;
- sa.sa_flags = 0;
- __sigemptyset (&sa.sa_mask);
- DO_LOCK (); /* mutex lock*/
- if (ADD_REF () == 0)
- {
- if (__sigaction (SIGINT, &sa, &intr) < 0) /*执行时 SIGINT被忽略*/
- {
- SUB_REF ();
- goto out;
- }
- if (__sigaction (SIGQUIT, &sa, &quit) < 0) /*执行时 SIGQUIT被忽略*/
- {
- save = errno;
- SUB_REF ();
- goto out_restore_sigint;
- }
- }
- DO_UNLOCK ();
- /* We reuse the bitmap in the 'sa' structure. */
- __sigaddset (&sa.sa_mask, SIGCHLD);
- save = errno;
- if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0) /*执行时设置SIG_BLOCK标志位,SIGCHLD被阻塞,执行失败,则恢复之前的信号的bitmap*/
- {
- #ifndef _LIBC
- if (errno == ENOSYS)
- __set_errno (save);
- else
- #endif
- {
- DO_LOCK ();
- if (SUB_REF () == 0)
- {
- save = errno;
- (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
- out_restore_sigint:
- (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
- __set_errno (save);
- }
- out:
- DO_UNLOCK ();
- return -1;
- }
- }
- #ifdef CLEANUP_HANDLER
- CLEANUP_HANDLER;
- #endif
- /*执行成功,调用fork,生成子进程执行command命令*/
- #ifdef FORK
- pid = FORK (); /*调用SYS_CALL生成子进程*/
- #else
- pid = __fork ();
- #endif
- if (pid == (pid_t) 0) //
- {
- /* Child side. */
- const char *new_argv[4];
- new_argv[0] = SHELL_NAME;
- new_argv[1] = "-c";
- new_argv[2] = line;
- new_argv[3] = NULL;
- /* Restore the signals. */
- (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
- (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
- (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
- INIT_LOCK ();
- /* Exec the shell. */
- (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
- _exit (127); /*exec执行失败则返回127*/
- }
- else if (pid < (pid_t) 0)
- /* The fork failed. */
- status = -1;
- else /*父进程,waitpid*/
- /* Parent side. */
- {
- /* Note the system() is a cancellation point. But since we call
- waitpid() which itself is a cancellation point we do not
- have to do anything here. */
- if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid)
- status = -1; /*waitpid 失败返回1*/
- }
- #ifdef CLEANUP_HANDLER
- CLEANUP_RESET;
- #endif
- save = errno;
- DO_LOCK ();
- if ((SUB_REF () == 0
- && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
- | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
- || __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0)
- {
- #ifndef _LIBC
- /* glibc cannot be used on systems without waitpid. */
- if (errno == ENOSYS)
- __set_errno (save);
- else
- #endif
- status = -1;
- }
- DO_UNLOCK ();
- return status;
- }
- 总结:system函数的返回值:分2大类:
- (1) 当参数为空时,调用do_system ("exit 0"),返回值为NULL /*网上都说是返回非0值,但我测的是NULL !!!!*/
- (2) 调用result = do_system (line);
- 当执行忽略SIGINT和SIGQUIT信号时,错误返回-1
- fork子进程时出现错误 返回值为-1
- 当exec执行错误或命令无效时返回值为127
- 当waitpid错误时 返回值为-1
- if(NULL == cmdstring) //如果cmdstring为空趁早闪退吧,尽管system()函数也能处理空指针
- 以下可以得到返回值错在什么位置,相关知识详见APUE(摘录的具体位置忘了,作者看到后请留言)
- if(NULL == cmdstring) //如果cmdstring为空趁早闪退吧,尽管system()函数也能处理空指针
- {
- return XXX;
- }
- status = system(cmdstring);
- if(status < 0)
- {
- printf("cmd: %s\t error: %s", cmdstring, strerror(errno)); // 这里务必要把errno信息输出或记入Log
- return XXX;
- }
- if(WIFEXITED(status))
- {
- printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); //取得cmdstring执行结果
- }
- else if(WIFSIGNALED(status))
- {
- printf("abnormal termination,signal number =%d\n", WTERMSIG(status)); //如果cmdstring被信号中断,取得信号值
- }
- else if(WIFSTOPPED(status))
- {
- printf("process stopped, signal number =%d\n", WSTOPSIG(status)); //如果cmdstring被信号暂停执行,取得信号值
- }
0 0
- inux 下system函数原型:http://blog.chinaunix.net/uid-29191363-id-4020441.html
- Linux下关于system调用 http://blog.chinaunix.net/uid-21768364-id-3995764.html
- http://blog.chinaunix.net/uid-22666718-id-1771703.html
- http://blog.chinaunix.net/uid-20322254-id-145835.html
- http://blog.chinaunix.net/uid-25547034-id-3155778.html
- http://blog.chinaunix.net/uid-25750954-id-2956084.html
- http://blog.chinaunix.net/uid-22342564-id-3053393.html
- http://blog.chinaunix.net/uid-25082381-id-3242162.html
- http://blog.chinaunix.net/uid-25737580-id-3182286.html
- http://blog.chinaunix.net/uid-25835268-id-3055356.html--makefile
- http://blog.chinaunix.net/uid-8874157-id-2012678.html
- http://blog.chinaunix.net/uid-21289517-id-3081793.html
- http://blog.chinaunix.net/uid-20543672-id-3244832.html
- http://blog.chinaunix.net/uid-21222282-id-3244532.html
- http://blog.chinaunix.net/uid-21501855-id-4490453.html
- http://blog.chinaunix.net/uid-20484604-id-1941290.html
- http://blog.chinaunix.net/uid-20569459-id-335214.html
- http://blog.chinaunix.net/uid-21411227-id-1826986.html
- 数据缺失值的4种处理方法
- 如何编写一个分布式数据库
- jquery常用选择器(下)
- android.content.ActivityNotFoundException: Unable to find explicit activity class
- iOS编程规范
- inux 下system函数原型:http://blog.chinaunix.net/uid-29191363-id-4020441.html
- Navicat Premium for mac 11.0 中文破解版安装
- OC学习笔记-Foundation框架(二)
- 水文--151002
- 嵌入式开发(一)虚拟机上的ubuntu系统上搭建nfs过程及遇到问题
- poj 1700 Crossing River 贪心
- noip2012 质因数分解 (枚举)
- system()函数 http://blog.csdn.net/ghevinn/article/details/7916126
- HDU 3823 Prime Friend