如何从文件中有效地读取环境参数,与exec一起使用

时间:2014-12-20 09:01:31

标签: c linux environment-variables exec command-line-arguments

我希望能够保存到流程的argv和环境文件,以及以后能够forkexec 使用保存到文件的参数。

我能想到的唯一设计是将参数列表作为长字符串写入文件,但是我需要将它从字符串转换为字符串数组,这可能但非常麻烦。

有人能想出更好的方法吗?

2 个答案:

答案 0 :(得分:1)

我对文件格式的建议

  • 第一行是十进制数N,等于argc
  • 接下来的N行是argv字符串,每行一个字符串
  • 然后是另一个十进制数M,它等于环境字符串的数量
  • 接下来的M行是环境字符串,每行一个字符串

将文件读回内存

  • 使用getline阅读第一行,并使用sscanf
  • 转换数字
  • malloc一组N + 1个指针
  • 使用getline读取下N行,将指针存储在argv数组
  • argv数组
  • 的末尾放置一个NULL指针
  • 使用getline阅读下一行,并使用sscanf
  • 转换数字
  • malloc一组M + 1指针
  • 使用getline读取下一行M行,将指针存储在env数组
  • env数组
  • 的末尾放置一个NULL指针

使用getline时,请注意两件事。首先,它将自动malloc字符串的内存。其次,它将换行符放在字符串的末尾,因此您必须将其删除。

使用argv

读取getline字符串的示例代码
int N = 5;
char **argv = malloc( (N + 1) * sizeof(char *) );

char *line;
size_t linecap, length;

for ( int i = 0; i < N; i++ )
{
    line = NULL;            // request that getline allocate memory
    linecap = 0;
    if ( (length = getline( &line, &linecap, fp )) <= 0 )
        exit( 1 );          // file ended prematurely

    line[length-1] = '\0';  // get rid of the pesky newline
    argv[i] = line;
}

argv[N] = NULL;

答案 1 :(得分:0)

我解决这个问题的方法是编写一个具有以下结构的二进制文件:

begin file header:

  0x00 :: 0x03 [  4 bytes] number of entries

for each entry n at offset 0x04 + n * 4:

  0x00 :: 0x03 [  4 bytes] string length of entry (including terminating \0)

end file header

在标题之后,将所有条目作为字符串写入文件,包括终止\0字节。

要阅读此文件,我会使用fopenfreadfclose从文件中读取偏移数组,然后我会mmap该文件,并将偏移数组转换为指向mmapped区域的指针数组。

便携性注意:

如果您希望能够在一个架构上读取文件并在另一个架构上阅读,则需要

  • 确保使用固定宽度数据类型(例如uint32_tuint64_t
  • 决定字节顺序以避免字节序问题。

所以,比方说,如果你想写一个uint32_t到一个文件,没有你可以使用的字节序问题

void
write_uint32 (FILE *f, uint32_t v)
{
  unsigned char out[4] = { 0 };
  out[0] = v & 0xff; v >>= 8;
  out[1] = v & 0xff; v >>= 8;
  out[2] = v & 0xff; v >>= 8;
  out[3] = v
  fwrite(out, 1, sizeof(out), f);
}

并读取相同的值

uint32_t
read_uint32 (FILE *f)
{
  unsigned char in[4] = { 0 }
  fread(in, 1, sizeof(in), f);
  return in[3] << 24 | in[2] << 16 | in[1] << 8 | in[0];
}