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 + -
显示快捷键?