linux之lseek函数解析

时间:2021-10-04 08:42:20

一、

[lingyun@localhost lseek]$ vim lseek.c       

 + lseek.c                                                                                                      
/*********************************************************************************
 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 
 *                  All rights reserved.
 *
 *       Filename:  lseek.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/28/2013~)
 *         Author:  fulinux <fulinux@sina.com>
 *      ChangeLog:  1, Release initial version on "07/28/2013 01:33:51 PM"
 *                 
 ********************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>


#define ERR_EXIT(m)\
    do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)


int main(void)
{
    int fd;


    if(fd = open("file.hole", O_WRONLY|O_CREAT|O_TRUNC, 0644) == -1)
        ERR_EXIT("open error");


    write(fd, "hello", 5);
    /* offset now = 5 */


    if(lseek(fd, 2*1024, SEEK_CUR) == -1)
        ERR_EXIT("lseek error");
    /* offset now = 2*1024 + 5 */


    write(fd, "world\n", 5);
    /* offset now = 2*1024 + 10 */


    close(fd);
    return 0;

}


[lingyun@localhost lseek]$ gcc lseek.c 
[lingyun@localhost lseek]$ ls
a.out  lseek.c
[lingyun@localhost lseek]$ ./a.out 
hellolseek error: Illegal seek
[lingyun@localhost lseek]$ sudo ./a.out 
hellolseek error: Illegal seek
[lingyun@localhost lseek]$ ls
a.out  file.hole  lseek.c
[lingyun@localhost lseek]$ cat file.hole


原因是上面的函数中的红色语句有问题:

因为"<"的优先级大于"=",因此你open那一句实际上把0赋给了fd,所以改成if((fd = open("2.txt",O_RDWR|O_CREAT)) < 0) 就对了

[lingyun@localhost lseek]$ vim lseek.c       
 + lseek.c                                                                                                      
/*********************************************************************************
 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 
 *                  All rights reserved.
 *
 *       Filename:  lseek.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/28/2013~)
 *         Author:  fulinux <fulinux@sina.com>
 *      ChangeLog:  1, Release initial version on "07/28/2013 01:33:51 PM"
 *                 
 ********************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>


#define ERR_EXIT(m)\
    do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)


int main(void)
{
    int fd;


    if((fd = open("file.hole", O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
        ERR_EXIT("open error");


    write(fd, "hello", 5);
    /* offset now = 5 */


    if(lseek(fd, 2*1024, SEEK_CUR) == -1)
        ERR_EXIT("lseek error");
    /* offset now = 2*1024 + 5 */


    write(fd, "world\n", 5);
    /* offset now = 2*1024 + 10 */


    close(fd);
    return 0;
}

[lingyun@localhost lseek]$ gcc lseek.c 
[lingyun@localhost lseek]$ ./a.out 
[lingyun@localhost lseek]$ cat file.hole 
helloworld
[lingyun@localhost lseek]$ du -h file.hole 
4.0K    file.hole
[lingyun@localhost lseek]$ od -c file.hole 
0000000   h   e   l   l   o  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0004000  \0  \0  \0  \0  \0   w   o   r   l   d
0004012
[lingyun@localhost lseek]$ 

二、
[lingyun@localhost lseek_2]$ vim lseek.c
    if(write(fd, buf1, 10) != 10)
