0

我一直试图了解原因,但找不到Invalid Argument使用perror. 任何人都可以提出这个错误的原因吗?

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

int main(int argc,char *argv[])
{ 

    int fd;
    char buffer[255];
    struct flock fvar;

    if(argc==1)
    {
        printf("usage:./a.out filename\n");
        return -1;
    }

    if((fd=open(argv[1],O_RDWR))==-1)
    {
        perror("open");
        exit(1);
    }

    fvar.l_type=F_WRLCK;
    fvar.l_whence=SEEK_END;
    fvar.l_start=SEEK_END-100;
    fvar.l_len=100;

    printf("press enter to set lock\n");
    getchar();
    printf("trying to get lock..\n");

  **if((fcntl(fd,F_SETLK,&fvar))==-1)
    {
         perror("fcntl") ;
         fcntl(fd,F_GETLK,&fvar);**
         printf("\nFile already locked by process (pid): \t%d\n",fvar.l_pid);
         return -1;
    }

    printf("locked\n");

    if((lseek(fd,SEEK_END-50,SEEK_END))==-1)
    {
        perror("lseek");
        exit(1);
    }

    if((read(fd,buffer,100))==-1)
    {
        perror("read");
        exit(1);
    }

    printf("data read from file..\n");
    puts(buffer);
    printf("press enter to release lock\n");

    getchar();

    fvar.l_type = F_UNLCK;
    fvar.l_whence = SEEK_SET;
    fvar.l_start = 0;
    fvar.l_len = 0;

    if((fcntl(fd,F_UNLCK,&fvar))==-1)
    {
        perror("fcntl");
        exit(0);
    }

    printf("Unlocked\n");
    close(fd);

    return 0;
}

我试过检查论点。文件描述符看起来不错,flock 的参数是 double ,triple,quadruple ... 检查次数。我只是不明白问题出在哪里。

4

2 回答 2

2

您正在设置:

fvar.l_type=F_WRLCK;
fvar.l_whence=SEEK_END;
fvar.l_start=SEEK_END-100;
fvar.l_len=100;

fcntl 的手册页(至少在 Linux 上)说:

l_start 是锁的起始偏移量,并且相对于以下任何一个进行解释:文件的开头(如果l_whence 是 SEEK_SET);当前文件偏移量(如果l_whenceSEEK_CUR);或文件的结尾(如果l_whenceSEEK_END)。在最后两种情况下,l_start 如果偏移量不在文件开头之前,则可以是负数。

您正在设置l_startSEEK_END-100. 由于SEEK_END等于 2(同样,在 Linux 上,尽管其他系统可能类似),这意味着您设置l_start为 -98。如果文件长度小于 98 字节,那将在文件开始之前 - 正如手册页所说,这是不允许的。这很可能是EINVAL.

相反,您应该:

  1. 确保您使用的是文件中的偏移量
  2. 不使用SEEK_END-100(or SEEK_END-50)fcntllseek- 这不是它们的工作方式 - 只需使用-100or-50代替。
于 2015-06-05T15:21:59.753 回答
0

如果fvar.l_whence设置为SEEK_END,fvar.l_start是从文件末尾的偏移量。如果您希望锁在结束前 100 个字节开始,那么l_start应该是-100(不是SEEK_END-100)。

于 2015-06-05T15:20:55.867 回答