為什麼unix和linux里的函數前面都有一個 『f』 ?

如題,
最近在看unix環境高級編程,發現裡面很多函數前面都有一個f,比如fopen,ftruncate,fstat, fchown等,而且不要『f』又是一套函數,我網上也沒搜到有什麼具體含義。


f 一般是 file 或 fd 的意思。不過 Unix 的庫函數和系統調用的命名很混亂,題主舉的幾個例子其實有兩種情況:

open/fopen:open 是 syscall 的名字,fopen 是 C 庫函數的名字。為了避免和 syscall 名字衝突,C 庫函數里的 wrapper 很多都帶 f 前綴。其實還有一種情況就是不帶 f 的是作用在 stdin/stdout 上的帶 f 的作用在 FILE* 上……

剩下的:不帶 f 的第一個參數是路徑,帶 f 的第一個參數是 fd。


先列出APUE書中第3,4,5章中出現的所有關於文件操作的函數吧。

第三章
文件IO--無緩衝IO

#include
&

int
open(const char *pathname, int oflag, ... /* mode_t mode
*/ );

int
creat(const char *pathname, mode_t mode);

int
fcntl(int filedes, int cmd, ... /* int arg */ );

#include
&

int
close(int filedes);

off_t
lseek(int filedes, off_t offset, int whence);

ssize_t
read(int filedes, void *buf, size_t nbytes);

ssize_t
write(int filedes, const void *buf, size_t nbytes);

ssize_t
pread(int filedes, void *buf, size_t nbytes, off_t offset);

ssize_t
pwrite(int filedes, const void *buf,
size_t nbytes, off_t offset);

int
dup(int filedes);

int
dup2(int filedes, int filedes2);

int
fsync(int filedes);

int
fdatasync(int filedes);

void
sync(void);

#include
&

int
ioctl(int filedes, int request, ...);

第四章
文件和文件夾

#include
&

int
stat(const char *restrict pathname, struct stat *restrict buf);

int
fstat(int filedes, struct stat *buf);

int
lstat(const char *restrict pathname, struct stat *restrict buf);

mode_t
umask(mode_t cmask);

int
chmod(const char *pathname, mode_t mode);

int
fchmod(int filedes, mode_t mode);

int
mkdir(const char *pathname, mode_t mode);

#include
&

int
access(const char *pathname, int mode);

int
chown(const char *pathname, uid_t owner, gid_t group);

int
fchown(int filedes, uid_t owner, gid_t group);

int
lchown(const char *pathname, uid_t owner,
gid_t group);

int
truncate(const char *pathname, off_t length);

int
ftruncate(int filedes, off_t length);

int
link(const char *existingpath, const char *newpath);

int
unlink(const char *pathname);

int
symlink(const char *actualpath, const char *sympath);

ssize_t
readlink(const char* restrict pathname,
char *restrict buf,
size_t
bufsize);

int
rmdir(const char *pathname);

int
chdir(const char *pathname);

int
fchdir(int filedes);

char
*getcwd(char *buf, size_t size);

#include
&

int
utime(const char *pathname, const struct utimbuf *times);

#include
&

DIR
*opendir(const char *pathname);

struct
dirent *readdir(DIR *dp);

void
rewinddir(DIR *dp);

int
closedir(DIR *dp);

long
telldir(DIR *dp);

void
seekdir(DIR *dp, long loc);

#include &

int remove(const char *pathname);

int rename(const char *oldname, const char *newname);

第五章
標準IO

#include
&

int
fwide(FILE *fp, int mode);

void
setbuf(FILE *restrict fp, char *restrict buf);

int
setvbuf(FILE *restrict fp, char *restrict buf,
int mode,
size_t
size);

int
fflush(FILE *fp);

FILE
*fopen(const char *restrict pathname, const char *restrict type);

FILE
*freopen(const char *restrict pathname, const char *restrict type,
FILE *restrict fp);

FILE
*fdopen(int filedes, const char *type);

int
fclose(FILE *fp);

int
ungetc(int c, FILE *fp);

int
getc(FILE *fp);

int
fgetc(FILE *fp);

int
getchar(void);

char
*fgets(char *restrict buf, int n, FILE *restrict fp);

char
*gets(char *buf);

int
ferror(FILE *fp);

int
feof(FILE *fp);

void
clearerr(FILE *fp);

int
putc(int c, FILE *fp);

int
fputc(int c, FILE *fp);

