home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.hp
- Path: sparky!uunet!think.com!rpi!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 (LONG) (last updated: 13-Nov-1992)
- Message-ID: <1993Jan1.060005.15498@alchemy.chem.utoronto.ca>
- Sender: news@alchemy.chem.utoronto.ca (USENET news)
- Organization: University of Toronto Chemistry Department
- Date: Fri, 1 Jan 1993 06:00:05 GMT
- Lines: 899
-
- 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).
- /etc/utmp - contains all sorts of records, not just current logins;
- old login records are found if file is read blindly.
- setproctitle - doesn't work as expected (see notes below for a version
- that really does work on HP-UX).
-
-
- 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:
- ----------------
-
- For a conversion to a "better" generator, use:
-
- #define srandom srand48
- #define random lrand48
-
- For a simple conversion, use:
-
- 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>" should be modified to contain 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>
-
- #ifndef LOCK_SH
- #define LOCK_SH 1
- #endif
- #ifndef LOCK_EX
- #define LOCK_EX 2
- #endif
- #ifndef LOCK_NB
- #define LOCK_NB 4
- #endif
- #ifndef LOCK_UN
- #define LOCK_UN 8
- #endif
-
- 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);
- }
-
-
- alloca:
- -------
-
- /*
- alloca -- (mostly) portable public-domain implementation -- D A Gwyn
-
- last edit: 86/05/30 rms
- include config.h, since on VMS it renames some symbols.
- Use xmalloc instead of malloc.
-
- This implementation of the PWB library alloca() function,
- which is used to allocate space off the run-time stack so
- that it is automatically reclaimed upon procedure exit,
- was inspired by discussions with J. Q. Johnson of Cornell.
-
- It should work under any C implementation that uses an
- actual procedure stack (as opposed to a linked list of
- frames). There are some preprocessor constants that can
- be defined when compiling for your specific system, for
- improved efficiency; however, the defaults should be okay.
-
- The general concept of this implementation is to keep
- track of all alloca()-allocated blocks, and reclaim any
- that are found to be deeper in the stack than the current
- invocation. This heuristic does not reclaim storage as
- soon as it becomes invalid, but it will do so eventually.
-
- As a special case, alloca(0) reclaims storage without
- allocating any. It is a good idea to use alloca(0) in
- your main control loop, etc. to force garbage collection.
- */
- #ifndef lint
- static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
- #endif
-
- #ifdef emacs
- #include "config.h"
- #ifdef static
- /* actually, only want this if static is defined as ""
- -- this is for usg, in which emacs must undefine static
- in order to make unexec workable
- */
- #ifndef STACK_DIRECTION
- you
- lose
- -- must know STACK_DIRECTION at compile-time
- #endif /* STACK_DIRECTION undefined */
- #endif static
- #else
- #define xmalloc malloc
- #endif emacs
-
- #if defined(X3J11) || defined(__STDC__)
- typedef void *pointer; /* generic pointer type */
- #else
- typedef char *pointer; /* generic pointer type */
- #endif
-
- #define NULL 0 /* null pointer constant */
-
- extern void free();
- extern pointer xmalloc();
-
- /*
- Define STACK_DIRECTION if you know the direction of stack
- growth for your system; otherwise it will be automatically
- deduced at run-time.
-
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown
- */
-
- #ifndef STACK_DIRECTION
- #define STACK_DIRECTION 0 /* direction unknown */
- #endif
-
- #if STACK_DIRECTION != 0
-
- #define STACK_DIR STACK_DIRECTION /* known at compile-time */
-
- #else /* STACK_DIRECTION == 0; need run-time code */
-
- static int stack_dir; /* 1 or -1 once known */
- #define STACK_DIR stack_dir
-
- static void
- find_stack_direction (/* void */)
- {
- static char *addr = NULL; /* address of first
- `dummy', once known */
- auto char dummy; /* to get stack address */
-
- if (addr == NULL)
- { /* initial entry */
- addr = &dummy;
-
- find_stack_direction (); /* recurse once */
- }
- else /* second entry */
- if (&dummy > addr)
- stack_dir = 1; /* stack grew upward */
- else
- stack_dir = -1; /* stack grew downward */
- }
-
- #endif /* STACK_DIRECTION == 0 */
-
- /*
- An "alloca header" is used to:
- (a) chain together all alloca()ed blocks;
- (b) keep track of stack depth.
-
- It is very important that sizeof(header) agree with malloc()
- alignment chunk size. The following default should work okay.
- */
-
- #ifndef ALIGN_SIZE
- #define ALIGN_SIZE sizeof(double)
- #endif
-
- typedef union hdr
- {
- char align[ALIGN_SIZE]; /* to force sizeof(header) */
- struct
- {
- union hdr *next; /* for chaining headers */
- char *deep; /* for stack depth measure */
- } h;
- } header;
-
- /*
- alloca( size ) returns a pointer to at least `size' bytes of
- storage which will be automatically reclaimed upon exit from
- the procedure that called alloca(). Originally, this space
- was supposed to be taken from the current stack frame of the
- caller, but that method cannot be made to work for some
- implementations of C, for example under Gould's UTX/32.
- */
-
- static header *last_alloca_header = NULL; /* -> last alloca header */
-
- pointer
- alloca (size) /* returns pointer to storage */
- unsigned size; /* # bytes to allocate */
- {
- auto char probe; /* probes stack depth: */
- register char *depth = &probe;
-
- #if STACK_DIRECTION == 0
- if (STACK_DIR == 0) /* unknown growth direction */
- find_stack_direction ();
- #endif
-
- /* Reclaim garbage, defined as all alloca()ed storage that
- was allocated from deeper in the stack than currently. */
-
- {
- register header *hp; /* traverses linked list */
-
- for (hp = last_alloca_header; hp != NULL;)
- if (STACK_DIR > 0 && hp->h.deep > depth
- || STACK_DIR < 0 && hp->h.deep < depth)
- {
- register header *np = hp->h.next;
-
- free ((pointer) hp); /* collect garbage */
-
- hp = np; /* -> next header */
- }
- else
- break; /* rest are not deeper */
-
- last_alloca_header = hp; /* -> last valid storage */
- }
-
- if (size == 0)
- return NULL; /* no allocation required */
-
- /* Allocate combined header + user data storage. */
-
- {
- register pointer new = xmalloc (sizeof (header) + size);
- /* address of header */
-
- ((header *)new)->h.next = last_alloca_header;
- ((header *)new)->h.deep = depth;
-
- last_alloca_header = (header *)new;
-
- /* User storage begins just after header. */
-
- return (pointer)((char *)new + sizeof(header));
- }
- }
-
-
- setproctitle:
- -------------
-
- From: Tor Lillqvist (tml@tik.vtt.fi),
- Technical Research Centre of Finland,
- Laboratory for Information Processing (VTT/TIK).
-
- Q: How can I write to the argv[] strings in a program so that the
- altered strings show up in 'ps'?
-
- A: In HP-UX you can't do it by clobbering the argv strings, but with the
- undocumented pstat syscall. This code is from sendmail 5.65c (routine
- conf.c). Modify to your taste (especially remove the " (sendmail)").
-
- /*
- ** SETPROCTITLE -- set process title for ps
- **
- ** Parameters:
- ** fmt -- a printf style format string.
- ** a, b, c -- possible parameters to fmt.
- **
- ** Returns:
- ** none.
- **
- ** Side Effects:
- ** Clobbers argv of our main procedure so ps(1) will
- ** display the title.
- */
-
- /*VARARGS1*/
- void
- #ifdef __STDC__
- setproctitle(const char *fmt, ...)
- #else /* !__STDC__ */
- setproctitle(fmt, va_alist)
- const char *fmt;
- va_dcl
- #endif /* __STDC__ */
- {
- #if defined(SETPROCTITLE) && !defined(SYSV)
- va_list args;
- register char *p;
- register int i;
- #if defined(__hpux) && defined(PSTAT_SETCMD)
- union pstun un;
- #else
- extern char **Argv;
- extern char *LastArgv;
- #endif
- char buf[MAXLINE];
-
- # ifdef __STDC__
- va_start(args, fmt);
- # else /* !__STDC__ */
- va_start(args);
- # endif /* __STDC__ */
- (void) vsprintf(buf, fmt, args);
- va_end(args);
-
- #if defined(__hpux) && defined(PSTAT_SETCMD)
- (void) sprintf(buf + strlen(buf), " (sendmail)");
- un.pst_command = buf;
- pstat(PSTAT_SETCMD, un, strlen(buf), 0, 0);
- #else
- /* make ps print "(sendmail)" */
- p = Argv[0];
- *p++ = '-';
-
- i = strlen(buf);
- if (i > LastArgv - p - 2)
- {
- i = LastArgv - p - 2;
- buf[i] = '\0';
- }
- (void) strcpy(p, buf);
- p += i;
- while (p < LastArgv)
- *p++ = ' ';
- #endif
- #endif /* SETPROCTITLE && !SYSV */
- }
-