📄 sysutils.c
字号:
struct termios ttyattrs;#endif#ifndef HAVE_TERMIOS_H if(! ioctl(0, TCGETA, &ttyattrs))#else if(! tcgetattr(0, &ttyattrs))#endif return(YES);#if 0 if(errno == EBADF || errno == EINVAL) return(DONT_KNOW);#endif return(NO);}#define NULLDEV "/dev/null"Int32free_fds(){ int *fds = NULL, *newfds = NULL, fd; Int32 num_fds = 0; while((fd = open(NULLDEV, O_RDONLY)) >= 0){ newfds = ZSRENEWP(fds, int, num_fds + 1, num_fds); if(!newfds){ close(fd); break; } fds = newfds; fds[num_fds] = fd; num_fds++; } for(fd = 0; fd < num_fds; fd++) close(fds[fd]); free(fds); return(num_fds);}/* This is for stupid HP's HP-UX-10 header ioctl.h (Grrrrr HP !) */#if defined(__hpux) || defined(hpux)#ifndef TIOCNOTTY#define notdef 1#undef _SYS_IOCTL_INCLUDED#include <sys/ioctl.h>#ifndef TIOCNOTTY#warning Definition of macro TIOCNOTTY cannot be found !#endif#endif#endifintdetach_from_tty(){ int fd, r; r = 1; if((fd = open("/dev/tty", O_RDWR)) >= 0){ r = ioctl(fd, TIOCNOTTY); close(fd); } return(r);}Int32set_env(UChar * vname, UChar * value){ UChar *cptr; Int32 r;#ifdef HAVE_SETENV r = setenv(vname, value, 1);#else#ifdef HAVE_ENVIRON static Flag environ_malloced = NO; extern char **environ; Int32 nl, n, vl, ol; char **cpptr, **fptr = NULL; char *tmp_newstr; r = 0; nl = strlen(vname); vl = strlen(value); for(n = 0, cpptr = environ; *cpptr; cpptr++, n++) if(!strncmp(*cpptr, vname, nl)) if((*cpptr)[nl] == '=') fptr = cpptr; if(fptr){ /* Here i do something, that is a tiny bit risky. The problem is * to find out, if an environment entry has been obtained by malloc * or is belonging to the process initialized segments. There are * no reasonable assumptions to determine this from the pointers * there. So i mark the malloced entries, that i make myself, with * a trailing == sequence behind the null-byte terminating the * string. == is a very unlike sequence appearing in any following * environment variables (usually) on the stack. This would require * a variable with the name = or an empty name, in any way a crazy * thing to do, cause a variable like that is not queryable. On the * other side, if i happen to access bytes, that are above the * entire environment area, it is very unlike, that this leads to * a segfault, because usually the memory above the environment is * used for other stuff, so the accesses are valid. If they really * contain ==, bad day. But i never expect this to happen */ ol = strlen(*fptr); if(ol < nl + vl + 1){ tmp_newstr = NEWP(UChar, nl + 1 + vl + 1 + 2); if(!tmp_newstr){ r = -1; } else{ strcpy(tmp_newstr, *fptr); strcpy(tmp_newstr + nl + 1, value); tmp_newstr[nl + 1 + vl + 1] = '='; tmp_newstr[nl + 1 + vl + 2] = '='; cptr = NULL; if((*fptr)[ol + 1] == '=' && (*fptr)[ol + 2] == '=') cptr = *fptr; *fptr = tmp_newstr; ZFREE(cptr); } } else{ strcpy(*fptr + nl + 1, value); } } else{ cpptr = environ_malloced ? RENEWP(environ, char *, n + 2) : NEWP(char *, n + 2); if(!cpptr){ r = -1; } else{ if(!environ_malloced) memcpy(cpptr, environ, n * sizeof(char *)); cpptr[n + 1] = NULL; cpptr[n] = strchain(vname, "=", value, NULL); if(!*cpptr[n]){ free(cpptr); r = -1; } else{ environ = cpptr; environ_malloced = YES; } } }#else#error No way to set an environment variable. Failing r = -1;#endif#endif return(r);}Int32unset_env(UChar * vname){ Int32 r = 0;#ifdef HAVE_UNSETENV unsetenv(vname);#else#ifdef HAVE_ENVIRON extern char **environ; Int32 l, n; char **cpptr, **fptr, *cptr; char *tmp_newstr; l = strlen(vname); fptr = NULL; for(n = 0, cpptr = environ; *cpptr; cpptr++, n++) if(!strncmp(*cpptr, vname, l)) if((*cpptr)[l] == '=') fptr = cpptr; if(fptr){ cptr = *fptr; l = fptr - environ; memmove(fptr, fptr + 1, (n - l) * sizeof(char *)); /* see above in set_env: If after the string and the trailing * null byte two equal signs == follow, this entry has been * malloced by set_env. So we can free it */ l = strlen(cptr); if(cptr[l + 1] == '=' && cptr[l + 2] == '=') free(cptr); }#else#error No way to set an environment variable. Failing r = -1;#endif#endif return(r);}void /* the super-safe generalized vsyslog */gvsyslog( UChar *ident, int options, int facility, int prio, UChar *fmt, va_list args){ openlog(ident, options, facility);#ifdef HAVE_VSYSLOG vsyslog(prio, fmt, args);#else#ifdef HAVE_VSNPRINTF { UChar lbuf[10000]; /* we just hope, there is nothing important */ /* after 9999 characters any more */ vsnprintf(lbuf, 9998, fmt, args); lbuf[9999] = '\0'; syslog(prio, "%s", lbuf); }#else { UChar *line; int fd; FILE *fp; fd = tmp_file(NULL); if(fd < 0) return; fp = fdopen(fd, "r+"); if(!fp){ close(fd); return; } vfprintf(fp, fmt, args); fseek(fp, 0, SEEK_SET); while(!feof(fp)){ line = fget_alloc_str(fp); if(!line) continue; syslog(prio, "%s", line); free(line); } fclose(fp); }#endif#endif closelog();}voidgenlogmsg(UChar * ident, int prio, int fac, UChar * fmt, ...){ va_list args; va_start(args, fmt); gvsyslog(ident, LOG_PID, fac, prio, fmt, args); va_end(args);}#if defined(unix) || defined(__unix) || defined(_AIX)intopen_to_pipe( UChar *prog, UChar *filename, UChar fds, int *pidp, int mode){ int fd = -1, pid, pp[2], i; char **progargv; if(!filename && !prog) return -1; if(filename){ fd = open(filename, O_WRONLY | O_APPEND | O_CREAT | O_BINARY, mode); if(fd < 0) return(-1); } if(prog){ i = pipe(pp); if(i){ if(filename) close(fd); return(-1); } pid = fork_forced(); if(pid < 0){ if(filename) close(fd); return(-1); } if(!pid){ /* child */ if( (i = cmd2argvqf(&progargv, prog)) ) exit(i); close(pp[1]); if(filename){ if(fds & 1) dup2(fd, 1); if(fds & 2) dup2(fd, 2); } dup2(pp[0], 0); execvp(progargv[0], progargv + 1); exit(errno); } close(pp[0]); if(filename) close(fd); fd = pp[1]; if(pidp) *pidp = pid; } return(fd);} intopen_from_pipe(UChar * prog, UChar * filename, UChar fds, int * pidp){ int fd = -1, pid, pp[2], i; char **progargv; if(!filename && !prog) return -1; if(filename){ fd = open(filename, O_RDONLY | O_BINARY); if(fd < 0) return(-1); } if(prog){ i = pipe(pp); if(i){ if(filename) close(fd); return(-1); } pid = fork_forced(); if(pid < 0){ if(filename) close(fd); return(-1); } if(!pid){ /* child */ close(pp[0]); if( (i = cmd2argvqf(&progargv, prog)) ) exit(i); if(filename){ dup2(fd, 0); } if(fds & 1) dup2(pp[1], 1); if(fds & 2) dup2(pp[1], 2); execvp(progargv[0], progargv + 1); exit(errno); } close(pp[1]); if(filename) close(fd); fd = pp[0]; if(pidp) *pidp = pid; } return(fd);} Int32open_from_to_pipe(UChar * prog, int * pipes, UChar fds, int * pidp){ int pid, topp[2], frompp[2], i, j; char **progargv; if(!prog) return -1; i = pipe(topp); j = pipe(frompp); if(i || j){ if(i){ close(topp[0]); close(topp[1]); } if(j){ close(frompp[0]); close(frompp[1]); } return(-1); } pid = fork_forced(); if(pid < 0){ return(-1); } if(!pid){ /* child */ close(frompp[0]); close(topp[1]); if( (i = cmd2argvqf(&progargv, prog)) ) exit(i); dup2(topp[0], 0); if(fds & 1) dup2(frompp[1], 1); if(fds & 2) dup2(frompp[1], 2); execvp(progargv[0], progargv + 1); exit(errno); } close(frompp[1]); close(topp[0]); if(pidp) *pidp = pid; if(pipes){ pipes[0] = frompp[0]; pipes[1] = topp[1]; } return(0);}intopen_to_pipe_sigblk( UChar *prog, UChar *filename, UChar fds, int *pidp, int mode, sigset_t *sigs){ int r; sigset_t nsigs, osigs; if(prog){ COPYVAL(nsigs, *sigs); /* in case it's modified by sigprocmask */ sigprocmask(SIG_SETMASK, &nsigs, &osigs); } r = open_to_pipe(prog, filename, fds, pidp, mode); if(prog) sigprocmask(SIG_SETMASK, &osigs, NULL); return(r);}intopen_from_pipe_sigblk( UChar *prog, UChar *filename, UChar fds, int *pidp, sigset_t *sigs){ int r; sigset_t nsigs, osigs; if(prog){ COPYVAL(nsigs, *sigs); /* in case it's modified by sigprocmask */ sigprocmask(SIG_SETMASK, &nsigs, &osigs); } r = open_from_pipe(prog, filename, fds, pidp); if(prog) sigprocmask(SIG_SETMASK, &osigs, NULL); return(r);}Int32open_from_to_pipe_sigblk( UChar *prog, int *pipes, UChar fds, int *pidp, sigset_t *sigs){ int r; sigset_t nsigs, osigs; if(prog){ COPYVAL(nsigs, *sigs); /* in case it's modified by sigprocmask */ sigprocmask(SIG_SETMASK, &nsigs, &osigs); } r = open_from_to_pipe(prog, pipes, fds, pidp); if(prog) sigprocmask(SIG_SETMASK, &osigs, NULL); return(r);}intfd_system_fork(char * prnam, int * fds){ int infd[2], outfd[2], errfd[2], i, flags; char *the_shell; if(!fds || !prnam){ errno = EINVAL; return(-1); } if(!(the_shell = getenv("SHELL"))) the_shell = "/bin/sh"; i = pipe(infd); if(i) return(-1); i = pipe(outfd); if(i) return(-1); i = pipe(errfd); if(i) return(-1); i = fork(); if(i < 0) return(-1); if(i == 0){ /* child */ if(fds[0]) dup2(infd[0], 0); else close(infd[0]); if(fds[1]) dup2(outfd[1], 1); else close(outfd[1]); if(fds[2]) dup2(errfd[1], 2); else close(errfd[1]); close(infd[1]); close(outfd[0]); close(errfd[0]); flags = fcntl(1, F_GETFL); fcntl(1, F_SETFL, flags | O_SYNC); flags = fcntl(2, F_GETFL); fcntl(2, F_SETFL, flags | O_SYNC); execl(the_shell, the_shell, "-c", prnam, NULL); fprintf(stderr, T_("Error: could not start subprocess \"%s\".\n"), prnam); exit(1); } if(fds[0]) fds[0] = infd[1]; else close(infd[1]); if(fds[1]) fds[1] = outfd[0]; else close(outfd[0]); if(fds[2]) fds[2] = errfd[0]; else close(errfd[0]); close(infd[0]); close(outfd[1]); close(errfd[1]); return(i);}intfp_system_fork(char * pnam, FILE ** fps){ int fds[3], pid; if(!fps || !pnam){ errno = EINVAL; return(-1); } pid = fd_system_fork(pnam, fds); if(pid < 1) return(pid); fps[0] = fdopen(fds[0], "w"); fps[1] = fdopen(fds[1], "r"); fps[2] = fdopen(fds[2], "r"); if(!fps[0] || !fps[1] || !fps[2]){ if(fps[0]) fclose(fps[0]); if(fps[1]) fclose(fps[1]); if(fps[2]) fclose(fps[2]); return(-1); } return(pid);}intfdpopen(char * cmd, int mode, int * pidp){ int fds[3], pid, rfd; rfd = -1; switch(mode){ case O_WRONLY: fds[0] = 1; fds[1] = 0; fds[2] = 0; pid = fd_system_fork(cmd, fds); if(pid < 0) return(-1); rfd = fds[0]; break; case O_RDONLY: fds[0] = 0; fds[1] = 1; fds[2] = 0; pid = fd_system_fork(cmd, fds); if(pid < 0) return(-1); rfd = fds[1]; break; default: errno = EINVAL; return(-1); } if(pidp) *pidp = pid; return(rfd);}#endif /* defined(unix) || defined(__unix) || defined(_AIX) */Int32bytes_free_real_mem_pag(Int32 chunksize, Int32 maxsize){ Real64 avg_duration, total_duration, timediff; Int32 nmeasured, newsize; Int32 allocated = 0; UChar *mem = NULL, *newmem; time_t start_time, end_time; struct timeval start_tod, end_tod; avg_duration = total_duration = 0.0; nmeasured = 0; if(maxsize / chunksize < 8) maxsize = chunksize * 8; forever{ do{ start_time = time(NULL); gettimeofday(&start_tod, NULL); }while(start_time != time(NULL)); if((newsize = allocated + chunksize) > maxsize) break; newmem = ZRENEWP(mem, UChar, newsize); if(!newmem) break; mem = newmem; memset(mem + allocated, 0x5a, chunksize); do{ end_time = time(NULL); gettimeofday(&end_tod, NULL); }while(end_time != time(NULL)); timediff = (Real64) (end_tod.tv_sec - start_tod.tv_sec) + (Real64) (end_tod.tv_usec - start_tod.tv_usec) / 1000000.0; if(timediff < 0.0) timediff += 86400.0; if(nmeasured == 0){ avg_duration = total_duration = timediff; } else{ if(timediff > avg_duration * 5.0 && nmeasured >= 8) break; total_duration += timediff; avg_duration = total_duration / (Real64) nmeasured; } nmeasured++; allocated = newsize; } ZFREE(mem); return(allocated);}#ifndef _WIN32 /* here we believe in the maximum thinkable BS occuring */Int32get_fs_space(UChar * path, Real64 * bsize){ Real64 freeblocks, availblocks; Int32 blocksize, i; if(!bsize){ errno = EINVAL; return(-1); } i = get_fs_status(path, &blocksize, NULL, &freeblocks, &availblocks); if(i) return(i); *bsize = (Real64) blocksize * (getuid() ? availblocks : freeblocks); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -