系统编程(1)
2017-01-03 本文已影响22人
酸菜牛肉
cpu:PC AR
open()
create()
O_RDONLY:只读方式打开文件
O_WRONLY:只写方式打开文件
O_RDWR:读写方式打开文件
O_APPEND
O_CREAT
O_DIRECTORY
O_EXCL
- 一个简单的文件copy的程序:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#define BUFFER_SIZE 100
int main(int argc,char *argv[])
{
if(argc != 3)
{
printf("usage:%s<src_file> <dst_file>\n",argv[0]);
return 1;
}
int src_fd = 0;
int dst_fd = 0;
int n = 0;
char buf[BUFFER_SIZE] = {"\0"};
char *src_file = argv[1];
char *dst_file = argv[2];
char cover_dir = '\0';
char cover_filename[BUFFER_SIZE] = {'\0'};
if(access(dst_file,F_OK) == 0)
{
printf("directorie is exist!!,,Do you want to cover, y or n:");
scanf("%c",&cover_dir);
switch(cover_dir)
{
case 'y':
case 'Y':
{
//dst_fd = open(dst_file,O_WRONLY | O_TRUNC,S_IRUSR | S_IWUSR);
if((dst_fd = open(dst_file,O_WRONLY | O_TRUNC)) == -1)
{
perror("open dst error");
return -1;
}
}
break;
case 'n':
case 'N':
{
printf("Please resume load of filename:");
getchar();
scanf("%s",cover_filename);
if((dst_fd = open(cover_filename,O_WRONLY | O_TRUNC | O_CREAT,S_IRUSR | S_IWUSR)) == -1)
{
perror("open dst error\n");
return -1;
}
break;
}
break;
default:
printf("Please input again!!!\n");
return -1;
}
}
else{
if((dst_fd = open(dst_file,O_WRONLY | O_TRUNC | O_CREAT,S_IRUSR | S_IWUSR)) == -1)
{
perror("open dst error");
return -1;
}
}
if((src_fd = open(src_file,O_RDONLY)) == -1)
{
perror("open src error");
return -1;
}
while((n = read(src_fd,buf,BUFFER_SIZE)) > 0)
{
write(dst_fd,buf,n);
}
close(src_fd);
close(dst_fd);
//1.open
//2.1 read data form src_file
//2.2 write data to dst_file
//3.close
return 0;
}
简单模仿一个shell的ls命令
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <pwd.h>
#include <time.h>
#include <grp.h>
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("usage : %s <filename>\n", argv[0]);
return 1;
}
struct stat file_stat;
struct passwd *pw = NULL;
struct group *grp = NULL;
memset(&file_stat, 0, sizeof(file_stat));
if(stat(argv[1], &file_stat) == -1)
{
perror("stat error");
return 1;
}
// 打印文件类型和权限信息
// 思路:通过预定义的宏函数分析st_mode的值
if(S_ISREG(file_stat.st_mode))
printf("-");
if(S_ISDIR(file_stat.st_mode))
printf("d");
if(S_ISCHR(file_stat.st_mode))
printf("c");
// ...
if(file_stat.st_mode & S_IRUSR)
printf("r");
else
printf("-");
if(file_stat.st_mode & S_IWUSR)
printf("w");
else
printf("-");
if(file_stat.st_mode & S_IXUSR)
printf("x");
else
printf("-");
// 打印硬链接数目
printf("%d\t", file_stat.st_nlink);
// 通过文件所有者ID获取文件所有者名称
pw = getpwuid(file_stat.st_uid);
printf("%s\t", pw->pw_name);
// 通过文件所属组ID获取文件所属组名称
grp = getgrgid(file_stat.st_gid);
printf("%s\t", grp->gr_name);
// 打印文件大小
printf("%d\t", file_stat.st_size);
// 打印文件的最后修改时间
printf("%s\t", ctime(&(file_stat.st_mtime)));
printf("\n");
return 0;
}
fork通过copy的方式创建一个进程,父进程和子进程同事存在,子进程会执行父进程中的内容,执行时不分先后顺序。需要判读其返回值来判断来区分函数的字符进程。。exec系列函数创建进程的时候具有替代进程的属性,参数有path路径和 envo路径寻找的方式
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<pwd.h>
#include <grp.h>
#define DEBUG_MODE 1
#define COM_MAX_LEN 128
int main(int argc,char *argv[])
{
pid_t pid = 0;
char command[COM_MAX_LEN] = {'\0'};
int status = 0;
char *delim = " ";
char *str_command[2];
struct passwd *pw = NULL;
struct stat file_stat;
memset(&file_stat, 0, sizeof(file_stat));
while(1)
{
// 通过文件所有者ID获取文件所有者名称
pw = getpwuid(file_stat.st_uid);
printf("%s>", pw->pw_name);
//printf(">>>>>>>>>");
//uid_t st_uid; /* user ID of owner */
fgets(command,COM_MAX_LEN,stdin);
command[strlen(command)-1] = '\0';
if(strcmp(command,".exit") == 0)
return 0;
str_command[0] = strtok(command,delim);
str_command[1] = strtok(NULL,delim);
//strcpy(str_command[],p);
if((pid = fork()) == 0)
{
printf("in child peocess :%d\n",getpid());
//利用exec函数将该子进程的执行指令替换
execlp(str_command[0],str_command[0],str_command[1],NULL);
//在path路劲中收索执行ls命令
//2.在path路劲中搜索执行ls -l /命令
//execlp("ls","ls","-l",NULL);
return 0;
}
//防止僵尸进程的产生
pid = wait(&status);
#if DEBUG_MODE
printf("in parent process child %d process exit code: \n",pid);
#endif
}
return 0;
}
//练习:
//参考上述代码,完成自己的shell命令解释器
//基本功能1:能够输入并执行普通的不带选项和参数的shell命令
//基本功能2:shell命令解释器具备不同的
- 模仿shell的命令解释器:
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<pwd.h>
#include <grp.h>
#define DEBUG_MODE 1
#define COM_MAX_LEN 128
int main(int argc,char *argv[])
{
pid_t pid = 0;
char command[COM_MAX_LEN] = {'\0'};
int status = 0;
char *delim = " ";
char *str_command[2];
struct passwd *pw = NULL;
struct stat file_stat;
memset(&file_stat, 0, sizeof(file_stat));
while(1)
{
// 通过文件所有者ID获取文件所有者名称
pw = getpwuid(file_stat.st_uid);
printf("%s>", pw->pw_name);
//printf(">>>>>>>>>");
//uid_t st_uid; /* user ID of owner */
fgets(command,COM_MAX_LEN,stdin);
command[strlen(command)-1] = '\0';
if(strcmp(command,".exit") == 0)
return 0;
str_command[0] = strtok(command,delim);
str_command[1] = strtok(NULL,delim);
//strcpy(str_command[],p);
if((pid = fork()) == 0)
{
printf("in child peocess :%d\n",getpid());
//利用exec函数将该子进程的执行指令替换
execlp(str_command[0],str_command[0],str_command[1],NULL);
//在path路劲中收索执行ls命令
//2.在path路劲中搜索执行ls -l /命令
//execlp("ls","ls","-l",NULL);
return 0;
}
//防止僵尸进程的产生
pid = wait(&status);
#if DEBUG_MODE
printf("in parent process child %d process exit code: \n",pid);
#endif
}
return 0;
}
进程的5种状态,创建、等待、run、关闭、阻塞。。
信号在只能在进程的间传递信号,起到激发的作用,不能传递信息。