README libunistd
Copyright 2008 Robin.Rowe@cinepaint.org
License OSI BSD
Revised 2008.02.05

What Is Libunistd?

Libunistd is a very thin POSIX wrapper created by Robin Rowe that 
enables building typical Linux code on Windows with VC++. Using 
libunistd, many Linux terminal-based apps will build on Windows 
as-is or with only minor changes.

Supported POSIX Calls...

Libunistd supports open/read/write/close, dlopen, opendir, 
gettimeofday, and the typical BSD socket calls 
accept/bind/connect/listen/select/socket. It also allows iostream.h 
and fstream.h to substitute for their non-dot-h counterparts in VC++. 

Unsupported POSIX Calls...

The most notable omission is fork. Portable programs can be revised 
to handle POSIX threads (pthread) instead. A Windows pthreads port 
is available from Red Hat or there's a chopped down lite version I 
created in CinePaint CVS. Also missing is fancy signal handling. 
And, ioctls are obviously not portable.

How to Use...

To use libunistd simply #include <unistd.h> in your code and set 
your Windows build path to find it. You should not need any #ifdef 
WIN32 code in your app. The whole point of libunistd is to eliminate 
that junk. 

You'll want to statically link to the (tiny) libunistd library. That 
has implementations of opendir and gettimeofday. You'll also need to 
link to Windows' Winsock library and possibly its Common Controls 
library. If you're running sockets from a Windows command-line app, 
there's a magic start-up function called StartWinsock() you'll need 
to call. 

How It Works...

Many POSIX calls are available in Windows to support its 
implementation of BSD sockets, but have non-standard header names. 
There are many deliberately empty POSIX headers in libunistd so that 
Windows won't complain about missing Linux POSIX headers. Most of 
Windows POSIX implementation is in <winsock.h>, but you don't need 
to know that. Just include unistd.h and it will straighten out the 
Windows mess. Including unistd.h on Linux does no harm. That this 
file is standard on nix systems but not present on Windows is the 
trick to making code portable.

Alternatives...

Note that libunistd is deliberately a very thin implementation 
covering only the most basic POSIX calls that everyone uses. If you 
want a full-featured POSIX implementation and don't care how 
cumbersome it is, you're looking for Cygwin. If you're looking for 
a thin implementation of nix shell tools (ls, diff, du...) then you 
want CoreUtils for Windows, not Cygwin. With CoreUtils you can 
handle patching and other nix tasks in Windows using the standard 
nix command-line tools. By the way, if you're looking for a nice 
free Windows Perl you want PxPerl. A nice free Windows text editor 
that handles unix-style line feeds is Notepad++.

Implementation Notes...

arpa/net.h
bits/utsname.h
 #define _UTSNAME_LENGTH 65
 #define _UTSNAME_DOMAIN_LENGTH _UTSNAME_LENGTH
net/if.h
netnet/in.h
sys/mman.h
sys/syscal.h
sys/utsname.h
sys/socket.h
sys/ioctl.h
sys/signal.h
sys/select.h

dirent.h
 struct dirent;
 struct DIR;
 opendir(const char*);
 readdir (DIR*);
 closedir (DIR*);
 rewinddir (DIR*);
 telldir (DIR*);
 seekdir (DIR*, long);

dlfcn.h
 #define dlopen(mLibName,unused)
 #define dlsym(mHandle,funcname)
 #define dlclose(mHandle) 
 #define dlerror()

fix_strlen.h
 Makes strlen(0) safe.

fix_vcast.h
 Makes int to void* casts safe.

fstream.h
 #include <fstream>
 using namespace std;

iostream.h
 #include <iostream>
 using namespace std;
 
pwd.h
 struct passwd;

netdb.h

sched.h
 not implemented
 
sigsetops.h

timeofday.h
 struct timespec;
 int gettimeofday(struct timeval* t,void* timezone);
 int settimeofday(const struct timeval *tv , void *tz);
 
unistd.h

 #define pow10(x) pow(x,10)
 #define alloca _alloca
 #define LONG_LONG_MAX LLONG_MAX     
 #define LONG_LONG_MIN LLONG_MIN     
 #define snprintf _snprintf
 #define vsnprintf _vsnprintf
 #define strcasecmp _stricmp
 #define strncasecmp _strnicmp
 #define popen _popen
 #define pclose _pclose
 typedef int ssize_t;
 #define lstat stat
 typedef unsigned short mode_t;
 #define mkdir _mkdir
 #define F_OK 0
 #define X_OK 0
 #define W_OK 2
 #ifndef S_ISREG
 #define S_ISREG(x) (_S_IFREG & x)
 #define S_ISLNK(x) 0
 #ifndef S_ISDIR
 #define S_ISDIR(x) (_S_IFDIR & x)
 #define S_IXUSR _S_IEXEC
 #define S_IRUSR _S_IREAD
 #define S_IWUSR _S_IWRITE
 #define S_IXOTH 0
 #define S_IXGRP 0
 #define S_IFMT   _S_IFMT
 #define S_IFDIR  _S_IFDIR
 #define S_IFCHR  _S_IFCHR
 #define S_IFREG  _S_IFREG
 #define S_IREAD  _S_IREAD
 #define S_IWRITE _S_IWRITE
 #define S_IEXEC  _S_IEXEC
 int ffs(int i);
 #define STDIN_FILENO fileno(stdin)
 #define SIGALRM NSIG+1
 #define SIGHUP NSIG+2
 #define SIGQUIT NSIG+3
 #define SIGBUS NSIG+4
 #define SIGPIPE NSIG+5
 #define SIGKILL SIGTERM
 #define SIGCHLD NSIG+6
 #define SIGUSR1 NSIG+7
 #define SIGUSR2 NSIG+8
 #define WNOHANG 0
 #define rint(x) floor ((x) + 0.5)
 #define getpid _getpid
 typedef int pid_t;
 typedef int gid_t;
 typedef int uid_t;
 int setgid(gid_t gid);
 int setuid(uid_t uid);
 #define kill(pid,sig) ExitProcess(sig)
 #define lround floor
 #define roundl floor

###
