popen函数和access函数的用法

  • popen函数从代码中去获取终端执行命令后显示的信息
  • access (判断是否具有存取文件的权限)

popen函数从代码中去获取终端执行命令后显示的信息

popen (建立管道 I/O)
相关函数 pipe, mkfifo, pclose, fork, system, fopen
头文件 #include <stdio.h>
定义函数 FILE * popen(const char * command, const char * type);
函数说明 popen()会调用 fork()产生子进程, 然后从子进程中调用/bin/sh -c 来执行参数 command 的指令.
参数 type 可使用 "r"代表读取, "w"代表写入. 依照此 type 值, popen()会建立管道连到子进程的标准输出设
备或标准输入设备, 然后返回一个文件指针. 随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子
进程的标准输入设备中. 此外, 所有使用文件指针(FILE*)操作的函数也都可以使用, 除了 fclose()以外.
返回值 若成功则返回文件指针, 否则返回 NULL, 错误原因存于 errno 中.
错误代码 EINVAL 参数 type 不合法. 注意事项 在编写具 SUID/SGID 权限的程序时请尽量避免使用 popen()
Linux 常用 C 函数
popen()会继承环境变量, 通过环境变量可能会造成系统安全的问题.
范例

#include <stdio.h>
main()
{
FILE * fp;
char buffer[80];
fp = popen("cat /etc/passwd", "r");//把command命令反馈的信息填入到buffer里
fgets(buffer, sizeof(buffer), fp);
printf("%s", buffer);
pclose(fp);
}
执行 root :x:0 0: root: /root: /bin/bash

access (判断是否具有存取文件的权限)

相关函数 stat, open, chmod, chown, setuid, setgid
头文件 #include <unistd.h>
定义函数 int access(const char * pathname, int mode);
函数说明 access()会检查是否可以读/写某一已存在的文件. 参数 mode 有几种情况组合, R_OK, W_OK, X_OK
和 F_OK. R_OK, W_OK 与 X_OK 用来检查文件是否具有读娶写入和执行的权限. F_OK 则是用来判断该文件是否
存在. 由于 access()只作权限的核查, 并不理会文件形态或文件内容, 因此, 如果一目录表示为"可写入", 表
示可以在该目录中建立新文件等操作, 而非意味此目录可以被当做文件处理. 例如, 你会发现 DOS 的文件都具有"
可执行"权限, 但用 execve()执行时则会失败.
返回值 若所有欲查核的权限都通过了检查则返回 0 值, 表示成功, 只要有一权限被禁止则返回-1.
错误代码 EACCESS 参数 pathname 所指定的文件不符合所要求测试的权限.

EROFS 欲测试写入权限的文件存在于只读文件系统内.
 EFAULT 参数 pathname 指针超出可存取内存空间.
 EINVAL 参数 mode 不正确.
 ENAMETOOLONG 参数 pathname 太长.
 ENOTDIR 参数 pathname 为一目录.
 ENOMEM 核心内存不足
 ELOOP 参数 pathname 有过多符号连接问题.
 EIO I/O 存取错误.

附加说明 使用 access()作用户认证方面的判断要特别小心,例如在 access()后再做 open()的空文件可能会造
成系统安全上的问题.
范例 /* 判断是否允许读取/etc/passwd */

#include <unistd.h>
int main()
{
if(access("/etc/passwd/config", F_OK) == 0)
printf("/etc/passwd/config exists\n");
}
执行 /etc/passwd/config exists