           Win32 Equivalents for Unix System Calls

Version 1.0 - Last Update: 09/14/92

Overview
This document serves as a guide for moving Unix code to the
Win32 API and C run time (CRT) libaries as implemented on
Windows NT.  Applications programmed to the Win32 API have
access to the widest range of functionality using the
Windows NT operating system.

The Windows NT operating system consists of subsystems, each
of which can expose a different programming interface (API).
In the first release, Windows NT has the ability to execute
Win32-based applications, sixteen bit Windows applications
(Windows 3.x), MS-DOS applications, POSIX and OS/2 character
mode applications; this guide is only relevant for moving
Unix code to the Win32 API.

For information on the Win16 and MS-DOS APIs, please refer
to the myriad books and guides available for that purpose.
For more information on the POSIX system calls, refer to the
POSIX.1 (1003.1) specification.

This document is not a discussion of the Windows NT
operating system or its architecture.  For more informatoin
on those topics, please refer to the "Inside Windows NT"
publication, or various brochures on Windows NT.

Microsoft sponsors a forum on Compuserve devoted to Unix
ISVs (Independent Software Vendors) moving code to the Win32
API. All support is done through this mechanism.

In this document, "Level" denotes level of mapping between
the Unix  system call and the Win32 API.  "Y" means
supported through either the Win32 API or the C run time
libraries, "W" indicates that a work around exists, or a
difference between the Unix  system call and the provided
system call.  "N" specifies that a direct translation does
not exist, or the call is not relevant in the context of the
Win32 API.

Disclaimers
The information contained in this document is generally
believed to be factual. Errors will be corrected as they are
detected. Please send electronic mail to
brianmo@microsoft.com with your suggestions on how  this
document can be improved.

File I/O

The Win32 API supports the concept of volumes; this is
analogous to the Unix  concept of block devices.  Different
types of file systems may be used on different volumes.
Refer to Chapter 5,  "File I/O" in the Windows NT
Programmer's Reference overview for information on the
characteristics of  the file systems,  including file length
restrictions, security considerations,and case sensistivity.
Windows NT file systems do not have  inodes; consequently,
though the stat structure contains an st.ino field, it is
always zero.  Hard links are present only on the NTFS
(Windows NT file system) file system, and creatable only
from the POSIX API.  This means

In addition to these run-time-library system calls which in
general are compatible with their Unix  equivalents, APIs
are provided that specifically exploit Windows NT features
for overlapped (non-blocking) I/O,  error conditions,  etc.
In many cases, a single API call suffices for a non-blocking
file I/O function call for a Windows NT application, where a
somewhat complex signalling mechanism would  traditionally
be used with Unix .  For specific information on the Windows
NT specific calls, see the programmer's reference manual.


     Function Categ  Lev          Windows/CRT
     Call     ory    el        Equiv/Workaround
     access   File    Y  access - 01 mode not
             I/O        supported
     chdir    File    Y  chdir
             I/O
     chmod    File    W  chmod - Access bits differ
             I/O        -- see C runtime reference
     chown    File    W  Use Win32  SetFileSecurity
             I/O        - see Win32 reference
     chroot   File    W  Use Win32 User Contexts
             I/O
     clearerr File    Y                            
             I/O
     fcntl    File    W  locking functions:stat
             I/O
     fdopen   File    Y  CRT has extended
             I/O        functionality
     feof     File    Y                            
             I/O
     ferror   File    Y                            
             I/O
     fflush   File    Y                            
             I/O
     fileno   File    Y                            
             I/O
     fopen    File    Y                            
             I/O
     fread    File    Y                            
             I/O
     freopen  File    Y                            
             I/O
     fseek    File    Y                            
             I/O
     fstat    File    W  Use stat
             I/O
     ftell    File    Y                            
             I/O
     fwrite   File    Y                            
             I/O
     getcwd   File    Y                            
             I/O
     ioctl    File    N  APIs must be exposed by
             I/O        device drivers
     link     File    N                            
             I/O
     mkdir    File    Y                            
             I/O
     mount    File    N                            
             I/O
     readlink File    N                            
             I/O
     rewind   File    Y                            
             I/O
     rmdir    File    Y                            
             I/O
     stat     File    Y                            
             I/O
     sync     File    N                            
             I/O
     sysfs    File    N                            
             I/O
     umask    File    Y  use CRT umask function
             I/O
     umount   File    N                            
             I/O
     unlink   File    Y  Some errno returns not
             I/O        supported
     ustat    File    W  Use GetVolumeInformation
             I/O
     utime    File    Y                            
             I/O

