|< C Run-Time 2 | Main | C Run-Time 4 >| Site Index | Download |


 

MODULE B

IMPLEMENTATION SPECIFIC

MICROSOFT C Run-Time 3

 

 

 

 

My Training Period:      hours

 

Note:

This Module is a continuation from the previous one.  Program examples, compiled using Visual C++ .Net (Visual studio .Net 2003).  It is low-level programming and the .Net used is Unmanaged (/clr is not set: Project menu → your_project_name Properties… sub menu → Configuration Properties folder → General subfolder → Used Managed Extension setting set to No).  All programs are in debug mode, run on Windows 2000 and Xp Pro.

 

Abilities

 

         Able to recognize the standard and implementation specific C.

         Able to find and collect the required and related information in order to use functions to accomplish your tasks.

         Able to understand and use functions that available in the libraries in your own programs.

 

File-Handling Functions (Open File)

 

-      The following functions used to open files.

 

Function

Use

fopen()

Opens a file and returns a pointer to the open file.

_fsopen()

Open a stream with file sharing and returns a pointer to the open file.

_open()

Opens a file and returns a file handle to the opened file.

_sopen()

Open a file with file sharing and returns a file handle to the open file.

_fdopen()

Associates a stream with a file that was previously opened for low-level I/O and returns a pointer to the open stream.

_fileno()

Gets the file handle associated with a stream and returns the file handle.

_open_osfhandle()

Associates a C run-time file handle with an existing operating-system file handle and returns a C run-time file handle.

_pipe()

Creates a pipe for reading and writing.

freopen()

Reassign a file pointer.

 

Table 1:  File opening functions.

 

-      The following Table is an example of the needed information for fopen() and wfopen() functions.

 

Information

Description

The function

fopen(), wfopen().

The use

Open a file.

The prototype

FILE *fopen( 
   const char *filename,
   const char *mode);
 
 
/*For wide character*/
FILE *_wfopen( 
   const wchar_t *filename,
   const wchar_t *mode);

Example

char fname[30] = "C:\\testfile.txt";

fopen(fname, "r");

The parameters

filename – The filename.

mode - Type of access permitted.

The return value

Each of these functions returns a pointer to the open file.  A null pointer value indicates an error.

The header file

<stdio.h> or <wchar.h> (for _wopen())

 

Table 2:  fopen() and wfopen() function information.

 

-      The fopen() function opens the file specified by filename_wfopen() is a wide-character version of fopen() and the arguments to _wfopen() are wide-character strings.

-      _wfopen() and fopen() behave identically otherwise.

-      The character string mode specifies the type of access requested for the file, as follows:

 

mode

"r"

Opens for reading. If the file does not exist or cannot be found, the fopen() call fails.

"w"

Opens an empty file for writing.  If the given file exists, its contents are destroyed.

"a"

Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn't exist.

"r+"

Opens for both reading and writing, the file must exist.

"w+"

Opens an empty file for both reading and writing.  If the given file exists, its contents are destroyed.

"a+"

Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn't exist.

The following characters can be included in mode to specify the translation mode for newline characters:

t

Open in text (translated) mode. In this mode, CTRL+Z is interpreted as an end-of-file character on input.  In files opened for reading/writing with "a+", fopen() checks for a CTRL+Z at the end of the file and removes it, if possible.  This is done because using fseek() and ftell() to move within a file that ends with a CTRL+Z, may cause fseek() to behave improperly near the end of the file.

b

Open in binary (un-translated) mode; translations involving carriage-return and linefeed characters are suppressed.

c

Enable the commit flag for the associated filename so that the contents of the file buffer are written directly to disk if either fflush() or _flushall() is called.

n

Reset the commit flag for the associated filename to "no-commit".  This is the default.  It also overrides the global commit flag if you link your program with commode.obj. The global commit flag default is "no-commit" unless you explicitly link your program with commode.obj.

S

Specifies that caching is optimized for, but not restricted to, sequential access from disk.

R

