- 论坛徽章:
- 0
|
关于API的返回值类型——一定要耐心检查
http://hi.baidu.com/baiqueniaodu ... 2bd290a1ec9c49.html
关于返回值类型问题
走查代码,发现有人这样使用linux api uint32_t rc = read(fd , ...)
让我这写了多年c的人情何以堪啊,谁搞的就不提了,分析分析这个现象:
先说一下返回值:
关于返回值正常情况下有多重用途:
正确的情况是唯一的:返回读到的数量
错误的情况各有各的错误:各种error
在Linux下面的API定义非常一致,正确的>= 0 ,错误的 < 0
1、最重要的还是人的问题:
做事不够严谨,对细节把握不够,喜欢凭运气猜来猜去,毛毛糙糙
使用API重来都没有仔细看过这个函数的定义,没有看手册的习惯
根本不知道怎么看
哥给新人培训的第一件事情是如何看man
使用vi 光标移至api名字后 shift+k快速打开相关的man page
man 2 or 3 api_name
2、做事情没有研究的态度,很多人做事模模糊糊
对一些概念不清楚如何来明确。
另外对于转型,将负数赋值给无符号数的结果应该知道的,只有杯具一坨。
下面根据手册,来分析常见问题:
# man 2 read
READ(2) Linux Programmer’s Manual READ(2)
NAME
read - read from a file descriptor
SYNOPSIS
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
关于什么叫ssize_t == signed size_t ,很多人弄不清楚类型到底是什么
bits/types.h:# define __SWORD_TYPE int
bits/types.h:# define __SWORD_TYPE long int
bits/typesizes.h:#define __SSIZE_T_TYPE __SWORD_TYPE
bits/types.h:__STD_TYPE __SSIZE_T_TYPE __ssize_t; /* Type of a byte count, or error. */
unistd.h:typedef __ssize_t ssize_t;
根据头文件的搜索以及宏定义推导可以得知,在32 和 64位下面类型可表示的范围是不同的,可以确定其类型,简单的说一定要寻根究底的搞清楚,不然就老老实实的按照下面的说明详细的看一遍,并且理解了。
另外就是使用google baidu之类的来搜索,搞工程的千万不能猜来猜去
DESCRIPTION
read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.
If count is zero, read() returns zero and has no other results. If count is greater than SSIZE_MAX, the result is unspecified.
RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It
is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are
actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal),
or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left
unspecified whether the file position (if any) changes.
ERRORS
EAGAIN The file descriptor fd refers to a file other than a socket and has been marked non-blocking (O_NONBLOCK), and the read would
block.
read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.
If count is zero, read() returns zero and has no other results. If count is greater than SSIZE_MAX, the result is unspecified.
RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It
is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are
actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal),
or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left
unspecified whether the file position (if any) changes.
ERRORS
EAGAIN The file descriptor fd refers to a file other than a socket and has been marked non-blocking (O_NONBLOCK), and the read would
block.
EAGAIN or EWOULDBLOCK
The file descriptor fd refers to a socket and has been marked non-blocking (O_NONBLOCK), and the read would block.
POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so
a portable application should check for both possibilities.
EBADF fd is not a valid file descriptor or is not open for reading.
EFAULT buf is outside your accessible address space.
EINTR The call was interrupted by a signal before any data was read; see signal(7).
EINVAL fd is attached to an object which is unsuitable for reading; or the file was opened with the O_DIRECT flag, and either the
address specified in buf, the value specified in count, or the current file offset is not suitably aligned.
EINVAL fd was created via a call to timerfd_create(2) and the wrong size buffer was given to read(); see timerfd_create(2) for further
information.
EIO I/O error. This will happen for example when the process is in a background process group, tries to read from its controlling
tty, and either it is ignoring or blocking SIGTTIN or its process group is orphaned. It may also occur when there is a low-
level I/O error while reading from a disk or tape.
EISDIR fd refers to a directory.
Other errors may occur, depending on the object connected to fd. POSIX allows a read() that is interrupted after reading some data to
return -1 (with errno set to EINTR) or to return the number of bytes already read.
CONFORMING TO
SVr4, 4.3BSD, POSIX.1-2001. |
|