apue(4)

来源:互联网 发布:windows 7 toolkit 编辑:程序博客网 时间:2024/06/07 00:39
 

4.17. symlink and readlink Functions

#include <unistd.h> int symlink(const char *actualpath, const char *sympath); A new directory entry, sympath, is created that points to actualpath. It is not required that actualpath exist when the symbolic link is created. Also, actualpath and sympath need not reside in the same file system. #include <unistd.h> ssize_t readlink(const char* restrict pathname, char *restrict buf, size_t bufsize); 如果读取readlink成功,buf里保存着link里的内容,返回link的长度。(注意:不是以0结尾)

4.18. File Times

Three time fields are maintained for each file. 

Field

Description

Example

ls(1) option

st_atime

last-access time of file data

read

-u

st_mtime

last-modification time of file data

write

default

st_ctime

last-change time of i-node status

chmod, chown

-c

个人空间相册

Note that the system does not maintain the last-access time for an i-node. This is why the functions access and stat, for example, don't change any of the three times.

4.19. utime Function

The access time and the modification time of a file can be changed with theutime function.

#include <utime.h> int utime(const char *pathname, const struct utimbuf *times); struct utimbuf { time_t actime; /* access time */ time_t modtime; /* modification time */ } If times is a null pointer, the access time and the modification time are both set to the current time. 当需要真正设置时间时,必须有root权限,只拥有文件的权限是不够的。

4.20. mkdir and rmdir Functions

#include <sys/stat.h> int mkdir(const char *pathname, mode_t mode); The user ID of a new file is set to the effective user ID of the process.  The group ID of a new file can be the effective group ID of the process. The group ID of a new file can be the group ID of the directory in which the file is being created. Solaris 9 and Linux 2.4.22 also have the new directory inherit the set-group-ID bit from the parent directory.  #include <unistd.h> int rmdir(const char *pathname); An empty directory is deleted with the rmdir function.

4.21. Reading Directories

#include <dirent.h> 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); struct dirent { ino_t d_ino; /* i-node number */ char d_name[NAME_MAX + 1]; /* null-terminated filename */ }figure 4.21

4.22. chdir, fchdir, and getcwd Functions

#include <unistd.h> int chdir(const char *pathname); int fchdir(int filedes); #include <unistd.h> char *getcwd(char *buf, size_t size); 返回的字符串以NULL结束

4.23. Device Special Files

The two fields st_dev and st_rdev are often confused.

4.24. Summary of File Access Permission Bits

Constant

Description

Effect on regular file

Effect on directory

S_ISUID

set-user-ID

set effective user ID on execution

(not used)

S_ISGID

set-group-ID

if group-execute set then set effective group ID on execution; otherwise enable mandatory record locking (if supported)

set group ID of new files created in directory to group ID of directory

S_ISVTX

sticky bit

control caching of file contents (if supported)

restrict removal and renaming of files in directory

S_IRUSR

user-read

user permission to read file

user permission to read directory entries

S_IWUSR

user-write

user permission to write file

user permission to remove and create files in directory

S_IXUSR

user-execute

user permission to execute file

user permission to search for given pathname in directory

S_IRGRP

group-read

group permission to read file

group permission to read directory entries

S_IWGRP

group-write

group permission to write file

group permission to remove and create files in directory

S_IXGRP

group-execute

group permission to execute file

group permission to search for given pathname in directory

S_IROTH

other-read

other permission to read file

other permission to read directory entries

S_IWOTH

other-write

other permission to write file

other permission to remove and create files in directory

S_IXOTH

other-execute

other permission to execute file

other permission to search for given pathname in directory

EXERCISE 4.14

st_atime是最后一次读的时间,st_mtime是最后一次接受新邮件的时间。

5.2. Streams and FILE Objects

#include <stdio.h> #include <wchar.h> int fwide(FILE *fp, int mode); Returns: positive if stream is wide-oriented, negative if stream is byte-oriented, or 0 if stream has no orientation

参数如果是正的,会试着设置streamwide,如果是负的,会试着设置streambyte,如果是0,显示现在的类型。