Specifies that caching is optimized for, but not restricted to, random access from disk.

T

Specifies a file as temporary.  If possible, it is not flushed to disk.

D

Specifies a file as temporary.  It is deleted when the last file pointer is closed.

 

Table 3:  File type of access, mode.

 

-      To learn more about standard C for file I/O goes C File I/O and for C++ goes C++ File I/O.  Get the big picture of the standard and implementation specific for the file I/O and other topics in C and C++ as well.

-      The following Table is an example of the needed information for _sopen() and _wsopen() functions.

 

Information

Description

The function

_sopen(), _wsopen().

The use

Open a file for sharing.

The prototype

int _sopen(
   const char *filename,
   int oflag,
   int shflag [,
   int pmode ]);
 
/*For wide character*/
int _wsopen(
   const wchar_t *filename,
   int oflag,
   int shflag [,
   int pmode ]);

Example

char fname[50] = C:\\testfile.txt;

int _sopen(fname, _O_CREAT, _SH_DENYNO, _S_IWRITE);

The parameters

filename – The filename.

oflag - Type of operations allowed.

shflag - Type of sharing allowed.

pmode - Permission setting.

The return value

Each of these functions returns a file descriptor for the opened file.  A return value of –1 indicates an error, in which case errno is set to one of the following values:

EACCES - Given path is a directory, or file is read-only, but an open-for-writing operation was attempted.

EEXIST - _O_CREAT and _O_EXCL flags were specified, but filename already exists.

EINVAL - Invalid oflag or shflag argument.

EMFILE - No more file descriptors available.

ENOENT - File or path not found.

The header file

<io.h> or <wchar.h> (for _wsopen())

 

Table 4:  _sopen() and _wsopen() functions information.

 

-      oflag is an integer expression formed from one or more of the following manifest constants or constant combinations that defined in fcntl.h.

 

oflag

Description

_O_APPEND

Moves file pointer to end of file before every write operation.

_O_BINARY

Opens file in binary (untranslated) mode.

_O_CREAT

Creates and opens new file for writing. Has no effect if file specified by filename exists.  pmode argument is required when _O_CREAT is specified.

_O_CREAT | _O_SHORT_LIVED

Create file as temporary and if possible do not flush to disk.  pmode argument is required when _O_CREAT is specified.

_O_CREAT | _O_TEMPORARY

Create file as temporary; file is deleted when last file handle is closed.  pmode argument is required when _O_CREAT is specified.

_O_CREAT | _O_EXCL

Returns error value if file specified by filename exists.  Applies only when used with _O_CREAT.

_O_RANDOM

Specifies that caching is optimized for, but not restricted to, random access from disk.

_O_RDONLY

Opens file for reading only; cannot be specified with _O_RDWR or _O_WRONLY.

_O_RDWR

Opens file for both reading and writing; you cannot specify this flag with _O_RDONLY or _O_WRONLY.

_O_SEQUENTIAL

Specifies that caching is optimized for, but not restricted to, sequential access from disk.

_O_TEXT

Opens file in text (translated) mode.

_O_TRUNC

Opens file and truncates it to zero length; file must have write permission. You cannot specify this flag with _O_RDONLY. _O_TRUNC used with _O_CREAT opens an existing file or creates a new file.  The _O_TRUNC flag destroys the contents of the specified file.

_O_WRONLY

Opens file for writing only; cannot be specified with _O_RDONLY or _O_RDWR.

 

Table 5:  oflag constants.

 

-      To specify the file access mode, you must specify either _O_RDONLY, _O_RDWR, or _O_WRONLY.  There is no default value for the access mode.

-      The argument shflag is a constant expression consisting of one of the following manifest constants, defined in share.h.

 

shflag

Description

_SH_DENYRW

Denies read and write access to file.

_SH_DENYWR

Denies write access to file.

_SH_DENYRD

Denies read access to file.

_SH_DENYNO

Permits read and write access.

 

Table 6:  shflag.

 

