run_erl.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 1,281 行 · 第 1/3 页

C
1,281
字号
#else#  define SLAVE_SIZE 1024#endif    static char slave[SLAVE_SIZE];    int sfd;#  undef SLAVE_SIZE  /*   * The modern way to find the ptys.   */  if (openpty(&mfd, &sfd, slave, NULL, NULL) == 0) {      close(sfd);      *ptyslave = slave;  }  return mfd;#else  /*   * The traditional way to find ptys. We only try it if openpty()   * is not available.   */  char *major, *minor;  static char majorchars[] = "pqrstuvwxyzabcdePQRSTUVWXYZABCDE";  static char minorchars[] = "0123456789abcdefghijklmnopqrstuv"			     "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_+";  /* In the old time the names where /dex/ptyXY where */  /* X is in "pqrs" and Y in "0123456789abcdef" but FreeBSD */  /* and some Linux version has extended this. */  /* This code could probebly be improved alot. For example look at */  /* http://www.xcf.berkeley.edu/~ali/K0D/UNIX/PTY/code/pty.c.html */  /* http://www.xcf.berkeley.edu/~ali/K0D/UNIX/PTY/code/upty.h.html */  {    /* New style devpts or devfs /dev/pty/{m,s}{0,1....} */    static char ptyname[] = "/dev/pty/mX";    for (minor = minorchars; *minor; minor++) {      ptyname[10] = *minor;      if ((mfd = open(ptyname, O_RDWR, 0)) >= 0) {	ptyname[9] = 's';	*ptyslave = ptyname;	return mfd;      }    }  }  {    /* Unix98 style /dev/ptym/ptyXY and /dev/pty/ttyXY */    static char ptyname[] = "/dev/ptym/ptyXY";    static char ttyname[] = "/dev/pty/ttyXY";    for (major = majorchars; *major; major++) {      ptyname[13] = *major;      for (minor = minorchars; *minor; minor++) {	ptyname[14] = *minor;	if ((mfd = open(ptyname, O_RDWR, 0)) >= 0) {	  ttyname[12] = *major;	  ttyname[13] = *minor;	  *ptyslave = ttyname;	  return mfd;	}      }    }  }  {    /* Old style /dev/ptyXY */    static char ptyname[] = "/dev/ptyXY";    for (major = majorchars; *major; major++) {      ptyname[8] = *major;      for (minor = minorchars; *minor; minor++) {	ptyname[9] = *minor;	if ((mfd = open(ptyname, O_RDWR, 0)) >= 0) {	  ptyname[5] = 't';	  *ptyslave = ptyname;	  return mfd;	}      }    }  }  return -1;#endif}static int open_pty_slave(char *name){  int sfd;#ifdef DEBUG  struct termios tty_rmode;#endif  if ((sfd = open(name, O_RDWR, 0)) < 0) {    return -1;  }#ifdef DEBUG  if (tcgetattr(sfd, &tty_rmode) , 0) {    fprintf(stderr, "Cannot get terminals current mode\n");    exit(-1);  }  show_terminal_settings(&tty_rmode);#endif  return sfd;}/* exec_shell() * Executes the named command (in argv format) in a /bin/sh. IO redirection * should already have been taken care of, and this process should be the * child of a fork. */static void exec_shell(char **argv){  char *sh, **vp;  int i;  sh = "/bin/sh";  if ((argv[0] = strrchr(sh, '/')) != NULL)    argv[0]++;  else    argv[0] = sh;  argv[1] = "-c";  status("Args before exec of shell:\n");  for (vp = argv, i = 0; *vp; vp++, i++)    status("argv[%d] = %s\n", i, *vp);  if (stdstatus) {      fclose(stdstatus);  }  execv(sh, argv);  if (run_daemon) {      OPEN_SYSLOG();  }  ERROR((LOG_ERR,"Could not execve\n"));}/* status() * Prints the arguments to a status file * Works like printf (see vfrpintf) */static void status(const char *format,...){  va_list args;  time_t now;  if (stdstatus == NULL)    stdstatus = fopen(statusfile, "w");  if (stdstatus == NULL)    return;  now = time(NULL);  fprintf(stdstatus, "run_erl [%d] %s", (int)getpid(), ctime(&now));  va_start(args, format);  vfprintf(stdstatus, format, args);  va_end(args);  fflush(stdstatus);}static void daemon_init(void)      /* As R Stevens wants it, to a certain extent anyway... */ {    pid_t pid;    int i, maxfd = HIGHEST_FILENO();     if ((pid = fork()) != 0)	exit(0);#if defined(USE_SETPGRP_NOARGS)    setpgrp();#elif defined(USE_SETPGRP)    setpgrp(0,getpid());#else                               setsid(); /* Seems to be the case on all current platforms */#endif    signal(SIGHUP, SIG_IGN);    if ((pid = fork()) != 0)	exit(0);    /* Should change working directory to "/" and change umask now, but that        would be backward incompatible */    for (i = 0; i < maxfd; ++i ) {	close(i);    }    OPEN_SYSLOG();    run_daemon = 1;}/* error() * Prints the arguments to stderr * Works like printf (see vfrpintf) */static void stderr_error(int priority /* ignored */, const char *format, ...){  va_list args;  time_t now;  now = time(NULL);  fprintf(stderr, "run_erl [%d] %s", (int)getpid(), ctime(&now));  va_start(args, format);  vfprintf(stderr, format, args);  va_end(args);}static void usage(char *pname){  fprintf(stderr, "Usage: %s (pipe_name|pipe_dir/) log_dir \"command [parameters ...]\"\n", pname);  fprintf(stderr, "\nYou may also set the environment variables RUN_ERL_LOG_GENERATIONS\n");  fprintf(stderr, "and RUN_ERL_LOG_MAXSIZE to the number of log files to use and the\n");  fprintf(stderr, "size of the log file when to switch to the next log file\n");}/* Instead of making sure basename exists, we do our own */static char *simple_basename(char *path){    char *ptr;    for (ptr = path; *ptr != '\0'; ++ptr) {	if (*ptr == '/') {	    path = ptr + 1;	}    }    return path;}static void init_outbuf(void){    outbuf_total = 1;    outbuf_base = malloc(BUFSIZ);    clear_outbuf();}static void clear_outbuf(void){    outbuf_in = outbuf_out = outbuf_base;}static int outbuf_size(void){    return outbuf_in - outbuf_out;}static char* outbuf_first(void){    return outbuf_out;}static void outbuf_delete(int bytes){    outbuf_out += bytes;    if (outbuf_out >= outbuf_in) {	outbuf_in = outbuf_out = outbuf_base;    }}static void outbuf_append(char* buf, int n){    if (outbuf_base+outbuf_total < outbuf_in+n) {	/*	 * The new data does not fit at the end of the buffer.	 * Slide down the data to the beginning of the buffer.	 */	if (outbuf_out > outbuf_base) {	    int size = outbuf_in - outbuf_out;	    char* p;	    outbuf_in -= outbuf_out - outbuf_base;	    p = outbuf_base;	    while (size-- > 0) {		*p++ = *outbuf_out++;	    }	    outbuf_out = outbuf_base;	}	/*	 * Allocate a larger buffer if we still cannot fit the data.	 */	if (outbuf_base+outbuf_total < outbuf_in+n) {	    int size = outbuf_in - outbuf_out;	    outbuf_total = size+n;	    outbuf_base = realloc(outbuf_base, outbuf_total);	    outbuf_out = outbuf_base;	    outbuf_in = outbuf_base + size;	}    }    /*     * Copy data to the end of the buffer.     */    memcpy(outbuf_in, buf, n);    outbuf_in += n;}#ifdef DEBUG#define S(x)  ((x) > 0 ? 1 : 0)static void show_terminal_settings(struct termios *t){  printf("c_iflag:\n");  printf("Signal interrupt on break:   BRKINT  %d\n", S(t->c_iflag & BRKINT));  printf("Map CR to NL on input:       ICRNL   %d\n", S(t->c_iflag & ICRNL));  printf("Ignore break condition:      IGNBRK  %d\n", S(t->c_iflag & IGNBRK));  printf("Ignore CR:                   IGNCR   %d\n", S(t->c_iflag & IGNCR));  printf("Ignore char with par. err's: IGNPAR  %d\n", S(t->c_iflag & IGNPAR));  printf("Map NL to CR on input:       INLCR   %d\n", S(t->c_iflag & INLCR));  printf("Enable input parity check:   INPCK   %d\n", S(t->c_iflag & INPCK));  printf("Strip character              ISTRIP  %d\n", S(t->c_iflag & ISTRIP));  printf("Enable start/stop input ctrl IXOFF   %d\n", S(t->c_iflag & IXOFF));  printf("ditto output ctrl            IXON    %d\n", S(t->c_iflag & IXON));  printf("Mark parity errors           PARMRK  %d\n", S(t->c_iflag & PARMRK));  printf("\n");  printf("c_oflag:\n");  printf("Perform output processing    OPOST   %d\n", S(t->c_oflag & OPOST));  printf("\n");  printf("c_cflag:\n");  printf("Ignore modem status lines    CLOCAL  %d\n", S(t->c_cflag & CLOCAL));  printf("\n");  printf("c_local:\n");  printf("Enable echo                  ECHO    %d\n", S(t->c_lflag & ECHO));  printf("\n");  printf("c_cc:\n");  printf("c_cc[VEOF]                           %d\n", t->c_cc[VEOF]);}#endif /* DEBUG *//* * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#ifndef HAVE_STRLCPY#include <sys/types.h>#include <string.h>/* * Copy src to string dst of size siz.  At most siz-1 characters * will be copied.  Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */size_tstrlcpy(char *dst, const char *src, size_t siz){	char *d = dst;	const char *s = src;	size_t n = siz;	/* Copy as many bytes as will fit */	if (n != 0 && --n != 0) {		do {			if ((*d++ = *s++) == 0)				break;		} while (--n != 0);	}	/* Not enough room in dst, add NUL and traverse rest of src */	if (n == 0) {		if (siz != 0)			*d = '\0';		/* NUL-terminate dst */		while (*s++)			;	}	return(s - src - 1);	/* count does not include NUL */}#endif /* !HAVE_STRLCPY */#ifndef HAVE_STRLCAT#include <sys/types.h>#include <string.h>/* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left).  At most siz-1 characters * will be copied.  Always NUL terminates (unless siz <= strlen(dst)). * Returns strlen(src) + MIN(siz, strlen(initial dst)). * If retval >= siz, truncation occurred. */size_tstrlcat(char *dst, const char *src, size_t siz){	char *d = dst;	const char *s = src;	size_t n = siz;	size_t dlen;	/* Find the end of dst and adjust bytes left but don't go past end */	while (n-- != 0 && *d != '\0')		d++;	dlen = d - dst;	n = siz - dlen;	if (n == 0)		return(dlen + strlen(s));	while (*s != '\0') {		if (n != 1) {			*d++ = *s;			n--;		}		s++;	}	*d = '\0';	return(dlen + (s - src));	/* count does not include NUL */}#endif /* !HAVE_STRLCAT */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?