Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.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
C 如何创建一个临时文件名';并发执行安全吗?_C_Linux_Temporary Files - Fatal编程技术网

C 如何创建一个临时文件名';并发执行安全吗?

C 如何创建一个临时文件名';并发执行安全吗?,c,linux,temporary-files,C,Linux,Temporary Files,在下面的代码中,我需要一个唯一的文件名,用它做一些事情,然后就这样吧。它是关于将.class文件转换为二进制文件的,我们称之为编译 当单独运行或一次运行3次时,它工作正常;但是,当我启动多个进程(例如7个进程)时,我遇到了一些问题,其中一个或多个编译失败 代码如下: #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> static unsign

在下面的代码中,我需要一个唯一的文件名,用它做一些事情,然后就这样吧。它是关于将.class文件转换为二进制文件的,我们称之为编译

当单独运行或一次运行3次时,它工作正常;但是,当我启动多个进程(例如7个进程)时,我遇到了一些问题,其中一个或多个编译失败

代码如下:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

static unsigned int numFiles = 0;
static unsigned long numBytes = 0;

FILE* rawf;
char* raw_file_name_end = ".raw_ujc";
char * rawfilename;

static void byte(unsigned char v){
    if(numBytes) printf(", ");

    printf((numBytes & 0x0F) ? "0x%02X" : "\n\t0x%02X", v);

    fwrite(&v,sizeof(v),1,rawf);

    numBytes++;
}

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

    const char* self = argv[0];
    int c;
    const char* classCvt = 0;
    long len;

    if(argc == 1){

        fprintf(stderr, "USAGE: %s [-c <path_to_classCvt>] <file 1> [<file 2> [ <file 3> [...]]] > result.c\n", self);
        return -1;
    }

    argv++;
    argc--;

    if(argv[0][0] == '-' && argv[0][1] == 'c' && !argv[0][2]){

        classCvt = argv[1];
        argv += 2;
        argc -= 2;
    }

    printf("\nService optimized bytecode = {\n\t");

    while(argc--){
        char* filename = *argv;

        rawfilename = malloc(sizeof(char) * (strlen(filename)-strlen(".class")) + sizeof(char) * strlen(raw_file_name_end)+1);

        strncpy(rawfilename,filename,(strlen(filename)-strlen(".class")));
        strcat(rawfilename,raw_file_name_end);
        fprintf(stderr, "rawfilename after alloc: %s \n", rawfilename);

        if(classCvt){

            char* t;

            filename = tempnam(NULL, NULL);
            if(!filename){
                fprintf(stderr, "%s: failed to create a tempfile: %d\n", self, errno);
                return -10;
            }

            t = malloc(strlen(filename) + strlen(classCvt) + strlen(*argv) + 32);
            if(!t){
                fprintf(stderr, "%s: failed to alloc a small string. This is unlikely\n", self);
                free(t);
                return -11;
            }
            sprintf(t, "%s < %s > %s", classCvt, *argv, filename);

            if(system(t)){

                fprintf(stderr, "%s: system() fail: %d\n", self, errno);
                free(t);
                return -12;
            }
            free(t);
        }
        printf("filename is %s\n",filename);
        FILE* f = fopen(filename, "r");
        rawf = fopen(rawfilename, "wb");


        if(filename != *argv){
            unlink(filename);
            free(filename);
        }

        if(!f){
            fprintf(stderr, "%s: failed to open '%s': %d\n", self, *argv, errno);
            fclose(f);
            return -2;
        }
        if(!f){
            fprintf(stderr, "%s: failed to open '%s': %d\n", self, *argv, errno);
            fclose(f);
            return -2;
        }
        if(fseek(f, 0, SEEK_END)){
            fprintf(stderr, "%s: failed to seek(1) in '%s': %d\n", self, *argv, errno);
            fclose(f);
            return -3;
        }
        len = ftell(f);
        if(len < 0){
            fprintf(stderr, "%s: failed to tell in '%s': %d\n", self, *argv, errno);
            fclose(f);
            return -4;
        }
        if(fseek(f, 0, SEEK_SET)){
            fprintf(stderr, "%s: failed to seek(2) in '%s': %d\n", self, *argv, errno);
            fclose(f);
            return -5;
        }
        if(len > 0x00FFFFFFUL){
            fprintf(stderr, "%s:  file '%s' is %lu bytes, while maximum allowable size is %lu.\n", self, *argv, len, 0x00FFFFFFUL);
            fclose(f);
            return -6;
        }

        byte(len >> 16);
        byte(len >> 8);
        byte(len);

        while((c = fgetc(f)) != EOF){
            byte(c);
        }

        numFiles++;
        fclose(f);
        fclose(rawf);

        argv++;
    }

    byte(0);
    byte(0);
    byte(0);

    printf("\n};\n");

    fprintf(stderr, "%s: processed %u files, producing %lu (0x%lX) bytes of output\n", self, numFiles, numBytes, numBytes);
    fprintf(stderr, "rawfilename at end: %s \n", rawfilename);
    free(rawfilename);

    return 0;
}
#包括
#包括
#包括
#包括
静态无符号整数文件=0;
静态无符号长字节数=0;
文件*rawf;
char*raw_file_name_end=“.raw_ujc”;
char*rawfilename;
静态空字节(无符号字符v){
如果(单位)为printf(“,”);
printf((numBytes&0x0F)-“0x%02X”:“\n\t0x%02X”,v);
fwrite(&v,sizeof(v),1,rawf);
numBytes++;
}
int main(int argc,字符**argv){
常量字符*self=argv[0];
INTC;
常量字符*classCvt=0;
龙伦;
如果(argc==1){
fprintf(stderr,“用法:%s[-c][[…]]]]>result.c\n”,self);
返回-1;
}
argv++;
argc--;
如果(argv[0][0]='-'&&argv[0][1]=='c'&&&!argv[0][2]){
classCvt=argv[1];
argv+=2;
argc-=2;
}
printf(“\n服务优化字节码={\n\t”);
而(argc--){
char*filename=*argv;
rawfilename=malloc(sizeof(char)*(strlen(filename)-strlen(“.class”))+sizeof(char)*strlen(raw\u file\u name\u end)+1;
strncpy(rawfilename,filename,(strlen(filename)-strlen(“.class”));
strcat(原始文件名、原始文件名、原始结束);
fprintf(stderr,“分配后的rawfilename:%s\n”,rawfilename);
if(类别CVT){
char*t;
filename=tempnam(NULL,NULL);
如果(!filename){
fprintf(stderr,“%s:未能创建临时文件:%d\n”,self,errno);
返回-10;
}
t=malloc(strlen(文件名)+strlen(classCvt)+strlen(*argv)+32);
如果(!t){
fprintf(stderr,“%s:分配小字符串失败。这不太可能\n”,self);
自由(t);
返回-11;
}
sprintf(t,“%s<%s>%s”,classCvt,*argv,文件名);
if(系统(t)){
fprintf(stderr,“%s:system()失败:%d\n”,self,errno);
自由(t);
返回-12;
}
自由(t);
}
printf(“文件名为%s\n”,文件名);
文件*f=fopen(文件名,“r”);
rawf=fopen(rawfilename,“wb”);
如果(文件名!=*argv){
取消链接(文件名);
免费(文件名);
}
如果(!f){
fprintf(stderr,“%s:无法打开“%s”:%d\n,self,*argv,errno);
fclose(f);
返回-2;
}
如果(!f){
fprintf(stderr,“%s:无法打开“%s”:%d\n,self,*argv,errno);
fclose(f);
返回-2;
}
if(fseek(f,0,SEEK_END)){
fprintf(stderr,“%s:在“%s”中查找(1)失败:%d\n”,self,*argv,errno);
fclose(f);
返回-3;
}
len=ftell(f);
if(len<0){
fprintf(stderr,“%s:在“%s”中告知失败:%d\n”,self,*argv,errno);
fclose(f);
返回-4;
}
if(fseek(f,0,SEEK_SET)){
fprintf(stderr,“%s:在“%s”中查找(2)失败:%d\n”,self,*argv,errno);
fclose(f);
返回-5;
}
如果(len>0x00FFFFFFUL){
fprintf(stderr,“%s:文件“%s”为%lu字节,而允许的最大大小为%lu。\n”,self,*argv,len,0x00FFFFFFUL);
fclose(f);
返回-6;
}
字节(len>>16);
字节(len>>8);
字节(len);
而((c=fgetc(f))!=EOF){
字节(c);
}
numFiles++;
fclose(f);
fclose(rawf);
argv++;
}
字节(0);
字节(0);
字节(0);
printf(“\n};\n”);
fprintf(stderr,“%s:处理了%u个文件,产生了%lu(0x%lX)字节的输出\n”,self,numFiles,numBytes,numBytes);
fprintf(stderr,“末尾的rawfilename:%s\n”,rawfilename);
免费(rawfilename);
返回0;
}
环顾四周后,人们建议使用
mkstemp()
;但是,正如您所看到的,我确实需要在几个地方使用文件名


我试着调整这个,但总是出错。如何安全地调整此工作方法?

来自
mkstemp

int mkstemp(char *template);
函数的作用是:从模板生成一个唯一的临时文件名,创建并打开文件,并返回文件的打开文件描述符。 模板的最后六个字符必须是“XXXXXX”,并且 替换为使文件名唯一的字符串因为它会 若要修改,模板不能是字符串常量,但应为 声明为字符数组。 该文件是以0600权限创建的,即读加写权限 仅供业主使用。返回的文件描述符提供读和写操作 对文件的写访问权限。文件是用open(2)O_EXCL打开的 标志,保证调用方是创建 文件


因此,如果需要文件名,可以在传递给mkstemp的
模板
参数中找到它。

来自
mkstemp的手册页

int mkstemp(char *template);
函数的作用是:从模板生成一个唯一的临时文件名,创建并打开文件,并返回文件的打开文件描述符。 模板的最后六个字符必须是“XXXXXX”,并且 替换为使文件名唯一的字符串因为它会 若要修改,模板不能是字符串常量,但应为 声明为字符数组。 该文件是以0600权限创建的,即读加写权限