Fixed bug when use lseek in fiber mode, because in fiber event lseek is used to check if the given fd is a valid socket.

This commit is contained in:
shuxin   zheng 2024-10-16 17:25:40 +08:00
parent 6600a6ac3b
commit d286be313b
5 changed files with 121 additions and 1 deletions

View File

@ -149,7 +149,7 @@ int event_checkfd(EVENT *ev UNUSED, FILE_EVENT *fe)
/* If we cannot seek, it must be a pipe, socket or fifo, else it /* If we cannot seek, it must be a pipe, socket or fifo, else it
* should be a file. * should be a file.
*/ */
if (lseek(fe->fd, (off_t) 0, SEEK_SET) == -1) { if (lseek(fe->fd, (off_t) 0, SEEK_CUR) == -1) {
switch (errno) { switch (errno) {
case ESPIPE: case ESPIPE:
fe->type = TYPE_SPIPE | TYPE_EVENTABLE; fe->type = TYPE_SPIPE | TYPE_EVENTABLE;

View File

@ -0,0 +1,2 @@
include ../Makefile_cpp.in
PROG = fseek_read

View File

@ -0,0 +1,90 @@
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
class file_reader : public acl::fiber {
public:
file_reader(const char* filepath, int offset, size_t length)
: filepath_(filepath), offset_(offset), length_(length) {}
~file_reader() {}
protected:
// @override
void run() {
acl::ifstream reader;
if (!reader.open_read(filepath_)) {
printf("open_read %s error\r\n", filepath_.c_str());
return;
}
printf("open_read %s ok\r\n", filepath_.c_str());
if (reader.fseek(offset_, SEEK_SET) == -1) {
printf("fseek %s error %s\r\n", filepath_.c_str(), acl::last_serror());
return;
}
char buf[8192];
if (length_ >= sizeof(buf)) {
length_ = sizeof(buf);
} else if (length_ == 0) {
length_ = 10;
}
int ret = reader.read(buf, length_, false);
if (ret <= 0) {
printf("read from %s error\r\n", filepath_.c_str());
return;
}
buf[ret] = 0;
printf("read data: [%s]\r\n", buf);
}
private:
acl::string filepath_;
int offset_;
size_t length_;
};
static void usage(const char* procname) {
printf("usage: %s -h [help] -f file_path -o offset -n length\r\n", procname);
}
int main(int argc, char* argv[]) {
int ch, offset = 0, length = 20;
acl::string filepath;
while ((ch = getopt(argc, argv, "hf:o:n:")) > 0) {
switch (ch) {
case 'h':
usage(argv[0]);
return 0;
case 'f':
filepath = optarg;
break;
case 'o':
offset = atoi(optarg);
break;
case 'n':
length = atoi(optarg);
break;
default:
break;
}
}
acl::acl_cpp_init();
acl::log::stdout_open(true);
if (filepath.empty()) {
usage(argv[0]);
return 1;
}
file_reader reader(filepath, offset, (size_t) length);
reader.start();
acl::fiber::schedule();
return 0;
}

View File

@ -0,0 +1,8 @@
// stdafx.cpp : 只包括标准包含文件的源文件
// master_threads.pch 将成为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
//引用任何所需的附加头文件,而不是在此文件中引用

View File

@ -0,0 +1,20 @@
// stdafx.h : 标准系统包含文件的包含文件,
// 或是常用但不常更改的项目特定的包含文件
//
#pragma once
//#include <iostream>
//#include <tchar.h>
// TODO: 在此处引用程序要求的附加头文件
#include "lib_acl.h"
#include "fiber/libfiber.hpp"
#include "acl_cpp/lib_acl.hpp"
#ifdef WIN32
#define snprintf _snprintf
#endif