-      The pmode argument is required only when you specify _O_CREAT.  If the file does not exist, pmode specifies the file's permission settings, which are set when the new file is closed the first time.  Otherwise pmode is ignored.

-      pmode is an integer expression that contains one or both of the manifest constants _S_IWRITE and _S_IREAD, defined in sys\stat.h.

-      When both constants are given, they are combined with the bitwise-OR operator.  The meaning of pmode is as follows:

 

pmode

Description

_S_IREAD

Reading only permitted.

_S_IWRITE

Writing permitted (effectively permits reading and writing).

_S_IREAD | _S_IWRITE

Reading and writing permitted.

 

Table 7:  pmode.

 

-      If write permission is not given, the file is read-only.  Under Windows 98/Me and Windows NT/2000/XP, all files are readable; it is not possible to give write-only permission.  Thus the modes _S_IWRITE and _S_IREAD | _S_IWRITE are equivalent.

-      _sopen() applies the current file-permission mask to pmode before setting the permissions.

-      The following Table is an example of the needed information in order to use the _open() function.

 

Information

Description

The function

_open().

The use

Open a file.

The prototype

int _open(const char *filename, int oflag [, int pmode]);

[ ... ] – denotes optional.

Example

char fname[50] = C:\\testfile.txt;

int _sopen(fname, _O_CREAT, _SH_DENYNO, _S_IWRITE);

The parameters

filename – The filename.

oflag - Type of operations allowed.

pmode - Permission mode.

The return value

Each of these functions returns a file handle for the opened file.  A return value of –1 indicates an error, in which case errno is set to one of the following values:

 

EACCES - Tried to open read-only file for writing, or file's sharing mode does not allow specified operations, or given path is directory.

EEXIST - _O_CREAT and _O_EXCL flags specified, but filename already exists.

EINVAL - Invalid oflag or pmode argument.

EMFILE - No more file handles available (too many open files).

ENOENT - File or path not found.

The header file

<io.h>

 

Table 8:  _open() function information.

 

-      Finally, a program example that uses the functions.  Originally the robots.txt file has write permission.

 

/*Playing with some of the file handling functions*/

#include <io.h>

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/stat.h>

 

/*You can try other files and directories*/

char obj[50] = "d:\\test\\testsubtwo\\testsubthree\\robots.txt";

char newobj[50] = "d:\\test\\testsubtwo\\testsubthree\\human.txt";

 

int main()

{

/*Check for existence*/

if((_access(obj, 0)) != -1)

  printf("%s file exists\n", obj);

else

  printf("%s file does not exist lol!\n", obj);

 

/*Check for read/write permission*/

if((_access(obj, 2)) != -1)

  printf("%s file has write permission\n", obj);

if((_access(obj, 4)) != -1)

  printf("%s file has read permission\n", obj);

if((_access(obj, 6)) != -1)

  printf("%s file has write and read permission\n\n", obj);

 

/* Make file read-only: */

if(_chmod(obj, _S_IREAD) == -1)

  perror("File not found lol!\n");

else

{

 printf("The file mode is changed to read-only\n");

 _chmod(obj, _S_IREAD);

}

if((_access(obj, 4)) != -1)

 printf("%s file has read permission\n", obj);

 

/*Change back to read/write*/

if(_chmod(obj, _S_IWRITE) == -1)

 perror("file not found lol!\n");

else

{

 printf("\nThe file\'s mode is changed to read/write\n");

 _chmod(obj, _S_IWRITE);

}

 

if((_access(obj, 2)) != -1)

 printf("%s file has write permission\n", obj);

 

/*Attempt to rename file*/

int result = rename(obj, newobj);

if(result != 0)

  printf("\nCould not rename %s\n", obj);

else

  printf("\n%s file has been renamed to\n %s\n", obj, newobj);

 

/*remove the file*/

if(remove(newobj) == -1)

  printf("\nCould not delete %s lol!\n", newobj);

else

  printf("\nOoops! %s file has been deleted lol!\n", newobj);

 

return 0;

}

 

