i mean, i really got no clue as how does fopen, creates/opens the file...?
is this in assembly or something?
thanks!
i mean, i really got no clue as how does fopen, creates/opens the file...?
is this in assembly or something?
thanks!
yes it is based upon low-level functions
Take for instance a Windows program....
<simplistic>
You call fopen().....this will then relate to a function in your library that will then call an API function (most likely CreateFile())....this will then map to an undocumented "lower level" API function (this might be NTReadFile() or whatever....its undocumented!)....this function may then call other undocumented functions until eventually it reaches the code that does what you want (and yeah this may be assembler....). Also along the way other thigs are done like mapping the file to your process, incrementing usage counts....blah blah blah....
</simplistic>
It depends on the library and how it implements the OS's system calls.....
ah i see, ehm, for instance (because of curiousity), i would like to open a file manually, no help from the standard c libarry or any api, where would i start then?
> where would i start then?
By writing an operating system
Your question has no meaning - if you peel away one API, you just get to another one, until all you have left is directly programming the disk controller using asm instructions.
Problem is, you've lost all sense of a file system at this point - all you have are disk sectors. So you have to write an operating system and a file system, and to make it anything like usable, you create APIs, which kinda defeats the original purpose...
Each 'C' library implements fopen() differently, to hide all the details of the operating system from you. This is so that your code can be made portable from one environment to another.
Code:FOPEN(3) Linux Programmer's Manual FOPEN(3) NAME fopen, fdopen, freopen - stream open functions SYNOPSIS #include <stdio.h> FILE *fopen (const char *path, const char *mode); FILE *fdopen (int fildes, const char *mode); FILE *freopen (const char *path, const char *mode, FILE *stream); DESCRIPTION The fopen function opens the file whose name is the string pointed to by path and associates a stream with it. The argument mode points to a string beginning with one of the following sequences (Additional characters may follow these sequences.): r Open text file for reading. The stream is posi- tioned at the beginning of the file. r+ Open for reading and writing. The stream is posi- tioned at the beginning of the file. w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. a Open for writing. The file is created if it does not exist. The stream is positioned at the end of the file. a+ Open for reading and writing. The file is created if it does not exist. The stream is positioned at the end of the file. The mode string can also include the letter ``b'' either as a third character or as a character between the charac- ters in any of the two-character strings described above. This is strictly for compatibility with ANSI C3.159-1989 (``ANSI C'') and has no effect; the ``b'' is ignored. Any created files will have mode S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH (0666), as modified by the process' umask value (see umask(2). Reads and writes may be intermixed on read/write streams in any order. Note that ANSI C requires that a file posi- tioning function intervene between output and input, unless an input operation encounters end-of-file. (If this condition is not met, then a read is allowed to return the result of writes other than the most recent.) Therefore it is good practice (and indeed sometimes neces- sary under Linux) to put an fseek or fgetpos operation between write and read operations on such a stream. This operation may be an apparent no-op (as in fseek(..., 0L, SEEK_CUR) called for its synchronizing side effect. The fdopen function associates a stream with the existing file descriptor, fildes. The mode of the stream (one of the values "r", "r+", "w", "w+", "a", "a+") must be com- patible with the mode of the file descriptor. The file position indicator of the new stream is set to that belonging to fildes, and the error and end-of-file indica- tors are cleared. Modes "w" or "w+" do not cause trunca- tion of the file. The file descriptor is not dup'ed. The result of applying fdopen to a shared memory object is undefined. The freopen function opens the file whose name is the string pointed to by path and associates the stream pointed to by stream with it. The original stream (if it exists) is closed. The mode argument is used just as in the fopen function. The primary use of the freopen func- tion is to change the file associated with a standard text stream (stderr, stdin, or stdout). RETURN VALUES Upon successful completion fopen, fdopen and freopen return a FILE pointer. Otherwise, NULL is returned and the global variable errno is set to indicate the error. ERRORS EINVAL The mode provided to fopen, fdopen, or freopen was invalid. The fopen, fdopen and freopen functions may also fail and set errno for any of the errors specified for the routine malloc(3). The fopen function may also fail and set errno for any of the errors specified for the routine open(2). The fdopen function may also fail and set errno for any of the errors specified for the routine fcntl(2). The freopen function may also fail and set errno for any of the errors specified for the routines open(2), fclose(3) and fflush(3). SEE ALSO open(2), fclose(3) STANDARDS The fopen and freopen functions conform to ANSI C3.159-1989 (``ANSI C''). The fdopen function conforms to IEEE Std1003.1-1988 (``POSIX.1''). BSD MANPAGE 13 December 1995 1
Asking the right question is sometimes more important than knowing the answer.
Please read the FAQ
C Reference Card (A MUST!)
Pointers and Memory
The Essentials
CString lib
ahh i see, so knowing how computer works + knowing a particular file system + asm then i will have my own fopen() function, hmm.., thanks!!
fopen() is not written in assembly. It is a high-level "wrapper" function provided by your compiler maker, as part of the C/C++ standard.
fopen() performs the necessary setup of the FILE structure, initialization and so forth, and then makes a call to the specified device driver (defined by stream).
Since C came from UNIX, it looks at all device I/O as generic streams. Keyboard, Monitor, drives, are no exception. This simplifies how wrappers are written.
The real magic to file I/O is handled by the device driver-- usually provided by your O/S.
If you wanted to access the drive directly, floppy or HDD, or CD for that matter, without using fopen(), you would make calls to the specific driver.
When the O/S loads, it loads a table of drivers which stay resident while the O/S is operating. Whenever you install new hardware, such as a drive, you always have to either install (from the vendor) or select (from a Windows popup) the driver that will allow the O/S to talk to the device.
You can iterate this list for the device and question, and talk directly to the device via the driver-- in essence, writing your own fopen().
Only if you wanted to write the driver yourself, would you have to understand the geometry of the device itself (sectors, tracks, volumes, etc.)
ehm, so where do i start here? read the instructions of a particular device driver?
Yes, you want to learn how disk drivers are written, or atleast how to call them. You should be able to call the disk driver from C/C++. If not, then assembler.
Below is a pseudo snippet to give you an idea what is on the otherside of the looking glass. Usually a true device driver (not a VB hack) is written like this:
Usually, your compiler should have a header file for dealing with drvices and/or drivers. Just match the _standard_ driver file format and you should be able to call it once you've initialized the appropriate parameters.Code:typedef enum /* Control Codes */ { ioRead = 1, ioWrite, ioFormat, ioSeek, ioControl }; typedef enum /* Error Results */ { errNonde = 0, errFormat = 1000, errBadIO, errDevFull, ErrOverRun, ErrUnderRun, ... ErrBuffNil }; typedef struct ioCntrlBlkStruc /* io Parameter block */ { struct ioCntrlBlkStruc *ioCntrlBlkNext; /* next control block */ long ioCmd; /* command */ long param1; /* first parameter */ long param2; /* second parameter */ long rsrvd1; /* reserved */ long rsrvd2; /* reserved */ }ioCntrlBlk; long Driver(ioCntrlBlk*,unsigned char*); /* Driver prototype */ long Driver(ioCntrlBlk *ioBlkP,unsigned char *buffer) { if(!buffer) return(errBuffNil); switch(ioBlkP->ioCmd) /* What to do? */ { case ioRead: /* read data to buffer */ ... break; case ioWrite: /* output data from buffer */ break; case ioFormat: /* init device at some level */ break; case ioSeek: /* see to location on device */ break; case ioControl /* any other conceivable command */ break; default: /* unkown */ break; }; return(errNone); }
WARNING-- back up your critical data before playing with your disk driver.
---
The calling it would be:
errResult = Driver(&myCtrlBlock,&bufferf);