不会改变现在的类型。

不会返回错误,但是当失败时,errono会被设置。

5.4. Buffering

Three types of buffering are provided:

Fully buffered.

Line buffered. Line buffering is typically used on a stream when it refers to a terminal: standard input and standard output

Unbuffered. The standard error stream, for example, is normally unbuffered.

Most implementations default to the following types of buffering.

  • Standard error is always unbuffered.

  • All other streams are line buffered if they refer to a terminal device; otherwise, they are fully buffered.

#include <stdio.h> void setbuf(FILE *restrict fp, char *restrict buf); int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);

These functions must be called after the stream has been openedbut before any other operation is performed on the stream.

To enable buffering, buf must point to a buffer of lengthBUFSIZ, a constant defined in <stdio.h>. Normally, the stream is then fully buffered, but some systems may set line buffering if the stream is associated with a terminal device. To disable buffering, we set buf to NULL.

With setvbuf, we specify exactly which type of buffering we want. This is done with the mode argument:

_IOFBF

fully buffered

_IOLBF

line buffered

_IONBF

unbuffered

#include <stdio.h> int fflush(FILE *fp); 如果错误返回值为EOF。如果参数为NULL,所有的stream flush

5.5. Opening a Stream

#include <stdio.h> 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); fdopen用于将一些只能获得fd的文件转化为标准I/O

type

Description

r orrb

open for reading

w orwb

truncate to 0 length or create for writing

a orab

append; open for writing at end of file, or create for writing

r+ orr+b or rb+

open for reading and writing

w+ orw+b or wb+

truncate to 0 length or create for reading and writing

a+ ora+b or ab+

open or create for reading and writing at end of file

 

Output cannot be directly followed by input without an interveningfflush, fseek, fsetpos,or rewind.

Input cannot be directly followed by output without an interveningfseek, fsetpos,or rewind, or an input operation that encounters an end of file.

#include <stdio.h> int fclose(FILE *fp);

5.6. Reading and Writing a Stream

#include <stdio.h> int ferror(FILE *fp); int feof(FILE *fp); void clearerr(FILE *fp);

Input Functions

#include <stdio.h> int getc(FILE *fp); int fgetc(FILE *fp); int getchar(void); getc can be implemented as a macro, whereas fgetc cannot be implemented as a macro. getc is faster, unsafer. int ungetc(int c, FILE *fp); //将值放回去,最好只放回一个,可以与原值不同。 回写的c放在缓冲区中,不直接写回磁盘。

Output Functions

#include <stdio.h> int putc(int c, FILE *fp); int fputc(int c, FILE *fp); int putchar(int c);

5.7. Line-at-a-Time I/O

#include <stdio.h> char *fgets(char *restrict buf, int n, FILE *restrict fp); char *gets(char *buf); fgets 返回的buf总是以NULL结尾。不要用gets #include <stdio.h> int fputs(const char *restrict str, FILE *restrict fp); int puts(const char *str); 两者负责输出NULL结尾字符串, fputs最后会不输出换行,puts会输出换行。 建议fputs char buf[MAXLINE]; When we use the line-at-a-time functions, fgets and fputs, the data is usually copied twice: once between the kernel and the standard I/O buffer (when the corresponding read or write is issued) and again between the standard I/O buffer and our line buffer.

5.8. Standard I/O Efficiency

 一般的说,选好缓冲区大小,read的效率比fgets高。但差别不大。 但fgetcfputc比长度为1read好。

5.9. Binary I/O

#include <stdio.h> 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); Both return: number of objects read or written The obvious generalization of these two cases is to read or write an array of structures. To do this, size would be the sizeof the structure, and nobj would be the number of elements in the array. 常用来读写结构体。

5.10. Positioning a Stream

#include <stdio.h> long ftell(FILE *fp); int fseek(FILE *fp, long offset, int whence); void rewind(FILE *fp); #include <stdio.h> off_t ftello(FILE *fp); //仅与ftell的返回值不同 int fseeko(FILE *fp, off_t offset, int whence); //仅与fseekoffset参数类型不同 #include <stdio.h> int fgetpos(FILE *restrict fp, fpos_t *restrict pos); int fsetpos(FILE *fp, const fpos_t *pos); 使用fpos_t 结构体来储存位置。

