File and Data Access


Interix file and data access differs in some respects from that of UNIX becauseof the underlying Windows input/output system. Consequently, certain UNIX features are different or do not work in Interix.

This section discusses:

  • Differences in Interix and UNIX file I/O

  • The Interix ioctl() function implementation

  • Directory operations

  • File system operations in Interix

Differences in Interix and UNIX File I/O

Interix does not support file I/O with memory caching turned off (O_DIRECT),and it also does not support the file I/O APIs listed in Table 10.13. Table 10.13 also provides code to implement the missing functions, if they are needed.

Table 10.13: File I/O APIs Not Supported by Interix

Function

Description

Suggested Interix Replacement

pread(fd, *buf, nbytes, offset)

Reads from a file descriptor at a given offset.

ssize_t pread(int fd, void *buf,
size_t count, off_t offset)

{
ssize_t size ;
off_t rtn
if (lrtn=seek(fd, offset,SEEK_SET) < 0)
return((ssize_t) rtn);
size = read(fd, *buf, nbytes)
return(size);
}

pwrite(fd, *buf, nbytes, offset)

Writes to a file descriptor at a given offset.

ssize_t pwrite(int fd, const void
*buf, size_t count, off_t offset)
{
ssize_t size;
off_t rtn
if (lrtn=seek(fd, offset,SEEK_SET) < 0)
return((ssize_t) rtn);
size = write(fd, *buf, nbytes)
return(size);
}

The Interix ioctl() Function Implementation

The ioctl() interface has many uses. The POSIX.1 committee did not standardize the ioctl() interface because the last argument cannot be type-checked: Its type depends upon the request. Instead, the committee assigned pieces of functionality to other interfaces.

In other words, ioctl() does not have a single standard. Its arguments, returns, and semantics vary according to the device driver. The call is used for operations that do not cleanly fit the UNIX stream I/O model.

The ioctl() interface has historically been used to handle the following:

  • File control (See File Control and ioctl() in this section.)

  • Socket control (See Socket Control and ioctl() in this section.)

  • Disk labels

  • Magnetic tape control

  • Terminal control

The disk label and magnetic tape I/O requests are not supported in the Interix environment.

The SFU 3.0 API set contains only a few ioctl() operations, including window resizing. The following two sections explain some additional operations.

File Control and ioctl()

The only ioctl() requests defined for file control are FIONREAD, to get the number of bytes available to read, and FIONBIO, to set and unset nonblocking I/O.

The FIOCLEX and FIONCLEX requests (usually found in Filio.h) are not provided. They can be replaced with the fcntl() FD_CLOEXEC request, as shown in the following example:

 #ifndef __INTERIX (void) ioctl(fd, FIOCLEX, NULL) #else (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFD)  FD_CLOEXEC)); #endif 

Socket Control and ioctl()

The only ioctl() request defined for sockets in Interix is SIOCATMARK. Other socket control requests are handled by using fcntl() or by using functions suchas setsockopt() .

Directory Operations

Interix supports a subset of the routines used to access directory entries. Interix does not support the calls shown in Table 10.14 on the next page.

Table 10.14: Directory Operations Routines Not Supported by Interix

Function Name

Description

Suggested Interix Replacement

alphasort

Can be used as the comparison function for the scandir() function to sort the directory entries into alphabetical order.

Use readdir() to retrieve all entries, then sort as desired using the libc sort() or any other sorting function.

getdents (fd, struct dirent*dirp, count)

Gets directory entries.

struct dirent * readdir (DIR *dirp)

getdirentries

Getd directory entries in a file system system-independent format.

struct dirent * readdir (DIR *dirp)

scandir

Scans a directory for matching entries.

readdir
For more information, see the code example in Interix readdir Conversion Example below.

Replacing scandir in Interix

Because Interix does not support scandir , convert to using readdir . The example UNIX scandir Example below shows UNIX code using the scandir function, and the Interix readdir Conversion Example example that follows it shows how this code is converted to use readdir under Interix.

UNIX scandir Example

This example lists the contents of the current directory, demonstrating the useof the scandir function in UNIX:

 #include <dirent.h> main() {     struct dirent **namelist;     int i, n;     n = scandir(".", &namelist, 0, 0);     if (n < 0)         perror("scandir");     else {         for (i=0; i<n; i++) {             printf("%s\n", namelist[i]->d_name);             free(namelist[n]);         }         free(namelist);     } } 
Interix readdir Conversion Example

