0

我正在尝试创建一个带有日志条目的目录mkstemp。但是,据我了解,我不能将字符串常量传递给mkstemp. 我为字符串分配内存并用于snprintf格式化我认为可以工作但mkstemp将 errno 设置为 EINVAL 的负值。

但是,在 linux手册中,mkstemp它清楚地说明了:

EINVAL 对于 mkstemp() 和 mkostemp():模板的最后六个字符不是 XXXXXX;现在模板没有改变。

此外,mkstemp从不修改我的动态字符串。

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

#define LOG_DIR "/tmp"

int main(int argc, char **argv) {
  char *fname;
  FILE *fp;

  if(argc != 3) {
    fprintf(stderr, "Usage: %s <msg> <severity>\n", argv[0]);
    return 0;
  }

  int length = snprintf(NULL, 0, "%s/log_entry.XXXXXX", LOG_DIR); // snprintf returns the required length for my string
  if(length < 0) {
    perror("snprintf failed");
    return 1;
  }
  fname = malloc(sizeof(char) * length); // allocate memory for fname based on the return value of snprintf
  snprintf(fname, length, "%s/log_entry.XXXXXX", LOG_DIR); // send formatted output into fname

  int fd = mkstemp(fname); // this returns -1 and errno is set to 22
  if(fd < 0) {
    perror("failed to create entry file");
    return 1;
  }
  fp = fdopen(fd, "w");
  if(fp == NULL) {
    perror("failed to open entry file");
    return 1;
  }
  fprintf(fp, "\"%s\" %d ",argv[1], atoi(argv[2]));
  fflush(fp);
  fclose(fp);
  free(fname);
  return 0;
}

这个片段在我的两台 Linux 机器上都出现了一个错误,但是如果我删除动态分配的字符串并明确设置fname它可以工作

char fname[] = "/tmp/log_entry.XXXXXX";
4

2 回答 2

2
fname = malloc(sizeof(char) * length);

应该:

fname = malloc(sizeof(char) * (length + 1)); 

现在

snprintf(fname, length+1, "%s/log_entry.XXXXXX", LOG_DIR); 

将创建文件名。在您的版本中,文件名没有以 6 'X' 结尾,这导致mkstemp失败。

于 2015-10-24T13:27:06.923 回答
1
 fname = malloc(sizeof(char) * length); 

你把它填满,不留空间'\0'。:为空终止符留一个空间 -

 fname = malloc(sizeof(char) *(length+1)); 

然后将长度snprintf也增加到length+1

于 2015-10-24T13:26:59.227 回答