当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 8 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 看apue遇到的一个问题:var&accmode
帖子发表于 : 2007-04-16 17:52 

注册: 2007-02-14 13:56
帖子: 52
地址: swust
送出感谢: 0 次
接收感谢: 0 次
这是完整的程序:
#include <sys/types.h>;
#include <fcntl.h>;
#include "ourhdr.h"
int main (int argc ,char *argv[] )
{
int accmode,val;
if (argc !=2 )
fprintf(stderr,"usage: a.out <descritpor#>;";
if ((val= fcntl(atoi(argv[1]), F_GETFL, 0)) <0)
fprintf(stderr,"fcntl error for fd %d", atoi(argv[1] ));
accmode=val & O_ACCMODE ; #######在这里。
if (accmode==O_RDONLY) printf("read only\n";
else if (accmode==O_WRONLY) printf("write only\n";
else if (accmode==O_RDWR) printf( "read and write\n";
else printf("unknown access mode\n";

if (val & O_APPEND ) printf (", append\n";
if (val & O_NONBLOCK) printf (", nonblocking\n";
if (val & O_SYNC) printf(", synchronous write\n";

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


accmod = val & O_ACCMODE; 是什么意思?请指教!!我是新手,请回答得详细点。另外就是val & O_APPEND 又是什么意思呢
书中说的是首先必须用屏蔽字O _ A C C M O D E取得存取方式位,然后将结果与这三种值. 可我还是不明白


页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2007-04-16 19:40 

注册: 2005-10-26 22:18
帖子: 31
送出感谢: 0 次
接收感谢: 0 次
fcntl这个函数你知道是干什么的吧?
从而val的值是由argv[1]所指定的文件描述符指向的文件的状态flag。
O_APPEND 与O_ACCMODE等都是宏,实际上是数字。
O_ACCMODE: 3, O_RDONLY: 0, O_WRONLY: 1, O_RDWR: 2
O_APPEND: 1024, O_NONBLOCK: 2048, O_SYNC: 4096

val与O_ACCMODE执行按位与操作,

以下以val为2举例:

2,就是二进制0010,由O_ACCMODE: 3(就是0011),二者按位与得到0010,即2。
即accmode=val & O_ACCMODE结果为2。
下面的三行,因为 O_RDONLY: 0, O_WRONLY: 1, O_RDWR: 2
if (accmode == O_RDONLY)
printf ("read only\n");
else if (accmode == O_WRONLY)
printf ("write only\n");
else if (accmode == O_RDWR)
printf ("read and write\n");
else
printf ("unknown access mode\n");
输出read and write。

而这几个值:O_APPEND: 1024, O_NONBLOCK: 2048, O_SYNC: 4096
O_APPEND: 1024就是0000 0100 0000 0000
O_SYNC: 4096 就是 0001 0000 0000 0000
显然与accmode(0010)执行按位与操作,结果都为0。

你直接从书上copy的代码?
我整理了一下,多了几个输出语句:

#include <sys/types.h>
#include <fcntl.h>
#include "apue.h" /*这是我的apue的头文件,你可以用你的*/
int
main (int argc, char *argv[])
{
int accmode, val;
if (argc != 2)
fprintf (stderr, "usage: a.out <descritpor#>;");
if ((val = fcntl (atoi (argv[1]), F_GETFL, 0)) < 0)
fprintf (stderr, "fcntl error for fd %d", atoi (argv[1]));
accmode = val & O_ACCMODE;
printf("accmode: %d, val: %d\n",accmode,val);
printf("O_ACCMODE: %d, O_RDONLY: %d, O_WRONLY: %d, O_RDWR: %d\n",O_ACCMODE,O_RDONLY,O_WRONLY,O_RDWR);
printf("O_APPEND: %d, O_NONBLOCK: %d, O_SYNC: %d\n",O_APPEND,O_NONBLOCK,O_SYNC);
if (accmode == O_RDONLY)
printf ("read only\n");
else if (accmode == O_WRONLY)
printf ("write only\n");
else if (accmode == O_RDWR)
printf ("read and write\n");
else
printf ("unknown access mode\n");

if (val & O_APPEND)
printf (", append\n");
if (val & O_NONBLOCK)
printf (", nonblocking\n");
if (val & O_SYNC)
printf (", synchronous write\n");

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


_________________
HP nx 6120,
cpu CM 1.5G,
chip 915GM,
memory 512M,
harddisk 40G 5400rpm。

ubuntu 7.04 feisty,
with beryl, etc.


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2007-04-17 14:36 

注册: 2007-02-14 13:56
帖子: 52
地址: swust
送出感谢: 0 次
接收感谢: 0 次
谢谢 这还是第一次得到如此详细的解答 太让人感动了 真的非常感谢你


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2007-04-17 14:53 

注册: 2007-02-14 13:56
帖子: 52
地址: swust
送出感谢: 0 次
接收感谢: 0 次
那顺便再问一个问题:
这也是copy书中的程序buf.c:
#include <stdio.h>
#include "ourhdr.h"

void pr_stdio(const char *, FILE *);
int
main(void)
{
FILE *fp;

fputs("enter any character\n", stdout);
if (getchar() == EOF)
err_sys("getchar error");
fputs("one line to standard error\n", stderr);

pr_stdio("stdin", stdin);
pr_stdio("stdout", stdout);
pr_stdio("stderr", stderr);

if ( (fp = fopen("/etc/motd", "r")) == NULL)
err_sys("fopen error");
if (getc(fp) == EOF)
err_sys("getc error");
pr_stdio("/etc/motd", fp);
exit(0);
}
void
pr_stdio(const char *name, FILE *fp)
{
printf("stream = %s, ", name);
/* following is nonportable */
if (fp->_flag & _IONBF) printf("unbuffered");
else if (fp->_flag & _IOLBF) printf("line buffered");
else /* if neither of above */ printf("fully buffered");
printf(", buffer size = %d\n", fp->_bufsiz);
}
编译时出错:
buf.c: In function ‘pr_stdio’:
buf.c:31: error: ‘FILE’ has no member named ‘_flag’
buf.c:32: error: ‘FILE’ has no member named ‘_flag’
buf.c:34: error: ‘FILE’ has no member named ‘_bufsiz’
书中作者也提到:结构成员_flag,_bufsiz是作者所使用的系统定义的。那请问我在哪个文件可以看到FILE结构的定义,
我查看了stdio.h文件 好像是没有FIL的定义。
谢谢!!!


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2007-04-17 17:39 

注册: 2005-10-26 22:18
帖子: 31
送出感谢: 0 次
接收感谢: 0 次
1.你看的是哪一版的apue?第一版有点老了,有些api变化了。
(也无怪作者注释中指出这一部分代码是不可移植的)
看第二版吧,2005年的,没有的话我有。
在2005版上,代码如下:

#include "apue.h"

void pr_stdio(const char *, FILE *);
int
main(void)
{
FILE *fp;
fputs("enter any character\n", stdout);
if (getchar() == EOF)
err_sys("getchar error");
fputs("one line to standard error\n", stderr);
pr_stdio("stdin", stdin);
pr_stdio("stdout", stdout);
pr_stdio("stderr", stderr);
if ((fp = fopen("/etc/motd", "r")) == NULL)
err_sys("fopen error");
if (getc(fp) == EOF)
err_sys("getc error");
pr_stdio("/etc/motd", fp);
exit(0);
}
void
pr_stdio(const char *name, FILE *fp)
{
printf("stream = %s, ", name);
/*
* The following is nonportable.
*/
if (fp->_IO_file_flags & _IO_UNBUFFERED)
printf("unbuffered");
else if (fp->_IO_file_flags & _IO_LINE_BUF)
printf("line buffered");
else /* if neither of above */
printf("fully buffered");
printf(", buffer size = %d\n", fp->_IO_buf_end - fp->_IO_buf_base);
}

2。我用的是ubuntu,这些头文件都是源里的包装的。
(05版的apue上的代码采用的流的GNU实现。linux上大都是这个实现。
如果你用的是BSD或者solaris,我就不知道了,自己查一下是如何实现的吧。)
我在我的机器上看到的<stdio.h>里面有这样几句:

#include <libio.h>
..........................
typedef struct _IO_FILE FILE;

可见FILE 其实就是_IO_FILE。后者在<libio.h>有如下定义:

struct _IO_FILE {
int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags/*************************************/

/* The following pointers correspond to the C++ streambuf protocol. */
/* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
char* _IO_read_ptr; /* Current read pointer */
char* _IO_read_end; /* End of get area. */
char* _IO_read_base; /* Start of putback+get area. */
char* _IO_write_base; /* Start of put area. */
char* _IO_write_ptr; /* Current put pointer. */
char* _IO_write_end; /* End of put area. */
char* _IO_buf_base; /* Start of reserve area. */
char* _IO_buf_end; /* End of reserve area. */
/* The following fields are used to support backing up and undo. */
char *_IO_save_base; /* Pointer to start of non-current get area. */
char *_IO_backup_base; /* Pointer to first valid character of backup area */
char *_IO_save_end; /* Pointer to end of non-current get area. */

struct _IO_marker *_markers;

struct _IO_FILE *_chain;

int _fileno;
#if 0
int _blksize;
#else
int _flags2;
#endif
_IO_off_t _old_offset; /* This used to be _offset but it's too small. */

#define __HAVE_COLUMN /* temporary */
/* 1+column number of pbase(); 0 is unknown. */
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];

/* char* _save_gptr; char* _save_egptr; */

_IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};


_________________
HP nx 6120,
cpu CM 1.5G,
chip 915GM,
memory 512M,
harddisk 40G 5400rpm。

ubuntu 7.04 feisty,
with beryl, etc.


页首
 用户资料  
 
6 楼 
 文章标题 :
帖子发表于 : 2007-04-17 17:43 

注册: 2005-10-26 22:18
帖子: 31
送出感谢: 0 次
接收感谢: 0 次
此外,_IO_UNBUFFERED和_IO_LINE_BUF 这两个宏也在<libio.h>中定义

#define _IO_UNBUFFERED 2
......................................
#define _IO_LINE_BUF 0x200


_________________
HP nx 6120,
cpu CM 1.5G,
chip 915GM,
memory 512M,
harddisk 40G 5400rpm。

ubuntu 7.04 feisty,
with beryl, etc.


页首
 用户资料  
 
7 楼 
 文章标题 :
帖子发表于 : 2007-04-18 22:21 

注册: 2007-02-14 13:56
帖子: 52
地址: swust
送出感谢: 0 次
接收感谢: 0 次
用的是第一版的 系统也是ubuntu6.10 按照你给你的程序 顺利通过
谢谢 你的讲解让我茅塞顿开 非常感谢
另外就是如果你有空的话麻烦把你的那本2005第二版的apue发给我一下:lpzgbd@sina.com 谢谢辛苦了


页首
 用户资料  
 
8 楼 
 文章标题 :
帖子发表于 : 2007-04-20 21:04 

注册: 2007-02-14 13:56
帖子: 52
地址: swust
送出感谢: 0 次
接收感谢: 0 次
我已经下了一本第二版的apue了 不过是英文的 哪位想要的话可以发信到lpzgbd@sina.com


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 8 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译