I want to know the internal members of the FILE structure, the last ones

When I read pg.176 of the C programming language in K & R, I was very excited. I found all the members of the FILE structure (which I was looking for) and it is just awesome to know how everything works. But guess what, gcc complains, the error is: “FILE does not have a member with the name“ fd. ”This means that everything has changed now, I searched Google, but could not find it. Please help in advance.

I can use fileno () to get the file descriptor, but I don't like working on the level of abstraction.

int main ( int argc, char **argv ){ FILE *fp = fopen ("ct.c", "r"); printf ("%i", fp->fd); return 0; } 
+7
c linux
Jun 20 '13 at 8:44
source share
2 answers

You need to look in the source code of the C library.

Since you mention gcc and Linux, you are probably using GNU libc, which of course is free software.

This file says:

 /* The opaque type of streams. This is the definition used elsewhere. */ typedef struct _IO_FILE __FILE; 

And this file declares the _IO_FILE structure:

 struct _IO_FILE { int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ #define _IO_file_flags _flags /* The following pointers correspond to the C++ streambuf protocol. */ /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ char* _IO_read_ptr; /* Current read pointer */ char* _IO_read_end; /* End of get area. */ char* _IO_read_base; /* Start of putback+get area. */ char* _IO_write_base; /* Start of put area. */ char* _IO_write_ptr; /* Current put pointer. */ char* _IO_write_end; /* End of put area. */ char* _IO_buf_base; /* Start of reserve area. */ char* _IO_buf_end; /* End of reserve area. */ /* The following fields are used to support backing up and undo. */ char *_IO_save_base; /* Pointer to start of non-current get area. */ char *_IO_backup_base; /* Pointer to first valid character of backup area */ char *_IO_save_end; /* Pointer to end of non-current get area. */ struct _IO_marker *_markers; struct _IO_FILE *_chain; int _fileno; #if 0 int _blksize; #else int _flags2; #endif _IO_off_t _old_offset; /* This used to be _offset but it too small. */ #define __HAVE_COLUMN /* temporary */ /* 1+column number of pbase(); 0 is unknown. */ unsigned short _cur_column; signed char _vtable_offset; char _shortbuf[1]; /* char* _save_gptr; char* _save_egptr; */ _IO_lock_t *_lock; #ifdef _IO_USE_OLD_IO_FILE }; 

Most likely, the aforementioned one, coming from a “real” library of production quality, is a little more complicated than the example used in K & R. And of course you cannot use this, since the library is internal and FILE is an opaque type, as they say.

+13
Jun 20 '13 at 8:52
source share

@Unwind's answer is good, but I found another solution for Unix-like systems with GCC.

Unfortunately, C does not support reflection ( Support for reflection in C ), but you can analyze the output of the C preprocessor.




Script source code

 setivolkylany$~/Downloads$ cat script.sh # a tempfile for source code on the C programming language FILE_C=`tempfile` # a tempfile for preprocessor`s output FILE_I=`tempfile` printf "#include \"stdio.h\"\nint main() {return 0;}" > $FILE_C cpp $FILE_C > $FILE_I # parse content of the tempfile for preprocessor`s output # and display only the structure print_it=false while read line; do if [ "$line" == "struct _IO_FILE {" ]; then print_it=true fi; if [ "$print_it" = true ]; then echo $line fi; if [ "$line" == "};" ]; then print_it=false fi; done < $FILE_I # clean tempfiles rm $FILE_C $FILE_I 

Exit

 setivolkylany$~/Downloads$ ./script.sh struct _IO_FILE { int _flags; char* _IO_read_ptr; char* _IO_read_end; char* _IO_read_base; char* _IO_write_base; char* _IO_write_ptr; char* _IO_write_end; char* _IO_buf_base; char* _IO_buf_end; char *_IO_save_base; char *_IO_backup_base; char *_IO_save_end; struct _IO_marker *_markers; struct _IO_FILE *_chain; int _fileno; int _flags2; __off_t _old_offset; unsigned short _cur_column; signed char _vtable_offset; char _shortbuf[1]; _IO_lock_t *_lock; # 293 "/usr/include/libio.h" 3 4 __off64_t _offset; # 302 "/usr/include/libio.h" 3 4 void *__pad1; void *__pad2; void *__pad3; void *__pad4; size_t __pad5; int _mode; char _unused2[15 chrome-remote-desktop_current_amd64.deb data_structures_algorithms_tutorial.pdf dict-uk_ua-3-5-1.oxt getline.c jquery-3.1.1.min.js ld-linux.so (1).2 ld-linux.so.2 Makefile Portable Microsoft Office 2003.exe Python-3.5.2 script.sh teamviewer_12.0.71510_amd64.deb teamviewer_12.0.71510_i386.deb text_editor.zip sizeof (int) - 4 chrome-remote-desktop_current_amd64.deb data_structures_algorithms_tutorial.pdf dict-uk_ua-3-5-1.oxt getline.c jquery-3.1.1.min.js ld-linux.so (1).2 ld-linux.so.2 Makefile Portable Microsoft Office 2003.exe Python-3.5.2 script.sh teamviewer_12.0.71510_amd64.deb teamviewer_12.0.71510_i386.deb text_editor.zip sizeof (void *) - sizeof (size_t)]; }; 



This solution is not very subtle, but rather a reflection of the implementation of the attempt in the C programming language.

0
Mar 06 '17 at 18:44
source share



All Articles