linux 命令的 C mmap 实现
C mmap implementation for linux command
我有以下代码,基本上重现了 linux 中 wc 命令的功能。我的问题是如何使用 mmap
重写代码?我知道我可以使用 struct stat sb;
然后 char *file_in_memory = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
但我无法让它工作/我不知道如何在 while 循环 while ((n = read(file, buffer, LUNG_BUF - 1)) > 0)
中正确实现它。在我 运行 代码之后的尝试中,它将仅显示值 0.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#define LUNG_BUF 4096
int main(int argc, char** argv)
{
int bytes = 0;
int words = 0;
int newLine = 0;
int max_value; // the maximum of the above three
int dim; // string width of the max value
char buffer[LUNG_BUF];
enum states { WHITESPACE, WORD };
int state = WHITESPACE;
if ( argc !=2 )
{
printf( "No file name\n%s", argv[0]);
}
else
{
int file = open(argv[1], O_RDONLY);
if(file < 0)
{
printf("can not open :%s\n",argv[1]);
}
else
{
char *thefile = argv[1];
size_t n;
while ((n = read(file, buffer, LUNG_BUF - 1)) > 0)
{
buffer[n] = '[=11=]';
char *ptr = buffer;
while (*ptr)
{
bytes++;
if (*ptr == ' ' || *ptr == '\t')
{
state = WHITESPACE;
}
else if (*ptr == '\n')
{
newLine++;
state = WHITESPACE;
}
else
{
if (state == WHITESPACE)
{
words++;
}
state = WORD;
}
ptr++;
}
}
// find out the largest value of all and determine the printed width of it
max_value = newLine;
if (words > max_value)
max_value = words;
if (bytes > max_value)
max_value = bytes;
dim = snprintf(NULL, 0, "%d", max_value);
// print lines, words, bytes and filename aligned to the longest number
printf("%*d %*d %*d %s\n", dim, newLine, dim, words, dim, bytes, thefile);
}
}
}
我正在尝试的脚本:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#define LUNG_BUF 4096
int main(int argc, char** argv)
{
int bytes = 0;
int words = 0;
int newLine = 0;
int max_value; // the maximum of the above three
int dim; // string width of the max value
char buffer[LUNG_BUF];
enum states { WHITESPACE, WORD };
int state = WHITESPACE;
if ( argc !=2 )
{
printf( "No file name\n%s", argv[0]);
}
else
{
int file = open(argv[1], O_RDONLY);
if(file < 0)
{
printf("can not open :%s\n",argv[1]);
}
else
{
char *thefile = argv[1];
size_t n;
struct stat sb;
char *file_in_memory = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
for(int i=0;i<=sb.st_size;i++)
{
buffer[i] = '[=12=]';
char *ptr = buffer;
while (*ptr)
{
bytes++;
if (*ptr == ' ' || *ptr == '\t')
{
state = WHITESPACE;
}
else if (*ptr == '\n')
{
newLine++;
state = WHITESPACE;
}
else
{
if (state == WHITESPACE)
{
words++;
}
state = WORD;
}
ptr++;
}
}
// find out the largest value of all and determine the printed width of it
max_value = newLine;
if (words > max_value)
max_value = words;
if (bytes > max_value)
max_value = bytes;
dim = snprintf(NULL, 0, "%d", max_value);
// print lines, words, bytes and filename aligned to the longest number
printf("%*d %*d %*d %s\n", dim, newLine, dim, words, dim, bytes, thefile);
munmap(file_in_memory, sb.st_size);
close(file);
}
}
}
您在上面发布的代码没有编译并且有很多问题。我在下面整理了一下,希望这会有所帮助。我尽量不改变太多,这样你就可以看到我做了什么。
您实际上并没有调用 stat 并且您传递给 mmap 的 fd 变量不是您用来打开文件的变量。
如果可以的话,我总是会用“-Wall -Werror”编译你的代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main(int argc, char** argv)
{
if ( argc !=2 )
{
printf( "No file name\n%s", argv[0]);
exit(-1);
}
char *fileName = argv[1];
int file = open(fileName, O_RDONLY);
if(file < 0)
{
perror("Error: ");
exit(-1);
}
struct stat sb = {0};
stat(fileName, &sb);
char *filePtr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, file, 0);
if (filePtr == MAP_FAILED)
{
perror("Error:");
exit(-1);
}
int bytes = sb.st_size;
int words = 0;
int newLine = 0;
enum states { WHITESPACE, WORD };
int state = WHITESPACE;
for(size_t pos=0;pos<=sb.st_size;pos++)
{
if (state == WHITESPACE)
{
if (filePtr[pos] == '\n')
{
newLine++;
}
else if ((filePtr[pos] != ' ') && (filePtr[pos] != '\t'))
{
state = WORD;
}
}
else // (state == WORD)
{
if (filePtr[pos] == ' ' || filePtr[pos] == '\t')
{
state = WHITESPACE;
words++;
}
else if (filePtr[pos] == '\n')
{
state = WHITESPACE;
words++;
newLine++;
}
}
}
// Max value is always bytes
int dim = snprintf(NULL, 0, "%d", bytes);
// print lines, words, bytes and filename aligned to the longest number
printf("%*d %*d %*d %s\n", dim, newLine, dim, words, dim, bytes, fileName);
munmap(filePtr, sb.st_size);
close(file);
}
我有以下代码,基本上重现了 linux 中 wc 命令的功能。我的问题是如何使用 mmap
重写代码?我知道我可以使用 struct stat sb;
然后 char *file_in_memory = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
但我无法让它工作/我不知道如何在 while 循环 while ((n = read(file, buffer, LUNG_BUF - 1)) > 0)
中正确实现它。在我 运行 代码之后的尝试中,它将仅显示值 0.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#define LUNG_BUF 4096
int main(int argc, char** argv)
{
int bytes = 0;
int words = 0;
int newLine = 0;
int max_value; // the maximum of the above three
int dim; // string width of the max value
char buffer[LUNG_BUF];
enum states { WHITESPACE, WORD };
int state = WHITESPACE;
if ( argc !=2 )
{
printf( "No file name\n%s", argv[0]);
}
else
{
int file = open(argv[1], O_RDONLY);
if(file < 0)
{
printf("can not open :%s\n",argv[1]);
}
else
{
char *thefile = argv[1];
size_t n;
while ((n = read(file, buffer, LUNG_BUF - 1)) > 0)
{
buffer[n] = '[=11=]';
char *ptr = buffer;
while (*ptr)
{
bytes++;
if (*ptr == ' ' || *ptr == '\t')
{
state = WHITESPACE;
}
else if (*ptr == '\n')
{
newLine++;
state = WHITESPACE;
}
else
{
if (state == WHITESPACE)
{
words++;
}
state = WORD;
}
ptr++;
}
}
// find out the largest value of all and determine the printed width of it
max_value = newLine;
if (words > max_value)
max_value = words;
if (bytes > max_value)
max_value = bytes;
dim = snprintf(NULL, 0, "%d", max_value);
// print lines, words, bytes and filename aligned to the longest number
printf("%*d %*d %*d %s\n", dim, newLine, dim, words, dim, bytes, thefile);
}
}
}
我正在尝试的脚本:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#define LUNG_BUF 4096
int main(int argc, char** argv)
{
int bytes = 0;
int words = 0;
int newLine = 0;
int max_value; // the maximum of the above three
int dim; // string width of the max value
char buffer[LUNG_BUF];
enum states { WHITESPACE, WORD };
int state = WHITESPACE;
if ( argc !=2 )
{
printf( "No file name\n%s", argv[0]);
}
else
{
int file = open(argv[1], O_RDONLY);
if(file < 0)
{
printf("can not open :%s\n",argv[1]);
}
else
{
char *thefile = argv[1];
size_t n;
struct stat sb;
char *file_in_memory = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
for(int i=0;i<=sb.st_size;i++)
{
buffer[i] = '[=12=]';
char *ptr = buffer;
while (*ptr)
{
bytes++;
if (*ptr == ' ' || *ptr == '\t')
{
state = WHITESPACE;
}
else if (*ptr == '\n')
{
newLine++;
state = WHITESPACE;
}
else
{
if (state == WHITESPACE)
{
words++;
}
state = WORD;
}
ptr++;
}
}
// find out the largest value of all and determine the printed width of it
max_value = newLine;
if (words > max_value)
max_value = words;
if (bytes > max_value)
max_value = bytes;
dim = snprintf(NULL, 0, "%d", max_value);
// print lines, words, bytes and filename aligned to the longest number
printf("%*d %*d %*d %s\n", dim, newLine, dim, words, dim, bytes, thefile);
munmap(file_in_memory, sb.st_size);
close(file);
}
}
}
您在上面发布的代码没有编译并且有很多问题。我在下面整理了一下,希望这会有所帮助。我尽量不改变太多,这样你就可以看到我做了什么。
您实际上并没有调用 stat 并且您传递给 mmap 的 fd 变量不是您用来打开文件的变量。 如果可以的话,我总是会用“-Wall -Werror”编译你的代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main(int argc, char** argv)
{
if ( argc !=2 )
{
printf( "No file name\n%s", argv[0]);
exit(-1);
}
char *fileName = argv[1];
int file = open(fileName, O_RDONLY);
if(file < 0)
{
perror("Error: ");
exit(-1);
}
struct stat sb = {0};
stat(fileName, &sb);
char *filePtr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, file, 0);
if (filePtr == MAP_FAILED)
{
perror("Error:");
exit(-1);
}
int bytes = sb.st_size;
int words = 0;
int newLine = 0;
enum states { WHITESPACE, WORD };
int state = WHITESPACE;
for(size_t pos=0;pos<=sb.st_size;pos++)
{
if (state == WHITESPACE)
{
if (filePtr[pos] == '\n')
{
newLine++;
}
else if ((filePtr[pos] != ' ') && (filePtr[pos] != '\t'))
{
state = WORD;
}
}
else // (state == WORD)
{
if (filePtr[pos] == ' ' || filePtr[pos] == '\t')
{
state = WHITESPACE;
words++;
}
else if (filePtr[pos] == '\n')
{
state = WHITESPACE;
words++;
newLine++;
}
}
}
// Max value is always bytes
int dim = snprintf(NULL, 0, "%d", bytes);
// print lines, words, bytes and filename aligned to the longest number
printf("%*d %*d %*d %s\n", dim, newLine, dim, words, dim, bytes, fileName);
munmap(filePtr, sb.st_size);
close(file);
}