#include "ruby.h"
#include "ruby/util.h"
#define compat_init_setproctitle ruby_init_setproctitle
#ifndef HAVE_SETPROCTITLE
#include <stdarg.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_PSTAT_H
#include <sys/pstat.h>
#endif
#include <string.h>
#if defined(__APPLE__)
# ifdef HAVE_CRT_EXTERNS_H
# include <crt_externs.h>
# undef environ
# define environ (*_NSGetEnviron())
# else
# include "crt_externs.h"
# endif
#endif
#define SPT_NONE 0
#define SPT_PSTAT 1
#define SPT_REUSEARGV 2
#ifndef SPT_TYPE
# define SPT_TYPE SPT_NONE
#endif
#ifndef SPT_PADCHAR
# define SPT_PADCHAR '\0'
#endif
#if SPT_TYPE == SPT_REUSEARGV
static char *argv_start = NULL;
static size_t argv_env_len = 0;
static size_t argv_len = 0;
#endif
#endif
void
compat_init_setproctitle(int argc, char *argv[])
{
#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
extern char **environ;
char *lastargv = NULL;
char *lastenvp = NULL;
char **envp = environ;
int i;
if (argc == 0 || argv[0] == NULL)
return;
for (i = 0; envp[i] != NULL; i++)
;
if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
environ = envp;
return;
}
for (i = 0; i < argc; i++) {
if (lastargv == NULL || lastargv + 1 == argv[i])
lastargv = argv[i] + strlen(argv[i]);
}
lastenvp = lastargv;
for (i = 0; envp[i] != NULL; i++) {
if (lastenvp + 1 == envp[i])
lastenvp = envp[i] + strlen(envp[i]);
}
argv[1] = NULL;
argv_start = argv[0];
argv_len = lastargv - argv[0];
argv_env_len = lastenvp - argv[0];
for (i = 0; envp[i] != NULL; i++)
environ[i] = ruby_strdup(envp[i]);
environ[i] = NULL;
#endif
}
#ifndef HAVE_SETPROCTITLE
void
setproctitle(const char *fmt, ...)
{
#if SPT_TYPE != SPT_NONE
va_list ap;
char ptitle[1024];
size_t len;
size_t argvlen;
#if SPT_TYPE == SPT_PSTAT
union pstun pst;
#endif
#if SPT_TYPE == SPT_REUSEARGV
if (argv_env_len <= 0)
return;
#endif
va_start(ap, fmt);
if (fmt != NULL) {
vsnprintf(ptitle, sizeof(ptitle) , fmt, ap);
}
va_end(ap);
#if SPT_TYPE == SPT_PSTAT
pst.pst_command = ptitle;
pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0);
#elif SPT_TYPE == SPT_REUSEARGV
len = strlcpy(argv_start, ptitle, argv_env_len);
argvlen = len > argv_len ? argv_env_len : argv_len;
for(; len < argvlen; len++)
argv_start[len] = SPT_PADCHAR;
#endif
#endif
}
#endif