The standard C library, libc.a
, is automatically linked into your
programs by the gcc
control program. It provides many of the
functions that are normally associated with C programs. This document
gives the proper usage information about each of the functions and
variables found in libc.a
.
For each function or variable that the library provides, the definition of that symbol will include information on which header files to include in your source to obtain prototypes and type definitions relevant to the use of that symbol.
Note that many of the functions in libm.a
(the math library) are
defined in math.h
but are not present in libc.a. Some are, which
may get confusing, but the rule of thumb is this--the C library
contains those functions that ANSI dictates must exist, so that you
don't need the -lm
if you only use ANSI functions. In contrast,
libm.a
contains more functions and supports additional
functionality such as the matherr
call-back and compliance to
several alternative standards of behavior in case of FP errors.
See libm, for more details.
Debugging support functions are in the library libdbg.a
; link
your program with -ldbg
to use them.
#include <dos.h> extern int _8087;
This variable is provided for compatibility with other DOS compilers.
It contains 3
if a numeric coprocessor is installed, otherwise
0
. If the environment variable 387
is set to either
y
or n
, the value of _8087
reflects the override
(i.e., _8087
is unconditionally assigned the value 3 if
387
is set to y
, 0 if it is set to n
).
not ANSI, not POSIX
#include <stdlib.h> void abort(void);
When you call abort
, the message "Abort!" is printed on stdout
and the program is aborted by calling raise (SIGABRT)
(see SIGABRT). By default, this causes the CPU registers
and the call frame stack dump to be printed, and the program then exits
with an exit code of -1 (255). If the SIGABRT
signal is caught
by a handler that returns, the program exits with an exit code of 1.
This function does not return.
ANSI, POSIX
if ((q = malloc(100)) == NULL) abort();
#include <stdlib.h> int abs(int value);
The absolute value of value
is returned.
ANSI, POSIX
int sq = 7; sq = sq * abs(sq) + 1;
#include <unistd.h> int access(const char *filename, int flags);
This function determines what kind of access modes a given file allows.
The parameter flags is the logical or
of one or more of the
following flags:
R_OK
W_OK
X_OK
F_OK
D_OK
Zero if the requested access mode is allowed, nonzero if not.
not ANSI, POSIX
if (access("file.ext", W_OK)) return ERROR_CANNOT_WRITE; open("file.ext", O_RDWR);
#include <math.h> double acos(double x);
This function returns the angle in the range [0..Pi]
radians
whose cosine is x. If the absolute value of x is greater
than 1, a domain error occurs, and errno
is set to EDOM
.
The arc cosine, in radians, of x. If the absolute value of
x is greater than 1, the function returns a NaN
.
ANSI, POSIX
#include <math.h> double acosh(double x);
This function returns the inverse hyperbolic cosine of x.
The inverse hyperbolic cosine of x. If the value of x is
less than 1, the return value is NaN
and errno
is set to
EDOM
.
not ANSI, not POSIX
#include <mntent.h> int addmntent(FILE *filep, const struct mntent *mnt);
This function is a no-op for MS-DOS, but is provided to assist in Unix ports. See getmntent.
This function always returns nonzero to signify an error.
not ANSI, not POSIX
#include <unistd.h> unsigned alarm(unsigned seconds);
This function causes the signal SIGALRM
to be raised in
seconds seconds. A value of zero for seconds cancels any
pending alarm. If an alarm has previously been set, the new alarm delay
will supercede the prior call.
Note that signals in DJGPP are deferred when the program is inside a real-mode (e.g., DOS) call or isn't touching its data; see signal, for more details.
A misfeature of Windows 9X prevents the timer tick interrupt from being
delivered to programs that are in the background (i.e. don't have the
focus), even though the program itself might continue to run, if you
uncheck the Background: Always suspend property in the Property
Sheets. Therefore, alarm
will not work in background programs on
Windows 9X.
The number of seconds remaining on the timer (i.e. always seconds).
not ANSI, POSIX
signal(SIGALRM,my_alarm_routine); alarm(5);
#include <stdlib.h> void *alloca(size_t _size)
Allocate memory that will be automatically released when the current procedure exits. Note that, when compiling with gcc, alloca is a built-in function and not a library call.
A pointer to the memory, else NULL.
not ANSI, not POSIX
q = alloca(strlen(x)+1); strcpy(q, x);
#include <time.h> char *asctime(const struct tm *tptr);
This function returns an ASCII representation of the time represented by tptr. The string returned is always 26 characters and has this format:
Sun Jan 01 12:34:56 1993\n\0
The string pointed to is in a static buffer and will be overwritten with each call to asctime. The data should be copied if it needs to be preserved.
The layout of the struct tm
structure is like this:
struct tm { int tm_sec; /* seconds after the minute [0-60] */ int tm_min; /* minutes after the hour [0-59] */ int tm_hour; /* hours since midnight [0-23] */ int tm_mday; /* day of the month [1-31] */ int tm_mon; /* months since January [0-11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday [0-6] */ int tm_yday; /* days since January 1 [0-365] */ int tm_isdst; /* Daylight Savings Time flag */ long tm_gmtoff; /* offset from GMT in seconds */ char * tm_zone; /* timezone abbreviation */ };
A pointer to the string.
ANSI, POSIX
time_t now; time(&now); printf("The current time is %s", asctime(localtime(&now)));
#include <math.h> double asin(double x);
This function returns the angle in the range [-Pi/2..Pi/2]
whose
sine is x.
The inverse sine, in radians, of x. If the absolute value of
x is greater than 1, the return value is NaN
and
errno
is set to EDOM
.
ANSI, POSIX
#include <math.h> double asinh(double x);
This function returns the inverse hyperbolic sine of the argument x.
The inverse hyperbolic sine of x. If the argument x is a
NaN
, the return value is NaN
and errno
is set to
EDOM
. If x is a positive or negative Inf
, the
return value is equal to the value of x, and errno
is left
unchanged.
not ANSI, not POSIX
#define NDEBUG #include <assert.h> assert(expression); assertval(expression);
These macros are used to assist in debugging. The source code includes
references to assert
or assertval
, passing them
expressions that should be true
(non-zero). When the expression
yields false
(zero), a diagnostic message is printed to the
standard error stream, and the program aborts.
If you define the macro NDEBUG
before including assert.h
,
then these assert
and assertval
expand to nothing to
reduce code size after debugging is done.
assert
returns 1 if its argument is non-zero, else it aborts.
assertval
returns the value of its expression argument, if
non-zero, else it aborts.
ANSI (see note 1), POSIX (see note 2)
Notes:
assert
is ANSI, assertval
is not.
assert
is Posix, assertval
is not.
/* Like `strdup', but doesn't crash if the argument is NULL. */ char * safe_strdup(const char *s) { assert(s != 0); return strdup(s); }
#include <math.h> double atan(double x);
This function computes the angle, in the range [-Pi/2..Pi/2]
radians, whose tangent is x.
The arc tangent, in radians, of x. If x is a NaN
,
the return value is NaN
and errno
is set to EDOM
.
If x is a positive or negative Inf
, the return value is
equal to positive or negative Pi/2
, respectively, and
errno
is left unchanged.
ANSI, POSIX
#include <math.h> double atan2(double y, double x);
This function computes the angle, in the range [-Pi..Pi]
radians,
whose tangent is y/x
. In other words, it computes
the angle, in radians, of the vector (x,y) with respect to
the +x
axis, reckoning the counterclockwise direction as
positive, and returning the value in the range [-Pi, Pi]
.
The arc tangent, in radians, of y/x
. Pi
is
returned if x is negative and y is a negative zero,
-0.0
. -Pi
is returned, if x is negative, and
y is a positive zero, +0.0
.
If either x or y is infinite, atan2
returns,
respectively, Pi
with the sign of y or zero, and
errno
is left unchanged. However, if both arguments are
infinite, the return value is NaN
and errno
is set to
EDOM
.
A NaN
is returned, and errno
is set to EDOM
, if
either x and y are both zero, or if either one of the
arguments is a NaN
.
ANSI, POSIX
#include <math.h> double atanh(double x);
This function computes the inverse hyperbolic tangent of x.
The inverse hyperbolic tangent of x. If the the value of
x is plus or minus 1, the return value is an Inf
with the
same sign as the argument x, and errno
is set to
ERANGE
. If the absolute value of x is greater than 1, the
return value is NaN
and errno
is set to EDOM
.
not ANSI, not POSIX
#include <stdlib.h> int atexit(void (*func)(void));
This function places the specified function func on a list of
functions to be called when exit
is called. These functions are
called as if a last-in-first-out queue is used, that is, the last
function registered with atexit
will be the first function called
by exit
.
At least 32 functions can be registered this way.
Zero on success, non-zero on error.
ANSI, POSIX
void exit_func() { remove("file.tmp"); } ... atexit(exit_func); ...
#include <stdlib.h> double atof(const char *string);
Convert as much of the string as possible to an equivalent double precision real number.
This function is almost like strtod(string, NULL)
(see strtod).
The equivalent value, or zero if the string does not represent a number.
ANSI, POSIX
main(int argc, char **argv) { double d = atof(argv[1]); ...
#include <stdlib.h> int atoi(const char *string);
Convert as much of the string as possible to an equivalent integer value.
This function is almost like (int)strtol(string, NULL, 10)
(see strtol).
The equivalent value, or zero if the string does not represent a number.
ANSI, POSIX
main(int argc, char **argv) { int i = atoi(argv[1]); ...
#include <stdlib.h> long atol(const char *string);
Convert as much of the string as possible to an equivalent long integer value.
This function is almost like strtol(string, NULL, 10)
(see strtol).
The equivalent value, or zero if the string does not represent a number.
ANSI, POSIX
main(int argc, char **argv) { long l = atol(argv[1]); ...
#include <stdlib.h> long double _atold(const char *string);
Convert as much of the string as possible to an equivalent long double precision real number.
This function is almost like _strtold(string, NULL)
(see _strtold).
The equivalent value, or zero if the string does not represent a number.
not ANSI, not POSIX
main(int argc, char **argv) { long double d = _atold(argv[1]); ...
#include <unistd.h> char * basename (const char *fname);
This function returns the basename of the file, which is the last
part of its full name given by fname, with the drive letter and
leading directories stripped off. For example, the basename of
c:/foo/bar/file.ext
is file.ext
, and the basename of
a:foo
is foo
. Trailing slashes and backslashes are
significant: the basename of c:/foo/bar/
is an empty string after
the rightmost slash.
This function treats both forward- and backslashes like directory separators, so it can handle file names with mixed styles of slashes.
A pointer into the original file name where the basename starts. Note
that this is not a new buffer allocated with malloc
. If
fname is a NULL pointer, the function will return a NULL pointer.
not ANSI, not POSIX
if (strcmp (basename (file_name), "gcc.exe") == 0) printf ("The file %s is the GNU C/C++ compiler\n", file_name);
#include <string.h> int bcmp(const void *ptr1, const void *ptr2, int length);
Compare memory pointed to by ptr1 and ptr2 for at most length bytes.
The number of bytes remaining when the first mismatch occurred, or zero if all bytes were equal.
not ANSI, not POSIX
void f(char *s1, char *s2) { int l = bcmp(s1, s2, strlen(s1)); printf("Difference: %s, %s\n", s1+strlen(s1)-l, s2+strlen(s1)-l); }
#include <string.h> void bcopy(const void *source, void *dest, int length);
Copy length bytes from source to dest. Overlapping regions are handled properly, although this behavior is not portable.
No value is returned.
not ANSI, not POSIX
struct s a, b; bcopy(a, b, sizeof(struct s));
#include <dos.h> int bdos(int func, unsigned dx, unsigned al);
Calls function func of the software interrupt 0x21, passing it
al as the subfunction and (the lower 16 bit of) dx in the
DX
register. This function will only work for a subset of DOS
functions which require no arguments at all, or take non-pointer arguments
in the AL
and DX
registers only. For functions which
require a pointer in the DX
register, use bdosptr
(see bdosptr).
Whatever the called function returns in the AX register.
not ANSI, not POSIX
/* read a character */ int ch = bdos(1, 0, 0) & 0xff;
#include <dos.h> int bdosptr(int func, void *ptr, unsigned al);
Calls function func of the software interrupt 0x21, passing it
al as the subfunction and a pointer to a copy of the buffer contents
whose address is in ptr through the DX
register. This
function will only work for a subset of DOS which require an argument
in the AL
register and a pointer in DX
register. For
functions which require non-pointer arguments in the DX
register,
use bdos
(see bdos). To make the contents of ptr
available to DOS, bdosptr
copies it to the transfer buffer located
in the low (below 1 Meg mark) memory.
Currently, some of the functions which take a pointer to a buffer in
DX
are NOT supported (notably, most of the FCB-based
functions). See int86, for the list of supported functions.
Whatever the called function returns in the AX register.
not ANSI, not POSIX
/* print a string */ bdosptr(9, "Hello, there$", 0);
#include <bios.h> unsigned _bios_disk(unsigned cmd, struct diskinfo_t *di)
This function interfaces with the BIOS disk sevice (interrupt 0x13). The parameter cmd select the corresponding disk service and the structure di holds the disk parameters.
struct diskinfo_t { unsigned drive; /* Drive number. */ unsigned head; /* Head number. */ unsigned track; /* Track number. */ unsigned sector; /* Sector number. */ unsigned nsectors; /* Number of sectors to read/write/verify. */ void *buffer; /* Buffer for reading/writing/verifying. */ }
The following services are available based on value of cmd:
_DISK_RESET
_DISK_STATUS
_DISK_READ
_DISK_WRITE
_DISK_FORMAT
_DISK_VERIFY
Return value of AX register. The meaning of high-order byte (AH):
0x00 No error 0x01 Invalid request or a bad command 0x02 Address mark not found 0x03 Disk write protected 0x04 Sector not found 0x05 Reset failed 0x06 Floppy disk removed 0x07 Drive parameter activity failed 0x08 Direct Memory Access (DMA) overrun 0x09 DMA crossed 64K boundary 0x0A Bad sector flag detected 0x0B Bad track flag detected 0x0C Media type not found 0x0D Invalid number of sectors on format 0x0E Control data access mark detected 0x0F DMA arbitration level out of range 0x10 Data read (CRC or ECC) error 0x11 Corrected data read (ECC) error 0x20 Controller failure 0x40 Seek error 0x80 Disk timed out or failed to respond 0xAA Drive not ready 0xBB Undefined error 0xCC Write fault on drive 0xE0 Status error 0xFF Sense operation failed
not ANSI, not POSIX
char record_buffer[512]; struct diskinfo_t di; di.drive = 0x80; di.head = 0; di.track = 0; di.sector = 0; di.nsectors = 1; di.buffer = &record_buffer; if ( _bios_disk(_DISK_READ, &di) ) puts("Disk error.");
#include <bios.h> unsigned _bios_equiplist(void)
This function returns the equipment word from BIOS request 0x11. The bits correspond to the following values:
Bits Meaning 0 True (1) if disk drive(s) installed 1 True (1) if math coprocessor installed 2-3 System RAM in 16K blocks (16-64K) 4-5 Initial video mode: 00 = Reserved 01 = 40 x 25 color 10 = 80 x 25 color 11 = 80 x 25 monochrome 6-7 Number of floppy-disk drives installed (00 = 1, 01 = 2, etc.) 8 False (0) if and only if a Direct Memory Access (DMA) chip is installed 9-11 Number of RS232 serial ports installed 12 True (1) if and only if a game adapter is installed 13 True (1) if and only if an internal modem is installed 14-15 Number of printers installed
The equipment word.
not ANSI, not POSIX
if ( _bios_equiplist() & 0xc000 ) do_printing();
#include <bios.h> unsigned _bios_keybrd(unsigned cmd);
The _bios_keybrd
function uses INT 0x16 to access the keyboard
services. The cmd argument can be any of the following manifest
constants:
_KEYBRD_READ
_NKEYBRD_READ
_KEYBRD_READ
, this
command knows about keys introduced with the AT-style 101-key keyboards,
such as <F11> and <F12>, and can distinguish between the editing
keys on the numeric pad and the grey keys of the edit pad. On the other
hand, some of the extended keys return two-byte sequences which
typically begin with the E0h
(224 decimal) prefix, so code that
uses _NKEYBRD_READ
should deal with this complexity.
_KEYBRD_READY
_NKEYBRD_READY
_KEYBRD_READY
, but recognizes extended keys such as <F12>,
which _KEYBRD_READY
ignores.
_KEYBRD_SHIFTSTATUS
40h:17h
in the
BIOS data area):
7654 3210 Meaning ---- ---X Right SHIFT is pressed ---- --X- Left SHIFT is pressed ---- -X-- CTRL is pressed ---- X--- ALT is pressed ---X ---- Scroll Lock locked --X- ---- Num Lock locked -X-- ---- Caps Lock locked X--- ---- Insert locked
_NKEYBRD_SHIFTSTATUS
40h:17h
in the BIOS data area combined with the extended shift
flags from the bytes at addresses 40h:18h
and 40h:96h
):
FEDC BA98 7654 3210 Meaning ---- ---- ---- ---X Right SHIFT is pressed ---- ---- ---- --X- Left SHIFT is pressed ---- ---- ---- -X-- CTRL is pressed ---- ---- ---- X--- ALT is pressed ---- ---- ---X ---- Scroll Lock locked ---- ---- --X- ---- Num Lock locked ---- ---- -X-- ---- Caps Lock locked ---- ---- X--- ---- Insert locked ---- ---X ---- ---- Left CTRL is pressed ---- --X- ---- ---- Left ALT is pressed ---- -X-- ---- ---- Right CTRL is pressed ---- X--- ---- ---- Right ALT is pressed ---X ---- ---- ---- Scroll Lock is pressed --X- ---- ---- ---- Num Lock is pressed -X-- ---- ---- ---- Caps Lock is pressed X--- ---- ---- ---- SysReq is pressed
Return Value
With the *_READ
and *_SHIFTSTATUS
arguments, the
_bios_keybrd
function returns the contents of the AX
register after the BIOS call. For the *_READ
arguments, this is
the combination of scan code and ASCII code for alphanumeric keys, or a
scan code and either zero or the E0h
prefix for special keys.
With the *_READY
arguments, _bios_keybrd
returns 0 if no
key is waiting in the BIOS keyboard buffer. If there is a key,
_bios_keybrd
returns the key waiting to be read (that is, the
same value as the corresponding *_READ
would return).
With the *_READ
and *_READY
arguments, the
_bios_keybrd
function returns -1 if Ctrl+<BREAK> has
been pressed and is the next keystroke to be read.
not ANSI, not POSIX
while( !_bios_keybrd(_KEYBRD_READY) ) try_to_do_something();
#include <bios.h> unsigned _bios_memsize(void);
This function returns the amount of system memory in 1K blocks (up to 640K).
Size of memory (in K).
not ANSI, not POSIX
printf("This system has %d bytes of memory\n", _bios_memsize() * 1024);
#include <bios.h> unsigned _bios_printer(unsigned cmd, unsigned printer, unsigned data);
The _bios_printer routine uses INT 0x17 to perform printer output services for parallel printers. The printer argument specifies the affected printer, where 0 is LPT1, 1 is LPT2, and so on. The cmd argument can be any of the following manifest constants:
_PRINTER_INIT
Reset and initialize the specified printer port
_PRINTER_STATUS
_PRINTER_WRITE
The _bios_printer function returns the value in the AX register after the BIOS interrupt. The high-order byte (AH) of the return value indicates the printer status after the operation, as defined below:
Bit Meaning if True 0 Printer timed out 1 Not used 2 Not used 3 I/O error 4 Printer selected 5 Out of paper 6 Acknowledge 7 Printer not busy
not ANSI, not POSIX
while (*c) _bios_printer(_PRINTER_WRITE, *c++, 0);
#include <bios.h> unsigned _bios_serialcom(unsigned cmd, unsingned serialport, unsigned data);
The _bios_serialcom routine uses INT 0x14 to provide serial communications services. The serialport argument is set to 0 for COM1, to 1 for COM2, and so on. The cmd argument can be set to one of the following manifest constants:
_COM_INIT
_COM_RECEIVE
_COM_SEND
_COM_STATUS
The data argument is ignored if cmd is set to _COM_RECEIVE or _COM_STATUS. The data argument for _COM_INIT is created by combining one or more of the following constants (with the OR operator):
_COM_CHR7 7 bits/character _COM_CHR8 8 bits/character _COM_STOP1 1 stop bit _COM_STOP2 2 stop bits _COM_NOPARITY no parity _COM_EVENPARITY even parity _COM_ODDPARITY odd parity _COM_110 110 baud _COM_150 150 baud _COM_300 300 baud _COM_600 600 baud _COM_1200 1200 baud _COM_2400 2400 baud _COM_4800 4800 baud _COM_9600 9600 baud
The default value of data is 1 stop bit, no parity, and 110 baud.
The function returns a 16-bit integer whose high-order byte contains status bits. The meaning of the low-order byte varies, depending on the cmd value. The high-order bits are as follows:
Bit Meaning if Set 15 Timed out 14 Transmission-shift register empty 13 Transmission-hold register empty 12 Break detected 11 Framing error 10 Parity error 9 Overrun error 8 Data ready
When service is _COM_SEND, bit 15 is set if data cannot be sent.
When service is _COM_RECEIVE, the byte read is returned in the low-order bits if the call is successful. If an error occurs, any of the bits 9, 10, 11, or 15 is set.
When service is _COM_INIT or _COM_STATUS, the low-order bits are defined as follows:
Bit Meaning if Set 7 Receive-line signal detected 6 Ring indicator 5 Data-set-ready 4 Clear-to-send 3 Change in receive-line signal detected 2 Trailing-edge ring indicator 1 Change in data-set-ready status 0 Change in clear-to-send status
not ANSI, not POSIX
/* 9600 baud, no parity, one stop, 8 bits */ _bios_serialcom(_COM_INIT, 0, _COM_9600|_COM_NOPARITY|_COM_STOP1|_COM_CHR8); for(i=0; buf[i]; i++) _bios_serialcom(_COM_SEND, 0, buf[i]);
#include <bios.h> unsigned _bios_timeofday(unsigned cmd, unsigned long *timeval);
The _bios_timeofday routine uses INT 0x1A to get or set the clock count (which is the number of 18.2 Hz ticks since midnight). The cmd argument can be either the _TIME_GETCLOCK or _TIME_SETCLOCK manifest constant.
If the argument is _TIME_GETCLOCK, the routine returns a nonzero value if midnight was passed since last read, or zero if midnight was not passed. If the argument is _TIME_SETCLOCK, the return value is undefined.
not ANSI, not POSIX
unsigned hour, min, sec, hsec; unsigned long ticks; ... ticks = (unsigned long)(hour * 65543.33) + (min * 1092.38) + (sec * 18.21) + (hsec * 0.182); _bios_timeofday(_TIME_SETCLOCK, &ticks);
#include <bios.h> int bioscom(int cmd, char data, int port);
This function accesses the BIOS interrupt 0x14 function, serial
communication services. port
should be the COM port (0=COM1,
1=COM2, etc).
The valid values of cmd are:
For initialization, the byte is made up of the following bits:
0000 0000 7654 3210 Meaning ---- --10 7 bits/character ---- --11 8 bits/character ---- -0-- 1 stop bit ---- -1-- 2 stop bits ---X 0--- no parity ---0 1--- odd parity ---1 1--- even parity 000- ---- 110 baud 001- ---- 150 baud 010- ---- 300 baud 011- ---- 600 baud 100- ---- 1200 baud 101- ---- 2400 baud 110- ---- 4800 baud 111- ---- 9600 baud
For writing a character out to the port, the return value's lower 8 bits contain the same byte as passed as the data argument.
For reading a character from the port, the value of data is ignored, and the lower 8 bits of the return value contain the byte read. Also, the "timeout" bit in the upper 8 bits is used as an error indicator in this case (0=success, 1=error). If it indicates an error, you should call the "get port status" variant to get the detailed error bits.
The return value is a sequence of bits that indicate the port status and, for cmd=0 and 3, the modem status. For read/write operations, the lower eight bits are the character read.
1111 1100 0000 0000 5432 1098 7654 3210 Meaning ---- ---- ---- ---1 CTS change ---- ---- ---- --1- DSR change ---- ---- ---- -1-- ring change ---- ---- ---- 1--- carrier detect change ---- ---- ---1 ---- CTS present ---- ---- --1- ---- DSR present ---- ---- -1-- ---- ring present ---- ---- 1--- ---- carrier detect ---- ---1 ---- ---- data ready ---- --1- ---- ---- overrun error ---- -1-- ---- ---- parity error ---- 1--- ---- ---- framing error ---1 ---- ---- ---- break detected --1- ---- ---- ---- transmit holding register empty -1-- ---- ---- ---- transmit shift register empty 1--- ---- ---- ---- time out (=1 if error present for cmd=1,2)
not ANSI, not POSIX
bioscom(0, 0xe3, 0); /* 9600 baud, no parity, one stop, 8 bits */ for (i=0; buf[i]; i++) bioscom(1, buf[i], 0);
#include <bios.h> int biosdisk(int cmd, int drive, int head, int track, int sector, int nsects, void *buffer);
This function interfaces with the BIOS disk sevice (interrupt 0x13). Please refer to a BIOS reference manual for detailed information about the parameters of this call. The function assumes a sector size of 512 bytes.
The following functions of Int 13h are currently supported:
The first request with more sectors than will fit in the transfer buffer will cause a DOS buffer to be allocated. This buffer is automatically freed when your application exits. Requests for more sectors than 18 sectors (9K) will fail.
Function 8 returns values in buffer as follows:
The value of AH returned by the BIOS. See _bios_disk, for a detailed list of possible status and error codes.
not ANSI, not POSIX
char buffer[512]; if (biosdisk(2, 0x80, 0, 0, 0, 1, buffer)) error("disk");
#include <bios.h> int biosequip(void);
This function returns the equipment word from BIOS request 0x11. The bits correspond to the following values:
1111 1100 0000 0000 5432 1098 7654 3210 Meaning ---- ---- ---- ---X 1 = disk drive(s) installed ---- ---- ---- --X- 1 = math coprocessor installed ---- ---- ---- XX-- System memory 00=16k 01=32k 10=48k 11=64k (non PS/2) ---- ---- ---- -X-- 1 = pointing device installed (PS/2) ---- ---- ---- X--- not used on PS/2 ---- ---- --XX ---- initial video mode: 01=CO40 10=CO80 11=MONO ---- ---- XX-- ---- disk drives 00=1 01=2 10=3 11=4 (zero if bit 1=0) ---- ---X ---- ---- 1 = no DMA available ---- XXX- ---- ---- number of serial ports installed (000=0 001=1 etc) ---X ---- ---- ---- 1 = game port adapter installed --X- ---- ---- ---- 1 = internal modem installed (PS/2) --X- ---- ---- ---- 1 = serial printer attached (non PS/2) XX-- ---- ---- ---- number of printers installed (00=0 01=1 10=2 11=3)
The equipment word.
not ANSI, not POSIX
if (biosequip() & 0xc000) do_printing();
#include <bios.h> int bioskey(int command)
This function issues the BIOS keyboard interrupt 16h with command in the AH register, and returns the results of that call. The argument command can accept the following values:
If the Ctrl-<BREAK> key was pressed, returns -1.
7654 3210 Meaning ---- ---X Right shift key down ---- --X- Left shift key down ---- -X-- Ctrl key down ---- X--- Alt key down ---X ---- Scroll lock on --X- ---- Num lock on -X-- ---- Caps lock on X--- ---- Insert on
E0h
prefix in the low 8 bits.
Almost every PC nowadays has an extended 101-key keyboard.
FEDC BA98 7654 3210 Meaning ---- ---- ---- ---X Right SHIFT is pressed ---- ---- ---- --X- Left SHIFT is pressed ---- ---- ---- -X-- CTRL is pressed ---- ---- ---- X--- ALT is pressed ---- ---- ---X ---- Scroll Lock locked ---- ---- --X- ---- Num Lock locked ---- ---- -X-- ---- Caps Lock locked ---- ---- X--- ---- Insert locked ---- ---X ---- ---- Left CTRL is pressed ---- --X- ---- ---- Left ALT is pressed ---- -X-- ---- ---- Right CTRL is pressed ---- X--- ---- ---- Right ALT is pressed ---X ---- ---- ---- Scroll Lock is pressed --X- ---- ---- ---- Num Lock is pressed -X-- ---- ---- ---- Caps Lock is pressed X--- ---- ---- ---- SysReq is pressed
Depends on command.
not ANSI, not POSIX
while (!bioskey(1)) do_stuff();
#include <bios.h> unsigned biosmemory(void);
This function returns the amount of system memory in 1k blocks.
Note that this function doesn't know about extended memory above the 640K mark, so it will report 640K at most. This is a limitation of the BIOS.
Bytes of memory / 1024.
not ANSI, not POSIX
printf("This system has %d bytes of memory\n", biosmemory()*1024);
#include <bios.h> int biosprint(int cmd, int byte, int port)
byte
is sent to parallel port port.
7654 3210 Meaning ---- ---X Timeout ---- -XX- Unused ---- X--- I/O Error ---X ---- Selected --X- ---- Out of paper -X-- ---- Acknowledged X--- ---- Idle
The printer status.
not ANSI, not POSIX
while (*c) biosprint(0, *c++, 0);
#include <bios.h> long biostime(int cmd, long newtime);
This function reads (cmd=0) or sets (cmd=1) the internal tick counter, which is the number of 18.2 Hz ticks since midnight.
When reading, the number of ticks since midnight.
not ANSI, not POSIX
long ticks = biostime(0, 0);
#include <conio.h> void blinkvideo(void);
Bit 7 (MSB
) of the character attribute byte has two possible
effects on EGA and VGA displays: it can either make the character blink
or change the background color to bright (thus allowing for 16
background colors as opposed to the usual 8). This function sets that
bit to display blinking characters. After a call to this function,
every character written to the screen with bit 7 of the attribute byte
set, will blink. The companion function intensevideo
(see intensevideo) has the opposite effect.
Note that there is no BIOS function to get the current status of this
bit, but bit 5 of the byte at 0040h:0065h
in the BIOS area
indicates the current state: if it's 1 (the default), blinking
characters will be displayed.
not ANSI, not POSIX
#include <unistd.h> int brk(void *ptr);
This function changes the break for the program. This is the
first address that, if referenced, will cause a fault to occur. The
program asks for more memory by specifying larger values for ptr.
Normally, this is done transparently through the malloc
function.
Zero if the break was changed, -1 if not. errno is set to the error.
not ANSI, not POSIX
if (brk(old_brk+1000)) printf("no memory\n");
#include <stdlib.h> void *bsearch (const void *key, const void *base, size_t num, size_t size, int (*ptf)(const void *ckey, const void *celem));
Given an array of values, perform a binary search on the values looking for value that "matches" the given key. A match is determined by calling the provided function ptf and passing it the key as ckey and a pointer to one of the elements of the array as celem. This function must return a negative number if the key is closer than the element to the beginning of the array, positive if it is closer to the end, and zero if the element matches the key.
The array begins at address base and contains num elements, each of size size.
Returns a pointer to the element that matches the key, else NULL.
ANSI, POSIX
typedef struct { int a, b; } q; int compare(void *key, void *elem) { return *(int *)key - ((q *)elem)->a; } q qlist[100]; ... q *match = bsearch(4, qlist, 100, sizeof(q), compare); printf("4->%d=n", match->b); ...
#include <string.h> void bzero(void *pointer, int length);
The data at pointer is filled with length zeros.
None.
not ANSI, not POSIX
char foo[100]; bzero(foo,100);
#include <stdlib.h> void *calloc(size_t num_elements, size_t size);
This function allocates enough memory for num_elements objects of size size. The memory returned is initialized to all zeros. The pointer returned should later be passed to free (see free) so that the memory can be returned to the heap.
You may use cfree (see xfree) to free the pointer also; it just calls free.
A pointer to the memory, or NULL
if no more memory is available.
ANSI, POSIX
Complex *x = calloc(12, sizeof(Complex)); cfree(x);
#include <math.h> double cbrt(double x);
This function computes the cube root of x. It is faster and more
accurate to call cbrt(x)
than to call
pow(x, 1./3.)
.
The cube root of x. If the value of x is NaN
, the
return value is NaN
and errno
is set to EDOM
.
Infinite arguments are returned unchanged, without setting
errno
.
not ANSI, not POSIX
#include <math.h> double ceil(double x);
This function computes the smallest integer greater than or equal to x.
The smallest integer value greater than or equal to x.
ANSI, POSIX
#include <termios.h> speed_t cfgetispeed (const struct termios *termiosp);
This function gets the input line speed stored in the structure termiosp. See Termios functions, for more details about this structure and the baudrate values it supports.
Note that the termios emulation handles console only, and that the input baudrate value is ignored by this implementation.
The input line speed on success, (speed_t) -1 for error.
not ANSI, POSIX
#include <termios.h> speed_t cfgetospeed (const struct termios *termiosp);
This function gets the output line speed stored in the structure termiosp. See Termios functions, for more details about this structure and the baudrate values it supports.
Note that the termios emulation handles console only, and that the baudrate value has no effect in this implementation.
The output line speed on success, (speed_t) -1 for error.
not ANSI, POSIX
#include <termios.h> void cfmakeraw (struct termios *termiosp);
This function sets the structure specified by termiosp for raw mode. It is provided for compatibility only. Note that the termios emulation handles console only.
Zero on success, nonzero on failure.
not ANSI, not POSIX
#include <stdlib.h> void cfree(void *pointer);
This function returns the memory allocated by calloc (see calloc) to the heap.
None.
not ANSI, not POSIX
Complex *x = calloc(12, sizeof(Complex)); cfree(x);
#include <termios.h> int cfsetispeed (struct termios *termiosp, speed_t speed);
This function sets the input line speed stored in the structure termiosp to speed. See Termios functions, for more details about this structure and the baudrate values it supports.
Note that the termios emulation handles console only, and that the baudrate values have no effect in this implementation.
Zero on success, nonzero on failure.
not ANSI, POSIX
#include <termios.h> int cfsetospeed (struct termios *termiosp, speed_t speed);
This function sets the output line speed stored in the structure termiosp to speed. See Termios functions, for more details about this structure and the baudrate values it supports.
Note that the termios emulation handles console only, and that the baudrate values have no effect in this implementation.
Zero on success, nonzero on failure.
not ANSI, POSIX
#include <termios.h> int cfsetspeed (struct termios *termiosp, speed_t speed);
This function sets the input and output line speed stored in the structure termiosp to speed. It is provided for compatibility only. Note that the termios emulation handles console only.
Zero on success, nonzero on failure.
not ANSI, not POSIX
#include <conio.h> char *cgets(char *_str);
Get a string from the console. This will take advantage of any command-line editing TSRs. To use, you must pre-fill the first character of the buffer. The first character is the size of the buffer. On return, the second character is the number of characters read. The third character is the first character read.
A pointer to the first character read.
not ANSI, not POSIX
#include <unistd.h> int chdir(const char *new_directory);
This function changes the current directory to new_directory. If a drive letter is specified, the current directory for that drive is changed and the current disk is set to that drive, else the current directory for the current drive is changed.
Zero if the new directory exists, else nonzero and errno set if error.
not ANSI, POSIX
if (chdir("/tmp")) perror("/tmp");
#include <sys/system.h> const _v2_prog_type *_check_v2_prog(const char *program, int fd);
This function checks a given program for various known types of
executables and/or other things. This function povides two differnt
entry points. One is to call the function with a not NULL
pointer as program
(in this case fd
is ignored),
then the file named by program
is opened and closed by
_check_v2_prog
.
When you pass NULL
as program
, then you have to pass
a valid file handle in fd
and _check_v2_prog
uses
that handle and does also not close the file on return.
_v2_prog_type
is defined in sys/system.h
like the following:
typedef struct { char magic[16]; int struct_length; char go32[16]; unsigned char buffer[0]; } _v1_stubinfo; typedef struct { union { unsigned version:8; /* The version of DJGPP created that COFF exe */ struct { unsigned minor:4; /* The minor version of DJGPP */ unsigned major:4; /* The major version of DJGPP */ } v; } version; unsigned object_format:4; /* What an object format */ # define _V2_OBJECT_FORMAT_UNKNOWN 0x00 # define _V2_OBJECT_FORMAT_COFF 0x01 # define _V2_OBJECT_FORMAT_PE_COFF 0x02 unsigned exec_format:4; /* What an executable format */ # define _V2_EXEC_FORMAT_UNKNOWN 0x00 # define _V2_EXEC_FORMAT_COFF 0x01 # define _V2_EXEC_FORMAT_STUBCOFF 0x02 # define _V2_EXEC_FORMAT_EXE 0x03 # define _V2_EXEC_FORMAT_UNIXSCRIPT 0x04 unsigned valid:1; /* Only when nonzero all the information is valid */ unsigned has_stubinfo:1; /* When nonzero the stubinfo info is valid */ unsigned unused:14; _v1_stubinfo *stubinfo; } _v2_prog_type;
The macros shown above can be used to test the different members of that structure for known values.
Warning: Do not modify any of the data in this structure.
After calling _check_v2_prog
you should check at first the member
valid
. Only if this is nonzero you can be sure that all the other
information in the struct is valid.
The same is for the stubinfo
member of the above struct, it is
valid only, when has_stubinfo
is nonzero.
not ANSI, not POSIX
To use the information returned in the struct you can use code like the following:
#include <stdio.h> #include <sys/system.h> int main() { const _v2_prog_type *type; /* Since we pass a valid name, we can use -1 as the second argument */ type = _check_v2_prog ("foo", -1); /* There was something wrong */ if (!type->valid) { fprintf(stderr, "Could not check the file 'foo'. Giving up.\\n"); return 1; } /* Currently only the COFF format is valid to be a V2 executable */ if (type->object_format != _V2_OBJECT_FORMAT_COFF) { fprintf(stderr, "File 'foo' is not in COFF format\\n"); return 2; } /* The major version is not 2 */ if (type->version.v.major != 2) { fprintf(stderr, "File 'foo' is not from DJGPP 2.xx\\n"); return 3; } fprintf(stdout, "File 'foo' is a valid DJGPP 2.xx executable\\n"); if (type->exec_format == _V2_EXEC_FORMAT_STUBCOFF) { fprintf(stdout, "File 'foo' has a stub loader prepended\\n"); } return 0; }
#include <sys/stat.h> int chmod(const char *path, mode_t mode);
This function changes the mode (writable or write-only) of the specified file. The value of mode can be a combination of one or more of the following:
S_IRUSR
S_IWUSR
Other S_I*
values could be included, but they will be ignored.
Zero if the file exists and the mode was changed, else nonzero.
not ANSI, POSIX
chmod("/tmp/dj.dat", S_IWUSR|S_IRUSR);
#include <io.h> int _chmod(const char *filename, int func, mode_t mode);
This is a direct connection to the MS-DOS chmod function call, int
0x21, %ax = 0x4300/0x4301. If func is 0, then DOS is called with
AX = 0x4300, which returns an attribute byte of a file. If func
is 1, then the attributes of a file are set as specified in mode.
Note that the directory and volume attribute bits must always be 0 when
_chmod()
is called with func = 1, or else the call will fail.
The third argument is optional when getting attributes.
The attribute bits are defined as follows:
Bit Meaning 76543210 .......1 Read-only ......1. Hidden .....1.. System ....1... Volume Label ...1.... Directory ..1..... Archive xx...... Reserved (used by some network redirectors)
On platforms where the LFN API (see LFN) is available,
_chmod
calls function 0x7143 of Interrupt 21h, to support long
file names.
If the file exists, _chmod()
returns its attribute byte in case
it succeded, or -1 in case of failure.
not ANSI, not POSIX
#include <unistd.h> int chown(const char *file, int owner, int group);
This function does nothing under MS-DOS
This function always returns zero if the file exists, else it returns
-1 and sets errno to ENOENT
.
not ANSI, POSIX
#include <io.h> int chsize(int handle, long size);
Just calls ftruncate (see ftruncate).
Zero on success, -1 on failure.
not ANSI, not POSIX
#include <debug/dbgcom.h> void cleanup_client (void);
This functions is typically called when the debugged process exits or is aborted. It restores segment descriptors, closes file handles that were left open by the debuggee, frees protected-mode and conventional memory and any segment descriptors allocated by the debuggee, and restores the debugger's original signal handlers.
#include <float.h> unsigned int _clear87(void);
Clears the floating point processor's exception flags.
The previous status word.
not ANSI, not POSIX
#include <stdio.h> void clearerr(FILE *stream);
This function clears the EOF and error indicators for the file stream.
None.
ANSI, POSIX
clearerr(stdout);
#include <time.h> clock_t clock(void);
This function returns the number of clock ticks since an arbitrary time,
actually, since the first call to clock
, which itself returns
zero. The number of tics per second is CLOCKS_PER_SEC.
The number of tics.
ANSI, POSIX
printf("%d seconds have elapsed\n", clock()/CLOCKS_PER_SEC);
#include <unistd.h> int close(int fd);
The open file associated with fd is closed.
Zero if the file was closed, nonzero if fd was invalid or already closed.
not ANSI, POSIX
int fd = open("data", O_RDONLY); close(fd);
#include <io.h> int _close(int fd);
This is a direct connection to the MS-DOS close function call, int 0x21, %ah = 0x3e. This function can be hooked by the See File System Extensions. If you don't want this, you should use See _dos_close.
Zero if the file was closed, else nonzero.
not ANSI, not POSIX
#include <dirent.h> int closedir(DIR *dir);
This function closes a directory opened by opendir (see opendir).
Zero on success, nonzero if dir is invalid.
not ANSI, POSIX
#include <conio.h> void clreol(void);
Clear to end of line.
None.
not ANSI, not POSIX
#include <conio.h> void clrscr(void);
Clear the entire screen.
not ANSI, not POSIX
#include <conio.h> int _conio_kbhit(void);
Determines whether or not a character is waiting at the keyboard. If
there is an ungetch'd character, this function returns true. Note
that if you include conio.h
, the kbhit function is
redefined to be this function instead.
Nonzero if a key is waiting, else zero.
not ANSI, not POSIX
#include <float.h> unsigned int _control87(unsigned int newcw, unsigned int mask);
This function sets and retrieves the FPU's control word.
The control word is a special 16-bit register maintained by the math coprocessor. By setting and clearing bit fields in the control word, you can exercise control of certain aspects of coprocessor operation. The individual bits of the x87 control word are defined by macros in float.h, and shown in this table:
---- ---- --XX XXXX = MCW_EM - exception masks (1=handle exception internally, 0=fault) ---- ---- ---- ---X = EM_INVALID - invalid operation ---- ---- ---- --X- = EM_DENORMAL - denormal operand ---- ---- ---- -X-- = EM_ZERODIVIDE - divide by zero ---- ---- ---- X--- = EM_OVERFLOW - overflow ---- ---- ---X ---- = EM_UNDERFLOW - underflow ---- ---- --X- ---- = EM_INEXACT - rounding was required ---- --XX ---- ---- = MCW_PC - precision control ---- --00 ---- ---- = PC_24 - single precision ---- --10 ---- ---- = PC_53 - double precision ---- --11 ---- ---- = PC_64 - extended precision ---- XX-- ---- ---- = MCW_RC - rounding control ---- 00-- ---- ---- = RC_NEAR - round to nearest ---- 01-- ---- ---- = RC_DOWN - round towards -Inf ---- 10-- ---- ---- = RC_UP - round towards +Inf ---- 11-- ---- ---- = RC_CHOP - round towards zero ---X ---- ---- ---- = MCW_IC - infinity control (obsolete, always affine) ---0 ---- ---- ---- = IC_AFFINE - -Inf < +Inf ---1 ---- ---- ---- = IC_PROJECTIVE - -Inf == +Inf
_control87
uses the value of newcw and mask variables
together to determine which bits of the FPU's control word should be
set, and to what values. For each bit in mask that is set (equals
to 1), the corresponding bit in newcw specifies the new value of
the same bit in the FPU's control word, which _control87
should
set. Bits which correspond to reset (zero) bits in mask are not
changed in the FPU's control word. Thus, using a zero value for
mask retrieves the current value of the control word without
changing it.
The exception bits MCW_EM
(the low-order 6 bits) of the control
word define the exception mask. That is, if a certain bit is
set, the corresponding exception will be masked, i.e., it will not
generate an FP exception (which normally causes signal SIGFPE
to
be delivered). A masked exception will be handled internally by the
coprocessor. In general, that means that it will generate special
results, such as NaN, Not-a-Number (e.g., when you attempt to
compute a square root of a negative number), denormalized result (in
case of underflow), or infinity (e.g., in the case of division by zero,
or when the result overflows).
By default, DJGPP startup code masks all FP exceptions.
The precision-control field MCW_PC
(bits 8 and 9) controls the
internal precision of the coprocessor by selecting the number of
precision bits in the mantissa of the FP numbers. The values
PC_24
, PC_53
, and PC_64
set the precision to 24,
53, and 64-bit mantissa, respectively. This feature of the coprocessor
is for compatibility with the IEEE 745 standard and only affect
the FADD
, FSUB
FSUBR
, FMUL
, FDIV
,
FDIVR
, and FSQRT
instructions. Lowering the precision
will not decrease the execution time of FP instructions.
The MCW_PC
field is set to use the full-precision 64-bit
mantissa by the DJGPP startup code.
The rounding-control field MCW_RC
(bits 10 and 11) controls the
type (round or chop) and direction (-Inf or +Inf) of the rounding. It
only affects arithmetic instructions. Set to round-to-nearest state by
the DJGPP startup code.
The infinity-control bit MCW_IC
has no effect on 80387 and later
coprocessors.
The previous control word.
(Note that this is different from what _control87
from the
Borland C library which returns the new control word.)
not ANSI, not POSIX
/* mask all exceptions, except invalid operation */ _control87 (0x033e, 0xffff);
#include <math.h> double cos(double x);
This function computes the cosine of x (which should be given in radians).
The cosine of x. If the absolute value of x is finite but
greater than or equal to 2^63, the value is 1 (since for
arguments that large each bit of the mantissa is more than Pi
).
If the value of x is infinite or NaN
, the return value is
NaN
and errno
is set to EDOM
.
ANSI, POSIX
In general, this function's relative accuracy is about
1.7*10^(-16), which is close to the machine precision for a
double
. However, for arguments very close to Pi/2
and its
odd multiples, the relative accuracy can be many times worse, due to
loss of precision in the internal FPU computations. Since
cos(Pi/2) is zero, the absolute accuracy is still very good; but
if your program needs to preserve high relative accuracy for such
arguments, link with -lm
and use the version of cos
from
libm.a
which does elaborate argument reduction, but is about
three times slower.
#include <math.h> double cosh(double x);
This function computes the hyperbolic sine of x.
The hyperbolic cosine of x. If the value of x is a
NaN
, the return value is NaN
and errno
is set to
EDOM
. If the value of x is so large that the result would
overflow a double
, the return value is Inf
and
errno
is set to ERANGE
. If x is either a positive
or a negative infinity, the result is +Inf
, and errno
is
not changed.
ANSI, POSIX
#include <conio.h> int cprintf(const char *_format, ...);
Like printf
(see printf), but prints through the console,
taking into consideration window borders and text attributes. There
is currently a 2048-byte limit on the size of each individual cprintf
call.
The number of characters written.
not ANSI, not POSIX
#include <conio.h> int cputs(const char *_str);
Puts the string onto the console. The cursor position is updated.
Zero on success.
not ANSI, not POSIX
#include <fcntl.h> #include <sys/stat.h> /* for mode definitions */ int creat(const char *filename, mode_t mode);
This function creates the given file and opens it for writing. If the
file exists, it is truncated to zero size, unless it is read-only, in
which case the function fails. If the file does not exist, it will be
created read-only if mode does not have S_IWUSR
set.
A file descriptor >= 0, or a negative number on error.
not ANSI, POSIX
int fd = creat("data", S_IRUSR|S_IWUSR); write(fd, buf, 1024); close(fd);
#include <io.h> int _creat(const char *path, int attrib);
This is a direct connection to the MS-DOS creat function call, int 0x21,
%ah = 0x3c. The file is set to binary mode. This function can be
hooked by the File System Extensions, see File System Extensions. If you don't want this, you should use _dos_creat
(see _dos_creat) or _dos_creatnew
(see _dos_creatnew).
On platforms where the LFN API (see LFN) is available,
_creat
calls function 0x716C of Interrupt 21h, to support long
file names.
The new file descriptor, else -1 on error.
not ANSI, not POSIX
#include <fcntl.h> #include <dir.h> #include <io.h> int _creatnew(const char *path, int attrib, int flags);
This function creates a file given by path and opens it, like
_creat
does, but only if it didn't already exist. If the named
file exists, _creatnew
fails. (In contrast, _creat
opens
existing files and overwrites their contents, see _creat.)
The attributes of the created file are determined by attrib. The
file is usually given the normal attribute (00H). If attrib is
non-zero, additional attributes will be set. The following macros,
defined on <dir.h>
, can be used to control the attributes of the
created file (the associated numeric values appear in parentheses):
FA_RDONLY (1)
FA_HIDDEN (2)
FA_SYSTEM (4)
Other bits (FA_LABEL
and FA_DIREC
) are ignored by DOS.
The argument flags controls the sharing mode and the fine details
of how the file is handled by the operating system. The following
macros, defined on <fcntl.h>
, can be used for this (associated
numeric values are given in parentheses):
SH_COMPAT (00h)
SH_DENYRW (10h)
SH_DENYWR (20h)
SH_DENYRD (30h)
SH_DENYNO (40h)
Note that the file is always open for both reading and writing;
_creatnew
ignores any bits in the lower nibble of flags
(O_RDONLY
, O_WRONLY
, etc.).
_creatnew
calls DOS function 716Ch when long file names are
supported, 6C00h otherwise. (On DOS version 3.x, function 5B00h is
called which ignores the value of flags, since function 6C00h is
only supported by DOS 4.0 and later.)
The file handle returned by _creatnew
is set to binary mode.
This function can be hooked by the Filesystem Extensions handlers, as
described in File System Extensions. If you don't want this, you
should use _dos_creatnew
(see _dos_creatnew) instead.
The new file descriptor, else -1 on error.
not ANSI, not POSIX
#include <io.h> size_t crlf2nl(char *buf, ssize_t len);
This function removes Ctrl-M characters from the given buf.
The number of characters remaining in the buffer are returned.
not ANSI, not POSIX
#include <crt0.h> char **__crt0_glob_function(char *_argument);
If the application wishes to provide a wildcard expansion function, it
should define a __crt0_glob_function
function. It should return
a list of the expanded values, or 0 if no expansion will occur. The
startup code will free the returned pointer if it is nonzero.
If no expander function is provided, wildcards will be expanded in the
POSIX.1 style by the default __crt0_glob_function
from the C
library. To disable expansion, provide a __crt0_glob_function
that always returns 0.
not ANSI, not POSIX
#include <crt0.h> void __crt0_load_environment_file(char *_app_name);
This function, provided by libc.a, does all the work required to load
additional environment variables from the file djgpp.env
whose
full pathname is given by the DJGPP
environment variable. If the
application does not use environment variables, the programmer can
reduce the size of the program image by providing a version of this
function that does nothing.
not ANSI, not POSIX
#include <crt0.h> void __crt0_setup_arguments(void);
This function, provided by libc.a, does all the work required to
provide the two arguments passed to main() (usually argc
and
argv
). If main() does not use these arguments, the programmer
can reduce the size of the program image by providing a version of
this function that does nothing.
Note that since the default __crt0_setup_arguments_function
will
not expand wildcards inside quotes (" or '), you
can quote a part of the argument that doesn't include wildcards and
still have them expanded. This is so you could use wildcard expansion
with filenames which have embedded whitespace (on LFN filesystems).
See __crt0_load_environment_file.
not ANSI, not POSIX
#include <crt0.h> int _crt0_startup_flags = ...;
This variable can be used to determine what the startup code will (or will not) do when the program begins. This can be used to tailor the startup environment to a particular program.
_CRT0_FLAG_PRESERVE_UPPER_CASE
argv[0]
is left in whatever case it was. If not set, all
characters are mapped to lower case. Note that if the argv0
field in the stubinfo structure is present, the case of that part
of argv[0]
is not affected.
_CRT0_FLAG_USE_DOS_SLASHES
argv[0]
. If
not set, all reverse slashes are replaced with unix-style slashes.
_CRT0_FLAG_DROP_EXE_SUFFIX
.exe
suffix is removed from the file name component
of argv[0]
. If not set, the suffix remains.
_CRT0_FLAG_DROP_DRIVE_SPECIFIER
C:
) is removed from the
beginning of argv[0]
(if present). If not set, the drive
specifier remains.
_CRT0_FLAG_DISALLOW_RESPONSE_FILES
@gcc.rf
) are not expanded. If not
set, the contents of the response files are used to create arguments.
Note that if the file does not exist, that argument remains unexpanded.
_CRT0_FLAG_KEEP_QUOTES
'
, "
, and \
will be
retained in argv[]
elements when processing command lines passed
by DOS and via system
. This is used by the redir
program,
and should only be needed if you want to get the original command line
exactly as it was passed by the caller.
_CRT0_FLAG_FILL_SBRK_MEMORY
sbrk
'd memory with a constant value. If not, memory
gets whatever happens to have been in there, which breaks some
applications.
_CRT0_FLAG_FILL_DEADBEEF
0xdeadbeef
, else fill with zero.
This is especially useful for debugging uninitialized memory problems.
_CRT0_FLAG_NEARPTR
_CRT0_FLAG_NULLOK
_CRT0_FLAG_NMI_SIGNAL
_CRT0_FLAG_NO_LFN
LFN
.
_CRT0_FLAG_NONMOVE_SBRK
sbrk
algorithm uses multiple DPMI memory blocks which
makes sure the base of CS/DS/SS does not change. This may cause
problems with sbrk(0)
values and programs with other assumptions
about sbrk
behavior. This flag is useful with near pointers,
since a constant pointer to DOS/Video memory can be computed without
needing to reload it after any routine which might call sbrk
.
_CRT0_FLAG_UNIX_SBRK
sbrk
algorithm resizes memory blocks so that the
layout of memory is set up to be the most compatible with Unix
sbrk
expectations. This mode should not be used with hardware
interrupts, near pointers, and may cause problems with QDPMI virtual
memory. On NT, this is the recommended algorithm.
If your program requires a specific sbrk
behavior, you
should set either this or the previous flag, since the default may
change in different libc releases.
_CRT0_FLAG_LOCK_MEMORY
sbrk
'ed, so the locking may fail. This bit may be set or cleared
during execution. When sbrk
uses multiple memory zones, it can be
difficult to lock all memory since the memory block size and location is
impossible to determine.
_CRT0_FLAG_PRESERVE_FILENAME_CASE
getcwd
, _fixpath
and others. Note that when this flag is
set, ALL filenames on MSDOS systems will appear in upper-case, which is
both ugly and will break many Unix-born programs. Use only if you know
exactly what you are doing!
This flag overrides the value of the environment variable FNCASE
,
See _preserve_fncase.
not ANSI, not POSIX
#include <conio.h> int cscanf(const char *_format, ...);
Like scanf
(see scanf), but it reads from the standard input
device directly, avoiding buffering both by DOS and by the library.
Each character is read by getche
(see getche).
The number of fields stored.
not ANSI, not POSIX
#include <unistd.h> char *ctermid(char *s);
This function returns the name of the current terminal device. Under MS-DOS, this is always "con".
If s is null, returns pointer to internal static string "con". Otherwise, copies "con" to buffer pointed by s.
not ANSI, POSIX
#include <time.h> char *ctime(const time_t *cal);
This function returns an ASCII representation of the time in cal.
This is equivalent to asctime(localtime(cal))
. See asctime.
See localtime.
The ascii representation of the time.
ANSI, POSIX
#include <dos.h> void delay(unsigned msec);
This function causes the program to pause for msec milliseconds.
It uses the int 15h
delay function to relinquish the CPU to other
programs that might need it.
Some operating systems that emulate DOS, such as OS/2 and Windows/NT,
hang the DOS session when the <Pause> key is pressed during the call
to delay
. Plain DOS and Windows 3.X and 9X are known to not have
this bug.
None.
not ANSI, not POSIX
delay(200); /* delay for 1/5 second */
#include <conio.h> void delline(void);
The line the cursor is on is deleted; lines below it scroll up.
not ANSI, not POSIX
#include <dos.h> int _detect_80387(void);
Detects whether a numeric coprocessor is present. Note that floating-point code will work even without a coprocessor, due to the existence of emulation.
1 if a coprocessor is present, 0 if not.
not ANSI, not POSIX
if (_detect_80387()) printf("You have a coprocessor\n");
#include <time.h> double difftime(time_t t1, time_t t0);
This function returns the difference in time, in seconds, from t0 to t1.
The number of seconds.
ANSI, POSIX
time_t t1, t0; double elapsed; time(&t0); do_something(); time(&t1); elapsed = difftime(t1, t0);
#include <unistd.h> char * dirname (const char *fname);
This function returns the directory part of the argument fname
copied to a buffer allocated by calling malloc
. The directory
part is everything up to but not including the rightmost slash (either
forward- or backslash) in fname. If fname includes a drive
letter but no slashes, the function will return x:.
where
x is the drive letter. If fname includes neither the drive
letter nor any slashes, "."
will be returned. Trailing slashes
are removed from the result, unless it is a root directory, with or
without a drive letter.
The directory part in malloc'ed storage, or a NULL pointer of either there's not enough free memory, or fname is a NULL pointer.
not ANSI, not POSIX
printf ("The parent of current directory is %s\n", dirname (getcwd (0, PATH_MAX)));
#include <dos.h> int disable(void);
This function disables interrupts.
See enable.
Returns nonzero if the interrupts had been enabled before this call, zero if they were already disabled.
not ANSI, not POSIX
int ints_were_enabled; ints_were_enabled = disable(); . . . do some stuff . . . if (ints_were_enabled) enable();
#include <stdlib.h> div_t div(int numerator, int denominator);
Returns the quotient and remainder of the division numerator divided by denominator. The return type is as follows:
typedef struct { int quot; int rem; } div_t;
The results of the division are returned.
ANSI, POSIX
div_t d = div(42, 3); printf("42 = %d x 3 + %d\n", d.quot, d.rem); div(+40, +3) = { +13, +1 } div(+40, -3) = { -13, -1 } div(-40, +3) = { -13, -1 } div(-40, -3) = { +13, -1 }
#include <sys/exceptn.h> void __djgpp_exception_toggle(void);
This function is automatically called when the program exits, to restore handling of all the exceptions to their normal state. You may also call it from your program, around the code fragments where you need to temporarily restore all the exceptions to their default handling. One example of such case might be a call to a library functions that spawn child programs, when you don't want to handle signals generated while the child runs (by default, those signals are also passed to the parent).
not ANSI, not POSIX
__djgpp_exception_toggle(); system("myprog"); __djgpp_exception_toggle();
#include <dpmi.h> int __djgpp_map_physical_memory(void *our_addr, unsigned long num_bytes, unsigned long phys_addr);
This function attempts to map a range of physical memory over the
specified addresses. One common use of this routine is to map device
memory, such as a linear frame buffer, into the address space of the
calling program. our_addr, num_bytes, and phys_addr
must be page-aligned. If they are not page-aligned, errno will
be set to EINVAL
and the routine will fail.
This routine properly handles memory ranges that span multiple DPMI
handles, while __dpmi_map_device_in_memory_block
does not.
Consult DPMI documentation on function 0508H for details on how this function works. Note: since 0508H is a DPMI service new with DPMI 1.0, this call will fail on most DPMI 0.9 servers. For your program to work on a wide range of systems, you should not assume this call will succeed.
Even on failure, this routine may affect a subset of the pages specified.
0 on success, -1 on failure. On failure, errno will be set to
EINVAL
for illegal input parameters, or EACCES
if the
DPMI server rejected the mapping request.
not ANSI, not POSIX
if (__djgpp_map_physical_memory (my_page_aligned_memory, 16384, 0x40000000)) printf ("Failed to map physical addresses!\n");
#include <crt0.h> __djgpp_sbrk_handle *__djgpp_memory_handle(unsigned address);
This function returns a pointer to a structure containing the memory handle and program relative offset associated with the address passed. It is just a convenient way to process the __djgpp_memory_handle_list.
A pointer to the __djgpp_sbrk_handle associated with a particular address.
not ANSI, not POSIX
#include <crt0.h> extern __djgpp_sbrk_handle __djgpp_memory_handle_list[256];
This array contains a list of memory handles and program relative offsets allocated by sbrk() in addition to the handle allocated by the stub. These values are normally not needed unless you are doing low-level DPMI page protection or memory mapping.
not ANSI, not POSIX
#include <sys/nearptr.h> void __djgpp_nearptr_disable(void);
This function disables near pointers, and re-enables protection. See __djgpp_nearptr_enable.
not ANSI, not POSIX
#include <sys/nearptr.h> int __djgpp_nearptr_enable(void);
This function enables "near pointers" to be used to access the DOS
memory arena. Sort of. When you call this function, it will return
nonzero if it has successfully enabled near pointers. If so, you must
add the value __djgpp_conventional_base
to the linear address
of the physical memory. For example:
if (__djgpp_nearptr_enable()) { short *screen = (short *)(__djgpp_conventional_base + 0xb8000); for (i=0; i<80*24*2; i++) screen[i] = 0x0720; __djgpp_nearptr_disable(); }
The variable __djgpp_base_address
contains the linear base
address of the application's data segment. You can subtract this
value from other linear addresses that DPMI functions might return
in order to obtain a near pointer to those linear regions as well.
If using the Unix-like sbrk algorithm, near pointers are only valid
until the next malloc
, system
, spawn*
, or
exec*
function call, since the linear base address of the
application may be changed by these calls.
WARNING: When you enable near pointers, you disable all the protection that the system is providing. If you are not careful, your application may destroy the data in your computer. USE AT YOUR OWN RISK!
Returns 0 if near pointers are not available, or nonzero if they are.
not ANSI, not POSIX
#include <sys/exceptn.h> int __djgpp_set_ctrl_c(int enable);
This function sets and resets the bit which controls whether signals
SIGINT
and SIGQUIT
(see signal) will be raised when
you press the INTR or QUIT keys. By default these generate signals
which, if uncaught by a signal handler, will abort your program.
However, when you call the setmode
library function to switch the
console reads to binary mode, or open the console in binary mode for
reading, this generation of signals is turned off, because some
programs want to get the ^C
and ^\
characters as any other
character and handle them by themselves.
__djgpp_set_ctrl_c
lets you explicitly determine the effect of
INTR and QUIT keys. When called with a non-zero, positive value of
enable, it arranges for SIGINT
and SIGQUIT
signals
to be generated when the appropriate key is pressed; if you call it with
a zero in enable, these keys are treated as normal characters. If
enable is negative, __djgpp_set_ctrl_c
returns the current
state of the signal generation, but doesn't change it.
For getting similar effects via the POSIX termios
functions, see
tcsetattr.
Note that the effect of Ctrl-<BREAK> key is unaffected by this
function; use the _go32_want_ctrl_break
library function to
control it.
Also note that in DJGPP, the effect of the interrupt signal will only be
seen when the program is in protected mode (See Signal Mechanism,
for more details). Thus, if you press Ctrl-C while your
program calls DOS (e.g., when reading from the console), the
SIGINT
signal handler will only be called after that call
returns.
The state of SIGINT
and SIGQUIT
generation before the
call: 0 if it was disabled, 1 if it was enabled. If the argument
enable is negative, the state is not altered.
not ANSI, not POSIX
setmode(fileno(stdin), O_BINARY); if (isatty(fileno(stdin))); __djgpp_set_ctrl_c(1);
#include <dpmi.h> int __djgpp_set_page_attributes(void *our_addr, unsigned long num_bytes, unsigned short attributes);
This function sets the DPMI page attributes for the pages in a range
of memory. our_addr and num_bytes must be page-aligned.
If they are not page-aligned, errno will be set to EINVAL
and the routine will fail.
Consult DPMI documentation on function 0507H for the meaning of the attributes argument. Note: since 0507H is a DPMI service new with DPMI 1.0, this call will fail on most DPMI 0.9 servers. For your program to work on a wide range of systems, you should not assume this call will succeed.
Even on failure, this routine may affect a subset of the pages specified.
0 on success, -1 on failure. On failure, errno will be set to
EINVAL
for illegal input parameters, or EACCES
if the
DPMI server rejected the attribute setting.
not ANSI, not POSIX
if (__djgpp_set_page_attributes (my_page_aligned_memory, 16384, 0)) printf ("Failed to make pages uncommitted!\n");
#include <sys/exceptn.h> void __djgpp_set_sigint_key(int new_key);
This function changes the INTR key that generates the signal
SIGINT
. By default, Ctrl-C is set as the INTR key. To
replace it with another key, put the scan code of the new INTR
key into the bits 0-7 and the required keyboard status byte into bits
8-15 of new_key, and call this function. Here's how the keyboard
status bits are defined:
Bit 76543210 Meaning .......X Right Shift key ......X. Left Shift key .....X.. Ctrl key ....X... Alt key ...X.... Scroll Lock key ..X..... Num Lock key .X...... Caps Lock key X....... Insert
A 1 in any of the above bits means that the corresponding key should be pressed; a zero means it should be released. Currently, all but the lower 4 bits are always ignored by the DJGPP keyboard handler when you set the INTR key using this function.
For example, the default Ctrl-C key should be passed as
0x042e
, since the scan code of the <C> key is 2Eh, and when
the <Ctrl> key is pressed, the keyboard status byte is 04h.
To disable SIGINT
generation, pass zero as the argument (since no
key has a zero scan code).
This function will set things up so that the left <Shift> key
doesn't affect Ctrl- and Alt-modified keys; the right <Shift> key
won't affect them either, unless its bit is explicitly set in
new_key. This means that Ctrl-C and Ctrl-c will both
trigger SIGINT
if 0x042e
is passed to this function.
The DJGPP built-in keyboard handler pretends that when the right <Shift> key is pressed, so is the left <Shift> key (but not vice versa).
For getting similar effects via the POSIX termios
functions, see
tcsetattr.
The previous INTR key (scan code in bits 0-7, keyboad status in bits 8-15).
not ANSI, not POSIX
__djgpp_set_sigint_key(0x0422); /* make Ctrl-g generate SIGINT's */
#include <sys/exceptn.h> void __djgpp_set_sigquit_key(int new_key);
This function changes the QUIT key that generates the signal
SIGQUIT
. By default, Ctrl-\ is set as the QUIT key. To
replace it with another key, put the scan code of the new QUIT
key into the bits 0-7 and the required keyboard status byte into bits
8-15 of new_key, and call this function. Here's how the keyboard
status bits are defined:
Bit 76543210 Meaning .......X Right Shift key ......X. Left Shift key .....X.. Ctrl key ....X... Alt key ...X.... Scroll Lock key ..X..... Num Lock key .X...... Caps Lock key X....... Insert
A 1 in any of the above bits means that the corresponding key should be pressed; a zero means it should be released. Currently, all but the lower 4 bits are always ignored by the DJGPP keyboard handler when you set the QUIT key with this function.
For example, the default Ctrl-\ key should be passed as
0x042b
, since the scan code of \
is 2Bh and when the
<Ctrl> key is pressed, the keyboard status byte is 04h.
To disable SIGQUIT
generation, pass zero as the argument (since
no key has a zero scan code).
This function will set things up so that the left <Shift> key
doesn't affect Ctrl- and Alt-modified keys; the right <Shift> key
won't affect them either, unless its bit is explicitly set in
new_key. This means that Ctrl-\ and Ctrl-| will both
trigger SIGQUIT
if 0x042b
is passed to this function.
The DJGPP built-in keyboard handler pretends that when the right <Shift> key is pressed, so is the left <Shift> key (but not vice versa).
For getting similar effects via the POSIX termios
functions, see
tcsetattr.
The previous QUIT key (scan code in bits 0-7, keyboad status in bits 8-15).
not ANSI, not POSIX
__djgpp_set_sigint_key(0); /* disable SIGQUIT's */
#include <fcntl.h> int __djgpp_share_flags = ...;
This variable controls the share flags used by open
(and hence
fopen
) when opening a file.
If you assign any value other than 0 to this variable libc will use
that value for the sharing bits when if calls DOS to open the file.
But if you specify any share flag in the open
call then these
flags will remain untouched. In this way __djgpp_share_flags
acts just like a default and by default is 0 ensuring maximum
compatibility with older versions of djgpp.
If you don't know how the share flags act consult any DOS reference. They
allow to share or protect a file when it's opened more than once by the
same task or by two or more tasks. The exact behavior depends on the exact
case. One interesting thing is that when the file is opened by two tasks
under Windows the results are different if you use Windows 3.1 or Windows 95.
To add even more complexity Windows 3.1 is affected by SHARE.EXE
.
The available flags are:
SH_COMPAT 0x0000
SH_DENYRW 0x0010
SH_DENYWR 0x0020
SH_DENYRD 0x0030
SH_DENYNO 0x0040
Of course these flags are DOS specific and doesn't exist under other OSs;
and as you can imagine __djgpp_share_flags
is djgpp specific.
not ANSI, not POSIX
#include <signal.h> void __djgpp_traceback_exit(int signo);
This function is a signal handler which will print a traceback and abort
the program. It is called by default by the DJGPP signal-handling code
when any signal except SIGQUIT
is raised (SIGQUIT
is by
default discarded).
You can use this function to get the Unix behavior of aborting the
program on SIGQUIT
(see the example below).
When this function is called directly, pass the signal number as its signo argument.
not ANSI, not POSIX
signal(SIGQUIT, __djgpp_traceback_exit);
#include <stdio.h> void _djstat_describe_lossage(FILE *fp);
Accesses the global variable _djstat_fail_bits and prints to the
stream given by fp a human-readable description of the undocumented
DOS features which the last call to stat()
or fstat()
failed
to use. (If fp is zero, the function prints to stderr.) If the
last call to f?stat()
didn't set any failure bits, an "all's
well" message is printed. This function is designed to help in debugging
these functions in hostile environments (like DOS clones) and in adapting
them to the future DOS versions. If you ever have any strange results
returned by f?stat()
, please call this function and post the
diagnostics it printed to the DJGPP mailing list.
The diagnostic messages this function prints are almost self-explanatory. Some explanations of terminology and abbreviations used by the printed messages will further clarify them.
SDA (Swappable DOS Area) - this is an internal DOS structure.
stat()
uses it to get the full directory entry (including the
starting cluster number) of a file. The pointer to SDA found by
stat()
is trusted only if we find the pathname of our file at a
specific offset in that SDA.
SFT (System File Table) - another internal DOS structure, used
in file operations. fstat()
uses it to get full information on a
file given its handle. An SFT entry which is found by fstat()
is
only trusted if it contains files size and time stamp like those
returned by DOS functions 57h and 42h. Novell NetWare 3.x traps DOS
file operations in such a way they never get to SFT, so some failure
messages refer specifically to Novell.
Hashing - the fall-back method of returning a unique inode number for each file. It is used whenever the starting cluster of a file couldn't be reliably determined.
None.
not ANSI, not POSIX
if (stat(path, &stat_buf)) _djstat_describe_lossage((FILE *)0);
#include <sys/stat.h> extern unsigned short _djstat_fail_bits;
As proper operation of stat
(see stat) and fstat
(see fstat) depend on undocumented DOS features, they could fail in
some incompatible environment or a future DOS version. If they do, the
_djstat_fail_bits
variable will have some of its bits set. Each
bit describes a single feature which was used and failed. The function
_djstat_describe_lossage may be called to print a human-readable
description of the bits which were set by the last call to
f?stat
. This should make debugging f?stat
failures in
an unanticipated environment a lot easier.
The following bits are currently defined:
_STFAIL_SDA
_STFAIL_OSVER
stat
or
less than 2.0 for fstat
).
_STFAIL_BADSDA
_STFAIL_TRUENAME
_truename
(see _truename) function call
failed.
_STFAIL_HASH
_STFAIL_LABEL
_STFAIL_DCOUNT
_STFAIL_WRITEBIT
fstat
was asked to get write access bit of a file, but couldn't.
_STFAIL_DEVNO
fstat
failed to get device number.
_STFAIL_BADSFT
fstat
, but its contents
can't be trusted because it didn't match file size and time stamp as
reported by DOS.
_STFAIL_SFTIDX
_STFAIL_SFTNF
Below are some explanations of terminology and abbreviations used by the
printed messages, which will further clarify the meaning of the above bits
and their descriptions printed by _djstat_describe_lossage
(see _djstat_describe_lossage).
SDA (Swappable Data Area) - this is an internal DOS structure.
stat
uses it to get the full directory entry (including the
starting cluster number) of a file. The pointer to SDA found by
stat
is trusted only if we find the pathname of our file at a
specific offset in that SDA.
SFT (System File Table) - another internal DOS structure, used
in file operations. fstat
uses it to get full information on a file
given its handle. An SFT entry which is found by fstat
is only
trusted if it contains files size and time stamp like those returned by
DOS functions 57h and 42h. Novell NetWare 3.x traps DOS file operations
in such a way they never get to SFT, so some failure messages refer
specifically to Novell.
Hashing - the fall-back method of returning a unique inode number for each file. It is used whenever the starting cluster of a file couldn't be reliably determined. The full pathname of the file is looked up in a table of files seen earlier (hashing is used to speed the lookup process). If found, the inode from the table is returned; this ensures that a given file will get the same inode number. Otherwise a new inode number is invented, recorded in the table and returned to caller.
not ANSI, not POSIX
#include <sys/stat.h> extern unsigned short _djstat_flags;
This variable contains bits for some fields of struct stat
which are
expensive to compute under DOS. Any such computation is only done by
stat
(see stat) or fstat
(see fstat) if the
corresponding bit in _djstat_flags
is cleared. By
default, all the bits are cleared, so applications which don't care,
automagically get a full version, possibly at a price of performance.
To get the fastest possible version for your application, clear
only the bits which you need and set all the others.
The following bits are currently defined:
_STAT_INODE
stat
and fstat
to compute the st_ino
(inode
number) field.
_STAT_EXEC_EXT
stat
and fstat
to compute the execute access bit
from the file-name extension. stat
and fstat
know about
many popular file-name extensions, to speed up the computation of the
execute access bit.
_STAT_EXEC_MAGIC
stat
and fstat
to compute the execute access bit from
magic signature (the first two bytes of the file), see _is_executable,
if the file-name extension is not enough for this.
Computing the execute access bit from the magic signature is by far the
most expensive part of stat
and fstat
(because it requires
to read the first two bytes of every file). If your application doesn't
care about execute access bit, setting _STAT_EXEC_MAGIC
will
significantly speed it up.
Note that if _STAT_EXEC_MAGIC
is set, but _STAT_EXEC_EXT
is not, some files which shouldn't be flagged as executables (e.g., COFF
*.o
object files) will have their execute bit set, because they
have the magic number signature at their beginning. Therefore, only use
the above combination if you want to debug the list of extensions
provided in is_exec.c
file.
_STAT_DIRSIZE
stat
to compute directory size by counting the number of its
entries (unless some friendly network redirector brought a true directory
size with it). Also computes the number of subdirectories and sets the
number of links st_nlink
field.
This computation is also quite expensive, especially for directories
with large sub-directories. If your application doesn't care about size
of directories and the st_nlink
member, you should set the
_STAT_DIRSIZE
bit in _djstat_flags
.
_STAT_ROOT_TIME
stat
to try to get time stamp of root directory from its
volume label entry, if there is one.
_STAT_WRITEBIT
fstat
that file's write access bit is required (this needs
special treatment only under some versions of Novell Netware).
Note that if you set a bit, some failure bits in
_djstat_fail_bits
(see _djstat_fail_bits) might not be set,
because some computations which report failures are only done when they
are required.
not ANSI, not POSIX
#include <stdio.h> int _doprnt(const char *format, void *params, FILE *file);
This is an internal function that is used by all the printf
style
functions, which simply pass their format, arguments, and stream to this
function.
See printf, for a discussion of the allowed formats and arguments.
The number of characters generated is returned.
not ANSI, not POSIX
int args[] = { 1, 2, 3, 66 }; _doprnt("%d %d %d %c\n", args, stdout);
#include <dos.h> unsigned int _dos_close(int handle);
This is a direct connection to the MS-DOS close function call (%ah = 0x3E). This function closes the specified file.
See _dos_open. See _dos_creat. See _dos_creatnew. See _dos_read. See _dos_write.
Returns 0 if successful or DOS error code on error (and sets errno).
not ANSI, not POSIX
int handle; _dos_creat("FOO.DAT", _A_ARCH, &handle); ... _dos_close(handle);
#include <dos.h> unsigned int _dos_commit(int handle);
This is a direct connection to the MS-DOS commit function call (%ah = 0x68). This function flushes DOS internal file buffers to disk.
Returns 0 if successful or DOS error code on error (and sets errno).
not ANSI, not POSIX
_dos_write(handle, buffer, 1000, &result); _dos_commit(handle); _dos_close(handle);
#include <dos.h> unsigned int _dos_creat(const char *filename, unsigned short attr, int *handle);
This is a direct connection to the MS-DOS creat function call (%ah = 0x3C). This function creates the given file with the given attribute and puts file handle into handle if creating is successful. If the file already exists it truncates the file to zero length. Meaning of attr parameter is the following:
_A_NORMAL (0x00)
_A_RDONLY (0x01)
_A_HIDDEN (0x02)
_A_SYSTEM (0x04)
_A_ARCH (0x20)
See also _dos_open, _dos_creatnew, _dos_read, _dos_write, and _dos_close.
This function does not support long filenames, even on systems where the LFN API (see LFN) is available. For LFN-aware functions with similar functionality see _creat, and _creatnew. Also see creat, and open, which are Posix-standard.
Returns 0 if successful or DOS error code on error (and sets errno)
not ANSI, not POSIX
int handle; if ( !_dos_creat("FOO.DAT", _A_ARCH, &handle) ) puts("Creating was successful !");
#include <dos.h> unsigned int _dos_creatnew(const char *filename, unsigned short attr, int *handle);
This is a direct connection to the MS-DOS create unique function call (%ah = 0x5B). This function creates the given file with the given attribute and puts file handle into handle if creating is successful. This function will fail if the specified file exists. Meaning of attr parameter is the following:
_A_NORMAL (0x00)
_A_RDONLY (0x01)
_A_HIDDEN (0x02)
_A_SYSTEM (0x04)
_A_ARCH (0x20)
See also _dos_open, _dos_creat, _dos_read, _dos_write, and _dos_close.
This function does not support long filenames, even on systems where the LFN API (see LFN) is available. For LFN-aware functions with similar functionality see _creatnew, and _creat. Also see creat, and open, which are Posix-standard.
Returns 0 if successful or DOS error code on error (and sets errno).
not ANSI, not POSIX
int handle; if ( !_dos_creatnew("FOO.DAT", _A_NORMAL, &handle) ) puts("Creating was successful !");
#include <dos.h> unsigned int _dos_findfirst(char *name, unsigned int attr, struct find_t *result);
This function and the related _dos_findnext
(see _dos_findnext)
are used to scan directories for the list of files therein. The name
is a wildcard that specifies the directory and files to search. result
is a structure to hold the results and state of the search, and attr
is a combination of the following:
_A_NORMAL (0x00)
_A_RDONLY (0x01)
_A_HIDDEN (0x02)
_A_SYSTEM (0x04)
_A_VOLID (0x08)
_A_SUBDIR (0x10)
_A_ARCH (0x20)
The results are returned in a struct find_t
defined on
<dos.h>
as follows:
struct find_t { char reserved[21]; unsigned char attrib; unsigned short wr_time; unsigned short wr_date; unsigned long size; char name[256]; };
See _dos_findnext.
This function does not support long filenames, even on systems where the LFN API (see LFN) is available. For LFN-aware functions with similar functionality see findfirst, and findnext. Also see opendir, and readdir, which are Posix-standard.
Zero if a match is found, DOS error code if not found (and sets errno).
not ANSI, not POSIX
#include <dos.h> struct find_t f; if ( !_dos_findfirst("*.DAT", &f, _A_ARCH | _A_RDONLY) ) { do { printf("%-14s %10u %02u:%02u:%02u %02u/%02u/%04u\n", f.name, f.size, (f.wr_time >> 11) & 0x1f, (f.wr_time >> 5) & 0x3f, (f.wr_time & 0x1f) * 2, (f.wr_date >> 5) & 0x0f, (f.wr_date & 0x1f), ((f.wr_date >> 9) & 0x7f) + 1980); } while( !_dos_findnext(&f) ); }
#include <dos.h> unsigned int _dos_findnext(struct find_t *result);
This finds the next file in the search started by _dos_findfirst
.
See _dos_findfirst, for the description of struct find_t
.
This function does not support long filenames, even on systems where the LFN API (see LFN) is available. For LFN-aware functions with similar functionality see findfirst, and findnext. Also see opendir, and readdir, which are Posix-standard.
Zero if a match is found, DOS error code if not found (and sets errno).
not ANSI, not POSIX
#include <dos.h> void _dos_getdate(struct dosdate_t *date);
This function gets the current date and fills the date structure with these values.
struct dosdate_t { unsigned char day; /* 1-31 */ unsigned char month; /* 1-12 */ unsigned short year; /* 1980-2099 */ unsigned char dayofweek; /* 0-6, 0=Sunday */ };
See _dos_setdate. See _dos_gettime. See _dos_settime.
None.
not ANSI, not POSIX
struct dosdate_t date; _dos_getdate(&date);
#include <dos.h> unsigned int _dos_getdiskfree(unsigned int drive, struct diskfree_t *diskspace);
This function determines the free space on drive drive
(0=default, 1=A:, 2=B:, etc.) and fills diskspace structure.
The members of struct diskfree_t
are defined by <dos.h>
as
follows:
struct diskfree_t { unsigned short total_clusters; unsigned short avail_clusters; unsigned short sectors_per_cluster; unsigned short bytes_per_sector; };
Returns with 0 if successful, non-zero on error (and sets errno
to EINVAL
).
not ANSI, not POSIX
struct diskfree_t df; unsigned long freebytes; if ( !_dos_getdiskfree(0, &df) ) { freebytes = (unsigned long)df.avail_clusters * (unsigned long)df.bytes_per_sector * (unsigned long)df.sectors_per_cluster; printf("There is %lu free bytes on the current drive.\n", freebytes); } else printf("Unable to get free disk space.\n");
#include <dos.h> void _dos_getdrive(unsigned int *p_drive);
This function determine the current default drive and writes this value into p_drive (1=A:, 2=B:, etc.).
See _dos_setdrive.
None.
not ANSI, not POSIX
unsigned int drive; _dos_getdrive(&drive); printf("The current drive is %c:.\n", 'A' - 1 + drive);
#include <dos.h> unsigned int _dos_getfileattr(const char *filename, unsigned int *p_attr);
This function determines the attributes of given file and fills attr with it. Use the following constans (in DOS.H) to check this value.
_A_NORMAL (0x00)
_A_RDONLY (0x01)
_A_HIDDEN (0x02)
_A_SYSTEM (0x04)
_A_VOLID (0x08)
_A_SUBDIR (0x10)
_A_ARCH (0x20)
See _dos_setfileattr.
This function does not support long filenames, even on systems where the LFN API (see LFN) is available. For LFN-aware functions with similar functionality see _chmod. Also see chmod, access, and stat, which are Posix-standard.
Returns with 0 if successful and DOS error value on error (and sets errno=ENOENT).
not ANSI, not POSIX
unsigned int attr; if ( !_dos_getfileattr("FOO.DAT", &attr) ) { puts("FOO.DAT attributes are:"); if ( attr & _A_ARCH ) puts("Archive"); if ( attr & _A_RDONLY ) puts("Read only"); if ( attr & _A_HIDDEN ) puts("Hidden"); if ( attr & _A_SYSTEM ) puts("Is it part of DOS ?"); if ( attr & _A_VOLID ) puts("Volume ID"); if ( attr & _A_SUBDIR ) puts("Directory"); } else puts("Unable to get FOO.DAT attributes.");
#include <dos.h> unsigned int _dos_getftime(int handle, unsigned int *p_date, unsigned *p_time);
This function gets the date and time of the given file and puts these values into p_date and p_time variable. The meaning of DOS date in the p_date variable is the following:
F E D C B A 9 8 7 6 5 4 3 2 1 0 (bits) X X X X X X X X X X X X X X X X *-----------------------* *-----------* *---------------* year month day year = 0-119 (relative to 1980) month = 1-12 day = 1-31
The meaning of DOS time in the p_time variable is the following:
F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X X X X X X X X X X X X X X *---------------* *-------------------* *---------------* hours minutes seconds hours = 0-23 minutes = 0-59 seconds = 0-29 in two-second intervals
See _dos_setftime.
This function cannot be used to return last access and creation date and time, even on systems where the LFN API (see LFN) is available. See _lfn_get_ftime, for a function that can be used to get the other two times. Also see fstat, which is Posix-standard.
Returns 0 if successful and return DOS error on error (and sets errno=EBADF).
not ANSI, not POSIX
unsigned int handle, date, time; _dos_open("FOO.DAT", O_RDWR, &handle); _dos_gettime(handle, &date, &time); _dos_close(handle); printf("FOO.DAT date and time is: %04u-%02u-%02u %02u:%02u:%02u.\n", /* year month day */ ((date >> 9) & 0x7F) + 1980U, (date >> 5) & 0x0F, date & 0x1F, /* hour minute second */ (time >> 11) & 0x1F, (time >> 5) & 0x3F, (time & 0x1F) * 2);
#include <dos.h> void _dos_gettime(struct dostime_t *time);
This function gets the current time and fills the time structure with these values.
struct dostime_t { unsigned char hour; /* 0-23 */ unsigned char minute; /* 0-59 */ unsigned char second; /* 0-59 */ unsigned char hsecond; /* 0-99 */ };
See _dos_settime. See _dos_getdate. See _dos_setdate.
None.
not ANSI, not POSIX
struct dostime_t time; _dos_gettime(&time);
#include <io.h> int _dos_lock(int _fd, long _offset, long _length)
Adds an advisory lock to the specified region of the file.
Zero if the lock was added, nonzero otherwise.
not ANSI, not POSIX
#include <fcntl.h> #include <share.h> #include <dos.h> unsigned int _dos_open(const char *filename, unsigned short mode, int *handle);
This is a direct connection to the MS-DOS open function call (%ah = 0x3D). This function opens the given file with the given mode and puts handle of file into handle if openning is successful. Meaning of mode parameter is the following:
Access mode bits (in FCNTL.H):
O_RDONLY (_O_RDONLY) 0x00
O_WRONLY (_O_WRONLY) 0x01
O_RDWR (_O_RDWR) 0x02
Sharing mode bits (in SHARE.H):
SH_COMPAT (_SH_COMPAT) 0x00
SH_DENYRW (_SH_DENYRW) 0x10
SH_DENYWR (_SH_DENYWR) 0x20
SH_DENYRD (_SH_DENYRD) 0x30
SH_DENYNO (_SH_DENYNO) 0x40
Inheritance bits (in FCNTL.H):
O_NOINHERIT (_O_NOINHERIT) 0x80
See also _dos_creat, _dos_creatnew, _dos_read, _dos_write, and _dos_close.
This function does not support long filenames, even on systems where the LFN API (see LFN) is available. For LFN-aware functions with similar functionality see _open, _creat, and _creatnew. Also see open, and creat, which are Posix-standard.
Returns 0 if successful or DOS error code on error (and sets errno to EACCES, EINVAL, EMFILE or ENOENT).
not ANSI, not POSIX
int handle; if ( !_dos_open("FOO.DAT", O_RDWR, &handle) ) puts("Wow, file opening was successful !");
#include <dos.h> unsigned int _dos_read(int handle, void *buffer, unsigned int count, unsigned int *result);
This is a direct connection to the MS-DOS read function call (%ah = 0x3F). No conversion is done on the data; it is read as raw binary data. This function reads from handle into buffer count bytes. count value may be arbitrary size (for example > 64KB). It puts number of bytes read into result if reading is successful.
See also _dos_open, _dos_creat, _dos_creatnew, _dos_write, and _dos_close.
Returns 0 if successful or DOS error code on error (and sets errno to EACCES or EBADF)
not ANSI, not POSIX
int handle; unsigned int result; char *filebuffer; if ( !_dos_open("FOO.DAT", O_RDONLY, &handle) ) { puts("FOO.DAT openning was successful."); if ( (filebuffer = malloc(130000)) != NULL ) { if ( !_dos_read(handle, buffer, 130000, &result) ) printf("%u bytes read from FOO.DAT.\n", result); else puts("Reading error."); ... /* Do something with filebuffer. */ ... } _dos_close(handle); }
#include <dos.h> unsigned int _dos_setdate(struct dosdate_t *date);
This function sets the current date. The dosdate_t structure is as follows:
struct dosdate_t { unsigned char day; /* 1-31 */ unsigned char month; /* 1-12 */ unsigned short year; /* 1980-2099 */ unsigned char dayofweek; /* 0-6, 0=Sunday */ };
dayofweek field has no effect at this function call.
See _dos_getdate. See _dos_gettime. See _dos_settime.
Returns 0 if successful and non-zero on error (and sets errno=EINVAL).
not ANSI, not POSIX
struct dosdate_t date; date->year = 1999; date->month = 12; date->day = 31; if ( !_dos_setdate(&date) ) puts("It was a valid date.");
#include <dos.h> void _dos_setdrive(unsigned int drive, unsigned int *p_drives);
This function set the current default drive based on drive (1=A:, 2=B:, etc.) and determines the number of available logical drives and fills p_drives with it.
See _dos_getdrive.
None.
not ANSI, not POSIX
unsigned int available_drives; /* The current drive will be A: */ _dos_setdrive(1, &available_drives); printf("Number of available logical drives %u.\n", available_drives);
#include <dos.h> unsigned int _dos_setfileattr(const char *filename, unsigned int attr);
This function sets the attributes of given file. Use the following constans in DOS.H to create attr parameter:
_A_NORMAL (0x00)
_A_RDONLY (0x01)
_A_HIDDEN (0x02)
_A_SYSTEM (0x04)
_A_VOLID (0x08)
_A_SUBDIR (0x10)
_A_ARCH (0x20)
See _dos_getfileattr.
This function does not support long filenames, even on systems where the LFN API (see LFN) is available. For LFN-aware functions with similar functionality see _chmod. Also see chmod, which is Posix-standard.
Returns with 0 if successful and DOS error value on error (and sets errno to ENOENT or EACCES).
not ANSI, not POSIX
if ( !_dos_setfileattr("FOO.DAT", _A_RDONLY | _A_HIDDEN) ) puts("FOO.DAT is hidden now.");
#include <dos.h> unsigned int _dos_setftime(int handle, unsigned int date, unsigned time);
This function sets the date and time of the given file. The meaning of DOS date in the date variable is the following:
F E D C B A 9 8 7 6 5 4 3 2 1 0 (bits) x x x x x x x x x x x x x x x x *-----------* *-----* *-------* year month day year = 0-119 (relative to 1980) month = 1-12 day = 1-31
The meaning of DOS time in the time variable is the following:
F E D C B A 9 8 7 6 5 4 3 2 1 0 (bits) x x x x x x x x x x x x x x x x *-------* *---------* *-------* hours minutes seconds hours = 0-23 minutes = 0-59 seconds = 0-29 in two-second intervals
See _dos_getftime.
This function cannot be used to set the last access date and time, even on systems where the LFN API (see LFN) is available. For LFN-aware functions with similar functionality see utime, which is Posix-standard, and see utimes.
Returns 0 if successful and return DOS error on error (and sets errno=EBADF).
not ANSI, not POSIX
struct dosdate_t d; struct dostime_t t; unsigned int handle, date, time; _dos_open("FOO.DAT", O_RDWR, &handle); _dos_getdate(&d); _dos_gettime(&t); date = ((d.year - 1980) << 9) | (d.month << 5) | d.day; time = (t.hour << 11) | (t.minute << 5) | (t.second / 2); _dos_settime(handle, date, time); _dos_close(handle);
#include <dos.h> void _dos_settime(struct dostime_t *time);
This function sets the current time. The time structure is as follows:
struct dostime_t { unsigned char hour; /* 0-23 */ unsigned char minute; /* 0-59 */ unsigned char second; /* 0-59 */ unsigned char hsecond; /* 0-99 */ };
See _dos_gettime. See _dos_getdate. See _dos_setdate.
Returns 0 if successful and non-zero on error (and sets errno=EINVAL).
not ANSI, not POSIX
struct dostime_t time; time->hour = 23; time->minute = 59; time->second = 59; time->hsecond = 99; if ( !_dos_settime(&time) ) puts("It was a valid time.");
#include <io.h> _dos_unlock(int _fd, long _offset, long _length)
Removes an advisory lock to the specified region of the file.
Zero if the lock was removed, nonzero otherwise.
not ANSI, not POSIX
#include <dos.h> unsigned int _dos_write(int handle, const void *buffer, unsigned int count, unsigned int *result);
This is a direct connection to the MS-DOS write function call (%ah = 0x40). No conversion is done on the data; it is written as raw binary data. This function writes count bytes from buffer to handle. count value may be arbitrary size (e.g. > 64KB). It puts the number of bytes written into result if writing is successful.
See also _dos_open, _dos_creat, _dos_creatnew, _dos_read, and _dos_close.
Returns 0 if successful or DOS error code on error (and sets errno to EACCES or EBADF)
not ANSI, not POSIX
int handle; unsigned int result; char *filebuffer; if ( !_dos_creat("FOO.DAT", _A_ARCH, &handle) ) { puts("FOO.DAT creating was successful."); if ( (filebuffer = malloc(130000)) != NULL ) { ... /* Put something into filebuffer. */ ... if ( !_dos_write(handle, buffer, 130000, &result) ) printf("%u bytes written into FOO.DAT.", result); else puts("Writing error."); } _dos_close(handle); }
#include <stdio.h> int _doscan(FILE *file, const char *format, void **ptrs_to_args);
This is an internal function that is used by all the scanf
style
functions, which simply pass their format, arguments, and stream to this
function.
See scanf, for a discussion of the allowed formats and arguments.
The number of characters successfully scanned is returned, or -1 on error.
not ANSI, not POSIX
int x, y; int *args[2]; args[0] = &x; args[1] = &y; _doscan(stdin, "%d %d", args);
#include <errno.h> extern int _doserrno;
Whenever a DOS call returns a failure indication, this variable is assigned the value of the error code returned by the failed DOS call.
For a list of the error codes and their short descriptions, see dosexterr.
not ANSI, not POSIX
_doserrno = 0; fprintf (stdprn, "Hello, world!\r\n\f"); if (_doserrno == 0x1c) fprintf (stderr, "The printer is out of paper!\n");
#include <dos.h> int dosexterr(struct DOSERROR *p_error);
This function reads extended error information from DOS and fills p_error structure.
struct _DOSERROR { int exterror; char class; char action; char locus; };
Values for extended error code (exterror field):
00h (0) no error 01h (1) function number invalid 02h (2) file not found 03h (3) path not found 04h (4) too many open files (no handles available) 05h (5) access denied 06h (6) invalid handle 07h (7) memory control block destroyed 08h (8) insufficient memory 09h (9) memory block address invalid 0Ah (10) environment invalid (usually >32K in length) 0Bh (11) format invalid 0Ch (12) access code invalid 0Dh (13) data invalid 0Eh (14) reserved 0Fh (15) invalid drive 10h (16) attempted to remove current directory 11h (17) not same device 12h (18) no more files 13h (19) disk write-protected 14h (20) unknown unit 15h (21) drive not ready 16h (22) unknown command 17h (23) data error (CRC) 18h (24) bad request structure length 19h (25) seek error 1Ah (26) unknown media type (non-DOS disk) 1Bh (27) sector not found 1Ch (28) printer out of paper 1Dh (29) write fault 1Eh (30) read fault 1Fh (31) general failure 20h (32) sharing violation 21h (33) lock violation 22h (34) disk change invalid (ES:DI -> media ID structure)(see below) 23h (35) FCB unavailable 24h (36) sharing buffer overflow 25h (37) (DOS 4+) code page mismatch 26h (38) (DOS 4+) cannot complete file operation (out of input) 27h (39) (DOS 4+) insufficient disk space 28h-31h reserved 32h (50) network request not supported 33h (51) remote computer not listening 34h (52) duplicate name on network 35h (53) network name not found 36h (54) network busy 37h (55) network device no longer exists 38h (56) network BIOS command limit exceeded 39h (57) network adapter hardware error 3Ah (58) incorrect response from network 3Bh (59) unexpected network error 3Ch (60) incompatible remote adapter 3Dh (61) print queue full 3Eh (62) queue not full 3Fh (63) not enough space to print file 40h (64) network name was deleted 41h (65) network: Access denied 42h (66) network device type incorrect 43h (67) network name not found 44h (68) network name limit exceeded 45h (69) network BIOS session limit exceeded 46h (70) temporarily paused 47h (71) network request not accepted 48h (72) network print/disk redirection paused 49h (73) network software not installed (LANtastic) invalid network version 4Ah (74) unexpected adapter close (LANtastic) account expired 4Bh (75) (LANtastic) password expired 4Ch (76) (LANtastic) login attempt invalid at this time 4Dh (77) (LANtastic v3+) disk limit exceeded on network node 4Eh (78) (LANtastic v3+) not logged in to network node 4Fh (79) reserved 50h (80) file exists 51h (81) reserved 52h (82) cannot make directory 53h (83) fail on INT 24h 54h (84) (DOS 3.3+) too many redirections 55h (85) (DOS 3.3+) duplicate redirection 56h (86) (DOS 3.3+) invalid password 57h (87) (DOS 3.3+) invalid parameter 58h (88) (DOS 3.3+) network write fault 59h (89) (DOS 4+) function not supported on network 5Ah (90) (DOS 4+) required system component not installed 64h (100) (MSCDEX) unknown error 65h (101) (MSCDEX) not ready 66h (102) (MSCDEX) EMS memory no longer valid 67h (103) (MSCDEX) not High Sierra or ISO-9660 format 68h (104) (MSCDEX) door open
Values for error class (class field):
01h out of resource (storage space or I/O channels) 02h temporary situation (file or record lock) 03h authorization (denied access) 04h internal (system software bug) 05h hardware failure 06h system failure (configuration file missing or incorrect) 07h application program error 08h not found 09h bad format 0Ah locked 0Bh media error 0Ch already exists 0Dh unknown
Values for suggested action (action field):
01h retry 02h delayed retry 03h prompt user to reenter input 04h abort after cleanup 05h immediate abort 06h ignore 07h retry after user intervention
Values for error locus (locus field):
01h unknown or not appropriate 02h block device (disk error) 03h network related 04h serial device (timeout) 05h memory related
Returns with the extended error code.
not ANSI, not POSIX
#include <stdio.h> #include <dos.h> void main(void) { FILE *fp; struct _DOSERROR de; fp = fopen("EXAMPLE.DAT","r"); if ( fp == NULL ) { puts("Unable to open file for reading."); _dosexterr(&de); printf("Extended DOS error information:\n"); printf("Extended error: %i\n",de.exterror); printf("Class: %x\n",de.class); printf("Action: %x\n",de.action); printf("Error Locus: %x\n",de.locus); } }
#include <sys/movedata.h> void dosmemget(int offset, int length, void *buffer);
This function transfers data from MS-DOS's conventional memory space to the program's virtual address space. The offset is a physical address, which can be computed from a real-mode segment/offset pair as follows:
offset = segment * 16 + offset;
The length is the number of bytes to transfer, and buffer is
a pointer to somewhere in your virtual address space (such as memory
obtained from malloc
) where the data will go.
None.
not ANSI, not POSIX
unsigned short shift_state; dosmemget(0x417, 2, &shift_state); if (shift_state & 0x0004) /* Ctrl key pressed */;
#include <sys/movedata.h> void _dosmemgetb(unsigned long offset, size_t xfers, void *buffer);
This function transfers data from MS-DOS's conventional memory space to the program's virtual address space, using only byte transfers. The offset is a physical address, which can be computed from a real-mode segment/offset pair as follows:
offset = segment * 16 + offset;
The xfers is the number of bytes to transfer, and buffer is
a pointer to somewhere in your virtual address space (such as memory
obtained from malloc
) where the data will go.
None.
not ANSI, not POSIX
unsigned short shift_state; _dosmemgetb(0x417, 2, &shift_state); if (shift_state & 0x0004) /* Ctrl key pressed */;
#include <sys/movedata.h> void _dosmemgetl(unsigned long offset, size_t xfers, void *buffer);
This function transfers data from MS-DOS's conventional memory space to the program's virtual address space, using only long-word (32-bit) transfers. The offset is a physical address, which can be computed from a real-mode segment/offset pair as follows:
offset = segment * 16 + offset;
The count is the number of long-words to transfer, and
buffer is a pointer to somewhere in your virtual address space
(such as memory obtained from malloc
) where the data will go.
None.
not ANSI, not POSIX
unsigned long shift_state; _dosmemgetl(0x417, 1, &shift_state); if (shift_state & 0x0004) /* Ctrl key pressed */;
#include <sys/movedata.h> void _dosmemgetw(unsigned long offset, size_t xfers, void *buffer);
This function transfers data from MS-DOS's conventional memory space to the program's virtual address space, using only short-word (16-bit) transfers. The offset is a physical address, which can be computed from a real-mode segment/offset pair as follows:
offset = segment * 16 + offset;
The xfers is the number of words to transfer, and buffer
is a pointer to somewhere in your virtual address space (such as
memory obtained from malloc
) where the data will go.
None.
not ANSI, not POSIX
unsigned short shift_state; _dosmemgetw(0x417, 1, &shift_state); if (shift_state & 0x0004) /* Ctrl key pressed */;
#include <sys/movedata.h> void dosmemput(const void *buffer, int length, int offset);
This function transfers data from the program's virtual address space to MS-DOS's conventional memory space. The offset is a physical address, which can be computed from a real-mode segment/offset pair as follows:
offset = segment * 16 + offset;
The length is the number of bytes to transfer, and buffer is
a pointer to somewhere in your virtual address space (such as memory
obtained from malloc
) where the data will come from.
None.
not ANSI, not POSIX
unsigned short save_screen[25][80]; dosmemput(save_screen, 80*2*25, 0xb8000);
#include <sys/movedata.h> void _dosmemputb(const void *buffer, size_t xfers, unsigned long offset);
This function transfers data from the program's virtual address space to MS-DOS's conventional memory space, using only byte (8-bit) transfers. The offset is a physical address, which can be computed from a real-mode segment/offset pair as follows:
offset = segment * 16 + offset;
The xfers is the number of bytes to transfer, and buffer
is a pointer to somewhere in your virtual address space (such as
memory obtained from malloc
) where the data will come from.
None.
not ANSI, not POSIX
unsigned short save_screen[25][80]; _dosmemputb(save_screen, 0xb8000, 80*2*25);
#include <sys/movedata.h> void _dosmemputl(const void *buffer, size_t xfers, unsigned long offset);
This function transfers data from the program's virtual address space to MS-DOS's conventional memory space, using only long-word (32-bit) transfers. The offset is a physical address, which can be computed from a real-mode segment/offset pair as follows:
offset = segment * 16 + offset;
The xfers is the number of long-words to transfer, and
buffer is a pointer to somewhere in your virtual address space
(such as memory obtained from malloc
) where the data will come
from.
None.
not ANSI, not POSIX
unsigned short save_screen[25][80]; _dosmemputl(save_screen, 40*25, 0xb8000);
#include <sys/movedata.h> void _dosmemputw(const void *buffer, size_t xfers, unsigned long offset);
This function transfers data from the program's virtual address space to MS-DOS's conventional memory space, using only short-word (16-bit) transfers. The offset is a physical address, which can be computed from a real-mode segment/offset pair as follows:
offset = segment * 16 + offset;
The xfers is the number of short-words to transfer, and
buffer is a pointer to somewhere in your virtual address space
(such as memory obtained from malloc
) where the data will come
from.
None.
not ANSI, not POSIX
unsigned short save_screen[25][80]; _dosmemputw(save_screen, 0xb8000, 80*25);
extern unsigned short __dpmi_error;
For most functions, the error returned from the DPMI server is stored in this variable.
typedef struct { unsigned short offset16; unsigned short segment; } __dpmi_raddr;
This structure is used to hold a real-mode address, which consists of a segment:offset pair.
typedef struct { unsigned long offset32; unsigned short selector; } __dpmi_paddr;
This structure is used to hold a protected-mode address, which consists of a selector:offset pair.
typedef struct { unsigned long handle; /* 0, 2 */ unsigned long size; /* or count */ /* 4, 6 */ unsigned long address; /* 8, 10 */ } __dpmi_meminfo;
This structure is used by many functions that need to refer to blocks
of 32-bit memory. The size
field doubles as a count for those
operations that want a count of something, or return a count.
typedef union { struct { unsigned long edi; unsigned long esi; unsigned long ebp; unsigned long res; unsigned long ebx; unsigned long edx; unsigned long ecx; unsigned long eax; } d; struct { unsigned short di, di_hi; unsigned short si, si_hi; unsigned short bp, bp_hi; unsigned short res, res_hi; unsigned short bx, bx_hi; unsigned short dx, dx_hi; unsigned short cx, cx_hi; unsigned short ax, ax_hi; unsigned short flags; unsigned short es; unsigned short ds; unsigned short fs; unsigned short gs; unsigned short ip; unsigned short cs; unsigned short sp; unsigned short ss; } x; struct { unsigned char edi[4]; unsigned char esi[4]; unsigned char ebp[4]; unsigned char res[4]; unsigned char bl, bh, ebx_b2, ebx_b3; unsigned char dl, dh, edx_b2, edx_b3; unsigned char cl, ch, ecx_b2, ecx_b3; unsigned char al, ah, eax_b2, eax_b3; } h; } __dpmi_regs;
This structure is used by functions that pass register information, such as simulating real-mode calls.
typedef struct { unsigned char major; unsigned char minor; unsigned short flags; unsigned char cpu; unsigned char master_pic; unsigned char slave_pic; } __dpmi_version_ret;
This structure is used to return version information to the program.
typedef struct { unsigned long largest_available_free_block_in_bytes; unsigned long maximum_unlocked_page_allocation_in_pages; unsigned long maximum_locked_page_allocation_in_pages; unsigned long linear_address_space_size_in_pages; unsigned long total_number_of_unlocked_pages; unsigned long total_number_of_free_pages; unsigned long total_number_of_physical_pages; unsigned long free_linear_address_space_in_pages; unsigned long size_of_paging_file_partition_in_pages; unsigned long reserved[3]; } __dpmi_free_mem_info;
This structure is used to return information about the state of virtual memory in the system.
typedef struct { unsigned long total_allocated_bytes_of_physical_memory_host; unsigned long total_allocated_bytes_of_virtual_memory_host; unsigned long total_available_bytes_of_virtual_memory_host; unsigned long total_allocated_bytes_of_virtual_memory_vcpu; unsigned long total_available_bytes_of_virtual_memory_vcpu; unsigned long total_allocated_bytes_of_virtual_memory_client; unsigned long total_available_bytes_of_virtual_memory_client; unsigned long total_locked_bytes_of_memory_client; unsigned long max_locked_bytes_of_memory_client; unsigned long highest_linear_address_available_to_client; unsigned long size_in_bytes_of_largest_free_memory_block; unsigned long size_of_minimum_allocation_unit_in_bytes; unsigned long size_of_allocation_alignment_unit_in_bytes; unsigned long reserved[19]; } __dpmi_memory_info;
This is also used to return memory information, but by a different function.
typedef struct { unsigned long data16[2]; unsigned long code16[2]; unsigned short ip; unsigned short reserved; unsigned long data32[2]; unsigned long code32[2]; unsigned long eip; } __dpmi_callback_info;
This structure is used to install TSR programs.
typedef struct { unsigned long size_requested; unsigned long size; unsigned long handle; unsigned long address; unsigned long name_offset; unsigned short name_selector; unsigned short reserved1; unsigned long reserved2; } __dpmi_shminfo;
This structure is used to manipulate shared memory regions.
To obtain the DPMI specification, Contact Intel and order document number 240977-001. Also, try ftp.qdeck.com:/pub/memory/dpmi* and http://www.delorie.com/djgpp/doc/dpmi/.
#include <dpmi.h> int __dpmi_allocate_dos_memory(int _paragraphs, int *_ret_selector_or_max);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0100
This function allocates DOS memory. You pass it the number of paragraphs ((bytes+15)>>4) to allocate. If it succeeds, it returns a segment (dos-style) and fills in _ret_selector_or_max with a selector (protected-mode) that you can use to reference the same memory. Note that it's the selector you use to free the block, not the segment.
-1 on error, else the segment [0000..FFFF].
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_allocate_ldt_descriptors(int count);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0000
Allocates count descriptors.
-1 on error, else the first descriptor. Use __dpmi_get_selector_increment_value to figure out the remaining selectors.
not ANSI, not POSIX
short sel = __dpmi_allocate_ldt_descriptors(1);
#include <dpmi.h> int __dpmi_allocate_linear_memory(__dpmi_meminfo *info, int commit);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0504 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This allocates a block of page-aligned linear address space. Pass a desired address (or zero for any) and a size. commit is 1 for committed pages, else they are uncommitted. It returns a handle and the actual address.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_allocate_memory(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0501
This allocates virtual memory. Fill in size, returns handle and address.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_allocate_real_mode_callback(void (*_handler)(void), __dpmi_regs *_regs, __dpmi_raddr *_ret);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0303
This function gives you a real-mode address to pass to TSRs that gets reflected to your protected-mode handler. You pass it a register block to use; it gets filled in with the real-mode registers when your handler is called, and the registers are set from it when the handler returns.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_allocate_shared_memory(__dpmi_shminfo *info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0d00 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function allocates a shared memory block that can be accessed from
different virtual machines. Fill the required length in
info->size_requested
. The function fills the rest of the
structure: allocated length in info->size
, block handle in
info->handle
, linear address in info->address
,
and the selector:offset of an ASCIIZ block name (up to 128 bytes
long) in info->name_selector
and
info->name_offset
, respectively.
The access to the shared memory block can be serialized by calling
the __dpmi_serialize_on_shared_memory
function
(see __dpmi_serialize_on_shared_memory).
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_allocate_specific_ldt_descriptor(int _selector);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x000d
This allocates the specific selector given.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_clear_debug_watchpoint(unsigned long _handle);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0b01
Clear a debug watchpoint.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_create_alias_descriptor(int _selector);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x000a
Create a new selector with the same parameters as the given one.
-1 on error, else the new selector.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_discard_page_contents(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0703
Advises the server that the given pages are no longer needed and may be reclaimed. Fill in address and size (in bytes).
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_free_dos_memory(int _selector);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0101
This function frees the dos memory allocated by __dpmi_allocate_dos_memory. Remember to pass the selector and not the segment.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_free_ldt_descriptor(int descriptor);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0001
This function frees a single descriptor, even if it was allocated as one of many.
-1 on error, else zero.
not ANSI, not POSIX
__dpmi_free_ldt_descriptor(sel);
#include <dpmi.h> int __dpmi_free_memory(unsigned long _handle);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0502
This frees a block of virtual memory.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_free_physical_address_mapping(__dpmi_meminfo *info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0801 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function unmaps a physical device mapped with __dpmi_physical_address_mapping. Fill in the linear address.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_free_real_mode_callback(__dpmi_raddr *_addr);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0303
This function frees the real-mode callback address.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_free_serialization_on_shared_memory(unsigned long handle, int flags);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0d03 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function frees the serialization on shared memory block specified by its handle handle. The bit-mapped variable flags defines the following bits:
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_free_shared_memory(unsigned long handle);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0d01 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function frees the shared memory block specified by the given handle. The handle becomes invalid after this call.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_and_disable_virtual_interrupt_state(void);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0900
This function disables interrupts, and returns the previous setting.
The previous setting.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_and_enable_virtual_interrupt_state(void);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0901
This function enables interrupts, and returns the previous setting.
The previous setting.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_and_set_virtual_interrupt_state(int _old_state);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AH = 0x09
This function restores the interrupt state from a previous call to __dpmi_get_and_disable_virtual_interrupt_state or __dpmi_get_and_enable_virtual_interrupt_state.
The previous setting.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_capabilities(int *flags, char *vendor_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0401 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
Gets the capabilities of the server. flags are as follows:
---- ---X = 1="page accessed/dirty" supported ---- --X- = 1="exceptions restartble" supported ---- -X-- = 1="device mapping" supported ---- X--- = 1="map conventional memory" supported ---X ---- = 1="demand zero-fill" supported --X- ---- = 1="write-protect client" supported -X-- ---- = 1="write-protect host" supported
The vendor info is a 128-byte buffer:
[0] host major number [1] host minor number [2..127] vendor name
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_coprocessor_status(void);
Please refer to DPMI Specification, for details on DPMI function call operation. Also see DPMI Overview, for general information.
DPMI function AX = 0x0e00 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
-1 on error, else returns the processor status flags. Here's the meaning of each set bit:
0000
0010
0011
0100
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_descriptor(int _selector, void *_buffer);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x000b
This function fills the 8-byte buffer pointed to by _buffer with the parameters of the descriptor whose selector is passed in _selector. The data has the following format:
[0] XXXX XXXX = segment limit [7:0] [1] XXXX XXXX = segment limit [15:8] [2] XXXX XXXX = base address [7:0] [3] XXXX XXXX = base address [15:8] [4] XXXX XXXX = base address [23:16] [5] ---- XXXX = type; see details below [5] ---X ---- = 0=system, 1=application (must be 1) [5] -XX- ---- = privilege level, usually 3 (binary 11) [5] X--- ---- = 0=absent, 1=present; usually 1 [6] ---- XXXX = segment limit [19:16] [6] ---X ---- = available for user; see details below [6] --0- ---- = must be zero [6] -X-- ---- = 0=16-bit 1=32-bit; usually 1 [6] X--- ---- = 0=byte-granular (small) 1=page-granular (big) [7] XXXX XXXX = base address [31:24]
Here's an alternative view of the layout that treats the buffer as an
array of 4 16-bit words (i.e., unsigned short
s):
[0] XXXX XXXX XXXX XXXX = segment limit [15:0] [1] XXXX XXXX XXXX XXXX = base address [15:0] [2] ---- ---- XXXX XXXX = base address [23:16] [2] ---- XXXX ---- ---- = type; see details below [2] ---1 ---- ---- ---- = 0=system, 1=application; must be 1 [2] -XX- ---- ---- ---- = privilege level, usually 3 (binary 11) [2] X--- ---- ---- ---- = 0=absent, 1=present; usually 1 [3] ---- ---- ---- XXXX = segment limit [19:16] [3] ---- ---- ---X ---- = available for user; see details below [3] ---- ---- --0- ---- = must be zero [3] ---- ---- -X-- ---- = 0=16-bit 1=32-bit; usually 1 [3] ---- ---- X--- ---- = 0=byte-granular (small) 1=page-granular (big) [3] XXXX XXXX ---- ---- = base address [31:24]
Special considerations apply to some of the fields:
For expand-down data segments (see below), the segment limit is the
lower limit of the segment; the upper limit is either 0xffffffff
or 0xffff, depending on whether the size bit is set (32-bit default
size) or not (16-bit default size). For expand-down segments, values of
offset less than the segment limit result in a GPF.
---X = 0=not accessed, 1=accessed --1- = 0=execute only, 1=execute/read; must be 1 -0-- = 0=non-conforming, 1=conforming; must be 0 1--- = 0=data segment, 1=code segment
The accessed/not accessed bit indicates whether the segment has been accessed since the last time the bit was cleared. This bit is set whenever the segment selector is loaded into a segment register, and the bit then remains set until explicitly cleared. This bit can be used for debugging purposes.
The read bit must be set to allow reading data from the code segment, which is done in several cases by the library. The DPMI spec (see DPMI Specification) requires this bit to be 1 for code segments.
The conforming bit must be cleared so that transfer of execution into this segment from a less-privileged segment will result in a GPF. The DPMI spec (see DPMI Specification) requires this bit to be 0 for code segments.
For data segments, the meaning of the type
field is as follows:
---X = 0=not accessed, 1=accessed --X- = 0=read-only, 1=read/write -X-- = 0=expand-up, 1=expand-down; usually 0 0--- = 0=data segment, 1=code segment
The accessed/not accessed bit has the same meaning as for code segments.
The expand up/down bit is meant to be 1 for stack segments whose size
should be changed dynamically, whereby changing the limit adds the
additional space to the bottom of the stack; for data segments and
statically-sized stack segments, this bit is usually zero.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_descriptor_access_rights(int _selector);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
This function returns the access rights byte from the lar
opcode.
The access byte. See __dpmi_set_descriptor_access_rights, for the details about the access information returned. Also see __dpmi_get_descriptor.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_extended_exception_handler_vector_pm(int vector, __dpmi_paddr *address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0210 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This gets the function that handles protected mode exceptions.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_extended_exception_handler_vector_rm(int vector, __dpmi_paddr *address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0211 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function gets the handler for real-mode exceptions.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_free_memory_information(__dpmi_free_mem_info *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0500
This function returns information about available memory. Unsupported fields will have -1 (0xfffffff) in them.
Zero. This always works.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_memory_block_size_and_base(__dpmi_meminfo *info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x050a (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
Pass the handle. It fills in the address and size.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_memory_information(__dpmi_memory_info *buffer);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x050b (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function returns virtual memory information, as follows:
total_allocated_bytes_of_physical_memory_host
total_allocated_bytes_of_virtual_memory_host
total_available_bytes_of_virtual_memory_host
total_allocated_bytes_of_virtual_memory_vcpu
total_available_bytes_of_virtual_memory_vcpu
total_allocated_bytes_of_virtual_memory_client
total_available_bytes_of_virtual_memory_client
total_locked_bytes_of_memory_client
max_locked_bytes_of_memory_client
highest_linear_address_available_to_client
size_in_bytes_of_largest_free_memory_block
size_of_minimum_allocation_unit_in_bytes
size_of_allocation_alignment_unit_in_bytes
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_multiple_descriptors(int count, void *buffer);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x000e (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function gets a list of selectors' parameters. The buffer pointed to by buffer must be prefilled with selector values, and will contain the parameters on return:
[0x00:2] selector #1 (pass) [0x02:8] parameters #1 (returned) [0x0a:2] selector #2 (pass) [0x0c:8] parameters #2 (returned) ...
Returns count if successful, the negative of the number of descriptors copied if failure.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_page_attributes(__dpmi_meminfo *info, short *buffer);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0506 (DPMI 1.0 only). Supported by CWSDPMI, but not by Windows.
This function retrieves the attributes of a number of pages. Pass the
handle in info->handle
, offset of first page (relative to
start of block) in info->address
, and number of pages in
info->count
. The buffer buffer gets filled in with
the attributes. For each page, a 16-bit attribute word in buffer
defines the attributes of that page as follows:
000
001
010
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_page_size(unsigned long *_size);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0604
Fills in the page size.
-1 on error (16-bit host), else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_processor_exception_handler_vector(int _vector, __dpmi_paddr *_address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0202
This function gets the current protected-mode exception handler (not interrupts) for the exception _vector. It will return a selector:offset pair in the members of the _address variable.
-1 on error (invalid vector), else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_protected_mode_interrupt_vector(int _vector, __dpmi_paddr *_address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0204
This function gets the address of the current protected mode interrupt (not exception) handler. It returns a selector:offset pair.
Zero. This always works.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_raw_mode_switch_addr(__dpmi_raddr *_rm, __dpmi_paddr *_pm);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0306
Read the spec for more info.
Zero. This always works.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_real_mode_interrupt_vector(int _vector, __dpmi_raddr *_address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0200
This function stores the real-mode interrupt vector address in _address. This is the same as the DOS get vector call, and returns a real-mode segment:offset pair.
Bits [31:8] in the vector number are silently ignored.
Zero. This function always works.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_segment_base_address(int _selector, unsigned long *_addr);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0006
The physical base address of the selector is stored in *addr.
-1 on error, else zero.
not ANSI, not POSIX
unsigned long addr; if (__dpmi_get_segment_base_address(selector, &addr)) ...
#include <dpmi.h> unsigned __dpmi_get_segment_limit(int _selector);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
The limit of the segment, as returned by the lsl
opcode.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_selector_increment_value(void);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0003
The value to add to each selector allocated by __dpmi_allocate_ldt_descriptors to get the next one.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_state_of_debug_watchpoint(unsigned long _handle, int *_status);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0b02
Gets the state of the watchpoint. Pass handle, fills in status (0=not encountered, 1=encountered).
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_state_save_restore_addr(__dpmi_raddr *_rm, __dpmi_paddr *_pm);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0305
Read the spec for info.
The number of bytes required to save state.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_vendor_specific_api_entry_point(char *_id, __dpmi_paddr *_api);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0a00
Look up a vendor-specific function, given the name of the function.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_version(__dpmi_version_ret *_ret);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0400
Fills in version information. The flags are as follows:
---- ---X = 0=16-bit host 1=32-bit host ---- --X- = 0=V86 used for reflected ints, 1=real mode ---- -X-- = 0=no virtual memory, 1=virtual memory supported
The cpu is 2=80286, 3=80386, 4=80486, etc.
DPMI 0.9 returns major=0 and minor=0x5a.
Zero. This always works.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_get_virtual_interrupt_state(void);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0902
This function returns the current interrupt flag (1=enabled).
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_install_resident_service_provider_callback(__dpmi_callback_info *info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0c00 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function installs a resident service provider callback and declares
an intent to provide resident protected-mode services after terminating
with a call to __dpmi_terminate_and_stay_resident
(see __dpmi_terminate_and_stay_resident).
The various members of info should be filled as follows:
data16
code16
ip
data32
code32
eip
See __dpmi_get_descriptor, for the details about the layout of the 8-byte segment descriptor.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_int(int _vector, __dpmi_regs *_regs);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0300
This function performs a software interrupt in real mode after filling in most the registers from the given structure. %ss, %esp, and %eflags are automatically taken care of, unlike __dpmi_simulate_real_mode_interrupt.
The following variables can be used to tune this function. By default, these variables are all zero.
__dpmi_int_ss
__dpmi_int_sp
__dpmi_int_flags
__dpmi_regs
structure.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_lock_linear_region(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0600
This function locks virtual memory, to prevent page faults during hardware interrupts. Pass address and size (in bytes).
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_map_conventional_memory_in_memory_block(__dpmi_meminfo *info, unsigned long physaddr);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0509 (DPMI 1.0 only). Supported by CWSDPMI, but not by Windows.
This function maps conventional memory (even when virtualized) to virtual memory. Pass the handle, offset, and number of pages.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_map_device_in_memory_block(__dpmi_meminfo *info, unsigned long *physaddr);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0508 (DPMI 1.0 only). Supported by CWSDPMI, but not by Windows.
This function maps a physical address range to virtual memory. Pass the handle, offset relative to the start of the block, and number of pages to map.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_mark_page_as_demand_paging_candidate(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0702
Advises the server that certain pages are unlikely to be used soon. Set address and size (in bytes).
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_mark_real_mode_region_as_pageable(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0602
This function advises the host that the given pages are suitable for page-out. Pass address and size (in bytes).
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_physical_address_mapping(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0800
Maps a physical device (like a graphics buffer) to linear memory. Fill in the physical address and size (in bytes). On return, the address is the linear address to use.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_relock_real_mode_region(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0603
This function relocks the pages unlocked with __dpmi_mark_real_mode_region_as_pageable. Pass address and size (in bytes).
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_reset_debug_watchpoint(unsigned long _handle);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0b03
Resets a watchpoint given its handle in _handle.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_resize_dos_memory(int _selector, int _newpara, int *_ret_max);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0102
This function resizes a dos memory block. Remember to pass the selector, and not the segment. If this call fails, _ret_max contains the largest number of paragraphs available.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_resize_linear_memory(__dpmi_meminfo *info, int commit);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0505 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function resizes a memory block. Pass the handle and new size. Bit 0 of commit is 1 for committed pages; bit 1 is 1 to automatically update descriptors. It returns a new handle and base address.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_resize_memory(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0503
This function changes the size of a virtual memory block. You must pass the handle and size fields. It may change the base address also; beware of debugging breakpoints and locked memory. It will return a new handle.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_segment_to_descriptor(int _segment);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0002
This function returns a selector that maps to what the real-mode segment provided would have referenced. Warning: this is a scarce resource.
-1 on error, else the selector.
not ANSI, not POSIX
short video = __dpmi_segment_to_descriptor(0xa000); movedata(_my_ds(), buffer, video, 0, 320*200);
#include <dpmi.h> int __dpmi_serialize_on_shared_memory(unsigned long handle, int flags);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0d02 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function serializes access to a shared memory block whose handle is given in handle. The bit-mapped variable flags defines the following bits:
An exclusive serialization blocks any serialization attempts for the same memory block from other virtual machines. A shared serialization blocks only exclusive serialization attempts from other virtual machines.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_coprocessor_emulation(int flags);
Please refer to DPMI Specification, for details on DPMI function call operation. Also see DPMI Overview, for general information.
DPMI function AX = 0x0e01 (DPMI v1.0 only, but supported by most DPMI v0.9 servers, including CWSDPMI, Windows, and QDPMI).
This function sets the co-processor emulation state as specified by flags. The only two used bits in flags are:
bit 0
bit 1
DJGPP programs using one of the provided emulators should generally call this functions with an argument of 2. (The DJGPP startup code does that automatically if no co-processor is detected.)
-1 on errors, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_debug_watchpoint(__dpmi_meminfo *_info, int _type);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0b00
Set a debug breakpoint. Type is 0 for execute, 1 for write, and 2 for access. Fill in address and size (1,2,4 bytes). Server fills in handle.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_descriptor(int _selector, void *_buffer);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x000c
This function sets the parameters of the selector _selector by copying the contents of the 8-byte buffer pointed to by _buffer into the LDT entry of the selector's descriptor. See __dpmi_get_descriptor, for the description of the contents of the 8-byte buffer.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_descriptor_access_rights(int _selector, int _rights);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0009
This sets the access rights of _selector to _rights.
The meaning of the individual bit fields of _rights is described below. For more details, please refer to __dpmi_get_descriptor.
---- ---- ---- ---X = 0=not accessed, 1=accessed ---- ---- ---- --X- = data: 0=read, 1=r/w; code: 1=readable ---- ---- ---- -X-- = data: 0=expand-up, 1=expand-down; code: 0=non-conforming ---- ---- ---- X--- = 0=data, 1=code ---- ---- ---1 ---- = must be 1 ---- ---- -XX- ---- = priviledge level (must equal CPL) ---- ---- X--- ---- = 0=absent, 1=present ---X ---- ---- ---- = available for the user --0- ---- ---- ---- = must be 0 -X-- ---- ---- ---- = 0=16-bit 1=32-bit X--- ---- ---- ---- = 0=byte granular (small) 1=page-granular (big)
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_extended_exception_handler_vector_pm(int vector, __dpmi_paddr *address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0212 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function installs a handler for protected-mode exceptions.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_extended_exception_handler_vector_rm(int vector, __dpmi_paddr *address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0213 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function installs a handler for real-mode exceptions.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_multiple_descriptors(int count, void *buffer);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x000f (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function sets multiple descriptors. Buffer usage is like in
__dpmi_get_multiple_descriptors
(see __dpmi_get_multiple_descriptors), but the caller fills in
everything before calling.
Returns count if successful, the negative of the number of descriptors set if failure.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_page_attributes(__dpmi_meminfo *info, short *buffer);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0507 (DPMI 1.0 only). Supported by CWSDPMI, but not by Windows.
This function sets attributes of a number of pages. Pass handle in
info->handle
, offset within block in
info->address
, and number of pages in
info->count
. buffer points to an array of 16-bit
words which specify the new attributes.
See __dpmi_get_page_attributes, for the definition of the page
attribute word.
The DJGPP startup code calls this function to uncommit the so-called
null page, the first 4KB of the program's address space. This
causes NULL
pointer dereferences, a frequent programmatic error,
to trigger a Page Fault exception, rather than go unnoticed.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_processor_exception_handler_vector(int _vector, __dpmi_paddr *_address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0203
This function installs a handler for protected mode exceptions (not interrupts). You must pass a selector:offset pair.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_protected_mode_interrupt_vector(int _vector, __dpmi_paddr *_address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0205
This function installs a protected-mode interrupt (not exception)
handler. You must pass a selector:offset pair. Hardware interrupts
will always be reflected to protected mode if you install a handler.
You must explicitely sti
before iret
because iret
won't always restore interrupts in a virtual environment.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_real_mode_interrupt_vector(int _vector, __dpmi_raddr *_address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0201
This function sets a real-mode interrupt vector. You must pass a segment:offset pair, not a selector.
Bits [31:8] in the vector number are silently ignored.
Zero. This function always works.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_segment_base_address(int _selector, unsigned _address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0007
This function sets the base address of the _selector to _address.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_set_segment_limit(int _selector, unsigned _address);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0008
This function sets the highest valid address in the segment referenced by _selector. For example, if you pass 0xfffff, the highest valid address is 0xfffff. Note: if you pass a number <= 64K, the segment changes to "non-big", and may cause unexpected problems. Limits for segments larger than 1MB must have their low 12 bits set.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_simulate_real_mode_interrupt(int _vector, __dpmi_regs *_regs);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0300
This function performs a software interrupt in real mode after filling in all the registers from the given structure. You must set %ss, %esp, and %eflags to valid real-mode values or zero, unlike __dpmi_int.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_simulate_real_mode_procedure_iret(__dpmi_regs *_regs);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0302
This function switches to real mode, filling in all the
registers from the structure. ss:sp and flags must be valid or zero.
The called function must return with an iret
.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_simulate_real_mode_procedure_retf(__dpmi_regs *_regs);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0301
This function switches to real mode with all the registers set
from the structure, including cs:ip. The function called should
return with a retf
. ss:sp and flags must be set to valid
values or zero.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_simulate_real_mode_procedure_retf_stack(__dpmi_regs *_regs, int stack_words_to_copy, const void *stack_data);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0301
This function switches to real mode with all the registers set
from the structure, including cs:ip. The function called should
return with a retf
. ss:sp and flags must be set to valid
values or zero.
You may optionally specify data to be copied to the real-mode stack,
to pass arguments to real-mode procedures with stack-based calling
conventions. If you don't want to copy data to the real mode stack,
pass 0 for stack_words_to_copy, and NULL
for
stack_bytes.
Note that the amount of stack data to be copied should be given in units of 16-bit words, not in bytes. This is defined by the underlying DPMI function.
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_terminate_and_stay_resident(int return_code, int paragraphs_to_keep);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0c01 (DPMI 1.0 only). Not supported by CWSDPMI and Windows.
This function terminates the calling program, but leaves it resident in memory. return_code specifies which value to return to the OS. paragraphs_to_keep specifies the number of paragraphs of DOS (conventional) memory to keep; it should be either zero or 6 or more. Note that any protected-mode memory remains allocated to the program unless explicitly freed before calling this function.
The calling program must call the function
__dpmi_install_resident_service_provider_callback
before this
one, otherwise it will be terminated instead of going TSR.
See __dpmi_install_resident_service_provider_callback.
This call does not return.
not ANSI, not POSIX
#include <dpmi.h> int __dpmi_unlock_linear_region(__dpmi_meminfo *_info);
Please refer to DPMI Specification for details on DPMI function call operation. Also see DPMI Overview for general information.
DPMI function AX = 0x0601
This function unlocks virtual memory. Pass address and size (in bytes).
-1 on error, else zero.
not ANSI, not POSIX
#include <dpmi.h> void __dpmi_yield(void);
__dpmi_yield
calls function 1680h of the interrupt 2Fh, which
tells the task manager in a multitasking environment that the calling
program doesn't need the rest of its time slice. The task manager will
then preempt the calling program and switch to another task that is
ready to run.
This function should be called in busy-wait loops, like when a program waits for user input via keyboard, after it finds the keyboard buffer empty, to enhance overall performance in a multitasking environment.
None. If the call isn't supported by the environment, like when running
on plain DOS, errno
is set to ENOSYS
.
not ANSI, not POSIX
#include <unistd.h> int dup(int old_handle);
This function duplicates the given file handle. Both handles refer to the same file and file pointer.
The new file handle, or -1 if error.
not ANSI, POSIX
do_file(dup(fileno(stdin)));
#include <unistd.h> int dup2(int existing_handle, int new_handle);
This call causes new_handle to refer to the same file and file pointer as existing_handle. If new_handle is an open file, it is closed.
The new handle, or -1 on error.
not ANSI, POSIX
/* copy new file to stdin stream */ close(0); dup2(new_stdin, 0); close(new_stdin);
#include <sys/dxe.h> void *_dxe_load(char *dxe_filename);
This function loads a dynamic executable image, whose file name is pointed to by dxe_filename, into memory and returns the entry point for the symbol associated with the image. The symbol may point to a structure or a function.
0 on failure, the address of the loaded symbol on success.
not ANSI, not POSIX
static int (*add)(int a, int b); add = _dxe_load("add.dxe"); if (add == 0) printf("Cannot load add.dxe\n"); else printf("Okay, 3 + 4 = %d\n", add(3,4));
#include <stdlib.h> char * ecvt (double value, int ndigits, int *decpt, int *sign)
This function converts the value into a null-terminated string, and returns a pointer to that string.
ecvt
works exactly like ecvtbuf
(see ecvtbuf), except
that it generates the string in an internal static buffer which is
overwritten on each call.
A pointer to the generated string.
not ANSI, not POSIX
#include <stdlib.h> char * ecvtbuf (double value, int ndigits, int *decpt, int *sign, char *buf)
This function converts its argument value into a null-terminated
string of ndigits digits in buf. buf should have
enough space to hold at least ndigits + 1
characters.
The produced string in buf does not include the decimal point. Instead, the position of the decimal point relative to the beginning of buf is stored in an integer variable whose address is passed in decpt. Thus, if buf is returned as "1234" and *decpt as 1, this corresponds to a value of 1.234; if *decpt is -1, this corresponds to a value of 0.01234, etc.
The sign is also not included in buf's value. If value is
negative, ecvtbuf
puts a nonzero value into the variable whose
address is passed in sign; otherwise it stores zero in
*sign.
The least-significant digit in buf is rounded.
ecvtbuf
produces the string "NaN" if value is a NaN, and
"Inf" or "Infinity" if value is an infinity (the longer form
is produced when ndigits is 8 or more).
A pointer to buf.
not ANSI, not POSIX
#include <stdlib.h> #include <stdio.h> #include <math.h> char vbuf[20]; int esign, edecpt; ecvtbuf (M_PI, 5, &edecpt, &esign, buf) /* This will print " 31416". */ printf ("%c%s", esign ? '-' : ' ', buf);
#include <debug/dbgcom.h> void edi_init (jmp_buf start_state);
This function is part of the DJGPP debugging support. It should be
called after a call to v2loadimage
(see v2loadimage) which
loads an executable program as a debuggee. edi_init
then takes
care of initializing the data structures which need to be set before the
debugger can set breakpoints and run the debuggee.
The argument start_state is usually set by a preceding call to
v2loadimage
.
not ANSI, not POSIX
if (v2loadimage (exec_file, cmdline, start_state)) { printf ("Load failed for image %s\n", exec_file); exit (1); } edi_init (start_state);
#include <dos.h> int enable(void);
This function enables interrupts.
See disable.
Returns nonzero if the interrupts were already enabled, zero if they had been disabled before this call.
not ANSI, not POSIX
int ints_were_enabled; ints_were_enabled = enable(); . . . do some stuff . . . if (!ints_were_enabled) disable();
#include <grp.h> void endgrent(void);
This function should be called after all calls to getgrent
,
getgrgid
, or getgrnam
.
None.
not ANSI, not POSIX
See getgrent.
#include <mntent.h> int endmntent(FILE *filep);
This function should be called after the last call to getmntent
(see getmntent).
This function always returns one.
not ANSI, not POSIX
#include <pwd.h> void endpwent(void);
This function should be called after the last call to getpwent (see getpwent).
None.
not ANSI, not POSIX
#include <errno.h> extern int errno;
This variable is used to hold the value of the error of the last function call. The value might be one of the following:
0
errno
to zero, but the
startup code does that just before calling main
(this is ANSI C
requirement).
1
2
3
system
and the functions from
the spawn
family assign this to errno
when the command
line is too long (longer than 126-character limit when invoking
non-DJGPP programs, or longer than the transfer buffer size when
invoking DJGPP programs).
4
5
6
7
8
wait
and
waitpid
, and by NetWare-related calls.
9
10
open
and mkdir
when a
file or directory by that name already exists.
11
NULL
pointer).
12
13
system
and the functions of
the spawn
family use that when the child program was interrupted
by Ctrl-<C>. Also, when DOS returns the "fail on INT 24h"
error code.
14
rename
, syntax errors in
the command line passed to system
, etc.
15
16
EACCES
in these cases, but DJGPP sometimes assigns EISDIR
to errno
, like when rename
is called to move a regular
file over a directory, or when system
or one of the spawn*
functions are passed a name of a directory instead of an executable
program.
17
FILES=
directive in CONFIG.SYS
is too small.
18
19
FILENAME_MAX
,
defined in stdio.h
).
20
21
22
23
_dxe_load
(when
the argument names a file that isn't a valid DXE), and by
NetWare-related calls which run programs remotely.
24
25
malloc
does NOT set errno
to ENOMEM
; however,
several library functions that use malloc
will do that when it
returns a NULL
pointer.
26
write
and _write
do this for it, when they
detect a full disk condition.
27
28
rename
and _truename
, do that if
they expect a valid directory pathname, but get either an invalid
(e.g. empty) pathname or a file that is not a directory.
29
rename
does, when it is called to move a directory over an
existing non-empty directory.
30
errno
to this when called on a device that is not a
TTY.
31
32
33
34
35
36
37
38
findfirst
and findnext
assign
this to errno
when they exhaust the files in the directory.
readdir
does that as well.
See perror.
ANSI, POSIX
#include <unistd.h> int execl(const char *path, const char *argv0, ...); int execle(const char *path, const char *argv0, ... /*, char *const envp[] */); int execlp(const char *path, const char *argv0, ...); int execlpe(const char *path, const char *argv0, ... /*, char *const envp[] */); int execv(const char *path, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]); int execvp(const char *path, char *const argv[]); int execvpe(const char *path, char *const argv[], char *const envp[]);
These functions operate by calling spawn*
with a type of
P_OVERLAY
. Refer to spawn* for a full description.
If successful, these functions do not return. If there is an error,
these functions return -1 and set errno
to indicate the error.
not ANSI, POSIX
execlp("gcc", "gcc", "-v", "hello.c", 0);
#include <unistd.h> void __exit(int exit_code);
This is an internal library function which exits the program, returning
exit_code to the calling process. No additional processing is
done, and any atexit
functions are not called. Since hardware
interrupts are not unhooked, this can cause crashes after the program
exits. This function is normally called only by _exit
; do
not call it directly.
This function does not return.
not ANSI, POSIX
#include <unistd.h> void _exit(int exit_code);
This function exits the program, returning exit_code to the
calling process. No additional processing (such as closing file
descriptors or calls to the static destructor functions) is done, and
any atexit
functions are not called; only the hardware interrupt
handlers are unhooked, to prevent system crashes e.g. after a call to
abort
. This function is normally called only by exit
and
abort
.
This function does not return.
not ANSI, not POSIX
#include <stdlib.h> void exit(int exit_code);
This function exits the program, returning exit_code to the
calling process. Before exiting, all open files are closed and all
atexit
and on_exit
requests are processed.
This function does not return.
ANSI, POSIX
if (argc < 4) { print_usage(); exit(1); }
#include <math.h> double exp(double x);
This function computes the exponential of x, e^x, where e is the base of the natural system of logarithms, approximately 2.718281828.
e to the x power. If the value of x is finite, but so
large in magnitude that its exponential cannot be accurately represented
by a double
, the return value is the nearest representable
double
(possibly, an Inf
), and errno
is set to
ERANGE
. If x is either a positive or a negative infinity,
the result is either +Inf
or zero, respectively, and errno
is not changed. If x is a NaN
, the return value is
NaN
and errno
is set to EDOM
.
ANSI, POSIX
#include <math.h> double exp10(double x);
This function computes 10 to the power of x, 10^x.
10 to the x power. If the value of x is finite, but so
large in magnitude that 10^x cannot be accurately represented by
a double
, the return value is the nearest representable
double
(possibly, an Inf
), and errno
is set to
ERANGE
. If x is either a positive or a negative infinity,
the result is either +Inf
or zero, respectively, and errno
is not changed. If x is a NaN
, the return value is
NaN
and errno
is set to EDOM
.
not ANSI, not POSIX
#include <math.h> double exp2(double x);
This function computes 2 to the power of x, 2^x.
2 to the x power. If the value of x is finite, but so large
in magnitude that 2^x cannot be accurately represented by a
double
, the return value is is the nearest representable
double
(possibly, an Inf
), and errno
is set to
ERANGE
. If x is either a positive or a negative infinity,
the result is either +Inf
or zero, respectively, and errno
is not changed. If x is a NaN
, the return value is
NaN
and errno
is set to EDOM
.
not ANSI, not POSIX
#include <math.h> double expm1(double x);
This function computes the value of e^x - 1, the exponential of
x minus 1, where e is the base of the natural system of
logarithms, approximately 2.718281828. The result is more accurate than
exp(x) - 1
for small values of x, where the latter method
would lose many significant digits.
e raised to the power x, minus 1. If the value of x is
finite, but so large that its exponent would overflow a double
,
the return value is Inf
, and errno
is set to
ERANGE
. If x is either a positive or a negative infinity,
the result is either +Inf
or -1, respectively, and errno
is not changed. If x is a NaN
, the return value is
NaN
and errno
is set to EDOM
.
not ANSI, not POSIX
#include <math.h> double fabs(double x);
This function computes the absolute value of its argument x.
x if x is positive, else -x. Note that in this
context, +0.0 is positive and -0.0 is negative. Infinities and
NaN
s are returned unchanged, except for the sign.
ANSI, POSIX
#include <sys/farptr.h> unsigned char _farpeekb(unsigned short selector, unsigned long offset); unsigned short _farpeekw(unsigned short selector, unsigned long offset); unsigned long _farpeekl(unsigned short selector, unsigned long offset); void _farpokeb(unsigned short sel, unsigned long off, unsigned char val); void _farpokew(unsigned short sel, unsigned long off, unsigned short val); void _farpokel(unsigned short sel, unsigned long off, unsigned long val); void _farsetsel(unsigned short selector); unsigned short _fargetsel(void); void _farnspokeb(unsigned long offset, unsigned char value); void _farnspokew(unsigned long offset, unsigned short value); void _farnspokel(unsigned long offset, unsigned long value); unsigned char _farnspeekb(unsigned long offset); unsigned short _farnspeekw(unsigned long offset); unsigned long _farnspeekl(unsigned long offset);
These functions provide the equivalent functionality of "far pointers" to peek or poke an absolute memory addresses, even though gcc doesn't understand the keyword "far". They come in handy when you need to access memory-mapped devices (like VGA) or some address in lower memory returned by a real-mode service. These functions are provided as inline assembler functions, so when you optimize your program they reduce to only a few opcodes (only one more than a regular memory access), resulting in very optimal code.
The first two groups of functions take a selector and an offset. This selector is not a dos segment. If you want to access dos memory, pass _go32_info_block.selector_for_linear_memory (or just _dos_ds) as the selector, and seg*16+ofs as the offset. For functions which poke the memory, you should also provide the value to put there.
The last two groups assume that you've used _farsetsel
to
specify the selector. You should avoid making any function calls
between _farsetsel
and using these other functions, unless
you're absolutely sure that they won't modify that selector. This
allows you to optimize loops by setting the selector once outside the
loop, and using the shorter functions within the loop.
You can use _fargetsel
if you want to temporary change the
selector with _farsetsel
and restore it afterwards.
Functions which peek the address return the value at given address.
_fargetsel
returns the current selector.
not ANSI, not POSIX
#include <stdio.h> int fclose(FILE *file);
This function closes the given file.
Zero on success, else EOF
.
ANSI, POSIX
FILE *f = fopen("data", "r"); fprintf(f, "Hello\n"); fclose(f);
#include <fcntl.h> int fcntl (int fd, int cmd, ...);
This function performs the operation specified by cmd on
the file open on handle fd. The following operations are defined
by the header fcntl.h
:
F_DUPFD
dup
does
(see dup), except that fcntl
also makes sure the returned
handle is the lowest available handle greater than or equal to the
integer value of the third argument.
F_GETFD
FD_CLOEXEC
close-on-exec (a.k.a. no-inherit) status of
fd. If the returned value has its least-significant bit set, the
file will not be inherited by programs invoked by this process;
otherwise, the file will remain open in the child processes.
Note that only the first 20 handles can be passed to child processes by
DOS/Windows; handles beyond that cannot be inherited. In addition, the
stub loader of the child DJGPP program will forcibly close handles 19
and 18 (since otherwise it will be unable to read the COFF executable
information and enter protected mode). Therefore, the current
implementation always returns 0 for handles below 18, meaning that all
those handles are inherited, and FD_CLOEXEC
for handles 18 and
above.
The no-inherit bit can be set when the file is open, by using the
O_NOINHERIT
in the open flags; see open.
F_SETFD
fcntl
always fails this call and sets errno
to ENOSYS
, since
DOS/Windows don't support changing the no-inherit status of an open
file.
F_GETFL
open
and creat
functions,
like O_READONLY
, O_APPEND
, etc. Currently, this command
always returns zero, with no flags set.
F_SETFL
errno
to ENOSYS
, since DOS and
Windows don't allow to change the descriptor flags after the file is
open.
F_GETLK
F_SETLK
F_SETLKW
F_SETLK
, but if the lock is blocked, the call will wait
until it is unblocked and the lock can be applied. This is unsupported
and will always fail.
This function can be hooked by the Filesystem extensions, see
File System Extensions. If you don't want this, and you are
calling fcntl
with the F_DUPFD
command, you should use
dup2
instead, see dup2.
If an invalid or unsupported value is passed in cmd, or fd
is an invalid file handle, the function returns -1 and sets errno
to the appropriate value. Unsupported values of cmd cause
ENOSYS
to be stored in errno
. If cmd is
F_DUPFD
, the function returns the new descriptor or -1 in case of
a failure.
not ANSI, POSIX (see note 1)
Notes:
F_DUPFD
shares the FD_CLOEXEC
flag with fd (unless they are on different sides of the 20-handle mark), since DOS/Windows only maintain a single set of bits for all the handles associated with the same call to open
.
/* Save the handle in a way that it won't be passed to child processes. */ int saved_fd = fcntl (fd, F_DUPFD, 20);
#include <stdlib.h> char * fcvt (double value, int ndigits, int *decpt, int *sign)
This function converts the value into a null-terminated string, and returns a pointer to that string.
fcvt
works exactly like fcvtbuf
(see fcvtbuf), except
that it generates the string in an internal static buffer which is
overwritten on each call.
A pointer to the generated string.
not ANSI, not POSIX
#include <stdlib.h> char * fcvtbuf (double value, int ndigits, int *decpt, int *sign, char *buf)
This function converts its argument value into a null-terminated
string in buf with ndigits digits to the right of the
decimal point. ndigits can be negative to indicate rounding to
the left of the decimal point. buf should have enough space to
hold at least 310+max(0,ndigits)
characters.
Note that, unlike ecvtbuf
(see ecvtbuf), fcvtbuf
only
counts the digits to the right of the decimal point. Thus, if
value is 123.45678 and ndigits is 4, then ecvtbuf
will produce "1235", but fcvtbuf
will produce "1234568" (and
*decpt will be 3 in both cases).
The produced string in buf does not include the decimal point. Instead, the position of the decimal point relative to the beginning of buf is stored in an integer variable whose address is passed in decpt. Thus, if buf is returned as "1234" and *decpt as 1, this corresponds to a value of 1.234; if *decpt is -1, this corresponds to a value of 0.01234, etc.
The sign is also not included in buf's value. If value is
negative, ecvtbuf
puts a nonzero value into the variable whose
address is passed in sign; otherwise it stores zero in
*sign.
The least-significant digit in buf is rounded.
ecvtbuf
produces the string "NaN" if value is a NaN, and
"Inf" or "Infinity" if value is an infinity (the longer form
is produced when ndigits is 8 or more).
A pointer to buf.
not ANSI, not POSIX
#include <stdlib.h> #include <stdio.h> #include <math.h> char vbuf[20]; int fsign, fdecpt; fcvtbuf (M_PI, 5, &fdecpt, &fsign, buf) /* This will print " 314159". */ printf ("%c%s", fsign ? '-' : ' ', buf);
#include <stdio.h> FILE *fdopen(int fd, const char *mode);
This function opens a stream-type file that uses the given fd
file, which must already be open. The file is opened with the modes
specified by mode, which is the same as for fopen
.
See fopen.
The newly created FILE *
, or NULL
on error.
not ANSI, POSIX
FILE *stdprn = fdopen(4, "w");
#include <stdio.h> int feof(FILE *file);
This function can be used to indicate if the given file is at the end-of-file or not.
Nonzero at end-of-file, zero otherwise.
ANSI, POSIX
while (!feof(stdin)) gets(line);
#include <stdio.h> int ferror(FILE *file);
This function can be used to indicate if the given file has encountered an error or not. See clearerr.
Nonzero for an error, zero otherwize.
ANSI, POSIX
if (ferror(stdin)) exit(1);
#include <stdio.h> int fflush(FILE *file);
If file is not a NULL
pointer, this function causes any
unwritten buffered data to be written out to the given file. This
is useful in cases where the output is line buffered and you want to
write a partial line.
If file is a NULL
pointer, fflush
writes any
buffered output to all files opened for output.
Note that fflush
has no effect for streams opened for reading
only. Also note that the operating system can further buffer/cache
writes to disk files; a call to fsync
(see fsync) or
sync
(see sync) is typically required to actually deliver
data to the file(s).
Zero on success, -1 on error. When called with a NULL
pointer,
-1 will be returned if an error happened while flushing some of the
streams (but fflush
will still try to flush all the rest before
it returns).
ANSI, POSIX
printf("Enter value : "); fflush(stdout); scanf(result);
#include <string.h> int ffs(int _mask);
This function find the first (least significant) bit set in the input value.
Bit position (1..32) of the least significant set bit, or zero if the input value is zero.
not ANSI, not POSIX
ffs(0) = 0 ffs(1) = 1 ffs(5) = 1 ffs(96) = 6
#include <stdio.h> int fgetc(FILE *file);
Returns the next character in the given file as an unsigned char.
The given char (value 0..255) or EOF
at end-of-file.
ANSI, POSIX
int c; while((c=fgetc(stdin)) != EOF) fputc(c, stdout);
#include <grp.h> struct group *fgetgrent(FILE *file);
This function, in MS-DOS, is exactly the same as getgrent
(see getgrent).
not ANSI, not POSIX
#include <stdio.h> int fgetpos(FILE *file, fpos_t *offset);
This function records the current file pointer for file, for
later use by fsetpos
.
Zero if successful, nonzero if not.
ANSI, POSIX
#include <stdio.h> char *fgets(char *buffer, int maxlength, FILE *file);
This function reads as much of a line from a file as possible, stopping
when the buffer is full (maxlength-1 characters), an end-of-line
is detected, or EOF
or an error is detected. It then stores a
NULL
to terminate the string.
The address of the buffer is returned on success, if EOF
is
encountered before any characters are stored, or if an error is
detected, NULL
is returned instead.
ANSI, POSIX
char buf[100]; while (fgets(buf, 100, stdin)) fputs(buf, stdout);
The File System Extensions are a part of the lowest level of I/O operations in the C runtime library of DJGPP. These extensions are provided to allow for cases where Unix uses a file descriptor to access such items as serial ports, memory, and the network, but DOS does not. It allows a set of functions (called an extension) to gain control when one of these low-level functions is called on a file descriptor set up by the extension.
Each extension must provide one or two handler functions. All handler functions take the same arguments:
int function(__FSEXT_Fnumber func_number, int *rv, va_list args);
The func_number identifies which function is to be emulated.
The file <sys/fsext.h>
defines the function numbers as follows:
__FSEXT_nop
__FSEXT_open
__FSEXT_creat
__FSEXT_read
__FSEXT_write
__FSEXT_ready
select
library function
(see select) when it needs to know whether a handle used to
reference the "file" is ready for reading or writing, or has an error
condition set. The handler should return an OR'ed bit mask of the
following bits (defined on <sys/fsext.h>
):
__FSEXT_ready_read
__FSEXT_ready_write
__FSEXT_ready_error
__FSEXT_close
__FSEXT_fcntl
__FSEXT_ioctl
__FSEXT_lseek
__FSEXT_link
__FSEXT_unlink
__FSEXT_dup
__FSEXT_dup2
__FSEXT_fstat
rv points to a temporary return value pointer. If the function is emulated by the handler, the return value should be stored here, and the handler should return a nonzero value. If the handler returns zero, it is assumed to have not emulated the call, and the regular DOS I/O function will happen. The args represent the arguments passed to the original function; these point to the actual arguments on the stack, so the emulation may choose to modify them and return zero to the regular function, which will then act on the modified arguments.
A normal extension would provide these parts:
socket
for networking) or an extension
to open (such as /dev/ttyS0
to access the serial port).
read
and
write
. This is a single function in the extension that uses
the function number parameter to select an extension function.
Please note that the special Unix filenames /dev/null
and
/dev/tty
are already mapped to the appropriate DOS names
NUL
and CON
, respectively, so you don't need to write
extensions for these.
#include <unistd.h> int __file_exists(const char *_fn);
This function provides a fast way to ask if a given file exists. Unlike access(), this function does not cause other objects to get linked in with your program, so is used primarily by the startup code to keep minimum code size small.
Zero if the file does not exist, nonzero if it does. Note that this is the opposite of what access() returns.
not ANSI, not POSIX
if (__file_exists(fname)) process_file(fname);
#include <dir.h> int __file_tree_walk(const char *dir, int (*func)(const char *path, const struct ffblk *ff));
This function recursively descends the directory hierarchy which starts
with dir. For each file in the hierarchy, __file_tree_walk
calls the user-defined function func which is passed a pointer to a
NULL
-terminated character array in path holding the full
pathname of the file, a pointer to a ffblk
structure
(see findfirst) ff with a DOS filesystem information about that
file.
This function always visits a directory before any of its siblings. The
argument dir must be a directory, or __file_tree_walk
will fail
and set errno to ENOTDIR
. The directory dir itself is
never passed to func.
The tree traversal continues until one of the following events:
(1) The tree is exhausted (i.e., all descendants of dir are
processed). In this case, __file_tree_walk
returns 0, meaning a
success.
(2) An invocation of func returns a non-zero value. In this case,
__file_tree_walk
stops the tree traversal and returns whatever
func returned.
(3) An error is detected within __file_tree_walk
. In that case,
ftw
returns -1 and sets errno (see errno) to a suitable
value.
Zero in case the entire tree was successfully traversed, -1 if
__file_tree_walk
detected some error during its operation, or any
other non-zero value which was returned by the user-defined function
func.
not ANSI, not POSIX
#include <stdlib.h> int ff_walker(const char *path, const struct ffblk *ff) { printf("%s:\t%lu\t", path, ff->ff_fsize); if (ff->ff_attrib & 1) printf("R"); if (ff->ff_attrib & 2) printf("H"); if (ff->ff_attrib & 4) printf("S"); if (ff->ff_attrib & 8) printf("V"); if (ff->ff_attrib & 0x10) printf("D"); if (ff->ff_attrib & 0x20) printf("A"); printf("\n"); if (strcmp(ff->ff_name, "XXXXX") == 0) return 42; return 0; } int main(int argc, char *argv[]) { if (argc > 1) { char msg[80]; sprintf(msg, "__file_tree_walk: %d", __file_tree_walk(argv[1], ff_walker)); if (errno) perror(msg); else puts(msg); } else printf("Usage: %s dir\n", argv[0]); return 0; }
#include <io.h> long filelength(int fhandle);
This function returns the size, in bytes, of a file whose handle is specified in the argument fhandle. To get the handle of a file opened by fopen or freopen, you can use fileno macro.
The size of the file in bytes, or (if any error occured) -1L and errno set to a value describing the cause of the failure.
not ANSI, not POSIX
printf("Size of file to which STDIN is redirected is %ld\n", filelength(0));
#include <stdio.h> int fileno(FILE *file);
This function returns the raw file descriptor number that file uses for I/O.
The file descriptor number.
not ANSI, POSIX
#include <dir.h> int findfirst(const char *pathname, struct ffblk *ffblk, int attrib);
This function and the related findnext
(see findnext) are used
to scan directories for the list of files therein. The pathname
is a wildcard that specifies the directory and files to search for (such
as subdir/*.c
), ffblk is a structure to hold the results and
state of the search, and attrib is a combination of the following:
FA_RDONLY
FA_HIDDEN
FA_SYSTEM
FA_LABEL
FA_DIREC
FA_ARCH
If a file has flag bits that are not specified in the attrib
parameter, the file will be excluded from the results. Thus, if you
specified FA_DIREC
and FA_LABEL
, subdirectories and the
volume label will be included in the results. Hidden and system files
will be excluded.
Since findfirst
calls DOS function 4eh, it is not possible to
exclude read-only files or archive files from the results. Even if
the FA_ARCH and FA_RDONLY bits are not specified in the attrib
parameter, the results will include any read-only and archive files in
the directory searched.
This function supports long file names.
The results of the search are stored in ffblk, which is extended
when the LFN API (see LFN) is supported. Fields marked
LFN are only valid if the lfn_magic
member is set to "LFN32".
struct ffblk { char lfn_magic[6]; /* LFN: the magic "LFN32" signature */ short lfn_handle; /* LFN: the handle used by findfirst/findnext */ unsigned short lfn_ctime; /* LFN: file creation time */ unsigned short lfn_cdate; /* LFN: file creation date */ unsigned short lfn_atime; /* LFN: file last access time (usually 0) */ unsigned short lfn_adate; /* LFN: file last access date */ char ff_reserved[5]; /* used to hold the state of the search */ unsigned char ff_attrib; /* actual attributes of the file found */ unsigned short ff_ftime; /* hours:5, minutes:6, (seconds/2):5 */ unsigned short ff_fdate; /* (year-1980):7, month:4, day:5 */ unsigned long ff_fsize; /* size of file */ char ff_name[260]; /* name of file as ASCIIZ string */ }
Zero if a match is found, nonzero if none found.
not ANSI, not POSIX
struct ffblk f; int done = findfirst("*.exe", &f, FA_HIDDEN | FA_SYSTEM); while (!done) { printf("%10u %2u:%02u:%02u %2u/%02u/%4u %s\n", f.ff_fsize, (f.ff_ftime >> 11) & 0x1f, (f.ff_ftime >> 5) & 0x3f, (f.ff_ftime & 0x1f) * 2, (f.ff_fdate >> 5) & 0x0f, (f.ff_fdate & 0x1f), ((f.ff_fdate >> 9) & 0x7f) + 1980, f.ff_name); done = findnext(&f); }
#include <dir.h> int findnext(struct ffblk *ffblk);
This finds the next file in the search started by findfirst
.
See findfirst.
Zero if there was a match, else nonzero.
not ANSI, not POSIX
#include <sys/stat.h> void _fixpath(const char *in_path, char *out_path);
This function canonicalizes the input path in_path and stores the result in the buffer pointed to by out_path.
The path is fixed by removing consecutive and trailing slashes, making the path absolute if it's relative by prepending the current drive letter and working directory, removing "." components, collapsing ".." components, adding a drive specifier if needed, and converting all slashes to '/'. DOS-style 8+3 names of directories which are part of the pathname, as well as its final filename part, are returned lower-cased in out_path, but long filenames are left intact. See _preserve_fncase, for more details on letter-case conversions in filenames.
Since the returned path name can be longer than the original one, the
caller should ensure there is enough space in the buffer pointed to by
out_path. Using ANSI-standard constant FILENAME_MAX
(defined on stdio.h
) or Posix-standard constant PATH_MAX
(defined on limits.h
) is recommended.
None.
not ANSI, not POSIX
char oldpath[100], newpath[FILENAME_MAX]; scanf(oldpath); _fixpath(oldpath, newpath); printf("that really is %s\n", newpath);
#include <math.h> double floor(double x);
This function computes the largest integer not greater than x.
The largest integer value less than or equal to x. Infinities and
NaN
s are returned unchanged.
ANSI, POSIX
#include <io.h> void _flush_disk_cache (void);
Attempts to update the disk with the data cached in the write-behind
disk caches (such as SmartDrv
and the built-in Windows 95 disk
cache).
Note that this does not flushes the DOS buffers. You need to
call fsync
(see fsync) or close
(see close) to
force DOS to commit the file data to the disk; sync
(see sync) does that for all open files.
None.
not ANSI, not POSIX
/* Make sure all files are actually written to disk. */ sync (); _flush_disk_cache ();
#include <math.h> double fmod(double x, double y);
This function computes the remainder of x/y
, which is
x - iy for some integer i such that
iy < x < (i+1)y.
The remainder of x/y. If x is Inf
or
NaN
, the return value is NaN
and errno
is set to
EDOM
. If y is zero, the return value is zero (but
errno
is not changed).
ANSI, POSIX
#include <fcntl.h> extern int _fmode;
This variable may be set to O_TEXT
or O_BINARY
to specify
the mode that newly opened files should be opened in if the open call
did not specify. See open. See fopen.
The default value is O_TEXT
.
not ANSI, not POSIX
_fmode = O_BINARY;
#include <fnmatch.h> int fnmatch(const char *pattern, const char *string, int flags);
This function indicates if string matches the pattern. The pattern may include the following special characters:
*
?
[...]
!
, matches if the character is not in the range.
Between the brackets, the range is specified by listing the characters
that are in the range, or two characters separated by -
to
indicate all characters in that range. For example, [a-d]
matches a
, b
, c
, or d
. If you want to
include the literal -
in the range, make it the first character,
like in [-afz]
.
\
\*
matches an asterisk. This feature is not available if
flags includes FNM_NOESCAPE
, in which case \
is
treated as a directory separator.
The value of flags is a combination of zero of more of the following:
FNM_PATHNAME
/
and \
in string never
match any of the wildcards in pattern.
FNM_NOESCAPE
\
may be used in
pattern for quoting special characters. If this flag is
set, \
is treated as a directory separator.
FNM_NOCASE
fnmatch
matches characters
case-insensitively, including in character ranges like [a-f]
.
Note that the case-folding is done by calling toupper
(see toupper), and thus might be sensitive to the current locale.
FNM_PERIOD
In the Posix specification, if this flag is set, leading dots in file
names will not match any wildcards. If FNM_PATHNAME
is set, a
dot after a slash also doesn't match any wildcards.
The DJGPP implementation treats forward slashes and backslashes as equal
when FNM_NOESCAPE
is set, since on DOS/Windows these two
characters are both used as directory separators in file names.
Zero if the string matches, FNM_NOMATCH
if it does not. Posix
defines an additional FNM_ERROR
code that's returned in case of
an error, but the current implementation never returns it.
not ANSI, POSIX (see note 1)
Notes:
\
and /
is DJGPP-specific.
if (fnmatch("*.[ch]", filename, FNM_PATHNAME|FNM_NOCASE)) do_source_file(filename);
#include <dir.h> void fnmerge (char *path, const char *drive, const char *dir, const char *name, const char *ext);
This function constructs a file path from its components
drive, dir, name, and ext. If any of these is a
NULL
pointer, it won't be used. Usually, the drive string
should include the trailing colon `:'
, the dir string should
include the trailing slash `/'
or backslash `\'
, and the
ext string should include the leading dot `.'
. However, if
any of these isn't present, fnmerge
will add them.
See fnsplit.
None.
not ANSI, not POSIX
char buf[MAXPATH]; fnmerge(buf, "d:", "/foo/", "data", ".txt");
#include <dir.h> int fnsplit (const char *path, char *drive, char *dir, char *name, char *ext);
This function decomposes a path into its components. It is smart
enough to know that .
and ..
are directories, and that
file names with a leading dot, like .emacs
, are not all extensions.
The drive, dir, name and ext arguments should
all be passed, but some or even all of them might be NULL
pointers.
Those of them which are non-NULL
should point to buffers which have
enough room for the strings they would hold. The constants MAXDRIVE
,
MAXDIR
, MAXFILE
and MAXEXT
, defined on dir.h, define
the maximum length of these buffers.
See fnmerge.
A flag that indicates which components were found:
DRIVE
DIRECTORY
FILENAME
EXTENSION
WILDCARDS
*
or ?
.
not ANSI, not POSIX
char d[MAXDRIVE], p[MAXDIR], f[MAXFILE], e[MAXEXT]; int which = fnsplit("d:/djgpp/bin/gcc.exe", d, p, f, e); d = "d:" p = "/djgpp/bin/" f = "gcc" e = ".exe"
#include <stdio.h> FILE *fopen(const char *filename, const char *mode);
This function opens a stream corresponding to the named filename with the given mode. The mode can be one of the following:
r
w
a
Followed by any of these characters:
b
When called to open the console in binary mode, fopen
will
disable the generation of SIGINT
when you press Ctrl-C
(Ctrl-Break will still cause SIGINT
), because many programs
that use binary reads from the console will also want to get the
^C
characters. You can use the __djgpp_set_ctrl_c
library
function (see __djgpp_set_ctrl_c) if you want Ctrl-C to
generate interrupts while console is read in binary mode.
t
+
O_RDWR
so that both reads and writes
can be done to the same file.
If the file is open for both reading and writing, you must call
fflush
, fseek
, or rewind
before switching from read
to write or from write to read.
The open file is set to line buffered if the underlying object is a device (stdin, stdout, etc), or is fully buffered if the underlying object is a disk file (data.c, etc).
If b
or t
is not specified in mode, the file type is
chosen by the value of fmode
(see _fmode).
If you need to specify the DOS share flags use the __djgpp_share_flags
.
See __djgpp_share_flags.
A pointer to the FILE
object, or NULL
if there was an
error.
ANSI, POSIX
FILE *f = fopen("foo", "rb+"); /* open existing file for read/write, binary mode */
#include <unistd.h> pid_t fork(void);
This function always returns -1 and sets errno
to ENOMEM, as
MS-DOS does not support multiple processes. It exists only to assist
in porting Unix programs.
not ANSI, POSIX
#include <unistd.h> long fpathconf(int fd, int name);
Returns configuration information on the filesystem that the open file
resides on. See pathconf. If the filesystem cannot be determined
from the file handle fd (e.g., for character devices),
fpathconf
will return the info for the current drive.
The configuration value; for details, see pathconf.
not ANSI, POSIX
#include <float.h> void _fpreset(void);
Resets the FPU completely.
not ANSI, not POSIX
#include <stdio.h> int fprintf(FILE *file, const char *format, ...);
Prints formatted output to the named file. See printf.
The number of characters written.
ANSI, POSIX
#include <stdio.h> int fpurge(FILE *file);
If file designates a buffered stream open for writing or for both
reading and writing, this function purges the stream's buffer without
writing it to disk. Otherwise, it does nothing (so it has no effect on
read-only streams such as stdin
).
Zero on success, -1 on failure.
not ANSI, not POSIX
#include <stdio.h> int fputc(int character, FILE *file);
This function writes the given character to the given file
.
The given character [0..255] or EOF
.
ANSI, POSIX
fputc('\n', stdout);
#include <stdio.h> int fputs(const char *string, FILE *file);
This function all the characters of string (except the trailing
NULL
) to the given file.
A nonnegative number on success, EOF
on error.
ANSI, POSIX
fputs("Hello\n", stdout);
#include <stdio.h> size_t fread(void *buffer, size_t size, size_t number, FILE *file);
This function reads size*number characters from file to buffer.
The number of items of size size read, or less if there was an error.
ANSI, POSIX
int foo[10]; fread(foo, sizeof(int), 10, stdin);
#include <stdlib.h> void free(void *ptr);
Returns the allocated memory to the heap (see malloc). If the
ptr is NULL
, it does nothing.
None.
ANSI, POSIX
char *q = (char *)malloc(20); free(q);
#include <stdio.h> FILE *freopen(const char *filename, const char *mode, FILE *file);
This function closes file if it was open, then opens a new
file like fopen(filename, mode)
but it reuses file.
This is useful to, for example, associate stdout
with a new file.
The new file, or NULL
on error.
ANSI, POSIX
freopen("/tmp/stdout.dat", "wb", stdout);
#include <math.h> double frexp(double x, int *pexp);
This function separates the given value x into a mantissa m in the
range [0.5,1)
and an exponent e, such that m*2^e = x.
It returns the value of the mantissa and stores the integer exponent in
*pexp.
The mantissa. If the value of x is NaN
or Inf
, the
return value is NaN
, zero is stored in *pexp
, and
errno
is set to EDOM
. If x is zero, *pexp and
the return value are also both zero.
ANSI, POSIX
#include <stdio.h> int fscanf(FILE *file, const char *format, ...);
This function scans formatted text from file and stores it in the variables pointed to by the arguments. See scanf.
The number of items successfully scanned.
ANSI, POSIX
#include <stdio.h> int fseek(FILE *file, long offset, int mode);
This function moves the file pointer for file according to mode:
SEEK_SET
SEEK_CUR
SEEK_END
Warning! The ANSI standard only allows values of zero for
offset when mode is not SEEK_SET
and the file has
been opened as a text file. Although this restriction is not enforced,
beware that there is not a one-to-one correspondence between file
characters and text characters under MS-DOS, so some fseek
operations may not do exactly what you expect.
Also, since lseek
under DOS does not return an error indication
when you try to move the file pointer before the beginning of the file,
neither will fseek
. Portable programs should call ftell
after fseek
to get the actual position of the file pointer.
Note that DOS does not mind if you seek before the beginning of the
file, like seeking from the end of the file by more than the file's
size. Therefore, lseek
will not return with an error in such
cases either.
Zero if successful, nonzero if not.
ANSI, POSIX
fseek(stdin, 12, SEEK_CUR); /* skip 12 bytes */
#include <stdio.h> int fsetpos(FILE *file, const fpos_t *offset);
This function moves the file pointer for file to position
offset, as recorded by fgetpos
.
Zero if successful, nonzero if not.
ANSI, POSIX
#include <sys/fsext.h> int __FSEXT_add_open_handler(__FSEXT_Function *_function);
This function is part of the File System Extensions. It is used
to add a handler for functions that do not get passed descriptors,
such as _open
and _creat
.
not ANSI, not POSIX
static int _my_handler(__FSEXT_Fnumber n, int *rv, va_list args) { . . . } int main() { __FSEXT_add_open_handler(_my_handler); }
#include <sys/fsext.h> int __FSEXT_alloc_fd(__FSEXT_Function *_function);
This function is part of the File System Extensions. It is used
by extensions that fully emulate the I/O functions, and thus don't
have a corresponding DOS file handle. Upon the first call, this
function opens DOS's NUL
device, so as to allocate a handle that
DOS won't then reuse. Upon subsequent calls, that handle is duplicated
by calling the DOS dup
function; this makes all of the handles
use a single entry in the System File Table, and thus be independent of
what the FILES=
parameter of CONFIG.SYS
says.
__FSEXT_alloc_fd
also assigns the handler function for the handle
it returns.
The module is responsible for calling _close
on the descriptor
after setting the handler function to zero in the extended close
handler.
If successful, a new file descriptor is returned. On error, a negative number is returned and errno is set to indicate the error.
not ANSI, not POSIX
int socket() { int fd = __FSEXT_alloc_fd(socket_handler); init_socket(fd); return fd; }
#include <sys/fsext.h> int __FSEXT_call_open_handlers(__FSEXT_Fnumber _function_number, int *rv, va_list _args);
This function is part of the File System Extensions. It is used
internally to libc.a to allow extensions to get an opportunity to
override the _open
and _creat
functions.
not ANSI, not POSIX
#include <sys/fsext.h> void *__FSEXT_get_data(int _fd);
This function is part of the File System Extensions. It is used
to retrieve a descriptor-specific pointer that was previously stored
by __FSEXT_set_data
(see __FSEXT_set_data). The pointer is not
otherwise used.
See __FSEXT_set_data, for an example of how this may be used.
Returns the stored pointer, or NULL if there was an error (or no pointer had been stored).
not ANSI, not POSIX
#include <sys/fsext.h> __FSEXT_Function *__FSEXT_get_function(int _fd);
This function is part of the File System Extensions. It is used internal to libc.a to redirect I/O requests to the appropriate extensions.
not ANSI, not POSIX
_read(int fd, void *buf, int len) { __FSEXT_Function *func = __FSEXT_get_function(fd); if (func) { int rv; if (func(__FSEXT_read, &rv, &fd)) return rv; } /* rest of read() */ }
#include <sys/fsext.h> void * __FSEXT_set_data(int _fd, void *_data);
This function is part of the File System Extensions. It is used
to store a descriptor-specific pointer that can later be retrieved by
__FSEXT_get_data
(see __FSEXT_get_data). The pointer is not
otherwise used.
This is useful when writing an extension that may be handling several
open pseudo-files. __FSEXT_set_data
can be used when creating or
opening the file to store a pointer to data about the specific file. Later,
when specific operation needs to be done (e.g. read, write, etc.) a
pointer to pseudo-file associated with the file descriptor can be fetched
with __FSEXT_get_data
.
Returns the pointer you passed it, or NULL if there was an error.
not ANSI, not POSIX
typedef struct { void* Ptr; off_t Current_Ofs; size_t Size; } _mem_file_t; int my_fsext(__FSEXT_Fnumber Op, int* RV, va_list Args) { const char* Path; void* Buffer; size_t Size; int fd; _mem_file_t* MPtr; switch (Op) { case __FSEXT_creat: /* Create a new memory file */ Path = va_list(Args, const char*); /* Check to see if we should create a new file */ if (strnicmp("/tmp/", Path, 5) != 0) return 0; /* Allocate some memory to keep info on our fake file */ MPtr = malloc(sizeof(_mem_file_t)); if (!MPtr) return 0; memset(MPtr, 0, sizeof(_mem_file_t)); /* Get a file descriptor we can use */ fd = __FSEXT_alloc_fd(my_fsext); if (fd < 0) { free(MPtr); return 0; } /* Now store our note about this file descriptor so we can lookup it up quickly later. */ __FSEXT_set_data(fd, MPtr); /* Return the file descriptor *RV = fd; return 1; case __FSEXT_read: /* Read from our memory file. */ fd = va_list(Args, int); Buffer = va_list(Args, void*); Size = va_list(Args, size_t); /* Look up the information about this file */ MPtr = __FSEXT_get_data(fd); if (!MPtr) { *RV = -1; return 1; } if (MPtr->Current_Ofs >= MPtr->Size) { *RV = 0; return 1; } if (Size > (MPtr->Size - MPtr->Current_Ofs)) Size = MPtr->Size - MPtr->Current_Ofs; memcpy(Buffer, (char*) MPtr->Ptr+MPtr->Current_Ofs, Size); MPtr->Current_Ofs += Size; *RV = Size; return 1; ... } }
#include <sys/fsext.h> int __FSEXT_set_function(int _fd, __FSEXT_Function *_function);
This function is part of the File System Extensions. It is used to set the handler function for those extensions that use DOS files for I/O. One situation where you might need this is when you must catch output to the terminal and play some tricks with it, like colorize it or redirect it to another device.
Zero in case of success, non-zero in case of failure (like if _fd is negative).
not ANSI, not POSIX
#include <sys/fsext.h> #include <conio.h> /* A simple example of a write handler which converts DOS I/O to the screen into direct writes to video RAM. */ static int my_screen_write (__FSEXT_Fnumber func, int *retval, va_list rest_args) { char *buf, *mybuf; size_t buflen; int fd = va_arg (rest_args, int); if (func != __FSEXT_write || !isatty (fd)) return 0; /* and the usual DOS call will be issued */ buf = va_arg (rest_args, char *); buflen = va_arg (rest_args, size_t); mybuf = alloca (buflen + 1); memcpy (mybuf, buf, buflen); mybuf[buflen] = '\0'; cputs (mybuf); *retval = buflen; return 1; /* meaning that we handled the call */ } /* Install our handler. The `attribute constructor' causes this function to be called by the startup code. */ static void __attribute__((constructor)) install_screen_write_handler (void) { __FSEXT_set_function (fileno (stdout), my_screen_write); }
#include <sys/stat.h> int fstat(int file, struct stat *sbuf);
This function obtains the status of the open file file and stores
it in sbuf. See stat, for the description of members of
struct stat
.
Some members of struct stat
are very expensive to compute. If
your application is a heavy user of fstat
and is too slow, you
can disable computation of the members your application doesn't need, as
described in _djstat_flags.
Zero on success, nonzero on failure (and errno set).
not ANSI, POSIX
struct stat s; fstat(fileno(stdin), &s); if (S_ISREG(s.st_mode)) puts("STDIN is a redirected disk file"); else if (S_ISCHR(s.st_mode)) puts("STDIN is a character device");
If a file was open in write-only mode, its execute mode bits might be incorrectly reported as if the file were non-executable. This is because some executables are only recognized by reading their first two bytes, which cannot be done for files open in write-only mode.
For fstat
to return correct info, you should make sure that all
the data written to the file has been delivered to the operating system,
e.g. by calling both fflush
and fsync
. Otherwise, the
buffering of the library I/O functions and the OS might cause stale info
to be returned.
Supplying a 100% Unix-compatible fstat
function under DOS is an
implementation nightmare. The following notes describe some of the
obscure points specific to fstat
s behavior in DJGPP.
1. The drive
for character devices (like con
, /dev/null
and others is returned as -1. For drives networked by Novell Netware, it
is returned as -2.
2. The starting cluster number of a file serves as its inode number. For
files whose starting cluster number is inaccessible (empty files, files on
networked drives, etc.) the st_inode
field will be invented
in a way which guarantees that no two different files will get the same
inode number (thus it is unique). This invented inode will also be
different from any real cluster number of any local file. However, only
for local, non-empty files/directories the inode is guaranteed to be
consistent between stat
and fstat
function calls.
3. The WRITE access mode bit is set only for the user (unless the file is
read-only, hidden or system). EXECUTE bit is set for directories, files
which can be executed from the DOS prompt (batch files, .com, .dll and .exe
executables) or run by go32-v2.exe
. For files which reside on
networked drives under Novell Netware, this can sometimes fail, in which
case only the read access bit is set.
4. The variable _djstat_flags
(see _djstat_flags) controls
what hard-to-get fields of struct stat
are needed by the
application.
#include <unistd.h> int fsync(int file);
Forces all information about the file with the given descriptor to be synchronized with the disk image. Works by calling DOS function 0x68. Warning: External disk caches are not flushed by this function.
Zero on success, nonzero on failure.
not ANSI, not POSIX
fsync(fileno(stdout));
#include <stdio.h> long ftell(FILE *file);
Returns the current file position for file
. This is suitable for
a future call to fseek
.
The file position, or -1 on error.
ANSI, POSIX
long p = ftell(stdout);
#include <sys/timeb.h> int ftime(struct timeb *buf);
This function stores the current time in the structure buf. The
format of struct timeb
is:
struct timeb { time_t time; /* seconds since 00:00:00 GMT 1/1/1970 */ unsigned short millitm; /* milliseconds */ short timezone; /* difference between GMT and local, minutes */ short dstflag; /* set if daylight savings time in affect */ };
Zero on success, nonzero on error.
not ANSI, not POSIX
struct timeb t; ftime(&t);
#include <unistd.h> int ftruncate(int handle, off_t where);
This function truncates the file open on handle at byte position where. The file pointer associated with handle is not changed.
Note that this function knows nothing about buffering by stdio functions
like fwrite
and fprintf
, so if handle comes from a
FILE
object, you need to call fflush
before calling this
function.
Zero for success, nonzero for failure.
not ANSI, not POSIX
int x = open("data", O_WRONLY); ftruncate(x, 1000); close(x);
#include <ftw.h> int ftw(const char *dir, int (*func)(const char *path, struct stat *stbuf, int flag), int depth);
This function recursively descends the directory hierarchy which starts
with dir. For each file in the hierarchy, ftw
calls the
user-defined function func which is passed a pointer to a
NULL
-terminated character array in path holding the full
pathname of the file, a pointer to a stat
structure (see stat)
stbuf with a filesystem information about that file, and an integer
flag. Possible values of flag are:
FTW_F
FTW_D
FTW_VL
FTW_DNR
readdir()
. (This
will never happen in DJGPP.)
FTW_NS
stat
fails for it.
If flag is FTW_DNR
, the descendants of that directory won't
be processed. If flag is FTW_NS
, then stbuf will be
garbled.
This function always visits a directory before any of its siblings. The
argument dir must be a directory, or ftw
will fail and set
errno to ENOTDIR
. The function func is called with
dir as its argument before the recursive descent begins.
The depth argument has no meaning in the DJGPP implementation and is always ignored.
The tree traversal continues until one of the following events:
(1) The tree is exhausted (i.e., all descendants of dir are
processed). In this case, ftw
returns 0, meaning a success.
(2) An invocation of func returns a non-zero value. In this case,
ftw
stops the tree traversal and returns whatever func
returned.
(3) An error is detected within ftw
. In that case, ftw
returns -1 and sets errno (see errno) to a suitable value.
Zero in case the entire tree was successfully traversed, -1 if ftw
detected some error during its operation, or any other non-zero value
which was returned by the user-defined function func.
This function uses malloc
(see malloc) for dynamic memory
allocation during its operation. If func disrupts the normal flow
of code execution by e.g. calling longjump
or if an interrupt
handler which never returns is executed, this memory will remain
permanently allocated.
This function calls opendir()
and readdir()
functions to
read the directory entries. Therefore, you can control what files will
your func get by setting the appropriate bits in the external
variable __opendir_flags. See opendir, for description of these
bits.
This function also calls stat
for every directory entry it passes
to func. If your application only needs some part of the
information returned in the stat
structure, you can make your
application significantly faster by setting bits in the external variable
_djstat_flags (see _djstat_flags for details). The most
expensive stat
features are _STAT_EXEC_MAGIC
and
_STAT_DIRSIZE
.
not ANSI, not POSIX
#include <stdlib.h> int file_walker(const char *path, struct stat *sb, int flag) { char *base; printf("%s:\t%u\t", path, sb->st_size); if (S_ISLABEL(sb->st_mode)) printf("V"); if (S_ISDIR(sb->st_mode)) printf("D"); if (S_ISCHR(sb->st_mode)) printf("C"); if (sb->st_mode & S_IRUSR) printf("r"); if (sb->st_mode & S_IWUSR) printf("w"); if (sb->st_mode & S_IXUSR) printf("x"); if (flag == FTW_NS) printf(" !!no_stat!!"); printf("\n"); base = strrchr(path, '/'); if (base == 0) base = strrchr(path, '\\'); if (base == 0) base = strrchr(path, ':'); if (strcmp(base == 0 ? path : base + 1, "xxxxx") == 0) return 42; return 0; } int main(int argc, char *argv[]) { if (argc > 1) { char msg[80]; sprintf(msg, "file_tree_walk: %d", ftw(argv[1], file_walker, 0)); if (errno) perror(msg); else puts(msg); } else printf("Usage: %s dir\n", argv[0]); return 0; }
#include <libc/file.h> void _fwalk(void (*function)(FILE *file));
For each open file in the system, the given function is called, passing the file pointer as its only argument.
None.
not ANSI, not POSIX
void pfile(FILE *x) { printf("FILE at %p\n", x); } _fwalk(pfile);
#include <stdio.h> size_t fwrite(void *buffer, size_t size, size_t number, FILE *file);
This function writes size*number characters from buffer to file.
The number of items of size size written, or less if there was an error.
ANSI, POSIX
int foo[10]; fwrite(foo, sizeof(int), 10, stdin);
#include <stdlib.h> char * gcvt (double value, int ndigits, char *buf)
This function converts its argument value into a null-terminated
string of ndigits significant digits in buf. buf
should have enough space to hold at least ndigits + 7
characters. The result roughly corresponds to what is obtained by the
following snippet:
(void) sprintf(buf, "%.*g", ndigits, value);
except that trailing zeros and trailing decimal point are suppressed.
The least-significant digit in buf is rounded.
ecvtbuf
produces the string "NaN" if value is a NaN, and
"Inf" if value is an infinity.
A pointer to buf.
not ANSI, not POSIX
#include <stdlib.h> #include <stdio.h> #include <math.h> char vbuf[20]; /* This will print " 3.14159". */ printf ("%s", gcvt (M_PI, 5, buf));
#include <io.h> short _get_dev_info(int handle);
Given a file handle in handle, this function returns the info word
from DOS IOCTL function 0 (Int 21h/AX=4400h). handle must refer
to an open file or device, otherwise the call will fail (and set
errno to EBADF
).
In case of success, the returned value is the coded information from the system about the character device or the file which is referenced by the file handle handle. The following table shows the meaning of the individual bits in the return value:
For a character device:
Bit(s) | Description
|
14 | Device can process IOCTL functions 02h and 03h
|
13 | Device supports output-until-busy
|
11 | Device supports OPEN/CLOSE calls
|
8 | Unknown; set by MS-DOS 6.2x KEYBxx.COM
|
7 | Always set for character devices
|
6 | End of file on input
|
5 | Device is in raw (binary) mode
|
4 | Device uses Int 29h
|
3 | Clock device
|
2 | NUL device
|
1 | Standard output device
|
0 | Standard input device
|
For a block device (a disk file):
Bit(s) | Description
|
15 | Device is remote (networked drive)
|
14 | Don't set file time stamp on close
|
11 | If set, non-removable media
|
11 | If clear, media is removable (e.g. floppy disk)
|
8 | Generate Int 24h if full disk or read past EOF
|
7 | Always clear for disk files
|
6 | File has not been written to
|
5-0 | Drive number (0 = A:)
|
Note that the functionality indicated by bit 8 for the block devices is only supported by DOS version 4.
Cooked mode means that on input C-<C>, C-<P>,
C-<S> and C-<Z> are processed, on output TAB
s
are expanded into spaces and CR
character is added before each
LF
, and input is terminated when the <RET> key is pressed.
In contrast, in raw mode, all the special characters are passed
verbatim, and the read operation waits until the specified number of
characters has been read.
The device information word described above. In case of error, -1 is
returned and errno is set to EBADF
.
not ANSI, not POSIX
int fd = open ("CLOCK$", O_RDONLY | O_BINARY); int clock_info = _get_dev_info (fd);
#include <dos.h> extern unsigned short _osmajor, _osminor; extern const char * _os_flavor; unsigned short _get_dos_version(int true_version);
This function gets the host OS version and flavor. If the argument true_version is non-zero, it will return a true version number, which is unaffected by possible tinkering with SETVER TSR program. (This is only available in DOS 5.0 or later.)
The external variables _osmajor
and _osminor
will always be
set to the major and minor parts of the advertised version number,
possibly changed by SETVER, even if true_version is non-zero. You
typically need the true version when you need an intimate knowledge of the
host OS internals, like when using undocumented features. Note that some
DOS clones (notably, DR-DOS) do not support DOS function required to
report the true DOS version; for these, the version reported might be
affected by SETVER even if true_version is non-zero.
The external variable _os_flavor
will point to a string which
describes the OEM name of the host OS variety.
_get_dos_version()
returns the version number (true version number,
if true_version is non-zero) as a 16-bit number: the major part of
the version in the upper 8 bits, the minor part in the lower 8 bits. For
instance, DOS version 6.20 will be returned as 0x0614.
not ANSI, not POSIX
unsigned short true_dos_version = _get_dos_version(1); if (true_dos_version < 0x0614) /* require DOS 6.20 or later */ puts("This program needs DOS 6.20 or later to run"); else printf("You are running %s variety of DOS\n", _os_flavor);
#include <fcntl.h> unsigned _get_volume_info (const char *path, int *max_file_len, int *max_path_len, char *fsystype);
This function returns filesystem information about the volume where
path resides. Only the root directory name part is actually used;
if path does not specify the drive explicitly, or is a NULL
pointer, the current drive is used. Upon return, the variable pointed
to by max_file_len contains the maximum length of a filename
(including the terminating zero), the variable pointed to by
max_path_len contains the maximum length of a pathname (including
the terminating zero), and a string that identifies the filesystem type
(e.g., "FAT", "NTFS" etc.) is placed into the buffer pointed to by
fsystype, which should be long enough (32 bytes are usually
enough). If any of these pointers is a NULL
pointer, it will be
ignored. The function returns various flags that describe features
supported by the given filesystem as a bit-mapped number. The following
bits are currently defined:
_FILESYS_CASE_SENSITIVE
_FILESYS_CASE_PRESERVED
_FILESYS_UNICODE
_FILESYS_LFN_SUPPORTED
_FILESYS_VOL_COMPRESSED
_FILESYS_UNKNOWN
A combination of the above bits if the LFN API is supported, or 0 (and
errno
set to ENOSYS
) if the LFN API is not supported by the
OS. If the drive letter is invalid, the function returns
_FILESYS_UNKNOWN
and sets errno
to either ENODEV
or
ENXIO
.
not ANSI, not POSIX
#include <stdio.h> int getc(FILE *file);
Get one character from file.
The character ([0..255]) or EOF
if eof or error.
ANSI, POSIX
int c; while ((c=getc(stdin)) != EOF) putc(c, stdout);
#include <dos.h> int getcbrk(void);
Get the setting of the Ctrl-C checking flag in MS-DOS.
See setcbrk.
0 if not checking, 1 if checking.
not ANSI, not POSIX
#include <conio.h> int getch(void);
A single character from the predefined standard input handle is read and
returned. The input is not buffered. If there is a character pending
from ungetch
(see ungetch), it is returned instead. The
character is not echoed to the screen. This function doesn't check for
special characters like Ctrl-<C>.
If the standard input handle is connected to the console, any pending
output in the stdout
and stderr
streams is flushed before
reading the input, if these streams are connected to the console.
The character.
not ANSI, not POSIX
#include <stdio.h> int getchar(void);
The same as fgetc(stdin)
(see fgetc).
The character, or EOF
.
ANSI, POSIX
#include <conio.h> int getche(void);
A single character from the predefined standard input handle is read and
returned. The input is not buffered. If there is a character pending
from ungetch
(see ungetch), it is returned instead. The
character is echoed to the screen. This function doesn't check for
special characters like Ctrl-<C>.
If the standard input handle is connected to the console, any pending
output in the stdout
and stderr
streams is flushed before
reading the input, if these streams are connected to the console.
The character.
not ANSI, not POSIX
#include <unistd.h> char *getcwd(char *buffer, int max);
Get the current directory. The return value includes the drive
specifier. If buffer is NULL
, getcwd
allocates
memory with malloc
. This call fails if more than max
characters are required to specify the current directory.
The buffer, either buffer or a newly-allocated buffer, or
NULL
on error.
not ANSI, POSIX
char *buf = (char *)malloc(PATH_MAX); if (buf && getcwd(buf, PATH_MAX)) { printf("cwd is %s\n", buf); free(buf); }
#include <dos.h> void getdate(struct date *);
This function gets the current date. The return structure is as follows:
struct date { short da_year; char da_day; char da_mon; };
None.
not ANSI, not POSIX
struct date d; getdate(&d);
#include <dos.h> void getdfree(unsigned char drive, struct dfree *ptr);
This function gets information about the size and fullness of the given drive (0=default, 1=A:, etc). The return structure is as follows:
struct dfree { unsigned df_avail; /* number of available clusters */ unsigned df_total; /* total number of clusters */ unsigned df_bsec; /* bytes per sector */ unsigned df_sclus; /* sectors per cluster */ };
None.
not ANSI, not POSIX
struct dfree d; getdfree(3, &d); /* drive C: */
#include <dir.h> int getdisk(void);
Gets the current disk (0=A).
See setdisk.
The current disk number.
not ANSI, not POSIX
printf("This drive is %c:\n", getdisk() + 'A');
#include <unistd.h> int getdtablesize(void);
Get the maximum number of open file descriptors the system supports.
255
not ANSI, not POSIX
#include <unistd.h> int getegid(void);
Get the effective group id.
42
not ANSI, POSIX
#include <stdlib.h> char *getenv(const char *name);
Get the setting of the environment variable name. Do not alter or free the returned value.
The value, or NULL
if that variable does not exist.
ANSI, POSIX
char *term = getenv("TERM");
#include <unistd.h> int geteuid(void);
Gets the effective UID.
42
not ANSI, POSIX
#include <dos.h> int getftime(int handle, struct ftime *ptr);
Get the timestamp for the given file handle. The return structure is as follows:
struct ftime { unsigned ft_tsec:5; /* 0-29, double to get real seconds */ unsigned ft_min:6; /* 0-59 */ unsigned ft_hour:5; /* 0-23 */ unsigned ft_day:5; /* 1-31 */ unsigned ft_month:4; /* 1-12 */ unsigned ft_year:7; /* since 1980 */ }
Zero on success, nonzero on failure.
not ANSI, not POSIX
struct ftime t; getftime(fd, &t);
#include <unistd.h> int getgid(void);
Get the current group id.
42
not ANSI, POSIX
#include <grp.h> struct group *getgrent(void);
This function returns the next available group entry. Note that for
MS-DOS, this is simulated. If the environment variable GROUP is set,
that is the name of the only group returned, else the only group is
"dos". Thus, under DOS, getgrent
will always fail on the
second and subsequent calls.
The return type of this and related function is as follows:
struct group { gid_t gr_gid; /* result of getgid() */ char ** gr_mem; /* gr_mem[0] points to getenv("USER"/"LOGNAME") or "user" */ char * gr_name; /* getenv("GROUP") or "dos" */ };
The next structure, or NULL
at the end of the list.
not ANSI, not POSIX
struct group *g; setgrent(); while ((g = getgrent()) != NULL) { printf("group %s gid %d\n", g->gr_name, g->gr_gid); } endgrent();
#include <grp.h> extern struct group *getgrgid(int gid);
This function returns the group entry that matches gid.
See getgrent, for the description of struct group
.
The matching group, or NULL
if none match.
not ANSI, POSIX
#include <grp.h> struct group *getgrnam(char *name);
This function returns the group entry for the group named name.
See getgrent, for the description of struct group
.
The matching group, or NULL
if none match.
not ANSI, POSIX
#include <unistd.h> int getgroups(int size, gid_t *grouplist);
This function always returns zero. It exists to assist porting from Unix.
Zero.
not ANSI, POSIX
#include <unistd.h> #include <sys/param.h> int gethostname (char *buf, int size);
Get the name of the host the program is executing on. This name
is obtained from the network software, if present, otherwise from
the "HOSTNAME"
environment variable, if present, finally
defaulting to "pc"
.
The call fails if more than size characters are required to
specify the host name. A buffer size of MAXGETHOSTNAME
is
guaranteed to be enough.
Zero on success, nonzero on failure.
not ANSI, not POSIX
char *buf = (char *) malloc (MAXGETHOSTNAME); if (buf && 0 == gethostname (buf, MAXGETHOSTNAME)) printf ("We're on %s\n", buf); if (buf) free(buf);
#include <sys/time.h> int getitimer(int which, struct itimerval *value);
This function gets the current value of the interval timer specified by
which into structure value. Variable which can have
the value of ITIMER_REAL
or ITIMER_PROF
.
See setitimer, for more details about timers.
Upon return, the it_value
member of value will hold the
amount of time left until timer expiration, or zero if the timer has
expired or was stopped by a previous call to setitimer
. The
it_interval
member will hold the interval between two successive
alarms as set by the last call to setitimer
(but note that
interval values less than the system clock granularity are rounded up to
that granularity). The value returned in it_interval
member is
not set to zero when the timer is stopped, it always retains the
interval that was last in use.
Returns 0 on success, -1 on failure (and sets errno
).
not ANSI, not POSIX
#include <pc.h> #include <keys.h> int getkey(void);
Waits for the user to press one key, then returns that key. Alt-key combinations have 0x100 added to them. Extended keys return their non-extended codes.
The file keys.h
has symbolic names for many of the keys.
See getxkey.
The key pressed.
not ANSI, not POSIX
while (getkey() != K_Alt_3) do_something();
#include <unistd.h> char *getlogin(void);
Get the login ID of the user.
Returns the value of the USER
environment variable, else the
LOGNAME
environment variable, else "dosuser"
.
not ANSI, POSIX
printf("I am %s\n", getlogin());
#include <stdlib.h> int getlongpass(const char *prompt, char *password, int max_length)
This function reads up to a Newline (CR or LF) or EOF (Ctrl-D or Ctrl-Z)
from the standard input, without an echo, after prompting with a
null-terminated string prompt. It puts a null-terminated string of
at most max_length - 1 first characters typed by the user into a
buffer pointed to by password. Pressing Ctrl-C or Ctrl-Break will
cause the calling program to exit(1)
.
Zero if successful, -1 on error (and errno is set to an appropriate value).
not ANSI, not POSIX
char password[MAX_PASS]; (void)getlongpass("Password: ", password, MAX_PASS);
#include <mntent.h> struct mntent *getmntent(FILE *filep);
This function returns information about the various drives that are
available to your program. Beginning with drive A:
, information
is retrieved for successive drives with successive calls to
getmntent
. Note that drives A:
and B:
will only be
returned if there is an MS-DOS formatted disk in the drive; empty drives
are skipped. For systems with a single floppy drive, it is returned as
if it were mounted on A:/
or B:/
, depending on how it was
last referenced (and if there is a disk in the drive).
For each drive scanned, a pointer to a static structure of the following type is returned:
struct mntent { char * mnt_fsname; /* The name of this file system */ char * mnt_dir; /* The root directory of this file system */ char * mnt_type; /* Filesystem type */ char * mnt_opts; /* Options, see below */ int mnt_freq; /* -1 */ int mnt_passno; /* -1 */ long mnt_time; /* -1 */ };
DJGPP implementation returns the following in the first 4 fields of
struct mntent
:
mnt_fsname
\\HOST\PATH
(this is called a UNC name).
For drives compressed with DoubleSpace, mnt_fsname
is the string
X:\DBLSPACE.NNN
, where X is the drive letter of
the host drive and NNN is the sequence number of the Compressed
Volume File.
For drives compressed with Stacker, mnt_fsname
is the string
X:\STACVOL.NNN
, where X and NNN are as
for DoubleSpace drives.
For drives compressed with Jam (a shareware disk compression software),
mnt_fsname
is the full name of the Jam archive file.
For SUBSTed drives, mnt_fsname
is the actual directory name that
that was SUBSTed to emulate a drive.
JOINed drives get their mnt_fsname
as if they were NOT JOINed
(i.e., either the label name or the default Drive X:
).
For drives with a volume label, mnt_fsname
is the name of the
label; otherwise the string Drive X:
, where X is the
drive letter.
mnt_dir
X:/
(where X is the drive letter), except that JOINed drives get
mnt_dir
as the name of the directory to which they were JOINed.
For systems with a single floppy drive (which can be referenced as either
a:/
or b:/
), the mount directory will be returned as one
of these, depending on which drive letter was last used to reference
that drive.
mnt_type
"fd" for floppy disks "hd" for hard disks "dblsp" for disks compressed with DoubleSpace "stac" for disks compressed with Stacker "jam" for disks compressed with Jam "cdrom" for CD-ROM drives "ram" for RAM disks "subst" for SUBSTed directories "join" for JOINed disks "net" for networked drives
mnt_opts
ro,dev=XX
for CD-ROM drives,
rw,dev=XX
for all the others, where XX is the
hexadecimal drive number of the REAL drive on which this filesystem
resides. That is, if you call stat
on mnt_fsname, you will
get the numeric equivalent of XX in st_dev
member of
struct stat
. E.g., for drive C:
you will get
rw,dev=02
. Note that SUBSTed and JOINed drives get the drive
numbers as if SUBST and JOIN were not in effect.
This function returns a pointer to a struct mntent
, or
NULL
if there are no more drives to report on.
not ANSI, not POSIX
struct mntent *m; FILE *f; f = setmntent("/etc/mnttab", "r"); while ((m = getmntent(f))) printf("Drive %s, name %s\n", m->mnt_dir, m->mnt_fsname); endmntent(f);
#include <unistd.h> int getopt(int argc, char * const *argv, const char *options); extern char *optarg; extern int optind, opterr, optopt;
Parse options from the command line. The options are a string of valid option characters. If a given option takes a parameter, that character should be followed by a colon.
For each valid switch, this function sets optarg
to the argument
(if the switch takes one), sets optind
to the index in argv
that it is using, sets optopt
to the option letter found, and
returns the option letter found.
If an unexpected option is found, getopt
will return ?
,
and if opterr
is nonzero, will print an error message to stderr.
The special option --
indicates that no more options follow on
the command line, and cause getopt
to stop looking.
The option found, or -1 if no more options.
not ANSI, POSIX
int c; opterr = 0; while ((c=getopt(argc, argv, "vbf:")) != -1) { switch (c) { case 'v': verbose_flag ++; break; case 'b': binary_flag ++; break; case 'f': output_filename = optarg; break; case '?': printf("Unknown option %c\n", optopt); usage(); exit(1); } }
#include <unistd.h> int getpagesize(void);
Return the size of the native virtual memory page size.
4096 for the i386 and higher processors.
not ANSI, not POSIX
#include <stdlib.h> char * getpass(const char *prompt)
This function reads up to a Newline (CR or LF) or EOF (Ctrl-D or Ctrl-Z)
from the standard input, without an echo, after prompting with a
null-terminated string prompt. It returns the string of at most 8
characters typed by the user. Pressing Ctrl-C or Ctrl-Break will cause
the calling program to exit(1)
.
A pointer to a static buffer which holds the user's response. The buffer will be overwritten by each new call. In case of any error in the lower I/O routines, a NULL pointer will be returned.
not ANSI, not POSIX
char *password = getpass("Password: ");
#include <unistd.h> int getpgrp(void);
Gets the process group, which is currently the same as the pid.
The process group.
not ANSI, POSIX
#include <unistd.h> int getpid(void);
Get the process ID, which uniquely identifies each program running on the system.
The process ID.
not ANSI, POSIX
#include <pwd.h> struct passwd *getpwent(void);
This function retrieves the next available password file entry. For MS-DOS, this is simulated by providing exactly one entry:
struct passwd { char * pw_name; /* getlogin() */ int pw_uid; /* getuid() */ int pw_gid; /* getgid() */ char * pw_dir; /* "/" or getenv("HOME") */ char * pw_shell; /* "/bin/sh" or getenv("SHELL") */ };
The pw_name
member is returned as described under getlogin
(see getlogin). The pw_uid
member is returned as described
under getuid
(see getuid). pw_gid
is returned as
described under getgid
(see getgid). The pw_dir
member is set to the value of the environment variable HOME
if it
is defined, or to /
otherwise. pw_shell
is set as
follows:
SHELL
is set, the value of
SHELL
.
SHELL
is not set, but COMSPEC
is, the value of
COMSPEC
.
pw_shell
is set to
"sh"
.
The next passwd entry, or NULL
if there are no more.
not ANSI, not POSIX
struct passwd *p; setpwent(); while ((p = getpwent()) != NULL) { printf("user %s name %s\n", p->pw_name, p->pw_gecos); } endpwent();
#include <pwd.h> struct passwd *getpwnam(const char *name);
This function gets the password file entry matching name. See
getpwent, for the description of struct passwd
.
The matching record, or NULL
if none match.
not ANSI, POSIX
#include <pwd.h> struct passwd *getpwuid(uid_t uid);
This function gets the password file entry matching uid. See
getpwent, for the description of struct passwd
.
The matching record, or NULL
if none match.
not ANSI, POSIX
#include <sys/resource.h> int getrlimit (int rltype, struct rlimit *rlimitp);
This function gets the resource limit specified by rltype and
stores it in the buffer pointed to by rlimitp. The rlimit
structure is defined on sys/resource.h
as follows:
struct rlimit { long rlim_cur; /* current (soft) limit */ long rlim_max; /* maximum value for rlim_cur */ };
The following resource types can be passed in rltype:
RLIMIT_CPU
RLIMIT_FSIZE
RLIMIT_DATA
RLIMIT_STACK
RLIMIT_CORE
RLIMIT_RSS
RLIMIT_MEMLOCK
RLIMIT_NPROC
RLIMIT_NOFILE
Currently, only the RLIMIT_STACK
and RLIMIT_NOFILE
are
meaningful: the first returns the value of _stklen
(see _stklen), the second the value returned by
sysconf(_SC_OPEN_MAX)
(see sysconf). All other members of
the rlimit
structure are set to RLIM_INFINITY
, defined in
sys/resource.h
as 2^31 - 1
.
Zero on success, nonzero on failure.
not ANSI, not POSIX
struct rlimit rlimitbuf; int rc = getrlimit (RLIMIT_STACK, &rlimitbuf);
#include <sys/time.h> #include <sys/resource.h> int getrusage(int who, struct rusage *rusage);
This function returns information about the running process. The
structure struct rusage
is defined on <sys/resource.h>
as
follows:
struct rusage { struct timeval ru_utime; /* user time used */ struct timeval ru_stime; /* system time used */ long ru_maxrss; /* integral max resident set size */ long ru_ixrss; /* integral shared text memory size */ long ru_idrss; /* integral unshared data size */ long ru_isrss; /* integral unshared stack size */ long ru_minflt; /* page reclaims */ long ru_majflt; /* page faults */ long ru_nswap; /* swaps */ long ru_inblock; /* block input operations */ long ru_oublock; /* block output operations */ long ru_msgsnd; /* messages sent */ long ru_msgrcv; /* messages received */ long ru_nsignals; /* signals received */ long ru_nvcsw; /* voluntary context switches */ long ru_nivcsw; /* involuntary context switches */ };
Currently, the only field that is computed is ru_utime
. It is
computed as the total elapsed time used by the calling program. The
remainder of the fields are set to zero.
The who parameter must be RUSAGE_SELF
or
RUSAGE_CHILDREN
.
Zero on success, nonzero on failure.
not ANSI, not POSIX
struct rusage r; getrusage(RUSAGE_SELF, &r);
#include <stdio.h> char *gets(char *buffer);
Reads characters from stdin
, storing them in buffer, until
either end of file or a newline is encountered. If any characters were
stored, the buffer is then NULL
terminated and its address
is returned, else NULL
is returned.
The address of the buffer, or NULL
.
ANSI, POSIX
char buf[1000]; while (gets(buf)) puts(buf);
#include <conio.h> int gettext(int _left, int _top, int _right, int _bottom, void *_destin);
Retrieve a block of screen characters into a buffer.
1
not ANSI, not POSIX
#include <conio.h> void gettextinfo(struct text_info *_r);
This function returns the parameters of the current window on the screen. The return structure is this:
struct text_info { unsigned char winleft; unsigned char wintop; unsigned char winright; unsigned char winbottom; unsigned char attribute; unsigned char normattr; unsigned char currmode; unsigned char screenheight; unsigned char screenwidth; unsigned char curx; unsigned char cury; };
The normattr
field is the text attribute which was in effect
before the program started.
not ANSI, not POSIX
#include <dos.h> void gettime(struct time *);
This function gets the current time. The return structure is as follows:
struct time { unsigned char ti_min; unsigned char ti_hour; unsigned char ti_hund; unsigned char ti_sec; };
None.
not ANSI, not POSIX
struct time t; gettime(&t);
#include <time.h> int gettimeofday(struct timeval *tp, struct timezone *tzp);
Gets the current GMT time and the local timezone information. The return structures are as follows:
struct timeval { long tv_sec; /* seconds since 00:00:00 GMT 1/1/1970 */ long tv_usec; /* microseconds */ }; struct timezone { int tz_minuteswest; /* west of GMT */ int tz_dsttime; /* set if daylight saving time in affect */ };
If either tp or tzp are NULL
, that information is not
provided.
Note that although this function returns microseconds for compatibility reasons, the values are precise to less than 1/20 of a second only. The underlying DOS function has 1/20 second granularity, as it is calculated from the 55 ms timer tick count, so you won't get better than that with gettimeofday().
See settimeofday.
Zero on success, nonzero on failure.
not ANSI, not POSIX
#include <unistd.h> int getuid(void);
Returns the user ID.
42
not ANSI, POSIX
#include <stdio.h> int getw(FILE *file);
Reads a single binary word in native format from file.
See putw.
The value read, or EOF
for end-of-file or error. Since
EOF
is a valid integer, you should use feof
or
ferror
to detect this situation.
not ANSI, not POSIX
int i = getw(stdin);
#include <unistd.h> char *getwd(char *buffer);
Get the current directory and put it in buffer. The return value includes the drive specifier.
buffer is returned.
not ANSI, not POSIX
char buf[PATH_MAX]; getwd(buf);
#include <pc.h> #include <keys.h> int getxkey(void);
Waits for the user to press one key, then returns that key. Alt-key combinations have 0x100 added to them, and extended keys have 0x200 added to them.
The file keys.h
has symbolic names for many of the keys.
See getkey.
The key pressed.
not ANSI, not POSIX
while (getxkey() != K_EEnd) do_something();
#include <glob.h> int glob(const char *pattern, int flags, int (*errfunc)(const char *epath, int eerrno), glob_t *pglob);
This function expands a filename wildcard which is passed as pattern. The pattern may include these special characters:
*
?
[...]
!
, matches any character not in the group. A
group is defined as a list of characters between the brackets,
e.g. [dkl_]
, or by two characters separated by -
to
indicate all characters between and including these two. For example,
[a-d]
matches a
, b
, c
, or d
, and
[!a-zA-Z0-9]
matches any character that is not alphanumeric.
...
\
\[
matches a literal [
. If flags includes
GLOB_NOESCAPE
, this quoting is disabled and \
is handled
as a simple character.
The variable flags controls certain options of the expansion process. Possible values for _flags are as follows:
GLOB_APPEND
pglob->gl_pathv
. By default, glob
discards all previous
contents of pglob->gl_pathv
and allocates a new memory block for
it. If you use GLOB_APPEND
, pglob
should point to a
structure returned by a previous call to glob
.
GLOB_DOOFFS
pglob->gl_offs
entries in gl_pathv
and put new
matches after that point. By default, glob
puts the new matches
beginning at pglob->gl_pathv[0]
. You can use this flag both with
GLOB_APPEND
(in which case the new matches will be put after the
first pglob->gl_offs
matches from previous call to glob
),
or without it (in which case the first pglob->gl_offs
entries in
pglob->gl_pathv
will be filled by NULL
pointers).
GLOB_ERR
GLOB_MARK
GLOB_NOCHECK
glob
doesn't change pglob
if no matches are
found.
GLOB_NOESCAPE
GLOB_NOSORT
Given the pattern and the flags, glob
expands the pattern and
returns a list of files that match the pattern in a structure a pointer
to which is passed via pglob. This structure is like this:
typedef struct { size_t gl_pathc; char **gl_pathv; size_t gl_offs; } glob_t;
In the structure, the gl_pathc
field holds the number of
filenames in gl_pathv
list; this includes the filenames produced
by this call, plus any previous filenames if GLOB_APPEND
or
GLOB_DOOFFS
were set in flags. The list of matches is
returned as an array of pointers to the filenames; gl_pathv
holds
the address of the array. Thus, the filenames which match the pattern
can be accessed as gl_pathv[0]
, gl_pathv[1]
, etc. If
GLOB_DOOFFS
was set in flags, the new matches begin at
offset given by gl_offs
.
Zero on success, or one of these codes:
GLOB_ABORTED
GLOB_NOMATCH
GLOB_NOSPACE
GLOB_ERR
glob
will not match names of volume labels.
On MSDOS, filenames are always matched case-insensitively. On filesystems that preserve letter-case in filenames (such as Windows 9x), matches are case-insensitive unless the pattern includes uppercase characters.
On MSDOS, the list of expanded filenames will be returned in lower case, if all the characters of the pattern (except those between brackets [...]) are lower-case; if some of them are upper-case, the expanded filenames will be also in upper case. On filesystems that preserve letter-case in filenames, long filenames are returned as they are found in the directory entry; DOS-style 8+3 filenames are returned as on MSDOS (in lower case if the pattern doesn't include any upper-case letters, in upper case otherwise).
When the environment variable LFN
is set to n, glob
behaves on Windows 9x exactly as it does on MSDOS.
Setting the environment variable FNCASE
to y, or setting
the _CRT0_FLAG_PRESERVE_FILENAME_CASE
bit in the
_crt0_startup_flags
variable (see _crt0_startup_flags)
suppresses any letter-case conversions in filenames and forces
case-sensitive filename matching. See _preserve_fncase.
not ANSI, POSIX
#include <stdlib.h> #include <string.h> #include <glob.h> /* Convert a wildcard pattern into a list of blank-separated filenames which match the wildcard. */ char * glob_pattern(char *wildcard) { char *gfilename; size_t cnt, length; glob_t glob_results; char **p; glob(wildcard, GLOB_NOCHECK, 0, &glob_results); /* How much space do we need? */ for (p = glob_results.gl_pathv, cnt = glob_results.gl_pathc; cnt; p++, cnt--) length += strlen(*p) + 1; /* Allocate the space and generate the list. */ gfilename = (char *) calloc(length, sizeof(char)); for (p = glob_results.gl_pathv, cnt = glob_results.gl_pathc; cnt; p++, cnt--) { strcat(gfilename, *p); if (cnt > 1) strcat(gfilename, " "); } globfree(&glob_results); return gfilename; }
#include <glob.h> void globfree(glob_t *_pglob);
Frees the memory associated with _pglob
.
not ANSI, POSIX
#include <time.h> struct tm *gmtime(const time_t *tod);
Converts the time represented by tod into a structure.
The return structure has this format:
struct tm { int tm_sec; /* seconds after the minute [0-60] */ int tm_min; /* minutes after the hour [0-59] */ int tm_hour; /* hours since midnight [0-23] */ int tm_mday; /* day of the month [1-31] */ int tm_mon; /* months since January [0-11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday [0-6] */ int tm_yday; /* days since January 1 [0-365] */ int tm_isdst; /* Daylight Savings Time flag */ long tm_gmtoff; /* offset from GMT in seconds */ char * tm_zone; /* timezone abbreviation */ };
A pointer to a static structure which is overwritten with each call.
ANSI, POSIX
time_t x; struct tm *t; time(&x); t = gmtime(&t);
#include <go32.h> u_short _go32_conventional_mem_selector();
This function returns a selector which has a physical base address
corresponding to the beginning of conventional memory. This selector
can be used as a parameter to movedata
(see movedata) to
manipulate memory in the conventional address space.
The selector.
not ANSI, not POSIX
short blank_row_buf[ScreenCols()]; /* scroll screen */ movedata(_go32_conventional_mem_selector(), 0xb8000 + ScreenCols()*2, _go32_conventional_mem_selector(), 0xb8000, ScreenCols() * (ScreenRows()-1) * 2); /* fill last row */ movedata(_go32_my_ds, (int)blank_row_buf, _go32_conventional_mem_selector(), 0xb8000 + ScreenCols()*(ScreenRows()-1)*2, ScreenCols() * 2);
#include <dpmi.h> int _go32_dpmi_allocate_dos_memory(_go32_dpmi_seginfo *info);
See DPMI Overview.
Allocate a part of the conventional memory area (the first 640K). Set
the size
field of info to the number of paragraphs
requested (this is (size in bytes + 15)/16), then call. The
rm_segment
field of info contains the segment of the
allocated memory.
The memory may be resized with _go32_dpmi_resize_dos_memory
and
must be freed with _go32_dpmi_free_dos_memory
.
If there isn't enough memory in the system, the size
field of
info has the largest available size, and an error is returned.
See also dosmemput, and dosmemget.
Zero on success, nonzero on failure.
not ANSI, not POSIX
_go32_dpmi_seginfo info; info.size = (want_size+15) / 16; _go32_dpmi_allocate_dos_memory(&info); dosmemput(buffer, want_size, info.rm_segment*16); _go32_dpmi_free_dos_memory(&info);
#include <dpmi.h> int _go32_dpmi_allocate_iret_wrapper(_go32_dpmi_seginfo *info);
See DPMI Overview.
This function creates a small assembler function that handles the
overhead of servicing an interrupt. To use, put the address of your
servicing function in the pm_offset
field of info and call
this function. The pm_field
will get replaced with the address
of the wrapper function, which you pass to both
_go32_dpmi_set_protected_mode_interrupt_vector
and
_go32_dpmi_free_iret_wrapper
.
See also _go32_dpmi_set_protected_mode_interrupt_vector, and _go32_dpmi_free_iret_wrapper.
Zero on success, nonzero on failure.
not ANSI, not POSIX
_go32_dpmi_seginfo info; info.pm_offset = my_handler; _go32_dpmi_allocate_iret_wrapper(&info); _go32_dpmi_set_protected_mode_interrupt_handler(0x75, &info); ... _go32_dpmi_free_iret_wrapper(&info);
#include <dpmi.h> int _go32_dpmi_allocate_real_mode_callback_iret(_go32_dpmi_seginfo *info, _go32_dpmi_registers *regs);
See DPMI Overview.
This function allocates a "real-mode callback". Fill in the
pm_offset
field of info and call this function. It will
fill in the rm_segment
and rm_offset
fields. Any time a
real-mode program calls the real-mode address, your function gets
called. The registers in effect will be stored in regs, which
should be a global, and will be passed to your function. Any changes in
regs will be reflected back into real mode. A wrapper will be
added to your function to simulate the effects of an iret
instruction, so this function is useful for trapping real-mode software
interrupts (like 0x1b - Ctrl-<Break> hit).
Zero on success, nonzero on failure.
not ANSI, not POSIX
_go32_dpmi_registers regs; my_handler(_go32_dpmi_registers *r) { r->d.eax = 4; } setup() { _go32_dpmi_seginfo info; _go32_dpmi_seginfo old_vector; _go32_dpmi_get_real_mode_interrupt_vector(0x84, &old_vector); info.pm_offset = my_handler; _go32_dpmi_allocate_real_mode_callback_iret(&info, ®s); _go32_dpmi_set_real_mode_interrupt_vector(0x84, &info); do_stuff(); _go32_dpmi_set_real_mode_interrupt_vector(0x84, &old_vector); _go32_dpmi_free_real_mode_callback(&info); }
#include <dpmi.h> int _go32_dpmi_allocate_real_mode_callback_retf(_go32_dpmi_seginfo *info, _go32_dpmi_registers *regs);
See DPMI Overview.
This function allocates a "real-mode callback". Fill in the
pm_offset
field of info and call this function. It will
fill in the rm_segment
and rm_offset
fields. Any time a
real-mode program calls the real-mode address, your function gets
called. The registers in effect will be stored in regs, which
should be a global, and will be passed to your function. Any changes in
regs will be reflected back into real mode. A wrapper will be
added to your function to simulate the effects of a far return, such
as the callback for the packet driver receiver.
Zero on success, nonzero on failure.
not ANSI, not POSIX
See _go32_dpmi_allocate_real_mode_callback_iret, for an example of usage.
#include <dpmi.h> int _go32_dpmi_chain_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info);
See DPMI Overview.
This function is used to chain a protected mode interrupt. It will build a suitable wrapper that will call your function and then jump to the next handler. Your function need not perform any special handling.
Warning! Because of the way DPMI works, you may not
longjmp
out of an interrupt handler or perform any system calls
(such as printf
) from within an interrupt handler.
Zero on success, nonzero on failure.
not ANSI, not POSIX
See _go32_dpmi_set_protected_mode_interrupt_vector.
#include <dpmi.h> int _go32_dpmi_free_dos_memory(_go32_dpmi_seginfo *info);
See DPMI Overview.
This function frees the conventional memory allocated by
_go32_dpmi_allocate_real_mode_memory
. You should pass it the
same structure as was used to allocate it.
Zero on success, nonzero on failure.
not ANSI, not POSIX
_go32_dpmi_seginfo info; info.size = 100; _go32_dpmi_allocate_dos_memory(&info); _go32_dpmi_free_dos_memory(&info);
#include <dpmi.h> int _go32_dpmi_free_iret_wrapper(_go32_dpmi_seginfo *info);
See DPMI Overview.
This function frees the memory used by the wrapper created by
_go32_dpmi_allocate_iret_wrapper
. You should not free a wrapper
that is still in use.
Zero on success, nonzero on failure.
not ANSI, not POSIX
See _go32_dpmi_allocate_iret_wrapper.
#include <dpmi.h> int _go32_dpmi_free_real_mode_callback(_go32_dpmi_seginfo *info);
See DPMI Overview.
This function frees the real-mode callbacks and wrappers allocated by
_go32_dpmi_allocate_real_mode_callback_iret
and
_go32_dpmi_allocate_real_mode_callback_retf
.
Zero on success, nonzero on failure.
not ANSI, not POSIX
See _go32_dpmi_allocate_real_mode_callback_iret, for an example of usage.
#include <dpmi.h int _go32_dpmi_get_free_memory_information(_go32_dpmi_meminfo *info);
This function fills in the following structure:
typedef struct { u_long available_memory; u_long available_pages; u_long available_lockable_pages; u_long linear_space; u_long unlocked_pages; u_long available_physical_pages; u_long total_physical_pages; u_long free_linear_space; u_long max_pages_in_paging_file; u_long reserved[3]; } _go32_dpmi_meminfo;
The only field that is guaranteed to have useful data is
available_memory
. Any unavailable field has -1 in it.
Zero on success, nonzero on failure.
not ANSI, not POSIX
int phys_mem_left() { _go32_dpmi_meminfo info; _go32_dpmi_get_free_memory_information(&info); if (info.available_physical_pages != -1) return info.available_physical_pages * 4096; return info.available_memory; }
#include <dpmi.h> int _go32_dpmi_get_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info);
See DPMI Overview.
This function puts the selector and offset of the specified interrupt
vector into the pm_selector
and pm_offset
fields of
info. This structure can be saved and later passed to
_go32_dpmi_get_protected_mode_interrupt_vector
to restore
a vector.
Zero on success, nonzero on failure.
not ANSI, not POSIX
See _go32_dpmi_set_protected_mode_interrupt_vector, for an example of usage.
#include <dpmi.h> int _go32_dpmi_get_real_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info);
See DPMI Overview.
This function gets the real-mode interrupt vector specified into the
address in the rm_segment
and rm_offset
fields in
info.
Zero on success, nonzero on failure.
not ANSI, not POSIX
See _go32_dpmi_allocate_real_mode_callback_iret, for an example of usage.
#include <dpmi.h> int _go32_dpmi_lock_code( void *lockaddr, unsigned long locksize);
Locks the given region of code, starting at lockaddr for locksize bytes. lockaddr is a regular pointer in your program, such as the address of a function.
0 if success, -1 if failure.
not ANSI, not POSIX
void my_handler() { } void lock_my_handler() { _go32_dpmi_lock_code(my_handler, (unsigned long)(lock_my_handler - my_handler)); }
#include <dpmi.h> int _go32_dpmi_lock_data( void *lockaddr, unsigned long locksize);
Locks the given region of data, starting at lockaddr for locksize bytes. lockaddr is a regular pointer in your program, such as the address of a variable.
0 if success, -1 if failure.
not ANSI, not POSIX
int semaphore=0; void lock_my_handler() { _go32_dpmi_lock_data(&semaphore, 4); }
#include <dpmi.h> unsigned long _go32_dpmi_remaining_physical_memory(void);
Returns the amount of physical memory that is still available in the system.
The amount in bytes.
not ANSI, not POSIX
#include <dpmi.h> unsigned long _go32_dpmi_remaining_virtual_memory(void);
Returns the amount of virtual memory that is still available in the system.
The amount in bytes.
not ANSI, not POSIX
#include <dpmi.h> int _go32_dpmi_resize_dos_memory(_go32_dpmi_seginfo *info);
See DPMI Overview.
The info structure is the same one used to allocate the memory.
Fill in a new value for size
and call this function. If there is
not enough memory to satisfy the request, the largest size is filled in
to the size
field, the memory is not resized, and this function
fails.
Zero on success, nonzero on failure.
not ANSI, not POSIX
_go32_dpmi_seginfo info; info.size = 10; _go32_dpmi_allocate_dos_memory(&info); info.size = 20; _go32_dpmi_resize_dos_memory(&info); _go32_dpmi_free_dos_memory(&info);
#include <dpmi.h> int _go32_dpmi_set_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info);
See DPMI Overview.
This function sets the protected mode interrupt vector specified to
point to the given function. The pm_offset
and
pm_selector
fields of info must be filled in
(see _go32_my_cs). The following should be noted:
longjmp
out of an interrupt handler.
printf
.
_go32_dpmi_allocate_iret_wrapper
and
_go32_dpmi_chain_protected_mode_interrupt_vector
functions can
wrap your function if you want.
_go32_my_cs
to get a selector valid for your functions.
Zero on success, nonzero on failure.
not ANSI, not POSIX
volatile int tics = 0; timer_handler() { tics++; } int main() { _go32_dpmi_seginfo old_handler, new_handler; printf("grabbing timer interrupt\n"); _go32_dpmi_get_protected_mode_interrupt_vector(8, &old_handler); new_handler.pm_offset = (int)tic_handler; new_handler.pm_selector = _go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(8, &new_handler); getkey(); printf("releasing timer interrupt\n"); _go32_dpmi_set_protected_mode_interrupt_vector(8, &old_handler); return 0; }
#include <dpmi.h> int _go32_dpmi_set_real_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info);
See DPMI Overview.
This function sets the real-mode interrupt vector specified to point to
the address in the rm_segment
and rm_offset
fields in
info.
Zero on success, nonzero on failure.
not ANSI, not POSIX
See _go32_dpmi_allocate_real_mode_callback_iret, for an example of usage.
#include <dpmi.h> int _go32_dpmi_simulate_fcall(_go32_dpmi_registers *regs);
See DPMI Overview.
This function simulates a real-mode far call to a function that returns
with a far return. The registers are set up from regs, including
CS
and IP
, which indicate the address of the call. Any
registers the function modifies are reflected in regs on return.
If SS
and SP
are both zero, a small temporary stack is
used when in real mode. If not, they are used as is. It's a good
idea to use memset
to initialize the register structure before
using it.
Zero on success, nonzero on failure.
not ANSI, not POSIX
_go32_dpmi_registers r; r.x.ax = 47; r.x.cs = some_segment; r.x.ip = some_offset; r.x.ss = r.x.sp = 0; _go32_dpmi_simulate_fcall(&r); printf("returns %d\n", r.x.ax);
#include <dpmi.h> int _go32_dpmi_simulate_fcall_iret(_go32_dpmi_registers *regs);
See DPMI Overview.
This function simulates a real-mode far call to a function that returns
with an iret
instruction. The registers are set up from
regs, including CS
and IP
, which indicate the
address of the call. Any registers the function modifies are reflected
in regs on return.
If SS
and SP
are both zero, a small temporary stack is
used when in real mode. If not, they are used as is. It's a good
idea to use memset
to initialize the register structure before
using it.
Zero on success, nonzero on failure.
not ANSI, not POSIX
_go32_dpmi_registers r; r.x.ax = 47; r.x.cs = some_segment; r.x.ip = some_offset; r.x.ss = r.x.sp = 0; _go32_dpmi_simulate_fcall_iret(&r); printf("returns %d\n", r.x.ax);
#include <dpmi.h> int _go32_dpmi_simulate_int(int vector, _go32_dpmi_registers *regs);
See DPMI Overview.
This function simulates a real-mode interrup. The registers are set up from
regs, including CS
and IP
, which indicate the
address of the call. Any registers the function modifies are reflected
in regs on return.
If SS
and SP
are both zero, a small temporary stack is
used when in real mode. If not, they are used as is. It's a good
idea to use memset
to initialize the register structure before
using it.
Zero on success, nonzero on failure.
not ANSI, not POSIX
_go32_dpmi_registers r; r.h.ah = 0x08; r.h.dl = 0x80; /* drive C: */ r.x.ss = r.x.sp = 0; _go32_dpmi_simulate_int(0x13, &r); printf("disk is %d cyl, %d head, %d sect\n", r.h.ch | ((r.x.cl<<2)&0x300), r.h.dh, r.h.cl & 0x3f));
#include <go32.h> extern __Go32_Info_Block _go32_info_block;
The go32 information block is a mechanism for go32
to pass
information to the application. Some of this information is generally
useful, such as the pid or the transfer buffer, while some is used
internally to libc.a
only.
The structure has this format:
typedef struct { unsigned long size_of_this_structure_in_bytes; unsigned long linear_address_of_primary_screen; unsigned long linear_address_of_secondary_screen; unsigned long linear_address_of_transfer_buffer; unsigned long size_of_transfer_buffer; unsigned long pid; unsigned char master_interrupt_controller_base; unsigned char slave_interrupt_controller_base; unsigned short selector_for_linear_memory; unsigned long linear_address_of_stub_info_structure; unsigned long linear_address_of_original_psp; unsigned short run_mode; unsigned short run_mode_info; } Go32_Info_Block;
The linear address fields provide values that are suitable for
dosmemget
, dosmemput
, and movedata
. The
selector_for_linear_memory is suitable for <sys/farptr.h>
selector parameters.
Due to the length of these fields, and their popularity, the following macros are available:
_dos_ds
__tb
The run_mode
field indicates the mode that the program is running
in. The following modes are defined:
_GO32_RUN_MODE_UNDEF
_GO32_RUN_MODE_RAW
_GO32_RUN_MODE_XMS
_GO32_RUN_MODE_VCPI
emm386
or qemm
) is
managing both the CPU and the memory.
_GO32_RUN_MODE_DPMI
qdpmi
or Windows) is
managing both the CPU and memory. Programs may rely on this value
to determine if it is safe to use DPMI 0.9 functions.
If this value is set, the run_mode_info
field has the DPMI
specification version, in hex, shifted eight bits. For example, DPMI
0.9 has 0x005A in the run_mode_info
field.
Note that the program should not assume that the value will be one of the listed values. If the program is running with an extender that provides some other mode (say, a newly released extender) then the program should be able to handle that case gracefully.
not ANSI, not POSIX
dosmemget(_go32_info_block.linear_address_of_primary_screen, 80*25*2, buf);
#include <dpmi.h> extern unsigned long _go32_interrupt_stack_size;
The default size of the interrupt handler's stack. Defaults to 32k.
not ANSI, not POSIX
#include <go32.h> u_short _go32_my_cs();
Returns the current CS
. This is useful for setting up interrupt
vectors and such.
CS
not ANSI, not POSIX
#include <go32.h> u_short _go32_my_ds();
Returns the current DS
. This is useful for moving memory
and such.
DS
not ANSI, not POSIX
#include <go32.h> u_short _go32_my_ss();
Returns the current SS
. This is useful for moving memory
and such.
SS
not ANSI, not POSIX
#include <dpmi.h> extern unsigned long _go32_rmcb_stack_size;
The default size of the real mode callback handler's stack. Defaults to 32k.
not ANSI, not POSIX
#include <go32.h> void _go32_want_ctrl_break(int yes);
This function tells go32 whether or not it wants Ctrl-Break to be
an exception or passed to the application. If you pass a nonzero value
for yes, pressing Ctrl-Break will set a flag that can be
detected with _go32_was_ctrl_break_hit
(see _go32_was_ctrl_break_hit). If you pass zero for yes, when
you press Ctrl-Break the program will be terminated.
Note that if you call _go32_was_ctrl_break_hit
, this function
automatically gets called to ask for Ctrl-Break events.
None.
not ANSI, not POSIX
_g32_want_ctrl_break(1); do_something_long(); _g32_want_ctrl_break(0);
#include <go32.h> unsigned _go32_was_ctrl_break_hit(void);
This function returns the number of times that Ctrl-Break was hit
since the last call to this function or _go32_want_ctrl_break
(see _go32_want_ctrl_break).
Zero if Ctrl-Break hasn't been hit, nonzero to indicate how many times if it has been hit.
Note that _go32_want_ctrl_break
is automatically called to
request these events, so you don't have to set up for this call.
not ANSI, not POSIX
while (!_go32_was_ctrl_break_hit()) do_something();
#include <conio.h> void gotoxy(int x, int y);
Move the cursor to row y, column x. The upper left corner of the current window is (1,1).
not ANSI, not POSIX
#include <conio.h> void gppconio_init(void);
Initialize the screen. This is called automatically at program start-up
if you use any of the conio
functions, but there may be
times when you need to call it again, typically after calling some video
BIOS function which affects screen parameters.
not ANSI, not POSIX
#include <mntent.h> char *hasmntopt(const struct mntent *mnt, const char *opt);
This function scans the mnt_opts
field of the mntent
structure pointed to by mnt for a substring that matches
opt. See getmntent.
This function returns the address of the substring if a match is found,
or NULL
otherwise.
not ANSI, not POSIX
#include <conio.h> void highvideo(void);
Causes any new characters put on the screen to be bright.
not ANSI, not POSIX
#include <netinet/in.h> unsigned long htonl(unsigned long val);
This function converts from host formatted longs to network formatted longs. For the i386 and higher processors, this means that the bytes are swapped from 1234 order to 4321 order.
The network-order value.
not ANSI, not POSIX
packet.ipaddr = htonl(ip);
#include <netinet/in.h> unsigned short htons(unsigned short val);
This function converts from host formatted shorts to network formatted shorts. For the i386 and higher processors, this means that the bytes are swapped from 12 order to 21 order.
The network-order value.
not ANSI, not POSIX
tcp.port = htons(port);
#include <math.h> double hypot(double x, double y);
This function computes sqrt(x*x + y*y)
,
the length of a hypotenuse of a right triangle whose shorter sides are
x and y. In other words, it computes the Euclidean distance
between the points (0,0)
and (x,y)
. Since the
computation is done in extended precision, there is no danger of
overflow or underflow when squaring the arguments, whereas direct
computation of sqrt(x*x + y*y)
could
cause overflow or underflow for extreme (very large or very small)
values of x and y.
The value of sqrt(x*x + y*y)
. If both
arguments are finite, but the result is so large that it would overflow
a double
, the return value is Inf
, and errno
is set
to ERANGE
. If one of the arguments is Inf
, the return
value is Inf
and the value of errno
is left unchanged. If
one of the arguments is NaN
, the return value is NaN
and
errno
is set to EDOM
.
not ANSI, not POSIX
#include <pc.h> unsigned char inb(unsigned short _port);
Calls inportb. Provided only for compatibility.
not ANSI, not POSIX
#include <strings.h> char *index(const char *string, int ch);
Returns a pointer to the first occurrence of ch in string.
Note that the NULL
character counts, so if you pass zero as
ch you'll get a pointer to the end of the string back.
A pointer to the character, or NULL
if it wasn't found.
not ANSI, not POSIX
if (index(path, '*')) do_wildcards(path);
#include <stdlib.h> char *initstate(unsigned seed, char *arg_state, int n);
Initializes the random number generator (see random) with pointer
arg_state to array of n bytes, then calls srandom
with
seed.
Pointer to old state information.
not ANSI, not POSIX
#include <pc.h> unsigned char inp(unsigned short _port);
Calls inportb. Provided only for compatibility.
not ANSI, not POSIX
#include <pc.h> unsigned char inportb(unsigned short _port);
Read a single 8-bit I/O port.
This function is provided as an inline assembler macro, and will be optimized down to a single opcode when you optimize your program.
The value returned through the port.
not ANSI, not POSIX
#include <pc.h> unsigned long inportl(unsigned short _port);
This function reads a single 32-bit I/O port.
This function is provided as an inline assembler macro, and will be optimized down to a single opcode when you optimize your program.
The value returned from the port.
not ANSI, not POSIX
#include <pc.h> void inportsb(unsigned short _port, unsigned char *_buf, unsigned _len);
Reads the 8-bit _port _len times, and stores the bytes in buf.
not ANSI, not POSIX
#include <pc.h> void inportsl(unsigned short _port, unsigned long *_buf, unsigned _len);
Reads the 32-bit _port _len times, and stores the bytes in buf.
not ANSI, not POSIX
#include <pc.h> void inportsw(unsigned short _port, unsigned short *_buf, unsigned _len);
Reads the 16-bit _port _len times, and stores the bytes in buf.
not ANSI, not POSIX
#include <pc.h> unsigned short inportw(unsigned short _port);
Read a single 16-bit I/O port.
This function is provided as an inline assembler macro, and will be optimized down to a single opcode when you optimize your program.
The value returned through the port.
not ANSI, not POSIX
#include <pc.h> unsigned short inpw(unsigned short _port);
Calls inportw. Provided only for compatibility.
not ANSI, not POSIX
#include <conio.h> void insline(void);
A blank line is inserted at the current cursor position. The previous line and lines below it scroll down.
not ANSI, not POSIX
#include <search.h> void insque(struct qelem *elem, struct qelem *pred);
This function manipulates queues built from doubly linked lists. Each element
in the queue must be in the form of struct qelem
which is defined
thus:
struct qelem { struct qelem *q_forw; struct qelem *q_back; char q_data[0]; }
This function inserts elem in a queue immediately after pred.
None.
not ANSI, not POSIX
#include <dos.h> int int386(int ivec, union REGS *in, union REGS *out);
This function is equal to int86
function.
See int86, for further description.
The returned value of EAX
.
not ANSI, not POSIX
#include <dos.h> int int386x(int ivec, union REGS *in, union REGS *out, struct SREGS *seg);
This function is equal to int86x
.
See int86, for further description.
The value of EAX
is returned.
not ANSI, not POSIX
#include <dos.h> int int86(int ivec, union REGS *in, union REGS *out);
The union REGS
is defined by <dos.h>
as follows:
struct DWORDREGS { unsigned long edi; unsigned long esi; unsigned long ebp; unsigned long cflag; unsigned long ebx; unsigned long edx; unsigned long ecx; unsigned long eax; unsigned short eflags; }; struct DWORDREGS_W { unsigned long di; unsigned long si; unsigned long bp; unsigned long cflag; unsigned long bx; unsigned long dx; unsigned long cx; unsigned long ax; unsigned short flags; }; struct WORDREGS { unsigned short di, _upper_di; unsigned short si, _upper_si; unsigned short bp, _upper_bp; unsigned short cflag, _upper_cflag; unsigned short bx, _upper_bx; unsigned short dx, _upper_dx; unsigned short cx, _upper_cx; unsigned short ax, _upper_ax; unsigned short flags; }; struct BYTEREGS { unsigned short di, _upper_di; unsigned short si, _upper_si; unsigned short bp, _upper_bp; unsigned long cflag; unsigned char bl; unsigned char bh; unsigned short _upper_bx; unsigned char dl; unsigned char dh; unsigned short _upper_dx; unsigned char cl; unsigned char ch; unsigned short _upper_cx; unsigned char al; unsigned char ah; unsigned short _upper_ax; unsigned short flags; }; union REGS { struct DWORDREGS d; #ifdef _NAIVE_DOS_REGS struct WORDREGS x; #else #ifdef _BORLAND_DOS_REGS struct DWORDREGS x; #else struct DWORDREGS_W x; #endif #endif struct WORDREGS w; struct BYTEREGS h; };
Note: The .x.
branch is a problem generator. Most programs expect
the .x.
branch to have e.g. ".x.ax
" members, and that
they are 16-bit. If you know you want 32-bit values, use the
.d.eax
members. If you know you want 16-bit values, use the
.w.ax
members. The .x.
members behave according to
#defines
, as follows:
default
#define
, the .x.
branch has
"ax
" members and is 32-bit. This is compatible with previous
versions of djgpp.
_NAIVE_DOS_REGS
.x.ax
, but they are 16-bit. This is
probably what most programs ported from 16-bit dos compilers will
want.
_BORLAND_DOS_REGS
.x.eax
which are 32-bit. This is
compatible with Borland's 32-bit compilers.
This function simulates a software interrupt. Note that, unlike the
__dpmi_int
function, requests that go through int86
and similar functions are specially processed to make them suitable for
invoking real-mode interrupts from protected-mode programs. For example,
if a particular routine takes a pointer in BX
, int86
expects
you to put a (protected-mode) pointer in EBX
. Therefore,
int86
should have specific support for every interrupt and function
you invoke this way. Currently, it supports only a subset of all
available interrupts and functions:
1) All functions of any interrupt which expects only scalar arguments registers (i.e., no pointers to buffers).
2) In addition, the following functions of interrupt 21h are supported: 9, 39h, 3Ah, 3Bh, 3Ch, 3Dh, 3Fh, 40h, 41h, 43h, 47h, 56h.
When the interrupt is invoked, the CPU registers are copied from in. After the interrupt, the CPU registers are copied to out.
This function is just like int86x
(see int86x) except that
suitable default values are used for the segment registers.
See also int86x, intdos, and bdos.
The returned value of EAX
.
not ANSI, not POSIX
union REGS r; r.x.ax = 0x0100; r.h.dl = 'c'; int86(0x21, &r, &r);
#include <dos.h> int int86x(int ivec, union REGS *in, union REGS *out, struct SREGS *seg);
This function is just like int86
(see int86) except that
values you pass in SREGS are used for the segment registers instead
of the defaults.
See also int86, intdos, and bdos.
The value of EAX
is returned.
not ANSI, not POSIX
union REGS r; struct SREGS s; r.h.ah = 0x31; r.h.dl = 'c'; r.x.si = si_val; s.ds = ds_val; int86x(0x21, &r, &r, &s);
#include <dos.h> int intdos(union REGS *in, union REGS *out);
This function is just like int86
(see int86x) except that
the interrupt vector is 0x21.
EAX
not ANSI, not POSIX
#include <dos.h> int intdosx(union REGS *in, union REGS *out, struct SREGS *s);
This function is just like int86x
(see int86x) except that the
interrupt vector is 0x21.
EAX
not ANSI, not POSIX
#include <conio.h> void intensevideo(void);
Bit 7 (MSB
) of the character attribute byte has two possible
effects on EGA and VGA displays: it can either make the character blink
or change the background color to bright (thus allowing for 16
background colors as opposed to the usual 8). This function sets that
bit to display bright background colors. After a call to this function,
every character written to the screen with bit 7 of the attribute byte
set, will have a bright background color. The companion function
blinkvideo
(see blinkvideo) has the opposite effect.
Note that there is no BIOS function to get the current status of this
bit, but bit 5 of the byte at 0040h:0065h
in the BIOS area
indicates the current state: if it's 1 (the default), blinking
characters will be displayed.
not ANSI, not POSIX
ino_t _invent_inode(const char *name, unsigned time_stamp, unsigned long fsize)
This invents an inode number for those files which don't have valid DOS cluster number. These could be:
/dev/null
or file system extensions
(see File System Extensions)
To ensure proper operation of this function, you must call it with a filename
in some canonical form. E.g., with a name returned by truename()
(see _truename), or that returned by _fixpath()
(see _fixpath).
The point here is that the entire program must abide by these
conventions through its operation, or else you risk getting different inode
numbers for the same file.
0 on error, otherwise the invented inode number for the file
not ANSI, not POSIX
The DOSish version of ioctl
performs an
interrupt 0x21, function 0x44. It takes care of supplying transfer buffers in
low address regions, if they are needed. For an exhaustive description of the
various commands and subcommands, see Ralf Brown's interrupt list.
It is highly recommended to use only the DOS_*
functions listed in sys/ioctl.h
.
#include <sys/ioctl.h> int ioctl(int fd, int cmd, ... );
The parameter fd
must refer to a file descriptor for character device
functions, or the number of a block device (usually current=0, A:=1, ...).
The following constants can be used for the cmd
parameter:
DOS_GETDEVDATA
DX
.
The call to ioctl
should look like this:
int ret_val = ioctl (fd, DOS_GETDEVDATA);
For another way of achieving the same effect, see _get_dev_info.
DOS_SETDEVDATA
DX
or -1. The call to ioctl
should look like this:
int ret_val = ioctl (fd, DOS_SETDEVDATA, 0, dev_info);
DOS_RCVDATA
cmd
must follow the
number of requested bytes to read and a pointer to a buffer. Returns the number
of bytes actually read or -1 on error. The call to ioctl
should
look like this:
unsigned char buf[bytes_to_read]; int ret_val = ioctl (fd, DOS_RCVDATA, bytes_to_read, &buf);
DOS_SNDDATA
cmd
must follow the
number of bytes to write and a pointer to a buffer holding the data.
Returns the number of bytes actually written. An example of a call:
unsigned char buf[bytes_to_write]; int ret_val = ioctl (fd, DOS_SNDDATA, bytes_to_write, &buf);
DOS_RCVCTLDATA
DOS_RCVDATA
.
DOS_SNDCTLDATA
DOS_SNDDATA
.
DOS_CHKINSTAT
0xff
if file is ready. Here's an example of how to call:
int ret_val = ioctl (fd, DOS_CHKINSTAT);
A more portable way of doing this is by calling select
.
See select.
DOS_CHKOUTSTAT
0xff
if file is ready. select
(see select) is
another, more portable way of doing the same.
DOS_ISCHANGEABLE
int ret_val = ioctl (fd, DOS_ISCHANGEABLE);
DOS_ISREDIRBLK
_is_remote_drive
(see _is_remote_drive) is another way of
returning the same info.
DOS_ISREDIRHND
DOS_SETRETRY
int ret_val = ioctl (fd, DOS_SETRETRY, pause_between_retries, max_retries);
DOS_GENCHARREQ
int ret_val = ioctl (fd, DOS_GENCHARREQ, category_and_function, ¶m_block, si_value, di_value, param_block_size);
Refer to Ralf Brown's Interrupt List for the details about each function
and relevant parameter block layout.
DOS_GENBLKREQ
int ret_val = ioctl (drive_no, DOS_GENBLKREQ, category_and_function, ¶m_block, si_value, di_value, param_block_size);
Note that instead of the handle, the first argument is the disk drive
number (0 = default, 1 = A:, etc.).
DOS_GLDRVMAP
int ret_val = ioctl (drive_no, DOS_GLDRVMAP);
will return 0 if the block device has only one logical drive assigned,
or a number in the range 1..26 which is the last drive numer used to
reference that drive (1 = A:, etc.). Thus, on a machine which has a
single floppy drive, calling ioctl (1, DOS_GLDRVMAP);
will return
2 if the floppy was last refered to as B:. This function and the next
one can be used together to prevent DOS from popping the ugly prompt
saying "Insert diskette for drive B: and press any key when ready".
DOS_SLDRVMAP
ioctl (1, DOS_SLDRVMAP);
will cause drive A: to be mapped to drive B:.
DOS_QGIOCTLCAPH
int ret_val = ioctl (fd, DOS_QGIOCTLCAPH, category_and_function);
This will return zero if the specified IOCTL function is supported, 1 if
not.
DOS_QGIOCTLCAPD
If your specific device driver requires different commands, they must be or'ed
together with the flags listed in <sys/ioctl.h>
to tell the drive about
transfer buffers and what to return.
See description above.
The bits of the device information word have the following meaning:\\ Character device:
13 output until busy supported
11 driver supports OPEN/CLOSE calls
7 set (indicates device)
6 EOF on input
5 raw (binary) mode
4 device is special (uses INT 29)
3 clock device
2 NUL device
1 standard output
0 standard input
Disk file:
14 don't set file date/time on closing (DOS 3.0+)
11 media not removable
8 (DOS 4 only) generate INT 24 if no disk space on write or read past end of file
7 clear (indicates file)
6 file has not been written
5-0 drive number (0 = A:)
#include <sys/ioctl.h> int main(int argc, char **argv){ char buf[6]; short *s; open(fd,"EMMQXXX0",O_RDONLY); mybuf[0] = '\0'; s = mybuf; ioctl(fd,DOS_SNDDATA,6, (int) &mybuf); if(*s ==0x25 )printf("EMM386 >= 4.45\n"); mybuf[0]='\x02'; ioctl(fd,DOS_SNDDATA,2,(int )&mybuf); printf("EMM Version %d.%d\n",(int )mybuf[0],(int) mybuf[1]); close(fd); }
ioctl
performs low level calls to communicate with device drivers. As
there are lots of different device drivers, no really general description is
possible.
The DJGPP version tries to cope with two different flavors of ioctl
,
a DOSish and a UNIXish way. To distinguish between DOS-like and UNIX-like
calls, all valid DOS commands have all 3 MSB set to 0, the UNIX command have
at least one of the 3 MSB set to 1.
The UNIX version first checks if an FSE handler is associated to the file
descriptor. If so, it calls the handler in the usual way File System Extensions. Otherwise it sets errno to ENOTTY
and returns -1.
As this part is still under development, it should not be used exhaustively.
#include <sys/stat.h> int _is_executable(const char *path, int fhandle, const char *extension);
This function determines if a file is executable under DOS/DJGPP
environment. The file may be given either by its path or its file
handle fhandle. If extension is non-NULL and non-empty, it
is used first to look up in a list of known extensions which determine
whether the file is executable. (If the _STAT_EXEC_EXT
bit of
the _djstat_flags
global variable (see _djstat_flags) is not
set, this step is skipped.) If extension is unavailable or not
enough to determine the result, the first 2 bytes of the file are
checked to contain one of the known magic numbers identifying the
file as executable. If the file's 2 first bytes need to be read but the
read fails, 0 is returned and errno is set. (The file is only searched
for magic number if the _STAT_EXEC_MAGIC
bit of the
_djstat_flags
variable is set.)
Note that if _STAT_EXEC_MAGIC
is set, but _STAT_EXEC_EXT
is not, some files which shouldn't be flagged as executables (e.g., COFF
*.o
object files) will have their execute bit set, because they
have the magic number signature at their beginning. Therefore, only use
the above combination if you want to debug the list of extensions
provided in is_exec.c
file from the library sources.
If the file passed by its handle was open as write-only, and the extension alone isn't enough to determine whether the file is executable, then this function returns 0, because it cannot look at the magic number.
This function is used internally by f?stat
; you are not supposed
to call it directly.
1 for executable file, 0 otherwise (including in case of errors in accessing the file).
not ANSI, not POSIX
int _is_remote_drive(int drv);
Given the drive number in drv (A: = 0, B: = 1, etc.), this function returns non-zero if the drive is treated by DOS as a remote (networked) drive, or zero otherwise. It does so by calling subfunction 09h of the DOS IOCTL function (interrupt 21h, AX=4409h) and looking at bit 12 of the device attribute word returned in the DX register.
Note that DOS treats CD-ROM drives as remote.
Zero for local drives, non-zero for remote and CD-ROM drives.
not ANSI, not POSIX
int _is_remote_handle(int fhandle);
Given the file handle of an open file in fhandle, this function returns non-zero if the drive where that file resides is treated by DOS as a remote (networked) drive, or zero otherwise. It does so by calling subfunction 0Ah of the DOS IOCTL function (interrupt 21h, AX=440Ah) and looking at bit 15 of the device attribute word returned in the DX register.
Note that DOS treats CD-ROM drives as remote.
Zero for files on local drives, non-zero for files on remote and CD-ROM drives.
not ANSI, not POSIX
#include <ctype.h> int isalnum(int c);
Tells if c is any letter or digit.
Nonzero if c is a letter or digit, else zero.
ANSI, POSIX
#include <ctype.h> int isalpha(int c);
Tells if c is a letter.
Nonzero if c is a letter, else zero.
ANSI, POSIX
#include <ctype.h> int isascii(int c);
Tells if c is an ASCII character (0x00 to 0x7f).
Nonzero if c is ASCII, else zero.
not ANSI, not POSIX
#include <unistd.h> int isatty(int fd);
Tells if the file descriptor refers to a terminal device or not.
Nonzero if fd is a terminal device, zero otherwise.
not ANSI, POSIX
if (isatty(1)) fflush(stdout);
#include <ctype.h> int iscntrl(int c);
Tells if c is a control character.
Nonzero if c is a control character, else zero.
ANSI, POSIX
#include <ctype.h> int isdigit(int c);
Tells if c is a digit.
Nonzero if c is a digit, else zero.
ANSI, POSIX
#include <ctype.h> int isgraph(int c);
Tells if c is a visible printing character. Space is not included.
Nonzero if c is a visible printing character, else zero.
ANSI, POSIX
#include <ctype.h> int islower(int c);
Tells if c is lower case or not.
Nonzero if c is lower case, else zero.
ANSI, POSIX
#include <ctype.h> int isprint(int c);
Tells if c is a printing character, which includes the space character.
Nonzero if c is a printing character, else zero.
ANSI, POSIX
#include <ctype.h> int ispunct(int c);
Tells if c is any printing character except space and those
indicated by isalnum
.
Nonzero if c is punctuation, else zero.
ANSI, POSIX
#include <ctype.h> int isspace(int c);
Tells if c is whitespace, that is, carriage return, newline, form feed, tab, vertical tab, or space.
Nonzero if c is whitespace, else zero.
ANSI, POSIX
#include <ctype.h> int isupper(int c);
Tells if c is an upper case character or not.
Nonzero if c is upper case, else zero.
ANSI, POSIX
#include <ctype.h> int isxdigit(int c);
Tells if c is a valid hexadecimal digit or not. This includes
[0-9a-fA-F]
.
Nonzero if c is a hex digit, else zero.
ANSI, POSIX
#include <stdlib.h> char * itoa(int value, char *string, int radix)
This function converts its argument value into a null-terminated
character string using radix as the base of the number system. The
resulting string with a length of upto 33 bytes (including the optional
sign and the terminating NULL
is put into the buffer whose address
is given by string. For radixes other than 10, value is
treated as an unsigned int (i.e., the sign bit is not interpreted as
such). The argument radix should specify the base, between 2 and
36, in which the string reprsentation of value is requested.
A pointer to string.
not ANSI, not POSIX
char binary_str[33]; (void)itoa(num, binary_str, 2);
#include <pc.h> int kbhit(void);
If the user has hit a key, this function will detect it. This function is very fast when there is no key waiting, so it may be used inside loops as needed.
If you test shift/alt/ctrl status with bios calls (e.g., using
bioskey (2)
or bioskey (0x12)
) then you should also use
bios calls for testing for keys. This can be done with by
bioskey (1)
or bioskey (0x11)
. Failing to do so can
cause trouble in multitasking environments like DESQview/X.
Nonzero if a key has been hit, else zero.
not ANSI, not POSIX
while (!kbhit()) do_stuff();
#include <signal.h> int kill(pid_t _pid, int _sig);
If _pid is the current getpid()
, the given _sig is
raised with raise.
-1 on error, else zero.
not ANSI, POSIX
#include <stdlib.h> long labs(long x);
This function takes the absolute value of x. See abs.
|x|
ANSI, POSIX
#include <math.h> double ldexp(double val, int exp);
This function computes val*2^exp.
val*2^exp. ldexp(0., exp)
returns 0 for all
values of exp
, without setting errno
. For non-zero values
of val, errno
is set to ERANGE
if the result cannot
be accurately represented by a double
, and the return value is
then the nearest representable double
(possibly, an Inf
).
If val is a NaN
or Inf
, the return value is
NaN
and errno
is set to EDOM
.
ANSI, POSIX
ldexp(3.5,4) == 3.5 * (2^4) == 56.0
#include <stdlib.h> ldiv_t ldiv(long numerator, long denominator);
Returns the quotient and remainder of the division numerator divided by denominator. The return type is as follows:
typedef struct { long quot; long rem; } ldiv_t;
The results of the division are returned.
ANSI, POSIX
ldiv_t l = ldiv(42, 3); printf("42 = %ld x 3 + %ld\n", l.quot, l.rem); ldiv(+40, +3) = { +13, +1 } ldiv(+40, -3) = { -13, -1 } ldiv(-40, +3) = { -13, -1 } ldiv(-40, -3) = { +13, -1 }
#include <fcntl.h> char * _lfn_gen_short_fname (const char *long_fname, char *short_fname);
This function generates a short (8+3) filename alias for the long filename pointed to by long_fname and puts it into the buffer pointed to by short_fname. It uses the same algorithm that Windows 9x uses, with the exception that the returned short name will never have a numeric tail, because this function doesn't check the directory to see whether the generated short name will collide with any other file in the directory. Note that long_fname must contain only the name part of a file; elements of a full pathname (like : or / are not allowed (they will cause the function to fail). short_fname will be returned upper-cased, since that is how 8+3 filenames are stored in directory entries.
When the LFN API is not supported (see _use_lfn), the function simply converts up to 12 characters of long_fname to upper-case and returns that. It will do the same if long_fname includes any characters illegal in a filename.
You might need to call this function if you want to know whether a given
filename is valid on MSDOS: if a case-sensitive string comparison
function such as strcmp
(see strcmp) returns a 0 when it
compares the original long filename with the short one returned by
_lfn_gen_short_fname
, then the filename is a valid DOS name.
(Note that if long_fname is in lower case, it might not compare
equal with short_fname because of the case difference.)
The function returns a pointer to short_fname.
not ANSI, not POSIX
#include <stdio.h> #include <string.h> #include <fcntl.h> int dos_check (char *fname) { char fshort[13]; int retval; if (stricmp (_lfn_gen_short_fname (fname, fshort), fname) == 0) { printf ("%s is a valid MSDOS 8+3 filename\n", fname); retval = 1; } else { printf ("%s will have to be changed for MSDOS\n", fname); retval = 0; } return retval; }
#include <fcntl.h> char _lfn_get_ftime (int fhandle, int flag);
This function returns creation and access time for files that reside on a filesystem which supports long filenames (such as Windows 95). Files which reside on native FAT filesystems will cause this function to fail. The fhandle parameter is the file handle as returned by one of the functions which open or create files. The flag parameter determines which time (creation or access) is returned. It can be set to one of the following:
_LFN_ATIME
_lfn_get_ftime
to return the time when the file was last
accessed. (Currently, it actually only returns the date of last
access; the time bits are all zeroed.)
_LFN_CTIME
_lfn_get_ftime
to return the time when the file was
created. Note that if the file was created by a program which doesn't
support long filenames, this time will be zero.
The file time stamp, as a packed unsigned int value:
Bits 0-4
Bits 5-10
Bits 11-15
Bits 16-20
Bits 21-24
Bits 25-31
If the underlying system calls fail, the function will return 0 and set
errno
to an appropriate value.
not ANSI, not POSIX
unsigned file_stamp = _lfn_get_ftime (handle, _LFN_CTIME);
#include <libc/ttyprvt.h> void __libc_termios_init (void);
This function sets read/write hooks for the termios emulation and import parameters. Currently importing parameters is not supported, the emulation is resolved by only internal(static) parameters. Note that this function is called by tcXXX function automatically.
not ANSI, not POSIX
#include <libm/math.h> enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix}; #define _LIB_VERSION_TYPE enum fdversion #define _LIB_VERSION _fdlib_version extern _LIB_VERSION_TYPE _LIB_VERSION; #define _IEEE_ fdlibm_ieee #define _SVID_ fdlibm_svid #define _XOPEN_ fdlibm_xopen #define _POSIX_ fdlibm_posix _LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
The alternate math library, libm.a
, originally written by
Cygnus support, provides versions of mathematical functions which
comply to several different standards of behavior in abnormal cases, and
are sometimes more accurate than those included in the default
libc.a
library, in particular when elaborate argument reduction
is required to avoid precision loss. Functions in libm.a
allow
to create programs with well-defined and standard-compliant behavior
when numerical errors occur, and provide the application with a means to
control their behavior in abnormal cases via the matherr
callback. They almost never rely on the features specific to the x87
FPU, and are thus slower and sometimes slightly less accurate than the
functions from libc.a
.
In contrast, the functions in the default libc.a
library are
written for maximum speed and exploitation of the x87 FPU features, do
not call matherr
, and are therefore much faster and sometimes
more accurate (due to the extended 80-bit precision with which the x87
FPU carries its calculations).
Another aspect of differences between functions in libc.a
and in
libm.a
is the value returned when the result overflows a
double
. The functions from libc.a
always return a
suitably signed infinity, Inf
, whereas for functions from
libm.a
an application can arrange for a large but finite value to
be returned. Getting finite return values might be important in certain
kinds of mathematical computations where the special rules defined for
infinities (e.g., Inf + a = Inf) might be inappropriate.
Refer to Math, for detailed
documentation of the individual functions from libm.a
. This
section explains the general setup of using those functions from DJGPP
programs.
To use the alternate math library with your program, you need to do the following:
<libm/math.h>
. Alternatively, you can include
<math.h>
as usual and compile with -D_USE_LIBM_MATH_H
option to gcc
, which will cause it to use libm/math.h
instead of the default math.h
. (The second possibility leaves
the source ANSI-compliant.)
_fdlib_version
to a value other than the
default _IEEE_
. The possible values are listed and explained
below.
main
function, set the FPU to a
predictable state by calling _clear87
(see _clear87) and
_fpreset
(see _fpreset) library functions. (Another
possibility is to make these calls in a function declared with
__attribute__((constructor))
, so it will be called before
main
.)
libm.a
library, e.g. by specifying
-lm
on the link command line.
The functions in libm.a
can emulate different standards. You can
select to which standard your program will comply by setting the global
variable _fdlib_version
(or the macro _LIB_VERSION
which
evaluates to it) to one of the values below. This will only affect the
behavior of the math functions when an error is signaled by the FPU.
_IEEE_
errno
. If the result
overflows, an Inf
is returned. This version gives the fastest
code.
_POSIX_
errno
to the
appropriate value (EDOM
or ERANGE
) and return to the
caller, without calling the matherr
function (see matherr).
If the result overflows, an Inf
is returned. This version should
be used for maximum POSIX- and ANSI-compliance.
_SVID_
matherr
function (see matherr), which can be customized to
the specific application needs. If matherr
returns zero, a
message is printed to the standard error stream which states the name of
the function that generated the error and the error type, and
errno
is set. If matherr
returns non-zero, there will be
no message and errno
will be left unaltered. If the result
overflows, this version returns HUGE
, a large but finite value
defined by libm/math.h
.
_XOPEN_
_SVID_
, but it never prints an error message, even if
matherr
returns zero, and Inf
us returned when a result
overflows.
not ANSI, not POSIX
/* Testing errno == EDOM after sqrt(-1). !!! MUST compile with -lm !!! */ #include <assert.h> #include <errno.h> #include <stdio.h> #include <libm/math.h> /* or #define _USE_LIBM_MATH_H and #include <math.h> */ #include <float.h> /* Setting _LIB_VERSION to anything but _IEEE_ will turn on errno handling. */ _LIB_VERSION_TYPE _LIB_VERSION = _POSIX_; int main (void) { /* Reset the FPU (possible previous FP problems). */ _clear87 (); _fpreset (); /* Run the test. */ errno = 0; assert(errno == 0); sqrt(-1.0); assert(errno == EDOM); /* this line should NOT cause the assertion to fail */ return(0); }
#include <unistd.h> int link(const char *exists, const char *new);
Because of limitations of MS-DOS, this function doesn't really link two
files together. However, it simulates a real link
by copying the
file at exists to new.
Zero on success, nonzero on failure.
not ANSI, POSIX
link("foo.c", "foo.bak");
#include <stdlib.h> long long llabs(long long x);
This function takes the absolute value of x. See abs.
|x|
not ANSI, not POSIX
#include <stdlib.h> lldiv_t lldiv(long long numerator, long long denominator);
Returns the quotient and remainder of the division numerator divided by denominator. The return type is as follows:
typedef struct { long long quot; long long rem; } lldiv_t;
The results of the division are returned.
not ANSI, not POSIX
lldiv_t l = lldiv(42, 3); printf("42 = %lld x 3 + %lld\n", l.quot, l.rem); lldiv(+40, +3) = { +13, +1 } lldiv(+40, -3) = { -13, -1 } lldiv(-40, +3) = { -13, -1 } lldiv(-40, -3) = { +13, -1 }
#include <debug/dbgcom.h> extern NPX npx; void load_npx (void);
This function restores the state of the x87 numeric processor from the
data saved in the external variable npx
. This variable is a
structure defined as follows in the header debug/dbgcom.h
:
typedef struct { unsigned short sig0; unsigned short sig1; unsigned short sig2; unsigned short sig3; unsigned short exponent:15; unsigned short sign:1; } NPXREG; typedef struct { unsigned long control; unsigned long status; unsigned long tag; unsigned long eip; unsigned long cs; unsigned long dataptr; unsigned long datasel; NPXREG reg[8]; long double st[8]; char st_valid[8]; long double mmx[8]; char in_mmx_mode; char top; } NPX;
load_npx
should be called immediately after run_child
(see run_child) is called to begin or resume the debugged program,
and provided that a call to save_npx
was issued before
run_child
was called. See save_npx.
not ANSI, not POSIX
save_npx (); run_child (); load_npx ();
#include <locale.h> struct lconv *localeconv(void);
This function returns a pointer to a static structure that contains information about the current locale. The structure contains these fields:
char *currency_symbol
char *decimal_point
printf
. Currently, only the first character
is significant.
char *grouping
CHAR_MAX
means to group the remainder of the digits together.
char *int_curr_symbol
char *mon_decimal_point
char *mon_grouping
char *negative_sign
char *positive_sign
char *thousands_sep
char frac_digits
char int_frac_digits
char n_cs_precedes
char n_sep_by_space
char n_sign_posn
char p_cs_precedes
char p_sep_by_space
char p_sign_posn
Note that any numeric field may have a value of CHAR_MAX
, which
indicates that no information is available.
A pointer to the struct lconv
structure.
ANSI, POSIX
struct lconv *l = localeconv; printf("%s%d\n", l->negative_sign, value);
#include <time.h> struct tm *localtime(const time_t *tod);
Converts the time represented by tod into a structure, correcting
for the local timezone. See gmtime, for the description of
struct tm
.
A pointer to a static structure which is overwritten with each call.
ANSI, POSIX
#include <io.h> int lock(int fd, long offset, long length);
Locks a region in file fd using MS-DOS file sharing interface. The region of length bytes, starting from offset, will become entirely inaccessible to other processes. If multiple locks are used on a single file they must be non-overlapping. The lock must be removed before the file is closed.
This function will fail unless SHARE, or a network software providing similar interface, is installed. This function is compatible with Borland C++ function of the same name.
See unlock.
Zero if successful, nonzero if not.
not ANSI, not POSIX
#include <math.h> double log(double x);
This function computes the natural logarithm of x.
The natural logarithm of x. If x is zero, a negative
infinity is returned and errno
is set to ERANGE
. If
x is negative or +Inf
or a NaN
, the return value is
NaN
and errno
is set to EDOM
.
ANSI, POSIX
#include <math.h> double log10(double x);
This function computes the base-10 logarithm of x.
The logarithm base 10 of x. If x is zero, a negative
infinity is returned and errno
is set to ERANGE
. If
x is negative or +Inf
or a NaN
, the return value is
NaN
and errno
is set to EDOM
.
ANSI, POSIX
#include <math.h> double log1p(double x);
This function computes the natural logarithm of 1 + x. It
is more accurate than log(1 + x)
for small values of
x.
The natural logarithm of 1 + x. If x is -1, a
negative infinity is returned and errno
is set to ERANGE
.
If x is less than -1 or +Inf
or a NaN
, the return
value is NaN
and errno
is set to EDOM
.
not ANSI, not POSIX
#include <math.h> double log2(double x);
This function computes the base-2 logarithm of x.
The base-2 logarithm of x. If x is zero, a negative
infinity is returned and errno
is set to ERANGE
. If
x is negative or +Inf
or a NaN
, the return value is
NaN
and errno
is set to EDOM
.
not ANSI, not POSIX
#include <setjmp.h> void longjmp(jmp_buf env, int val);
This function reverts back to a CPU state that was stored in env
by setjmp
(see setjmp). The state includes all CPU registers,
so any variable in a register when setjmp
was called will be
preserved, and all else will be indeterminate.
The value passed as val will be the return value of setjmp
when it resumes processing there. If val is zero, the return
value will be one.
This function does not return.
ANSI, POSIX
jmp_buf j; if (setjmp(j)) return; do_something(); longjmp(j, 1);
#include <conio.h> void lowvideo(void);
Causes any new characters put on the screen to be dim.
not ANSI, not POSIX
#include <unistd.h> off_t lseek(int fd, off_t offset, int whence);
This function moves the file pointer for handle fd according to whence:
SEEK_SET
SEEK_CUR
SEEK_END
The new offset is returned.
not ANSI, POSIX
lseek(fd, 12, SEEK_CUR); /* skip 12 bytes */
#include <stdlib.h> void *malloc(size_t size);
This function allocates a chunk of memory from the heap large enough to
hold any object that is size bytes in length. This memory must be
returned to the heap with free
(see free).
Note: this version of malloc is designed to reduce memory usage. A faster but less efficient version is available in the libc sources (djlsr*.zip) in src/libc/ansi/stdlib/fmalloc.c
A pointer to the allocated memory, or NULL
if there isn't enough
free memory to satisfy the request.
ANSI, POSIX
char *c = (char *)malloc(100);
#include <libm/math.h> enum fdversion _fdlib_version = _SVID_; int matherr(struct exception *exc);
matherr
is a user-definable handler for errors in math library
functions. It is only supported in the alternate math library (link
with -lm
), and will only be called if the global variable
_fdlib_version
is set to either _SVID_
or _XOPEN_
(see libm). You also need to mask the Invalid Operation exception
in the x87 control word (see _control87) or install a handler for
signal SIGFPE
(see signal), or else some exceptions will
generate SIGFPE
and your program will be terminated before it
gets a chance to call matherr
. DJGPP versions 2.02 and later
mask all FP exceptions at startup, so this consideration applies only to
programs that unmask FP exceptions at run time.
If the above conditions are met, every math function will call
matherr
when a numerical exception is detected. The default
version of matherr
, supplied with libm.a
, does nothing and
returns zero (the _SVID_
version will then print an error message
to the standard error stream and set errno
).
This default behavior is inappropriate in some cases. For example, an
interactive program which runs in a windowed environment might want the
error message to go to a particular window, or pop up a dialog box; a
fault-tolerant program might want to fall back to backup procedures so
that meaningful results are returned to the application code, etc. In
such cases, you should include your own version of matherr
in
your program.
matherr
is called with a single argument exc which is a
pointer to a structure defined on <libm/math.h>
like this:
struct exception { int type; char *name; double arg1, arg2, retval; };
The member type
is an integer code describing the type of
exception that has occured. It can be one of the following:
DOMAIN
log(-1)
).
SING
log(0)
).
OVERFLOW
exp(10000)
.
UNDERFLOW
exp(-10000)
.
TLOSS
sin(10e100)
.
These codes are defined on <libm/math.h>
.
The member name
points to the string that is the name of the
function which generated the exception. The members arg1
and
arg2
are the values of the arguments with which the function was
called (arg2
is undefined if the function only accepts a single
argument). The member retval
is set to the default value that
will be returned by the math library function; matherr
can change
it to return a different value.
matherr
should return zero if it couldn't handle the exception,
or non-zero if the exception was handled.
If matherr
returns zero, under _SVID_
version an error
message is printed which includes the name of the function and the
exception type, and under _SVID_
and _XOPEN_
errno
is set to an appropriate value. If matherr
returns non-zero, no
error message is printed and errno
is left unchanged.
not ANSI, not POSIX
#include <libm/math.h> int matherr(register struct exception *x) { switch (x->type) { case DOMAIN: /* change sqrt to return sqrt(-arg1), not NaN */ if (!strcmp(x->name, "sqrt")) { x->retval = sqrt(-x->arg1); return 1; /* be silent: no message, don't set errno */ } /* FALL THROUGH */ case SING: /* all other domain or sing exceptions, print message and abort */ fprintf(stderr, "domain exception in %s\n", x->name); abort(); break; } return 0; /* all other exceptions, execute default procedure */ }
#include <stdlib.h> int mblen(const char *s, size_t n);
This function returns the number of characters of string s that make up the next multibyte character. No more than n characters are checked.
If s is NULL
, the internal shift state is reset.
The number of characters that comprise the next multibyte character.
ANSI, POSIX
int n = mblen(string, INT_MAX); string += n;
#include <stdlib.h> size_t mbstowcs(wchar_t *wcs, const char *s, size_t n);
Converts a multibyte string to a wide character string. The result will be no more than n wide characters.
The number of wide characters stored.
ANSI, POSIX
int wlen = mbtowcs(wbuf, string, sizeof(wbuf)/sizeof(wchar_t));
#include <stdlib.h> int mbtowc(wchar_t *pwc, const char *s, size_t n);
Convert the first multibyte sequence in s to a wide character.
At most n characters are checked. If pwc is not
NULL
, the result is stored there. If s is null, the
internal shift state is reset.
The number of characters used by the multibyte sequence.
ANSI, POSIX
string += mbtowc(&wc, string, strlen(string));
#include <string.h> void * memccpy(void *to, const void *from, int ch, size_t nbytes)
This function copies characters from memory area from into to, stopping after the first occurrence of character ch has been copied, or after nbytes characters have been copied, whichever comes first. The buffers should not overlap.
A pointer to the character after the copy of ch in to,
or a NULL
pointer if ch was not found in the first
nbytes characters of from.
not ANSI, not POSIX
char inpbuf[256], dest[81]; printf("Enter a path: "); fflush(stdout); gets(inpbuf); memset(dest, 0, sizeof(dest)); if (memccpy(dest, inpbuf, '\\', 80)) printf("The first directory in path is %s\n", dest); else printf("No explicit directory in path\n");
#include <string.h> void *memchr(const void *string, int ch, size_t num);
This function searches num bytes starting at string, looking for the first occurence of ch.
A pointer to the first match, or NULL
if it wasn't found.
ANSI, POSIX
if (memchr(path, '/', strlen(path)) do_slash();
#include <string.h> int memcmp(const void *s1, const void *s2, size_t num);
This function compares two regions of memory, at s1 and s2, for num bytes.
ANSI, POSIX
#include <string.h> void *memcpy(void *dest, const void *src, int num);
This function copies num bytes from source to dest.
It assumes that the source and destination regions don't overlap; if you
need to copy overlapping regions, use memmove
instead.
See memmove.
dest
ANSI, POSIX
memcpy(buffer, temp_buffer, BUF_MAX);
#include <string.h> int memicmp(const void *s1, const void *s2, size_t num);
This function compares two regions of memory, at s1 and s2, for num bytes, disregarding case.
Zero if they're the same, nonzero if different, the sign indicates "order".
not ANSI, not POSIX
if (memicmp(arg, "-i", 2) == 0) /* '-I' or '-include' etc. */ do_include();
#include <string.h> void *memmove(void *dest, const void *source, int num);
This function copies num bytes from source to dest. The copy is done in such a way that if the two regions overlap, the source is always read before that byte is changed by writing to the destination.
dest
ANSI, POSIX
memmove(buf+1, buf, 99); memmove(buf, buf+1, 99);
#include <string.h> void *memset(void *buffer, int ch, size_t num);
This function stores num copies of ch, starting at buffer. This is often used to initialize objects to a known value, like zero.
Note that, although ch is declared int
in the prototype,
memset
only uses its least-significant byte to fill buffer.
buffer
ANSI, POSIX
struct tm t; memset(&t, 0, sizeof(t));
#include <sys/stat.h> int mkdir(const char *path, mode_t mode);
This function creates a subdirectory.
All the bits except S_IWUSR
in the mode argument are
ignored under MS-DOS. If S_IWUSR
is not set in
mode, the directory is created with read-only attribute bit set.
Note that DOS itself ignores the read-only bit of directories, but some
programs do not.
Zero if the subdirectory was created, nonzero on failure.
not ANSI, POSIX
mkdir("/usr/tmp", S_IWUSR);
#include <sys/stat.h> int mkfifo(const char *path, mode_t mode);
This function is provided only to assist in porting from Unix. It always returns an error condition.
not ANSI, POSIX
#include <sys/stat.h> int mknod(const char *path, mode_t mode, dev_t dev);
This function is provided to assist in porting from Unix. If mode
specifies a regular file, mknod
creates a file using path
as its name. If mode specifies a character device, and if the
device whose name is given by path exists and its device
specification as returned by stat
or fstat
is equal to
dev, mknod
returns -1 and sets errno
to
EEXIST
. In all other cases, -1 is returned errno
is set
to EACCES
.
The argument dev is ignored if mode does not specify a character device.
Zero on success, -1 on failure.
not ANSI, not POSIX
#include <stdio.h> int mkstemp(char *template);
template is a file specification that ends with six trailing
X
characters. This function replaces the XXXXXX
with a
set of characters such that the resulting file name names a nonexisting
file. It then creates and opens the file in a way which guarantees that
no other process can access this file.
Note that since MS-DOS is limited to eight characters for the file name,
and since none of the X
's get replaced by a dot, you can only
have two additional characters before the X
's.
Note also that the path you give will be modified in place.
The open file descriptor.
not ANSI, not POSIX
char path[100]; strcpy(path, "/tmp/ccXXXXXX"); int fd = mkstemp(path);
#include <stdio.h> char *mktemp(char *template);
template is a file specification that ends with six trailing
X
characters. This function replaces the XXXXXX
with a
set of characters such that the resulting file name names a nonexisting
file.
Note that since MS-DOS is limited to eight characters for the file name,
and since none of the X
's get replaced by a dot, you can only
have two additional characters before the X
's.
The resulting filename.
not ANSI, not POSIX
char template[] = "/tmp/ccXXXXXX"; mktemp(template); FILE *q = fopen(template, "w");
#include <time.h> time_t mktime(struct tm *tptr);
This function converts a time structure into the number of seconds since
00:00:00 GMT 1/1/1970. It also attempts to normalize the fields of
tptr. The layout of a struct tm
is as follows:
struct tm { int tm_sec; /* seconds after the minute [0-60] */ int tm_min; /* minutes after the hour [0-59] */ int tm_hour; /* hours since midnight [0-23] */ int tm_mday; /* day of the month [1-31] */ int tm_mon; /* months since January [0-11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday [0-6] */ int tm_yday; /* days since January 1 [0-365] */ int tm_isdst; /* Daylight Savings Time flag */ long tm_gmtoff; /* offset from GMT in seconds */ char * tm_zone; /* timezone abbreviation */ };
If you don't know whether daylight saving is in effect at the moment
specified by the contents of tptr, set the tm_isdst
member
to -1, which will cause mktime
to compute the DST flag using the
data base in the zoneinfo
subdirectory of your main DJGPP
installation. This requires that you set the environment variable
TZ
to a file in that directory which corresponds to your
geographical area.
The resulting time, or -1 if the time in tptr cannot be described in that format.
ANSI, POSIX
#include <math.h> double modf(double x, double *pint);
modf
breaks down x into its integer portion (which it
stores in *pint) and the remaining fractional portion, which it
returns. Both integer and fractional portions have the same sign as
x, except if x is a negative zero, in which case the integer
part is a positive zero.
The fractional portion. If x is Inf
or NaN
, the
return value is zero, the integer portion stored in *pint is the
same as the value of x, and errno
is set to EDOM
.
ANSI, POSIX
#include <math.h> long double modf(long double x, long double *pint);
modfl
breaks down x into its integer portion (which it
stores in *pint) and the remaining fractional portion, which it
returns.
The fractional portion.
not ANSI, not POSIX
#include <sys/mono.h> void _mono_clear(void);
Clears the monochrome monitor.
not ANSI, not POSIX
#include <sys/mono.h> void _mono_printf(const char *fmt, ...);
Like printf, but prints to the monochrome monitor.
not ANSI, not POSIX
#include <sys/mono.h> void _mono_putc(int c);
Prints a single character to the monochrome monitor.
not ANSI, not POSIX
#include <sys/movedata.h> void movedata(unsigned source_selector, unsigned source_offset, unsigned dest_selector, unsigned dest_offset, size_t length);
This function allows the caller to directly transfer information
between conventional and linear memory, and among each as well. The
selectors passed are not segment values like in DOS. They are
protected mode selectors that can be obtained by the _my_ds
and
_go32_info_block.selector_for_linear_memory
(or just
_dos_ds
) functions (_my_ds, _go32_info_block).
The offsets are linear offsets. If the selector is for the program's
data area, this offset corresponds to the address of a buffer (like
(unsigned)&something
). If the selector is for the conventional
memory area, the offset is the physical address of the memory, which
can be computed from a traditional segment/offset pair as
segment
*16+offset
. For example, the color text screen
buffer is at offset 0xb8000.
None.
not ANSI, not POSIX
short blank_row_buf[ScreenCols()]; /* scroll screen */ movedata(_dos_ds, 0xb8000 + ScreenCols()*2, _dos_ds, 0xb8000, ScreenCols() * (ScreenRows()-1) * 2); /* fill last row */ movedata(_my_ds(), (unsigned)blank_row_buf, _dos_ds, 0xb8000 + ScreenCols()*(ScreenRows()-1)*2, ScreenCols() * 2);
#include <sys/movedata.h> void _movedatab(unsigned, unsigned, unsigned, unsigned, size_t);
Just like movedata, but all transfers are always 8-bit transfers.
not ANSI, not POSIX
#include <sys/movedata.h> void _movedatal(unsigned, unsigned, unsigned, unsigned, size_t);
Just like movedata, but all transfers are always 32-bit transfers, and the count is a count of transfers, not bytes.
not ANSI, not POSIX
#include <sys/movedata.h> void _movedataw(unsigned, unsigned, unsigned, unsigned, size_t);
Just like movedata, but all transfers are always 16-bit transfers, and the count is a count of transfers, not bytes.
not ANSI, not POSIX
#include <conio.h> int movetext(int _left, int _top, int _right, int _bottom, int _destleft, int _desttop);
Moves a block of text on the screen.
1 on success, zero on error.
not ANSI, not POSIX
#include <sys/types.h> #include <sys/mman.h> int mprotect(void *addr, size_t len, int prot);
This function modifies the access protection of a memory region. Protection occurs in 4Kbyte regions (pages) aligned on 4Kbyte boundaries. All pages in the region will be changed, so addr and len should be multiples of 4096.
The protection prot for each page is specified with the values: PROT_NONE Region can not be touched (if or'ed is ignored). PROT_READ Region can be read (can be or'ed with PROT_WRITE). PROT_WRITE Region can be written (implies read access).
This function is only supported on DPMI hosts which provide some V1.0 extensions on V0.9 memory blocks.
The function returns 0 if successful and the value -1 if all the pages could not be set.
not ANSI, not POSIX
mprotect(readonly_buffer,8192,PROT_READ); mprotect(guard_area,4096,PROT_NONE); mprotect(NULL,4096,PROT_WRITE); /* Let NULL pointers not generate exceptions */
#include <sys/segments.h> unsigned short _my_cs();
Returns the current CS
. This is useful for setting up interrupt
vectors and such.
CS
not ANSI, not POSIX
#include <sys/segments.h> unsigned short _my_ds();
Returns the current DS
. This is useful for setting up interrupt
vectors and such.
DS
not ANSI, not POSIX
#include <sys/segments.h> unsigned short _my_ss();
Returns the current SS
. This is useful for setting up interrupt
vectors and such.
SS
not ANSI, not POSIX
#include <unistd.h> int nice(int _increment);
Adjusts the priority of the process. Provided for Unix compatibility only.
The new nice value.
not ANSI, not POSIX
#include <conio.h> void normvideo(void);
Resets the text attribute to what it was before the program started.
not ANSI, not POSIX
#include <pc.h> void nosound(void);
Disable the PC speaker.
not ANSI, not POSIX
#include <netinet/in.h> unsigned long ntohl(unsigned long val);
This function converts from network formatted longs to host formatted longs. For the i386 and higher processors, this means that the bytes are swapped from 1234 order to 4321 order.
The host-order value.
not ANSI, not POSIX
ip = ntohl(packet.ipaddr);
#include <netinet/in.h> unsigned short ntohs(unsigned short val);
This function converts from network formatted shorts to host formatted shorts. For the i386 and higher processors, this means that the bytes are swapped from 12 order to 21 order.
The host-order value.
not ANSI, not POSIX
port = ntohs(tcp.port);
#include <fcntl.h> #include <sys/stat.h> /* for mode definitions */ int open(const char *file, int mode /*, int permissions */);
This function opens the named file in the given mode, which is any combination of the following:
O_RDONLY
O_WRONLY
O_RDWR
O_CREAT
O_TRUNC
O_EXCL
O_CREAT
is also specified, the
open
call will fail.
O_APPEND
O_TEXT
_fmode
variable _fmode.
O_BINARY
When called to open the console in binary mode, open
will disable
the generation of SIGINT
when you press Ctrl-C
(Ctrl-Break will still cause SIGINT
), because many programs
that use binary reads from the console will also want to get the
^C
characters. You can use the __djgpp_set_ctrl_c
library
function (see __djgpp_set_ctrl_c) if you want Ctrl-C to
generate interrupts while console is read in binary mode.
If the file is created by this call, it will be given the read/write permissions specified by permissions, which may be any combination of these values:
S_IRUSR
S_IWUSR
Other S_I*
values may be included, but they will be ignored.
You can specify the share flags (a DOS specific feature) in mode.
And you can indicate default values for the share flags in
__djgpp_share_flags
. See __djgpp_share_flags.
If successful, the file descriptor is returned. On error, a negative
number is returned and errno
is set to indicate the error.
not ANSI, POSIX
int q = open("/tmp/foo.dat", O_RDONLY|O_BINARY);
#include <io.h> int _open(const char *path, int attrib);
This is a direct connection to the MS-DOS open function call, int 0x21,
%ah = 0x3d. (When long file names are supported, _open
calls
function 0x716c of Int 0x21.) The file is set to binary mode.
This function can be hooked by the File System Extensions
(see File System Extensions). If you don't want this, you should
use _dos_open
(see _dos_open) (but note that the latter
doesn't support long file names).
The new file descriptor, else -1 on error.
not ANSI, not POSIX
#include <dirent.h> extern int __opendir_flags; DIR *opendir(char *name);
This function "opens" a directory so that you can read the list of file
names in it. The pointer returned must be passed to closedir
when you are done with it. See readdir.
The global variable __opendir_flags
can be set to include the
following values to control the operation of opendir
:
__OPENDIR_PRESERVE_CASE
You can also use this flag if you want the names of files like
README
and FAQ
from Unix distributions to be returned in
upper-case on Windows 9X filesystems. See _preserve_fncase, for
other ways of achieving this and for more detailed description of the
automatic letter-case conversion by DJGPP library functions.
__OPENDIR_NO_HIDDEN
__OPENDIR_FIND_HIDDEN
__OPENDIR_FIND_LABEL
You can simply put int __opendir_flags = ...;
in your code. The
default is to let it get set to zero as an uninitialized variable.
The open directory structure, or NULL
on error.
not ANSI, POSIX (see note 1)
Notes:
__opendir_flags
variable is DJGPP-specific.
DIR *d = opendir("."); closedir(d);
#include <pc.h> void outb(unsigned short _port, unsigned char _data);
Calls outportb. Provided only for compatibility.
not ANSI, not POSIX
#include <pc.h> void outp(unsigned short _port, unsigned char _data);
Calls outportb. Provided only for compatibility.
not ANSI, not POSIX
#include <pc.h> void outportb(unsigned short _port, unsigned char _data);
Write a single byte to an 8-bit port.
This function is provided as an inline assembler macro, and will be optimized down to a single opcode when you optimize your program.
not ANSI, not POSIX
#include <pc.h> void outportl(unsigned short _port, unsigned long _data);
Write a single long to an 32-bit port.
This function is provided as an inline assembler macro, and will be optimized down to a single opcode when you optimize your program.
not ANSI, not POSIX
#include <pc.h> void outportsb(unsigned short _port, const unsigned char *_buf, unsigned _len);
Writes the _len bytes in _buf to the 8-bit _port.
not ANSI, not POSIX
#include <pc.h> void outportsl(unsigned short _port, const unsigned long *_buf, unsigned _len);
Writes the _len longs in _buf to the 32-bit _port.
not ANSI, not POSIX
#include <pc.h> void outportsw(unsigned short _port, const unsigned short *_buf, unsigned _len);
Writes the _len shorts in _buf to the 16-bit _port.
not ANSI, not POSIX
#include <pc.h> void outportw(unsigned short _port, unsigned short _data);
Write a single short to an 16-bit port.
This function is provided as an inline assembler macro, and will be optimized down to a single opcode when you optimize your program.
not ANSI, not POSIX
#include <pc.h> void outpw(unsigned short _port, unsigned short _data);
Calls outportw. Provided only for compatibility.
not ANSI, not POSIX
#include <unistd.h> long pathconf(const char *filename, int name);
This function returns various system-dependent configuration values. The name is one of the following:
_PC_LINK_MAX
_PC_MAX_CANON
_PC_MAX_INPUT
_PC_NAME_MAX
_get_volume_info
returns (usually 255); otherwise 12 will be
returned. See _use_lfn.
_PC_PATH_MAX
_get_volume_info
returns (usually 260); otherwise 80 will be
returned. See _use_lfn.
_PC_PIPE_BUF
_PC_CHOWN_RESTRICTED
chown
, otherwise anyone may give away files. The DJGPP
version always returns zero, since MS-DOS files can be freely given
away.
_PC_NO_TRUNC
pathconf (filename, _PC_NAME_MAX)
returns are truncated,
otherwise an error occurs if you use longer names. In DJGPP, this
returns 0, since DOS always silently truncates long names.
_PC_VDISABLE
The selected configuration value is returned.
not ANSI, POSIX
char *buf = malloc(pathconf("c:/", _PC_MAX_PATH)+1);
#include <unistd.h> int pause(void);
This function just calls __dpmi_yield()
(see __dpmi_yield)
to give up a slice of the CPU.
Zero.
not ANSI, POSIX
#include <stdio.h> int pclose(FILE *pipe);
This function closes a pipe opened with popen
(see popen).
Note that since MS-DOS is not multitasking, this function will actually
run the program specified in popen
if the pipe was opened for
writing.
Zero on success, nonzero on failure.
not ANSI, POSIX
FILE *f = popen("sort", "w"); write_to_pipe(f); pclose(f);
#include <stdio.h> void perror(const char *string);
This function formats an error message and prints it to stderr
.
The message is the string, a colon, and a message suitable for the error
condition indicated by errno
.
None.
ANSI, POSIX
int x = open("foo", O_RDONLY); if (x < 0) { perror("foo"); exit(1); }
#include <unistd.h> int pipe(int fildes[2]);
This function is provided only to assist in porting from Unix. It always returns an error condition.
not ANSI, POSIX
#include <stdio.h> FILE *popen(const char *program, const char *mode);
This function executes the named program
and attaches either its
input stream or its output stream to the returned file. While the file
is open, the calling program can write to the program (if the program
was open for writing) or read the program's output (if the program was
opened for reading). When the program is done, or if you have no more
input for it, pass the file pointer to pclose
(see pclose),
which terminates the program.
Since MS-DOS does not support multitasking, this function actually runs
the entire program when the program is opened for reading, and stores
the output in a temporary file. pclose
then removes that file.
Similarly, when you open a program for writing, a temp file holds the
data and pclose
runs the entire program.
The mode is the same as for fopen
(see fopen).
An open file which can be used to read the program's output or write to the program's input.
not ANSI, POSIX
FILE *p = popen("dir", "r"); read_program(p); pclose(p);
#include <math.h> double pow(double x, double y);
This function computes x^y, x raised to the power y.
x raised to the power y. If the result overflows a
double
or underflows, errno
is set to ERANGE
. If
y is NaN
, the return value is NaN
and errno
is set to EDOM
. If x and y are both 0, the return
value is 1, but errno
is set to EDOM
. If y is a
positive or a negative Infinity, the following results are returned,
depending on the value of x:
NaN
and errno
is set to EDOM
.
+Inf
-Inf
-Inf
+Inf
+Inf
.
NaN
and errno
is set to EDOM
.
ANSI, POSIX
#include <math.h> double pow10(double x);
This function computes 10 to the power of x, 10^x.
10 to the x power. If the value of x is finite, but so
large in magnitude that 10^x cannot be accurately represented by
a double
, the return value is the nearest representable !
double
(possibly, an Inf
), and errno
is set to
ERANGE
. If x is either a positive or a negative infinity,
the result is either +Inf
or zero, respectively, and errno
is not changed. If x is a NaN
, the return value is
NaN
and errno
is set to EDOM
.
not ANSI, not POSIX
#include <math.h> double pow2(double x);
This function computes 2 to the power of x, 2^x.
2 to the x power. If the value of x is finite, but so large
in magnitude that 2^x cannot be accurately represented by a
double
, the return value is the nearest representable
double
(possibly, an Inf
), and errno
is set to
ERANGE
. If x is either a positive or a negative infinity,
the result is either +Inf
or zero, respectively, and errno
is not changed. If x is a NaN
, the return value is
NaN
and errno
is set to EDOM
.
not ANSI, not POSIX
#include <math.h> double powi(double x, int iy);
This function computes x^iy, where iy is an integer number.
It does so by an optimized sequence of squarings and multiplications.
For integer values of exponent, it is always faster to call powi
than to call pow
with the same arguments, even if iy has a
very large value. For small values of iy, powi
is
much faster than pow
.
x raised to the iy power. If x and iy are both
zero, the return value is 1. If x is equal to zero, and iy
is negative, the return value is Inf
. This function never sets
errno
.
not ANSI, not POSIX
#include <fcntl.h> char _preserve_fncase (void);
This function returns a non-zero value if letter-case in filenames
should be preserved. It is used by library functions that get filenames
from the operating system (like readdir
, _fixpath
and
others). The usual behavior of these functions (when
_preserve_fncase
returns zero) is to down-case 8+3 DOS-style
filenames, but leave alone the letter-case in long filenames when these
are supported (see _use_lfn). This can be changed by either setting
_CRT0_FLAG_PRESERVE_FILENAME_CASE
bit in the
_crt0_startup_flags
variable (see _crt0_startup_flags), or by
setting the FNCASE
environment variable to Y at run time.
You might need such a setup e.g. on Windows 95 if you want to see files
with names like README
and FAQ
listed in upper-case (for
this to work, you will have to manually rename all the other files with
8+3 DOS-style names to lower-case names). When the case in filenames is
preserved, all filenames will be returned in upper case on MSDOS (and
other systems that don't support long filenames), or if the environment
variable LFN
is set to N on systems that support LFN. That
is because this is how filenames are stored in the DOS directory entries.
Zero when 8+3 filenames should be converted to lower-case, non-zero otherwise.
not ANSI, not POSIX
#include <stdio.h> int printf(const char *format, ...);
Sends formatted output from the arguments (...) to stdout
.
The format string contains regular characters to print, as well as conversion specifiers, which begin with a percent symbol. Each conversion speficier contains the following fields:
-
+
+
sign on positive numbers.
space
#
0
, hexadecimal
numbers with 0x
or 0X
, or force a trailing decimal point
if a floating point conversion would have omitted it.
0
*
), which means that the actual
width will be obtained from the next argument. If the argument is
negative, it supplies a -
flag and a positive width.
g
or G
, actual for others), or the maximum number of
characters for a string.
h
to specify
short
, l
to specify long ints, or L
to specify
long doubles. Long long type can be specified by L
or ll
.
c
d
D
e
E
f
g
G
i
n
o
p
x
specifier.
s
NULL
-terminated string.
u
U
x
X
%
The number of characters written.
ANSI, POSIX
printf("%-3d %10.2f%% Percent of %s\n", index, per[index], name[index]);
#include <signal.h> extern char *sys_siglist[]; void psignal (int sig, const char *msg);
This function produces a message on the standard error stream describing the signal given by its number in sig. It prints the string pointed to by msg, then the name of the signal, and a newline.
The names of signals can be retrieved using the array
sys_siglist
, with the signal number serving as an index into this
array.
not ANSI, not POSIX
#include <signal.h> void sig_catcher (int sig) { psignal (progname, sig); return; }
#include <libc/dosio.h> int _put_path(const char *path); int _put_path2(const char *path, int offset);
These functions are used internally by all low-level library functions
that need to pass file names to DOS. _put_path
copies its
argument path to the transfer buffer
(see _go32_info_block) starting at the beginning of the transfer
buffer; _put_path2
does the same except that it puts the file
name starting at offset bytes from the beginning of the transfer
buffer.
These functions are meant to be called by low-level library functions,
not by applications. You should only call them if you know what you are
doing. In particular, if you call any library function between a call
to _put_path
or _put_path2
and the call to a DOS function
that uses the file name, the file name in the transfer buffer could be
wiped out, corrupted or otherwise changed. You have been
warned!
Some constructs in file names are transformed while copying them, to allow transparent support for nifty features. Here's the list of these transformations:
Unix treats multiple slashes as a single slash, so some ported programs
pass names like c:/foo//bar
to library functions. DOS functions
choke on such file names, so collapsing the slashes prevents these names
from failing.
Various DOS calls cannot cope with file names like c:/foo/
; this
feature solves this problem.
Unix /dev/null
is mapped to DOS-standard NUL
, and Unix
/dev/tty
to DOS-standard CON
. This provides for
transparent support of these special devices, e.g. in Unix shell
scripts.
Any file name which begins with /dev/
or x:/dev/
(where x: is any valid DOS drive letter) has the /dev/
or
x:/dev/
prefix removed, and the rest is passed to DOS.
This is because some DOS functions don't recognize device names unless
they are devoid of the drive and directory specifications, and programs
could add a drive and a directory if they convert a name like
/dev/con
to a fully-qualified path name.
/dev/x/
is translated into x:/
.
This allows to use Unix-style absolute path names that begin with a
slash, instead of DOS-style names with a drive letter. Some Unix
programs and shell scripts fail for file names that include colons,
which are part of the drive letter specification; this feature allows to
work around such problems by using e.g. /dev/c/
where c:/
would fail.
/dev/env/foo/
is replaced by the value of the environment
variable foo.
(In other words, you can think of environment variables as if they were
sub-directories of a fictitious directory /dev/env
.)
This allows to use environment variable names inside path names compiled
into programs, and have them transparently expanded at run time. For
example, /dev/env/DJDIR/include
will expand to the exact path
name of the DJGPP include directory, no matter where DJGPP is installed
on the machine where the program runs. (The value of DJDIR
is
computed by the DJGPP startup code and pushed into the environment of
every DJGPP program before main
is called.)
Note that environment variables are case-sensitive, so
/dev/env/foo
and /dev/env/FOO
are not the same.
DOS shells usually upcase the name of the environment variable if you
set it with the built-in command SET
, so if you type
e.g. SET foo=bar
, the shell defines a variable named FOO
.
If the environment variable is undefined, it will expand into an empty
string. The expansion is done recursively, so environment variables may
reference other environment variables using the same /dev/env/
notation. For example, if the variable HOME
is set to
/dev/env/DJDIR/home
, and DJGPP is installed in
c:/software/djgpp
, then /dev/env/HOME/sources
will expand
to c:/software/djgpp/home/sources
.
It is possible to supply a default value, to be used if the variable is
not defined, or has an empty value. To this end, put the default value
after the name of the variable and delimit it by ~
, like in
/dev/env/DJDIR~c:/djgpp~/include
.
If you need to include a literal character ~
in either the
environment variable name or in the default value that replaces it, use
two ~
s in a row. For example, /dev/env/FOO~~
will expand
to the value of the variable FOO~
. Likewise,
/dev/env/FOO~~BAR~foo~~baz~
will expand to the value of the
variable FOO~BAR
if it is defined and nonempty, and to
foo~baz
otherwise. Leading ~
in the default value isn't
supported (it is interpreted as part of the preceding variable name).
The default value may also reference (other) environment variables, but
nested default values can get tricky. For example,
/dev/env/foo~/dev/env/bar~
will work, but
/dev/env/foo~/dev/env/bar~baz~~
will not. To use nested
default values, you need to double the quoting of the ~
characters, like in /dev/env/foo~/dev/env/bar~~baz~~~
.
Both functions return the offset into the transfer buffer of the terminating null character that ends the file name.
not ANSI, not POSIX
These functions are meant to be called by low-level library functions,
not by applications. You should only call them if you know what you are
doing. In particular, if you call any library function between a call
to _put_path
or _put_path2
and the call to a DOS function
that uses the file name, the file name in the transfer buffer could be
wiped out, corrupted and otherwise changed. You have been
warned!
__dpmi_regs r; _put_path("/dev/c/djgpp/bin/"); r.x.ax = 0x4300; /* get file attributes */ r.x.ds = __tb >> 4; r.x.dx = __tb & 0x0f; __dpmi_int(0x21, &r);
#include <stdio.h> int putc(int c, FILE *file);
This function writes one character to the given file.
The character written.
ANSI, POSIX
while ((c=getc(stdin)) != EOF) putc(c, stdout);
#include <conio.h> int putch(int _c);
Put the character _c on the screen at the current cursor position. The special characters return, linefeed, bell, and backspace are handled properly, as is line wrap and scrolling. The cursor position is updated.
The character is returned.
not ANSI, not POSIX
#include <stdio.h> int putchar(int c);
This is the same as fputc(c, stdout)
. See fputc.
The character written.
ANSI, POSIX
while ((c = getchar()) != EOF) putchar(c);
#include <stdlib.h> int putenv(const char *env);
This function adds an entry to the program's environment. The string
passed must be of the form NAME
=VALUE
. Any existing value
for the environment variable is gone.
putenv
will copy the string passed to it, and will
automatically free any existing string already in the environment.
Keep this in mind if you alter the environment yourself. The string
you pass is still your responsibility to free. Note that most
implementations will not let you free the string you pass, resulting
in memory leaks.
Zero on success, nonzero on failure.
not ANSI, not POSIX
putenv("SHELL=ksh.exe");
#include <stdio.h> int puts(const char *string);
This function writes string to stdout
, and then writes a
newline character.
Nonnegative for success, or EOF
on error.
ANSI, POSIX
puts("Hello, there");
#include <conio.h> int puttext(int _left, int _top, int _right, int _bottom, void *_source);
The opposite of gettext.
1 on success, zero on error.
not ANSI, not POSIX
#include <stdio.h> int putw(int x, FILE *file);
Writes a single binary word in native format to file.
The value written, or EOF
for end-of-file or error. Since
EOF
is a valid integer, you should use feof
or
ferror
to detect this situation.
not ANSI, not POSIX
putw(12, stdout);
#include <stdlib.h> void qsort(void *base, size_t numelem, size_t size, int (*cmp)(const void *e1, const void *e2));
This function sorts the given array in place. base is the address
of the first of numelem array entries, each of size size
bytes. qsort
uses the supplied function cmp to determine
the sort order for any two elements by passing the address of the two
elements and using the function's return address.
The return address of the function indicates the sort order:
None.
ANSI, POSIX
typedef struct { int size; int sequence; } Item; int qsort_helper_by_size(const void *e1, const void *e2) { return ((const Item *)e2)->size - ((const Item *)e1)->size; } Item list[100]; qsort(list, 100, sizeof(Item), qsort_helper_by_size); int qsort_stringlist(const void *e1, const void *e2) { return strcmp(*(char **)e1, *(char **)e2); } char *slist[10]; /* alphabetical order */ qsort(slist, 10, sizeof(char *), qsort_stringlist);
#include <signal.h> int raise(int sig);
This function raises the given signal sig. See the list of possible signals.
0 on success, -1 for illegal value of sig.
ANSI, POSIX
#include <stdlib.h> int rand(void);
Returns a pseudo-random number between zero and RAND_MAX
(defined
on stdlib.h
).
By default, this function always generates the same sequence of numbers
each time you run the program. (This is usually desirable when
debugging, or when comparing two different runs.) If you need to
produce a different sequence on every run, you must seed rand
by
calling srand
(see srand) before the first call to
rand
, and make sure to use a different argument to srand
each time. The usual technique is to get the argument to srand
from a call to the time
library function (see time), whose
return value changes every second.
To get a random number in the range 0..N, use rand()%(N+1)
. Note
that the low bits of the rand
's return value are not very random,
so rand()%N
for small values of N could be not enough
random. The alternative, but non-ANSI, function random
is
better if N is small. See random.
The number.
ANSI, POSIX
/* random pause */ srand(time(0)); for (i=rand(); i; i--);
#include <stdlib.h> double drand48(void); double erand48(unsigned short state[3]); unsigned long lrand48(void); unsigned long nrand48(unsigned short state[3]); long mrand48(void); long jrand48(unsigned short state[3]); void srand48(long seed); unsigned short *seed48(unsigned short state_seed[3]); void lcong48(unsigned short param[7]);
This is the family of *rand48
functions. The basis for these functions
is the linear congruential formula X[n+1] = (a*X[n] + c) mod 2^48,
n >= 0. a = 0x5deece66d and c = 0xb at start and after a call to either
srand48
or seed48
. A call to lcong48
changes a and c (and the internal state).
drand48
and erand48
return double
s uniformly
distributed in the interval [0.0, 1.0).
lrand48
and nrand48
return unsigned long
s
uniformly distributed in the interval [0, 2^31).
mrand48
and jrand48
return long
s uniformly
distributed in the interval [-2^31, 2^31).
erand48
, jrand48
and nrand48
requires the
state of the random generator to be passed.
drand48
, lrand48
and mrand48
uses an
internal state (common with all three functions) which should be
initialized with a call to one of the functions srand48
,
seed48
or lcong48
.
srand48
sets the high order 32 bits to the argument
seed. The low order 16 bits are set to the arbitrary value
0x330e.
seed48
sets the internal state according to the argument
state_seed (state_seed[0]
is least significant).
The previous state of the random generator is saved in an internal
(static) buffer, to which a pointer is returned.
lcong48
sets the internal state to param[0-2]
, a to
param[3-5]
(param[0]
and param[3]
are least significant) and c to param[6]
.
A random number.
not ANSI, not POSIX
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { srand48(time(NULL)); printf("%.12f is a random number in [0.0, 1.0).\n", drand48()); exit(0); }
#include <stdlib.h> long random(void);
Returns a random number in the range 0..MAXINT.
0 .. MAXINT
not ANSI, not POSIX
/* Produce a random integer between 0 and 199. */ int random_number = random () % 200;
#include <time.h> unsigned long rawclock(void);
Returns the number of clock tics (18.2 per second) since midnight.
The number of tics.
not ANSI, not POSIX
/* wait 1/4 second */ int i = rawclock()+5; while (rawclock()<i);
#include <unistd.h> ssize_t read(int fd, void *buffer, size_t length);
This function reads at most length bytes from file fd into
buffer. Note that in some cases, such as end-of-file conditions
and text files, it may read less than the requested number of bytes.
At end-of-file, read
will read exactly zero bytes.
The number of bytes read, zero meaning end-of-file, or -1 for an error.
not ANSI, POSIX
char buf[10]; int r = read(0, buf, 10);
#include <io.h> ssize_t _read(int fildes, void *buf, size_t nbyte);
This is a direct connection to the MS-DOS read function call, int 0x21, %ah = 0x3f. No conversion is done on the data; it is read as raw binary data. This function can be hooked by the See File System Extensions. If you don't want this, you should use See _dos_read.
The number of bytes read.
not ANSI, not POSIX
#include <debug/dbgcom.h> void read_child (unsigned child_addr, void *buf, unsigned len);
This function reads the memory of the debugged process starting at address child_addr for len bytes, and copies the data read to the buffer pointed to by buf. It is used primarily to save the original instruction at the point where a breakpoint instruction is inserted (to trigger a trap when the debuggee's code gets to that point). See write_child.
The function return zero if it has successfully transferred the data, non-zero otherwise (e.g., if the address in child_addr is outside the limits of the debuggee's code segment.
not ANSI, not POSIX
#include <debug/dbgcom.h> void read_sel_addr (unsigned offset, void *buf, unsigned len, unsigned sel);
This function reads the memory starting at offset offset in selector sel for len bytes, and copies the data read to the buffer pointed to by buf. See write_sel_addr.
The function return zero if it has successfully transferred the data, non-zero otherwise (e.g., if the address in offset is outside the limits of the segment whose selector is sel).
not ANSI, not POSIX
#include <dirent.h> struct dirent *readdir(DIR *dir);
This function reads entries from a directory opened by opendir
(see opendir). It returns the information in a static buffer with
this format:
struct dirent { unsigned short d_namlen; /* The length of the name (like strlen) */ char d_name[MAXNAMLEN+1]; /* The name */ };
Note that some directory entries might be skipped by readdir
,
depending on the bits set in the global variable
__opendir_flags
. See __opendir_flags.
A pointer to a static buffer that is overwritten with each call.
not ANSI, POSIX (see note 1)
Notes:
__opendir_flags
variable is DJGPP-specific.
DIR *d = opendir("."); struct dirent *de; while (de = readdir(d)) puts(de->d_name); closedir(d);
#include <stdlib.h> void *realloc(void *ptr, size_t size);
This function changes the size of the region pointed to by ptr.
If it can, it will reuse the same memory space, but it may have to
allocate a new memory space to satisfy the request. In either case, it
will return the pointer that you should use to refer to the (possibly
new) memory area. The pointer passed may be NULL
, in which case
this function acts just like malloc
(see malloc).
A pointer to the memory you should now refer to.
ANSI, POSIX
if (now+new > max) { max = now+new; p = realloc(p, max); }
#include <debug/redir.h> void redir_cmdline_delete (cmdline_t *cmd);
For the rationale and general description of the debugger redirection issue, see redir_debug_init.
This function serves as a destructor for a cmdline_t
object. It
frees storage used for the command-line arguments associated with
cmd, closes any open handles stored in it, and frees memory used
to store the file handles and the file names of the files where standard
handles were redirected.
The function is safe to use even if cmd might be a NULL
pointer, or if some of members of the cmdline_t
structure are
NULL
pointers. See redir_debug_init, for detailed description
of the cmdline_t
structure.
not ANSI, not POSIX
redir_cmdline_delete (&child_cmd);
#include <debug/redir.h> int redir_cmdline_parse (const char *args, cmdline_t *cmd);
For the rationale and general description of the debugger redirection issue, see redir_debug_init.
This function parses a command-line tail (i.e., without the program to
be invoked) passed as a string in args. For every redirection
directive in args, like >> foo
, it opens the file that is
the target of the redirection, and records in cmd the information
about these redirections. (See redir_debug_init, for details of the
cmdline_t
structure that is used to hold this information.) The
command line with redirections removed is placed into
cmd->command
(typically, it will be used to call
v2loadimage
, see v2loadimage), while the rest of information
is used by redir_to_child
and redir_to_debugger
to
redirect standard handles before and after calling run_child
.
The function returns zero in case of success, -1 otherwise. Failure
usually means some kind of syntax error, like >
without a file
name following it; or a file name that isn't allowed by the underlying
OS, like lost+found
on DOS.
not ANSI, not POSIX
/* Init command line storage. */ if (redir_debug_init (&child_cmd) == -1) fatal ("Cannot allocate redirection storage: not enough memory.\n"); /* Parse the command line and create redirections. */ if (strpbrk (args, "<>")) { if (redir_cmdline_parse (args, &child_cmd) == 0) args = child_cmd.command; else error ("Syntax error in command line."); } else child_cmd.command = strdup (args); cmdline = (char *) alloca (strlen (args) + 4); cmdline[0] = strlen (args); strcpy (cmdline + 1, args); cmdline[strlen (args) + 1] = 13; if (v2loadimage (exec_file, cmdline, start_state)) { printf ("Load failed for image %s\n", exec_file); exit (1); }
#include <debug/redir.h> int redir_debug_init (cmdline_t *cmd);
This function initializes the data structure in the cmd variable
required to save and restore debugger's standard handles across
invocations of run_child
(see run_child). The debugger will
then typically call redir_to_child
and redir_to_debugger
.
These functions are needed when a debugger wants to redirect standard
handles of the debuggee, or if the debuggee redirects some of its
standard handles, because the debuggee is not a separate process, we
just pretend it is by jumping between two threads of execution. But, as
far as DOS is concerned, the debugger and the debuggee are a single
process, and they share the same Job File Table (JFT). The JFT is
a table maintained by DOS in the program's PSP where, for each open
handle, DOS stores the index into the SFT, the System File Table.
(The SFT is an internal data structure where DOS maintains everything it
knows about a certain open file/device.) A handle that is returned by
open
, _open
and other similar functions is simply an index
into the JFT where DOS stored the SFT entry index for the file or device
that the program opened.
When a program starts, the first 5 entries in the JFT are preconnected to the standard devices. Any additional handles opened by either the debugger or the debuggee use handles beyond the first 5 (unless one of the preconnected handles is deliberately closed). Here we mostly deal with handles 0, 1 and 2, the standard input, standard output, and standard error; they all start connected to the console device (unless somebody redirects the debugger's I/O from the command line).
Since both the debugger and the debuggee share the same JFT, their handles 0, 1 and 2 point to the same JFT entries and thus are connected to the same files/devices. Therefore, if the debugger redirects its standard output, the standard output of the debuggee is also automagically redirected to the same file/device! Similarly, if the debuggee redirects its stdout to a file, you won't be able to see debugger's output (it will go to the same file where the debuggee has its output); and if the debuggee closes its standard input, you will lose the ability to talk to debugger!
The debugger redirection support attempts to solve all these problems by
creating an illusion of two separate sets of standard handles. Each
time the debuggee is about to be run or resumed, it should call
redir_to_child
to redirect debugger's own standard handles to the
file specified in the command-line (as given by e.g. the "run" command
of GDB) before running the debuggee, then call redir_to_debugger
to redirect them back to the debugger's original input/output when the
control is returned from the debuggee (e.g. after a breakpoint is hit).
Although the debugger and the debuggee have two separate copies of the
file-associated data structures, the debugger still can redirect
standard handles of the debuggee because they use the same JFT entries
as debugger's own standard handles.
The cmdline_t
structure is declared in the header
debug/redir.h
as follows:
struct dbg_redirect { int inf_handle; /* debuggee's handle */ int our_handle; /* debugger's handle */ char *file_name; /* file name where debuggee's handle is redirected */ int mode; /* mode used to open() the above file */ off_t filepos; /* file position of debuggee's handle; unused */ }; typedef struct _cmdline { char *command; /* command line with redirection removed */ int redirected; /* 1 if handles redirected for child */ struct dbg_redirect **redirection;/* info about redirected handles */ } cmdline_t;
In the cmdline_t
structure, the redirection
member points
to an array of 3 dbg_redirect
structures, one each for each one
of the 3 standard handles. The inf_handle
and our_handle
members of those structures are used to save the handle used,
respectively, by the debuggee (a.k.a. the inferior process) and
by the debugger.
The cmd variable is supposed to be defined by the debugger's
application code. redir_debug_init
is called to initialize that
variable. It calls redir_cmdline_delete
to close any open
handles held in cmd and to free any allocated storage; then it
fills cmd with the trivial information (i.e., every standard
stream is connected to the usual handles 0, 1, and 2).
redir_debug_init
returns zero in case of success, or -1
otherwise.
not ANSI, not POSIX
if (redir_debug_init (&child_cmd) == -1) fatal ("Cannot allocate redirection storage: not enough memory.\n");
#include <debug/redir.h> int redir_to_child (cmdline_t *cmd);
For the rationale and general description of the debugger redirection issue, see redir_debug_init.
This function redirects all 3 standard streams so that they point to the
files/devices where the child (a.k.a. debuggee) process connected
them. All three standard handles point to the console device by
default, but this could be changed, either because the command line for
the child requested redirection, like in prog > foo
, or because
the child program itself redirected one of its standard handles
e.g. with a call to dup2
.
redir_to_child
uses information stored in the cmdline_t
variable pointed to by the cmd argument to redirect the standard
streams as appropriate for the debuggee, while saving the original
debugger's handles to be restored by redir_to_debugger
.
The function returns zero in case of success, -1 in case of failure. Failure usually means the process has run out of available file handles.
not ANSI, not POSIX
errno = 0; if (redir_to_child (&child_cmd) == -1) { redir_to_debugger (&child_cmd); error ("Cannot redirect standard handles for program: %s.", strerror (errno)); }
#include <debug/redir.h> int redir_to_debugger (cmdline_t *cmd);
For the rationale and general description of the debugger redirection issue, see redir_debug_init.
This function redirects all 3 standard streams so that they point to the
files/devices where the debugger process connected them. All three
standard handles point to the console device by default, but this could
be changed, either because the command line for the child requested
redirection, like in prog > foo
, or because the child program
itself redirected one of its standard handles e.g. with a call to
dup2
.
redir_to_debugger
uses information stored in the cmdline_t
variable pointed to by the cmd argument to redirect the standard
streams as appropriate for the debugger, while saving the original
debuggee's handles to be restored by redir_to_child
.
The function returns zero in case of success, -1 in case of failure. Failure usually means the process has run out of available file handles.
not ANSI, not POSIX
/* Restore debugger's standard handles. */ errno = 0; if (redir_to_debugger (&child_cmd) == -1) error ("Cannot redirect standard handles for debugger: %s.", strerror (errno));
#include <sys/types.h> #include <regex.h> int regcomp(regex_t *preg, const char *pattern, int cflags);
This function is part of the implementation of POSIX 1003.2 regular expressions (REs).
regcomp
compiles the regular expression contained in the
pattern string, subject to the flags in cflags, and places
the results in the regex_t
structure pointed to by preg.
(The regular expression syntax, as defined by POSIX 1003.2, is
described below.)
The parameter cflags is the bitwise OR of zero or more of the following flags:
REG_EXTENDED
REG_BASIC
REG_EXTENDED
to improve readability.
This is an extension, compatible with but not specified by
POSIX 1003.2, and should be used with caution in software
intended to be portable to other systems.
REG_NOSPEC
REG_EXTENDED
and
REG_NOSPEC
may not be used in the same call to regcomp
.
REG_ICASE
REG_NOSUB
REG_NEWLINE
[^
bracket expressions and .
never match newline, a ^
anchor matches the null string after any
newline in the string in addition to its normal function, and the
$
anchor matches the null string before any newline in the string
in addition to its normal function.
REG_PEND
re_endp
member of the structure
pointed to by preg. The re_endp
member is of type
const char *
. This flag permits inclusion of NULs in the RE;
they are considered ordinary characters. This is an extension,
compatible with but not specified by POSIX 1003.2, and should be
used with caution in software intended to be portable to other systems.
When successful, regcomp
returns 0 and fills in the structure
pointed to by preg. One member of that structure (other than
re_endp
) is publicized: re_nsub
, of type size_t
,
contains the number of parenthesized subexpressions within the RE
(except that the value of this member is undefined if the
REG_NOSUB
flag was used).
Note that the length of the RE does matter; in particular, there is a strong speed bonus for keeping RE length under about 30 characters, with most special characters counting roughly double.
If regcomp
succeeds, it returns zero; if it fails, it returns a
non-zero error code, which is one of these:
REG_BADPAT
REG_ECOLLATE
REG_ECTYPE
REG_EESCAPE
\
applied to unescapable character
REG_ESUBREG
REG_EBRACK
REG_EPAREN
REG_EBRACE
REG_BADBR
REG_ERANGE
REG_ESPACE
((((a{1,100}){1,100}){1,100}){1,100}){1,100}'
will
eventually run almost any existing machine out of swap space)
REG_BADRPT
REG_EMPTY
REG_ASSERT
regcomp
)
REG_INVARG
Regular expressions (REs), as defined in POSIX 1003.2, come
in two forms: modern REs (roughly those of egrep
; 1003.2 calls
these extended REs) and obsolete REs (roughly those of ed
;
1003.2 basic REs). Obsolete REs mostly exist for backward
compatibility in some old programs; they will be discussed at the end.
1003.2 leaves some aspects of RE syntax and semantics open; `(*)' marks
decisions on these aspects that may not be fully portable to other
1003.2 implementations.
A (modern) RE is one(*) or more non-empty(*) branches, separated
by |
. It matches anything that matches one of the branches.
A branch is one(*) or more pieces, concatenated. It matches a match for the first, followed by a match for the second, etc.
A piece is an atom possibly followed by a single(*) *
,
+
, ?
, or bound. An atom followed by *
matches a sequence of 0 or more matches of the atom. An atom followed
by +
matches a sequence of 1 or more matches of the atom. An
atom followed by ?
matches a sequence of 0 or 1 matches of the
atom.
A bound is {
followed by an unsigned decimal integer,
possibly followed by ,
possibly followed by another unsigned
decimal integer, always followed by }
. The integers must lie
between 0 and RE_DUP_MAX
(255(*)) inclusive, and if there are two
of them, the first may not exceed the second. An atom followed by a
bound containing one integer i
and no comma matches a sequence of
exactly i
matches of the atom. An atom followed by a bound
containing one integer i
and a comma matches a sequence of
i
or more matches of the atom. An atom followed by a bound
containing two integers i
and j
matches a sequence of
i
through j
(inclusive) matches of the atom.
An atom is a regular expression enclosed in ()
(matching a match
for the regular expression), an empty set of ()
(matching the
null string(*)), a bracket expression (see below), .
(matching any single character), ^
(matching the null string at
the beginning of a line), $
(matching the null string at the end
of a line), a \
followed by one of the characters
^.[$()|*+?{\\
(matching that character taken as an ordinary
character), a \
followed by any other character(*) (matching
that character taken as an ordinary character, as if the \
had
not been present(*)), or a single character with no other significance
(matching that character). A {
followed by a character other
than a digit is an ordinary character, not the beginning of a bound(*).
It is illegal to end an RE with \
.
A bracket expression is a list of characters enclosed in
[]
. It normally matches any single character from the list (but
see below). If the list begins with ^
, it matches any single
character (but see below) not from the rest of the list. If two
characters in the list are separated by -
, this is shorthand for
the full range of characters between those two (inclusive) in the
collating sequence, e.g. [0-9]
in ASCII matches any decimal
digit. It is illegal(*) for two ranges to share an endpoint,
e.g. a-c-e
. Ranges are very collating-sequence-dependent, and
portable programs should avoid relying on them.
To include a literal ]
in the list, make it the first character
(following a possible ^
). To include a literal -
, make it
the first or last character, or the second endpoint of a range. To use
a literal -
as the first endpoint of a range, enclose it in
[.
and .]
to make it a collating element (see below).
With the exception of these and some combinations using [
(see
next paragraphs), all other special characters, including \
,
lose their special significance within a bracket expression.
Within a bracket expression, a collating element (a character, a
multi-character sequence that collates as if it were a single character,
or a collating-sequence name for either) enclosed in [.
and
.]
stands for the sequence of characters of that collating
element. The sequence is a single element of the bracket expression's
list. A bracket expression containing a multi-character collating
element can thus match more than one character, e.g. if the collating
sequence includes a ch
collating element, then the RE
[[.ch.]]*c
matches the first five characters of "chchcc".
Within a bracket expression, a collating element enclosed in [=
and =]
is an equivalence class, standing for the sequences of
characters of all collating elements equivalent to that one, including
itself. (If there are no other equivalent collating elements, the
treatment is as if the enclosing delimiters were [.
and
.]
.) For example, if o
and ^
are the members of an
equivalence class, then [[=o=]]
, [[=^=]]
, and [o^]
are all synonymous. An equivalence class may not be an endpoint
of a range.
Within a bracket expression, the name of a character class
enclosed in [:
and :]
stands for the list of all characters
belonging to that class.
Standard character class names are:
alnum digit punct alpha graph space blank lower upper cntrl print xdigit
These stand for the character classes defined by isalnum
(see isalnum), isdigit
(see isdigit), ispunct
(see ispunct), isalpha
(see isalpha), isgraph
(see isgraph), isspace
(see isspace) (blank
is the
same as space
), islower
(see islower), isupper
(see isupper), iscntrl
(see iscntrl), isprint
(see isprint), and isxdigit
(see isxdigit),
respectively. A locale may provide others. A character class may not
be used as an endpoint of a range.
There are two special cases(*) of bracket expressions: the bracket
expressions [[:<:]]
and [[:>:]]
match the null string at the
beginning and end of a word respectively. A word is defined as a
sequence of word characters which is neither preceded nor followed by
word characters. A word character is an alnum
character (as
defined by isalnum
library function) or an underscore. This is
an extension, compatible with but not specified by POSIX 1003.2,
and should be used with caution in software intended to be portable to
other systems.
In the event that an RE could match more than one substring of a given string, the RE matches the one starting earliest in the string. If the RE could match more than one substring starting at that point, it matches the longest. Subexpressions also match the longest possible substrings, subject to the constraint that the whole match be as long as possible, with subexpressions starting earlier in the RE taking priority over ones starting later. Note that higher-level subexpressions thus take priority over their lower-level component subexpressions.
Match lengths are measured in characters, not collating elements. A
null string is considered longer than no match at all. For example,
bb*
matches the three middle characters of "abbbc",
(wee|week)(knights|nights)
matches all ten characters of
"weeknights", when (.*).*
is matched against "abc" the
parenthesized subexpression matches all three characters, and when
(a*)*
is matched against "bc" both the whole RE and the
parenthesized subexpression match the null string.
If case-independent matching is specified, the effect is much as if all
case distinctions had vanished from the alphabet. When an alphabetic
that exists in multiple cases appears as an ordinary character outside a
bracket expression, it is effectively transformed into a bracket
expression containing both cases, e.g. x
becomes [xX]
.
When it appears inside a bracket expression, all case counterparts of it
are added to the bracket expression, so that (e.g.) [x]
becomes
[xX]
and [^x]
becomes [^xX]
.
No particular limit is imposed on the length of REs(*). Programs intended to be portable should not employ REs longer than 256 bytes, as an implementation can refuse to accept such REs and remain POSIX-compliant.
Obsolete (basic) regular expressions differ in several respects.
|
, +
, and ?
are ordinary characters and there is no
equivalent for their functionality. The delimiters for bounds are
\{
and \}
, with {
and }
by themselves
ordinary characters. The parentheses for nested subexpressions are
\(
and \)
, with (
and )
by themselves
ordinary characters. ^
is an ordinary character except at the
beginning of the RE or(*) the beginning of a parenthesized
subexpression, $
is an ordinary character except at the end of
the RE or(*) the end of a parenthesized subexpression, and *
is
an ordinary character if it appears at the beginning of the RE or the
beginning of a parenthesized subexpression (after a possible leading
^
). Finally, there is one new type of atom, a back
reference: \
followed by a non-zero decimal digit d
matches the same sequence of characters matched by the dth
parenthesized subexpression (numbering subexpressions by the positions
of their opening parentheses, left to right), so that (e.g.)
\([bc]\)\1
matches "bb" or "cc" but not "bc".
This implementation of the POSIX regexp functionality was written by Henry Spencer.
The locale is always assumed to be the default one of 1003.2, and only the collating elements etc. of that locale are available.
regcomp
implements bounded repetitions by macro expansion,
which is costly in time and space if counts are large or bounded
repetitions are nested.
An RE like, say,
((((a{1,100}){1,100}){1,100}){1,100}){1,100}
,
will (eventually) run almost any existing machine out of swap space.
There are suspected problems with response to obscure error conditions. Notably, certain kinds of internal overflow, produced only by truly enormous REs or by multiply nested bounded repetitions, are probably not handled well.
Due to a mistake in 1003.2, things like a)b
are legal REs because
)
is a special character only in the presence of a previous
unmatched (
. This can't be fixed until the spec is fixed.
The standard's definition of back references is vague. For example,
does a\e(\e(b\e)*\e2\e)*d
match "abbbd"? Until the standard
is clarified, behavior in such cases should not be relied on.
not ANSI, POSIX
#include <sys/types.h> #include <regex.h> size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
regerror
maps a non-zero value of errcode from either
regcomp
(Return Value, see regcomp) or regexec
(Return Value, see regexec) to a human-readable, printable message.
If preg is non-NULL
, the error code should have arisen from
use of the variable of the type regex_t
pointed to by preg,
and if the error code came from regcomp
, it should have been the
result from the most recent regcomp
using that regex_t
variable. (regerror
may be able to supply a more detailed
message using information from the regex_t
than from
errcode alone.) regerror
places the NUL
-terminated
message into the buffer pointed to by errbuf, limiting the length
(including the NUL
) to at most errbuf_size bytes. If the
whole message won't fit, as much of it as will fit before the
terminating NUL
is supplied. In any case, the returned value is
the size of buffer needed to hold the whole message (including
terminating NUL
). If errbuf_size is 0, errbuf is
ignored but the return value is still correct.
If the errcode given to regerror
is first ORed with
REG_ITOA
, the "message" that results is the printable name of
the error code, e.g. "REG_NOMATCH", rather than an explanation
thereof. If errcode is REG_ATOI
, then preg shall be
non-NULL and the re_endp
member of the structure it points to
must point to the printable name of an error code
(e.g. "REG_ECOLLATE"); in this case, the result in errbuf is the
decimal representation of the numeric value of the error code (0 if the
name is not recognized). REG_ITOA
and REG_ATOI
are
intended primarily as debugging facilities; they are extensions,
compatible with but not specified by POSIX 1003.2, and should be
used with caution in software intended to be portable to other systems.
Be warned also that they are considered experimental and changes are
possible.
The size of buffer needed to hold the message (including terminating
NUL
) is always returned, even if errbuf_size is zero.
not ANSI, POSIX
#include <sys/types.h> #include <regex.h> int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
regexec
matches the compiled RE pointed to by preg against
the string, subject to the flags in eflags, and reports
results using nmatch, pmatch, and the returned value. The
RE must have been compiled by a previous invocation of regcomp
(see regcomp). The compiled form is not altered during execution of
regexec
, so a single compiled RE can be used simultaneously by
multiple threads.
By default, the NUL-terminated string pointed to by string is considered to be the text of an entire line, with the NUL indicating the end of the line. (That is, any other end-of-line marker is considered to have been removed and replaced by the NUL.)
The eflags argument is the bitwise OR of zero or more of the following flags:
REG_NOTBOL
^
anchor should not match before it. This does not affect the
behavior of newlines under REG_NEWLINE
(REG_NEWLINE,
see regcomp).
REG_NOTEOL
$
anchor
should not match before it. This does not affect the behavior of
newlines under REG_NEWLINE
(REG_NEWLINE, see regcomp).
REG_STARTEND
string + pmatch[0].rm_so
and to have a terminating NUL
located at
string + pmatch[0].rm_eo
(there need not actually
be a NUL
at that location), regardless of the value of nmatch.
See below for the definition of pmatch and nmatch. This is
an extension, compatible with but not specified by POSIX 1003.2,
and should be used with caution in software intended to be portable to
other systems. Note that a non-zero rm_so
does not imply
REG_NOTBOL
; REG_STARTEND
affects only the location of the
string, not how it is matched.
REG_TRACE
REG_LARGE
REG_BACKR
Regular Expressions' Syntax, See regcomp, for a discussion of what is matched in situations where an RE or a portion thereof could match any of several substrings of string.
If REG_NOSUB
was specified in the compilation of the RE
(REG_NOSUB, see regcomp), or if nmatch is 0, regexec
ignores the pmatch argument (but see below for the case where
REG_STARTEND
is specified). Otherwise, pmatch should point
to an array of nmatch structures of type regmatch_t
. Such
a structure has at least the members rm_so
and rm_eo
, both
of type regoff_t
(a signed arithmetic type at least as large as
an off_t
and a ssize_t
, containing respectively the offset
of the first character of a substring and the offset of the first
character after the end of the substring. Offsets are measured from the
beginning of the string argument given to regexec
. An
empty substring is denoted by equal offsets, both indicating the
character following the empty substring.
When regexec
returns, the 0th member of the pmatch array is
filled in to indicate what substring of string was matched by the
entire RE. Remaining members report what substring was matched by
parenthesized subexpressions within the RE; member i
reports
subexpression i
, with subexpressions counted (starting at 1) by
the order of their opening parentheses in the RE, left to right. Unused
entries in the array--corresponding either to subexpressions that did
not participate in the match at all, or to subexpressions that do not
exist in the RE (that is, i > preg->re_nsub
--have both
rm_so
and rm_eo
set to -1
. If a subexpression
participated in the match several times, the reported substring is the
last one it matched. (Note, as an example in particular, that when the
RE (b*)+
matches "bbb", the parenthesized subexpression
matches the three b
s and then an infinite number of empty
strings following the last b
, so the reported substring is one of the
empties.)
If REG_STARTEND
is specified in eflags, pmatch must
point to at least one regmatch_t
variable (even if nmatch
is 0 or REG_NOSUB
was specified in the compilation of the RE,
REG_NOSUB, see regcomp), to hold the input offsets for
REG_STARTEND
. Use for output is still entirely controlled by
nmatch; if nmatch is 0 or REG_NOSUB
was specified,
the value of pmatch[0]
will not be changed by a successful
regexec
.
Normally, regexec
returns 0 for success and the non-zero code
REG_NOMATCH
for failure. Other non-zero error codes may be
returned in exceptional situations. The list of possible error return
values is below:
REG_ESPACE
REG_BADPAT
regcomp
REG_INVARG
string + pmatch[0].rm_eo
is less
than string + pmatch[0].rm_so
)
This implementation of the POSIX regexp functionality was written by Henry Spencer.
regexec
performance is poor. nmatch exceeding 0 is
expensive; nmatch exceeding 1 is worse. regexec
is largely
insensitive to RE complexity except that back references are
massively expensive. RE length does matter; in particular, there is a
strong speed bonus for keeping RE length under about 30 characters, with
most special characters counting roughly double.
The implementation of word-boundary matching is a bit of a kludge, and bugs may lurk in combinations of word-boundary matching and anchoring.
not ANSI, POSIX
#include <sys/types.h> #include <regex.h> void regfree(regex_t *preg);
regfree
frees any dynamically-allocated storage associated with
the compiled RE pointed to by preg. The remaining regex_t
is no longer a valid compiled RE and the effect of supplying it to
regexec
or regerror
is undefined.
not ANSI, POSIX
#include <stdio.h> int remove(const char *file);
This function removes the named file from the file system. Unless you have an un-erase program, the file and its contents are gone for good.
Zero on success, nonzero on failure.
ANSI, POSIX
remove("/tmp/data.tmp");
#include <search.h> void remque(struct qelem *elem);
This function manipulates queues built from doubly linked lists. Each element
in the queue must be in the form of struct qelem
which is defined
thus:
struct qelem { struct qelem *q_forw; struct qelem *q_back; char q_data[0]; }
This function removes the entry elem from a queue.
None.
not ANSI, not POSIX
#include <stdio.h> int _rename(const char *oldname, const char *newname);
This function renames an existing file or directory oldname to
newname. It is much smaller that rename
(see rename),
but it can only rename a directory so it stays under the same parent, it
cannot move directories between different branches of the directory
tree. This means that in the following example, the first call will
succeed, while the second will fail:
_rename("c:/path1/mydir", "c:/path1/yourdir"); _rename("c:/path1/mydir", "c:/path2");
On systems that support long filenames (see _use_lfn),
_rename
can also move directories (so that both calls in the
above example succeed there), unless the LFN
environment variable
is set to n, or the _CRT0_FLAG_NO_LFN
is set in the
_crt0_startup_flags
variable, See _crt0_startup_flags.
If you don't need the extra functionality offered by rename
(which usually is only expected by Unix-born programs), you can use
_rename
instead and thus make your program a lot smaller.
Zero on success, nonzero on failure.
not ANSI, not POSIX
#include <stdio.h> int rename(const char *oldname, const char *newname);
This function renames an existing file or directory oldname to
newname. If newname exists, then it is first removed. If
newname is a directory, it must be empty (or else errno will
be set to ENOTEMPTY
), and must not include oldname in its
path prefix (otherwise, errno will be set to EINVAL
). If
newname exists, both oldname and newname must be of the
same type (both directories or both regular files) (or else errno
will be set to ENOTDIR
or EISDIR
), and must reside on the
same logical device (otherwise, errno will be set to EXDEV
).
Wildcards are not allowed in either oldname or newname. DOS
won't allow renaming a current directory even on a non-default drive (you
will get the EBUSY
or EINVAL
in errno).
ENAMETOOLONG
will be returned for pathnames which are longer than
the limit imposed by DOS. If oldname doesn't exist, errno
will be set to ENOENT
. For most of the other calamities, DOS will
usually set errno to EACCES
.
If anything goes wrong during the operation of rename()
, the
function tries very hard to leave the things as ther were before it was
invoked, but it might not always succeed.
Zero on success, nonzero on failure.
ANSI, POSIX
rename("c:/mydir/some.doc", "c:/yourdir/some.sav"); rename("c:/path1/mydir", "c:/path2");
#include <stdio.h> void rewind(FILE *file);
This function repositions the file pointer to the beginning of the file and clears the error indicator.
None.
ANSI, POSIX
rewind(stdin);
#include <dirent.h> void rewinddir(DIR *dir);
This function resets the position of the dir so that the next call
to readdir
(see readdir) starts at the beginning again.
None.
not ANSI, POSIX
DIR *d = opendir("."); rewinddir(d);
#include <strings.h> char *rindex(const char *string, int ch);
Returns a pointer to the last occurrence of ch in string.
Note that the NULL
character counts, so if you pass zero as
ch you'll get a pointer to the end of the string back.
A pointer to the character, or NULL
if it wasn't found.
not ANSI, not POSIX
char *last_slash = rindex(filename, '/');
#include <unistd.h> int rmdir(const char *dirname);
This function removes directory dirname. The directory must be empty.
Zero if the directory was removed, nonzero on failure.
not ANSI, POSIX
rmdir("/tmp/datadir");
#include <debug/dbgcom.h> void run_child (void);
This function starts or resumes the debugged program, via a
longjmp
to the debuggee's code. When the debuggee hits a
breakpoint, or exits normally, the exception handler that is called to
service the breakpoint exception will longjmp
back to
run_child
, and it will then return to the caller.
After run_child
returns, the debugger usually examines the
a_tss
variable to find out the reason the debuggee stopped. The
a_tss
variable is defined by the header debug/tss.h
as
follows:
typedef struct TSS { unsigned short tss_back_link; unsigned short res0; unsigned long tss_esp0; unsigned short tss_ss0; unsigned short res1; unsigned long tss_esp1; unsigned short tss_ss1; unsigned short res2; unsigned long tss_esp2; unsigned short tss_ss2; unsigned short res3; unsigned long tss_cr3; unsigned long tss_eip; unsigned long tss_eflags; unsigned long tss_eax; unsigned long tss_ecx; unsigned long tss_edx; unsigned long tss_ebx; unsigned long tss_esp; unsigned long tss_ebp; unsigned long tss_esi; unsigned long tss_edi; unsigned short tss_es; unsigned short res4; unsigned short tss_cs; unsigned short res5; unsigned short tss_ss; unsigned short res6; unsigned short tss_ds; unsigned short res7; unsigned short tss_fs; unsigned short res8; unsigned short tss_gs; unsigned short res9; unsigned short tss_ldt; unsigned short res10; unsigned short tss_trap; unsigned char tss_iomap; unsigned char tss_irqn; unsigned long tss_error; } TSS; extern TSS a_tss;
See the example below for a typical tests after run_child
returns.
Note that, generally, you'd need to save the standard handles before
calling run_child
and restore them after it returns. Otherwise,
if the debuggee redirects one of its standard handles, the corresponding
debugger's standard handle is redirected as well.
See redir_to_child, and see redir_to_debugger.
not ANSI, not POSIX
save_npx (); run_child (); load_npx (); if (a_tss.tss_irqn == 0x21) { status = DEBUGGEE_EXITED; exit_code = a_tss.tss_eax & 0xff; } else { status = DEBUGGEE_GOT_SIGNAL if (a_tss.tss_irqn == 0x75) signal_number = SIGINT; else if (a_tss.tss_irqn == 1 || a_tss.tss_irqn == 3) signal_number = SIGTRAP; /* a breakpoint */ }
#include <debug/dbgcom.h> extern NPX npx; void save_npx (void);
This function saves the state of the x87 numeric processor in the
external variable npx
. This variable is a structure defined as
follows in the header debug/dbgcom.h
:
typedef struct { unsigned short sig0; unsigned short sig1; unsigned short sig2; unsigned short sig3; unsigned short exponent:15; unsigned short sign:1; } NPXREG; typedef struct { unsigned long control; unsigned long status; unsigned long tag; unsigned long eip; unsigned long cs; unsigned long dataptr; unsigned long datasel; NPXREG reg[8]; long double st[8]; char st_valid[8]; long double mmx[8]; char in_mmx_mode; char top; } NPX;
save_npx
should be called immediately before run_child
(see run_child) is called to begin or resume the debugged program.
To restore the x87 state when control is returned to the debugger, call
load_npx
, see load_npx.
not ANSI, not POSIX
save_npx (); run_child (); load_npx ();
#include <unistd.h> void *sbrk(int delta)
This function changes the "break" of the program by adding delta
to it. This is the highest address that your program can access without
causing a violation. Since the heap is the region under the break, you
can expand the heap (where malloc
gets memory from) by increasing
the break.
This function is normally accessed only by malloc
(see malloc).
The address of the first byte outside of the previous valid address range, or -1 if no more memory could be accessed. In other words, a pointer to the chunk of heap you just allocated, if you had passed a positive number.
not ANSI, not POSIX
char *buf; buf = sbrk(1000); /* allocate space */
#include <stdio.h> int scanf(const char *format, ...);
This function scans formatted text from stdin
and stores it in
the variables pointed to by the arguments. See scanf.
The format string contains regular characters which much match the input
exactly as well as a conversion specifiers, which begin with a percent
symbol. Any whitespace in the format string matches zero or more of any
whitespace characters in the input. Thus, a single space may match a
newline and two tabs in the input. All conversions except c
and
[
also skip leading whitespace automatically. Each conversion
specifier contains the following fields:
*
) which indicates that the input should be
converted according to the conversion spec, but not stored anywhere.
This allows to describe an input field that is to be skipped.
h
to specify
short
, l
to specify doubles or long ints, or L
or
ll
(two lower-case ell letters) to specify long doubles and the
long long type. If the h
qualifier appears before a specifier
that implies conversion to a long
or float
or
double
, like in %hD
or %hf
, it is generally
ignored.
c
%1s
to read the next non-whitespace character. Unlike with
%s
, the copied characters are not terminated with a null
character. If the width parameter is not specified, a width
of one is implied.
d
int
using 10 as the base of the
number representation.
hd
short
using 10 as the base.
ld
D
long
using 10 as the base.
Ld
lld
lD
long long
using 10 as the base.
e
E
f
F
g
G
float
).
le
lE
lf
lF
lg
lG
double
.
Le
LE
lle
llE
Lf
LF
llf
llF
Lg
LG
llg
llG
long double
.
i
0x
or 0
prefixes, and store in an int
.
See strtol.
hi
i
, but stores the result in a short
.
li
I
i
, but stores the result in a long
.
Li
lli
lI
i
, but stores the result in a long long
.
n
int
pointed to by the argument.
hn
n
, but the argument should point to a short
.
ln
n
, but the argument should point to a long
.
Ln
lln
n
, but the argument should point to a long long
.
o
int
, using base 8.
ho
short
, using base 8.
lo
O
long
, using base 8.
Lo
llo
lO
long long
, using base 8.
p
x
format.
s
u
int
using 10 as the base.
hu
short
using 10 as the base.
lu
U
long
using 10 as the base.
Lu
llu
lU
long long
using 10 as the base.
x
X
int
, using base 16.
hx
hX
short
, using base 16.
lx
lX
long
, using base 16.
Lx
LX
llx
llX
long long
, using base 16.
[...]
char
array, followed by a
terminating null character. If you do not specify the width
parameter, scanf
behaves as if width had a very large
value. Up to width characters are consumed and assigned, provided
that they match the specification inside the brackets. The characters
between the brackets determine which characters are allowed, and thus
when the copying stops. These characters may be regular characters
(example: [abcd]
) or a range of characters (example:
[a-d]
). If the first character is a caret (^
), then the
set specifies the set of characters that do not get copied (i.e. the
set is negated). To specify that the set contains a close-bracket
(]
), put it immediately after [
or [^
. To specify
a literal dash (-
), write it either immediately after [
or
[^
, or immediately before the closing ]
.
%
Integer formats make use of strtol
or strtoul
to perform
the actual conversions. Floating-point conversions use strtod
and _strtold
.
The number of items successfully matched and assigned. If input ends,
or if there is any input failure before the first item is converted and
assigned, EOF
is returned. Note that literal characters
(including whitespace) in the format string which matched input
characters count as "converted items", so input failure after
such characters were read and matched will not cause EOF
to be returned.
ANSI (see note 1), POSIX
Notes:
F
, D
, I
, O
, and U
are DJGPP extensions; they are provided for compatibility with Borland C and other compilers. The conversion specifiers for the long long
data type are GCC extensions. The meaning of [a-c]
as a range of characters is a very popular extension to ANSI (which merely says a dash "may have a special meaning" in that context).
int x, y; char buf[100]; scanf("%d %d %s", &x, &y, buf); /* read to end-of-line */ scanf("%d %[^\n]\n", &x, buf); /* read letters only */ scanf("[a-zA-Z]", buf);
#include <go32.h> #include <pc.h> unsigned long ScreenPrimary; unsigned long ScreenSecondary; extern unsigned char ScreenAttrib;
The first two variables (actually, they are #define'd aliases to fields in the _go32_info_block structure see _go32_info_block) allow access to the video memory of the primary and secondary screens as if they were arrays. To reference them, you must use dosmemget()/dosmemput() functions (dosmemget, dosmemput) or any one of the far pointer functions (see _far*), as the video memory is not mapped into your default address space.
The variable ScreenAttrib holds the current attribute which is in use by the text screen writes. The attribute is constructed as follows:
bits 0-3 - foreground color;
bits 4-6 - background color;
bit 7 - blink on (1) or off (0).
_farpokew(_dos_ds, ScreenPrimary, ( ((unsigned short) attr) << 8) + char ));
#include <pc.h> void ScreenClear(void);
This function clears the text screen. It overwrites it by blanks with the current background and foreground as specified by ScreenAttrib (see Screen Variables).
None.
not ANSI, not POSIX
ScreenClear();
#include <pc.h> int ScreenCols(void);
This function returns the number of columns of the screen. It does so by looking at the byte at the absolute address 40:4Ah in the BIOS area. In text modes, the meaning of number of columns is obvious; in graphics modes, this value is the number of columns of text available when using the video BIOS functions to write text.
The number of columns.
not ANSI, not POSIX
int available_columns = ScreenCols();
#include <pc.h> void ScreenGetChar(int *ch, int *attr, int col, int row);
This function stores the character and attribute of the current
primary screen at row given by row and column given by col
(these are zero-based) into the integers whose address is specified by
ch and attr. It does so by directly accessing the video memory,
so it will only work when the screen is in text mode. You can pass the value
NULL
in each of the pointers if you do not want to retrieve the
the corresponding information.
Warning: note that both the variables ch and attr are
pointers to an int
, not to a char
! You must pass
a pointer to an int
there, or your program will crash or work
erratically.
None.
not ANSI, not POSIX
int ch, attr; ScreenGetChar(&ch, &attr, 0, 0);
#include <pc.h> void ScreenGetCursor(int *row, int *column);
This function retrieves the current cursor position of the default video page by calling function 3 of the interrupt 10h, and stores it in the variables pointed by row and column.
None.
not ANSI, not POSIX
ScreenGetCursor(&wherex, &wherey);
#include <pc.h> int ScreenMode(void);
This function reports the current video mode as known to the system BIOS. It does so by accessing the byte at absolute address 40:49h.
The video mode.
not ANSI, not POSIX
video_mode = ScreenMode();
#include <pc.h> void ScreenPutChar(int ch, int attr, int col, int row);
This function writes the character whose value is specified in ch with an attribute attr at row given by row and column given by col, which are zero-based. It does so by directly accessing the video memory, so it will only work when the screen is in text mode.
None.
not ANSI, not POSIX
ScreenPutChar('R', (BLUE << 4) | LIGHTMAGENTA, 75, 0);
#include <pc.h> void ScreenPutString(const char *str, int attr, int column, int row);
Beginning at screen position given by column and row, this function displays the string given by str. Each string character gets the attribute given by attr. If column or row have values outside legal range for current video mode, nothing happens. The variables row and column are zero-based (e.g., the topmost row is row 0).
None.
not ANSI, not POSIX
ScreenPutString("Hello, world!", (BLUE << 4) | LIGHTBLUE, 20, 10);
#include <pc.h> void ScreenRetrieve(void *buf);
This function stores a replica of the current primary screen contents in
the buffer pointed to by buf. It assumes without checking that
buf has enough storage to hold the data. The required storage can
be computed as ScreenRows()*ScreenCols()*2
(ScreenRows,
ScreenCols).
None.
not ANSI, not POSIX
unsigned *saved_screen = (unsigned *)alloca(ScreenRows()*ScreenCols()*2; ScreenRetrieve(saved_screen);
#include <pc.h> int ScreenRows(void);
This function returns the number of rows of the text screen. It does so by looking at the byte at the absolute address 40:84h in the BIOS area. This method works only for video adapters with their own BIOS extensions, like EGA, VGA, SVGA etc.
The number of rows.
not ANSI, not POSIX
int rows = ScreenRows();
#include <pc.h> void ScreenSetCursor(int row, int column);
This function moves the cursor position on the default video page to the point given by (zero-based) row and column, by calling function 2 of interrupt 10h.
None.
not ANSI, not POSIX
ScreenSetCursor(0, 0); /* home the cursor */
#include <pc.h> void ScreenUpdate(void *buf);
This function writes the contents of the buffer buf to the primary screen. The buffer should contain an exact replica of the video memory, including the characters and their attributes.
None.
not ANSI, not POSIX
ScreenUpdate(saved_screen);
#include <pc.h> void ScreenUpdateLine(void *buf, int row);
This function writes the contents of buf to the screen line number given in row (the topmost line is row 0), on the primary screen.
None.
not ANSI, not POSIX
ScreenUpdateLine(line_buf, 10);
#include <pc.h> void ScreenVisualBell(void);
This function flashes the screen colors to produce the effect of "visual bell'. It does so by momentarily inverting the colors of every character on the screen.
None.
not ANSI, not POSIX
ScreenVisualBell();
#include <dir.h> char * searchpath(const char *file);
Given a name of a file in file, searches for that file in a list
of directories, including the current working directory and directories
listed in the PATH
environment variable, and if found, returns
the file name with leading directories prepended, so that the result can
be used to access the file (e.g. by calling open
or stat
).
If file includes a drive letter or leading directories,
searchpath
first tries that name unaltered, in case it is already
a fully-qualified path, or is relative to the current working
directory. If that fails, it tries every directory in PATH
in
turn. Note that this will find e.g. c:/foo/bar/baz.exe
if you
pass bar/baz.exe
to searchpath
and if c:/foo
is
mentioned in PATH
.
When successfull, the function returns a pointer to a static buffer
where the full pathname of the found file is stored. Otherwise, it
returns NULL
. (The static buffer is overwritten on each call.)
not ANSI, not POSIX
This function is provided for compatibility with Borland's library.
However, note that the Borland version disregards the leading
directories altogether and searches for the basename only. Thus, it
will happily find e.g. c:/foo/bar/baz.exe
, even if the directory
c:/foo/bar
doesn't exist, provided that baz.exe
is
somewhere on your PATH
. We think this is a bug, so DJGPP's
implementation doesn't behave like that.
printf("%s was found as %s\n", argv[1], searchpath(argv[1]));
#include <dirent.h> void seekdir(DIR *dir, long loc);
This function sets the location pointer in dir to the specified
loc. Note that the value used for loc should be either zero
or a value returned by telldir
(see telldir). The next call
to readdir
(see readdir) will read whatever entry follows that
point in the directory.
None.
not ANSI, not POSIX
int q = telldir(dir); do_stuff(); seekdir(dir, q);
#include <time.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
This function waits for files to be ready for input or output, or to have exceptional condition pending, or for a timeout.
Each fd_set
variable is a bitmap representation of a set of file
descriptors, one bit for every descriptor. The following macros shall
be used to deal with these sets:
FD_ZERO(p)
FD_SET(n, p)
FD_CLR(n, p)
FD_ISSET(n, p)
FD_SETSIZE
The nfds parameter is the number of bits to be examined in each of
the fd_set
sets: the function will only check file descriptors
0
through nfds - 1
, even if some bits are set for
descriptors beyond that.
On input, some of the bits of each one of the fd_set
sets for
which the function should wait, should be set using the FD_SET
macro. select
examines only those descriptors whose bits are
set.
Any of readfds
, writefds
, and exceptfds
can be a
NULL
pointer, if the caller is not interested in testing the
corresponding conditions.
On output, if select
returns a non-negative value, each
non-NULL
argument of the three sets will be replaced with a
subset in which a bit is set for every descriptor that was found to be,
respectively, ready for input, ready for output, and pending an
exceptional condition. Note that if select
returns -1, meaning a
failure, the descriptor sets are unchanged, so you should always
test the return value before looking at the bits in the returned sets.
The timeout value may be a NULL pointer (no timeout, i.e., wait
forever), a pointer to a zero-value structure (poll mode, i.e., test
once and exit immediately), or a pointer to a struct timeval
variable (timeout: select
will repeatedly test all the
descriptors until some of them become ready, or the timeout expires).
struct timeval
is defined as follows:
struct timeval { time_t tv_sec; long tv_usec; };
On successfull return, select
returns the number of files ready,
or 0, if the timeout expired. The input sets are replaced with subsets
that describe which files are ready for which operations. If
select
returns 0 (i.e., the timeout has expired), all the
non-NULL
sets have all their bits reset to zero.
On failure, select
returns -1, sets errno
to a suitable
value, and leaves the descriptor sets unchanged.
not ANSI, not POSIX
struct timeval timeout; fd_set read_fds, write_fds; int i, select_result; timeout.tv_sec = 5; /* 5-second timeout */ timeout.tv_usec = 0; /* Display status of the 5 files open by default. */ for (i = 0; i < 5; i++) { FD_ZERO (&read_fds); FD_SET (i, &read_fds); select_result = select (i + 1, &read_fds, 0, 0, &timeout); if (select_result == -1) { fprintf(stderr, "%d: Failure for input", i); perror(""); } else fprintf(stderr, "%d: %s ready for input\n", i, select_result ? "" : "NOT"); FD_ZERO (&write_fds); FD_SET (i, &write_fds); select_result = select (i + 1, 0, &write_fds, 0, &timeout); if (select_result == -1) { fprintf(stderr, "%d: Failure for output", i); perror(""); } else fprintf(stderr, "%d: %s ready for output\n", i, select_result ? "" : "NOT"); }
The following notes describe some details pertinent to the DJGPP
implementation of select
:
select
waits for the timeout to expire, it repeatedly calls
the __dpmi_yield
function (see __dpmi_yield), so that any
other programs that run at the same time (e.g., on Windows) get more CPU
time.
FILE
object created by
fopen
or fdopen
(see fopen) for which feof
or
ferror
return non-zero, will be reported in the exceptfds
set; also, such a handle will be reported not input-ready if there are
no pending buffered characters in the FILE
object. This might be
a feature or a bug, depending on your point of view; in particular, Unix
implementations usually don't check buffered input. Portable programs
should refrain from mixing select
with buffered I/O.
exceptfds
.
writefds
is only meaningful
for character devices.
select
will indicate that file handle 0 is ready for input, but a
call to getc
will still block until the <Enter> key is
pressed. If you need to make sure that reading a single character won't
block, you should read either with BIOS functions such as getkey
(see getkey, or with raw input DOS functions such as getch
(see getch), or switch the handle to binary mode with a call to
setmode
(see setmode).
#include <conio.h> void _set_screen_lines(int nlines);
This function sets the text screen width to 80 and its height to the
value given by nlines, which can be one of the following: 25, 28,
35, 40, 43 or 50. On a CGA, only 25-line screen is supported. On an
EGA, you can use 25, 35 and 43. VGA, PGA and MCGA support all of the
possible dimensions.
The number of columns (i.e., screen width) is 80 for all of the above
resolutions, because the standard EGA/VGA has no way of changing it.
After this function returns, calls to gettextinfo()
will return
the actual screen dimensions as set by _set_screen_lines()
.
That is, you can e.g. test whether _set_screen_lines()
succeeded
by checking the screen height returned by gettextinfo()
against
the desired height.
This function has a side effect of erasing the screen contents, so
application programs which use it should make their own arrangements to
redisplay it.
not ANSI, not POSIX
#include <stdio.h> void setbuf(FILE *file, char *buffer);
This function modifies the buffering characteristics of file.
First, if the file already has a buffer, it is freed. If there was any
pending data in it, it is lost, so this function should only be used
immediately after a call to fopen
.
If the buffer passed is NULL
, the file is set to
unbuffered. If a non-NULL
buffer is passed, it must be at least
BUFSIZ
bytes in size, and the file is set to fully buffered.
See setbuffer. See setlinebuf. See setvbuf.
None.
ANSI, POSIX
setbuf(stdout, malloc(BUFSIZ));
#include <stdio.h> void setbuffer(FILE *file, char *buffer, int length);
This function modifies the buffering characteristics of file.
First, if the file already has a buffer, it is freed. If there was any
pending data in it, it is lost, so this function should only be used
immediately after a call to fopen
.
If the buffer passed is NULL
, the file is set to
unbuffered. If a non-NULL
buffer is passed, it must be at least
size bytes in size, and the file is set to fully buffered.
See setbuf. See setlinebuf. See setvbuf.
None.
not ANSI, not POSIX
setbuffer(stdout, malloc(10000), 10000);
#include <dos.h> void setcbrk(int check);
Set the setting of the Ctrl-Break checking flag in MS-DOS. If check is zero, checking is not done. If nonzero, checking is done.
None.
not ANSI, not POSIX
#include <conio.h> void _setcursortype(int _type);
Sets the cursor type. _type is one of the following:
_NOCURSOR
_SOLIDCURSOR
_NORMALCURSOR
not ANSI, not POSIX
#include <dos.h> void setdate(struct date *ptr);
This function sets the current time.
For the description of struct date
, see getdate. Also see
settime.
None.
not ANSI, not POSIX
struct date d; setdate(&d);
#include <dir.h> int setdisk(int drive);
This function sets the current disk (0=A).
See also getdisk.
The highest drive actually present that the system can reference.
not ANSI, not POSIX
printf("There are %d drives\n", setdisk(getdisk()));
#include <stdlib.h> int setenv(const char *name, const char *value, int rewrite);
This function sets the environment variable name to value. If rewrite is set, then this function will replace any existing value. If it is not set, it will only put the variable into the environment if that variable isn't already defined.
Zero on success, -1 on failure.
not ANSI, not POSIX
#include <dos.h> int setftime(int handle, struct ftime *ftimep);
This function sets the modification time of a file. Note that since writing to a file, and closing a file opened for writing, also sets the modification time, you should only use this function on files opened for reading.
See getftime, for the description of struct ftime
.
Zero on success, nonzero on failure.
not ANSI, not POSIX
int q = open("data.txt", O_RDONLY); struct ftime f; f.ft_sec = f.ft_min = f.ft_hour = f.ft_day = f.ft_month = f.ft_year = 0; setftime(q, &f); close(q);
#include <unistd.h> int setgid(gid_t gid);
This function is simulated, since MS-DOS does not support group IDs.
If gid is equal to that returned by see getgid, returns zero.
Otherwise, returns -1 and sets errno
to EPERM.
not ANSI, POSIX
#include <grp.h> void setgrent(void);
This function should be called before any call to getgrent
,
getgrgid
, or getgrnam
, to start searching the groups' list
from the beginning. See getgrent.
None.
not ANSI, not POSIX
#include <sys/time.h> extern long __djgpp_clock_tick_interval; struct timeval { time_t tv_sec; long tv_usec; }; struct itimerval { struct timeval it_interval; /* timer interval */ struct timeval it_value; /* current value */ }; int setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
Each process has two interval timers, ITIMER_REAL
and
ITIMER_PROF
, which raise the signals SIGALRM
and
SIGPROF
, respectively. These are typically used to provide
alarm
and profiling capabilities.
This function changes the current value of the interval timer specified by
which to the values in structure value. The previous value
of the timer is returned in ovalue if it is not a NULL
pointer. When the timer expires, the appropriate signal is raised.
If value is a NULL
pointer, setitimer
stores the
previous timer value in ovalue (if it is non-NULL
), like
getitimer
does, but otherwise does nothing.
A timer is defined by the itimerval
structure. If the
it_value
member is non-zero it specifies the time to the next
timer expiration. If it_interval
is non-zero, it specifies the
value with which to reload the timer upon expiration. Setting
it_value
to zero disables a timer. Setting it_interval
to
zero causes the timer to stop after the next expiration (assuming that
it_value
is non-zero).
Although times can be given with microsecond resolution, the granularity
is determined by the timer interrupt frequency. Time values smaller
than the system clock granularity will be rounded up to that
granularity, before they are used. This means that passing a very small
but non-zero value in value->it_interval.tv_usec
will cause the
system clock granularity to be stored and returned by the next call to
getitimer
. See the example below.
If an application changes the system clock speed by reprogramming the
timer chip, it should make the new clock speed known to
setitimer
, otherwise intervals smaller than the default PC clock
speed cannot be set with a call to setitimer
due to rounding up
to clock granularity. To this end, an external variable
__djgpp_clock_tick_interval
is provided, which should be set to
the number of microseconds between two timer ticks that trigger
Interrupt 8. The default value of this variable is -1
, which
causes setitimer
to work with 54926 microsecond granularity that
corresponds to the standard 18.2Hz clock frequency. The library
never changes the value of __djgpp_clock_tick_interval
.
Returns 0 on success, -1 on failure (and sets errno
).
not ANSI, not POSIX
This version uses uclock
(see uclock) to determine the time
of expiration. Under Windows 3.X, this fails because the OS reprograms
the timer. Under Windows 9X, uclock
sometimes reports
erratic (non-increasing) time values; in these cases the timer might
fire at a wrong time.
A misfeature of Windows 9X prevents the timer tick interrupt from being delivered to programs that are in the background (i.e. don't have the focus), even though the program itself might continue to run, if you uncheck the Background: Always suspend property in the Property Sheets. Therefore, the timers will not work in background programs on Windows 9X.
Also, debuggers compiled with DJGPP v2.02 and earlier cannot cope with
timers and report SIGSEGV
or SIGABRT
, since signals were
not supported in a debugged program before DJGPP v2.03.
/* Find out what is the system clock granularity. */ struct itimerval tv; tv.it_interval.tv_sec = 0; tv.it_interval.tv_usec = 1; tv.it_value.tv_sec = 0; tv.it_value.tv_usec = 0; setitimer (ITIMER_REAL, &tv, 0); setitimer (ITIMER_REAL, 0, &tv); printf ("System clock granularity: %ld microseconds.\n", tv.it_interval.tv_usec);
#include <setjmp.h> int setjmp(jmp_buf j);
This function stores the complete CPU state into j. This
information is complete enough that longjmp
(see longjmp) can
return the program to that state. It is also complete enough to
implement coroutines.
This function will return zero if it is returning from it's own call. If longjmp is used to restore the state, it will return whatever value was passed to longjmp, except if zero is passed to longjmp it will return one.
ANSI, POSIX
jmp_buf j; if (setjmp(j)) return; do_something(); longjmp(j, 1);
#include <stdio.h> void setlinebuf(FILE *file);
This function modifies the buffering characteristics of file.
First, if the file already has a buffer, it is freed. If there was any
pending data in it, it is lost, so this function should only be used
immediately after a call to fopen
.
Next, a buffer is allocated and the file is set to line buffering.
See setbuf. See setlinebuf. See setvbuf.
None.
not ANSI, not POSIX
setlinebuf(stderr);
#include <locale.h> char *setlocale(int category, const char *locale);
This function sets part or all of the current locale. The category is one of the following:
LC_ALL
LC_COLLATE
LC_CTYPE
LC_MONETARY
LC_NUMERIC
LC_TIME
The locale should be the name of the current locale. Currently, only the "C" and "POSIX" locales are supported. If the locale is NULL, no action is performed. If locale is "", the locale is identified by environment variables (currently not supported).
See localeconv.
A static string naming the current locale for the given category, or NULL if the requested locale is not supported.
ANSI, POSIX
setlocale(LC_ALL, "C");
#include <mntent.h> FILE *setmntent(char *filename, const char *mode);
This function returns an open FILE* pointer which can be used by
getmntent (see getmntent). The arguments filename and
mode are always ignored under MS-DOS, but for portability should
be set, accordingly, to the name of the file which describes the mounted
filesystems and the open mode of that file (like the mode argument
to fopen
, see fopen). (There is no single standard for the
name of the file that keeps the mounted filesystems, but it is usually,
although not always, listed in the header <mntent.h>
.)
The FILE*
pointer is returned. For MS-DOS, this FILE*
is
not a real pointer and may only be used by getmntent
.
not ANSI, not POSIX
#include <mntent.h> #if defined(MNT_MNTTAB) #define MNTTAB_FILE MNT_MNTTAB #elif defined(MNTTABNAME) #define MNTTAB_FILE MNTTABNAME #else #define MNTTAB_FILE "/etc/mnttab" #endif FILE *mnt_fp = setmntent (MNTTAB_FILE, "r");
#include <io.h> int setmode(int file, int mode);
This function sets the mode of the given file to mode, which
is either O_TEXT
or O_BINARY
. It will also set the file
into either cooked or raw mode accordingly, and set any FILE*
objects that use this file into text or binary mode.
When called to put file that refers to the console into binary
mode, setmode
will disable the generation of the signals
SIGINT
and SIGQUIT
when you press, respectively,
Ctrl-<C> and Ctrl-<\> (Ctrl-<BREAK> will
still cause SIGINT
), because many programs that use binary reads
from the console will also want to get the ^C
and ^\
keys.
You can use the __djgpp_set_ctrl_c
library function
(see __djgpp_set_ctrl_c) if you want Ctrl-<C> and
Ctrl-<\> to generate signals while console is read in
binary mode.
Note that, for buffered streams (FILE*
), you must call
fflush
(see fflush) before setmode
, or call
setmode
before writing anything to the file, for proper
operation.
When successful, the function will return the previous mode of the given file. In case of failure, -1 is returned and errno is set.
not ANSI, not POSIX
setmode(0, O_BINARY);
#include <unistd.h> int setpgid(pid_t _pid, pid_t _pgid);
-1 (EPERM) if _pgid is not your current pid, else zero.
not ANSI, POSIX
#include <pwd.h> void setpwent(void);
This function reinitializes getpwent
so that scanning will start
from the start of the list. See getpwent.
None.
not ANSI, not POSIX
#include <sys/resource.h> int setrlimit (int rltype, const struct rlimit *rlimitp);
This function sets new limit pointed to by rlimitp on the resource limit specified by rltype. Note that currently it always fails.
Zero on success, nonzero on failure.
not ANSI, not POSIX
#include <unistd.h> pid_t setsid(void);
This function does not do anything. It exists to assist porting from Unix.
Return value of see getpid.
not ANSI, POSIX
#include <stdlib.h> char *setstate(char *arg_state);
Restores the random number generator (see random) state from pointer arg_state to state array.
Pointer to old state information.
not ANSI, not POSIX
#include <dos.h> void settime(struct time *ptr);
This function sets the current time.
For the description of struct time
, see gettime. Also see
setdate.
None.
not ANSI, not POSIX
struct time t; settime(&t);
#include <time.h> int settimeofday(struct timeval *tp, ...);
Sets the current GMT time. For compatibility, a second argument is accepted. See gettimeofday, for information on the structure types.
Zero if the time was set, nonzero on error.
not ANSI, not POSIX
#include <unistd.h> int setuid(uid_t uid);
This function is simulated, since MS-DOS does not support user IDs.
If uid is equal to that returned by see getuid, returns zero.
Otherwise, returns -1 and sets errno
to EPERM.
not ANSI, POSIX
#include <stdio.h> int setvbuf(FILE *file, char *buffer, int type, int length);
This function modifies the buffering characteristics of file.
First, if the file already has a buffer, it is freed. If there was any
pending data in it, it is lost, so this function should only be used
immediately after a call to fopen
.
If the type is _IONBF
, the buffer and length
are ignored and the file is set to unbuffered mode.
If the type is _IOLBF
or _IOFBF
, then the file is
set to line or fully buffered, respectively. If buffer is
NULL
, a buffer of size size is created and used as the
buffer. If buffer is non-NULL
, it must point to a buffer
of at least size size and will be used as the buffer.
See setbuf. See setbuffer. See setlinebuf.
Zero on success, nonzero on failure.
ANSI, POSIX
setvbuf(stderr, NULL, _IOLBF, 1000);
#include <signal.h> int sigaction (int sig, const struct sigaction *act, struct sigaction *oact);
This function allows to examine and/or change the action associated with
a signal sig. The struct sigaction
structure, defined by
the header file signal.h
, is declared as follows:
struct sigaction { int sa_flags; /* flags for the action; currently ignored */ void (*sa_handler)(int); /* the handler for the signal */ sigset_t sa_mask; /* additional signals to be blocked */ };
The sa_handler
member is a signal handler, see signal. The
sa_mask
member defines the signals, in addition to sig,
which are to be blocked during the execution of sa_handler
.
The sigaction
function sets the structure pointed to by
oact
to the current action for the signal sig, and then
sets the new action for sig as specified by act. If the
act argument is NULL
, sigaction
returns the current
signal action in oact, but doesn't change it. If the oact
argument is a NULL
pointer, it is ignored. Thus, passing
NULL
pointers for both act
and oact
is a way to
see if sig is a valid signal number on this system (if not,
sigaction
will return -1 and set errno
).
0 on success, -1 for illegal value of sig.
not ANSI, POSIX
#include <signal.h> int sigaddset (sigset_t *set, int signo)
This function adds the individual signal specified by signo the set of signals pointed to by set.
0 upon success, -1 if set is a NULL pointer, or if signo is specifies an unknown signal.
not ANSI, POSIX
#include <signal.h> int sigdelset (sigset_t *set, int signo)
This function removess the individual signal specified by signo from the set of signals pointed to by set.
0 upon success, -1 if set is a NULL pointer, or if signo is specifies an unknown signal.
not ANSI, POSIX
#include <signal.h> int sigemptyset (sigset_t *set)
This function initializes the set of signals pointed to by set to
exclude all signals known to the DJGPP runtime system. Such an empty
set, if passed to sigprocmask
(see sigprocmask), will cause
all signals to be passed immediately to their handlers.
0 upon success, -1 if set is a NULL pointer.
not ANSI, POSIX
#include <signal.h> int sigfillset (sigset_t *set)
This function initializes the set of signals pointed to by set to
include all signals known to the DJGPP runtime system. Such a full
set, if set by sigprocmask
(see sigprocmask), will cause
all signals to be blocked from delivery to their handlers. Note that
the set returned by this function only includes signals in the range
SIGABRT..SIGTRAP
; software interrupts and/or user-defined signals
aren't included.
0 upon success, -1 if set is a NULL pointer.
not ANSI, POSIX
sigset_t full_set, prev_set; sigfillset (&full_set); sigprocmask (SIG_UNBLOCK, &full_set, &prev_set);
#include <signal.h> int sigismember (sigset_t *set, int signo)
This function checks whether the signal specified by signo is a member of the set of signals pointed to by set.
1 if the specified signal is a member of the set, 0 if it isn't, or if signo specifies an unknown signal, -1 if set is a NULL pointer.
not ANSI, POSIX
#include <setjmp.h> int siglongjmp(sigjmp_buf env, int val);
See longjmp.
not ANSI, POSIX
#include <signal.h> void (*signal(int sig, void (*func)(int)))(int);
Signals are generated in response to some exceptional behavior of the program, such as division by 0. A signal can also report some asynchronous event outside the program, such as someone pressing a Ctrl-<BREAK> key combination.
Signals are numbered 0..255 for software interrupts and 256..287 for
exceptions (exception number plus 256); other implementation-specific
codes are specified in <signal.h>
(see below). Every signal is
given a mnemonic which you should use for portable programs.
By default, signal SIGQUIT
is discarded. This is so programs
ported from other DOS environments, where SIGQUIT
is generally
not supported, continue to work as they originally did. If you want
SIGQUIT
to abort with a traceback, install
__djgpp_traceback_exit
as its handler
(see __djgpp_traceback_exit).
The default handling for the rest of the signals is to print a traceback (a
stack dump which describes the sequence of function calls leading to the
generation of the signal) and abort the program by calling _exit
(see _exit). As an exception, the default handler for the signal
SIGINT
doesn't print the traceback, and calls exit
instead
of _exit
, when the INTR key (Ctrl-C by default) is pressed,
so that programs could be shut down safely in this manner.
SIGINT
raised by Ctrl-<BREAK> does generate the
traceback.
The function signal
allows you to change the default behavior for
a specific signal. It registers func as a signal handler for
signal number sig. After you register your function as the
handler for a particular signal, it will be called when that signal
occurs. The execution of the program will be suspended until the
handler returns or calls longjmp
(see longjmp).
You may pass SIG_DFL
as the value of func to reset the
signal handling for the signal sig to default (also
See __djgpp_exception_toggle, for a quick way to restore all the
signals' handling to default), SIG_ERR
to force an error when
that signal happens, or SIG_IGN
to ignore that signal. Signal
handlers that you write are regular C functions, and may call any
function that the ANSI/POSIX specs say are valid for signal handlers.
For maximum portability, a handler for hardware interrupts and processor
exceptions should only make calls to signal
, assign values to
data objects of type volatile sig_atomic_t
(defined as int
on <signal.h>
) and return. Handlers for hardware interrupts need
also be locked in memory (so that the operation of virtual memory
mechanism won't swap them out), See locking memory regions. Handlers for software interrupts can also terminate by
calling abort
, exit
or longjmp
.
The following signals are defined on <signal.h>
:
SIGABRT
assert
macro to
terminate the program when an assertion fails (see assert), and by
the abort
function (see abort).
SIGFPE
The DJGPP startup code masks all numeric exceptions, so this signal is
usually only triggered by an integer divide by zero operation. If you
want to unmask some of the numeric exceptions, see _control87.
SIGILL
SIGINT
setmode
(see setmode), generation of SIGINT
as result of Ctrl-C
key is disabled. This is so for programs (such as Emacs) which want to
be able to read the ^C
character as any other character. Use the
library function __djgpp_set_ctrl_c
to restore SIGINT
generation when Ctrl-C is hit, if you need this.
See __djgpp_set_ctrl_c, for details on how this should be done.
Ctrl-<BREAK> always generates SIGINT
.
DJGPP hooks the keyboard hardware interrupt (Int 09h) to be able to
generate SIGINT
in response to the INTR key; you should be
aware of this when you install a handler for the keyboard interrupt.
Note that the key which generates SIGINT
can be changed with a
call to __djgpp_set_sigint_key
function.
See __djgpp_set_sigint_key.
SIGSEGV
SIGTERM
The signals below this are not defined by ANSI C, and cannot be used
when compiling under -ansi
option to gcc
.
SIGALRM
alarm
library function (see alarm).
SIGHUP
SIGKILL
SIGPIPE
SIGQUIT
__djgpp_set_sigquit_key
function.
See __djgpp_set_sigquit_key. By default, SIGQUIT
is
discarded, even if its handler is SIG_DFL
, so that DOS programs
which don't expect it do not break. You can change the effect of
SIGQUIT
to abort with traceback by installing
__djgpp_traceback_exit
as its handler.
See __djgpp_traceback_exit.
DJGPP hooks the keyboard hardware interrupt (Int 09h) to be able to
generate SIGQUIT
in response to the QUIT key; you should be
aware of this when you install a handler for the keyboard interrupt.
SIGUSR1
SIGUSR2
The signals below are not defined by ANSI C and POSIX, and cannot be
used when compiling under either -ansi
or -posix
options
to gcc
.
SIGTRAP
SIGNOFP
SIGTIMR
setitimer
and alarm
functions
(See setitimer, and see alarm).
SIGPROF
-pg
option to gcc
.
The previous handler for signal sig, or SIG_ERR
if the
value of sig is outside legal limits.
Due to subtle aspects of protected-mode programs operation under MS-DOS,
signal handlers cannot be safely called from hardware interrupt
handlers. Therefore, DJGPP exception-handling mechanism arranges for
the signal handler to be called on the first occasion that the program
is in protected mode and touches any of its data. This means that if
the exception occurs while the processor is in real mode, like when your
program calls some DOS service, the signal handler won't be called until
that call returns. For instance, if you call read
(or
scanf
, or gets
) to read text from the console and press
Ctrl-C, you will have to press Enter to terminate the
read
call to cause the signal handler for SIGINT
to be
called. Another significant implication of this implementation is that
when the program isn't touching any of its data (like in very tight
loops which only use values in the registers), it cannot be interrupted.
ANSI, POSIX
#include <signal.h> int sigpending (sigset_t *set)
This function retrieves the signals that have been sent to the program,
but are being blocked from delivery by the program's signal mask
(see sigprocmask). The bit-mapped value which describes the pending
signals is stored in the structure pointed to by set. You can use
the sigismember
function (see sigismember) to see what
individual signals are pending.
0 on success, -1 on failure (and errno set to EFAULT
).
not ANSI, POSIX
#include <signal.h> sigset_t pending_signals; /* If SIGINT is pending, force it to be raised. */ if (sigpending (&pending_signals) == 0 && sigismember (&pending_signals, SIGINT)) { sigset_t new_set, old_set; sigemptyset (&new_set); sigaddset (&new_set, SIGINT); sigprocmask (SIG_UNBLOCK, &new_set, &old_set); /* will raise SIGINT */ sigprocmask (SIG_SETMASK, &old_set, &new_set); /* restore mask */ }
#include <signal.h> int sigprocmask (int how, const sigset_t *new_set, sigset_t *old_set)
This function is used to examine and/or change the program's current
signal mask. The current signal mask determines which signals are
blocked from being delivered to the program. A signal is blocked if its
bit in the mask is set. (See sigismember, See sigaddset,
See sigdelset, See sigemptyset, See sigfillset, for information
about functions to manipulate the signal masks.) When a blocked signal
happens, it is not delivered to the program until such time as that
signal is unblocked by another call to sigprocmask
. Thus
blocking a signal is an alternative to ignoring it (by setting its
handler to SIG_IGN
, see signal), but has an advantage of not
missing the signal entirely.
The value of the argument how determines the operation: if it is
SIG_BLOCK
, the set pointed to by the argument new_set is
added to the current signal mask. If the value is
SIG_UNBLOCK
, the set pointed to by new_set is
removed from the current signal mask. If the value is
SIG_SETMASK
, the current mask is replaced by the set
pointed to by new_set.
If the argument old_set is not NULL
, the previous mask is
stored in the space pointed to by old_set. If the value of the
argument new_set is NULL
, the value of how is not
significant and the process signal mask is unchanged; thus, the call
with a zero new_set can be used to inquire about currently blocked
signals, without changing the current set.
If the new set defined by the call causes some pending signals to be
unblocked, they are all delivered (by calling raise
) before the
call to sigprocmask
returns.
The DJGPP implementation only records a single occurrence of any given signal, so when the signal is unblocked, its handler will be called at most once.
It is not possible to block CPU exceptions such as Page Fault, General
Protection Fault etc. (mapped to SIGSEGV
signal); for these,
sigprocmask
will behave as if the call succeeded, but when an
exception happens, the signal handler will be called anyway (the default
handler will abort the program).
Also note that there are no provisions to save and restore any
additional info about the signal beyond the fact that it happened. A
signal handler might need such info to handle the signal intelligently.
For example, a handler for SIGFPE
might need to examine the
status word of the FPU to see what exactly went wrong. But if the
signal was blocked and is delivered after a call to sigprocmask
has unblocked it, that information is lost. Therefore, if you need
access to such auxiliary information in the signal handler, don't block
that signal.
0 on success, -1 for illegal value of sig or illegal address in new_set or old_set.
not ANSI, POSIX
#include <conio.h> #include <signal.h> static void sig_catcher (int signo) { cprintf ("\r\nGot signal %d\r\n", signo); } int main (void) { sigset_t sigmask, prevmask; signal (SIGINT, sig_catcher); sigemptyset (&sigmask); sigaddset (&sigmask, SIGINT); if (sigprocmask (SIG_SETMASK, &sigmask, &prevmask) == 0) cputs ("SIGINT blocked. Try to interrupt me now.\r\n"); while (!kbhit ()) ; cputs ("See? I wasn't interrupted.\r\n"); cputs ("But now I will unblock SIGINT, and then get the signal.\r\n"); sigprocmask (SIG_UNBLOCK, &sigmask, &prevmask); return 0; }
#include <setjmp.h> int sigsetjmp(sigjmp_buf env, int savemask);
See setjmp.
not ANSI, POSIX
#include <math.h> double sin(double x);
This function computes the sine of x (which should be given in radians).
The sine of x. If the absolute value of x is finite but
greater than or equal to 2^63, the value is 0 (since for
arguments that large each bit of the mantissa is more than Pi
).
If the value of x is infinite or NaN
, the return value is
NaN
and errno
is set to EDOM
.
ANSI, POSIX
In general, this function's relative accuracy is about
1.7*10^(-16), which is close to the machine precision for a
double
. However, for arguments very close to Pi
and its
odd multiples, the relative accuracy can be many times worse, due to
loss of precision in the internal FPU computations. Since
sin(Pi) is zero, the absolute accuracy is still very good; but if
your program needs to preserve high relative accuracy for such
arguments, link with -lm
and use the version of sin
from
libm.a
which does elaborate argument reduction, but is about
three times slower.
#include <math.h> void sincos(double *cosine, double *sine, double x);
This function computes the cosine and the sine of x in a single
call, and stores the results in the addresses pointed to by cosine
and sine, respectively. Since the function exploits a machine
instruction that computes both cosine and sine simultaneously, it is
faster to call sincos
than to call cos
and sin
for
the same argument.
If the absolute value of x is finite but greater than or equal to
2^63, the value stored in *cosine is 1 and the value stored
in *sine is 0 (since for arguments that large each bit of the
mantissa is more than Pi
). If the value of x is infinite
or NaN
, NaN
is stored in both *cosine and
*sine, and errno
is set to EDOM
.
None.
not ANSI, not POSIX
#include <math.h> double sinh(double x);
This function computes the hyperbolic sine of x.
The hyperbolic sine of x. If the absolute value of x is
finite but so large that the result would overflow a double
, the
return value is Inf
with the same sign as x, and
errno
is set to ERANGE
. If x is either a positive
or a negative infinity, the result is +Inf
with the same sign as
x, and errno
is not changed. If x is NaN
, the
return value is NaN
and errno
is set to EDOM
.
ANSI, POSIX
#include <unistd.h> unsigned sleep(unsigned seconds);
This function causes the program to pause for seconds seconds.
The number of seconds that haven't passed (i.e. always zero)
not ANSI, POSIX
sleep(5);
#include <pc.h> void sound(int _frequency);
Enables the PC speaker at the given frequency. The argument _frequency should be given in Hertz units.
not ANSI, not POSIX
#include <process.h> int spawnl(int mode, const char *path, const char *argv0, ..., NULL); int spawnle(int mode, const char *path, const char *argv0, ..., NULL /*, const char **envp */); int spawnlp(int mode, const char *path, const char *argv0, ..., NULL); int spawnlpe(int mode, const char *path, const char *argv0, ..., NULL /*, const char **envp */); int spawnv(int mode, const char *path, const char **argv); int spawnve(int mode, const char *path, const char **argv, const char **envp); int spawnvp(int mode, const char *path, const char **argv); int spawnvpe(int mode, const char *path, const char **argv, const char **envp);
These functions run other programs. The path points to the
program to run, and may optionally include its extension. These
functions will look for a file path with the extensions
.com
, .exe
, .bat
, .btm
, .sh
,
.ksh
, .pl
and .sed
; if none is found, neither in
the current directory nor along the PATH
, they will look for
path itself.
.com
programs are invoked via the usual DOS calls; DJGPP .exe
programs
are invoked in a way that allows long command lines to be passed; other
.exe
programs are invoked via DOS; .bat
and .btm
programs are invoked via the command processor given by the
COMSPEC
environment variable; .sh
, .ksh
programs
and programs with any other extensions that have #!
as their
first two characters are assumed to be Unix-style scripts and are
invoked by calling a program whose pathname immediately follows the
first two characters. (If the name of that program is a Unix-style
pathname, without a drive letter and without an extension, like
/bin/sh
, the spawn
functions will additionally look them
up on the PATH
; this allows to run Unix scripts without editing,
if you have a shell installed somewhere along your PATH
.) Any
non-recognizable files will be also invoked via DOS calls.
WARNING! DOS is rather stupid in invoking programs: if the
file doesn't have the telltale "MZ" signature of the .exe
style
programs, DOS assumes it is a .com
style image and tries to
execute it directly. If the file is not really an executable program,
your application will almost certainly crash. Applications that need to
be robust in such situations should test whether the program file is
indeed an executable, e.g. with calls to stat
(see stat) or
_is_executable
(see _is_executable) library functions.
Note that built-in commands of the shells can not be invoked via
these functions; use system
instead, or invoke the appropriate
shell with the built-in command as its argument.
The programs are invoked with the arguments given. The zeroth argument
is normally not used, since MS-DOS cannot pass it separately, but for
compatibility it should be the name of the program. There are
two ways of passing arguments. The l
functions (like
spawnl
) take a list of arguments, with a NULL
at the end of the
list. This is useful when you know how many argument there will be
ahead of time. The v
functions (like spawnv
) take a
pointer to a list of arguments, which also must be NULL
-terminated.
This is useful when you need to compute the number of arguments at runtime.
In either case, you may also specify e
to indicate that you will
be giving an explicit environment, else the current environment is used.
You may also specify p
to indicate that you would like
spawn*
to search the PATH
(in either the environment you
pass or the current environment) for the executable, else it will only
check the explicit path given.
Note that these function understand about other DJGPP programs, and will call them directly, so that you can pass command lines longer than 126 characters to them without any special code. DJGPP programs called by these functions will not glob the arguments passed to them; other programs also won't glob the arguments if they suppress expansion when given quoted filenames.
When the calling program runs on Windows 9X or Windows 2000 and calls
the system shell to run the child program, or if the child program is a
native Windows program (in PE-COFF
format), or when the system
shell is 4DOS
or NDOS
and the shell is called to run the
command, command lines longer than 126 characters are passed via the
environment variable CMDLINE
.
See exec*.
If successful and mode
is P_WAIT
, these functions return
the exit code of the child process in the lower 8 bits of the return
value. Note that if the program is run by a command processor (e.g., if
it's a batch file), the exit code of that command processor will be
returned. COMMAND.COM
is notorious for returning 0 even if it
couldn't run the command.
If successful and mode is P_OVERLAY
, these functions will
not return.
If there is an error (e.g., the program specified as argv[0]
cannot be run, or the command line is too long), these functions return
-1 and set errno
to indicate the error. If the child program was
interrupted by <Ctrl-C> or a Critical Device error, errno
is
set to EINTR
(even if the child's exit code is 0), and bits 8-17
of the return value are set to SIGINT
or SIGABRT
,
accordingly. Note that you must set the signal handler for
SIGINT
to SIG_IGN
, or arrange for the handler to return,
or else your program will be aborted before it will get chance to set
the value of the return code.
not ANSI, not POSIX
char *environ[] = { "PATH=c:\\dos;c:\\djgpp;c:\\usr\\local\\bin", "DJGPP=c:/djgpp", 0 }; char *args[] = { "gcc", "-v", "hello.c", 0 }; spawnvpe(P_WAIT, "gcc", args, environ);
#include <stdio.h> int sprintf(char *buffer, const char *format, ...);
Sends formatted output from the arguments (...) to the buffer. See printf.
The number of characters written.
ANSI, POSIX
#include <math.h> double sqrt(double x);
This function computes the square root of x.
The square root of x. If x is negative or a NaN
, the
return value is NaN
and errno
is set to EDOM
.
ANSI, POSIX
#include <stdlib.h> void srand(unsigned seed);
Initializes the random number generator for rand()
. If you
pass the same seed, rand()
will return the same sequence of
numbers. You can seed from time or rawclock.
ANSI, POSIX
/* random pause */ srand(time(0)); for (i=rand(); i; i--);
#include <stdlib.h> int srandom(int seed);
Initializes the random number generator (see random). Passing the
same seed results in random
returning predictable sequences
of numbers, unless see initstate or see setstate are called.
Zero.
not ANSI, not POSIX
srandom(45);
#include <stdio.h> int sscanf(const char *string, const char *format, ...);
This function scans formatted text from the string and stores it in the variables pointed to by the arguments. See scanf.
The number of items successfully scanned.
ANSI, POSIX
#include <stdlib.h> int stackavail(void);
This function returns the number of bytes that are available on the stack.
not ANSI, not POSIX
printf("Available stack size is %d bytes\n", stackavail());
#include <sys/stat.h> int stat(const char *file, struct stat *sbuf);
This function obtains the status of the file file and stores it in sbuf, which has this structure:
struct stat { time_t st_atime; /* time of last access */ time_t st_ctime; /* time of file's creation */ dev_t st_dev; /* The drive number (0 = a:) */ gid_t st_gid; /* what getgid() returns */ ino_t st_ino; /* starting cluster or unique identifier */ mode_t st_mode; /* file mode - S_IF* and S_IRUSR/S_IWUSR */ time_t st_mtime; /* time that the file was last written */ nlink_t st_nlink; /* 2 + number of subdirs, or 1 for files */ off_t st_size; /* size of file in bytes */ off_t st_blksize; /* the size of transfer buffer */ uid_t st_uid; /* what getuid() returns */ };
The st_atime
, st_ctime
and st_mtime
have different
values only when long file names are supported (e.g. on Windows 9X);
otherwise, they all have the same value: the time that the file was last
written1. Most Windows 9X VFAT filesystems only support the date of
the file's last access (the time is set to zero); therefore, the DJGPP
implementation of stat
sets the st_atime
member to the
same value as st_mtime
if the time part of st_atime
returned by the filesystem is zero (to prevent the situation where the
file appears to have been created after it was last accessed,
which doesn't look good).
Some members of struct stat
are very expensive to compute. If
your application is a heavy user of stat
and is too slow, you can
disable computation of the members your application doesn't need, as
described in _djstat_flags.
Zero on success, nonzero on failure (and errno set).
not ANSI, POSIX
struct stat s; stat("data.txt", &s); if (S_ISDIR(s.st_mode)) printf("is directory\n");
Supplying a 100% Unix-compatible stat
function under DOS is an
implementation nightmare. The following notes describe some of the
obscure points specific to stat
s behavior in DJGPP.
1. The drive
for character devices (like con
, /dev/null
and others is returned as -1. For drives networked by Novell Netware, it
is returned as -2.
2. The starting cluster number of a file serves as its inode number. For
files whose starting cluster number is inaccessible (empty files, files on
Windows 9X, on networked drives, etc.) the st_inode
field will be
invented
in a way which guarantees that no two different files will get the same
inode number (thus it is unique). This invented inode will also be
different from any real cluster number of any local file. However, only
on plain DOS, and only for local, non-empty files/directories the inode
is guaranteed to be consistent between stat
and fstat
function calls.
3. The WRITE access mode bit is set only for the user (unless the file is
read-only, hidden or system). EXECUTE bit is set for directories, files
which can be executed from the DOS prompt (batch files, .com, .dll and .exe
executables) or run by go32-v2
.
4. Size of directories is reported as the number of its files (sans `.' and `..' entries) multiplied by 32 bytes (the size of directory entry). On FAT filesystems that support the LFN API (such as Windows 9X), the reported size of the directory accounts for additional space used to store the long file names.
5. Time stamp for root directories is taken from the volume label entry, if that's available; otherwise, it is reported as 1-Jan-1980.
6. The variable _djstat_flags
(see _djstat_flags) controls
what hard-to-get fields of struct stat
are needed by the
application.
7. stat
should not be used to get an up-to-date info about a file
which is open and has been written to, because stat
will only
return correct data after the file is closed. Use fstat
(see fstat) while the file is open. Alternatively, you can call
fflush
and fsync
to make the OS flush all the file's data
to the disk, before calling stat
.
8. The number of links st_nlink
is always 1 for files other than
directories. For directories, it is the number of subdirectories plus
2. This is so that programs written for Unix that depend on this to
optimize recursive traversal of the directory tree, will still work.
#include <sys/vfs.h> int statfs(const char *filename, struct statfs *buf);
This function returns information about the given "filesystem". The drive letter of the given filename, or the default drive if none is given, is used to retrieve the following structure:
struct statfs { long f_type; /* 0 */ long f_bsize; /* bytes per cluster */ long f_blocks; /* clusters on drive */ long f_bfree; /* available clusters */ long f_bavail; /* available clusters */ long f_files; /* clusters on drive */ long f_ffree; /* available clusters */ fsid_t f_fsid; /* [0]=drive_number, [1]=MOUNT_UFS long f_magic; /* FS_MAGIC */ };
Zero on success, nonzero on failure.
not ANSI, not POSIX
struct statfs fs; statfs("anything", &fs); printf("%d bytes left\n", fs.f_bfree * fs.f_bsize);
#include <float.h> unsigned int _status87(void);
Returns the status word of the FPU, which indicate the results of the most recently completed FPU operation:
---- ---- ---- ---X = SW_INVALID - invalid operation ---- ---- ---- --X- = SW_DENORMAL - denormalized operand ---- ---- ---- -X-- = SW_ZERODIVIDE - division by zero ---- ---- ---- X--- = SW_OVERFLOW - overflow ---- ---- ---X ---- = SW_UNDERFLOW - underflow ---- ---- --X- ---- = SW_INEXACT - loss of precision ---- ---- -X-- ---- = SW_STACKFAULT - stack over/under flow ---- ---- X--- ---- = SW_ERRORSUMMARY - set if any errors -X-- -XXX ---- ---- = SW_COND - condition code ---- ---X ---- ---- = SW_C0 ---- --X- ---- ---- = SW_C1 ---- -X-- ---- ---- = SW_C2 -X-- ---- ---- ---- = SW_C3 --XX X--- ---- ---- = SW_TOP - top of stack (use SW_TOP_SHIFT to shift it) X--- ---- ---- ---- = SW_BUSY - fpu is busy
not ANSI, not POSIX
extern int _stklen;
This variable sets the minimum stack length that the program requires. Note that the stack may be much larger than this. This value should be set statically, as it is only used at startup.
not ANSI, not POSIX
int _stklen = 256000;
#include <string.h> char *stpcpy(char *_dest, const char *_src);
Like strcpy
(see strcpy), but return value different.
Returns a pointer to the trailing NUL in dest.
not ANSI, not POSIX
#include <string.h> int strcasecmp(const char *s1, const char *s2);
This function compares the two strings, disregarding case.
Zero if they're the same, nonzero if different, the sign indicates "order".
not ANSI, not POSIX
if (strcasecmp(arg, "-i") == 0) do_include();
#include <string.h> char *strcat(char *s1, const char *s2);
This function concatenates s2 to the end of s1.
s1
ANSI, POSIX
char buf[100] = "hello"; strcat(buf, " there");
#include <string.h> char *strchr(const char *s, int c);
This function returns a pointer to the first occurrence of c in
s. Note that if c is NULL
, this will return a
pointer to the end of the string.
A pointer to the character, or NULL
if it wasn't found.
ANSI, POSIX
char *slash = strchr(filename, '/');
#include <string.h> int strcmp(const char *s1, const char *s2);
This function compares s1 and s2.
Zero if the strings are equal, a positive number if s1 comes after s2 in the ASCII collating sequense, else a negative number.
ANSI, POSIX
if (strcmp(arg, "-i") == 0) do_include();
#include <string.h> int strcoll(const char *s1, const char *s2);
This function compares s1 and s2, using the collating sequences from the current locale.
Zero if the strings are equal, a positive number if s1 comes after s2 in the collating sequense, else a negative number.
ANSI, POSIX
while (strcoll(var, list[i]) < 0) i++;
#include <string.h> char *strcpy(char *s1, const char *s2);
This function copies s2 into s1.
s1
ANSI, POSIX
char buf[100]; strcpy(buf, arg);
#include <string.h> size_t strcspn(const char *s1, const char *set);
This function finds the first character in s1 that matches any
character in set. Note that the NULL
bytes at the end of
each string counts, so you'll at least get a pointer to the end of the
string if nothing else.
The index of the found character.
ANSI, POSIX
int i = strcspn(command, "<>|"); if (command[i]) do_redirection();
#include <string.h> char * strdup (const char *source);
Returns a newly allocated area of memory that contains a duplicate of the string pointed to by source. The memory returned by this call must be freed by the caller.
Returns the newly allocated string, or NULL if there is no more memory.
not ANSI, not POSIX
char *foo() { return strdup("hello"); }
#include <string.h> char *strerror(int error);
This function returns a string that describes the error.
A pointer to a static string that should not be modified or free'd.
ANSI, POSIX
if (f=fopen("foo", "r") == 0) printf("Error! %s: %s\n", "foo", strerror(errno));
#include <time.h> size_t strftime(char *buf, size_t n, const char *format, const struct tm *time_info);
This function formats the time data in time_info according to the given format and stores it in buf, not exceeding n bytes.
The format string is like printf
in that any character other than
%
is added to the output string, and for each character following
a %
a pattern is added to the string as follows, with the
examples as if the time was Friday, October 1, 1993, at 03:30:34 PM EDT:
%A
Friday
)
%a
Fri
)
%B
October
)
%b
%h
Oct
)
%C
%a %b %e %H:%M:%S %Y
(Fri Oct 1 15:30:34 1993
)
%c
%m/%d/%y %H:%M:%S
(10/01/93 15:30:34
)
%e
2
)
%D
%m/%d/%y
(10/01/93
)
%d
02
)
%H
15
)
%I
03
)
%j
275
)
%k
15
)
%l
3
)
%M
30
)
%m
10
)
%n
\n
)
%p
PM
)
%R
%H:%M
(15:30
)
%r
%I:%M:%S %p
(03:30:35 PM
)
%S
35
)
%T
%X
%H:%M:%S
(15:30:35
)
%t
\t
)
%U
39
)
%u
6
)
%W
39
)
%w
5
)
%x
%m/%d/%y
(10/01/93
)
%y
93
)
%Y
1993
)
%Z
EDT
)
%%
%
)
The number of characters stored.
ANSI, POSIX
time_t now = time (NULL); struct tm *t = localtime (&now); char buf[100]; /* Print today's date e.g. "January 31, 2001". */ strftime (buf, 100, "%B %d, %Y", t);
#include <string.h> int stricmp(const char *s1, const char *s2);
This function compares the two strings, disregarding case.
Zero if they're the same, nonzero if different, the sign indicates "order".
not ANSI, not POSIX
if (stricmp(arg, "-i") == 0) do_include();
#include <string.h> size_t strlen(const char *string);
This function returns the number of characters in string.
The length of the string.
ANSI, POSIX
if (strlen(fname) > PATH_MAX) invalid_file(fname);
#include <string.h> char *strlwr(char *string);
This function replaces all upper case letters in string with lower case letters.
The string.
not ANSI, not POSIX
char buf[100] = "Hello"; strlwr(buf);
#include <string.h> int strncasecmp(const char *s1, const char *s2, size_t max);
This function compares s1 and s2, ignoring case, up to a maximum of max characters.
Zero if the strings are equal, a positive number if s1 comes after s2 in the ASCII collating sequense, else a negative number.
not ANSI, not POSIX
if (strncasecmp(foo, "-i", 2) == 0) do_include();
#include <string.h> char *strncat(char *s1, const char *s2, size_t max);
This function concatenates up to max characters of s2 to the end of s1.
s1
ANSI, POSIX
strncat(fname, extension, 4);
#include <string.h> int strncmp(const char *s1, const char *s2, size_t max);
This function compares up to max characters of s1 and s2.
Zero if the strings are equal, a positive number if s1 comes after s2 in the ASCII collating sequense, else a negative number.
ANSI, POSIX
if (strncmp(arg, "-i", 2) == 0) do_include();
#include <string.h> char *strncpy(char *s1, const char *s2, size_t max);
This function copies up to max characters of s2 into s1.
s1
ANSI, POSIX
char buf[100]; strncpy(buf, arg, 99);
#include <string.h> int strnicmp(const char *s1, const char *s2, size_t max);
This function compares s1 and s2, ignoring case, up to a maximum of max characters.
Zero if the strings are equal, a positive number if s1 comes after s2 in the ASCII collating sequense, else a negative number.
not ANSI, not POSIX
if (strnicmp(foo, "-i", 2) == 0) do_include();
#include <string.h> char *strpbrk(const char *s1, const char *set);
This function finds the first character in s1 that matches any character in set.
A pointer to the first match, or NULL
if none are found.
ANSI, POSIX
if (strpbrk(command, "<>|")) do_redirection();
#include <string.h> char *strrchr(const char *s1, int c);
This function finds the last occurrence of c
in s1
.
A pointer to the last match, or NULL
if the character isn't in
the string.
ANSI, POSIX
char *last_slash = strrchr(filename, '/');
#include <string.h> char *strsep(char **stringp, char *delim);
This function retrieves the next token from the given string, where
stringp points to a variable holding, initially, the start of the
string. Tokens are delimited by a character from delim. Each
time the function is called, it returns a pointer to the next token, and
sets *stringp to the next spot to check, or NULL
.
The next token, or NULL.
not ANSI, not POSIX
main() { char *buf = "Hello there,stranger"; char **bp = &buf; char *tok; while (tok = strsep(bp, " ,")) printf("tok = `%s'\n", tok); } tok = `Hello' tok = `' tok = `there' tok = `stranger'
#include <string.h> size_t strspn(const char *s1, const char *set);
This function finds the first character in s1 that does not match
any character in set. Note that the NULL
bytes at the end
of s1 counts, so you'll at least get a pointer to the end of the
string if nothing else.
The index of the found character.
ANSI, POSIX
int i = strspn(entry, " \t\b"); if (entry[i]) do_something();
#include <string.h> char *strstr(const char *s1, const char *s2);
This function finds the first occurrence of s2 in s1.
A pointer within s1, or NULL
if s2 wasn't found.
ANSI, POSIX
if (strstr(command, ".exe")) do_exe();
#include <stdlib.h> double strtod(const char *s, char **endp);
This function converts as many characters of s as look like a
floating point number into that number. If endp is not a null
pointer, *endp
is set to point to the first unconverted
character.
The value the represented by s.
If a number represented by s doesn't fit into the range of values
representable by the type double
, the function returns either
-HUGE_VAL
(if s begins with the character -
) or
+HUGE_VAL
, and sets errno
to ERANGE
.
ANSI, POSIX
char *buf = "123ret"; char *bp; double x = strtod(buf, &bp);
#include <string.h> char *strtok(char *s1, const char *s2);
This function retrieves tokens from s1 which are delimited by characters from s2.
To initiate the search, pass the string to be searched as s1. For
the remaining tokens, pass NULL
instead.
A pointer to the token, or NULL
if no more are found.
ANSI, POSIX
main() { char *buf = "Hello there, stranger"; char *tok; for (tok = strtok(buf, " ,"); tok; tok=strtok(0, " ,")) printf("tok = `%s'\n", tok); } tok = `Hello' tok = `there' tok = `stranger'
#include <stdlib.h> long strtol(const char *s, char **endp, int base);
This function converts as much of s as looks like an appropriate number into the value of that number. If endp is not a null pointer, *endp is set to point to the first unused character.
The base argument indicates what base the digits (or letters)
should be treated as. If base is zero, the base is determined by
looking for 0x
, 0X
, or 0
as the first part of the
string, and sets the base used to 16, 16, or 8 if it finds one. The
default base is 10 if none of those prefixes are found.
The value.
ANSI, POSIX
printf("Enter a number: "); fflush(stdout); gets(buf); char *bp; printf("The value is %d\n", strtol(buf, &bp, 0));
#include <stdlib.h> long double _strtold(const char *s, char **endp);
This function converts as many characters of s that look like a floating point number into one, and sets *endp to point to the first unused character.
The value the string represented.
not ANSI, not POSIX
char *buf = "123ret"; char *bp; long double x = _strtold(buf, &bp);
#include <stdlib.h> long long strtoll(const char *s, char **endp, int base);
This function converts as much of s as looks like an appropriate number into the value of that number, and sets *endp to point to the first unused character.
The base argument indicates what base the digits (or letters)
should be treated as. If base is zero, the base is determined by
looking for 0x
, 0X
, or 0
as the first part of the
string, and sets the base used to 16, 16, or 8 if it finds one. The
default base is 10 if none of those prefixes are found.
The value.
not ANSI, not POSIX
printf("Enter a number: "); fflush(stdout); gets(buf); char *bp; printf("The value is %lld\n", strtoll(buf, &bp, 0));
#include <stdlib.h> unsigned long strtoul(const char *s, char **endp, int base);
This is just like strtol
(see strtol) except that the result
is unsigned.
The value.
ANSI, POSIX
printf("Enter a number: "); fflush(stdout); gets(buf); char *bp; printf("The value is %u\n", strtoul(buf, &bp, 0));
#include <stdlib.h> unsigned long long strtoull(const char *s, char **endp, int base);
This is just like strtoll
(see strtoll) except that the result
is unsigned.
The value.
not ANSI, not POSIX
printf("Enter a number: "); fflush(stdout); gets(buf); char *bp; printf("The value is %llu\n", strtoull(buf, &bp, 0));
#include <string.h> char *strupr(char *string);
This function converts all lower case characters in string to upper case.
string
not ANSI, not POSIX
char buf[] = "Foo!"; strupr(buf);
#include <string.h> size_t strxfrm(char *s1, const char *s2, size_t max);
This copies characters from s2 to s1, which must be able to
hold max characters. Each character is transformed according to
the locale such that strcmp(s1b, s2b)
is just like
strcoll(s1, s2)
where s1b
and s2b
are the
transforms of s1
and s2
.
The actual number of bytes required to transform s2, including the
NULL
.
ANSI, POSIX
#include <stdlib.h> void swab(const void *from, void *to, int nbytes);
This function copies nbytes bytes from the address pointed to by from to the address pointed by to, exchanging adjacent even and odd bytes. It is useful for carrying binary data between little-endian and big-endian machines. The argument nbytes should be even, and the buffers from and to should not overlap.
None.
not ANSI, not POSIX
#include <unistd.h> int symlink(const char *exists, const char *new);
MSDOS doesn't support symbolic links. However, DJGPP supports
"symlinks" to DJGPP programs. This function simulates a symlink
between two .exe
files in the DJGPP style. It creates a program
whose name is pointed to by new which, when run, will actually
execute the program exists passing it the string pointed by
new in argv[0]
(some programs change their behavior
depending on what's passed in argv[0]
). The file referred to by
exists doesn't really have to exist when this function is called.
If exists points to an existing file, the function checks
that it is a DJGPP executable; if not, the call will fail with
EXDEV
.
Both new and exists can point to a name with or without the
.exe
extension.
Note that both exists and new must specify file names which
reside in the same
directory (this is a restriction of the DJGPP "symlinks"); the
function will fail and set errno
to EXDEV
if they aren't.
This functions runs the stubify
and stubedit
programs, so
they should be somewhere on your PATH
for the function to
succeed. (These programs come with the DJGPP development distribution.)
Zero in case of success, -1 in case of failure (and errno
set to
the appropriate error code).
not ANSI, not POSIX
symlink ("c:/djgpp/bin/grep", "c:/djgpp/bin/fgrep");
#include <debug/syms.h> void syms_init (char *file);
This function reads debugging symbols from the named file, which
should be an executable program (either a .exe
file or a raw COFF
image created by ld.exe
, the linker). It then processes the
symbols: classifies them by type, sorts them by name and value, and
stores them in internal data structures used by other symbol-related
functions, such as syms_val2name
, syms_val2line
, etc.
You must call syms_init
before calling the other
syms_*
functions.
Currently, syms_init
only supports COFF and AOUT debugging
format, so programs compiled with -gstabs
cannot be processed by
it.
None.
not ANSI, not POSIX
syms_init("c:/foo/bar/baz.exe");
#include <debug/syms.h> unsigned long syms_line2val (char *filename, int lnum);
This function returns the address of the first instruction produced from
the line lnum of the source file filename that was linked
into a program whose symbols were read by a previous call to
syms_init
.
COFF debugging format does not support pathnames, so filename should not include leading directories, just the basename.
You must call syms_init
(see syms_init) before calling any of
the other syms_*
functions for the first time.
The address of the first instruction produced from the line, or zero if filename is not found in the symbol table or if no executable code was generated for line lnum in filename.
not ANSI, not POSIX
syms_init ("foo.exe"); printf ("Line 3 of foo.c is at address %lx\n", syms_line2val("foo.c", 3));
#include <debug/syms.h> void syms_listwild (char *pattern, void (*handler) (unsigned long addr, char type_c, char *name, char *file, int lnum));
This function walks through all the symbols that were read by a previous
call to syms_init
(see syms_init). For each symbol whose
name matches pattern, it invokes the user-defined function
handler, passing it information about that symbol:
address
type_c
T
t
D
d
B
b
F
f
a.out
file only).
V
v
a.out
file only).
I
i
a.out
file only).
U
u
A
a
name
file
lnum
Since variables and functions defined in C get prepended with an
underscore _
, begin pattern with _
if you want it to
match C symbols.
You must call syms_init
(see syms_init) before calling any of
the other syms_*
functions for the first time.
None.
not ANSI, not POSIX
void print_sym (unsigned long addr, char type_c, char *name, char *file, int lnum) { printf (file ? "%s: %lx %c %s:%d\n" : "%s: %lx %c\n", name, addr, type_c, file ? file : "", lnum ); } int main (void) { syms_init ("foo.exe"); /* List all the symbols which begin with "___djgpp". */ syms_listwild ("___djgpp*", print_sym); return 0; }
#include <debug/syms.h> char *syms_module (int nfile);
This function returns the name of the source file (a.k.a. module) whose ordinal number in the symbol table is nfile.
You must call syms_init
(see syms_init) before calling any of
the other syms_*
functions for the first time.
The name of the source file, or a NULL
pointer if nfile is
negative or larger than the total number of modules linked into the
program whose symbols were read by syms_init
.
not ANSI, not POSIX
#include <debug/syms.h> extern int undefined_symbol; extern int syms_printwhy; unsigned long syms_name2val (const char *string);
This function returns the address of a symbol specified by string. string may be one of the following:
file#[line]
, where
file is the name of one of the source files linked into the
program whose symbols were read by syms_init
, and line is a
line number in that file. If line is omitted, it defaults
to zero.
Note that the COFF format supported by DJGPP only stores the basename of the source files, so do not specify file with leading directories.
_
.
%reg
. reg specifies the value of one
of the debuggee's registers saved in the external variable a_tss
(see run_child).
syms_name2val
looks up the specified file, line, and symbol in
the symbol table prepared by syms_init
, finds their addresses,
adds the offset, if any, and returns the result.
If the specified file, line, or symbol cannot be found,
syms_name2val
returns zero and sets the global variable
undefined_symbol
to a non-zero value. If the global variable
syms_printwhy
is non-zero, an error message is printed
telling which part of the argument string was invalid.
You must call syms_init
(see syms_init) before calling any of
the other syms_*
functions for the first time.
The address specified by string, or zero, if none found.
not ANSI, not POSIX
unsigned long addr1, addr2, addr3; syms_init ("foo.exe"); addr1 = syms_name2val ("foo.c#256+12"); addr2 = syms_name2val ("_main"); addr3 = syms_name2val ("struct_a_var+%eax+4");
#include <debug/syms.h> char *syms_val2line (unsigned long addr, int *line, int exact);
This function takes an address addr and returns the source file name which correspond to that address. The line number in that source file is stored in the variable pointed by line. If exact is non-zero, the function succeeds only if addr is the first address which corresponds to some source line.
You must call syms_init
(see syms_init) before calling any of
the other syms_*
functions for the first time.
The name of the source file which corresponds to addr, or
NULL
if none was found.
not ANSI, not POSIX
int lineno; char *file_name; syms_init ("foo.exe"); file_name = syms_val2line (0x1c12, &lineno); printf ("The address %x is on %s, line %d\n", 0x1c12, file_name, line);
#include <debug/syms.h> char *syms_val2name (unsigned long addr, unsigned long *offset);
This function takes an address addr and returns the name of the
closest symbol whose address is less that addr. If offset
is not a NULL
pointer, the offset of addr from the symbol's
address is stored in the variable pointed to by offset.
You must call syms_init
(see syms_init) before calling any of
the other syms_*
functions for the first time.
This function is meant to be used to convert numerical addresses into
function names and offsets into their code, like what symify
does
with the call frame traceback.
The function ignores several dummy symbols, like _end
and
_etext
.
The name of the found symbol, or the printed hexadecimal representation
of addr, if no symbol was found near addr. The return value
is a pointer to a static buffer, so don't overwrite it and don't pass it
to free
!
not ANSI, not POSIX
unsigned long offs; char *symbol_name; syms_init ("foo.exe"); symbol_name = syms_val2name (0x1c12, &offs); printf ("The address %x is at %s%+ld\n", 0x1c12, symbol_name, offs);
#include <unistd.h> int sync(void);
Intended to assist porting Unix programs. Under Unix, sync
flushes all caches of previously written data. In this implementation,
sync
calls fsync
on every open file. See fsync. It
also calls _flush_disk_cache
(see _flush_disk_cache) to try
to force cached data to the disk.
Always returns 0.
not ANSI, not POSIX
sync();
#include <errno.h> extern char *sys_errlist[];
This array contains error messages, indexed by errno
, that
describe the errors.
not ANSI, not POSIX
printf("Error: %s\n", sys_errlist[errno]);
#include <errno.h> extern int sys_nerr;
This variable gives the number of error messages in sys_errlist
(see sys_errlist).
not ANSI, not POSIX
if (errno < sys_nerr) printf("Error: %s\n", sys_errlist[errno]);
#include <unistd.h> long sysconf(int which);
This function returns various system configuration values, based on which:
case _SC_ARG_MAX: return _go32_info_block.size_of_transfer_buffer; case _SC_CHILD_MAX: return CHILD_MAX; case _SC_CLK_TCK: return CLOCKS_PER_SEC; case _SC_NGROUPS_MAX: return NGROUPS_MAX; case _SC_OPEN_MAX: return 255; case _SC_JOB_CONTROL: return -1; case _SC_SAVED_IDS: return -1; case _SC_STREAM_MAX: return _POSIX_STREAM_MAX; case _SC_TZNAME_MAX: return TZNAME_MAX; case _SC_VERSION: return _POSIX_VERSION;
The value.
not ANSI, POSIX
#include <stdlib.h> int system(const char *cmd);
This function runs the command or program specified by cmd. If
cmd is a null pointer, system
returns non-zero only if a
shell is available. If cmd is an empty string, the command
processor pointed to by SHELL
or COMSPEC
variables in the
environment will be invoked interactively; type exit <RET> to
return to the program which called system
. (Note that some other
DOS compilers treat a null pointer like an empty command line, contrary
to ANSI C requirements.)
When calling programs compiled by DJGPP this function will not use
command.com
and so will not be subject to its 126 character limit
on command lines.
When the calling program runs on Windows 9X or Windows 2000 and calls
the system shell to run the child program, or if the child program is a
native Windows program (in PE-COFF
format), or when the system
shell is 4DOS
or NDOS
, command lines longer than 126
characters are passed via the environment variable CMDLINE
.
Command lines and pipes( i.e., the use of "<", ">", ">>", and "|") will be simulated internally in this function; this means that you can have both long command lines and redirection/pipes when running DJGPP programs with this function.
By default, command.com
will only be invoked to run commands
internal to it, or to run batch files (but this can be changed, see
below). In these cases, the returned error code will always be zero,
since command.com
always exits with code 0.
Certain commands internal to command.com
that don't make sense or
cause no effect in the context of system
are ignored by this
function. These are REM
, EXIT
, GOTO
, SHIFT
;
SET
, PATH
and PROMPT
are ignored only if called
with an argument. You can disable this feature if you need, see below.
Some commands are emulated internally by system
, because the
emulation is better than the original. Currently, the only emulated
command is CD
or CHDIR
: the emulation knows about forward
slashes and also switches the current drive. This emulation can also be
switched off, as explained below.
When system
is presented with an internal shell command, it
checks the environment variables SHELL
and COMSPEC
(in
that order) and invokes the program that they point to. If the shell
thus found is one of the DOS shells (command.com
, 4DOS
or
NDOS
), they are called with the /c
switch prepended to the
command line. Otherwise, system
assumes that the shell is a
Unix-style shell and passes it the entire command line via a temporary
file, invoking the shell with a single argument which is the name of
that file.
Shell scripts and batch files are invoked by calling either the program
whose name appears on the first line (like in #! /bin/sh
), or
the default shell if none is specified by the script. If the name of
the shell specified by the script is a Unix-style pathname, without a
drive letter and with no extension, system
will additionally
search for it on the PATH
. This allows to invoke Unix shell
scripts unmodified, if you have a ported shell installed on your
system.
You can customize the behavior of system
using a bit-mapped
variable __system_flags, defined on <stdlib.h>
. The
following bits are currently defined:
__system_redirect
system
can use its
internal redirection and pipe code. If reset, any command line that
includes an unquoted redirection symbol will be passed to the shell.
__system_call_cmdproc
system
will always call the shell to execute the
command line. If reset (the default), the shell will only be called
when needed, as described above.
You should always set this bit if you use a real, Unix-style
shell (also, set __system_use_shell
, described below, and the
SHELL
environment variable).
__system_use_shell
SHELL
environment variable will take
precedence upon COMSPEC
; this allows you to specify a special
shell for system
that doesn't affect the rest of DOS. If reset,
only COMSPEC
is used to find the name of the command processor.
__system_allow_multiple_cmds
;
character. If reset (the default), the command line passed to
system
is executed as a single command and ;
has no
special meaning.
__system_allow_long_cmds
system
will handle command lines longer
than the DOS 126-character limit; this might crash your program in some
cases, as the low-level functions that invoke the child program will
only pass them the first 126 characters. When reset, system
will
detect early that the command line is longer than 126 characters and
refuse to run it, but you will not be able to call DJGPP programs with
long command lines.
__system_emulate_command
system
will pass the entire command line
to the shell if its name is one of the following: sh.exe
,
sh16.exe
, sh32.exe
, bash.exe
, tcsh.exe
.
When set, system
will attempt to emulate redirection and pipes
internally, even if COMSPEC
or SHELL
point to a Unix-style
shell.
__system_handle_null_commands
COMMAND.COM
and
compatible shells which have no effect in the context of system
,
are ignored (the list of these commands was given above). If reset,
these commands are processed as all others, which means
COMMAND.COM
will be called to execute them.
Note that this bit shouldn't be used with a Unix-style shell, because it
does the wrong thing then. With Unix-style shells, you are supposed to
set the __system_call_cmdproc
bit which will always call the
shell.
__system_ignore_chdir
CD
and CHDIR
commands are ignored. When reset
(the default), the processing of these commands depends on the
__system_emulate_chdir
bit, see below.
This bit is for compatibility with Unix, where a single cd dir
command has no effect, because the current working directory there is
not a global notion (as on MSDOS). Don't set this bit if you use
multiple commands (see __system_allow_multiple_cmds
above).
__system_emulate_chdir
CD
and CHDIR
commands are emulated
internally: they change the drive when the argument specifies a drive
letter, and they support both forward slashes and backslashes in
pathnames. When CD
is called without an argument, it prints the
current working directory with forward slashes and down-cases DOS 8+3
names. If this bit is reset (the default), CD
and CHDIR
are passed to the shell.
The behavior of system
can be customized at run time by defining
the variable DJSYSFLAGS
in the environment. The value of that
variable should be the numerical value of __system_flags
that
you'd like to set; it will override the value of __system_flags
specified when the program was compiled.
If cmd is a null pointer, system
returns non-zero if a
shell is available. The actual test for the existence of an executable
file pointed to by SHELL
or COMSPEC
is only performed if
the shell is to be invoked to process the entire command line; if most
of the work is to be done by system
itself, passing a null
pointer always yields a non-zero return value, since the internal
emulation is always "available".
Otherwise, the return value is the exit status of the child process in
its lower 8 bits; bits 8-17 of the return value will hold SIGINT
or SIGABRT
if the child process was aborted by Ctrl-C or
Critical Device Error, respectively; otherwise it will be zero. If the
child couldn't be run, system
will return -1 and set errno
to an appropriate value. Note that if COMMAND.COM
was used to
run the child, it will always return a 0 status, even if the command
didn't run successfully. However, system
only calls
COMMAND.COM
when it needs to run commands internal to it.
ANSI, POSIX
system("cc1plus.exe @cc123456.gp");
#include <math.h> double tan(double x);
This function computes the tangent of x (which should be given in radians).
The tangent of x. If the absolute value of x is finite but
greater than or equal to 2^63, the return value is 0 (since for
arguments that large each bit of the mantissa is more than Pi
).
If the value of x is infinite or NaN
, the return value is
NaN
and errno
is set to EDOM
.
ANSI, POSIX
#include <math.h> double tanh(double x);
This function computes the hyperbolic tangent of x.
The hyperbolic tangent of x. If x is either a positive or a
negative infinity, the result is unity with the same sign as x,
and errno
is not changed. If x is NaN
, the return
value is NaN
and errno
is set to EDOM
.
ANSI, POSIX
#include <termios.h> int tcdrain (int fd);
This function waits until all the output is written to the file/device referred to by the handle fd. In this implementation, this function does nothing except checking the validity of its arguments; it is provided for compatibility only. Note that the termios emulation handles console only.
Zero on success, nonzero on failure.
not ANSI, POSIX
#include <termios.h> int tcflow (int fd, int action);
This function suspends transmission of data to, or reception of data from, the device/file open on handle fd. The action argument can take one of these values:
TCOOFF
TCOON
TCIOFF
TCION
The current START and STOP characters are stored in the termios
structure that is currently in effect. See Termios functions, for
more details about that.
Note that the DJGPP termios emulation handles console only.
Zero on success, nonzero on failure.
not ANSI, POSIX
#include <termios.h> int tcflush (int fd, int which);
This function clears the input and/or output queues on for the device/file open on handle fd. The which argument can take these values:
TCIFLUSH
TCOFLUSH
TCIOFLUSH
TCIFLUSH
and TCOFLUSH
Note that the termios emulation handles console only.
Zero on success, nonzero on failure.
not ANSI, POSIX
#include <termios.h> int tcgetattr (int fd, struct termios *termiosp);
This function gets the parameters associated with the file/device
referred to by the handle fd and stores them in the termios
structure termiosp. See Termios functions, for the full
description of struct termios
and its members.
Note that the termios emulation handles console only.
Zero on success, nonzero on failure.
not ANSI, POSIX
struct termios termiosbuf; int rc = tcgetattr (0, &termiosbuf);
#include <termios.h> int tcgetpgrp (int fd);
This function returns the value of the process group ID for the foreground process associated with the terminal. The file descriptor fd must be connected to the terminal, otherwise the function will fail.
If fd is connected to the terminal, the function returns the
process group ID, which is currently identical to the value returned by
getpgrp()
(see getpgrp). Otherwise, it returns -1 and sets
errno
to ENOTTY
.
not ANSI, POSIX
#include <termios.h> int tcsendbreak (int fd, int duration);
This function generates a break condition for duration*0.25
seconds. In the current implementation this function does nothing; it
is provided for compatibility only. Note that the termios emulation
handles console only.
Zero on success, nonzero on failure.
not ANSI, POSIX
#include <termios.h> int tcsetattr (int fd, int action, const struct termios *termiosp);
This function sets termios structure for device open on the handle fd from the structure termiosp. Note that the termios emulation handles console only.
The action argument can accept the following values:
TCSANOW
TCSADRAIN
TCSAFLUSH
Currently, any of these values causes the values in termiosp to take effect immediately.
See Termios functions, for the description of the struct
termios
structure.
Zero on success, nonzero on failure.
not ANSI, POSIX
tcsetattr (0, TCSANOW, &termiosbuf);
#include <termios.h> int tcsetpgrp (int fd, pid_t pgroup_id);
This function sets the foreground process group ID for the terminal connected to file descriptor fd. fd must be a valid handle connected to a terminal device, and pgroup_id must be the process group ID of the calling process, or the function will fail.
If fd is a valid handle connected to a terminal and
pgroup_id is equal to what getpgrp()
returns
(see getpgrp), the function will do nothing and return zero.
Otherwise, -1 will be returned and errno
will be set to a
suitable value. In particular, if the pgroup_id argument is
different from what getpgrp()
returns, tcsetpgrp
sets
errno
to ENOSYS
.
not ANSI, POSIX
#include <io.h> off_t tell(int file);
This function returns the location of the file pointer for file.
The file pointer, or -1 on error.
not ANSI, not POSIX
off_t q = tell(fd);
#include <dirent.h> long telldir(DIR *dir);
This function returns a value which indicates the position of the
pointer in the given directory. This value is only useful as an
argument to seekdir
(see seekdir).
The directory pointer.
not ANSI, not POSIX
DIR *dir; long q = telldir(dir); do_something(); seekdir(dir, q);
#include <stdio.h> char * tempnam(const char *tmpdir, const char *prefix);
This function generates a file name which can be used for a temporary file, and makes sure that no other file by that name exists.
The caller has control on the choice of the temporary file's directory,
and the initial letters of the file's basename. If the argument
tmpdir points to the name of the directory in which the temporary
file will be created, tempnam
will ensure that the generate name
is unique in that directory. If the argument prefix
points to a string, then that string will be used as the first few
characters of the file's basename. Due to limitations of the DOS 8.3
file namespace, only up to two first characters in prefix will be
used.
If tmpdir is NULL
, or empty, or points to a non-existent
directory, tempnam
will use a default directory. The default
directory is determined by testing, in sequence, the directories
defined by the values of environment variables TMPDIR
,
TEMP
and TMP
. The first variable that is found to point
to an existing directory will be used. If none of these variables
specify a valid directory, tempnam
will use the static default
path prefix defined by P_tmpdir
on <stdio.h>
, or
"c:/"
, in that order.
If prefix is NULL
or empty, tempnam
will supply its
own default prefix "tm"
.
tempnam
puts the generated name into space allocated by
malloc
. It is up to the caller to free that space when it is no
longer needed.
Note that tempnam
does not actually create the file, nor does it
ensure in any way that the file will be automatically deleted when it's
no longer used. It is the user's responsibility to do that.
On success, tempnam
returns a pointer to space (allocated with a
call to malloc
) where the file name is constructed. If
malloc
failed to provide sufficient memory buffer, or if no valid
directory to hold the file was found, tempnam
returns a
NULL
pointer.
not ANSI, not POSIX
#include <stdio.h> tempnam ("c:/tmp/", "foo");
The termios
functions allow to control terminals and asynchronous
communications ports. The DJGPP implementation currently supports the
termios
functionality for console devices only. It does that by
reading the keyboard via the BIOS Int 16h and writes to the screen via
the direct output interrupt 29h. This I/O redirection is performed by
the special hook internal to the library.
Many of the termios
functions accept a termiosp argument
which is a pointer to a struct termios
variable. Here's the
description of this structure:
#define NCCS 12 struct termios { cc_t c_cc[NCCS]; /* control characters */ tcflag_t c_cflag; /* control modes */ tcflag_t c_iflag; /* input modes */ tcflag_t c_lflag; /* local modes */ tcflag_t c_oflag; /* output modes */ speed_t c_ispeed; /* input baudrate */ speed_t c_ospeed; /* output baudrate */ }
The array c_cc[]
defines the special control characters. the
following table lists the supported control functions the default
characters which invoke those functions, and the default values for MIN
and TIME parameters:
Index | Name | Function | Default Value
|
1 | VEOF | Signal End-Of-Input | Ctrl-D
|
2 | VEOL | Signal End-Of-Line | [Disabled]
|
3 | VERASE | Delete previous character | Backspace
|
4 | VINTR | Generate SIGINT | Ctrl-C
|
5 | VKILL | Erase current line | Ctrl-U
|
6 | VMIN | The MIN value | 1
|
7 | VQUIT | Generate SIGQUIT | Ctrl-\
|
8 | VSTART | Resume output | Ctrl-Q
|
9 | VSTOP | Suspend output | Ctrl-S
|
10 | VSUSP | Suspend program | Ctrl-Z
|
11 | VTIME | TIME value | 0
|
The special characters (like VEOL
, VKILL
, etc.) produce
their effect only under the canonical input processing, that is,
when the ICANON
bit in the c_lflag
member of struct
termios
(see below) is set. If ICANON
is not set, all
characters are processed as regular characters and returned to the
caller; only the VMIN
and VTIME
parameters are meaningful
in the non-canonical processing mode.
The VEOL
character can be used to signal end of line (and thus
end of input in the canonical mode) in addition to the normal RET
key. In the non-canonical mode, input ends as soon as at least
VMIN
characters are received.
Note that the values of VMIN
and VTIME
are currently
ignored; termios
functions always work as if VMIN
were 1
and VTIME
were zero. Other parameters are supported (for console
devices only), except that VSTOP and VSTART characters are not inserted
to the input, but otherwise produce no effect.
The c_cflag
member of struct termios
describes the
hardware terminal control, as follows:
Symbol | Function
|
B0 | Hang up
|
B50 | 50 baud
|
B75 | 75 baud
|
B110 | 110 baud
|
B134 | 134.5 baud
|
B150 | 150 baud
|
B200 | 200 baud
|
B300 | 300 baud
|
B600 | 600 baud
|
B1200 | 1200 baud
|
B1800 | 1800 baud
|
B2400 | 2400 baud
|
B4800 | 4800 baud
|
B9600 | 9600 baud
|
B19200 | 19200 baud
|
B38400 | 38400 baud
|
CSIZE | Character size:
|
CS5 | 5-bit characters
|
CS6 | 6-bit characters
|
CS7 | 7-bit characters
|
CS8 | 8-bit characters
|
CSTOPB | If set, send two stop bits
|
CREAD | Enable reading
|
PARENB | Enable parity
|
PARODD | If set, use odd parity
|
HUPCL | Hang up on last close
|
CLOCAL | If set, line is local
|
Note that since the DOS terminal doesn't use asynchronous ports, the
above parameters are always ignored by the implementation. The default
value of c_cflag
is (CS8|CREAD|CLOCAL)
.
The c_lflag
member of struct termios
defines the local
modes that control the terminal functions:
Symbol | Function
|
ISIG | If set, enable signals SIGINT and SIGQUIT
|
ICANON | If set, enable canonical input processing
|
ECHO | If set, enable echoing
|
ECHOE | Erase character deletes
|
ECHOK | Output newline after the kill character
|
ECHONL | Echo the newline
|
NOFLSH | [Ignored]
|
TOSTOP | [Ignored]
|
ECHOCTL | Echo control characters as ^X
|
ECHOKE | Erase killed line
|
IEXTEN | [Ignored]
|
The default value of c_lflag
is
(ISIG|ICANON|ECHO|IEXTEN|ECHOE|ECHOKE|ECHOCTL)
.
The c_iflag
member of struct termios
describes the input
control:
Symbol | Function
|
IGNBRK | Ignore Ctrl-BREAK
|
BRKINT | Generate SIGINT on Ctrl-BREAK
|
IGNPAR | [Ignored]
|
PARMRK | [Ignored]
|
INPCK | [Ignored]
|
ISTRIP | Strip the 8th bit from input
|
INLCR | Map NL to CR on input
|
IGNCR | Ignore CR characters
|
ICRNL | Map CR to NL on input
|
IXON | [Ignored]
|
IXOFF | Enable start/stop input control
|
IMAXBEL | Ring the bell if input line too long
|
The default value of c_iflag
is (BRKINT|ICRNL|IMAXBEL)
.
The c_oflag
member of struct termios
specifies the output
handling:
Symbol | Function
|
OPOST | If not set, output characters verbatim
|
ONLCR | Map newline to CR-LF pair on output
|
OCRNL | Map CR to NL on output
|
ONOEOT | Don't output EOT characters
|
Note that if the OPOST
bit is not set, all the other flags are
ignored and the characters are output verbatim. The default value of
c_oflag
is (OPOST|ONLCR|ONOEOT)
.
The c_ispeed
and c_ospeed
members specify, respectively,
the input and output baudrate of the terminal. They are set by default
to 9600 baud, but the value is always ignored by this implementation,
since no asynchronous ports are used.
#include <conio.h> void textattr(int _attr);
Sets the attribute used for future writes to the screen:
---- XXXX = foreground color -XXX ---- = background color X--- ---- = 1=blink 0=steady
The include file <conio.h> contains an enum COLORS that define the various values that can be used for these bitfields; light colors can only be used for the foreground.
not ANSI, not POSIX
/* blinking white on blue */ textattr(BLINK | (BLUE << 4) | WHITE);
#include <conio.h> void textbackground(int _color);
Sets just the background of the text attribute. See textattr.
not ANSI, not POSIX
#include <conio.h> void textcolor(int _color);
Sets just the foreground of the text attribute. See textattr.
not ANSI, not POSIX
#include <conio.h> void textmode(int _mode);
Sets the text mode of the screen. _mode is one of the following:
LASTMODE
textmode()
.
BW40
C40
BW80
C80
MONO
C4350
See _set_screen_lines, for a more versatile method of setting text screen dimensions.
not ANSI, not POSIX
#include <time.h> time_t time(time_t *t);
If t is not NULL
, the current time is stored in *t
.
The current time is returned.
ANSI, POSIX
printf("Time is %d\n", time(0));
#include <sys/times.h> clock_t times(struct tms *buf);
This function returns the number of clock ticks used by the current
process and all of its children until the moment of call. The number
of tics per second is CLOCKS_PER_SEC
, defined on time.h.
This is the structure in which times
returns its info:
struct tms { clock_t tms_cstime; clock_t tms_cutime; clock_t tms_stime; clock_t tms_utime; };
Currently, the elapsed time of the running program is returned in the
tms_utime
field, and all other fields return as zero.
The number of elapsed tics since the program started.
not ANSI, POSIX
printf("We used %d seconds of elapsed time\n", times(&buf)/CLOCKS_PER_SEC);
#include <stdio.h> FILE *tmpfile(void);
This function opens a temporary file. It will automatically be removed if the file is closed or when the program exits. The name of the file is generated by the same algorithm as described under tmpnam() (see tmpnam).
A newly opened file.
ANSI, POSIX
FILE *tmp = tmpfile();
#include <stdio.h> char *tmpnam(char *s);
This functions generates a string that is a valid file name and that
is not the same as the name of an existing file. A different string is
guaranteed to be produced each time it is called, up to TMP_MAX
times (TMP_MAX
is defined on stdio.h). If tmpnam
is called
more than TMP_MAX times, the behavior is implementation-dependent (ours
just wraps around and tries to reuse the same file names from the
beginning).
This function examines the environment to determine the directory in which
the temporary file will be opened. It looks for one of the variables
"TMPDIR"
, "TEMP"
and "TMP"
, in that order. The first
one which is found in the environment will be used on the assumption that
it points to a directory. If neither of the above variables is defined,
tmpnam
defaults to the "c:/" directory (which under MS-DOS might
mean that it fails to generate TMP_MAX unique names, because DOS root
directories cannot grow beyond certain limits).
If s is a null pointer, tmpnam
leaves its result in an
internal static buffer and returns a pointer to that buffer. If s
is not a null pointer, it is assumed to point to an array of at least
L_tmpnam
characters, and tmpnam
writes its result in that
array and returns a pointer to it as its value.
ANSI, POSIX
char buf[L_tmpnam]; char *s = tmpnam(buf);
#include <ctype.h> int toascii(int c);
This function strips the high bit of c, forcing it to be an ASCII character.
The ASCII character.
not ANSI, not POSIX
for (i=0; buf[i]; i++) buf[i] = toascii(buf[i]);
#include <ctype.h> int tolower(int c);
This function returns c, converting it to lower case if it is upper case. See toupper.
The lower case letter.
ANSI, POSIX
for (i=0; buf[i]; i++) buf[i] = tolower(buf[i]);
#include <ctype.h> int toupper(int c);
This function returns c, converting it to upper case if it is lower case. See tolower.
The upper case letter.
ANSI, POSIX
for (i=0; buf[i]; i++) buf[i] = toupper(buf[i]);
#include <sys/stat.h> char * _truename(const char *path, char *true_path);
Given a path of a file, returns in true_path its canonicalized pathname, with all letters uppercased, default drive and directory made explicit, forward slashes converted to backslashes, asterisks converted to appropriate number of of question marks, file and directory names truncated to 8.3 if necessary, "." and ".." resolved, extra slashes (but the last, if present) removed, SUBSTed, JOINed and ASSIGNed drives resolved. Character devices return as "X:/DEVNAME" (note the forward slash!), where X is the CURRENT drive and DEVNAME is the device name (e.g. CON). This is exactly what DOS TRUENAME command does. See Ralph Brown's Interrupt List for more details.
The named path doesn't have to exist, but the drive, if given as part of it, should be a legal DOS drive, as this function hits the disk.
The function will fail if given a path which (1) is an empty string; or (2) contains only the drive letter (e.g. "c:"); or (3) has leading whitespace. It will also fail if it couldn't allocate memory required for its communication with DOS or for true_path (see below).
Upon success, the function will place the result in true_path, if that's non-NULL; the buffer should be large enough to contain the largest possible pathname (PATH_MAX characters). If true_path is a NULL pointer, the space to hold the result will be allocated by calling malloc; it is up to the caller to release the buffer by calling free.
The function returns the pointer to the result. In case of any failure, a NULL pointer is returned, and errno is set.
not ANSI, not POSIX
fprintf(stderr, "True name of %s is %s\n", path, _truename(path, (char *)0));
#include <unistd.h> int truncate(const char *file, off_t size);
This function truncates file to size bytes.
Zero on success, nonzero on failure.
not ANSI, not POSIX
truncate("/tmp/data.txt", 400);
#include <unistd.h> char *ttyname(int file);
Gives the name of the terminal associated with file.
Returns "con" if file is a device, else NULL
.
not ANSI, POSIX
char *tty = ttyname(0);
#include <time.h> extern char *tzname[2]; void tzset(void);
This function initializes the global variable tzname
according to
environment variable TZ
. After the call, tzname
holds the
specifications for the time zone for the standard and daylight-saving
times.
None.
not ANSI, POSIX
#include <time.h> void tzsetwall(void);
This function sets up the time conversion information used by
localtime
(see localtime) so that localtime
returns
the best available approximation of the local wall clock time.
None.
not ANSI, not POSIX
#include <time.h> uclock_t uclock(void);
This function returns the number of uclock ticks since an arbitrary time,
actually, since the first call to uclock
, which itself returns
zero. The number of tics per second is UCLOCKS_PER_SEC
(declared
in the time.h
header file.
uclock
is provided for very high-resulution timing. It is
currently accurate to better than 1 microsecond (actually about 840
nanoseconds). You cannot time across two midnights with this
implementation, giving a maximum useful period of 48 hours and an
effective limit of 24 hours. Casting to a 32-bit integer limits its
usefulness to about an hour before 32 bits will wrap.
Note that printf
will only print a value of type uclock_t
correctly if you use format specifiers for long long
data, such
as %Ld
or %lld
, because uclock_t
is a 64-bit integer.
See printf.
Also note that uclock
reprograms the interval timer in your PC
to act as a rate generator rather than a square wave generator. I've
had no problems running in this mode all the time, but if you notice
strange things happening with the clock (losing time) after using
uclock
, check to see if this is the cause of the problem.
Windows 3.X doesn't allow to reprogram the timer, so the values returned
by uclock
there are incorrect. DOS and Windows 9X don't have
this problem.
The number of tics.
not ANSI, not POSIX
printf("%Ld seconds have elapsed\n", (long long)(uclock()/UCLOCKS_PER_SEC));
#include <sys/stat.h> mode_t umask(mode_t cmask);
This function does nothing. It exists to assist porting.
not ANSI, POSIX
#include <sys/utsname.h> #int uname(struct utsname *u);
Fills in the structure with information about the system.
struct utsname { char machine[9]; char nodename[32]; char release[9]; char sysname[9]; char version[9]; };
machine
nodename
release
sysname
version
Zero on success, else nonzero.
not ANSI, POSIX
#include <stdio.h> int ungetc(int c, FILE *file);
This function pushes c back into the file. You can only push back one character at a time.
The pushed-back character, or EOF
on error.
ANSI, POSIX
int q; while (q = getc(stdin) != 'q'); ungetc(q);
#include <conio.h> int ungetch(int);
Puts a character back, so that getch will return it instead of actually reading the console.
The charater is returned.
not ANSI, not POSIX
#include <unistd.h> int unlink(const char *file);
This function removes a file from the file system.
Zero on success, nonzero on failure.
not ANSI, POSIX
unlink("data.txt");
#include <io.h> int unlock(int fd, long offset, long length);
Unlocks a region previously locked by lock
.
See lock.
Zero if successful, nonzero if not.
not ANSI, not POSIX
#include <fcntl.h> char _use_lfn(const char *path);
The _use_lfn
function returns a nonzero value if the low level
libc routines will use the Long File Name (LFN) functions provided
with Windows 9x (and other advanced filesystems), when accessing files
and directories on the same filesystem as path. path may be
any legal pathname; however, the function only needs the name of the
root directory on the particular drive in question. If path is a
NULL
pointer, the function assumes that all the filesystems
support (or do not support) LFN in the same manner, and returns the info
pertinent to the last filesystem that was queried; this usually makes
the call faster. Note that on Windows 95 you don't need to distinguish
between different drives: they all support LFN API. If path does
not specify the drive explicitly, the current drive is used.
The header fcntl.h
defines a macro _USE_LFN
; applications
should use this macro instead of calling _use_lfn
directly. That
is so this routine could be replaced with one which always returns 0 to
disable using long file names. Calling _USE_LFN
also makes the
code more portable to other operating systems, where the macro can be
redefined to whatever is appropriate for that environment (e.g., it
should be a constant 1 on Unix systems and constant 0 for environments
that don't support LFN API, like some other MSDOS compilers).
Currently, _USE_LFN
assumes that LFN API does not depend
on a drive.
Long file names can also be disabled by setting the flag
_CRT0_FLAG_NO_LFN
in _crt0_startup_flags
for an image
which should not allow use of long file names. Long names can be
suppressed at runtime on a global basis by setting the environment
variable LFN
to N
, i.e. SET LFN=N
. This might be
needed if a distribution expected the truncation of long file names to
8.3 format to work. For example, if a C source routine included the
file exception.h (9 letters) and the file was unzipped as exceptio.h,
then GCC would not find the file unless you set LFN=n
. The
environment variable can be set in the DJGPP.ENV
file to always
disable LFN support on any system, or can be set in the DOS environment
for a short term (single project) basis. If you dual boot a system
between Windows 95 and DOS, you probably should set LFN=n
in your
DJGPP.ENV
file, since long file names would not be visible under
DOS, and working with the short names under DOS will damage the long
names when returning to Windows 95.
If LFN APIs are supported and should be used, it returns 1, else 0.
Note that if the _CRT0_FLAG_NO_LFN
bit is set, or LFN
is
set to N
or n
in the environment, both _use_lfn
and
_USE_LFN
will always return 0 without querying the filesystem.
You can reset the _CRT0_FLAG_NO_LFN
bit at runtime to force
filesystem to be queried.
not ANSI, not POSIX
#include <fcntl.h> #include <sys/stat.h> int fd = creat (_USE_LFN ? "MyCurrentJobFile.Text" : "currjob.txt", S_IRUSR | S_IWUSR);
#include <unistd.h> unsigned usleep(unsigned usec);
This function pauses the program for usec microseconds. Note
that, since usleep
calls clock
internally, and the latter
has a 55-msec granularity, any argument less than 55msec will result in
a pause of random length between 0 and 55 msec. Any argument less
than 11msec (more precisely, less than 11264 microseconds), will always
result in zero-length pause (because clock
multiplies the timer
count by 5). See clock.
The number of unslept microseconds (i.e. zero).
not ANSI, not POSIX
usleep(500000);
#include <utime.h> int utime(const char *file, const struct utimbuf *time);
This function sets the modification timestamp on the file. The new time is stored in this structure:
struct utimbuf { time_t actime; /* access time (unused on FAT filesystems) */ time_t modtime; /* modification time */ };
Note that, as under DOS a file only has a single timestamp, the
actime
field of struct utimbuf
is ignored by this
function, and only modtime
field is used. On filesystems which
support long filenames, both fields are used and both access and
modification times are set.
Zero for success, nonzero for failure.
not ANSI, POSIX
struct utimbuf t; t.modtime = time(0); utime("data.txt", &t);
#include <sys/time.h> int utimes(const char *file, struct timeval tvp[2]);
This function sets the file access time as specified by
tvp[0]
, and its modification time as specified by
tvp[1]
. struct timeval
is defined as follows:
struct timeval { time_t tv_sec; long tv_usec; };
Note that DOS and Windows maintain the file times with 2-second
granularity. Therefore, the tv_usec
member of the argument is
always ignored, and the underlying filesystem truncates (or sometimes
rounds) the actual file time stamp to the multiple of 2 seconds.
On plain DOS, only one file time is maintained, which is arbitrarily
taken from tvp[1].tv_sec
. On Windows 9X, both times are
used, but note that most versions of Windows only use the date part and
ignore the time.
Due to limitations of DOS and Windows, you cannot set times of directories.
Zero on success, nonzero on failure.
not ANSI, not POSIX
time_t now; struct timeval tvp[2]; time(&now); tvp[1].tv_sec = now + 100; utimes("foo.dat", tvp);
#include <debug/v2load.h> int v2loadimage (const char *program, const char *cmdline, jmp_buf load_state);
This function loads an executable image of a DJGPP v2.x program and
prepares it for debugging. program should point to the file name
of the executable program. v2loadimage
does not search
the PATH
and does not try any executable extensions, so
program should point to a fully-qualified path, complete with the
drive, directory, and file-name extension; otherwise the call will fail.
cmdline should point to the command-line arguments to be passed to
the program. The format of the command line should be exactly like the
command tail DOS passes to programs: the first byte gives the length of
the command tail, the tail itself begins with the second byte, and the
tail is terminated by a CR character (decimal code 13); the length byte
does not include the CR. The command-line arguments should look as if
they were to be passed to the library function system
. In
particular, all special characters like wildcards and whitespace should
be quoted as if they were typed at the DOS prompt.
Note that currently, this function doesn't support command lines longer than the DOS 126-character limit.
After the function loads the image and sets up the necessary memory
segments for it to be able to run, it sets load_state so that it
can be used to longjmp
to the debuggee's entry point. This
information is typically used by run_child
(see run_child).
Zero in case of success, non-zero otherwise.
not ANSI, not POSIX
cmdline = (char *) alloca (strlen (args) + 4); cmdline[0] = strlen (args); strcpy (cmdline + 1, args); cmdline[strlen (args) + 1] = 13; if (v2loadimage (exec_file, cmdline, start_state)) { printf ("Load failed for image %s\n", exec_file); exit (1); } edi_init (start_state);
#include <stdarg.h> void va_start(va_list ap, LAST_REQUIRED_ARG); TYPE va_arg(va_list ap, TYPE); void va_end(va_list ap);
Used to write functions taking a variable number of arguments. Note that these are actually macros, and not functions. You must prototype the function with `...' in its argument list. Then, you do the following:
va_list
.
va_start
with it and the name of the
last required (i.e. non-variable) argument.
va_arg
with the
va_list
variable and the type of the argument. As another
alternative, you can pass the va_list
to another function,
which may then use va_arg
to get at the arguments.
vprintf
is an example of this.
va_end
to destroy the va_list
.
Be aware that your function must have some way to determine the number
and types of the arguments. Usually this comes from one of the required
arguments. Some popular ways are to pass a count, or to pass some
special value (like NULL
) at the end.
Also, the variable arguments will be promoted according to standard C
promotion rules. Arguments of type char
and short
will
be promoted to int
, and you should retrieve them as such. Those
of type float
will be promoted to double
.
va_arg
returns the argument it fetched, the other macros return nothing.
ANSI, POSIX
int find_the_sum(int count, ...) { va_list ap; int i; int total = 0; va_start(ap, count); for (i = 0; i < count; i++) total += va_arg(ap, int); va_end(ap); return total; } int other_function(void) { return find_the_sum(6, 1, 2, 3, 4, 5, 6); }
#include <unistd.h> pid_t vfork(void);
This function always returns -1 and sets `errno' to ENOMEM, as MS-DOS does not support multiple processes. It exists only to assist in porting Unix programs.
not ANSI, not POSIX
#include <stdio.h> #include <stdarg.h> int vfprintf(FILE *file, const char *format, va_list arguments);
Sends formatted output from the arguments to the file. See printf.
The number of characters written.
ANSI, POSIX
void my_errmsg(char *format, ...) { va_list arg; va_start(arg, format); fprintf(stderr, "my_errmsg: "); vfprintf(stderr, format, arg); va_end(arg); }
#include <stdio.h> int vfscanf(FILE *file, const char *format, va_list arguments);
This function scans formatted text from file and stores it in the variables pointed to by the arguments. See scanf.
The number of items successfully scanned.
not ANSI, not POSIX
#include <stdio.h> #include <stdarg.h> int vprintf(const char *format, va_list arguments);
Sends formatted output from the arguments to stdout
.
See printf. See vfprintf.
The number of characters written.
ANSI, POSIX
#include <stdio.h> int vscanf(const char *format, va_list arguments);
This function scans formatted text from stdin
and stores it in the
variables pointed to by the arguments. See scanf.
See vfscanf.
The number of items successfully scanned.
not ANSI, not POSIX
#include <stdio.h> #include <stdarg.h> int vsprintf(char *buffer, const char *format, va_list arguments);
Sends formatted output from the arguments to the buffer. See printf. See vfprintf.
The number of characters written.
ANSI, POSIX
#include <stdio.h> int vsscanf(const char *string, const char *format, va_list arguments);
This function scans formatted text from the string and stores it in the variables pointed to by the arguments. See scanf. See vfscanf.
The number of items successfully scanned.
not ANSI, not POSIX
#include <sys/wait.h> pid_t pid = wait(int *status);
This function causes its caller to delay its execution until a signal
is received or one of its child processes terminates. If any child has
terminated, return is immediate, returning the process ID and its exit
status, if that's available. If no children processes were called since
the last call, then -1 is returned and errno
is set.
If successful, this function returns the exit status of the child. If
there is an error, these functions return -1 and set errno
to
indicate the error type.
Currently, this function always fails.
not ANSI, POSIX
#include <sys/wait.h> pid_t pid = waitpid((pid_t pid, int *status, int options);
Currently, this function always fails. A -1 is returned and errno
is set to indicate there are no children.
If successful, this function returns the exit status of the child. If
there is an error, these functions return -1 and set errno
to
indicate the error type.
Currently, this function always fails.
not ANSI, POSIX
#include <stdlib.h> size_t wcstombs(char *s, const wchar_t *wcs, size_t n);
Converts a wide character string to a multibyte string. At most n characters are stored.
The number of characters stored.
ANSI, POSIX
int len = wcstombs(buf, wstring, sizeof(buf));
#include <stdlib.h> int wctomb(char *s, wchar_t wchar);
Convert a wide character to a multibyte character. The string s
must be at least MB_LEN_MAX
bytes long.
The number of characters stored.
ANSI, POSIX
char s[MB_LEN_MAX]; int mlen = wctomb(s, wc);
#include <conio.h> int wherex(void);
The column the cursor is on. The leftmost column is 1.
not ANSI, not POSIX
#include <conio.h> int wherey(void);
The row the cursor is on. The topmost row is 1.
not ANSI, not POSIX
#include <debug/wild.h> int wild (char *pattern, char *string);
This function matches a string pointed to by string against a
pattern pointed to by pattern. pattern may include wildcard
characters ?
and *
, meaning, respectively, any single
character and any string of characters. The function returns non-zero
if the string matches the pattern, zero otherwise.
This functions is meant to be used for simple matching of patterns, such as if a debugger needs to allow specification of symbols using wildcards.
The function returns non-zero if the string matches the pattern, zero otherwise.
not ANSI, not POSIX
#include <conio.h> void window(int _left, int _top, int _right, int _bottom);
Specifies the window on the screen to be used for future output requests. The upper left corner of the physical screen is (1,1).
not ANSI, not POSIX
#include <unistd.h> int write(int file, const void *buffer, size_t count);
This function writes count bytes from buffer to file. It returns the number of bytes actually written. It will return zero or a number less than count if the disk is full, and may return less than count even under valid conditions.
Note that if file is a text file, write
may write more
bytes than it reports.
If count is zero, the function does nothing and returns zero.
Use _write
if you want to actually ask dos to write zero bytes.
The precise behavior of write
when the target filesystem is full
are somewhat troublesome, because DOS doesn't fail the underlying system
call. If your application needs to rely on errno
being set to
ENOSPC
in such cases, you need to invoke write
as shown in
the example below. In a nutshell, the trick is to call write
one
more time after it returns a value smaller than the count
parameter; then it will always set errno
if the disk is
full.
The number of bytes written, zero at EOF, or -1 on error.
not ANSI, POSIX
This example shows how to call write
in a way which ensures that
errno
will be set to ENOSPC
if the target filesystem is or
becomes full:
char *buf_ptr; /* the buffer to write */ size_t buf_len; /* the number of bytes to write */ int desc; /* the file descriptor to write to */ while (buf_len > 0) { int written = write (desc, buf_ptr, buf_len); if (written <= 0) break; buf_ptr += written; buf_len -= written; }
#include <io.h> ssize_t _write(int fildes, void *buf, size_t nbyte);
This is a direct connection to the MS-DOS write function call, int
0x21, %ah = 0x40. No conversion is done on the data; it is written as
raw binary data. This function can be hooked by the File-system
extensions, see File System Extensions. If you don't want this,
you should use _dos_write
instead, see _dos_write.
The number of bytes written, or -1 (and errno
set) in case of
failure.
Note that DOS doesn't return an error indication when the target disk is
full; therefore if the disk fills up while the data is written,
_write
does not return -1, it returns the number of
bytes it succeeded to write. If you need to detect the disk full
condition reliably, call _write
again to try to write the rest of
the data. This will cause DOS to return zero as the number of written
bytes, and then _write
will return -1 and set errno
to ENOSPC
. The example below shows one way of doing this.
not ANSI, not POSIX
This example shows how to call _write
in a way which ensures that
errno
will be set to ENOSPC
if the target filesystem is or
becomes full:
char *buf_ptr; /* the buffer to write */ size_t buf_len; /* the number of bytes to write */ int desc; /* the file descriptor to write to */ while (buf_len > 0) { int written = _write (desc, buf_ptr, buf_len); if (written <= 0) break; buf_ptr += written; buf_len -= written; }
#include <debug/dbgcom.h> void write_child (unsigned child_addr, void *buf, unsigned len);
This function transfers len bytes from the buffer pointed to by
buf in the debugger's data segment to the memory of the debugged
process starting at the address child_addr. It is used primarily
to insert a breakpoint instruction into the debugged process (to trigger
a trap when the debuggee's code gets to that point). The companion
function read_child
(see read_child) is usually called before
write_child
to save the original code overwritten by the
breakpoint instruction.
The function return zero if it has successfully transferred the data, non-zero otherwise (e.g., if the address in child_addr is outside the limits of the debuggee's code segment.
not ANSI, not POSIX
#include <debug/dbgcom.h> void write_sel_addr (unsigned sel, unsigned offset, void *buf, unsigned len);
This function transfers len bytes from the buffer pointed to by
buf in the data segment whose selector is sel, at offset
offset. The companion function read_sel_addr
(see read_sel_addr) is usually called before write_sel_addr
to save the original contents, if needed.
The function return zero if it has successfully transferred the data, non-zero otherwise (e.g., if the address in offset is outside the limits of the sels segment).
not ANSI, not POSIX
#include <stdlib.h> void xfree(void *ptr);
Frees memory allocated by xmalloc
(see xmalloc). This
function guarantees that a NULL pointer is handled gracefully.
Note that, currently, the header stdlib.h
does not
declare a prototype for xfree
, because many programs declare
its prototype in different and conflicting ways. If you use
xfree
in your own code, you might need to provide your own
prototype explicitly.
not ANSI, not POSIX
void *f = xmalloc(100); xfree(f);
#include <stdlib.h> void *xmalloc(size_t size);
This function is just like malloc
(see malloc), except that if
there is no more memory, it prints an error message and exits.
Note that, currently, the header stdlib.h
does not
declare a prototype for xmalloc
, because many programs declare
its prototype in different and conflicting ways. If you use
xmalloc
in your own code, you might need to provide your own
prototype explicitly.
A pointer to the newly allocated memory.
not ANSI, not POSIX
char *f = xmalloc(100);
#include <stdlib.h> void *xrealloc(void *ptr, size_t size);
This function is just like realloc
(see realloc), except that
if there is no more memory, it prints an error message and exits. It
can also properly handle ptr being NULL
.
Note that, currently, the header stdlib.h
does not
declare a prototype for xrealloc
, because many programs declare
its prototype in different and conflicting ways. If you use
xrealloc
in your own code, you might need to provide your own
prototype explicitly.
A pointer to a possibly new block.
not ANSI, not POSIX
char *buf; buf = (char *)xrealloc(buf, new_size);
The DJGPP standard C library is ANSI- and POSIX-compliant, and provides many additional functions for compatibility with Unix/Linux systems. However, some of the functions needed for this compatibility are very hard or impossible to implement using DOS facilities.
Therefore, a small number of library functions are really just stubs:
they are provided because POSIX requires them to be present in a
compliant library, or because they are widely available on Unix systems,
but they either always fail, or handle only the trivial cases and fail
for all the others. An example of the former behavior is the function
fork
: it always returns a failure indication; an example of the
latter behavior is the function mknode
: it handles the cases of
regular files and existing character devices, but fails for all other
file types.
This chapter lists all such functions. This list is here for the benefit of programmers who write portable programs or port Unix packages to DJGPP.
Each function below is labeled as either "always fails" or "trivial", depending on which of the two classes described above it belongs to. An additional class, labeled "no-op", includes functions which pretend to succeed, but have no real effect, since the underlying functionality is either always available or always ignored.
F_DUPFD
and F_GETFD
.
Even when long file names are supported, the three time values
returned by stat
might be identical if the file was last written
by a program which used legacy DOS functions that don't know about long
file names.