5.11. Formatted I/O

#include <stdio.h> 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, ...); sprintf自动在最后加上NULL %[flags][fldwidth][precision][lenmodifier]convtype #include <stdarg.h> #include <stdio.h> 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); #include <stdio.h> 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, ...); #include <stdarg.h> #include <stdio.h> 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);

5.12. Implementation Details

#include <stdio.h> int fileno(FILE *fp); 返回fd FILE_IO_file_flags; _IO_buf_base; _IO_buf_end; _IO_UNBUFFERED; _IO_LINE_BUFFERED; 。。。) 三种类型buffer大小不顾定,重定向后buffer可能改变。

5.13. Temporary Files

#include <stdio.h> char *tmpnam(char *ptr); FILE *tmpfile(void); char *tempnam(const char *directory, const char *prefix); int mkstemp(char *template); 使用tmpnam,先申请一个字符数组长度为L_tmpnam,参数为NULL时名称存储在唯一一个静态区域内。 tmpfile自动创建临时文件,返回指针。打开方式为wb+,自动删除。 Tempnam可以自定义临时文件位置和前缀 mdktemptemplateXXXXXX结尾,不自动清除,需要自己unlink。 提倡使用tmpfilemkstemp,其他两个在返回文件名和真正创建文件时有间隙,其他可能创建同名文件。 ?

5.14. Alternatives to Standard I/O

When we use the line-at-a-time functions, fgets and fputs, the data is usually copied twice: once between the kernel and the standard I/O buffer (when the corresponding read or write is issued) and again between the standard I/O buffer and our line buffer.  EXERCISE 5.6 fsync fflush

6.2. Password File

Description

struct passwd member

user name

char *pw_name

encrypted password

char *pw_passwd(.......)

numerical user ID

uid_t pw_uid

numerical group ID

gid_t pw_gid

comment field

char *pw_gecos

initial working directory

char *pw_dir

initial shell (user program)

char *pw_shell

user access class

char *pw_class

next time to change password

time_t pw_change

account expiration time

time_t pw_expire

Many services have separate user IDs for the daemon processes (Chapter 13) that help implement the service.  The nobody user name can be used to allow people to log in to a system, but with a user ID (65534) and group ID (65534) that provide no privileges.  Vipw 一个command修改passwd #include <pwd.h> struct passwd *getpwuid(uid_t uid); //根据uid返回passwd entry struct passwd *getpwnam(const char *name); //根据name返回passwd entry struct passwd *getpwent(void); //迭代返回 passwd entry void setpwent(void); //rewind void endpwent(void); //close The functions to access the shadow password file on Linux and Solaris are discussed in Section 6.3. We can't use the value returned in the pw_passwd field by the functions described in Section 6.2 to compare an encrypted password, since that field is not the encrypted password. Instead, we need to find the user's entry in the shadow file and use its encrypted password field.

6.3. Shadow Passwords

Description

struct spwd member

user login name

char *sp_namp

encrypted password

char *sp_pwdp

days since Epoch of last password change

int sp_lstchg

days until change allowed

int sp_min

days before change required

int sp_max

days warning for expiration

int sp_warn

days before account inactive

int sp_inact

days since Epoch when account expires

int sp_expire.

reserved

unsigned int sp_flag

#include <shadow.h> struct spwd *getspnam(const char *name); struct spwd *getspent(void); void setspent(void); void endspent(void);

6.4. Group File

Description

struct group member

group name

char *gr_name

encrypted password

char *gr_passwd

numerical group ID

int gr_gid

array of pointers to individual user names

char **gr_mem

#include <grp.h> struct group *getgrgid(gid_t gid); struct group *getgrnam(const char *name); struct group *getgrent(void); void setgrent(void); void endgrent(void);

6.5. Supplementary Group IDs