In Interix, you must change from using the scandir function to using the readdir function. The following code shows how to do this. In the scandir example, scandir is called once and returns the number of directory entries and a structure containing those entries. In contrast, the readdir function is called in a loop. Each time readdir is called, it returns a new directory entry until there are none left, and then it returns NULL.

 #include <dirent.h> #include <stdio.h> main() {     DIR *dp;     struct dirent *entry;     if((dp = opendir(".")) == NULL)         perror("opendir");     else {         while((entry = readdir(dp)) != NULL)             printf("%s\n",entry->d_name);         closedir(dp);     } } 

For other examples of UNIX code that ports to Interix without change, see Directory Scanning in Chapter 9, Win32 Code Conversion.

Working Directory

Interix does not support the routines to get the current working directory shownin Table 10.15.

Table 10.15: Working Directory Routines Not Supported by Interix

Function Name

Description

Suggested Interix Replacement

get_current_dir_name

Gets current working directory
(define:__USE_GNU).

getcwd (buf, max)

getwd

Gets current working directory
(define:__USE_BSD).

getcwd(buf, max)

The getwd API as defined on BSD systems is particularly dangerous becauseit is vulnerable to buffer overrun attacks. Replace it with getcwd and a bufferof known size.

For an example of UNIX code that ports to Interix without change, see Working Directory in Chapter 9, Win32 Code Conversion.

File System Operations in Interix

Operations on file systems in Interix differ in a number of ways from file system operations under UNIX. Some functions are not supported, such as sync , sysfs , and ustat . Others have different parameters or use a different set of options for UNIX.

Table 10.16 lists the file system information functions that need to be replaced.

Table 10.16: File System Information Functions Not Supported by Interix

Function

Description

Suggested Interix Replacement

statfs, fstatfs

Get file system statistics.

statvfs
For more information about statvfs , see Table 10.17.

sync

Writes all information in memory that should be on disk, including modified super blocks, modified inodes, and delayed block I/O.

No support or equivalent in Interix.

sysfs

Gets file system type information.

statvfs
For more information about statvfs , see Table 10.17.

ustat

Gets file system statistics.

Port to statfs first.

The Windows NTFS file system is structured and implemented in such a way as to obviate the need for the sync function. NTFS uses a log-based mechanism to ensure that file system metadata (the equivalent of super blocks and inodes) are updated in sync with changes to file data. In the event of a system failure, automated NTFS file system recovery guarantees that either metadata corresponds to data appearing in files or the changes to the files never occurred. (This also eliminates the need for a utility like the UNIX fsck command.)

When using the statvfs function in Interix, be aware that the statfs structure has some members different from those usually found in UNIX. Table 10.17 summarizes these differences. In general, references to the statfs structure can by replaced with references to the statvfs structure.

Table 10.17: Differences Between UNIX statfs and Interix statvfs

UNIX statfs

Interix statvfs Structure

DescriptionStructure

long f_type

unsigned long f_type;

Type of file system.
For more information, see Commonly Supported File Systems in UNIX and Supported File System Types in Interix following this table.

long f_bsize

unsigned long f_bsize;

Transfer block size.

long f_blocks

unsigned long f_blocks;

Total data blocks in file system.

long f_bfree

unsigned long f_bfree;

Free blocks in file system.

long f_bavail

unsigned long f_bavail;

Free blocks available to non-superuser.

long f_files

lunsigned ong f_files;

Total file nodes in file system.
(Currently returns 0.)

long f_ffree

unsigned long f_ffree;

Free file nodes in file system.
(Currently returns 0.)

fsid_t f_fsid

unsigned long f_fsid;

File system ID.

long f_namelen

unsigned long f_namemax;

Maximum length of file names .

long f_spare[6]

unsigned long f_flag;

Bit mask of values describing the file system.

 

unsigned long f_frsize;

Fundamental block size.

 

unsigned long f_favail;

Total number of file serial numbers available to a nonprivileged process.
(Currently returns 0.)

 

unsigned long f_iosize;

Optimal transfer block size.

 

char f_mntonname
[MNAMELEN+1];

Mountpoint for the file system.

 

char f_mntfromname
[MNAMELEN+1];

Mounted file system.

When using statvfs , the file system types supported by Interix differ from those supported by most implementations of UNIX. The two lists below illustrate this by comparing a common subset of UNIX-supported file systems with those supported in Interix. It is rare for these differences to have any impact on the migration of an application.

Commonly Supported File Systems in UNIX

§  AFFS_SUPER_MAGIC

0xADFF

§  EXT_SUPER_MAGIC

0x137D

§  EXT2_OLD_SUPER_MAGIC

0xEF51

§  EXT2_SUPER_MAGIC