int
putchar(int c);

int
fputs(const char *restrict str, FILE *restrict fp);

int
puts(const char *str);

size_t
fread(void *restrict ptr, size_t size,
size_t nobj,
FILE *restrict
fp);

size_t
fwrite(const void *restrict ptr, size_t size, size_t nobj,
FILE
*restrict fp);

long
ftell(FILE *fp);

int
fseek(FILE *fp, long offset, int whence);

void
rewind(FILE *fp);

off_t
ftello(FILE *fp);

int
fseeko(FILE *fp, off_t offset, int whence);

int
fgetpos(FILE *restrict fp, fpos_t *restrict pos);

int
fsetpos(FILE *fp, const fpos_t *pos);

int
printf(const char *restrict format, ...);

int
fprintf(FILE *restrict fp, const char *restrict format, ...);

int
sprintf(char *restrict buf, const char *restrict format, ...);

int
snprintf(char *restrict buf, size_t n,
const char *restrict format,
...);

int
vprintf(const char *restrict format, va_list arg);

int
vfprintf(FILE *restrict fp, const char *restrict format,
va_list
arg);

int
vsprintf(char *restrict buf, const char *restrict format,
va_list
arg);

int
vsnprintf(char *restrict buf, size_t n,
const char *restrict format,
va_list arg);

int
scanf(const char *restrict format, ...);

int
fscanf(FILE *restrict fp, const char *restrict format, ...);

int
sscanf(const char *restrict buf, const char *restrict format,
...);

int
vscanf(const char *restrict format, va_list arg);

int
vfscanf(FILE *restrict fp, const char *restrict format,
va_list
arg);

int
vsscanf(const char *restrict buf, const char *restrict format,
va_list arg);

int
fileno(FILE *fp);

char
*tmpnam(char *ptr);

FILE
*tmpfile(void);

char
*tempnam(const char *directory, const char *prefix);

int
mkstemp(char *template);

題主這個問題可以分兩種情況回答:

  • 系統提供的文件操作

根據上述列表可以看到,第3章全部以及第4章的大部分(除了第4章的最後remove和rename兩個函數)都是系統提供的文件操作。

第三章中出現f的函數有3個:

int fcntl(int filedes, int cmd, ... /* int arg */ );

int fsync(int filedes);

int fdatasync(int filedes);

而這三個函數中只有fsync有一個沒有f的同名函數sync,前者是同步某個文件,而後者是同步該進程中的所有文件。其他兩個並沒有不帶f的同名函數,這裡只能猜測,加上f更容易讓人理解,這是針對文件的操作。

第四章中出現f的函數就比較容易區分了,因為所有帶f的函數都有一個與之匹配的不帶f的函數,而帶f的函數是以文件描述符作為參數,不帶f的函數則是以文件路徑作為參數。

通過以上觀察,可以得出如下結論:

系統提供的基本上是不帶f的函數來表示文件操作,而只有含有同名函數時,為了加以區分,將以文件描述符為參數的函數添加上f,而以文件路徑為參數的函數不加f。

  • 標準庫提供的文件操作

標準庫中的函數大部分都帶f,而僅當操作標準輸入/輸出時,不帶f。其中幾個例外列於下邊:

void setbuf(FILE *restrict fp, char *restrict buf);

int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);

int ungetc(int c, FILE *fp);

int getc(FILE *fp);

int putc(int c, FILE *fp);

void rewind(FILE *fp);

void clearerr(FILE *fp);

以上這些函數都有一個FILE*類型的流fp,卻沒有添加f,用粗體標註的兩個函數和帶f的函數功能一樣,僅僅實現不同,這兩者可以使用宏來實現,而fgetc和fputc是不可以用宏實現的。其他幾個只能說這樣命名沒有歧義,並且不與系統調用衝突,且簡練(lan)。


linux系統 一切都可看做是 文件 操作 。有這麼一種說法


推薦閱讀:

網路編程(三):從libevent到事件通知機制
Linux的目錄結構是否過於複雜難懂,不夠清晰直觀?
電腦複製粘貼背後發生了什麼?
正在學習嵌入式linux開發,求推薦詳細介紹makefile和鏈接腳本語法相關的書籍或者資料。?
一個用慣了windows的用戶,怎樣上手linux系統?如果用linux系統,能夠勝任日常辦公需求嗎?

TAG:Linux | Unix | UNIX環境高級編程書籍 |