Porting Issues

Microsoft Windows Services for UNIX 3.0

On This Page

SFU (Interix) Specific Issues SFU (Interix) Specific Issues
SFU 3.0 (Interix) Enhancement Overview SFU 3.0 (Interix) Enhancement Overview
SFU 3.0 (Interix) Lab Objectives SFU 3.0 (Interix) Lab Objectives
Lab 2: SFU 3.0 Installation Lab 2: SFU 3.0 Installation
Lab 3: Product Walk-through Lab 3: Product Walk-through
SFU 3.0 (Interix) Porting SFU 3.0 (Interix) Porting
Lab 4: SFU 3.0 (Interix) Porting Examples Lab 4: SFU 3.0 (Interix) Porting Examples
Appendix A – Some API Additions to the Interix SDK from Interix 2.2 to SFU 3.0 Appendix A – Some API Additions to the Interix SDK from Interix 2.2 to SFU 3.0

SFU (Interix) Specific Issues

SFU 3.0 (Interix) Specific Issues Overview

  • What is Interix?

  • Interix Environment

    • Features of Interix

    • Interix Specific Behaviors

    • Security on Windows

    • File System

  • Working with WIN32 Programs

    • Invoking/Stopping WIN32 Programs

    • File Redirection

  • Services and Daemons

    • Telnet & Syslog Daemons

What Is Interix?

Interix 3.0, a key component of Services for UNIX version 3.0, is a complete subsystem environment for a Windows machine. It conforms to the POSIX.1 and POSIX.2 standards; these standards describe operating system service interfaces and utilities such as shell , awk , vi , and so on.

Interix provides portability. This is done through a consistent set of interfaces that let users and applications move between platforms. Portable, open systems are built of different industry standards, such as the ISO/IEEE POSIX standards and the ISO/ANSI C-language standard. An industry specification, such as the Open Group's Single UNIX Specification, incorporates these standards and adds other feature definitions. Interix implements the most-requested features of these standards and specifications on Windows, including integration with all the functionality present in the Window's environment.

Interix provides the important features of popular open systems platforms, including pipes, hard file links, symbolic file links, networking services, and X11 graphical support through the X Window System. Also, you get utilities such as Korn Shell, awk, and vi. Shell scripts and other scripted applications can run under Interix.

The Interix environment is not an emulation; it is a separate environment subsystem that integrates with the Windows kernel, just as the Win32 subsystem does. When you install Interix, you install a new extended subsystem that replaces the POSIX subsystem provided by Microsoft with Windows. The Interix extended subsystem provides all of the features described in the POSIX.1 standard, and more.

Interix Environment

The Interix environment is built upon the Interix subsystem, a replacement for the Windows POSIX subsystem. The Interix subsystem provides many additional features and functionality.

Windows is built to provide more than one set of programming interfaces to the operating system kernel. Each of these sets of interfaces is called an "environment subsystem." The familiar Win32 environment is one such subsystem; the POSIX and Interix environments are other subsystems. Both the Interix and Win32 subsystems can run at the same time. Other subsystems are provided with Windows for different purposes such as the security subsystem; these subsystems are "integral subsystems."

The Interix and Win32 environments provide approximately the same speed of performance. Some Interix applications run faster than the equivalent Win32 application, and some Win32 applications run faster than the equivalent Interix application.

One of the networking features of Windows is the use of "domains" (which are different from inter-network domains). A domain is a set of Windows machines that use a single password database. The existence of Windows domains has effects even in the Interix subsystem.

Features of Interix

The Interix subsystem provides a POSIX system environment for your Windows machine. That includes all features dictated by the POSIX.1 and POSIX.2 standards, derived from the 4.2BSD, 4.3BSD, Version 6, and System III operating systems. In particular, Interix features:

  • Simultaneous users

  • Korn and C Shells

  • Complete job control

  • Device support (/dev/null, /dev/tty, /dev/tape, /dev/pty)

  • Sockets support

  • Shared memory, message queues, semaphores

Interix-Specific Behaviors

The Interix environment conforms to the POSIX standards (1003.1 and 1003.2). Three behaviors of the Interix environment may surprise users of open systems:

  • Pathnames can contain drive letters, but Interix 3 uses a single rooted filesystem.

  • Interix has no super user

  • User authentication is different

Security on Windows

In the Windows security model users and groups share the same namespace in the Security Access database, rather than groups and users being separate as they are in UNIX.

Within the Interix subsystem, file ownership on the NTFS file-system behaves as the POSIX standard requires. If you're not going to exchange files between the Interix environment and the Win32 environment, you probably won't notice a difference. Under-standing the Windows security model makes it easier to understand interactions between the utilities from one environment and files from another. For example, chown , chgrp , and chmod may not behave as you expect on files created using Win32 applications.

User and group information is stored in the Security Access database. Both users and groups are stored in the same database, but group and user names must be unique; no group can have a user's name and vice versa. (This database replaces the /etc/passwd and /etc/groups files in UNIX.) Users and groups are created using the appropriate Windows methodology (User Manager, Active Directory Users and Computers, or Local Users and Groups) or with the Win32 net user command. (Example shell scripts to create and remove users are included in the directory /usr/examples/admin.) Users can belong to many groups.

File System

For a behavior closest to the one described in the Single UNIX Specification, you should install and use Interix on NTFS. NTFS supports all of the requirements of a POSIX file system.

  • Pathnames use / as the pathname separator.

  • Pathnames starting with /dev/fs/D, where D is an uppercase letter, refer to files on a particular drive. For example, pathnames beginning with /dev/fs/C are on the C: drive.

  • Filenames are case-sensitive (Temp, temp, and TEMP are all different files and the system can distinguish between them). On Windows XP this is optional – the Interix subsystem can be configured to be case preserving but case-insensitive on Windows XP.

    On a FAT file-system or across a network, file names are case-insensitive, though case is generally preserved. For reasons internal to Windows NT, file specifications using shell wildcards (such as ? or *) are case-sensitive on a FAT file-system and across a network.

  • NTFS filenames allow the full character set specified by POSIX.1.

    The following characters are not allowed in filenames:

    \ / : * ? ! | " < > control characters

    The directory name $$psxjunk is reserved for use by the POSIX subsystem.

  • Both hard links and symbolic links work (files can have more than one name).

  • Real user and group names appear as the file owner and file group when you do a long directory listing. (Note that files can be owned by a group, and not only by a user.)

    On a FAT or HPFS file-system, the user owns all files

    "Everyone" and the group "Everyone".

You can determine the type of a file-system by using the df command on a directory in that file-system.

If you are using both Interix utilities and Win32 applications on the same files, keep in mind the following:

  • Win32 applications do not provide access to case-sensitive file-names or to hard links.

  • Most Interix utilities expect lines in script files to end in a line-feed only. The Interix ed , ex , and vi editors maintain the files as found, but some Win32 editors do not.

Working with WIN32 Programs

Invoking/Stopping WIN32 Programs

Invoking Win32 Programs

