diff options
| author | cvs2svn <cvs2svn@FreeBSD.org> | 2000-08-04 08:05:53 +0000 |
|---|---|---|
| committer | cvs2svn <cvs2svn@FreeBSD.org> | 2000-08-04 08:05:53 +0000 |
| commit | 9817a6f41e64e7cffc76ff23bf1f60dc7ad37d8b (patch) | |
| tree | e23f45f2a6d3c60167e90424d88964218fded096 /lib/libc | |
| parent | 59a6808533c016c6d5495dc0b1758ae488810488 (diff) | |
Notes
Diffstat (limited to 'lib/libc')
| -rw-r--r-- | lib/libc/alpha/gen/rfork_thread.S | 65 | ||||
| -rw-r--r-- | lib/libc/gen/setproctitle.c | 147 | ||||
| -rw-r--r-- | lib/libc/i386/gen/rfork_thread.S | 112 |
3 files changed, 324 insertions, 0 deletions
diff --git a/lib/libc/alpha/gen/rfork_thread.S b/lib/libc/alpha/gen/rfork_thread.S new file mode 100644 index 000000000000..ff0ed2c5acc2 --- /dev/null +++ b/lib/libc/alpha/gen/rfork_thread.S @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include "SYS.h" +#include <sys/syscall.h> +/* #include <machine/pal.h> */ + +/* + * This is pretty evil and based mostly on examples from other syscall + * stubs and code that gcc generated. Correctness is uncertain, but it + * seems to work quite happily. + */ +LEAF(rfork_thread, 1) + br gp,L1 /* XXX profiling */ +L1: + LDGP(pv) + lda sp,-16(sp) + stq ra,0(sp) + mov a3,a5 + CALLSYS_ERROR(rfork) + beq v0,$child + addl v0,zero,v0 + ldq ra,0(sp) + lda sp,16(sp) + RET +$child: + mov a1,sp + lda sp,-16(sp) + stq zero,0(sp) + mov a5,a0 + mov a2,t12 + jsr ra,(t12),0 + ldgp gp,0(ra) + mov v0,a0 +#ifdef SYS_exit + CALLSYS_NOERROR(exit) +#else + CALLSYS_NOERROR(sys_exit) +#endif +END(rfork_thread) diff --git a/lib/libc/gen/setproctitle.c b/lib/libc/gen/setproctitle.c new file mode 100644 index 000000000000..d0f224bff86d --- /dev/null +++ b/lib/libc/gen/setproctitle.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1995 Peter Wemm <peter@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice immediately at the beginning of the file, without modification, + * this list of conditions, and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Absolutely no warranty of function or purpose is made by the author + * Peter Wemm. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/exec.h> +#include <sys/sysctl.h> + +#include <vm/vm.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +/* + * Older FreeBSD 2.0, 2.1 and 2.2 had different ps_strings structures and + * in different locations. + * 1: old_ps_strings at the very top of the stack. + * 2: old_ps_strings at SPARE_USRSPACE below the top of the stack. + * 3: ps_strings at the very top of the stack. + * This attempts to support a kernel built in the #2 and #3 era. + */ + +struct old_ps_strings { + char *old_ps_argvstr; + int old_ps_nargvstr; + char *old_ps_envstr; + int old_ps_nenvstr; +}; +#define OLD_PS_STRINGS ((struct old_ps_strings *) \ + (USRSTACK - SPARE_USRSPACE - sizeof(struct old_ps_strings))) + +#include <stdarg.h> + +#define SPT_BUFSIZE 2048 /* from other parts of sendmail */ +extern char * __progname; /* is this defined in a .h anywhere? */ + +void +setproctitle(const char *fmt, ...) +{ + static struct ps_strings *ps_strings; + static char buf[SPT_BUFSIZE]; + static char obuf[SPT_BUFSIZE]; + static char **oargv, *kbuf; + static int oargc = -1; + static char *nargv[2] = { buf, NULL }; + char **nargvp; + int nargc; + va_list ap; + size_t len; + unsigned long ul_ps_strings; + int oid[4]; + + va_start(ap, fmt); + + if (fmt) { + buf[sizeof(buf) - 1] = '\0'; + + if (fmt[0] == '-') { + /* skip program name prefix */ + fmt++; + len = 0; + } else { + /* print program name heading for grep */ + (void) snprintf(buf, sizeof(buf), "%s: ", __progname); + len = strlen(buf); + } + + /* print the argument string */ + (void) vsnprintf(buf + len, sizeof(buf) - len, fmt, ap); + + nargvp = nargv; + nargc = 1; + kbuf = buf; + } else if (*obuf != '\0') { + /* Idea from NetBSD - reset the title on fmt == NULL */ + nargvp = oargv; + nargc = oargc; + kbuf = obuf; + } else + /* Nothing to restore */ + return; + + va_end(ap); + + /* Set the title into the kernel cached command line */ + oid[0] = CTL_KERN; + oid[1] = KERN_PROC; + oid[2] = KERN_PROC_ARGS; + oid[3] = getpid(); + sysctl(oid, 4, 0, 0, kbuf, strlen(kbuf) + 1); + + if (ps_strings == NULL) { + len = sizeof(ul_ps_strings); + if (sysctlbyname("kern.ps_strings", &ul_ps_strings, &len, NULL, + 0) == -1) + ul_ps_strings = PS_STRINGS; + ps_strings = (struct ps_strings *)ul_ps_strings; + } + + /* PS_STRINGS points to zeroed memory on a style #2 kernel */ + if (ps_strings->ps_argvstr) { + /* style #3 */ + if (oargc == -1) { + /* Record our original args */ + oargc = ps_strings->ps_nargvstr; + oargv = ps_strings->ps_argvstr; + for (nargc = len = 0; nargc < oargc; nargc++) { + snprintf(obuf + len, sizeof(obuf) - len, "%s%s", + len ? " " : "", oargv[nargc]); + if (len) + len++; + len += strlen(oargv[nargc]); + if (len >= sizeof(obuf)) + break; + } + } + ps_strings->ps_nargvstr = nargc; + ps_strings->ps_argvstr = nargvp; + } else { + /* style #2 - we can only restore our first arg :-( */ + if (*obuf == '\0') + strncpy(obuf, OLD_PS_STRINGS->old_ps_argvstr, + sizeof(obuf) - 1); + OLD_PS_STRINGS->old_ps_nargvstr = 1; + OLD_PS_STRINGS->old_ps_argvstr = nargvp[0]; + } +} diff --git a/lib/libc/i386/gen/rfork_thread.S b/lib/libc/i386/gen/rfork_thread.S new file mode 100644 index 000000000000..2d63b67c7d0c --- /dev/null +++ b/lib/libc/i386/gen/rfork_thread.S @@ -0,0 +1,112 @@ +/*- + * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * With thanks to John Dyson for the original version of this. + */ + +#include <SYS.h> + +/* + * 8 12 16 20 + * rfork_thread(flags, stack_addr, start_fnc, start_arg); + * + * flags: Flags to rfork system call. See rfork(2). + * stack_addr: Top of stack for thread. + * start_fnc: Address of thread function to call in child. + * start_arg: Argument to pass to the thread function in child. + */ + +ENTRY(rfork_thread) + pushl %ebp + movl %esp, %ebp + pushl %esi + + /* + * Push thread info onto the new thread's stack + */ + movl 12(%ebp), %esi # get stack addr + + subl $4, %esi + movl 20(%ebp), %eax # get start argument + movl %eax, (%esi) + + subl $4, %esi + movl 16(%ebp), %eax # get start thread address + movl %eax, (%esi) + + /* + * Prepare and execute the thread creation syscall + */ + pushl 8(%ebp) + pushl $0 + leal SYS_rfork, %eax + KERNCALL + jb 2f + + /* + * Check to see if we are in the parent or child + */ + cmpl $0, %edx + jnz 1f + addl $8, %esp + popl %esi + movl %ebp, %esp + popl %ebp + ret + .p2align 2 + + /* + * If we are in the child (new thread), then + * set-up the call to the internal subroutine. If it + * returns, then call __exit. + */ +1: + movl %esi,%esp + popl %eax + call *%eax + addl $4, %esp + + /* + * Exit system call + */ + pushl %eax + pushl $0 +#ifdef SYS_exit + leal SYS_exit, %eax +#else + leal SYS_sys_exit, %eax +#endif + KERNCALL + + /* + * Branch here if the thread creation fails: + */ +2: + PIC_PROLOGUE + jmp PIC_PLT(HIDENAME(cerror)) |