Low Level I/O

In general, low level file I/O calls should be avoided.
Instead, use the higher level "fopen, fclose" or Win32 file
handling API calls.

     Function  Category  Lev  Windows/CRT
     Call                el   Equiv/Workaround
     close     Low        W   Use higher-level
               Level          fclose
               I/O
     creat     Low        W   Use higher-level
               Level          fopen
               I/O
     dup       Low        W   See
               Level          DuplicateHandle
               I/O
     lseek     Low        Y   
               Level
               I/O
     open      Low        W   see CRT - open
               Level          flags and modes
               I/O            may differ
     read      Low        Y   
               Level
               I/O
     write     Low        Y   
               Level
               I/O

Memory

The model of a Windows NT process differs from that in Unix
, so sbrk and brk calls are not relevant in the context of a
Windows NT process.  Equivalent functionality is found in
the memory statistic information APIs, as well as malloc and
free. Windows NT provides additional system calls for
Virtual memory management, including explicit reservation
and commitment of memory pages, heap management, and shared
memory.  Please refer to the Windows NT programmers
reference for more information.

     Function  Category  Lev  Windows/CRT
     Call                el   Equiv/Workaround
     brk       Memory     N   malloc
     calloc    Memory     Y   
     free      Memory     Y   
     malloc    Memory     Y   
     mknod     Memory     W   mkdir for
                              directories, use
                              named pipes for
                              fifos
     mmap      Memory     W   Use Windows NT
                              shared memory
                              functions
     mprotect  Memory     W   Use Windows NT
                              virtual  memory
                              functions
     munmap    Memory         
     realloc   Memory     Y   
     sbrk      Memory     N   use malloc, or
                              process statistic
                              calls

Processes and Process Control

Windows NT provides a very powerful function, CreateProcess,
which duplicates the functionality of fork/exec usage, as
well as providing security.  The C run-time libaries for
exec are also provided.  Fork itself is not provided, since
it is not possible to exactly "clone"a Win32 process. For
applications in which two distinct processes are required
(fork followed by exec), CreateProcess can be used in
combination with WaitForSingleObject (which replaces
wait()).  If fork usage requires two identical processes,
the second may be started with CreateProcess, and some
manner of synchronizing through IPC or shared memory must be
used.   In many cases, a single process will suffice, with
additional threads created to perform additional work.

     Function  Category  Lev  Windows/CRT
     Call                el   Equiv/Workaround
     exit      Process    Y   shared memory
               Control        cleanup;
                              flexibility
     execl     Process    Y   
               Control
     execle    Process    Y   
               Control
     execlp    Process    Y   
               Control
     execv     Process    Y   
               Control
     execve    Process    Y   
               Control
     execvp    Process    Y   
               Control
     exit      Process    Y   
               Control
     fork      Process    W   Depending on
               Control        usage,
                              CreateProcess
     pause     Process        
               Control
     vfork     Process        
               Control
     wait      Process    W   Use
               Control        WaitForSingleObjec
                              t
     waitid    Process        
               Control
     waitpid   Process    W   Use
               Control        WaitForSingleObjec
                              t
     sleep     Process    W   Use Sleep; Sleep
               Control        arg is
                              milliseconds


Pipes
CreateProcess can be used in combination with
DuplicateHandle to provide popen and pclose functionality --
refer to the attached code fragment for details <<TO BE
PROVIDED>>.

     Function  Category  Lev  Windows/CRT
     Call                el   Equiv/Workaround
     pclose    Pipes     W    
     pipe      Pipes     W    CRT provides
                              pipe()
     popen     Pipes     W    refer to work-
                              around

Group/User ID
The Windows NT model of groups, processes, and users differs
from that of Unix .  In general, Windows NT associates
Access Control Lists (ACLs) to objects; security descriptors
(SIDs) are associated with users and running programs, and
used by Windows NT to grant or deny access to objects.
Please refer to the Windows NT Programmer's reference for
more information on these functions.

     Function  Category  Lev  Windows/CRT
     Call                el   Equiv/Workaround
     geteuid   ID        W    See Win32 Security
               control        APIs
     getgid    ID        W    See Win32 Security
               control        APIs
     getpgrp   ID        W    See Win32 Security
               control        APIs
     getpid    ID        Y    
               control
     getppid   ID        N    
               control
     getuid    ID        W    See Win32 Security
               control        APIs
     setgid    ID        W    See Win32 Security
               control        APIs
     setpgrp   ID        W    See Win32 Security
               control        APIs
     setuid    ID        W    See Win32 Security
               control        APIs