The output:

 

d:\test\testsubtwo\testsubthree\robots.txt file exists

d:\test\testsubtwo\testsubthree\robots.txt file has write permission

d:\test\testsubtwo\testsubthree\robots.txt file has read permission

d:\test\testsubtwo\testsubthree\robots.txt file has write and read permission

 

The file mode is changed to read-only

d:\test\testsubtwo\testsubthree\robots.txt file has read permission

 

The file's mode is changed to read/write

d:\test\testsubtwo\testsubthree\robots.txt file has write permission

 

d:\test\testsubtwo\testsubthree\robots.txt file has been renamed to

 d:\test\testsubtwo\testsubthree\human.txt

 

Ooops! d:\test\testsubtwo\testsubthree\human.txt file has been deleted lol!

Press any key to continue

 

The File Permission mask

 

-      The following Table is the needed information in order to use the _umask() function.

 

Information

Description

The function

_umask().

The use

Sets the default file-permission mask.

The prototype

int _umask(int pmode);

Example

_umask(_S_IWRITE);

The parameters

pmode - default permission setting - _S_IREAD_S_IWRITE.

The return value

Returns the previous value of pmode. There is no error return.

The header files

<io.h>, <sys/stat.h> and <sys/types.h>.

 

Table 9:  _umask() function information.

 

-      The _umask() function sets the file-permission mask of the current process to the mode specified by pmode.

-      The file-permission mask modifies the permission setting of new files created by _creat(), _open(), or _sopen().  If a bit in the mask is 1, the corresponding bit in the file's requested permission value is set to 0 (disallowed).

-      If a bit in the mask is 0, the corresponding bit is left unchanged.  The permission setting for a new file is not set until the file is closed for the first time.

-      The argument pmode is a constant expression containing one or both of the manifest constants _S_IREAD and _S_IWRITE, defined in sys\stat.h.

-      When both constants are given, they are joined with the bitwise-OR operator ( | ).  If the pmode argument is _S_IREAD, reading is not allowed (the file is write-only).  If the pmode argument is _S_IWRITE, writing is not allowed (the file is read-only).

-      For example, if the write bit is set in the mask, any new files will be read-only.  Note that with MS-DOS and the Windows operating systems, all files are readable.  It is not possible to give write-only permission.  Therefore, setting the read bit with _umask() has no effect on the file's modes.

-      The following is a simple program example.

 

/*This program uses _umask to set the file-permission mask

so that all future files will be created as read-only files.

Then we create a file for write and test opening the file

for writing*/

#include <fcntl.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <io.h>

#include <stdio.h>

 

int main()

{

int fh, oldmask;

/*File in current working directory*/

char test[20] = "test.txt";

 

/*Create read-only files: */

oldmask = _umask(_S_IWRITE);

printf("Oldmask = 0x%.4x\n", oldmask);

 

/*create a file with write permission*/

fh = _creat(test, _S_IWRITE);

   if(fh == -1)

      printf("Couldn't create %s file!\n", test);

   else

   {

      printf("%s file successfully created.\n", test);

      _close(fh);

   }

 

/*Try opening file for write*/

fh = _open(test, _O_WRONLY);

if(fh == -1)

  printf("%s opening failed!\n", test);

else

{

  printf("%s opening succeeded!\n", test);

  if(_close(fh) == 0)

  printf("%s closed successfully!\n", test);

}

printf("Oldmask = 0x%.4x\n", oldmask);

return 0;

}

 

The output:

 

Oldmask = 0x0000

test.txt file successfully created.

test.txt opening failed!

Oldmask = 0x0000

Press any key to continue

 

The File Statistic

 

-      The _stat(), _stat64(), _stati64(), _wstat(), _wstat64(), _wstati64() functions used for file statistic.  The information needed in order to use these functions is listed in the following Table.

 

 

Information

Description

The function

_stat(), _stat64(), _stati64(), _wstat(), _wstat64(), _wstati64()

The use