/*********************************************************************************
 + lseek.c                                                                                                                          
 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 
 *                  All rights reserved.
 *
 *       Filename:  lseek.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/28/2013~)
 *         Author:  fulinux <fulinux@sina.com>
 *      ChangeLog:  1, Release initial version on "07/28/2013 03:36:38 PM"
 *                 
 ********************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>


char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";


int main(void)
{
    int fd;


    if((fd = creat("file.hole",0644)) < 0)
    {
        perror("creat error");
        exit(EXIT_FAILURE);
    }


    if(write(fd, buf1, 10) != 10)
    {
        perror("write buf1 error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 10 */


    if(lseek(fd, 16384, SEEK_SET) == -1)
    {   
        perror("lseek error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 16384 */


    if(write(fd, buf2, 10) != 10)
    {
        perror("write error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 16394 */


    exit(0);


}
 ~/apue/lseek/lseek_2/lseek.c[+]   CWD: /usr/local/src/lingyun/apue/lseek/lseek_2   Line: 54/56:12                                  
"lseek.c" [New] 56L, 1258C written


[lingyun@localhost lseek_2]$ ls
lseek.c
[lingyun@localhost lseek_2]$ gcc lseek.c 
[lingyun@localhost lseek_2]$ ./a.out 
[lingyun@localhost lseek_2]$ du -h file.hole 
8.0K    file.hole
[lingyun@localhost lseek_2]$ od -c file.hole 
0000000   a   b   c   d   e   f   g   h   i   j  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0040000   A   B   C   D   E   F   G   H   I   J
0040012
[lingyun@localhost lseek_2]$ cat file.hole 
abcdefghijABCDEFGHIJ[lingyun@localhost lseek_2]$ 


三、
下面是把SEEK_CUR改为了SEEK_END,并且offset = -5,得到的结果就是buf2覆盖了buf1后面的5个字符。如下:
[lingyun@localhost lseek_3]$ vim lseek.c 
 + lseek.c                                                                                                                          
/*********************************************************************************
 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 
 *                  All rights reserved.
 *
 *       Filename:  lseek.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/28/2013~)
 *         Author:  fulinux <fulinux@sina.com>
 *      ChangeLog:  1, Release initial version on "07/28/2013 03:36:38 PM"
 *                 
 ********************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>


char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";


int main(void)
{
    int fd;


    if((fd = creat("file.hole",0644)) < 0)
    {
        perror("creat error");
        exit(EXIT_FAILURE);
    }


    if(write(fd, buf1, 10) != 10)
    {
        perror("write buf1 error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 10 */


    if(lseek(fd, -5, SEEK_END) == -1)
    {
        perror("lseek error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 16384 */


    if(write(fd, buf2, 10) != 10)
    {
        perror("write error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 16394 */


    exit(0);


 ~/apue/lseek/lseek_3/lseek.c[+]   CWD: /usr/local/src/lingyun/apue/lseek/lseek_3   Line: 40/56:19                                  
"lseek.c" 56L, 1255C written


[lingyun@localhost lseek_3]$ gcc lseek.c 
[lingyun@localhost lseek_3]$ ./a.out 
[lingyun@localhost lseek_3]$ od -c file.hole 
0000000   a   b   c   d   e   A   B   C   D   E   F   G   H   I   J
0000017
[lingyun@localhost lseek_3]$ 

四、
[lingyun@localhost lseek_3]$ vim lseek.c 
    if(lseek(fd, 0, SEEK_CUR) == -1)
/*********************************************************************************
 + lseek.c                                                                                                                          
 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 
 *                  All rights reserved.
 *
 *       Filename:  lseek.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/28/2013~)
 *         Author:  fulinux <fulinux@sina.com>
 *      ChangeLog:  1, Release initial version on "07/28/2013 03:36:38 PM"
 *                 
 ********************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>


char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";


int main(void)
{
    int fd;


    if((fd = creat("file.hole",0644)) < 0)
    {
        perror("creat error");
        exit(EXIT_FAILURE);
    }


    if(write(fd, buf1, 10) != 10)
    {
        perror("write buf1 error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 10 */


    if(lseek(fd, 0, SEEK_CUR) == -1) 
    {
        perror("lseek error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 16384 */


    if(write(fd, buf2, 10) != 10)
    {
        perror("write error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 16394 */


    exit(0);


}
 ~/apue/lseek/lseek_3/lseek.c[+]   CWD: /usr/local/src/lingyun/apue/lseek/lseek_3   Line: 56/56:1                                   
"lseek.c" 56L, 1254C written


[lingyun@localhost lseek_3]$ ls
a.out  lseek.c
[lingyun@localhost lseek_3]$ gcc lseek.c 
[lingyun@localhost lseek_3]$ ./a.out 
[lingyun@localhost lseek_3]$ od -c file.hole 
0000000   a   b   c   d   e   f   g   h   i   j   A   B   C   D   E   F
0000020   G   H   I   J
0000024
[lingyun@localhost lseek_3]$ 


 
五、
[lingyun@localhost lseek_3]$ vim lseek.c 
 + lseek.c                                                                                                                          
 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 
 *                  All rights reserved.
 *
 *       Filename:  lseek.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/28/2013~)
 *         Author:  fulinux <fulinux@sina.com>
 *      ChangeLog:  1, Release initial version on "07/28/2013 03:36:38 PM"
 *                 
 ********************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>


char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";


int main(void)
{
    int fd;


    if((fd = creat("file.hole",0644)) < 0)
    {
        perror("creat error");
        exit(EXIT_FAILURE);
    }


    if(write(fd, buf1, 10) != 10)
    {
        perror("write buf1 error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 10 */


    if(lseek(fd, 0, SEEK_SET) == -1)
    {
        perror("lseek error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 16384 */


    if(write(fd, buf2, 10) != 10)
    {
        perror("write error");
        exit(EXIT_FAILURE);
    }
    /* offset now = 16394 */


    exit(0);


}
 ~/apue/lseek/lseek_3/lseek.c[+]   CWD: /usr/local/src/lingyun/apue/lseek/lseek_3   Line: 40/56:28                                  
"lseek.c" 56L, 1254C written


[lingyun@localhost lseek_3]$ gcc lseek.c 
[lingyun@localhost lseek_3]$ ./a.out 
[lingyun@localhost lseek_3]$ od -c file.hole 
0000000   A   B   C   D   E   F   G   H   I   J
0000012
[lingyun@localhost lseek_3]$