IPC
There is no explicit generalized message queueing mechanism
(analogous to the System V Unix msg* functions) provided in
the Win32 API.  By combining the shared memory functions
with the semaphore functions in a standard Dynamic Link
Library (DLL), the generalized message queueing functions
can be emulated.  Usually a better solution for interprocess
communication is to take advantage of one of the built in
Windows message passing mechanisms like Dynamic Data
Exchange (DDE), or message posting.

Rather than the the Unix key_t structure used as an ersatz
"handle" for coordinating IPC between processes, Win32 uses
named objects, which are instantiated through handles.  In
addition to just providing a reference to the shared object,
Win32 handles also have security and other attribute
information attached that can be explicitly controlled by
the programmer.

Semaphores are just one type of synchronization object that
Windows NT provides (others are events, mutexes, and
critical sections).  Synchronization objects are "waited on"
through the WaitForSingleObject or WaitForMultipleObject
APIs -- refer to the programmer's reference for more
information.

Shared memory is accomplished through memory mapping of
files.  Refer to the CreateFileMapping, OpenFileMapping,
MapViewOfFile, UnmapViewOfFile, FlushViewOfFile, ReadFile,
WriteFile, and CreateFile APIs.

     Function  Category  Lev  Windows/CRT
     Call                el   Equiv/Workaround
     msgctl    Message   W    Use standard
               Control        message posting
                              mechanism
     msgget    Message   W    
               Control
     msgrcv    Message   W    
               Control
     msgsnd    Message   W    
               Control
     semctl    Semaphor  W    Use Windows NT
               es             semaphore
                              functions
     semget    Semaphor  W    Use Windows NT
               es             semaphore
                              functions
     semop     Semaphor  W    Use Windows NT
               es             semaphore
                              functions
     shmat     Shared    W    Use Windows NT
               Memory         shared memory
                              functions
     shmctl    Shared    W    Use Windows NT
               Memory         shared memory
                              functions
     shmdt     Shared    W    Use Windows NT
               Memory         shared memory
                              functions
     shmget    Shared    W    Use Windows NT
               Memory         shared memory
                              functions
     shmop     Shared    W    Use Windows NT
               Memory         shared memory
                              functions

Signals
Seven types of signals are supported in Windows NT --
(SIGFPE, SIGILL, SIGSEGV, SIGINT SIGBREAK, SIGABRT, and
SIGTERM).  In general, out of bound events (normally
indicated through signals in various Unixes) are
indicated/handled  by the use of Windows messages, or by
callback functions.  In cases where signals would normally
be used (non-blocking or pending I/O, for example), the
mechanism for handling out-of-band information is explicitly
provided for in the initiating I/O call.

Windows NT supports multiple threads.  As source code is
modified to exploit multiple threads, it is important to
remember that a signal is raised on the thread that caused
it, and only on that thread.

     kill      Signals   W    TerminateThread,
                              TerminateProcess
     sigactio  Signals        
     n
     sigalsta  Signals        
     ck
     sighold   Signals        
     sigignor  Signals        
     e
     signal    Signals   Y    
     sigpause  Signals        
     sigpendi  Signals        
     ng
     sigprocm  Signals        
     ask
     sigrelse  Signals        
     sigsend   Signals        
     sigsends  Signals        
     et
     sigset    Signals        
     sigsuspe  Signals        
     nd
     alarm     Signals    N   Use SetTimer and
                              case statement in
                              WndProc

Miscellaneous
The directory functions opendir(), readdir(), closedir(),can
be handled by the Win32 equivalent of FindFirstFile(),
FindNextFile(), and FileCloseFile() APIs.  The Writedir()
call does not have an equivalent in the Win32 API
specification.  A library of these functions is provided in
the Appendix1.


     Function  Category  Lev  Windows/CRT
     Call                el   Equiv/Workaround
     opendir   director   W   FindFirstFile
               y
     readdir   director   W   FindNextFile
               y
     closedir  director   W   FileCloseFile
               y
     nice      Limits     W   use
                              SetThreadPriority
     ulimit    Limits     N   
     sys3b     Misc       N   
     uadmin    Misc       N   
     profil    Perfinfo   W   See Profiling APIs
     ptrace    Perfinfo   W   See  debugging
                              APIs
     ioctl     Device     W   Use
               Control        DeviceIOControl to
                              access device
                              driver directly
     uname     System     W   Use GetVersion
               Informat       GetComputerName,
               ion            and GetSystemInfo
     times     Perfinfo   W   Use GeSystemTime
                              and GetTickCount
                              APIs, as well as
                              others.
                              
                              


