Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;无效参数";论fcntl在C语言中的使用_C_Unix_Systems Programming_Fcntl - Fatal编程技术网

&引用;无效参数";论fcntl在C语言中的使用

&引用;无效参数";论fcntl在C语言中的使用,c,unix,systems-programming,fcntl,C,Unix,Systems Programming,Fcntl,我一直在试图理解原因,但找不到使用peror时给出的无效参数错误的有效原因。有人能提出这个错误的原因吗 #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];

我一直在试图理解原因,但找不到使用
peror
时给出的
无效参数
错误的有效原因。有人能提出这个错误的原因吗

#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;
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{ 
int-fd;
字符缓冲区[255];
结构群fvar;
如果(argc==1)
{
printf(“用法:./a.out文件名\n”);
返回-1;
}
如果((fd=open(argv[1],O_RDWR))=-1)
{
佩罗(“公开”);
出口(1);
}
fvar.l_type=F_WRLCK;
fvar.l_whence=SEEK_END;
fvar.l_start=SEEK_END-100;
fvar.l_len=100;
printf(“按enter键设置锁定\n”);
getchar();
printf(“尝试获取锁..\n”);
**if((fcntl(fd、F_SETLK和fvar))=-1)
{
perror(“fcntl”);
fcntl(fd、F_GETLK和fvar)**
printf(“\n文件已被进程(pid)锁定):\t%d\n”,fvar.l\u pid);
返回-1;
}
printf(“锁定的\n”);
if((lseek(fd,SEEK_END-50,SEEK_END))=-1)
{
perror(“lseek”);
出口(1);
}
如果((读取(fd,缓冲区,100))=-1)
{
佩罗(“阅读”);
出口(1);
}
printf(“从文件读取的数据..\n”);
放置(缓冲);
printf(“按enter键释放锁”);
getchar();
fvar.l_type=F_UNLCK;
fvar.l_whence=搜索集;
fvar.l_start=0;
fvar.l_len=0;
如果((fcntl(fd、F_UNLCK和fvar))=-1)
{
perror(“fcntl”);
出口(0);
}
printf(“未锁定的\n”);
关闭(fd);
返回0;
}

我已经试过核实这些论点。文件描述符看起来不错,flock的参数有双参数、三参数、四参数。。。检查次数。我就是不明白问题出在哪里

如果将
fvar.l\u
设置为
SEEK\u END
fvar.l\u start
是文件末尾的偏移量。如果希望锁在结束前100字节开始,则
l\u start
应为
-100
(而不是
SEEK\u end-100
)。

您正在设置:

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\u
搜索集);当前文件偏移量(如果
l\u那里
SEEK\u CUR
);或 文件的结尾(如果
l\u那里
SEEK\u end
)。在最后两名 在提供偏移量的情况下,
l_start
可以是负数 不在文件开始之前

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

相反,你应该:

  • 确保正在使用文件中的偏移量
  • 不要将
    SEEK_END-100
    (或
    SEEK_END-50
    )用于
    fcntl
    lseek
    -这不是它们的工作方式-只需使用
    -100
    -50

  • 你正在运行它的文件有多长(以字节为单位)?哦,等等,这有关系吗?它工作了,谢谢!这是真的,但由于
    SEEK\u END
    通常是一个小的正整数(在Linux上是2),这意味着代码使用-98作为偏移量,如果文件长度为98字节或更长,这将起作用(尽管它可能不会锁定OP期望的值)。如果文件短于此,则更改为-100的错误较小,但不会删除错误…因此,您的重点不是使用SEEK_END-100(或50),而是使用-100或-50作为偏移集以查找_END,或者只是将偏移更改为SEEK_set?另外,为什么我不能对lseek使用“SEEK_END-50”?您的输入很有帮助。是的,请使用
    -100
    -50
    (或切换到
    SEEK\u SET
    )。您不能对
    lseek()
    使用
    SEEK\u END-50
    ,因为这不是
    SEEK\u END
    的工作原理-您需要对
    whence
    参数使用
    SEEK\u END
    ,而对
    偏移量只使用
    -50
    。很高兴你发现答案很有用:)