0xEF53

§  HPFS_SUPER_MAGIC

0xF995E849

§  ISOFS_SUPER_MAGIC

0x9660

§  MINIX_SUPER_MAGIC

0x137F /* orig. minix */

§  MINIX_SUPER_MAGIC2

0x138F /* 30 char minix */

§  MINIX2_SUPER_MAGIC

0x2468 /* minix V2 */

§  MINIX2_SUPER_MAGIC2

0x2478 /* minix V2, 30 char names */

§  MSDOS_SUPER_MAGIC

0x4d44

§  NCP_SUPER_MAGIC

0x564c

§  NFS_SUPER_MAGIC

0x6969

§  PROC_SUPER_MAGIC

0x9fa0

§  SMB_SUPER_MAGIC

0x517B

§  XENIX_SUPER_MAGIC

0x012FF7B4

§  SYSV4_SUPER_MAGIC

0x012FF7B5

§  SYSV2_SUPER_MAGIC

0x012FF7B6

§  COH_SUPER_MAGIC

0x012FF7B7

§  UFS_MAGIC

0x00011954

§  XFS_SUPER_MAGIC

0x58465342

§  _XIAFS_SUPER_MAGIC

0x012FD16D

Supported File System Types in Interix

§  ST_FSTYPE_UNKNOWN

/* unknown */

§  ST_FSTYPE_NTFS

1

/* NTFS */

§  ST_FSTYPE_OFS

2

/* OFS-NT object FS */

§  ST_FSTYPE_CDFS

3

 

§  ST_FSTYPE_CDROM

 

ST_FSTYPE_CDFS

§  ST_FSTYPE_ISO9660

 

ST_FSTYPE_CDFS

§  ST_FSTYPE_FATFS

4

/* MS-DOS FAT FS */

§  ST_FSTYPE_MSDOS

 

ST_FSTYPE_FATFS

§  ST_FSTYPE_HPFS

5

/* OS2 HPFS */

§  ST_FSTYPE_SAMBA

6

/* Samba FS */

§  ST_FSTYPE_NFS

8

/* NFS */

§  ST_FSTYPE_MAX

8

/* for now */

File System Mount Entry Management

Interix does not support dynamically mounted file systems, as UNIX does. Therefore, Interix does not include a file to define the mount table.

Mount tables are stored in different files on different implementations of UNIX. They are usually stored under the /etc directory and have names such as mtaband fstab or mnttab and vfstab.

This is unlikely to affect the migration of an application. However, if the application does use dynamically mounted file systems, remove the functionality and ensure that the file system is permanently mounted.

On UNIX systems, additional disk space is made available at some particular point in the file hierarchy by mounting a new disk volume onto a directory, or by replacing the directory with a symbolic link to some already mounted volume. The first operation can be performed in Windows through the use of the Windows Disk Management tool. This solution makes the additional space visible to Interixand Win32 applications. If your application environment doesn t require Win32 applications to see this additional space, you can instead replace the directorywith a symbolic link to any directory on any other volume on the system.

Library Porting

Applications still use the gdbm database (that is, an indexed file storage system), which is good at storing relatively static indexed data. The following APIs are used by an application that uses the gdbm database:

  • gdbm_close()

  • gdbm_delete()

  • gdbm_exists()

  • gdbm_fdesc()

  • gdbm_fetch()

  • gdbm_firstkey()

  • gdbm_nextkey()

  • gdbm_open()

  • gdbm_reorganize()

  • gdbm_setopt()

  • gdbm_store()

  • gdbm_strerror()

  • gdbm_sync()

An example of application code using these functions follows:

 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <gdbm.h> #include <string.h> #define TEST_DB_FILE "/tmp/gdbmtest1" #define NUM_ITEMS 3 struct test_data {     char some_chars[10];     int  an_integer;     char more_chars[21]; }; int main() {     struct test_data data_to_store[NUM_ITEMS];     struct test_data item_retrieved;     char key_to_use[20];     int i, result;     datum key_datum;     datum data_datum;     GDBM_FILE gdbm_ptr;     gdbm_ptr = gdbm_open(TEST_DB_FILE, 512, O_RDWR  O_CREAT, 0666, 0);     if (!gdbm_ptr) {         fprintf(stderr, "Database Open Failed\n");         exit(EXIT_FAILURE);     } /* put some data in the structures */     memset(data_to_store, 


UNIX Application Migration Guide
Unix Application Migration Guide (Patterns & Practices)
ISBN: 0735618380
EAN: 2147483647
Year: 2003
Pages: 134

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net