gpt4 book ai didi

c - 如何创建一个可以安全并发执行的临时文件名?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:33:59 26 4
gpt4 key购买 nike

在下面的代码中,我需要一个唯一的文件名,用它做一些事情,让它成为现实。它是关于将 .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;
}

环顾四周,人们推荐使用mkstemp();但是,如您所见,我实际上确实在几个地方需要文件名。

我尝试对此进行调整,但一直遇到错误。我怎样才能安全地调整这种工作方式?

最佳答案

来自 mkstemp 的联机帮助页

int mkstemp(char *template);

The mkstemp() function generates a unique temporary filename from template, creates and opens the file, and returns an open file descriptor for the file. The last six characters of template must be "XXXXXX" and these are replaced with a string that makes the filename unique. Since it will be modified, template must not be a string constant, but should be declared as a character array. The file is created with permissions 0600, that is, read plus write for owner only. The returned file descriptor provides both read and write access to the file. The file is opened with the open(2) O_EXCL flag, guaranteeing that the caller is the process that creates the file.

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

关于c - 如何创建一个可以安全并发执行的临时文件名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43200889/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com