#include <unistd.h> int getgroups(int gidsetsize, gid_t grouplist[]); The getgroups function fills in the array grouplist with the supplementary group IDs. Up to gidsetsize elements are stored in the array. The number of supplementary group IDs stored in the array is returned by the function. As a special case, if gidsetsize is 0, the function returns only the number of supplementary group IDs. The array grouplist is not modified. (This allows the caller to determine the size of the grouplist array to allocate.) #include <grp.h> /* on Linux */ #include <unistd.h> /* on FreeBSD, Mac OS X, and Solaris */ int setgroups(int ngroups, const gid_t grouplist[]); The setgroups function can be called by the superuser to set the supplementary group ID list for the calling process: grouplist contains the array of group IDs, and ngroups specifies the number of elements in the array. The value of ngroups cannot be larger than NGROUPS_MAX. int initgroups(const char *username, gid_t basegid);

6.7. Other Data Files

Figure 6.6. Similar routines for accessing system data files

Description

Data file

Header

Structure

Additional keyed lookup functions

passwords

/etc/passwd

<pwd.h>

passwd

getpwnam,getpwuid

groups

/etc/group

<grp.h>

group

getgrnam,getgrgid

shadow

/etc/shadow

<shadow.h>

spwd

getspnam

hosts

/etc/hosts

<netdb.h>

hostent

gethostbyname,gethostbyaddr

networks

/etc/networks

<netdb.h>

netent

getnetbyname,getnetbyaddr

protocols

/etc/protocols

<netdb.h>

protoent

getprotobyname,getprotobynumber

services

/etc/services

<netdb.h>

servent

getservbyname,getservbyport

The general principle is that every data file has at least three functions:

  1. A get function that reads the next record, opening the file if necessary. These functions normally return a pointer to a structure. A null pointer is returned when the end of file is reached. Most of the get functions return a pointer to astatic structure, so we always have to copy it if we want to save it.

  2. A set function that opens the file, if not already open, and rewinds the file. This function is used when we know we want to start again at the beginning of the file.

  3. An end enTRy that closes the data file. As we mentioned earlier, we always have to call this when we're done, to close all the files.

6.8. Login Accounting

Two data files that have been provided with most UNIX systems are the utmp file, which keeps track of all the users currently logged in, and the wtmp file, which keeps track of all logins and logouts.

 struct utmp { char ut_line[8]; /* tty line: "ttyh0", "ttyd0", "ttyp0", ... */ char ut_name[8]; /* login name */ long ut_time; /* seconds since Epoch */ };

6.9. System Identification

#include <sys/utsname.h> int uname(struct utsname *name); struct utsname { char sysname[]; /* name of the operating system */ char nodename[]; /* name of this node */ char release[]; /* current release of operating system */ char version[]; /* current version of this release */ char machine[]; /* name of hardware type */ };

6.10. Time and Date Routines

#include <time.h> time_t time(time_t *calptr); int gettimeofday(struct timeval *restrict tp, void *restrict tzp); tzp再不同的平台下,支持情况不同,一般为NULL struct tm *gmtime(const time_t *calptr); struct tm *localtime(const time_t *calptr); time_t mktime(struct tm *tmptr); char *asctime(const struct tm *tmptr); char *ctime(const time_t *calptr); size_t strftime(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr); We mentioned that the four functions in Figure 6.8 with dashed lines were affected by the TZ environment variable: localtime, mktime, ctime, and strftime. struct timeval { time_t tv_sec; /* seconds */ long tv_usec; /* microseconds */ }; struct tm { /* a broken-down time */ int tm_sec; /* seconds after the minute: [0 - 60] */ int tm_min; /* minutes after the hour: [0 - 59] */ int tm_hour; /* hours after midnight: [0 - 23] */ int tm_mday; /* day of the month: [1 - 31] */ int tm_mon; /* months since January: [0 - 11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday: [0 - 6] */ int tm_yday; /* days since January 1: [0 - 365] */ int tm_isdst; /* daylight saving time flag: <0, 0, >0 */ }; 
原创粉丝点击