@remotex точно това е проблема errno си е 0 без да го пипам. И аз си мислех за битовете

Здравейте пак,
За да не ми умре темичката, а и за да дам последен шанс на bob_bob_mara да се изяви, ето моята мисла:
Включването на unistd.h яно е важно за да знае компилатора капабилитито ( български превод

) на систмата. Пример:
Ако компилирам със включен unistd.h, lseek се извиква със следните инструкции:
400638: 8b 45 fc mov -0x4(%rbp),%eax
40063b: ba 01 00 00 00 mov $0x1,%edx
400640: 48 c7 c6 f6 ff ff ff mov $0xfffffffffffffff6,%rsi <- 64-битов регистър 400647: 89 c7 mov %eax,%edi
400649: e8 62 fe ff ff callq 4004b0 <lseek@plt>
А ако го направя без unistd.h се извиква така ( дори и да компилирам с gcc -m64 ):
400642: 8b 45 fc mov -0x4(%rbp),%eax
400645: ba 01 00 00 00 mov $0x1,%edx
40064a: be f6 ff ff ff mov $0xfffffff6,%esi <- 32битов код 40064f: 89 c7 mov %eax,%edi
400651: b8 00 00 00 00 mov $0x0,%eax
400656: e8 55 fe ff ff callq 4004b0 <lseek@plt>
В кода на ядрото четем:
http://lxr.free-electrons.com/source/fs/ext4/file.c#L218http://lxr.free-electrons.com/source/fs/read_write.c#L69http://lxr.free-electrons.com/source/fs/read_write.c#L38Забележете, че е точно както са написали в open group - няма проверка дали offset е отрицателен от началото на файла - ако тази заявка е невалидна, то следва върната стойност да мине през glibc и да се зададе стойност на errno=-върната стойност. Т.е. най-вероятно, ако offset-а е невалиден, то glibc вдига errno.
Нека сега да разширим задачата. Долу е кода на skynet2 :
GeSHi (C):
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
//#include <unistd.h>
#define lseek lseek64
int main(){
int errno_tmp;
int fd = open("file",O_WRONLY|O_TRUNC|O_CREAT);
if (fd < 0 ){
write(2,"Cannot open file\n",17);
return 1;
}
write(fd,"abcde",5);
off_t off = lseek(fd,-10,SEEK_CUR);
errno_tmp = errno;
if ( off < 0 ){
printf("Offset is currently negative: %d !\n",off
);
printf("Errno=%d\n",errno_tmp
);
}
int written_bytes = write(fd,"12345",5);
errno_tmp = errno;
if (written_bytes < 0){
printf("Written bytes is negative. errno=%d\n",errno_tmp
);
}
printf("Written bytes = %d!\n",written_bytes
);
close(fd);
return 0;
}
Компилираме и изпълняваме. Хайде да отгатнем какво има във file?
GeSHi (Bash):
$ ./zad10.exe
Offset is currently negative: -5!
Errno=0
Written bytes = 5!
$ cat file
abcde
^C
### Точно така - cat няма да спре да работи...
$ ll file
-rw-r--r--. 1 ivan ivan 4294967296 Aug 29 18:54 file
### WoW 2^32 размер
$ du file
8 file
### Или не?
А къде точно е "12345"

Интересно е как може да разцъкаме тази ситуация...