Socket Functions
Windows NT provides access to a Berkeley-style sockets
mechanism through the Windows Sockets Interface standard.
Please refer to this document for more information on the
Windows Sockets Interface API, and/or examine WINSOCK.H in
the include file directory in the Windows NT software
development kit.

The Windows Socket specification is available via anonymous
ftp in WinHelp, WinWord, PostScript, ASCII text, and RTF
file formats from vax.ftp.com (FTP Software), ftp.uu.net (in
the vendor/microsoft directory), among other places.
Section 2.6 of the Windows Socket specification document
details differences between Windows Sockets and BSD sockets.

The gethostname() call is not explicitly exported in the
WINSOCK.DLL library on Windows NT; to get the host name, use
LoadModule to get a handle to the WINSOCK.DLL library, and
then GetProcAddr to retrieve the entry point to this
routine, or the alternate method of accessing the Registry
to read the IP Address field from the TCP/IP information
section.

 1992 Microsoft Corporation.  All rights reserved.
This document is for informational purposes only.  Microsoft
makes no warranties, express or implied, in this document.
Microsoft and MS-DOS are registered trademarks and Windows,
Windows NT, Win32, Win32s, and the Windows logo are
trademarks of Microsoft Corporation.
Unix is a registered trademark of Unix Systems Laboratories.
DEC and VMS are registered trade marks of Digital Equipment
Corporation.  CompuServe is a registered trademark of
CompuServe Corporation.
    Appendix A - A Berkeley Compatible Directory Package

/*
 * @(#) dir.h 2.0 17 Jun 91   Public Domain.
 *
 *  A public domain implementation of BSD directory routines
for
 *  MS-DOS.  Written by Michael Rendell
({uunet,utai}michael@garfield),
 *  August 1987
 *
 *  Enhanced and ported to OS/2 by Kai Uwe Rommel; added
scandir() prototype
 *  December 1989, February 1990
 *  Change of MAXPATHLEN for HPFS, October 1990
 *
 *  Unenhanced and ported to Windows NT by Bill Gallagher
 *  17 Jun 91
 *  changed d_name to char * instead of array, removed non-
std extensions
 *
 *  Cleanup, other hackery, Summer '92, Brian Moran ,
brianmo@microsoft.com
 */
#define DB_MAX_PATH_LENGTH    256 /* this shouldn't be hard
wired here - use sys max path */

struct direct
{
  ino_t    d_ino;                   /* a bit of a farce */
  int      d_reclen;                /* more farce */
  int      d_namlen;                /* length of d_name */
  char      *d_name;
};

struct _dircontents
{
  char *_d_entry;
  struct _dircontents *_d_next;
};

typedef struct _dirdesc
{
  int  dd_id;                           /* uniquely identify
each open directory*/
  long dd_loc;                          /* where we are in
directory entry */
  struct _dircontents *dd_contents;     /* pointer to
contents of dir */
  struct _dircontents *dd_cp;      /* pointer to current
position */
}
DIR;

extern DIR *opendir(char *);
extern struct direct *readdir(DIR *);
extern void seekdir(DIR *, long);
extern long telldir(DIR *);
extern void closedir(DIR *);
#define rewinddir(dirp) seekdir(dirp, 0L)

/* end of dir.h */


/*
   dir.c for MS-DOS by Samuel Lam <skl@van-bc.UUCP>, June/87
*/

#ifdef WIN32
/*
 * @(#)dir.c 1.4 87/11/06 Public Domain.
 *
 *  A public domain implementation of BSD directory routines
for
 *  MS-DOS.  Written by Michael Rendell
({uunet,utai}michael@garfield),
 *  August 1897
 *  Ported to OS/2 by Kai Uwe Rommel
 *  December 1989, February 1990
 *  Ported to Windows NT 22 May 91
 *    other mods Summer '92 brianmo@microsoft.com
 */


/*Includes:
 *   crt
 */
#include <stdlib.h>
#include <string.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <ndir.h>                  /* this from the GNULIB
dir */

