我正在使用虚拟机(virutalbox)运行乔恩·埃里克森(Jon Erickson)的第二版“黑客:剥削的艺术”来运行随附的LiveCD(Ubuntu 7.04)。在第0x281节“文件访问”中,作者使用第82-84页上的示例说明了通过文件描述符以及open()close()read()和write()函数访问文件的方法。
simplenote.c的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
void usage(char *prog_name,char *filename){
printf("Usage: %s < data to add to %s>\n",prog_name,filename);
exit(0);
}
void fatal(char *);
void *ec_malloc(unsigned int );
int main(int argc,char *argv[]){
int fd; //file descriptor
char *buffer,*datafile;
buffer = (char *)ec_malloc(100);
datafile = (char *)ec_malloc(20);
strcpy(datafile,"/tmp/notes");
if(argc < 2)
usage(argv[0],datafile);
strcpy(buffer,argv[1]);
printf("[DEBUG] buffer @ %p:\'%s'\n",buffer,buffer);
printf("[DEBUG] datafile @ %p:\'%s'\n",datafile,datafile);
strncat(buffer,"\n",1);//Add a newline on the end.
fd = open(datafile,O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR);
if(fd == -1)
fatal("in main() while opening file");
printf("[DEBUG] file descriptor is %d\n",fd);
//Writing data
if(write(fd,buffer,strlen(buffer)) == -1)
fatal("in main() while writing buffer to file");
//Closing file
if(close(fd) == -1)
fatal("in main() while closing file");
printf("Note has been saved.\n");
free(buffer);
free(datafile);
}
//A function to display an error message and then exit
void fatal(char *message){
char error_message[100];
strcpy(error_message,"[!!]Fatal Error");
strncat(error_message,message,83);
perror(error_message);
exit(-1);
}
//An error-checked malloc() wrapper function
void *ec_malloc(unsigned int size){
void *ptr;
ptr = malloc(size);
if(ptr == NULL)
fatal("in ec_malloc() on memory allocation");
return ptr;
}
但是,当我在终端窗口中输入本书中所述的以下说明时,它会返回以下错误消息:
reader@hacking:~/booksrc $ gcc -o simplenote simplenote.c
In file included from /usr/include/sys/stat.h:105, from simplenote.c:6:
/usr/include/bits/stat.h:70: error: field 'st_atim' has incomplete type
/usr/include/bits/stat.h:71: error: field 'st_mtim' has incomplete type
/usr/include/bits/stat.h:72: error: field 'st_ctim' has incomplete type
simplenote.c: In function 'main':
simplenote.c:35: error: 'O-WRONLY' undeclared (first use in this function)
simplenote.c:35: error: (Each undeclared identifier is reported only once
simplenote.c:35: error: for each function it appears in.)
simplenote.c:35: error: 'O_CREAT' undeclared (first use in this function)
simplenote.c:35: error: 'O_APPEND' undeclared (first use in this function)
这是sys / stat.h第105行:
#include <bits/stat.h>
这是bits / stat.h第63-83行:
#ifdef __USE_MISC
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
identifier 'timespec' to appear in the <sys/stat.h> header.
Therefore we have to handle the use of this header in strictly
standard-compliant sources special. */
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
# define st_atime st_atim.tv_sec /* Backward compatibility */
# define st_mtime st_mtim.tv_sec
# define st_ctime st_ctim.tv_sec
#else
__time_t st_atime; /* Time of last access. */
unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
unsigned long int st_ctimensec; /* Nsecs of last status change. */
#endif
我想这可能对第一组问题有用:
C++ system file bits/stat.h suddenly breaks with "error: field ‘st_atim’ has incomplete type"
/usr/include/time.h
cat time.h
在我的终端窗口中什么也没做。
这是simplenote.c主要功能行1-6、34-35:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
// Opening the file
fd = open(datafile, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
我猜想开放函数问题源自fcntl.h吗?
由于作者提供的代码错误,我似乎总是遇到问题。我不想一直依靠stackoverflow社区来寻求帮助,因此对于您以后对检查和解决这些问题的新手有何建议?
谢谢。
最佳答案
将选择的评论转换为半连贯的答案。
您可能应该显式启用POSIX定义。将-D_XOPEN_SOURCE=700
添加到命令行,或者在第一个#define _XOPEN_SOURCE 700
之前添加#include
,看看是否可以解决任何问题。但是,您不应该遇到问题。标头应该是独立的。
哦,但是Ubuntu 7.04是过时的……您可能需要使用600而不是700。它是什么时候发布的(该书何时出版)?如果是2009年或更早,则可能需要较旧的版本(600)。看到错误仍然令人惊讶。您指定的命令行不包含通常会引起麻烦的选项(例如-ansi -pedantic
或-std=c99 -pedantic
)。您也可以尝试使用-std=gnu99
。它可能会更好。
您最近有一个类似的问题(gcc -o stdlib.h syntax error c Hacking the Art of Exploitation)。你解决了吗?听起来好像Live CD上的编译系统不是自相干的,或者您使用它的方式意味着它没有自相干的行为。您确定编译系统有效吗?它似乎是半失效的。是否以某种方式使用了错误的标题?
我可以通过在#include <stdint.h>
之前插入#include <stdlib.h>
来解决先前的问题
我将尝试-D_XOPEN_SOURCE=600
并回复您。编译系统一定有问题。
好吧,您可能需要在<time.h>
之前包含<sys/time.h>
(或者可能是<sys/stat.h>
),但是<sys/stat.h>
标头会被破坏(如果可行)。如果必须在包含<stdlib.h>
之前添加<stdint.h>
,则#include <sys/types.h>
标头会损坏。我想Ubuntu 7.04可能太旧了,以至于您应该在许多头文件之前使用<stdlib.h>
,但这仍然不是#include <sys/types.h>
的借口。那应该是独立的。 POSIX 1997在<sys/stat.h>
之前需要st_atim
; POSIX 2004没有。而且我不认为Ubuntu 7.04这么老。
但是请注意,st_atime
成员是新成员。它已添加到POSIX 2008(因此在POSIX 2013中)。之前只是st_atime
(现在st_atim.tv_sec
现在是-D_XOPEN_SOURCE=600
的宏)。
包括<stdio.h>
处理的bit stat问题。 Ubuntu 7.04于2007年发布,而我正在使用的书的第二版于2008年问世。此外,不确定这是否有用,但在另一个包含<string.h>
和<stdio.h>
的示例中(相对(仅-DXOPEN_SOURCE=600
),则代码无需任何干预即可正常运行。
有趣的……它将使您的生活变得有趣,而生活不必变得有趣。 (想到“像你这样一个有趣的时代”这样的中国诅咒。)在所有合辑中都使用-std=gnu99
选项,但要保持手指交叉;可以很好地解决您的大多数问题。考虑同时使用或代替。运气好的话,其中一个或两个都可以解决大多数问题。
关于c - stat.h文件访问文件描述符open()黑客利用艺术,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31622726/