When running a Win32 program from the Interix environment, keep in mind the distinction between the name of the program to be run and the arguments to the program. The name must be in POSIX format; the arguments must be in the format expected by the program (usually Win32 format).

You can start the Notepad program with the command

/dev/fs/C/WINNT40/system32/notepad.exe

assuming your Win32 programs are stored in /dev/fs/WINNT40/system32 and that the Notepad program file is named notepad.exe. Since case is important in the Interix system, this may not work if the program is actually named NOTEPAD.EXE. (Case is important if the Win32 program is installed on an NTFS file-system.)

Interix 3 hides much of this complexity, however, by including a set of shell scripts to hide the requirement for knowing where notepad.exe is located, or whether it is "notepad.exe", or "Notepad.exe", or even "NOTEPAD.EXE". These scripts are located in /usr/contrib./win32/bin and allow you to start the Notepad program by simply typing "notepad".

If you wanted to start Notepad to edit the DOS file c:\readme.txt, use the command:

notepad C:\\readme.txt

The argument, the pathname of the file readme.txt, is in the Win32 format. The double \ is necessary because the Interix shells treat backslash as special. You could also surround the filename in quotes, either single or double, like this:

notepad 'C:\readme.txt'

For those programs which don't have already created shell scripts to handle this, you can get around the most annoying parts of the problem by creating your own shell scripts, or using aliases, symbolic links, and similar techniques to hide the complexities of where a program is located and what it's case is, etc.

Stopping Win32 Programs

In earlier versions of Interix, you could not stop a Win32 program using the Interix kill utility. However, in version 3, this has been changed and you can stop Win32 programs just as if they were started from the Interix subsystem. You can use ps to list any Win32 process, whether started from an Interix process or a Win32 process.

Note: Although you can kill an Interix process using the Task Manager or TKILL.EXE, you should not do this. When an Interix process is killed from the Win32 environment, certain important clean-up functions are not performed. The results (especially if you make a habit of it) are likely to be both subtle and bad.

File Redirection

Win32 programs can accept input redirected from standard in (as in < file); you can also redirect their standard output (with > file) and their standard error.

Win32 programs can also be used in command pipelines. But some Win32 programs are not well-behaved; they "poison" any pipeline they feed into. In order to provide more robust behavior when piping to and from Win32 programs, Interix includes a Win32 utility, cat32.exe, which is simply a "better behaved" filter. For example, if you experience problems with a particular Win32 program in a pipeline, try inserting cat32 into the pipeline as shown below:

$ net.exe users | cat32 | more

Services and Daemons

The Windows system provides a Service Control Manager, which handles services. Services are either automatic (are begun on system startup) or manual (must be started by the user).

The Services applet in the Control Panel is one way of controlling services on Windows; using the Services applet, you can add, remove, view, start, and stop services. For security reasons, each running service is affiliated with a user and a password and has its own unique ID number. Most services are associated with the user "Local System" which is provided for that purpose and doesn't require a password. Information on each service is available in the Registry, but it's normally invisible to the user.

In order to run a service, your user account must have the "Service Logon Right" privilege. This privilege is automatically given to your account the first time you start or install a service using the Interix service utility. It is possible for the Administrator to remove that right from your account; however, and then you wouldn't be able to run services.

A service has no console display. You cannot send a signal to a service using kill, though you can stop it using the Services applet of the Control Panel or using the service utility.

A service runs in a minimal environment. It has only the environment assigned to the system's "Default User" (see the System applet of the Control Panel), plus the TZ environment variable. Its standard input, output, and error are all redirected to /dev/null.

Cron Service

The cron service runs commands according to a schedule. Each user gets a personal cron service, but the user's account name must be added to the cron.allow file to permit you to use cron. You add, delete, and edit commands run by cron using the crontab utility.

In Services for UNIX v3.0, there are both Win32 and Interix based cron services. The controlling files for the Win32 based cron are located in %WINDIR%\system32\drivers\etc\cron, while the ones for the Interix based cron are located in /usr/lib/cron.