Get status information on a file.

The prototype

int _stat(const char *path, struct _stat *buffer);
int _stat64(const char *path, struct __stat64 *buffer);
int _stati64(const char *path, struct _stati64 *buffer);
int _wstat(const wchar_t *path, struct _stat *buffer);
int _wstat64(const wchar_t *path, struct __stat64 *buffer);

int _wstati64(const wchar_t *path, struct _stati64 *buffer);

Example

struct __stat64 buf;

char fname[50] = "c:\\WINNT\\system32\\config\\sam.log";

_stat64(fname, &buf);

The parameters

path - Pointer to a string containing the path of existing file.

buffer - Pointer to structure that stores results.

The return value

Each of these functions returns 0 if the file-status information is obtained.  A return value of –1 indicates an error, in which case errno is set to ENOENT, indicating that the filename or path could not be found.

The date stamp on a file can be represented if it is later than midnight, January 1, 1970, and before 19:14:07 January 18, 2038, UTC unless you use _stat64() or _wstat64(), in which case the date can be represented up till 23:59:59, December 31, 3000, UTC.

The header files

_stat(), _stat64(), _stati64() -  <sys/types.h> followed by <sys/stat.h>.

_wstat(), _wstat64(), _wstati64() -  <sys/types.h> followed by <sys/stat.h> or <wchar.h>.

 

Table 10:  File statistic functions information.

 

-      The _stat() function obtains information about the file or directory specified by path and stores it in the structure pointed to by buffer.

-      _stat() automatically handles multibyte-character string arguments as appropriate, recognizing multibyte-character sequences according to the multibyte code page currently in use.

-      _wstat() is a wide-character version of _stat(); the path argument to _wstat() is a wide-character string (More information and implementation of the wide character can be found in Locale, Wide Character & Unicode (Story) and Windows Users & Groups tutorial (Implementation)).

-      The _stat structure, defined in sys\stat.h, includes the following elements.  You should be familiar in using and accessing structure elements.

 

Element

Description

st_gid

Numeric identifier of group that owns file (UNIX-specific) This field will always be zero on Windows NT systems.  A redirected file is classified as a Windows NT file.

st_atime

Time of last access of file. Valid on NTFS but not on FAT formatted disk drives.

st_ctime

Time of creation of file. Valid on NTFS but not on FAT formatted disk drives.

st_dev

Drive number of the disk containing the file (same as st_rdev).

st_ino

Number of the information node (the inode) for the file (UNIX-specific).  On UNIX file systems, the inode describes the file date and time stamps, permissions, and content. When files are hard-linked to one another, they share the same inode.  The inode, and therefore st_ino, has no meaning in the FAT, HPFS, or NTFS file systems.

st_mode

Bit mask for file-mode information.  The _S_IFDIR bit is set if path specifies a directory; the _S_IFREG bit is set if path specifies an ordinary file or a device. User read/write bits are set according to the file's permission mode; user execute bits are set according to the filename extension.

st_mtime

Time of last modification of file.

st_nlink

Always 1 on non-NTFS file systems.

st_rdev

Drive number of the disk containing the file (same as st_dev).

st_size

Size of the file in bytes; a 64-bit integer for _stati64() and _wstati64().

st_uid

Numeric identifier of user who owns file (UNIX-specific). This field will always be zero on Windows NT systems. A redirected file is classified as a Windows NT file.

 

Table 11:  _stat structure members.

 

-      If path refers to a device, the st_size, various time fields, st_dev, and st_rdev fields in the _stat structure are meaningless.  Because stat.h uses the _dev_t type that is defined in types.h, you must include types.h before stat.h in your code.

-      The following is a program example.

 

/*Using the _stat64 function reporting a file information*/

#include <time.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

 

int main()

{

struct __stat64 buf;

int result;

char fname[50] = "c:\\WINNT\\system32\\config\\sam.log";

 

/*Get data associated with a file*/

result = _stat64(fname, &buf);

 

/*Test if statistics are valid*/