プログラミングの概要システム
オペレーティングシステムの機能:
すべてのリソースを管理するためのオペレーティングシステム、および関連付け異なるデバイスと異なるプログラム
Linuxのシステムプログラミング:
プログラミング環境のLinuxオペレーティングシステムおよびオペレーティングシステムが提供するシステムコールとライブラリの多様性を使用して、システムリソースへのアクセス
システムコールの概要
ソフトウェアレベルのUNIXライクなシステム:
ユーザ・オペレーティング・システム・プログラムに提供される「特別な」システムコール機能インターフェースのセット
のセットが提供するサービス・プログラム、オペレーティング・システム(カーネル)のためのユーザインタフェース
の例:
ユーザーは、関連するシステムのファイル・システムを起動し、システムが開いているファイルを要求し、ファイルの読み込みと書き込み、またはファイルを閉じることができます
機能ロジックにより、システムコール:
プロセス制御、プロセス間通信、ファイルシステム管理、システム管理、メモリ管理、ネットワーク管理、ソケット制御、ユーザ管理
システムコールの戻り値:
成功:0
失敗しました:ネガティブ
関数は、エラーメッセージを表示するために使用することができるPERRORエラー情報は、グローバル変数errnoに格納されます。
システムは、規範に従うことを呼び出します
Linuxでは、インタフェース(API)をプログラミングアプリケーションは、POSIX標準に準拠しています
POSIX標準は、使用するオペレーティングシステムコールプログラミング・インターフェース(API実際に)、記述し、既存のUNIXの実践と経験に基づいた
アプリケーションのソースコードは、複数のオペレーティングシステム上で実行時に移植できることを確実にするために
以下のような:
Linuxのオープン、書き込みで書き込まれ、読み取りは、UNIXオペレーティングシステムに直接移植することができます
システムコールI / O機能
機能I / O操作でシステムコールは、ファイルディスクリプタのためのものです
対応するファイルディスクリプタを操作することにより、直接することができ
以下のような:
オープン、クローズ、書き込み、読み、のioctl
ファイルディスクリプタ
非負の整数のファイルディスクリプタ
既存のファイルを開くか、新しいファイルシステム(カーネル)を作成する場合、ファイルディスクリプタを返します
ファイル記述子は、開いているファイルを指定するために使用されます
// 程序运行后这三个文件描述符是默认打开
#define STDIN_FILENO 0 //标准输入的文件描述符
#define STDOUT_FILENO 1 //标准输出的文件描述符
#define STDERR_FILENO 2 //标准错误的文件描述符
オープン関数
ファイルを開きます
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// 文件存在
int open(const char *pathname, int flags);
/* 文件不存在
* pathname: 文件的路径及文件名
* flags:行为标志
* O_RDONLY 只读方式打开
* O_WRONLY 只写方式打开
* O_RDWR 可读可写方式打开
* 下列值 位或
* O_CREAT 文件不存在则创建文件,mode说明文件权限
* O_EXCL 指定O_CREAT,且文件已存在 则出错
* O_TRUNC 文件存在 清除文件内容
* O_APPEND 写文件,数据添加到文件末尾
* O_NONBLOCK 打开的文件是FIFO,字符文件,块文件,该选项为非堵塞标志位
* mode:文件权限(可读,可写,可执行)的设置
* 取值 八进制 含义
* S_IRWXU 700 文件所有者的读,写,可执行权限
* S_IRUSR 400 文件所有者的读权限
* S_IWUSR 200 文件所有者的写权限
* S_IXUSR 100 文件所有者的可执行权限
* S_IRWXG 70 文件所有者同组用户的读写可执行权限
* S_IRGRP 40 文件所有者同组用户的读权限
*
* return:成功:文件描述符 失败:-1,可用 perror 查看原因
*/
int open(const char *pathname, int flags, mode_t mode);
close関数
ファイルを閉じます
#include <unistd.h>
/*
*fd:调用open打开文件返回的文件描述符
* return:成功:0 失败:-1 可用 perror 去查看原因
*/
int close(int fd);
書き込み機能
指定したファイルに書き込まれたデータの数
#include <unistd.h>
/*
* fd:文件描述符
* addr:数据首地址
* count: 写入数据的字节个数
* return:成功:写入字节个数 失败:-1
*/
ssize_t write(int fd, const void *addr, size_t count);
読み取り機能
指定された数を読み込むためのデータメモリ
#include <unistd.h>
/*
* fd:文件描述符
* addr:内存首地址
* count:读取的字节个数
* return:成功:读取的字节个数 失败:-1
*/
ssize_t read(int fd, void *addr, size_t count);
ライブラリ関数を削除
ファイルの削除
#include <stdio.h>
/*
* pathname: 文件路径+文件名
* return:成功:0 失败:-1
*/
int remove(const char * pathname);
例:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void test1();
void test2();
void test3();
int main(int argc, char *argv[])
{
test1();
test2();
test3();
return 0;
}
void test1()
{
char buf[32] = "";
read(0, buf, sizeof(buf));
write(1, buf, strlen(buf));
}
void test2()
{
int fd = 0;
char str[] = "hello file";
fd = open("./a.txt",O_WRONLY | O_CREAT | O_EXCL, 0777);
if(-1 == fd)
{
perror("open");
return;
}
printf("fd = %d\n", fd);
write(fd, str, strlen(str));
close(fd);
}
void test3()
{
int fd = 0;
char buf[128] = "";
int len = 0;
fd = open("a.txt",O_RDONLY);
if(-1 == fd)
{
perror("open");
return;
}
len = read(fd, buf, sizeof(buf));
printf("len = %d\n", len);
printf("buf = %s\n", buf);
close(fd);
}
印刷:
システムコールやライブラリ関数
システムコールを呼び出す必要はありません
すべての関数の機能、および結果を完了するために、カーネル空間に切り替えることなく、アプリケーション・プログラムにフィードバックされます。
以下のような:などのstrcpy、BZERO文字列操作関数、
あなたは、システムコールを呼び出す必要があります
カーネル空間、対応する機能に、このようなパッケージングシステム関数呼び出しに切り替える必要があり
などのprintf、関数fread、など
ライブラリ関数とシステムコールとの関係
すべてのシステム・コールがライブラリ機能にパッケージ化されていない、システムが機能の多くは、呼び出すことによって、システムに実装する必要があります提供します
システムコールは、時間がかかり、頻繁に使用されるプログラムは、システムの効率が低下しますプログラムを呼び出します
カーネルコード、カーネルモードでCPUの作業を実行している場合、システムコールは環境スタックとメモリのユーザーモードを維持する必要性の前に発生し、その後、カーネルに転送
-state操作
システムコールの後、だけでなく、為替ユーザー状態のカットに。このスイッチング環境では、多くの時間を消費します
アクセスファイルにタイムライブラリ関数は、アクセス改善、これIOシステムコールへの直接呼び出しの回数を減らし、バッファの種類を設定し、必要に応じて
効率を
処理アプリケーションは、機能を実行、のprintf関数を呼び出します
cpコマンドを達成
目標:
使用して、システムコールのcpコマンド
原理:
使用してファイルにファイルを開くためのシステムとコールオープン、リードを使用して、ファイルからデータを読み取り、書き込み、書き込みデータ
ARGCメイン関数に格納された実行可能プログラムに渡される引数の数を、パラメータはARGV内のポインタの最初のアドレスアレイに記憶されています
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const * argv[])
{
int srcFd = 0;
char fileName[64] = "";
int dstFd = 0;
char buf[128] = "";
int len = 0;
if(3 != argc)
{
printf("请按 ./a.out srcdst 传参\n");
return 0;
}
// 打开源文件
srcFd = open(argv[1], O_RDONLY);
if(-1 == srcFd)
{
perror("open");
return 0;
}
// 打开目的文件
sprintf(fileName, "%s/%s",argv[2],argv[1]);
dstFd = open(fileName, O_WRONLY | O_CREAT, 0777);
if(-1 == dstFd)
{
perror("open");
return 0;
}
while(1)
{
len = read(srcFd, buf, sizeof(buf));
if(len <= 0)
{
break;
}
write(dstFd, buf, len);
}
close(srcFd);
close(dstFd);
return 0;
}