/*
 *   NT specific
 */
#include <stdio.h>
#include <windows.h>

/*
 *   random typedefs
 */
#define HDIR        HANDLE
#define HFILE       HANDLE
#define PHFILE      PHANDLE

/*
 *   local functions
 */
static char *getdirent(char *);
static void free_dircontents(struct _dircontents *);

static HDIR                   FindHandle;
static WIN32_FIND_DATA   FileFindData;

static struct direct dp;

DIR *opendirx(char *name,char *pattern)
{
  struct stat statb;
  DIR *dirp;
  char c;
  char *s;
  struct _dircontents *dp;
  char path[ DB_MAX_PATH_LENGTH ];

  strcpy(path,name);

  if (((c = path[strlen(path)-1]) == '\\' || c == '/') &&
(strlen(path) > 1) )
  {
    path[strlen(path) - 1] = 0;

    if ( path[strlen(path) - 1] == ':' )
      strcat(path, "\\.");
  }
  else
    if ( path[strlen(path) - 1] == ':' )
      strcat(path, ".");



  if (stat(path, &statb) < 0 || (statb.st_mode & S_IFMT) !=
S_IFDIR)
    return NULL;


  if ( (dirp = malloc(sizeof(DIR))) == NULL )
    return NULL;

  if ( path[strlen(path) - 1] == '.' )
    strcpy(path + strlen(path) - 1, pattern);
  else
    if ( ((c = path[strlen(path) - 1]) == '\\' || c == '/')
&&
         (strlen(path) == 1) )
      strcat(path, pattern);
    else
     {
      strcat(path, "\\");
      strcat(path, pattern);
     }

  dirp -> dd_loc = 0;
  dirp -> dd_contents = dirp -> dd_cp = NULL;



  if ((s = getdirent(path)) == NULL)
    return dirp;

  do
  {
    if (((dp = malloc(sizeof(struct _dircontents))) == NULL)
||
        ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL)
)
    {
      if (dp)
        free(dp);
      free_dircontents(dirp -> dd_contents);

      return NULL;
    }

    if (dirp -> dd_contents)
      dirp -> dd_cp = dirp -> dd_cp -> _d_next = dp;
    else
      dirp -> dd_contents = dirp -> dd_cp = dp;

    strcpy(dp -> _d_entry, s);
    dp -> _d_next = NULL;

  }
  while ((s = getdirent(NULL)) != NULL);

  dirp -> dd_cp = dirp -> dd_contents;
  return dirp;
}

void closedir(DIR * dirp)
{
  free_dircontents(dirp -> dd_contents);
  free(dirp);
}

struct direct *readdir(DIR * dirp)
{
  /* static struct direct dp; */
  if (dirp -> dd_cp == NULL)
    return NULL;

  /*strcpy(dp.d_name,dirp->dd_cp->_d_entry); */

  dp.d_name = dirp->dd_cp->_d_entry;

  dp.d_namlen = dp.d_reclen =
    strlen(dp.d_name);

  dp.d_ino = dirp->dd_loc+1; /* fake the inode */

  dirp -> dd_cp = dirp -> dd_cp -> _d_next;
  dirp -> dd_loc++;


  return &dp;
}

void seekdir(DIR * dirp, long off)
{
  long i = off;
  struct _dircontents *dp;

  if (off >= 0)
  {
    for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -
> _d_next);

    dirp -> dd_loc = off - (i + 1);
    dirp -> dd_cp = dp;
  }
}


long telldir(DIR * dirp)
{
  return dirp -> dd_loc;
}

static void free_dircontents(struct _dircontents * dp)
{
  struct _dircontents *odp;

  while (dp)
  {
    if (dp -> _d_entry)
      free(dp -> _d_entry);

    dp = (odp = dp) -> _d_next;
    free(odp);
  }
}
/* end of "free_dircontents" */

static char *getdirent(char *dir)
{
  int done;

  if (dir != NULL)
  {                        /* get first entry */
     if ((FindHandle = FindFirstFile( dir, &FileFindData ))
            == (HDIR)0xffffffff)
     {
          return NULL;
     }
  }
  else                          /* get next entry */
       done = FindNextFile( FindHandle, &FileFindData );

  if (done != 0)
    return FileFindData.cFileName;
  else
  {
    FindClose(FindHandle);
    return NULL;
  }
}
/* end of getdirent() */

#endif


_______________________________
1
