UNIX环境编程基础

mycopy实例重写:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
	int fsrc;
	int fdst;
	char buffer[1024]={0};

	if(argc!=3)
	{
		printf("command is not found\n");
		return 0;
	}

	fsrc = open(argv[1],O_RDWR);
	lseek(fsrc,0,SEEK_SET);
	
	read(fsrc,buffer,1024);
	
	fdst = open(argv[2],O_RDWR|O_CREAT,0600);
	write(fdst,buffer,sizeof(buffer));

	close(fsrc);
	close(fdst);

	return 0;
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc mycopy.c -o mycopy
lwb@ubuntu:~/fileoperate$ ./mycopy hello.c hellotest.c (同一目录下拷贝文件成功)

lseek函数实例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>

int main()
{
	char *buf="abcdefg";
	char *buf1=NULL;
	int i=0;
	int fd=creat("./lseektest.txt",0700);   
	if(fd<0)
	{
		printf("file create is faild;");
	}
	open("./lseektest.txt",O_RDWR);
	write(fd,buf,8);
	close(fd);

	int fd1=open("./lseektest.txt",O_RDWR);
	lseek(fd1,3,SEEK_SET);
	lseek(fd1,-2,SEEK_CUR);
	buf1=(char *)malloc(8);
	memset(buf1,0,8);
	read(fd1,buf1,3);
	printf("testfile current char is: ");
	
	while(buf1[i]!='\0')
	{
	putchar(buf1[i]);
	i++;
	}
	putchar('\n');
	free(buf1);
	close(fd1);	
	return 0;
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc lseek.c -o lseek
lwb@ubuntu:~/fileoperate$ ./lseek
testfile current char is: bcd

列出一个目录中的所有文件:

#include <sys/types.h>
#include <stdio.h>
#include <dirent.h>
#include <ourhdr.h>
#include <string.h>

int main(int argc, char *argv[])
{
	DIR *dp;
	struct dirent *dirp;

	if(argc!=2)
	err_quit("argument count is faild");
	
	if((dp=opendir(argv[1]))==NULL)
	err_sys("can not open %s", argv[1]);
	
	while((dirp=readdir(dp))!=NULL)
	printf("%s    ",dirp->d_name);

	closedir(dp);
	putchar('\n');
	exit(0);
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc myls.c -o myls -l apue
lwb@ubuntu:~/fileoperate$ ./myls .
lseek    ..    process_ctrl.c    lseek.c    process    myiocopy    myls   mystdcopy.c    signal.c    .    myiocopy.c    process_ctrl     myls.c    

标准输入复制到标准输出:
#include <ourhdr.h>
#define BUFFSIZE 4096
int main()
{
	int n;
	char buf[BUFFSIZE];
	
	while((n=read(STDIN_FILENO, buf, BUFFSIZE))>0)
	{
		if(strstr(buf,"quit!"))
		exit(1);
			
		if(write(STDOUT_FILENO, buf, n)!=n)
		err_sys("write error");
	}
		
	if(n<0)
	err_sys("read error");

	exit(0);
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc mystdcopy.c -o mystdcopy -l apue
lwb@ubuntu:~/fileoperate$ ./mystdcopy > data
hello world
quit! (Ctrl+D 也可退出)
lwb@ubuntu:~/fileoperate$ cat data
hello world

利用标准I/O将标准输入复制到标准输出:

#include <ourhdr.h>
#include <string.h>

int main()
{
	int c;
	while((c=getc(stdin))!=EOF)
	{
		if(c=='q')
		exit(1);

		if(putc(c,stdout)==EOF)
		err_sys("output error");
	}

	if(ferror(stdin))
	err_sys("input error");
	
	exit(0);
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc myiocopy.c -o myiocopy -l apue
lwb@ubuntu:~/fileoperate$ ./myiocopy > data
Hello world!
q (Ctrl+D 也可退出)
lwb@ubuntu:~/fileoperate$ cat data
Hello world!

程序是存放在磁盘文件中的可执行文件。使用6个exec函数中的一个由内核将程序读入存储器,并使其执行。程序的执行实例被称为进程。

打印进程ID:

#include <ourhdr.h>

int main()
{
	printf("this process id is %d\n",getpid());
	exit(0);
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc processid.c -o processid -l apue
lwb@ubuntu:~/fileoperate$ ./processid
this process id is 2490

进程控制:从标准输入读命令并执行

#include <sys/types.h>
#include <sys/wait.h>
#include <ourhdr.h>

int main()
{
	char buf[MAXLINE];
	pid_t pid;
	int status;
	printf("%% ");

	while(fgets(buf, MAXLINE, stdin) != NULL)
	{
		buf[strlen(buf)-1]=0;

		if((pid = fork())<0)
			err_sys("fork error");
		else if(pid == 0)
		{
			execlp(buf, buf, (char *)0);
			err_ret("could not execute: %s", buf);
			exit(127);
		}

		if((pid=waitpid(pid, &status, 0))<0)
		err_sys("waitpid error");

		printf("%% ");
	}
	putchar('\n');
	exit(0);
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc process_ctrl.c -o process_ctrl -l apue
lwb@ubuntu:~/fileoperate$ ./process_ctrl
% pwd
/home/lwb/fileoperate
% date
Tue May 3 04:47:36 PDT 2022
% (Ctrl+D键入文件结束符)

出错处理:示例strerror和perror

#include <errno.h>
#include <ourhdr.h>

int main(int argc, char *argv[])
{
	fprintf(stderr, "EACCES: %s\n", strerror(EACCES));

	errno = ENOENT;
	perror(argv[0]);

	exit(0);
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc errno.c -o errno -l apue
lwb@ubuntu:~/fileoperate$ ./errno
EACCES: Permission denied
./errno: No such file or directory

用户标识:打印用户ID和组ID

#include <ourhdr.h>
int main()
{
	printf("uid = %d, gid = %d\n", getuid(), getpid());
	exit(0);
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc userid.c -o userid -l apue
lwb@ubuntu:~/fileoperate$ ./userid
uid = 1000, gid = 2553

信号的产生有多种情况,两种键盘方式:中断键(Delete键或Ctrl+C)和Ctrl+\,他们被用于中断当前运行进程。另一种信号产生的方式是调用kill()函数,在一个进程中调用此函数就可以向另一个进程发送一个信号,当向另一个进程发送信号时,我们必须时该进程的所有者。

信号:从标准输入读命令并执行

#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <ourhdr.h>

static void sig_int(int);

void sig_int(int signo)
{
	printf(" interrupt\n%%");
}


int main()
{
	char buf[MAXLINE];
	pid_t pid;
	int status;

	if(signal(SIGINT, sig_int)==SIG_ERR)
	err_sys("signal error");

	printf("%% ");
	while(fgets(buf, MAXLINE, stdin)!=NULL)
	{
		buf[strlen(buf)-1]=0;
		if((pid=fork())<0)
		{
		err_sys("fork error");
		}
		else if(pid==0)
		{
			execlp(buf, buf, (char *)0);
			err_ret("couldn't execute: %s", buf);
			exit(127);
		}

		if((pid=waitpid(pid, &status, 0))<0)
		err_sys("waitpid error");

		printf("%% ");
	}
	putchar('\n');
	exit(0);
}

【运行结果】
lwb@ubuntu:~/fileoperate$ gcc signal.c -o signal -l apue
lwb@ubuntu:~/fileoperate$ ./signal
% pwd
/home/lwb/fileoperate
% date
Tue May 3 05:09:58 PDT 2022
% who
lwb :0 2022-05-03 03:41 (:0)
lwb pts/0 2022-05-03 05:02 (192.168.**.)
% ^C interrupt (ctrl+c中断键)
^\Quit (core dumped) (ctrl+\退出键)

参考链接:
https://blog.csdn.net/anlian523/article/details/90740075
https://blog.csdn.net/slismy/article/details/109472681

摘自:尤晋元 UNIX环境高级编程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值