Cron is different from most other services because cron provides a more extensive environment and mails you the standard output and standard error of the command. A cron job sets the following environment variables in the execution environment: $HOME (your home directory), $LOGNAME (your login name), $PATH (a PATH that is guaranteed to find the Interix utilities, though it won't necessarily be your PATH), and $SHELL (the pathname to sh ).

Telnet & Syslog Daemons

The Telnet Daemon

The telnet daemon telnetd is provided as part of Interix, but is disabled in inetd.conf by default, since the Win32 based Telnet Service is installed with Services for UNIX version 3.0. You may only run one telnet server, so you must disable the Win32 telnet service prior to enabling the Interix telnetd.

When you are running the telnet daemon on your machine, other users can login to your machine (using a telnet client), if they have accounts on your machine.

The Syslog Daemon

The syslog daemon, syslogd, is a facility for storing and rerouting log messages from applications and system services. The syslogd facility is administrative: when something goes wrong, you can check the log files for any relevant messages, or have them written to your terminal screen or to another computer.

Syslogd handles only INTERIX processes which were written to use the syslog() API; it does not handle log messages from the Win32 sub-system. (For those, use the Windows NT Event Log and Event Viewer.)

If syslogd is not running as a service, messages intended for syslogd are all appended to the file /var/adm/log/logger.

Note: This file, like all log files, can grow very large. Check it regularly and shorten or delete it when it grows too large.

By default, syslogd is started by init. To run syslogd as a Windows service, you can install it using service:

  1. Log into the Administrator account.

  2. From an INTERIX shell, install the service using the service command. Syslogd must have the -s option:

    $ service install /bin/syslogd –s

  3. Once installed as a service, you must start it by using the following command:

    $ service start syslogd

    The syslogd service is configured with the file syslog.conf in the /etc/ directory.

SFU 3.0 (Interix) Enhancement Overview

  • Integration of SFU and Interix

    • Coherent installation

    • Clean set of tools and utilities

    • Network Drive Access through /net

  • Single Rooted File System

  • User Name Mapping support

  • Support for Symbolic Links

  • Support proper setuid/setgid semantics

  • Resource accounting support

  • UNIX domain sockets

Several important features have been added to Interix in Microsoft Windows Services for UNIX 3.0.

Integration of SFU and Interix

Clean set of tools and utilities

Principal domain name

The Interix subsystem concept of a "principal domain" can now be used to reduce the length of displayed user and group names. The principal domain is separate from the system's primary domain. The primary domain for a system is the domain to which the system is joined; that is, the domain displayed in System Properties. The Interix principal domain is set by default to the system primary domain, but can be altered from it.

For example, when the primary domain for the system is WESTCORP and users are also in the WESTCORP domain, by default, the Interix principal domain will be WESTCORP. A command such as who will display a user named Carl in the WESTCORP domain as just Carl. A user from another domain, such as Susannah in EASTCORP, will be displayed as EASTCORP+Susannah.

No /bin/ksh.exe or /bin/csh.exe files

You can still start the Korn shell or the C shell from the Windows cmd.exe command line by typing ksh -l or csh -l, respectively. Both commands now call batch files, ksh.bat or csh.bat, instead of executable files. The ksh.bat file consists primarily of posix /u /c /bin/ksh %1 %2 %3 %4 %5 %6 %7 %8 %9; the csh.bat file consists primarily of posix /u /c /bin/csh %1 %2 %3 %4 %5 %6 %7 %8 %9. The /u option enables posix.exe to use a UNIX-style path. These commands also work for starting the Interix shells from a shortcut.

A new environment variable called PATH_WINDOWS

Windows style cmd searching is implemented in the Korn shell using the PATH_WINDOWS environment variable. You can use this variable to specify the directories that require case-insensitive searching and suffix matching. For example, you will see the results of the Windows ipconfig command in a Korn shell, if the PATH_WINDOWS environment variable contains the /dev/fs/C/WINNT/system32 directory.

Access to NFS-mounted files using Client for NFS

This includes the ability to look up, create, delete, read, and write files over NFS. Also, you can create and resolve symbolic links through NFS.

Network Drive Access through /net

The /net virtual directory provides a mechanism for accessing files on the network that is similar to the Windows Universal Naming Convention (UNC). For example, the file \\Saturn\marketing\report.xls can be referred to within Interix as /net/Saturn/marketing/report.xls.

Single-rooted file system

Interix maps the root directory (/) to the SFU installation directory, which is typically C:\SFU. Under the Interix root directory, you will find the subdirectories that would usually exist in UNIX, such as /usr and /etc, and symbolic links that map to Windows drive letters, such as /A and /C. There are also special virtual directories, such as /net for network resources and /dev for devices. In addition to entries for the usual devices, the /dev directory includes entries that correspond to Windows drive letters. For example, /fs/A, /fs/C, and /fs/D correspond to drive A:, drive C:, and drive D:, respectively.

User Name Mapping support

Interix uses User Name Mapping (when available) to associate Windows users with user identifiers (UIDs) and group identifiers (GIDs). This ensures that resource ownership information will be consistent across computers.

Interix includes symbolic links that are based on the XPG4 version 2 specification (Single UNIX Specification). A symbolic link is a file that refers to another file name instead of data. You can create multiple symbolic links to a file to enable access from multiple locations. For example, if you create symbolic links from /tmp/hosts and /usr/hosts to /etc/hosts, you can look up the hosts file from either /tmp/hosts or /usr/hosts. You can also use symbolic links with directories. You create symbolic links with the -s option on the ln command.

The super user account and appropriate privileges

On many systems, a root or super user has complete control of the system. The Interix subsystem does not recognize a root user. When the POSIX standard was developed, the concept of a root user was considered an administrative issue. Instead of a root user, the POSIX standard defines appropriate privileges for some operations.

Support proper setuid/setgid semantics

The setuid and setgid mechanisms allow a program, when run, to adopt certain aspects of a security principal other than that of the user running the program. In other words, the setuid and setgid mechanisms allow an application to control the answer to the question, "Who are you?" Appropriate privileges answer the question, "What can you do?"

Appropriate privileges are typically required for a variety of actions. These include accessing the file system, sending signals to other processes (process control), or changing the effective user identifier (UID) or group identifier (GID) for a process in order to change the ability of that process to perform certain actions.

A file has permissions that include bits to set a UID (setuid) and set a GID (setgid). If either or both bits are set on a file, and a process executes that file, the process gains the UID or GID of the file. In the case of Interix, when a process executes a file that has the setuid or setgid bit set, Interix constructs local security tokens for the process with the privileges assigned to the owner or group of the file. Because the tokens are local, they are not recognized by other computers on the network. This means that, even if the file is owned by a member of the Domain Administrators group, for example, the process will not have trusted access through Windows networking to other computers in the domain. Instead, the privileges will be effective only on the computer on which the process is running.

For the setuid() or setgid() API functions, a process must have the effective UID that maps back to the system account, the administrator account for the local domain, or the administrator account for the principal domain. The local administrator account can only change the UID or GID to another ID in the same domain.

Resource accounting support

Interix now support the getrlimit() and setrlimit() API calls to control the consumption of resources by the calling process, but is only a partial implementation. A call to one of these functions identifies a resource to be operated on as well as a resource limit. A process may set the soft limit to any value less than or equal to the hard limit, or lower the hard limit down to the current soft limit.

The getrlimit() and setrlimit() deal with the following resources:

  • The maximum size, in bytes, of a core file created by this process.

  • The maximum time, in seconds, of CPU time a process can use. If the process exceeds this time, the system generates SIGXCPU for the process.

  • Maximum size in bytes of a process' data segment.

  • The maximum size, in bytes, of a file created by a process.

  • The highest possible value for a file descriptor, plus one.

  • The maximum size, in bites, of a process' stack.

  • Maximum size in bytes of a process' total available memory.

UNIX domain sockets

UNIX domain socket semantics are supported in the subsystem. Your applications can open UNIX domain sockets and use them for inter-process communication.

SFU 3.0 (Interix) Lab Objectives

  • Product Installation

  • Product Walk-Through

  • Porting Examples

Lab 2: SFU 3.0 Installation

The installation of SFU 3.0 (Interix) on a Windows 2000 Advanced Server machine is a straightforward process and is essentially identical to the SFU 2.0 and Interix 2.2 installation process. The only major difference is that now you can install all the components (i.e. both SFU and Interix) together because the two products have been integrated. Therefore, because the installation of SFU 3.0 Beta has already been completed we will not repeat the steps as part of this lab.

Lab 3: Product Walk-through

Overview

This section will walk you through the various aspects of the Interix software and services, and how they interact with the Windows environment. This section will cover installing Unix services as Windows services and review commands, shells, the file system, etc.

Lab Tasks

In this lab you will perform the following tasks:

  • Explore the Interix Single-rooted file-system

  • Use System Administration tools

Exercise 3-1: Explore the Interix Single-rooted file-system

With the release of SFU 3.0, a single-rooted file system and a more "standard" UNIX file hierarchy are now supported.

To explore some of the characteristics of the single-rooted file-system of Interix, perform the following steps:

  1. Start a Korn shell by clicking StartProgramsService for Unix AdministrationKorn Shell.

  2. To display the current SFU 3.0 file system and the initial file hierarchy, enter the following commands:

$ pwd /dev/fs/H $ ls -al / total 176 dr-xr-xr-x 1 0 0 0 Jun 11 20:56 . dr-xr-xr-x 1 0 0 0 Jun 11 20:56 .. lrwxr-xr-x+ 1 +Administrators Domain Users 9 Jun 7 18:35 A -> /dev/fs/A lrwxr-xr-x+ 1 +Administrators Domain Users 9 Jun 7 18:35 C -> /dev/fs/C lrwxr-xr-x+ 1 +Administrators Domain Users 9 Jun 7 18:35 D -> /dev/fs/D lrwxr-xr-x+ 1 +Administrators Domain Users 9 Jun 7 18:35 E -> /dev/fs/E lrwxr-xr-x+ 1 +Administrators Domain Users 9 Jun 7 18:35 F -> /dev/fs/F lrwxr-xr-x+ 1 +Administrators Domain Users 9 Jun 7 18:35 G -> /dev/fs/G lrwxr-xr-x+ 1 +Administrators Domain Users 9 Jun 7 18:35 H -> /dev/fs/H drwxrwxr-x 1 +Administrators +SYSTEM 0 Jun 7 18:32 Mapper drwxrwxr-x 1 +Administrators +SYSTEM 4096 Jun 7 18:31 TlntW2K drwxrwxr-x 1 +Administrators +SYSTEM 8192 Jun 7 18:32 admin drwxrwxr-x 1 Administrator +Administrators 45056 Jun 7 18:33 bin drwxrwxr-x 1 Administrator +Administrators 16384 Jun 7 18:35 common dr-xr-xr-x 1 0 0 0 Jun 11 20:56 dev drwxrwxr-x 1 +Administrators +SYSTEM 0 Jun 7 18:32 docs drwxrwxr-x 1 Administrator +Administrators 4096 Jun 7 18:32 etc drwxrwxr-x 1 +Administrators +SYSTEM 4096 Jun 11 10:05 help lr--r--r-- 1 Administrator +Administrators 7 May 28 01:56 lib -> usr/lib drwxrwxr-x 1 +Administrators +SYSTEM 0 Jun 7 18:31 log dr-xr-xr-x 1 0 0 0 Jun 11 20:56 net drwxrwxr-x 1 +Administrators +SYSTEM 0 Jun 7 18:32 nfs dr-xr-xr-x 1 0 0 0 Jun 11 20:56 proc drwxrwxrwt 1 Administrator +Administrators 0 Jun 7 18:43 tmp drwxrwxr-x 1 Administrator +Administrators 4096 Jun 7 18:33 usr drwxrwxr-x 1 Administrator +Administrators 0 Jun 7 18:32 var $

Notice that the initial working directory location is now under a directory: **/dev/fs**

Also notice that we now have the "typical" UNIX directories (e.g. bin, etc, lib, tmp, usr, var) directly under the Interix subsystem root (i.e. "/" ).

Another change to observe (from the listing above) is the automatic creation of symbolic links for each of the drive letters under /dev/fs (e.g. C -\> /dev/fs/C, the "l" in the first column denotes the fact that this is a symbolic link). This allows us to enter a command like the following to obtain a listing of the directories and files under the C: drive:

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

$ ls -al /C

…instead of requiring enter of the following (less characters to enter…UNIX system administrators love fewer key strokes):

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

$ ls -al /dev/fs/C

  1. Now enter the following command:

$ ls -al /dev/fs ls: A: Input/output error ls: G: Input/output error total 48 drwxrwxrwx 1 +Administrators +Administrators 8192 Jun 7 18:21 C drwxrwxrwx 1 +Administrators +Administrators 8192 Jun 11 16:25 D drwxrwxrwx 1 +Administrators +Administrators 4096 Jun 7 18:21 F drwxrwxrwx 1 +Administrators +Administrators 4096 Jun 7 18:43 H $

Notice that the directory **/dev/fs**, has all the drive letters "mounted" under it, including C, the installation drive for our installation of SFU 3.0 and where the default initial working directory is located. This is also where any network mounted drives will be located. Note that A: and G: are not "mounted" because no floppy disk is installed in the A: drive and no cdrom is installed in the G: cdrom drive.
  1. Now enter the following command (i.e. all servers on the network are located under; /net):

$ ls /net/lnxdell etc tmp $

This allowed us to list the shares that are available on the Linux *lnxdell* server from the Korn Shell command line. Now enter the following command to list the file folders (directories) and files under the "tmp" share (resource name) on the Linux *lnxdell* server:

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

$ ls /net/lnxdell/tmp LinuxProg my_fifo orbit-ltwork orbit-root tksysv-backup $

This listed the directories/files under the /tmp share on the *lnxdell* system. Similarly we can enter the same commands for a Windows 2000 server system.

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

$ ls /net/ltworksrv1 DriveC $ ls /net/ltworksrv1/DriveC AUTOEXEC.BAT NTDETECT.COM boot.ini CONFIG.SYS Program Files bootsect.lnx Documents and Settings System Volume Information let.txt IO.SYS WINNT let2.txt Inetpub arcldr.exe ntldr MSDOS.SYS arcsetup.exe pagefile.sys

  1. The above commands also have equivalents in a Windows command shell (cmd.exe) as follows:

C:&gt;ls \lnxdell etc tmp C:&gt;ls \lnxdell\tmp LinuxProg orbit-ltwork tksysv-backup my_fifo orbit-root C:&gt;ls \ltworksrv1 DriveC C:&gt;ls \ltworksrv1\DriveC AUTOEXEC.BAT NTDETECT.COM boot.ini CONFIG.SYS Program Files bootsect.lnx Documents and Settings System Volume Information let.txt IO.SYS WINNT let2.txt Inetpub arcldr.exe ntldr MSDOS.SYS arcsetup.exe pagefile.sys C:&gt;

**Note:** Summary of network file naming syntax:

<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr class="header">
<th><p>FS Type</p></th>
<th><p>Interix Naming</p></th>
<th><p>Win32 Naming</p></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><ul>
<li><p>CIFS</p></li>
</ul></td>
<td><ul>
<li><p>/net/&lt;cifs_server_name&gt;/&lt;resource name&gt;</p></li>
</ul></td>
<td><ul>
<li><p>\\&lt;cifs_server_name&gt;\&lt;resource name&gt;</p></li>
</ul></td>
</tr>
<tr class="even">
<td><ul>
<li><p>NFS</p></li>
</ul></td>
<td><ul>
<li><p>/net/&lt;nfs_server_name&gt;/&lt;resource name&gt;</p></li>
</ul></td>
<td><ul>
<li><p>\\&lt;nfs_server_name&gt;\&lt;resource name&gt;</p></li>
</ul></td>
</tr>
</tbody>
</table>
  1. Next, you can mount an exported Linux NFS file share using the mount command as follows:

C:&gt;mount lnxdell:/tmp I:

And now enter the following command from the Korn Shell and notice the change in the output from the same command in step 3 above (the change is bolded for clarity):

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

$ ls -al /dev/fs ls: A: Input/output error ls: G: Input/output error total 48 drwxrwxrwx 1 +Administrators +Administrators 8192 Jun 7 18:21 C drwxrwxrwx 1 +Administrators +Administrators 8192 Jun 11 16:25 D drwxrwxrwx 1 +Administrators +Administrators 4096 Jun 7 18:21 F drwxrwxrwx 1 +Administrators +Administrators 4096 Jun 7 18:43 H drwxrwxrwx 9nobody
nogroup 0 Jun 12 03:02 I $

Notice that the directory **/dev/fs**, has all the drive letters "mounted" under it, including I, the network mounted drive we just created with the mount command. Now enter the following commands (the first to list the file folders and files mounted under /dev/fs/I, the second will fail):

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

$ ls /dev/fs/I LinuxProg my_fifo orbit-ltwork orbit-root tksysv-backup $ ls /I ls: /I: No such file or directory

Why didn't the second command work (i.e. provide the same output as ls /dev/fs/I)? (Hint: review the discussion of symbolic links and drive letters earlier in this exercise.)

Exercise 3-2: Using System Administration Tools

In this exercise we will explore some of the system administration tools available with SFU 3.0.

  1. Start a Korn shell by selecting StartProgramsService for Unix AdministrationKorn Shell.

  2. Enter the dnsquery command as follows to query the DNS server for information about the Linux server lnxdell:

$ dnsquery –n 19.1.2.100 lnxdell.AdforLinux.com ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31794 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; lnxdell.ADforLinux.com, type = ANY, class = IN lnxdell.ADforLinux.com. 1H IN A 19.1.2.201 $

  1. Enter the fileinfo command as follows to query SFU for the version number of the Interix (POSIX) subsystem files:

$ fileinfo /dev/fs/C/WINNT/system32/PSXSS.EXE 7.0.1620.1 /dev/fs/C/WINNT/system32/PSXDLL.DLL 7.0.1620.1 /dev/fs/C/WINNT/system32/POSIX.EXE 7.0.1620.1 /dev/fs/C/WINNT/system32/PSXRUN.EXE 7.0.1620.1

**Note:** Notice the number 1620, which denotes SFU 3.0 RC1 in our case, was used for these lab exercises.
  1. Enter the last command to list the last logins of users and ttys:

$ last user1 ttyn01 localhost Tue Jun 5 13:19 still logged in user1 ttyn01 localhost Tue Jun 5 13:19 - 13:19 (00:00) user1 ttyn01 localhost Tue Jun 5 12:58 - 13:19 (00:20) user1 ttyn01 localhost Tue Jun 5 12:58 - 12:58 (00:00) user1 ttyn02 localhost Tue Jun 5 12:58 still logged in user1 ttyn01 localhost Tue Jun 5 12:58 - 12:58 (00:00) user1 ttyn01 localhost Tue Jun 5 12:20 - 12:20 (00:00) user1 ttyn01 localhost Tue Jun 5 12:19 - 12:20 (00:00) user1 ttyn01 localhost Tue Jun 5 12:19 - 12:19 (00:00) user1 ttyn01 localhost Tue Jun 5 12:19 - 12:19 (00:00) user1 ttyn01 localhost Tue Jun 5 12:19 - 12:19 (00:00) UnknownUser ttyn01 localhost Tue Jun 6 10:15 - 12:19 (02:03) UnknownUser ttyn01 localhost Tue Jun 6 10:15 - 10:15 (00:00) ltwork ttyn01 localhost Tue Jun 6 10:12 - 10:15 (00:02) ltwork ttyn01 localhost Tue Jun 6 10:12 - 10:12 (00:00) UnknownUser ttyn01 localhost Tue Jun 6 10:11 - 10:12 (00:00) UnknownUser ttyn01 localhost Tue Jun 6 10:11 - 10:11 (00:00) user1 ttyn00 localhost Tue Jun 6 09:58 still logged in ltwork ttyn00 localhost Tue Jun 6 09:52 - 09:58 (00:06) UnknownUser ttyn01 localhost Tue Jun 6 09:48 - 10:11 (00:23) UnknownUser ttyn01 localhost Tue Jun 6 09:48 - 09:48 (00:00) UnknownUser ttyn01 localhost Tue Jun 6 09:45 - 09:45 (00:00) ltwork ttyn00 localhost Tue Jun 6 09:34 - 09:52 (00:17) Administrator ttyn00 localhost Tue Jun 6 09:34 - 09:34 (00:00) Administrator ttyn00 localhost Mon Jun 4 17:38 - 09:34 (15:55) Administrator ttyn00 localhost Mon Jun 4 17:38 - 17:38 (00:00) Administrator ttyn00 localhost Mon Jun 4 16:37 - 17:37 (00:59) Administrator ttyn00 localhost Mon Jun 4 16:37 - 16:37 (00:00) Administrator ttyn00 localhost Mon Jun 4 16:37 - 16:37 (00:00) Administrator ttyn00 localhost Mon Jun 4 16:37 - 16:37 (00:00) . new time localhost Mon Jun 4 16:10 still logged in . old time localhost Mon Jun 4 16:10 still logged in . system boot localhost Mon Jun 4 16:10 still logged in Administrator ttyn00 localhost Mon Jun 4 15:21 - 16:37 (01:16) Administrator ttyn01 localhost Mon Jun 4 15:21 - 09:45 (18:24) Administrator ttyn01 localhost Mon Jun 4 14:37 - 15:21 (00:44) Administrator ttyn00 localhost Mon Jun 4 10:51 - 15:21 (04:29) Administrator ttyn00 localhost Mon Jun 4 10:49 - 10:51 (00:02) Administrator ttyn00 localhost Mon Jun 4 10:49 - 10:49 (00:00) . new time localhost Mon Jun 4 05:38 - 16:10 (10:32) . old time localhost Mon Jun 4 05:38 - 16:10 (10:32) . system boot localhost Mon Jun 4 05:38 - 16:10 (10:32) Administrator ttyn00 localhost Fri Jun 1 11:16 - 10:49 (2+23:32) Administrator ttyn00 localhost Thu May 31 18:42 - 11:16 (16:34) . new time localhost Thu May 31 18:39 - 05:38 (3+10:58) . old time localhost Thu May 31 18:39 - 05:38 (3+10:58) . system boot localhost Thu May 31 18:39 - 05:38 (3+10:58) . new time localhost Thu May 31 18:36 - 18:39 (00:03) . old time localhost Thu May 31 18:36 - 18:39 (00:03) . system boot localhost Thu May 31 18:36 - 18:39 (00:03) wtmp begins Thu Jun 1 18:36

  1. To change password you can use the passwd command, for example:

$ passwd Enter old password: Re-enter old password: New password: Re-enter new password: $

  1. To list the current domain use the pdomain command, for example:

$ pdomain ADFORLINUX

SFU 3.0 (Interix) Porting

Caveats of Porting with SFU 3.0

Open Systems (e.g. SVR4 or BSD) Shell Script Porting Caveats:

  • Most shell scripts from a traditional UNIX system work because pathname notation, $PATH, and the #! notation are supported along with proper device names such as /dev/null.

  • Interix now has a standard UNIX file hierarchy and a single root. On Interix, absolute pathnames that begin with a single slash (or three or more slashes) are taken as referring to the root of the Interix (SFU) installation.

    Absolute pathnames normally do not need to be converted, since symbolic links can be added to handle most situations.

    Typical symbolic link creation would include:

    /usr/ucb /usr/contrib/bin

    /usr/local/bin /usr/contrib/bin

  • The #! notation in Interix allows the script to name its own interpreter, and typically does NOT require any modification.

  • $PATH separation is accomplished using ":"

  • Several useful tools are provided by Interix to allow powerful scripts to be built around Win32 based executables:

    • chgpath, ntpath2posix, posixpath2nt, winpath2unix, unixpath2win: convert between path syntax styles

    • cat32: used to handle poorly constructed Win32 command line tool output

    • wvisible: tests whether the user is running on the root window. (Prevent them from running a Win32 GUI app on a telnet session)

    • runwin32: Runs entire command lines from the Win32 world managing command line syntax conversions.

  • By default, Interix stores system binaries in one of two directories: /bin and /usr/contrib. It stores the X11 and Win32 binaries in the directories /usr/X11R5/bin and /usr/contrib/win32/bin, respectively. A symbolic link has also been added so that /usr/bin /bin, and therefore, modification of absolute paths from /usr/bin => /bin are no longer required.

  • Both symbolic and hard links are supported.

  • Interix now supports setuid/setgid (e.g. scripts that change EUID or EGID to another owner).

  • Any scripts that rely on information from /etc/passwd or /etc/group (e.g. grep for a username) will need to be modified to use other techniques to obtain information about a user, for example:

    • Win32 ADSI scripts

    • Win32 net users commands

    • Calls to Interix getpwent(), setpwent(), getgrent(), setgrent() APIs

Porting Applications Written in C: An Overview

The Interix subsystem is a POSIX.1-conformant subsystem. It supports sockets, BSD 4.4 interfaces, System V IPC mechanisms, pseudo terminals, memory mapped files, UNIX domain sockets, and much more.

The typical porting process is to type make (utility that runs an application specific configuration file, "Makefile" is the default, that specifies the steps necessary to create the application binary) in the source directory and then fix the problems as the compiler reports them. The most common change required is to select the appropriate compile flags for a POSIX.1 system (part of the definitions found in the Makefile configuration file).

A set of ported sources are installed in /usr/examples. For each file that required changes from the publicly available source, a diff file has been included.

Porting Applications Written in C Caveats:

The following types of programs do not port well:

  • Programs that use syscall() (Note: this also creates a problem for programs ported to Linux).

  • Programs that manipulate the kernel memory (/dev/kmem)

  • Programs that perform operations like ioctl or ioperm on anything that isn't a terminal or modem on a port

  • Programs that expect to perform raw i/o on a device (e.g. floppy, cdrom, hard drive)

  • Programs that "Chat" on the parallel port

  • Programs that rely on threads (e.g. apache 2.0)

Lab 4: SFU 3.0 (Interix) Porting Examples

Overview

The Lab will demonstrate how to port applications from the UNIX-only environment to the Windows 2000-Interix environment. The examples are meant to give a broad understanding of the concepts involved in porting applications and do not include all possible variations and/or problems associated with porting.

The Interix SDK provides the compiler interfaces cc, c89, gcc, and g++. To use cc, c89, you must already have Microsoft Visual C/C++ setup and running because cc and c89 invoke the MSVC utilities CL.EXE and LINK.EXE by searching your path for the programs. This is the case for these labs. The Interix header files work with both the MSVC and gcc compilers. You must use the g++ interface to compile C++ code (there will not be any C++ examples in this lab).

The last exercise, Failure Example, is designed to fail intentionally. One of the goals of this exercise is to allow the you to determine in a short amount of time whether or not Interix is the ideal solution for their particular situation. It is non-productive to spend many hours working on porting an application if in the end it will never work.

Porting Examples

  • Porting a Single-Rooted File System depend application

  • Porting a Program that uses Symbolic Links

  • Porting a Program that uses Resources and Limits

Lab Tasks

In this lab you will perform the following tasks:

  • Porting a Single-Rooted File System depend application

  • Porting a Program that uses Symbolic Links

  • Porting a Program that uses Resources and Limits

Exercise 4-1: Porting a Single-Rooted File System depend application

As discussed in Exercise 3, Interix now has a more "standard" Unix file hierarchy, and a file system with a single root. On Interix, absolute pathnames that begin with one or more slashes are taken as referring to the root of the Interix 3 (SFUv3) installation.

Let us look at a problem application for Interix 2.2 where we didn't have a single rooted filesystem. We will now find that the single-rooted file system and standard file hierarchy provide for a "clean" port.

  1. If you have a Linux system available, (lnxdell in the examples below), let's first verify the behavior there. If not, skip ahead to step #9. At the Telnet prompt, type:

    Microsoft Telnet> open lnxdell

  2. Logon to Telnet server computer as follows:

    login: devuser1 Password: devuser1

  3. If the file system.c has not already been created create it with the following text:

    Note: The following example is from Beginning Linux Programming, by Richard Stones and Neil Matthew, WROX ISBN 1-861002-97-1

    #include <unistd.h>
     #include <sys/stat.h>
     #include <fcntl.h>
     int main()
     {
         char c;
         int in, out;
         in = open("/tmp/file.in", O_RDONLY);
         out = open("/tmp/file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
         while(read(in,&c,1) == 1)
             write(out,&c,1);
         exit(0);
     }
  4. Verify the contents of the file by entering the following command to list the system program source code:

    [devuser1@lnxdell devuser1]$ cat system.c

  5. If the file /tmp/file.in doesn't already exist, create it with the following contents:

record 1 record 2 record 3

  1. Now enter the following command to compile and link the program:

    [devuser1@lnxdell devuser1]$ cc -o system system.c

  2. Verify that the program works by entering:

    [devuser1@lnxdell devuser1]$ cat /tmp/file.out

    The output should look like the following:

    cat: /tmp/file.out: No such file or directory

    Now enter the following command to execute the system program:

    [devuser1@lnxdell devuser1]$ ./system

    and then enter the following command to list the program's output file:

    [devuser1@lnxdell devuser1] $ cat /tmp/file.out

    Now the output should look like the following:

record 1 record 2 record 3

  1. To exit the remote machine, type the following at Telnet client prompt:

    Microsoft Telnet> quit

  2. To startup a Korn Shell and enter the following:

$ gcc -o system system.c

  1. Verify that /tmp/file.out does not exist by entering:

$ cat /tmp/file.out

The output should look like the following:

cat: cannot open file /tmp/file.out : No such file or directory
  1. If the file /tmp/file.in doesn't already exist, create it with the following contents:

record 1 record 2 record 3

  1. Now enter the following command to execute the system program::

$ ./system

and then re-enter the following command to list the program's output file:

$ cat /tmp/file.out

Now the output should look like the following:

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

record 1 record 2 record 3

This is because the root of the file system (i.e. "/") does have a directory named tmp , and that is what the program is referring to when it specifies "/tmp/file.out". With Interix 2.2, which did not support a single rooted filesystem and standard locations, there was no directory /tmp, thus the program would not work without modification.

In this lab exercise, we will see how Interix now supports symbolic links. Let us look at a "problem" application that would have failed to work correctly with Interix 2.2. We will now find that support for symbolic links, and therefore the lstat API (see Appendix A - Support for Symbolic Links), allows the program to function with symbolic links the way it was intended.

  1. Start a Korn Shell. If printdir.c exists, cat its contents which should look like those below, if not, create it with the text below.

    $ cat printdir.c

    Note: This example is from "Beginning Linux Programming", by Richard Stones and Neil Matthew, WROX ISBN 1-861002-97-1 with a modification to check for lstat API support

    You will see output that looks something like the following:

    /* We start with the appropriate headers and a function, printdir, which prints out the current directory. It will recurse for subdirectories, the depth parameter is used for indentation. */

#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> void printdir(char *dir, int depth) { DIR *dp; struct dirent entry; struct stat statbuf; if((dp = opendir(dir)) == NULL) { fprintf(stderr,"cannot open directory: %s\n", dir); return; } chdir(dir); while((entry = readdir(dp)) != NULL) { / The addition of the following check allows lstat to be included in the compilation when symbolic links are supported / #ifdef S_IFLNK lstat(entry->d_name,&statbuf); #else stat(entry->d_name,&statbuf); #endif if(S_ISDIR(statbuf.st_mode)) { / Found a directory, but ignore . and .. */ if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0) continue; printf("%s%s/\n",depth,"",entry->d_name); / Recurse at a new indent level */ printdir(entry->d_name,depth+4); } else printf("%s%s\n",depth,"",entry->d_name); } chdir(".."); closedir(dp); } / Now we move onto the main function. / int main(int argc, char argv[]) { char *topdir, pwd[2]="."; if (argc != 2) topdir=pwd; else topdir=argv[1]; printf("Directory scan of %s\n",topdir); printdir(topdir,0); printf("done.\n"); exit(0); } [devuser1@lnxdell devuser1]$

The program prints out the directory hierarchy specified in its command line argument or the current directory if none is specified.
  1. Now compile and link the printdir program as follows (notice we did not make any changes to the printdir.c source code):

$ gcc -o printdir printdir.c

  1. Enter the objdump command as follows on the new version of the printdir binary to show that lstat is in the headers of this version:

$ objdump -x printdir | grep stat 101c8 164 _lstat 102a6 106 _fstat [503](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 1) 0x000033b0 __statusfp __statusfp : [1175](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000d778 __lstat [1193](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000d808 __fstat [1238](sec -2)(fl 0x00)(ty 0)(scl 103) (nx 1) 0x000004d9 wk_lstat.asm [1260](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000ea40 ___lconv_static_decimal [1264](sec 4)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000100d8 __imp___lstat [1357](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000ea44 ___lconv_static_null [1378](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _lstat [1412](sec 4)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00010120 __imp___fstat

  1. Verify the program works by entering:

$ ./printdir

This will print out the files and folders in the current directory (devuser1). The change you will notice is that because this program now calls **lstat** (as originally intended) the link itself is stated and not the file that is obtained by tracing the links.

Why didn't we need to make a source code modification to affect this change? The reason is as follows:

In Exercise 10-5 from Section 1 we made the following change:

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

/* The addition of the following check allows lstat to be included in the compilation when symbolic links are supported */ #ifdef S_IFLNK lstat(entry->d_name,&statbuf); #else stat(entry->d_name,&statbuf); #endif

And if you were to look in version Interix 2.2 and version SFU 3.0 of the stat.h header file under …\\usr\\include\\sys you would see the following:

Interix 2.2 stat.h extract:

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

… … #define S_IFREG 0x08000 /* regular / #define S_IFSOCK 0x0C000 / socket / #if 0 / not implmented yet / #define S_IFLNK 0xA000 / symbolic link */ #endif … …

SFU 3.0 stat.h extract:

<pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">

… … #define S_IFREG 0x08000 /* regular / #define S_IFLNK 0x0A000 / symbolic link / #define S_IFSOCK 0x0C000 / socket */ … …

Since S_IFLNK is defined in SFU 3.0 the compiler's #ifdef S_IFLNK directive is true and lstat is included in the final linked binary automatically. No change in source code required.

Exercise 4-3: Porting a Program that uses Resources and Limits

In this lab exercise, we'll see how Interix now supports Resource Accounting (e.g. getrlimit(), setrlimit() - get or set resource limits, respectively) and Process Management (e.g. getpriority(), setpriority() - get or set process' nice, i.e. scheduling priority, value, respectively).

Let us look at a "problem" application for Interix 2.2 and we will see that with Interix 3 (SFUv3.0) the support for resource limit (see Appendix A – Resource accounting) and process management API's (see Appendix A – Process Management), allows the program to be ported and function on Interix.

  1. Create a file limits.c if it doesn't already exist. It should contain the following:

// 1 Make the includes for all the functions we're going to be using in this program. #include <sys/types.h> #include <sys/resource.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> // 2 The void function writes a string to a temporary file 10000 times and then performs some arithmetic // to generate load on the CPU. void work() { FILE f; int i; double x = 4.5; f = tmpfile(); for(i = 0; i < 10000; i++) { fprintf(f,"Do some output\n"); if(ferror(f)) { fprintf(stderr,"Error writing to temporary file\n"); exit(1); } } for(i = 0; i < 1000000; i++) x = log(xx + 3.21); } // 3 The main function calls work and then uses the getrusage function to discover how much CPU time it has used. It displays this information on screen. int main() { struct rusage r_usage; struct rlimit r_limit; int priority; work(); /* Interix Behavior: Does not support getrusage at a 2.2.5 release / getrusage(RUSAGE_SELF, &r_usage); printf("CPU usage: User = %ld.%06ld, System = %ld.%06ld\n", r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec, r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec); // 4 Next, it calls getpriority and getrlimit to find out its current priority and file size limits respectively. / Interix Behavior: Does not support getpriority at a 2.2.5 release / priority = getpriority(PRIO_PROCESS, getpid()); printf("Current priority = %d\n", priority); / Interix Behavior: Does not support getrlimit at a 2.2.5 release / getrlimit(RLIMIT_FSIZE, &r_limit); printf("Current FSIZE limit: soft = %ld, hard = %ld\n", r_limit.rlim_cur, r_limit.rlim_max); // 5 Finally, we set a file size limit using setrlimit and call work again, which fails because // it attempts to create too large a file. r_limit.rlim_cur = 2048; r_limit.rlim_max = 4096; printf("Setting a 2K file size limit\n"); / Interix Behavior: Does not support setrlimit at a 2.2.5 release */ setrlimit(RLIMIT_FSIZE, &r_limit); work(); exit(0); }

  1. Verify the contents of the file:

$ cat limits.c

**Note:** This example is from Beginning Linux Programming, by Richard Stones and Neil Matthew, WROX ISBN 1-861002-97-1 with some comments added about Interix version 2.2.5

You should see output that looks something like the above:
  1. Now enter the following command to compile and link this program:

$ gcc -o limits limits.c –lm

  1. Verify that the program works by entering:

$ ./limits CPU usage: User = 0.450000, System = 0.000000 Current priority = 2 Current FSIZE limit: soft = -1, hard = -1 Setting a 2K file size limit File size limit exceeded (core dumped)

The program worked as expected, that is, it sets a file size limit of 2K bytes and then fails (with a core dump) because it attempts to create a file that is too large (with a call to the work function).

Appendix A – Some API Additions to the Interix SDK from Interix 2.2 to SFU 3.0

Key Enhancements

Integration of SFU and Interix (and improved Windows Integration)

Function

Description

getloginenv()

Retrieve Win32 user environment

getpdomain()

Retrieve name of principal domain

path_casesensitive()

Ensure correct case of pathname

realpath()

Resolve pathnames (including symbolic links)

strcasestr()

Case-insensitive search for substring in a string

unixpath2win()

Convert an Interix pathname to Windows syntax

winpath2unix()

Convert a Windows pathname to Interix syntax

Single Rooted File System

chroot() - change root directory

Support for Symbolic Links

Function

Description

lstat()

Get file status (symbolic link support)

readlink()

Read the contents of a symbolic link

realpath()

Resolve pathnames (including symbolic links)

symlink()

Create symbolic link to a file

Support proper setuid/setgid semantics

Function

Description

seteuid(), setegid()

Set effective user and group ID respectively

setregid()

Set real and effective group ID

setreuid()

Set real and effective user ID's

Process Management

Function

Description

getpriority(), setpriority()

Get or set process' nice (i.e. scheduling priority) value

nice()

Change a process' nice (i.e. scheduling priority) value

usleep()

Suspend process execution for interval of microseconds

vfork()

Spawn a new process efficiently, sharing virtual memory

Resource accounting

Function

Description

getrlimit(), setrlimit()

Get or set resource limits, respectively

getdtablesize()

Return file descriptor table size (equivalent to getrlimit call with the option RLIMIT_NOFILE)

getrusage()

Get information about use of resources

Enhanced Memory Management APIs

Function

Description

brk(), sbrk()

Set or change space allocation

madvise()

Give advise about use of memory

mctl()

Control memory management

memcntl

Manage memory in mappings

mprotect()

Change access protections on memory mappings

msync()

Write pages to storage, synchronizing memory

Encryption (DES) APIs

crypt(), setkey(), encrypt(), des_setkey(), des_cipher()

Other Enhancements

Access user database

endpwent(), getpwent(), setpwent()

getpass() - get user's password

Account (user) database operations

getgrent(), getgrnam_nomembers(), getgrgid_nomembers(), getgrent_nomembers()

Group database operations

setgroupent(), setgrent(), endgrent()

Date and Time

Function

Description

ftime()

Get date and time

getitimer(), setitimer()

Get and set value of interval timer

settimeofday()

Set date and time

Directory/File operations

dirfd(), telldir(), seekdir()

fgetln() - get a line from a stream

fflush(), fpurge() - flush a stream

flock() - apply or remove an advisory lock on an open file

lockf() - lock sections of file with advisory-mode locks

mknod() - create a regular file, special file, or directory

setbuf(), setbuffer(), setlinebuf(), setvbuf() - stream buffering operations

truncate() - truncate a file to a specified length

Environment manipulation

env_alloc(), env_winlogin(), env_login(), env_cron(), env_free(), env_get(), env_set(), env_unset()

env_put(), env_array(), env_putarray(), env_expand_win(), env_strfree()

Floating-point number into a string

ecvt(), fcvt(), gcvt()

Functions for IEEE arithmetic

copysign(), drem(), copysignf(), finite(), finitef(), ilogb(), nextafter(), remainder(), scalbn(), scalbnf()

Get network/protocol entry

getnetent(), getnetbyaddr(), getnetbyname(), setnetent(), endnetent()

getprotoent() - get protocol entry

Message Catalog (Natural Language) Support

Function

Description

catclose()

Close message catalog

catgets()

Retrieve string from message catalog

catopen()

Open message catalog

Return a stream to a remote command

rcmd(), rresvport(), iruserok(), ruserok()

RPC - library routines for remote procedure calls

auth_destroy(), authnone_create(), authunix_create(), authunix_create_default()

callrpc(), clnt_broadcast(), clnt_call(), clnt_destroy(), clnt_create(), clnt_control(), clnt_freeres()

clnt_geterr(), clnt_pcreateerror(), clnt_perrno(), clnt_perror(), clnt_spcreateerror(), clnt_sperrno()

clnt_sperror(), clntraw_create(), clnttcp_create(), clntudp_create(), clntudp_bufcreate()

get_myaddress(), pmap_getmaps(), pmap_getport(), clnt_statpmap_rmtcall(), pmap_set()

pmap_unset(), registerrpc(), svc_destroy(), svc_freeargs(), svc_getcaller(), svc_getreqset()

svc_getreq(), svc_register(), svc_run(), svc_sendreply(), svcerr_auth(), svcerr_decode()

svcerr_noproc(), svcerr_noprog(), svcerr_progvers(), svcerr_systemerr(), svcerr_weakauth()

svcraw_create(), svctcp_create(), svcfd_create(), svcudp_bufcreate(), xdr_accepted_reply()

xdr_authunix_parms(), xdr_callhdr(), xdr_callmsg(), xdr_opaque_auth(), xdr_pmap(), xdr_pmaplist()

xdr_rejected_reply(), xdr_replymsg(), xprt_register(), xprt_unregister()

getrpcent(), getrpcbyname(), getrpcbynumber() - get RPC entry

getrpcport() - get RPC port number

Shared Object (Library) Management

Function

Description

dlclose()

Close shared library object

dlerror()

Report diagnostic information on dynamic linking

dlopen()

Open shared object

dlsym()

Get the address of a symbol from a dynamically-linked object

Signals

strsignal(), strsigname() - return string or name describing signal

ualarm() - schedule signal after specified time

Sockets

bindresvport() - bind a socket to a privileged IP port

socketpair() - create a pair of connected sockets

XDR - library routines for external data representation

xdr_array(), xdr_bool(), xdr_bytes(), xdr_char(), xdr_destroy(), xdr_double(), xdr_enum(), xdr_float()

xdr_free(), xdr_free(), xdr_getpos(), xdr_inline(), xdr_int(), xdr_long(), xdrmem_create(), xdr_opaque()

xdr_pointer(), xdrrec_create(), xdrrec_endofrecord(), xdrrec_eof(), xdrrec_skiprecord(), xdr_reference()

xdr_setpos(), xdr_short(), xdrstdio_create(), xdr_string(), xdr_u_char(), xdr_u_int(), xdr_u_long()

xdr_u_short(), xdr_union(), xdr_vector(), xdr_void(), xdr_wrapstring()

Miscellaneous

a64l(), l64a() - convert between a 32-bit integer and radix-64 ASCII

ftok() - Create key for IPC facilities

openpty() - open pseudo-terminal

strunvis(), unvis() - decode a visual representation of characters

strvis(), strvisx(), vis() - visually encode characters

t_accept - accept a connection request

varargs - variable argument lists