请问一个pwrite函数的问题?

maoloverme1 2012-09-27 10:43:42
我在32位的linux下写了一个程序,程序代码如下:
#define _FILE_OFFSET_BITS 64
#define __USE_FILE_OFFSET64
#define __USE_LARGEFIILE64
#define _LARGEFILE64_SOURCE
#include <unistd.h>
#include <stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
int main()
{
int fd;
int count = 128;
off_t offset = 0X80000000;
int ret;
char buf[1024]="hi ! this is pwrite.";
char pathname[128] = "/tmp/1.txt";
fd = open( pathname, O_WRONLY);
printf("size of off_t is %d\n",sizeof(off_t));

if((ret = pwrite(fd, buf, count, offset))==-1)
{
printf("errno = %d\n",errno);
printf("pwrite error\n");
exit(1);
}
else
{
printf("pwrite success\n");
printf("the writed data is:%s", buf);
}

return 0;
}
但是pwrite函数返回-1,errorno是22,但是我把 0X80000000设为0X7fffffff,就很正常。请问这是什么原因?如何解决这个问题?谢谢!
...全文
572 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuv25 2012-09-27
  • 打赏
  • 举报
回复
版本:redhat linux
加上以下代码就是8
------------------------------
#define _FILE_OFFSET_BITS 64
#define __USE_FILE_OFFSET64
#define __USE_LARGEFIILE64
#define _LARGEFILE64_SOURCE
------------------------------

没加就是4.

[Quote=引用 5 楼 的回复:]

楼上的是啥版本?至少我的ubuntu 32位是4...

引用 4 楼 的回复:

ff_t就是long long
printf("size of off_t %d\n", sizeof(off_t));
输出:size of off_t 8

引用 3 楼 的回复:

你32位linux, off_t就是long
printf("size of off_t %d\n"……
[/Quote]
maoloverme1 2012-09-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
楼上的是啥版本?至少我的ubuntu 32位是4...


引用 4 楼 的回复:

ff_t就是long long
printf("size of off_t %d\n", sizeof(off_t));
输出:size of off_t 8

引用 3 楼 的回复:

你32位linux, off_t就是long
printf("size of off_t %d\n",……
[/Quote]
你加了这几句话没有:
#define _FILE_OFFSET_BITS 64
#define __USE_FILE_OFFSET64
#define __USE_LARGEFIILE64
#define _LARGEFILE64_SOURCE
没有加的话就是4
nevil 2012-09-27
  • 打赏
  • 举报
回复
楼上的是啥版本?至少我的ubuntu 32位是4...

[Quote=引用 4 楼 的回复:]

ff_t就是long long
printf("size of off_t %d\n", sizeof(off_t));
输出:size of off_t 8

引用 3 楼 的回复:

你32位linux, off_t就是long
printf("size of off_t %d\n", sizeof(off_t));
输出:size of off_t 4

引用 2 楼……
[/Quote]
xuv25 2012-09-27
  • 打赏
  • 举报
回复
ff_t就是long long
printf("size of off_t %d\n", sizeof(off_t));
输出:size of off_t 8

[Quote=引用 3 楼 的回复:]

你32位linux, off_t就是long
printf("size of off_t %d\n", sizeof(off_t));
输出:size of off_t 4

引用 2 楼 的回复:

引用 1 楼 的回复:
因为off_t数据类型是带符号的,0X80000000最高位是1,所以是个负值,偏移位值到文件起始以外了,所以返回无效参数

现在off_t是64位的……
[/Quote]
nevil 2012-09-27
  • 打赏
  • 举报
回复
你32位linux, off_t就是long
printf("size of off_t %d\n", sizeof(off_t));
输出:size of off_t 4

[Quote=引用 2 楼 的回复:]

引用 1 楼 的回复:
因为off_t数据类型是带符号的,0X80000000最高位是1,所以是个负值,偏移位值到文件起始以外了,所以返回无效参数

现在off_t是64位的啊!
[/Quote]
maoloverme1 2012-09-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
因为off_t数据类型是带符号的,0X80000000最高位是1,所以是个负值,偏移位值到文件起始以外了,所以返回无效参数
[/Quote]
现在off_t是64位的啊!
nevil 2012-09-27
  • 打赏
  • 举报
回复
因为off_t数据类型是带符号的,0X80000000最高位是1,所以是个负值,偏移位值到文件起始以外了,所以返回无效参数
nevil 2012-09-27
  • 打赏
  • 举报
回复
某些条件下pwrite和pwrite64是一样的,如下红色
但是#if defined __USE_UNIX98 || defined __USE_XOPEN2K8这个条件不满足的话pwrite和pwrite64是不同的,pwrite只接收32位的off_t

#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
# ifndef __USE_FILE_OFFSET64
/* Read NBYTES into BUF from FD at the given position OFFSET without
changing the file pointer. Return the number read, -1 for errors
or 0 for EOF.

This function is a cancellation point and therefore not marked with
__THROW. */
extern ssize_t pread (int __fd, void *__buf, size_t __nbytes,
__off_t __offset) __wur;

/* Write N bytes of BUF to FD at the given position OFFSET without
changing the file pointer. Return the number written, or -1.

This function is a cancellation point and therefore not marked with
__THROW. */
extern ssize_t pwrite (int __fd, __const void *__buf, size_t __n,
__off_t __offset) __wur;
# else
# ifdef __REDIRECT
extern ssize_t __REDIRECT (pread, (int __fd, void *__buf, size_t __nbytes,
__off64_t __offset),
pread64) __wur;
extern ssize_t __REDIRECT (pwrite, (int __fd, __const void *__buf,
size_t __nbytes, __off64_t __offset),
pwrite64) __wur;
# else
# define pread pread64
# define pwrite pwrite64

# endif
# endif
maoloverme1 2012-09-27
  • 打赏
  • 举报
回复
用pwrite64可以了,但是请问为什么pwrite不行呢?
nevil 2012-09-27
  • 打赏
  • 举报
回复
建议直接使用pwrite64()
maoloverme1 2012-09-27
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
根据楼主的错误,必然是楼主的机器off_t是4字节,没啥好争论的
[/Quote]
可是我用sizeof(off_t)打出的值是8啊。为什么你说是4呢?
maoloverme1 2012-09-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
根据如下定义,32位系统下off_t的长度最主要是看你是否定义了#define _FILE_OFFSET_BITS 64

通常情况下没定义的话off_t就是4个字节,而在python/mysql等一些软件里自定义了
/usr/include/python2.6/pyconfig.h:#define _FILE_OFFSET_BITS 64
/usr/include/mysql/my_co……
[/Quote]
那为什么off_t的大小为64位,pwrite在offset=0X80000000的情况下会返回-1?
nevil 2012-09-27
  • 打赏
  • 举报
回复
根据楼主的错误,必然是楼主的机器off_t是4字节,没啥好争论的
nevil 2012-09-27
  • 打赏
  • 举报
回复
根据如下定义,32位系统下off_t的长度最主要是看你是否定义了#define _FILE_OFFSET_BITS 64

通常情况下没定义的话off_t就是4个字节,而在python/mysql等一些软件里自定义了
/usr/include/python2.6/pyconfig.h:#define _FILE_OFFSET_BITS 64
/usr/include/mysql/my_config.h:#define _FILE_OFFSET_BITS 64

所以python/mysql里里使用起来就是8个字节的

/usr/include/features.h
#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
# define __USE_FILE_OFFSET64 1
#endif

/usr/include/unistd.h
# ifndef __off_t_defined
# ifndef __USE_FILE_OFFSET64
typedef __off_t off_t;
# else
typedef __off64_t off_t;
# endif
# define __off_t_defined
# endif

本书以当前UNIX规范为基础,详细介绍了UNIX系统函数的用法,并用大量的代码和示例程序进行演示,对实际编程具有指导意义。全书共9章,内容包括:基本概念、基本文件I/O、高级文件I/0、终端I/O、进程与线程、基本进程间通信、高级进程间通信、网络技术与套接字,以及信号与定时器等。涉及POSIX、FreeBSD、Solaris、Linux等几大主流系统实现。每章末都给出一了些练习,一些是简单的程序设计问题,还有一些可以作为学期的UNIX程序设计项目。 本书适合广大UNIX和c程序员、研究人员、高校相关专业师生学习和参考。 目录 出版者的话 专家指导委员会 译者序 前言 第1章 基本概念 1.1 UNIX和Linux一览 1.2 UNIX的版本 1.3 使用系统调用 1.4 错误处理 1.5 UNIX标准 1.6 共享头文件 1.7 日期和时间 1.8 关于示例代码 1.9 必要的资源 练习 第2章 基本文件I/0系统调用 2.1 概述 2.2 文件描述符及打开文件描述 2.3 文件权限位符号 2.4 open和creat系统调用 2.5 umask系统调用 2.6 unlink系统调用 2.7 创建临时文件 2.8 文件偏移量和O_APPEND 2.9 write系统调用 2.10 read系统调用 2.11 close系统调用 2.12 用户缓冲I/O 2.13 iseek系统调用 2.14 pread和pwrite系统调用 2.15 ready和writev系统调JFf】 2.16 同步I/O 2.17 truncate和ftruncate系统调用 练习 第3章 高级文件I/O 3.1 概述 3.2 磁盘特殊文件和文件系统 3.3 硬链接和符号链接 3.4 路径名 3.5 访问和显示文件元数据 3.6 目录 3.7 改变信息节点 3.8 其他的文件处理调用 3.9 异步I/O 练习 第4章 终端I/0 4.1 概述 4.2 从终端读取数据 4.3 会话和进程组(作业) 4.4 ioctl系统调用 4.5 设置终端属性 4.6 其他终端控制系统调用 4.7 终端识别系统调用 4.8 全屏应用程序 4.9 流I/O 4.10 伪终端 练习 第5章 进程和线程 5.1 概述 5.2 环境 5.3 exeo系统调用 5.4 实现shell(版本1) 5.5 fork系统调用 5.6 实现shell(版本2) 5.7 exit系统调用和进程终止 5 8 wait、waitpid和waitid系统调用 5.9 信号、终止和等待 5.10 实现shell(版本3) 5.11 获得用户ID和组ID 5.12 设置用户ID和组ID 5.13 获得进程ID 5.14 chroot系统调用 5.15 获得并设置优先级 5.16 进程限制 5.17 线程介绍 5.18 阻塞问题 练习 第6章 基本的进程间通信 6.1 概述 6.2 管道 6.3 dup和dup2系统调用 6.4 一个真正的shell 6.5 非重定向管道的双向通信 6.6 用双向管道进行双向通信 练习 第7章 高级进程间通信 7.1 概述 7.2 FIFO或命名管道 7.3 抽象的简单消息接口(sMI) 7.4 SystemVIPC 7.5 System V消息队列 7.6 POSIX IPC 7.7 POSIX消息队列 7.8 关于信号量 7.9 System V信号量 7.10 POSIX信号量 7.11 文件锁 7.12 关于共享内存 7.13 System V共享内存 7.14 POSIX共享内存 7.15 性能比较 练习 第8章 网络和套接字 8.1 套接字基础 8.2 套接字地址 8.3 套接字选项 8.4 简单套接字接口 8.5 SMI套接字实现 8.6 无连接套接字 8.7 带外数据 8.8 网络数据库函数 8.9 其他系统调用 8.10 高性能方面的考虑 练习 第9章 信号和定时器 9.1 信号的基本概念 9.2 等待信号 9.3 其他信号系统调用 9.4 不赞成使用的信号系统调用 9.5 实时信号扩展 9.6 全局跳转 9.7 时钟和定时器 练习 附录A 进程属性 附录B ux:一个对标准uNIx函数进行包装的程序 附录c Jtux:标准UNIX函数的Java/Jython接口 附录D 函数字母速查表及其分类表 参考文献

23,110

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