apache运行时文件读写注释
- apr_file_t的结构使用
struct apr_file_t {
apr_pool_t *pool;//apache对应的内存池使用效果
int filedes;//文件描述符
char *fname;//文件名
apr_int32_t flags;//文件操作权限
int eof_hit;//是否到达文件尾
int is_pipe;//是否是管道文件
apr_interval_time_t timeout;//是否超时
int buffered;//是否是buffer
//是否阻塞
enum {BLK_UNKNOWN, BLK_OFF, BLK_ON } blocking;
int ungetchar; /* Last char provided by an unget op. (-1 = no char)*/
/* if there is a timeout set, then this pollset is used */
apr_pollset_t *pollset;
/* Stuff for buffered mode */
char *buffer;
apr_size_t bufpos; /* Read/Write position in buffer */
apr_size_t bufsize; /* The buffer size */
apr_off_t dataRead; /* amount of valid data read into buffer */
int direction; /* buffer being used for 0 = read, 1 = write */
//文件偏移位置
apr_off_t filePtr; /* position in file of handle */
#if APR_HAS_THREADS
struct apr_thread_mutex_t *thlock;
#endif
};
2.关于文件的open函数注释
APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new,
const char *fname,
apr_int32_t flag,
apr_fileperms_t perm,
apr_pool_t *pool)
{
apr_os_file_t fd;
int oflags = 0;
#if APR_HAS_THREADS //是否多线程环境
apr_thread_mutex_t *thlock;
apr_status_t rv;
#endif
//可以读写
if ((flag & APR_FOPEN_READ) && (flag & APR_FOPEN_WRITE)) {
oflags = O_RDWR;
}
//只读
else if (flag & APR_FOPEN_READ) {
oflags = O_RDONLY;
}
//只写
else if (flag & APR_FOPEN_WRITE) {
oflags = O_WRONLY;
}
//其他
else {
return APR_EACCES;
}
//文件不存在第一次创建文件,如果文件有内存就删除
if (flag & APR_FOPEN_CREATE) {
oflags |= O_CREAT;
if (flag & APR_FOPEN_EXCL) {
oflags |= O_EXCL;
}
}
if ((flag & APR_FOPEN_EXCL) && !(flag & APR_FOPEN_CREATE)) {
return APR_EACCES;
}
//文件追加内容
if (flag & APR_FOPEN_APPEND) {
oflags |= O_APPEND;
}
//文件截断
if (flag & APR_FOPEN_TRUNCATE) {
oflags |= O_TRUNC;
}
#ifdef O_BINARY
if (flag & APR_FOPEN_BINARY) {
oflags |= O_BINARY;
}
#endif
if (flag & APR_FOPEN_NONBLOCK) {
#ifdef O_NONBLOCK
oflags |= O_NONBLOCK;
#else
return APR_ENOTIMPL;
#endif
}
#ifdef O_CLOEXEC
/* Introduced in Linux 2.6.23. Silently ignored on earlier Linux kernels.
*/
if (!(flag & APR_FOPEN_NOCLEANUP)) {
oflags |= O_CLOEXEC;
}
#endif
#if APR_HAS_LARGE_FILES && defined(_LARGEFILE64_SOURCE)
oflags |= O_LARGEFILE;
#elif defined(O_LARGEFILE)
if (flag & APR_FOPEN_LARGEFILE) {
oflags |= O_LARGEFILE;
}
#endif
#if APR_HAS_THREADS
if ((flag & APR_FOPEN_BUFFERED) && (flag & APR_FOPEN_XTHREAD)) {
rv = apr_thread_mutex_create(&thlock,
APR_THREAD_MUTEX_DEFAULT, pool);
if (rv) {
return rv;
}
}
#endif
if (perm == APR_OS_DEFAULT) {
fd = open(fname, oflags, 0666);
}
else {
fd = open(fname, oflags, apr_unix_perms2mode(perm));
}
if (fd < 0) {
return errno;
}
if (!(flag & APR_FOPEN_NOCLEANUP)) {
#ifdef O_CLOEXEC
static int has_o_cloexec = 0;
if (!has_o_cloexec)
#endif
{
int flags;
if ((flags = fcntl(fd, F_GETFD)) == -1) {
close(fd);
return errno;
}
if ((flags & FD_CLOEXEC) == 0) {
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
close(fd);
return errno;
}
}
#ifdef O_CLOEXEC
else {
has_o_cloexec = 1;
}
#endif
}
}
//创建file
//实例化文件对象
(*new) = (apr_file_t *)apr_pcalloc(pool, sizeof(apr_file_t));
(*new)->pool = pool;
(*new)->flags = flag;
(*new)->filedes = fd;
(*new)->fname = apr_pstrdup(pool, fname);
(*new)->blocking = BLK_ON;
(*new)->buffered = (flag & APR_FOPEN_BUFFERED) > 0;
if ((*new)->buffered) {
(*new)->buffer = apr_palloc(pool, APR_FILE_DEFAULT_BUFSIZE);
(*new)->bufsize = APR_FILE_DEFAULT_BUFSIZE;
#if APR_HAS_THREADS
if ((*new)->flags & APR_FOPEN_XTHREAD) {
(*new)->thlock = thlock;
}
#endif
}
else {
(*new)->buffer = NULL;
}
(*new)->is_pipe = 0;
(*new)->timeout = -1;
(*new)->ungetchar = -1;
(*new)->eof_hit = 0;
(*new)->filePtr = 0;
(*new)->bufpos = 0;
(*new)->dataRead = 0;
(*new)->direction = 0;
#ifndef WAITIO_USES_POLL
/* Start out with no pollset. apr_wait_for_io_or_timeout() will
* initialize the pollset if needed.
*/
(*new)->pollset = NULL;
#endif
if (!(flag & APR_FOPEN_NOCLEANUP)) {
apr_pool_cleanup_register((*new)->pool, (void *)(*new),
apr_unix_file_cleanup,
apr_unix_child_file_cleanup);
}
return APR_SUCCESS;
}