涉及到的相关函数
获取用户名 :
uid_t getuid(void);
struct passwd *getpwuid(uid_t uid);
//getpwuid 返回一个结构体指针,可以用来获取下列结构
struct passwd {
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
获取当前工作目录 :
char *getcwd(char *buf, size_t size);
getcwd可以将当前工作的绝对路径填充进buf指向的空间;
大小不超过size; 失败返回NULL指针, 并设置errno;
切换工作路径 :
int chdir(const char *path);
改变当前进程的工作路径,成功返回 0, 失败返回-1;
并设置errno;
The current working directory is the starting point for interpreting relative pathnames (those not starting with '/').
切换路径后修改命令行的提示
void swim_dir() {
if (chdir(vec[1]) < 0){
perror("chdir()");
return;
}
has_ch_dir = 1;
}
重定位功能相关函数
复制文件描述符
int dup(int oldfd); int dup2(int oldfd, int newfd); //dup用未使用的最小文件file descriptor 复制当前oldfd,并返回; //dup2将之前打开的newfd用来复制oldfd, 它会前关闭之前的newfd再 //指向oldfd,如果oldfd是无效的,那么它啥事也不做; 失败返回:-1,并设置errno;
啥是文件描述符 ?
文件描述符是数组下标, 数组里存放了打开文件结构体的指针, 指向的结构体里又有指向inode的指针; 该数组存在在每个进程空间里, 系统会默认打开默认stream: stdin/stdout/stderr;
fork() 复制产生子进程
fork可以产生一个新进程,通过duplicate 当前进程
fork后父子进程的区别:
- fork的返回值不一样, pid不一样, ppid不一样;
- 未决信号和文件锁不继承
- 资源利用量清零;
注意 : fork()进行写时复制(谁改变原内容, 谁复制)
pipe() 实现IPC机制
调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信, 有一个读端和写端, 通过 filedes参数传给用户程序的两个文件描述符, filedes[0]指向管道的读端, filedes[1]指向管道的写端;
/* On Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64; see NOTES */
struct fd_pair {
long fd[2];
};
struct fd_pair pipe();
/* On all other architectures */
int pipe(int pipefd[2]);
管道用法的栗子
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
pid_t pid;
int fd[2];
if (pipe(fd) < 0) {
perror("pipe()");
exit(1);
}
if ((pid = fork()) < 0){
perror("fork()");
exit(1);
}
int n;
char buf[20];
if (pid > 0) {
close(fd[0]);
write(fd[1], "hello pipe\n", 11);
wait(NULL);
}
else{
close(fd[1]);
sleep(1);
n = read(fd[0], buf, 20);
write(1, buf, n);
}
return 0;
}
命令的执行相关函数
当进程调用一种exec函数时, 改函数的用户空间代码和数据完全被新程序替代, 从新程序的启动例程开始执行
//exec函数族
int execl(const char *pathname, const char *arg, .../* (char *) NULL */);
int execlp(const char *file, const char *arg, ... /*