HP 3000 MPE/iX Porting Guide
Last updated May 29, 1998
Welcome to the MPE/iX Porting Guide!
At first glance, porting Unix programs to MPE/iX might seem like a hopeless
task. But the good news is that it's not really that difficult.
HP added a POSIX shell, POSIX utilities (like sed and grep), a POSIX API,
and a hierarchical file system to MPE/iX 4.5 back in 1992. Unfortunately
this major new functionality remained fairly obscure and under-utilized
by the customer base until about 1996, when the GNU gcc C compiler was
ported and released by Mark Klein. Shortly thereafter porting activity
picked up, and major Unix packages like Samba, Apache, syslog, the BIND
DNS server, sendmail, Perl, xntp, and Java were all ported to MPE/iX.
So as you begin your journey into the wonderful world of POSIX porting,
keep the following points in mind:
-
It's not as difficult as you may think.
-
Most major freeware Unix packages obtained from the Internet have been
written with portability as a major goal. There are perhaps 10 major
variants of Unix, and for the most part MPE shares the same idiosyncracies.
Chances are good that if your package comes with an autoconfigure script,
once you get that initial script ported to MPE the rest might be rather
painless. If there is no autoconfigure script, examine the documentation,
source, and header files for any portability symbols that you can define
at compile time via the -D compiler parameter.
-
Some C language experience is helpful, but an expert level of knowledge
is not required.
-
Porting is easier if you have experience on Unix building, installing,
administering, and using the package being ported.
-
The more ports you do, the easier the next one becomes!
-
If you get stuck, take a look at some of the other ports that have already
been done. Chances are good that somebody else has already encountered
and solved your same problem. If you get really stuck, post your
question to the HP3000-L mailing list.
Once you've completed your port, please let
me know if you have any new porting tips that you'd like to add to
this document.
Table of Contents
-
Contributors
-
Documentation
-
Scripts
-
Compiling and Linking
-
Include Files
-
Functions
-
Sockets
-
Terminal I/O
-
Miscellaneous
-
Bugs
Contributors
Documentation
-
Start with the document you're reading now, obviously. :-)
-
Lars' Samba porting notes
-
Berkeley Sockets/iX Reference Manual
-
HP C/iX Library Reference Manual
-
MPE/iX Developer's Kit Reference Manual Volume I
-
MPE/iX Developer's Kit Reference Manual Volume II
-
MPE/iX Shell and Utilities Reference Manual Volume I (tragically not on
LaserROM)
-
MPE/iX Shell and Utilities Reference Manual Volume II (tragically not on
LaserROM)
-
New Features of MPE/iX: Using the Hierarchical File System
-
Having access to Unix documentation for utilities and functions will be
helpful.
-
HP3000 Frequently Asked Questions
(includes information about the HP3000-L mailing list, an invaluable technical
resource for HP3000 users)
Scripts
-
GNU and other autoconfigure scripts need to be modified to run the test
program after it is compiled and linked in order to test for unresolved
external references. Edit the script and insert code near the end of the
ac_link string (but before any file redirection) to run the test program,
i.e. " && ! callci run ./conftest\;stdin=\*notfound | /bin/grep
^UNRESOLVED 1>&5 2>&5". The bogus "stdin=\*notfound" prevents
the test program from actually being run if there were no unresolved external
references, because doing so might cause a non-zero return code if the
test program should die because of incomplete parameters for the function
being tested for.
-
The shell's built-in cat command will drop bytes if you do "cat <inputfile
>outputfile". See Bugs below.
-
/bin/sed has trouble parsing regular expressions that use a / as the leading
and trailing delimiter, with interior / characters. See
Bugs below.
-
MPE commands can be called from the POSIX shell with the built-in callci
command. But if you want to execute callci from a batch job, see
Bugs below.
-
The SH.HPBIN.SYS shell suffers from terribly slow performance when running
huge autoconfigure scripts. For example, running the Perl/iX configure
script takes 45 minutes on a 3000/969KS200, and that's several integer
multiples longer than the time it takes to run the same script on a little
9000/817 running HPUX. Analysis with Glance suggests that the I/O
methods used by the shell to read scripts are very inefficient.
Compiling and Linking
-
Most porting work is done using the GNU gcc compiler from the
Interex MPE Freeware tape. But people are also using the HP C/iX
compiler.
-
Most ported code requires -D_POSIX_SOURCE in order to compile cleanly.
-
All ported socket code requires -D_SOCKET_SOURCE in order to compile cleanly.
-
At link time, unresolved external symbols are not returned as an error
condition because MPE supports run-time binding to external libraries.
This will confuse makefiles and autoconfigure scripts that expect the link
step to die with an error if there are unresolved externals.
-
If you are planning to emulate shared libraries or just want to use XLs
and are using shared data, there are conflicts between libc.a (libc.sl)
and /SYS/PUB/XL that could cause grief. The solution is to remove
those conflicts from libc.a. The LIBS.hp3000 script that comes with a future
release of gcc/iX has been modified to do this. For those that don't use
this script but want to use shared data, they need to be aware that this
could be a problem.
Include Files
-
The following symbols are missing from various include files:
#define AF_INET6 24
#define AF_UNSPEC 0
#define IFF_LOOPBACK 8
#define IFF_POINTOPOINT 0x10
#define IN_CLASSD(i) (((u_long)(i) & ((u_long)0xf0000000)) == ((u_long)0xe0000000))
#define INADDR_NONE (u_long)0xffffffff
#define ITIMER_REAL 0
#define MAX(x, y) ((x > y) ?x :y)
#define MAXNAMLEN 255
#define MAXPATHLEN 1024
#define MIN(x, y) ((x > y) ?y :x)
#define PF_INET AF_INET
#define PF_UNIX AF_UNIX
#define PF_UNSPEC AF_UNSPEC
#define SHM_R 0400 /* Read permission */
#define SHM_W 0200 /* Write permission */
#define S_IEXEC S_IXUSR
#define S_IREAD S_IRUSR
#define S_IWRITE S_IWUSR
#define SIOCGIFDSTADDR 0
#define SOCK_RAW 3
struct itimerval {
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
<grp.h> lacks gr_passwd.
<pwd.h> contains several fields which are uninitialized and unsupported:
/* the following fields are uninitialized until further notice */
char *pw_gecos; /* User info "name,mailstop,workphone,homephone"*/
char *pw_passwd;
char *pw_age;
char *pw_comment; /* User's comment */
long pw_audid;
int pw_audflg;
char *pw_spare[10]; /* expansion room */
Missing include files:
-
<arpa/inet.h>
-
<net/route.h>
-
<nlist.h>
-
<paths.h>
-
<sys/errno.h>
-
<sys/file.h>
-
<sys/mbuf.h>
-
<sys/param.h>
-
<sys/resource.h>
-
<sys/signal.h> (use <signal.h> instead)
-
<sys/time.h>
-
<utmp.h>
-
A good number of the above include files aren't really needed under MPE
at all. For example, if your source contains:
#include <sys/param.h>
The most portable way to not include that file would be to compile with
something like -DMPE and then:
#ifndef MPE
#include <sys/param.h>
#endif
The code you're porting may have already done this for other operating
systems, i.e. (arbitrary random example):
#ifndef AIX
#include <sys/param.h>
#endif
MPE can be added to the exception list like this:
#if !defined(AIX) && !defined(MPE)
#include <sys/param.h>
#endif
These same #if/#ifdef/#endif techniques should be used to bypass any code
that doesn't apply to MPE, or to activate special code required only
for MPE. Note that instead of a user-defined symbol like -DMPE, some
people prefer to use the symbol __hp3000s900 which is automatically defined
by the HP C/iX and gcc/iX compilers (you don't need to specify it via -D),
i.e.:
#ifndef __hp3000s900
#include <sys/param.h>
#endif
libbsd from jazz
contains the following include files that might be of interest:
-
/usr/include/bsd/a.out.h
-
/usr/include/bsd/ar.h
-
/usr/include/bsd/db.h
-
/usr/include/bsd/dirent.h
-
/usr/include/bsd/errno.h
-
/usr/include/bsd/fcntl.h
-
/usr/include/bsd/ftw.h
-
/usr/include/bsd/glob.h
-
/usr/include/bsd/mnttab.h
-
/usr/include/bsd/mpe.h
-
/usr/include/bsd/mpool.h
-
/usr/include/bsd/ndbm.h
-
/usr/include/bsd/nl_types.h
-
/usr/include/bsd/nlist.h
-
/usr/include/bsd/paths.h
-
/usr/include/bsd/pwd.h
-
/usr/include/bsd/resolv.h
-
/usr/include/bsd/sgtty.h
-
/usr/include/bsd/signal.h
-
/usr/include/bsd/stdio.h
-
/usr/include/bsd/stdlib.h
-
/usr/include/bsd/string.h
-
/usr/include/bsd/strings.h
-
/usr/include/bsd/sysexits.h
-
/usr/include/bsd/syslog.h
-
/usr/include/bsd/termios.h
-
/usr/include/bsd/time.h
-
/usr/include/bsd/tzfile.h
-
/usr/include/bsd/unistd.h
-
/usr/include/bsd/utmp.h
-
/usr/include/bsd/arpa/ftp.h
-
/usr/include/bsd/arpa/nameser.h
-
/usr/include/bsd/arpa/telnet.h
-
/usr/include/bsd/arpa/tftp.h
-
/usr/include/bsd/machine/endian.h
-
/usr/include/bsd/net/if.h
-
/usr/include/bsd/net/if_arp.h
-
/usr/include/bsd/netinet/in.h
-
/usr/include/bsd/netinet/in_systm.h
-
/usr/include/bsd/netinet/ip.h
-
/usr/include/bsd/netinet/ip_icmp.h
-
/usr/include/bsd/netinet/ip_var.h
-
/usr/include/bsd/protocols/rwhod.h
-
/usr/include/bsd/protocols/talkd.h
-
/usr/include/bsd/rpc/rpc.h
-
/usr/include/bsd/sys/cdefs.h
-
/usr/include/bsd/sys/dir.h
-
/usr/include/bsd/sys/errno.h
-
/usr/include/bsd/sys/file.h
-
/usr/include/bsd/sys/ioctl.h
-
/usr/include/bsd/sys/mman.h
-
/usr/include/bsd/sys/param.h
-
/usr/include/bsd/sys/resource.h
-
/usr/include/bsd/sys/signal.h
-
/usr/include/bsd/sys/socket.h
-
/usr/include/bsd/sys/stat.h
-
/usr/include/bsd/sys/statfs.h
-
/usr/include/bsd/sys/stdsyms.h
-
/usr/include/bsd/sys/syslog.h
-
/usr/include/bsd/sys/time.h
-
/usr/include/bsd/sys/ttychars.h
-
/usr/include/bsd/sys/wait.h
Various include files are available from the POSIX
wrappers package on jazz:
-
/POSIXC50/include/errnongd.h
-
/POSIXC50/include/general.h
-
/POSIXC50/include/grp.h
-
/POSIXC50/include/langinfo.h
-
/POSIXC50/include/libgen.h
-
/POSIXC50/include/mpe2.h
-
/POSIXC50/include/mpeaif.h
-
/POSIXC50/include/mpeerrno.h
-
/POSIXC50/include/mpestub.h
-
/POSIXC50/include/ourhdr.h
-
/POSIXC50/include/setsigint.h
-
/POSIXC50/include/signal.h
-
/POSIXC50/include/syslog.h
-
/POSIXC50/include/tcmpe.h
-
/POSIXC50/include/termtype.h
-
/POSIXC50/include/time.h
-
/POSIXC50/include/ulimit.h
-
/POSIXC50/include/unistd.h
-
/POSIXC50/include/util.h
-
/POSIXC50/include/sys/stat.h
Functions
-
MPE children created via fork() won't continue to run in the background
if the parent process terminates. Workaround: if possible, tell the
parent to just fall into the child code instead of doing fork()/exit().
-
MPE kill() requires you to be executing with the same UID as the process
that you want to kill. Having SM or PM capability is NOT sufficient.
-
MPE link() exists, but is unimplemented. If link() is being used to clone
a file, you can accomplish the same thing by copying the file:
int link(const char *path1, const char *path2)
{
#define LINK_BUFSIZE 4096
char buf[LINK_BUFSIZE];
int errsave, fd_path1, fd_path2, result, readlen, writelen;
struct stat st_path1;
/* Open the original file. */
if ((fd_path1 = open(path1,O_RDONLY)) < 0) return fd_path1;
/* Obtain the size and the mode. */
if ((result = fstat(fd_path1, &st_path1)) < 0)
{
errsave = errno;
close(fd_path1);
errno = errsave;
return result;
}
/* Create the duplicate copy. */
if ((fd_path2 = open(path2,O_CREAT|O_EXCL|O_WRONLY,st_path1.st_mode)) < 0)
{
errsave = errno;
close(fd_path1);
errno = errsave;
return fd_path2;
}
/* Copy all of the bytes LINK_BUFSIZE at a time. */
while ((readlen = read(fd_path1, &buf, LINK_BUFSIZE)) > 0)
if ((writelen = write(fd_path2, &buf, readlen)) < 0) break;
/* Any trouble reading? */
if (readlen < 0)
{
errsave = errno;
close(fd_path1);
close(fd_path2);
errno = errsave;
return readlen;
}
/* Any trouble writing? */
if (writelen < 0)
{
errsave = errno;
close(fd_path1);
close(fd_path2);
errno = errsave;
return writelen;
}
/* Close the input file. */
if ((result = close(fd_path1)) < 0)
{
errsave = errno;
close(fd_path2);
errno = errsave;
return result;
}
/* Close the output file. */
if ((result = close(fd_path2)) < 0) return result;
/* Success. */
return 0;
}
If link() is being used to rename a file (ie. link(old,new); unlink(old)),
just do a rename(old,new) instead.
If link() is being used as an atomic "test and set" method to create
a semaphore file, use open(O_CREAT|O_EXCL|O_WRONLY) instead. The open()
will fail if the file already exists; otherwise it will succeed and create
the file.
MPE does have lstat(), despite it being omitted from the MPE/iX Developer's
Kit manual.
MPE setgid() probably requires GETPRIVMODE(), but doesn't actually do anything
because MPE doesn't support direct gid switching.
MPE setuid() requires GETPRIVMODE(). Note that setuid() will also implicitly
change your gid to that of the MPE account that contains the new user ID.
Note that setuid() will improperly alter your current working directory;
see Bugs below.
MPE stat() and lstat() return st_blksize as zero.
Missing functions:
-
adjtime()
-
bcmp(), bcopy(), and bzero(); Workaround:
# define bcopy(src, dst, len) (memmove((dst), (src), (len)))
# define bzero(dst, len) (memset((dst), '\0', (len)))
# define bcmp(src, dst, len) (memcmp((src), (dst), (len)))
Actually, there are versions of bzero() and friends that exist in the NL.
They are used by certain portions of the kernel. If one forgets to include
the macros and an instruction memory protection happens, it is usually
because the code is binding to bzero() in the NL. Note that with the header
files that were contributed for 6.0, there are macros predefined for bzero()
and friends.
chroot(); no workaround possible; only HP can implement this vital security
functionality
daemon()
endgrent()
endpwent(); but see libBSD from jazz
fsync(); Workaround:
int fsync(fd)
int fd;
{
extern FCONTROL(short, short, void *);
FCONTROL(_MPE_FILENO(fd), 2, NULL);
return 0;
}
ftruncate(); Workaround:
int ftruncate(int fd, size_t wantsize) {
extern FCONTROL(short, short, void *);
long cursize;
/* determine current file size */
if ((cursize = lseek(fd, 0L, 2)) == -1)
return (-1);
/* maybe lengthen... */
if (cursize < wantsize) {
if (lseek(fd, wantsize - 1, 0) == -1 ||
write(fd, "", 1) == -1) {
return (-1);
}
return (0);
}
/* maybe shorten... */
if (wantsize < cursize) {
if (lseek(fd, wantsize - 1, 0) == -1) {
return (-1);
}
FCONTROL(_MPE_FILENO(fd),6,0); /* Write smaller EOF */
return (0);
}
return (0);
}
_getch(); use getchar() instead
getpass(); but see libBSD from jazz
getpwent(); but see libBSD from jazz
getgrent()
gettimeofday(); but see libBSD from jazz
getusershell(); use the constants '/SYS/HPBIN/SH' or '/SYS/PUB/CI' instead
initgroups(); not available under MPE because of limited group support
killpg(); not available under MPE because of limited group support
major() and minor(); Workaround:
#define major(x) 0
#define minor(x) 0
mkstemp()
nice(); but this is coming with 6.0
readv(); loop doing read() instead
setgrent()
setgroups(); not available under MPE because of limited group support
setitimer()
setpwent(); but see libBSD from jazz
setsid()
settimeofday()
statfs()
strcasecmp()
strdup(); but see libBSD from jazz
strncasecmp()
strsep()
utimes()
vfork(); use fork() instead
writev(); loop doing write() instead
A variety of missing functions are available in object-only
form in libbsd.a from jazz:
-
bcopy()
-
compress_mode()
-
dbm_clearerr()
-
dbm_close()
-
dbm_delete()
-
dbm_dirfno()
-
dbm_error()
-
dbm_fetch()
-
dbm_firstkey()
-
dbm_nextkey()
-
dbm_open()
-
dbm_store()
-
dbopen()
-
dosendwait()
-
endpwent()
-
fchmod()
-
fchown()
-
flock()
-
forkpty()
-
fsync()
-
ftruncate()
-
getenv()
-
getmode()
-
getpass()
-
getpwent()
-
gettimeofday()
-
getwd()
-
glob()
-
globfree()
-
hcreate()
-
hdestroy()
-
herror()
-
hsearch()
-
index()
-
login_tty()
-
main()
-
mkstemp()
-
mktemp()
-
mpool_close()
-
mpool_filter()
-
mpool_get()
-
mpool_new()
-
mpool_open()
-
mpool_put()
-
mpool_sync()
-
openpty()
-
putenv()
-
rcmd()
-
rindex()
-
rresvport()
-
ruserok()
-
sendwait()
-
setenv()
-
setlogmask()
-
setmode()
-
setpgrp()
-
setpwent()
-
sigblock()
-
sighold()
-
sigignore()
-
siginterrupt()
-
sigpause()
-
sigrelse()
-
sigsetmask()
-
sigspace()
-
sigvec()
-
sigvector()
-
snprintf()
-
strdup()
-
strsep()
-
subsys_break_handler()
-
tcgetattr()
-
tcgetpgrp()
-
tcsetattr()
-
tcsetpgrp()
-
tempnam()
-
tmpnam()
-
tread()
-
twrite()
-
unsetenv()
-
wait3()
-
writev()
A variety of missing functions are available in source
and object code form in POSIX Wrappers from jazz:
-
/POSIXC50/OPERATOR/source/chfc.c
-
/POSIXC50/OPERATOR/source/chfccmd.c
-
/POSIXC50/OPERATOR/source/chspacecmd.c
-
/POSIXC50/OPERATOR/source/online.c
-
/POSIXC50/SCRIPTS/source/mktempcmd.c
-
/POSIXC50/SCRIPTS/source/mpenamecmd.c
-
/POSIXC50/SCRIPTS/source/nohup.c
-
/POSIXC50/SCRIPTS/source/pintopidcmd.c
-
/POSIXC50/SCRIPTS/source/printnsf.c
-
/POSIXC50/SCRIPTS/source/printnsfcmd.c
-
/POSIXC50/SCRIPTS/source/putenvcmd.c
-
/POSIXC50/SCRIPTS/source/termtypecmd.c
-
/POSIXC50/SCRIPTS/source/tmpnamcmd.c
-
/POSIXC50/avail/_exit/_exitt.c
-
/POSIXC50/avail/abort/abortt.c
-
/POSIXC50/avail/access/access.c
-
/POSIXC50/avail/access/accessn.c
-
/POSIXC50/avail/access/accesst.c
-
/POSIXC50/avail/access/acctest.c
-
/POSIXC50/avail/atexit/atexitt.c
-
/POSIXC50/avail/atoi/atoit.c
-
/POSIXC50/avail/chmod/chmodt.c
-
/POSIXC50/avail/clock/clockt.c
-
/POSIXC50/avail/confstr/confstrt.c
-
/POSIXC50/avail/dup2/dup2t.c
-
/POSIXC50/avail/environ/environt.c
-
/POSIXC50/avail/exec/echoall.c
-
/POSIXC50/avail/exec/execl1t.c
-
/POSIXC50/avail/exec/execlt.c
-
/POSIXC50/avail/exec/execvpt.c
-
/POSIXC50/avail/exec/execvt.c
-
/POSIXC50/avail/exit/exitt.c
-
/POSIXC50/avail/fcntl/daemonsut.c
-
/POSIXC50/avail/fcntl/deadlockt.c
-
/POSIXC50/avail/fcntl/execl.c
-
/POSIXC50/avail/fcntl/fcntl.c
-
/POSIXC50/avail/fcntl/fcntlct.c
-
/POSIXC50/avail/fcntl/lockmandt.c
-
/POSIXC50/avail/fcntl/lockregt.c
-
/POSIXC50/avail/fcntl/lockreoft.c
-
/POSIXC50/avail/fcntl/locktest.c
-
/POSIXC50/avail/fcntl/nonblrt.c
-
/POSIXC50/avail/fcntl/nonblwt.c
-
/POSIXC50/avail/fcntl/prflags.c
-
/POSIXC50/avail/filehole/filehole.c
-
/POSIXC50/avail/fnmatch/fnmatcht.c
-
/POSIXC50/avail/fopen/fopen253t.c
-
/POSIXC50/avail/getcwd/getcwdt.c
-
/POSIXC50/avail/geteuid/geteuidt.c
-
/POSIXC50/avail/getgroups/getgroupst.c
-
/POSIXC50/avail/getlogin/getlogin.c
-
/POSIXC50/avail/getlogin/getlogint.c
-
/POSIXC50/avail/getopt/getopt.c
-
/POSIXC50/avail/getopt/getopt1t.c
-
/POSIXC50/avail/getopt/getoptt.c
-
/POSIXC50/avail/getpid/getpidt.c
-
/POSIXC50/avail/getpwnam/pwnamt.c
-
/POSIXC50/avail/getpwuid/pwuidt.c
-
/POSIXC50/avail/getuid/getuidt.c
-
/POSIXC50/avail/getuid/printuidst.c
-
/POSIXC50/avail/glob/globt.c
-
/POSIXC50/avail/ioctl/ioctl.c
-
/POSIXC50/avail/isatty/isattyt.c
-
/POSIXC50/avail/lstat/filetypet.c
-
/POSIXC50/avail/mkfifo/isfifo.c
-
/POSIXC50/avail/mkfifo/mkfifocmd.c
-
/POSIXC50/avail/mknod/mknod.c
-
/POSIXC50/avail/mknod/mknodt.c
-
/POSIXC50/avail/open/open.c
-
/POSIXC50/avail/open/open1011t.c
-
/POSIXC50/avail/open/openmaxt.c
-
/POSIXC50/avail/open/openreadt.c
-
/POSIXC50/avail/open/opent.c
-
/POSIXC50/avail/open/opentapeout.c
-
/POSIXC50/avail/perror/perrort.c
-
/POSIXC50/avail/pipe/pipet.c
-
/POSIXC50/avail/popen/popent.c
-
/POSIXC50/avail/putenv/putenvt.c
-
/POSIXC50/avail/race_conditions/race.c
-
/POSIXC50/avail/race_conditions/raceav.c
-
/POSIXC50/avail/race_conditions/raceav2.c
-
/POSIXC50/avail/race_conditions/racef.c
-
/POSIXC50/avail/readlink/readlinkt.c
-
/POSIXC50/avail/reg/regt.c
-
/POSIXC50/avail/remove/removet.c
-
/POSIXC50/avail/remove/rmt.c
-
/POSIXC50/avail/rename/rename.c
-
/POSIXC50/avail/rename/renamet.c
-
/POSIXC50/avail/semctl/semctlt.c
-
/POSIXC50/avail/setjmp/setjmpt.c
-
/POSIXC50/avail/setjmp/vart.c
-
/POSIXC50/avail/signal/signalt.c
-
/POSIXC50/avail/sigsetjmp/sigsetjmpt.c
-
/POSIXC50/avail/sigsuspend/critregt.c
-
/POSIXC50/avail/sigsuspend/globvart.c
-
/POSIXC50/avail/stat/statt.c
-
/POSIXC50/avail/symlink/symlinkt.c
-
/POSIXC50/avail/sysconf/confvalt.c
-
/POSIXC50/avail/system/cicmdt.c
-
/POSIXC50/avail/system/systemt.c
-
/POSIXC50/avail/system/systimet.c
-
/POSIXC50/avail/time/timet.c
-
/POSIXC50/avail/times/times1t.c
-
/POSIXC50/avail/times/timest.c
-
/POSIXC50/avail/tmpnam/tmpnam_errnot.c
-
/POSIXC50/avail/tmpnam/tmpnamt.c
-
/POSIXC50/avail/umask/umaskt.c
-
/POSIXC50/avail/uname/uname.c
-
/POSIXC50/avail/unlink/unlink1t.c
-
/POSIXC50/avail/unlink/unlinkt.c
-
/POSIXC50/avail/utime/utime.c
-
/POSIXC50/avail/utime/utimet.c
-
/POSIXC50/avail/utime/utsrt.c
-
/POSIXC50/avail/wordexp/wordexpt.c
-
/POSIXC50/defects/alarm/alarm.c
-
/POSIXC50/defects/alarm/read_timeout.c
-
/POSIXC50/defects/alarm/timeoutljt.c
-
/POSIXC50/defects/alarm/timeoutsrt.c
-
/POSIXC50/defects/alarm/timeoutt.c
-
/POSIXC50/defects/execvp/execvpt.c
-
/POSIXC50/defects/getgrgid/getgrgid.c
-
/POSIXC50/defects/getgrgid/getgrgid_real.c
-
/POSIXC50/defects/getgrgid/getgrmem.c
-
/POSIXC50/defects/getgrgid/getgrmemt.c
-
/POSIXC50/defects/getgrgid/getgrmemxl.c
-
/POSIXC50/defects/getgrgid/grgidt.c
-
/POSIXC50/defects/getgrnam/getgrnam.c
-
/POSIXC50/defects/getgrnam/getgrnam_real.c
-
/POSIXC50/defects/getgrnam/grnamsrt.c
-
/POSIXC50/defects/getgrnam/grnamt.c
-
/POSIXC50/defects/ttyname/ttyname.c
-
/POSIXC50/defects/ttyname/ttynamet.c
-
/POSIXC50/defects/ttyname/ttynsrt.c
-
/POSIXC50/defects/uname/uname.c
-
/POSIXC50/defects/uname/unamet.c
-
/POSIXC50/include/pmpeerror.c
-
/POSIXC50/include/pmpeerrort.c
-
/POSIXC50/include/strmpeerror.c
-
/POSIXC50/notavail/ctermid/ctermid.c
-
/POSIXC50/notavail/ctermid/ctermidt.c
-
/POSIXC50/notavail/fchmod/fchmod.c
-
/POSIXC50/notavail/fchmod/fchmodt.c
-
/POSIXC50/notavail/fpathconf/fpathconf.c
-
/POSIXC50/notavail/fpathconf/fpathconft.c
-
/POSIXC50/notavail/fsync/fsync.c
-
/POSIXC50/notavail/fsync/fsynct.c
-
/POSIXC50/notavail/ftruncate/ftruncate.c
-
/POSIXC50/notavail/ftruncate/ftruncatet.c
-
/POSIXC50/notavail/link/link.c
-
/POSIXC50/notavail/link/linkt.c
-
/POSIXC50/notavail/pathconf/confvalt.c
-
/POSIXC50/notavail/pathconf/pathconf.c
-
/POSIXC50/notavail/pathconf/pathconft.c
-
/POSIXC50/notavail/setgid/setgid.c
-
/POSIXC50/notavail/setgid/setgidt.c
-
/POSIXC50/notavail/setpgid/setpgid.c
-
/POSIXC50/notavail/setpgid/setpgidt.c
-
/POSIXC50/notavail/setsid/setsid.c
-
/POSIXC50/notavail/setsid/setsidt.c
-
/POSIXC50/notavail/setsigint/setsigint.c
-
/POSIXC50/notavail/setsigint/setsigint2.c
-
/POSIXC50/notavail/setsigint/setsigintat.c
-
/POSIXC50/notavail/setsigint/setsigintft.c
-
/POSIXC50/notavail/setsigint/setsigintt.c
-
/POSIXC50/notavail/setsigint/tcsetint1t.c
-
/POSIXC50/notavail/setsigint/tcsetint2t.c
-
/POSIXC50/notavail/setsigint/tcsetintt.c
-
/POSIXC50/notavail/setuid/setuid.c
-
/POSIXC50/notavail/setuid/setuid_real.c
-
/POSIXC50/notavail/setuid/setuids.c
-
/POSIXC50/notavail/setuid/setuidt.c
-
/POSIXC50/notavail/setuid/setuidxl.c
-
/POSIXC50/notavail/tc/crnlt.c
-
/POSIXC50/notavail/tc/read1chart.c
-
/POSIXC50/notavail/tc/read1t.c
-
/POSIXC50/notavail/tc/read2chart.c
-
/POSIXC50/notavail/tc/readt.c
-
/POSIXC50/notavail/tcdrain/tcdrain.c
-
/POSIXC50/notavail/tcdrain/tcdraint.c
-
/POSIXC50/notavail/tcflow/tcflow.c
-
/POSIXC50/notavail/tcflow/tcflowt.c
-
/POSIXC50/notavail/tcflush/tcflush.c
-
/POSIXC50/notavail/tcflush/tcflusht.c
-
/POSIXC50/notavail/tcgetattr/cfgetspeedt.c
-
/POSIXC50/notavail/tcgetattr/tcgetattr.c
-
/POSIXC50/notavail/tcgetattr/termt.c
-
/POSIXC50/notavail/tcgetpgrp/tcgetpgrp.c
-
/POSIXC50/notavail/tcgetpgrp/tcgetpgrpt.c
-
/POSIXC50/notavail/tcsendbreak/tcsendbreak.c
-
/POSIXC50/notavail/tcsendbreak/tcsendbreakt.c
-
/POSIXC50/notavail/tcsetattr/cst.c
-
/POSIXC50/notavail/tcsetattr/cu.c
-
/POSIXC50/notavail/tcsetattr/getpass.c
-
/POSIXC50/notavail/tcsetattr/getpasst.c
-
/POSIXC50/notavail/tcsetattr/getpswd.c
-
/POSIXC50/notavail/tcsetattr/getpswdt.c
-
/POSIXC50/notavail/tcsetattr/noresett.c
-
/POSIXC50/notavail/tcsetattr/raw_cbreakt.c
-
/POSIXC50/notavail/tcsetattr/read1t.c
-
/POSIXC50/notavail/tcsetattr/readioctlt.c
-
/POSIXC50/notavail/tcsetattr/readst.c
-
/POSIXC50/notavail/tcsetattr/readt.c
-
/POSIXC50/notavail/tcsetattr/shesc1t.c
-
/POSIXC50/notavail/tcsetattr/shesct.c
-
/POSIXC50/notavail/tcsetattr/tcsetattr.c
-
/POSIXC50/notavail/tcsetattr/tcsetshescape.c
-
/POSIXC50/notavail/tcsetattr/tcsetshreturn.c
-
/POSIXC50/notavail/tcsetattr/tctest.c
-
/POSIXC50/notavail/tcsetpgrp/tcsetpgrp.c
-
/POSIXC50/notavail/tcsetpgrp/tcsetpgrpt.c
-
/POSIXC50/rmsoon/cont.c
-
/POSIXC50/rmsoon/dirname.c
-
/POSIXC50/rmsoon/setegid.c
-
/POSIXC50/rmsoon/seteuid.c
-
/POSIXC50/rmsoon/streamjob.c
-
/POSIXC50/rmsoon/tcgetattr1.c
-
/POSIXC50/rmsoon/tcsetattr1.c
-
/POSIXC50/rmsoon/whence/whence.c
-
/POSIXC50/rmsoon/whence/whencet.c
-
/POSIXC50/scriptsdev/dirlist.c
-
/POSIXC50/scriptsdev/func.c
-
/POSIXC50/scriptsdev/hellow.c
-
/POSIXC50/stdc/raise/raise.c
-
/POSIXC50/stdc/raise/raiset.c
-
/POSIXC50/test/Xos.c
-
/POSIXC50/test/cpunbuf.c
-
/POSIXC50/test/read.c
-
/POSIXC50/test/structt.c
-
/POSIXC50/unix/basename/basename.c
-
/POSIXC50/unix/basename/basenamet.c
-
/POSIXC50/unix/currlangid/currlangid.c
-
/POSIXC50/unix/currlangid/currlangidt.c
-
/POSIXC50/unix/cuserid/cuseridt.c
-
/POSIXC50/unix/dirname/dirname.c
-
/POSIXC50/unix/dirname/dirnamet.c
-
/POSIXC50/unix/gettimeofday/gettimeofday.c
-
/POSIXC50/unix/gettimeofday/gettimeofdayt.c
-
/POSIXC50/unix/grent/grent.c
-
/POSIXC50/unix/grent/grentn.c
-
/POSIXC50/unix/grent/grentn1.c
-
/POSIXC50/unix/grent/grentt.c
-
/POSIXC50/unix/nice/nice.c
-
/POSIXC50/unix/nice/nicet.c
-
/POSIXC50/unix/psignal/psignal.c
-
/POSIXC50/unix/psignal/psignalt.c
-
/POSIXC50/unix/pwent/pwent.c
-
/POSIXC50/unix/pwent/pwentt.c
-
/POSIXC50/unix/setpgrp/setpgrp.c
-
/POSIXC50/unix/setpgrp/setpgrpt.c
-
/POSIXC50/unix/sync/sync.c
-
/POSIXC50/unix/sync/synct.c
-
/POSIXC50/unix/sys_siglist/siglistt.c
-
/POSIXC50/unix/sys_siglist/signot.c
-
/POSIXC50/unix/sys_siglist/sys_siglist.c
-
/POSIXC50/unix/truncate/truncate.c
-
/POSIXC50/unix/truncate/truncatet.c
-
/POSIXC50/unix/ulimit/ulimit.c
-
/POSIXC50/unix/ulimit/ulimitt.c
-
/POSIXC50/util/apue/clr_fl.c
-
/POSIXC50/util/apue/daemon_init.c
-
/POSIXC50/util/apue/err.c
-
/POSIXC50/util/apue/lock_reg.c
-
/POSIXC50/util/apue/lock_test.c
-
/POSIXC50/util/apue/log.c
-
/POSIXC50/util/apue/open_max.c
-
/POSIXC50/util/apue/openlog.c
-
/POSIXC50/util/apue/par_ch_sig.c
-
/POSIXC50/util/apue/path_alloc.c
-
/POSIXC50/util/apue/pr_exit.c
-
/POSIXC50/util/apue/pr_mask.c
-
/POSIXC50/util/apue/readn.c
-
/POSIXC50/util/apue/set_fl.c
-
/POSIXC50/util/apue/signal_intr.c
-
/POSIXC50/util/apue/syslog.c
-
/POSIXC50/util/apue/tty.c
-
/POSIXC50/util/apue/writen.c
-
/POSIXC50/util/chspace/chspace.c
-
/POSIXC50/util/env/getenv/getenv.c
-
/POSIXC50/util/env/getenv/getenvptr.c
-
/POSIXC50/util/env/getenv/getenvt.c
-
/POSIXC50/util/env/getenv/showenv.c
-
/POSIXC50/util/env/putenv/putenv.c
-
/POSIXC50/util/env/putenv/putenvt.c
-
/POSIXC50/util/errorstoci/errorstoci.c
-
/POSIXC50/util/errorstoci/errorstocit.c
-
/POSIXC50/util/getmpelogin/getmpelogin.c
-
/POSIXC50/util/getmpelogin/getmpelogint.c
-
/POSIXC50/util/getpw/getpw.c
-
/POSIXC50/util/getpw/getpwt.c
-
/POSIXC50/util/getpw/getpwxl.c
-
/POSIXC50/util/getvar/getvar.c
-
/POSIXC50/util/getvar/getvart.c
-
/POSIXC50/util/mpename/mpename.c
-
/POSIXC50/util/pintopid/pintopid.c
-
/POSIXC50/util/putvar/putvar.c
-
/POSIXC50/util/putvar/putvart.c
-
/POSIXC50/util/system_output/system_output.c
-
/POSIXC50/util/system_output/system_outputt.c
-
/POSIXC50/util/termtype/termtype.c
Sockets
-
bind()
-
MPE bind() requires GETPRIVMODE() to bind to ports less than 1024.
-
You cannot bind() to specific network interface addresses; instead you
must bind to the wildcard address of zero (i.e. INADDR_ANY). This
may cause problems for programs that use ioctl() to obtain the IP address
of each network interface and then proceed to bind() to each of those non-zero
addresses.
-
Duplicating socket descriptors may result in a system abort the next time
you call fork(); see Bugs below.
-
You *MUST* use sfcntl() to manipulate socket descriptors instead of fcntl().
Unfortunately this can be very painful if the program you are porting has
some fcntl() calls against socket descriptors, and other fcntl() calls
against file descriptors. You cannot use sfcntl() to manipulate file
descriptors.
-
Socket options defined in include files but not supported by setsockopt():
-
SO_KEEPALIVE
-
SO_REUSEADDR
-
SO_SNDBUF
-
TCP_NODELAY
-
recvfrom()
-
Calling recvfrom() against a stream will error with EOPNOTSUPP. Use
recv() instead.
-
The from address of a packet sent from the local host will inappropriately
be 127.0.0.1; see Bugs below.
-
MPE can't connect() to datagram sockets.
-
MPE inetd inappropriately passes the incoming socket only as stdin (fd
0), whereas HPUX inetd passes the incoming socket as stdin (fd 0) and stdout
(fd 1); see Bugs below.
-
Though it's not documented, ioctl() appears to support SIOCGIFxxx requests
for obtaining network interface configuration information.
-
The maximum size of the from address structure used by recvfrom() is sizeof(struct
sockaddr_in).
Terminal I/O
Ha ha ha ha! I feel sorry for you if you have to read this section!
The POSIX General Terminal Interface was never formally completed.
But see libbsd
from jazz for an unsupported informal implementation.
-
Missing functions (all of these are in libbsd):
-
getpass()
-
tcgetattr()
-
tcsetattr()
Miscellaneous
-
MPE does not appear to pass a valid environment pointer as the third positional
parameter to the main() outer block, i.e. main(argc, argv, envp).
Workaround:
int
main (argc, argv, envp)
int argc;
char **argv;
char **envp;
{
#ifdef __hp3000s900
envp = environ;
#endif
MPE does not support setuid/gid binaries, i.e. "chmod u+s setuidnmprg"
and "chmod g+s setgidnmprg".
MPE POSIX group names are returned by the gid-related functions in the
format "ACCOUNT" and POSIX user names are returned by the uid-related functions
in the format "USER.ACCOUNT".
MPE lacks the concept of uid 0 (i.e. root). When a POSIX function normally
requires you to be uid 0 in order to call it, MPE generally expects GETPRIVMODE().
MPE lacks /etc/group.
MPE lacks /etc/passwd.
MPE lacks /etc/utmp.
MPE lacks /dev/console. Workaround: use PRINTOP() (documented and
supported) or genmsg() (undocumented and unsupported).
MPE lacks supplementary group memberships. A process may belong to
one and only one group (the gid associated with your MPE account).
MPE programs with special capabilities (i.e. PM etc) must reside in the
MPE name space and cannot reside in the HFS name space. However,
you can certainly create a HFS symbolic link to point to the MPE program
name expressed in /ACCOUNT/GROUP/PROGRAM syntax.
HFS file names use a rather restrictive character set of A-Za-Z0-9_.- but
this is liberalized by the unsupported
MPEJXQ1 patch. Note that unsupported MPEJXQ1 has been superseded
by the supported beta patch MPEKX76.
When using POSIX programs to read traditional (i.e. non-bytestream) MPE
files, be aware that some POSIX programs first call stat() to determine
how many bytes are in the file. For fixed record length MPE files,
stat() returns:
(number of records) * (record length + 1 [the implied newline or LF record separator])
The POSIX program then proceeds to read the data. But the MPE bytestream
emulator strips any trailing blanks, and because those blanks are never
seen by your program, you will reach EOF before the stat() amount of filesize
bytes. This may possibly confuse your POSIX program. The best
workaround is to only use bytestream files with POSIX programs. If
you must use traditional MPE files, use variable length records instead
of fixed length records.
It is possible to call traditional MPE intrinsics like FCONTROL against
files opened in POSIX programs. See fsync() above
for an example of this.
Bugs
-
Under certain circumstances, if you use fdopen() to associate a file descriptor
with a stream, and then call fprintf() to print to that same stream, you
will enter an infinite loop within the fprintf() code in /lib/libc.a. The
workaround is to make the stream unbuffered via "setbuf(stream,NULL)".
See SR 5003406538.
-
If you use sfcntl/fcntl(F_SETFL) to set O_NONBLOCK, you will not be able
to unset it with another call to sfcntl/fcntl(F_SETFL). Use the equivalent
ioctl() requests instead. See SR 5003359554.
-
The shell's built-in cat command will drop bytes if
you do "cat <inputfile >outputfile". Use /bin/cat instead.
-
/bin/sed has trouble parsing regular expressions that
use a / as the leading and trailing delimiter, with interior / characters.
Workaround: use any character as the leading/trailing delimiter that does
NOT appear in the interior.
-
setuid() will improperly change the current working
directory to be the home directory of the new uid. The workaround is to
save and restore the cwd:
cwd = getcwd(cwd_buf, 256); /* Preserve the current working directory */
GETPRIVMODE();
result = setuid(uid);
GETUSERMODE();
chdir(cwd_buf); /* Restore the current working directory */
Duplicating socket descriptors via dup(), dup2(), fcntl(F_DUPFD),
or sfcntl(F_DUPFD) will result in a system abort the next time you call
fork().
Calling recvfrom() to read a datagram from the
same host executing the recvfrom() will always result in a "from" address
of 127.0.0.1. The proper Unix behavior is to return a non-loopback
address. A patch has been written and tested within HP to fix this.
MPE inetd inappropriately passes the incoming socket
only as stdin (fd 0), whereas HPUX inetd passes the incoming socket as
stdin (fd 0) and stdout (fd 1). Go figure. SR 5003355016
has been submitted to request that the existing functionality be
documented, and then to enhance the functionality to be like HPUX.
The callci built-in shell command will fail if you
use it from a batch job to execute a MPE command like :SETVAR which does
not support CI input/output redirection (CIOR). Workaround: create
an MPE command file that contains the MPE commands that don't support CIOR,
and then use callci to execute the MPE command file.
ftok() in -lsvipc improperly parses file names according to MPE syntax.
The workaround is to prepend "./" to file names that don't start with '.'
or '/'. SR 5003416081 has been submitted asking for this bug to be
fixed.
Mark Bixby