home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.hp
- Path: sparky!uunet!utcsri!helios.physics.utoronto.ca!alchemy.chem.utoronto.ca!news
- From: system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson))
- Subject: BSD to HP-UX porting tricks summary (LONG)
- Message-ID: <1992Sep14.190917.3551@alchemy.chem.utoronto.ca>
- Sender: news@alchemy.chem.utoronto.ca (USENET news)
- Organization: University of Toronto Chemistry Department
- Date: Mon, 14 Sep 1992 19:09:17 GMT
- Lines: 594
-
- HP TRICKS (home-grown and from news postings)
- =============================================
-
- Things to watch out for:
-
- TIOCNOTTY - this is not available on HP-UX (use setsid()); trying
- to open '/dev/tty' will also fail with status -1.
- setpgrp - this doesn't get rid of the controlling terminal
- if you use -lBSD (use setsid()).
- BSD signals - you almost certainly want them if your program came from
- a BSD system (e.g. Sun); this breaks 'setpgrp' among other
- things (see 'man bsdproc' and notes below).
-
-
- getwd:
- ------
-
- /* Replace 'SIZEOFARG-1' with the declared size of "arg", minus 1 */
-
- #ifdef __hpux
- #include <unistd.h>
- #define getwd(arg) getcwd(arg, (size_t) SIZEOFARG-1)
- #else
- char *getwd();
- #endif
-
-
- getrusage:
- ----------
-
- From: scot@pawnee.ugrad.ee.ufl.edu (Scott Miller)
- Newsgroups: comp.sys.hp
- Subject: Re: Where is getrusage()? (Summary)
- Organization: UF EE Department
-
- getrusage() is in the syscall includes
-
- Here is the code fragment I used:
-
- #ifdef hpux
- #include <sys/syscall.h>
- #define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
- #endif /* hpux */
-
-
- srandom, random:
- ----------------
-
- From: mjo@snclib.snc.edu (Mike O'Connor)
- Newsgroups: comp.sys.hp
- Subject: Re: random and srandom on HP9000/720 with HPUX-8.07
-
- #define srandom srand
- #define random rand
-
-
- getdtablesize:
- --------------
-
- /*
- * getdtablesize ()
- *
- * Returns the maximum number of file descriptors allowed.
- */
-
- #include <unistd.h>
-
- int
- getdtablesize ()
- {
- return(sysconf(_SC_OPEN_MAX));
- }
-
-
- usleep:
- -------
-
- /*
- * NAME:
- * usleep -- This is the precision timer for Test Set
- * Automation. It uses the select(2) system
- * call to delay for the desired number of
- * micro-seconds. This call returns ZERO
- * (which is usually ignored) on successful
- * completion, -1 otherwise.
- *
- * ALGORITHM:
- * 1) We range check the passed in microseconds and log a
- * warning message if appropriate. We then return without
- * delay, flagging an error.
- * 2) Load the Seconds and micro-seconds portion of the
- * interval timer structure.
- * 3) Call select(2) with no file descriptors set, just the
- * timer, this results in either delaying the proper
- * ammount of time or being interupted early by a signal.
- *
- * HISTORY:
- * Added when the need for a subsecond timer was evident.
- *
- * AUTHOR:
- * Michael J. Dyer Telephone: AT&T 414.647.4044
- * General Electric Medical Systems GE DialComm 8 *767.4044
- * P.O. Box 414 Mail Stop 12-27 Sect'y AT&T 414.647.4584
- * Milwaukee, Wisconsin USA 53201 8 *767.4584
- * internet: mike@sherlock.med.ge.com GEMS WIZARD e-mail: DYER
- */
-
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <time.h>
- #include <sys/time.h>
- #include <sys/param.h>
- #include <sys/types.h>
-
- int usleep( unsigned long int microSeconds )
- {
- unsigned int Seconds, uSec;
- int nfds, readfds, writefds, exceptfds;
- struct timeval Timer;
-
- nfds = readfds = writefds = exceptfds = 0;
-
- if( (microSeconds == (unsigned long) 0)
- || microSeconds > (unsigned long) 4000000 )
- {
- errno = ERANGE; /* value out of range */
- perror( "usleep time out of range ( 0 -> 4000000 ) " );
- return -1;
- }
-
- Seconds = microSeconds / (unsigned long) 1000000;
- uSec = microSeconds % (unsigned long) 1000000;
-
- Timer.tv_sec = Seconds;
- Timer.tv_usec = uSec;
-
- if( select( nfds, &readfds, &writefds, &exceptfds, &Timer ) < 0 )
- {
- perror( "usleep (select) failed" );
- return -1;
- }
-
- return 0;
- }
-
-
- flock:
- ------
-
- /*
- * flock (fd, operation)
- *
- * This routine performs some file locking like the BSD 'flock'
- * on the object described by the int file descriptor 'fd',
- * which must already be open.
- *
- * The operations that are available are:
- *
- * LOCK_SH - get a shared lock.
- * LOCK_EX - get an exclusive lock.
- * LOCK_NB - don't block (must be ORed with LOCK_SH or LOCK_EX).
- * LOCK_UN - release a lock.
- *
- * Return value: 0 if lock successful, -1 if failed.
- *
- * Note that whether the locks are enforced or advisory is
- * controlled by the presence or absence of the SETGID bit on
- * the executable.
- *
- * Note that there is no difference between shared and exclusive
- * locks, since the 'lockf' system call in SYSV doesn't make any
- * distinction.
- *
- * The file "<sys/file.h>" contains the definitions of the available
- * operations, which must be added manually (see below for the values).
- */
-
- #include <unistd.h>
- #include <sys/file.h>
- #include <errno.h>
-
- extern int errno;
-
- int
- flock (int fd, int operation)
- {
- int i;
-
- switch (operation) {
-
- /* LOCK_SH - get a shared lock */
- case LOCK_SH:
- /* LOCK_EX - get an exclusive lock */
- case LOCK_EX:
- i = lockf (fd, F_LOCK, 0);
- break;
-
- /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
- case LOCK_SH|LOCK_NB:
- /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
- case LOCK_EX|LOCK_NB:
- i = lockf (fd, F_TLOCK, 0);
- if (i == -1)
- if ((errno == EAGAIN) || (errno == EACCES))
- errno = EWOULDBLOCK;
- break;
-
- /* LOCK_UN - unlock */
- case LOCK_UN:
- i = lockf (fd, F_ULOCK, 0);
- break;
-
- /* Default - can't decipher operation */
- default:
- i = -1;
- errno = EINVAL;
- break;
- }
-
- return (i);
- }
-
- /*
- * An alternative version was posted by James Gritton
- * (gritton@byu.edu) in comp.sys.hp.
- * As far as I can tell, it works the same as the above
- * except for the "errno" values returned (and it defaults
- * an invalid operation to "unlock").
- * The definitions of LOCK_xx should be put into <sys/file.h> and/or
- * <fcntl.h>.
- * Note: this was typed in, so it may not work as given.
- */
-
- /*
- *#include <fcntl.h>
- *#define LOCK_SH 1
- *#define LOCK_EX 2
- *#define LOCK_NB 4
- *#define LOCK_UN 8
- *
- * int
- *flock (int fd, int operation)
- *{
- * struct flock fl;
- *
- * switch (operation & ~LOCK_NB) {
- * case LOCK_SH:
- * fl.l_type = F_RDLCK;
- * break;
- * case LOCK_EX:
- * fl.l_type = F_WRLCK;
- * break;
- * default:
- * fl.l_type = F_UNLCK;
- * break;
- * }
- *
- * fl.l_whence = SEEK_SET;
- * fl.l_start = fl.l_len = 0L;
- *
- * return fcntl (fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &fl);
- *}
- */
-
-
- getclktck:
- ----------
-
- /*
- * getclktck ()
- *
- * Returns the value of CLK_TCK (timer resolution).
- */
-
- #include <unistd.h>
-
- int
- getclktck ()
- {
- return(sysconf(_SC_CLK_TCK));
- }
-
-
- getloadavg (works on a wide variety of systems):
- ------------------------------------------------
-
- /*
- * getloadavg (ave, n)
- *
- * This routine returns 'n' double precision floats containing
- * the load averages in 'ave'; at most 3 values will be returned.
- *
- * Return value: 0 if successful, -1 if failed (and all load
- * averages are returned as 0).
- */
-
- #include <sys/types.h>
- #include <stdio.h>
- #include <nlist.h>
- #include <errno.h>
-
- extern int errno;
-
- #define STRSIZ 512 /* Sprintf buffer size */
- static char errstr[STRSIZ]; /* Global sprintf buffer */
-
- int ugetloads(float *a);
- static void mperror(char *s);
- static char *syserr();
-
- #define merror(a1) fprintf(stderr,"%s",a1)
- #define merror1(fmt,a1) { sprintf(errstr,fmt,a1); merror(errstr); }
-
- struct nlist nl[] = {
- #ifdef stardent
- # define unixpath "/unix"
- { "avenrun" },
- #else
- #ifdef __hpux
- # define unixpath "/hp-ux"
- #ifdef __hppa /* series 700 & 800 */
- { "avenrun" },
- #else /* series 300 & 400 */
- { "_avenrun" },
- #endif
- #else
- # define unixpath "/vmunix"
- { "_avenrun" },
- #endif
- #endif
- { 0 },
- };
-
- #ifndef RISCos
- int
- getloadavg (double *a, int na)
- {
- int i, nreturn;
- static int kmem = -1;
- #if defined(vax) || defined(__hpux)
- double avenrun[3];
- #else
- long avenrun[3];
- #endif
- #ifdef NOKMEM
- float aves[3];
- #endif /* NOKMEM */
-
- nreturn = na;
- if ( nreturn < 0 )
- nreturn = 0;
- if ( nreturn > 3 )
- nreturn = 3;
-
- #ifdef NOKMEM
- /* Use 'uptime' output for BSD-like systems with no /dev/kmem */
-
- i = ugetloads(aves);
- if( i == -1 ){
- merror("ugetloads failed\n");
- goto failed;
- }
- for (i = 0; i < nreturn; i++)
- a[i] = aves[i];
-
- #else /*NOKMEM*/
-
- if(kmem == -1) {
- #ifdef sgi
- # include <sys/sysmp.h>
- nl[0].n_value = sysmp(MP_KERNADDR, MPKA_AVENRUN) & 0x7fffffff;
- #else
- nlist(unixpath, nl);
- if (nl[0].n_type==0) {
- merror1("%s: No namelist\n", unixpath);
- goto failed;
- }
- #ifdef stardent
- nl[0].n_value &= 0x7fffffff;
- #endif
- #endif
- if((kmem = open("/dev/kmem", 0)) == -1) {
- mperror("Can't open(/dev/kmem)");
- goto failed;
- }
- }
- if( lseek(kmem, (off_t)nl[0].n_value, 0) == -1 ){
- mperror("Can't lseek in kmem");
- goto failed;
- }
- if( read(kmem, (char *)avenrun, sizeof(avenrun)) != sizeof(avenrun) ){
- mperror("Can't read kmem");
- goto failed;
- }
- for (i = 0; i < nreturn; i++)
- #if defined(sun) || defined(sequent)
- a[i] = avenrun[i] / FSCALE;
- #else
- #ifdef sgi
- a[i] = avenrun[i] / 1024;
- #else
- #if defined(BSD4_2) || defined(__hpux)
- a[i] = avenrun[i];
- #else
- #ifdef stardent
- a[i] = (double)avenrun[i] / (1<<16);
- #else
- a[i] = avenrun[i] / 1024;
- #endif /*stardent*/
- #endif /*BSD4_2*/
- #endif /*sgi*/
- #endif /*sun*/
- #endif /*NOKMEM*/
- return(0);
- failed:;
- for (i = 0; i < nreturn; i++)
- a[i] = 0;
- return(-1);
- }
- #else /*RISCos*/
- #include <sys/fixpoint.h>
- static
- getloadavg (double *a, int na)
- {
- int i, nreturn;
- static int kmem = -1;
- fix avenrun[3];
-
- nreturn = na;
- if ( nreturn < 0 )
- nreturn = 0;
- if ( nreturn > 3 )
- nreturn = 3;
-
- if(kmem == -1) {
- nlist("/unix", nl);
- if (nl[0].n_type==0) {
- merror("/unix: No namelist\n");
- goto failed;
- }
- if((kmem = open("/dev/kmem", 0)) == -1) {
- mperror("Can't open(/dev/kmem)");
- goto failed;
- }
- }
- if( lseek(kmem, (off_t)nl[0].n_value, 0) == -1 ){
- mperror("Can't lseek in kmem");
- goto failed;
- }
- if( read(kmem, (char *)avenrun, sizeof(avenrun)) != sizeof(avenrun) ){
- mperror("Can't read kmem");
- goto failed;
- }
- for (i = 0; i < nreturn; i++)
- a[i] = (int) FIX_TO_INT(avenrun[i]) + .5;
- return(0);
- failed:;
- for (i = 0; i < nreturn; i++)
- a[i] = 0;
- return(-1);
- }
- #endif /* RISCOS */
-
- /* ugetloads(ls)
- * float ld[3];
- *
- * Puts the 1, 5, and 15 minute load averages in the float
- * array passed to it. This program calls upon uptime(1)
- * which could have different ways of printing ie. with bsd4.2
- * " 9:34pm up 11 hrs, 3 users, load average: 0.25, 0.22, 0.24 "
- * notice the commas -- ^ --- ^.
- * while bsd4.1 does not print commas. The BSD41 define will
- * take care of this if that is your system, it defaults to
- * the 4.2 version.
- *
- * Author:
- * John Bien
- * {ihnp4 | ucbvax | decvax}!trwrb!jsb
- *
- * This routine taken from comp.sources.unix: Volume 4, Issue 78
- */
-
- FILE *popen();
-
- ugetloads(ld)
- float ld[3];
- {
- FILE *stream;
- int i;
-
- if((stream = popen("uptime","r")) == NULL)
- return(-1);
-
- #ifdef BSD41
- i = fscanf(stream,"%*[^l] load average: %f %f %f", &ld[0],&ld[1],&ld[2]);
- #else
- i = fscanf(stream,"%*[^l] load average: %f, %f, %f", &ld[0],&ld[1],&ld[2]);
- #endif /* BSD41 */
- pclose(stream);
- return i == 3 ? 0 : -1;
- }
-
- /* Routine to print messages to stderr, appending the system error message */
-
- static void
- mperror(char *s)
- {
- char *p;
- char str[STRSIZ]; /* must have own internal buffer */
-
- if( (p=index(s,'\n')) != NULL )
- *p = '\0';
- sprintf(str,"%s: %s\n", s, syserr());
- if( p )
- *p = '\n';
- merror(str);
- }
-
- /* Routine to get the last system error message */
-
- extern int sys_nerr;
- extern char *sys_errlist[];
-
- static char *
- syserr()
- {
- static char buf[80];
-
- if (errno >= 0 && errno < sys_nerr)
- return(sys_errlist[errno]);
- sprintf(buf,"Unknown error %d", errno);
- return(buf);
- }
-
-
- Dissociate from controlling terminal:
- -------------------------------------
-
- From: jhd@irfu.se (Jan D.)
- Organization: Swedish Institute of Space Physics, Uppsala, Sweden
-
- The code above should look like this on HP-UX (POSIX ?):
-
- #include <unistd.h> /* For _SC_OPEN_MAX */
-
- long tblsiz = sysconf(_SC_OPEN_MAX);
-
- if (fork())
- exit(0);
-
- setsid(); /* Disassociate from controlling terminal */
- for (c = 0; c < tblsiz; c++)
- (void) close(c);
- (void) open("/", O_RDONLY);
- (void) dup2(0, 1);
- (void) dup2(0, 2);
-
-
- Here's the deal regarding '-lBSD':
-
- setpgrp() (in libc) is equivalent to setsid().
- setpgrp(pid, pgrp) (in -lBSD) is equivalent to POSIX setpgid(pid, pgrp).
- setpgrp2(pid, pgrp) is also equivalent to POSIX setpgid(pid, pgrp).
-
- If you don't link with -lBSD you can replace setsid() in with setpgrp()
- if you wan't. They both will get rid of the controlling terminal.
-
- setpgrp(pid, pgrp) (-lBSD style), setpgid(pid, pgrp)
- and setpgrp2(pid, pgrp) will NOT remove the controlling terminal.
-
- Thus: The only way (I know of) in HP-UX to remove the controlling terminal
- is with setsid() or setpgrp() in libc. The only way in POSIX to get
- rid of the controlling terminal is with setsid().
-
-
- setlinebuf:
- -----------
-
- /*
- * setlinebuf (FILE *fp)
- *
- * Routine to set line buffering on "fp".
- */
-
- #include <stdio.h>
-
- int
- setlinebuf (FILE *fp)
- {
- (void) setvbuf (fp, NULL, _IOLBF, 0);
- return(0);
- }
-