psplinux.c
来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 1,098 行 · 第 1/2 页
C
1,098 行
if (WIFEXITED(stat)) { fprintf(stderr, "Lock manager startup aborted with a status of %d.", WEXITSTATUS(stat)); exit(WEXITSTATUS(stat)); } if (WIFSIGNALED(stat)) { fprintf(stderr, "Lock manager terminated by internal error or" "external signal (%d).\n", WTERMSIG(stat)); exit(-WTERMSIG(stat)); } fprintf(stderr, "Unexpected status signal from child process.\n"); exit(99);}/* =========================================================================== Fork the process to begin daemon mode*/void psp_daemonInit( DB_TCHAR *name){ pipe(pfd); if (fork()) { /* parent waits for child to start up and then exits */ signal(SIGCHLD, sigchld_handler); close(pfd[1]); read(pfd[0], &pfd[1], 1); /* pipe has now closed. */ printf("Lock manager '%s' started successfully.\n", name); close(pfd[0]); exit(0); } /* child continues here */ freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); setsid(); write(pfd[1], &pfd[0], sizeof(int)); close(pfd[0]); close(pfd[1]);}/* =========================================================================== Terminate running as a daemone. Nothing to do on Unix*/void psp_daemonTerm( void){}/* =========================================================================== Return a pointer to the first character of the file name portion of the supplied path*/char *psp_pathGetFile( const char *path){ char *cp; if ((cp = strrchr(path, DIRCHAR)) == NULL) return (char *) path; return cp + 1;}/* =========================================================================== Determine if the path is only a subdirectory (does not contain a file name)*/int psp_pathIsDir( const char *path){ size_t len; if (!path || !*path) return -1; len = strlen(path) - 1; if (path[len] == DIRCHAR) return 1; return 0;}/* =========================================================================== Split a path up into the subdirectory and file name components*/void psp_pathSplit( const char *path, char **dir, char **file){ char *cp; cp = strrchr(path, DIRCHAR); if (file) { if (cp && *(cp + 1)) *file = psp_strdup(cp + 1, 0); else *file = psp_strdup(path, 0); } if (dir) { if (cp) { *(cp + 1) = '\0'; *dir = psp_strdup(path, 0); } else *dir = NULL; }}/* =========================================================================== Return the path without any drive specifier*/char *psp_pathStripDrive( const char *path){ return (char *) path;}static char *dbtmp = "/tmp/";/* =========================================================================== Return the default temporary path*/char *psp_pathDefTmp( void){ return dbtmp;}typedef struct { DIR *entry; char *pattern;} DIR_ENTRY;/* =========================================================================== Open a directory for searching*/PSP_DIR psp_pathOpen( const char *path, const char *pattern){ DIR_ENTRY *dir; if ((dir = psp_getMemory(sizeof(DIR_ENTRY), 0)) == NULL) return NULL; if ((dir->entry = opendir(path)) == NULL) { psp_freeMemory(dir, 0); return NULL; } if ((dir->pattern = psp_strdup(pattern, 0)) == NULL) { psp_freeMemory(dir->entry, 0); psp_freeMemory(dir, 0); } return dir;}static int match( const char *str, const char *pattern){ char p; char s; while ((p = *pattern++) != '\0') { if (p == '*') { if ((p = *pattern++) == '\0') return 1; while (*str) { s = *str++; if (toupper(s) == toupper(p) && match(str, pattern)) return 1; } return 0; } if ((s = *str++) == '\0') return 0; if (p != '?' && toupper(p) != toupper(s)) return 0; } if (*str == '\0') return 1; return 0;}/* =========================================================================== Find next occurrence of requested name in path*/char *psp_pathNext( PSP_DIR dir){ size_t len; struct dirent *ent; DIR_ENTRY *d; if (!dir) return NULL; d = (DIR_ENTRY *) dir; for ( ; ; ) { if ((ent = readdir(d->entry)) == NULL) return NULL; if (match(ent->d_name, d->pattern)) break; } return psp_strdup(ent->d_name, 0);}/* =========================================================================== Close directory searching*/void psp_pathClose( PSP_DIR dir){ DIR_ENTRY *d; if (dir) { d = (DIR_ENTRY *) dir; closedir(d->entry); psp_freeMemory(d->pattern, 0); psp_freeMemory(d, 0); }}/* =========================================================================== Return a random (hopefully) seed*/long psp_seed( void){ return clock();}/* =========================================================================== Return the current time in seconds*/long psp_timeSecs( void){ return time(NULL);}/* =========================================================================== Return the current time in milliseconds*/long psp_timeMilliSecs( void){ struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000 + tv.tv_usec / 1000;}/* =========================================================================== Return the error number from the last call*/int psp_errno( void){ return errno;}/* =========================================================================== Return the contents of an environment variable*/char *psp_getenv( const char *var){ return getenv(var);}/* =========================================================================== Generate a unique name for a device*/static char *get_device( dev_t device, const char *src){ char *seppos; char *name; char *host; struct mntent *fstab; struct stat stbuf; FILE *mnt; if ((mnt = setmntent(MNTTAB, "r")) == NULL) return NULL; /* search in /etc/[fstab|checklist] */ while ((fstab = getmntent(mnt)) != NULL) { if (stat(fstab->mnt_dir, &stbuf) != -1 && stbuf.st_dev == device) break; } endmntent(mnt); if (fstab == NULL) return NULL; name = psp_getMemory(FILEIDLEN, 0); host = psp_getMemory(FILEIDLEN, 0); if (strncmp(fstab->mnt_fsname, "/dev", 4) == 0) { /* device is local */ if (gethostname(host, FILEIDLEN) < 0) { psp_freeMemory(host, 0); psp_freeMemory(name, 0); return NULL; } if (fstab->mnt_dir[0] == DIRCHAR && fstab->mnt_dir[1] == '\0') { /* we need /path_prefix, as that is what will be supplied in mnttab on a remote machine mounting this filesystem. */ char prefix[FILENMLEN]; char *cp; if (src[0] == DIRCHAR) strcpy(prefix, src); else { getcwd(prefix, FILENMLEN - 2); strcat(prefix, "/"); if (src[0] == '.') { if (src[1] == '.') { if ((cp = strrchr(prefix, DIRCHAR)) != NULL) *cp = '\0'; } strcat(prefix, &src[2]); } else strcat(prefix, src); } if ((cp = strchr(&prefix[1], DIRCHAR)) != NULL) *cp = '\0'; strncpy(name, prefix, FILEIDLEN); } else strncpy(name, fstab->mnt_dir, FILEIDLEN); } else if ((seppos = strchr(fstab->mnt_fsname, ':')) != NULL) { /* host:fsname */ *seppos = '\0'; strncpy(host, fstab->mnt_fsname, FILEIDLEN); strncpy(name, seppos + 1, FILEIDLEN); } else if ((seppos = strchr(fstab->mnt_fsname, '@')) != NULL) { /* fsname@host */ *seppos = '\0'; strncpy(host, seppos + 1, FILEIDLEN); strncpy(name, fstab->mnt_fsname, FILEIDLEN); } else { /* can't understand fsname in fstab */ psp_freeMemory(name, 0); psp_freeMemory(host, 0); return NULL; } name[FILEIDLEN - 1] = '\0'; /* convert device name to fsname@host */ strcat(name, "@"); host[FILEIDLEN - strlen(name) - 1] = '\0'; strcat(name, host); psp_freeMemory(host, 0); return name;}/* =========================================================================== Find the device in list of devices already discovered or search the mount table*/static char *find_device( dev_t device, const char *src){ char *name; DEVICE_LIST *p; if (!psp_inited) return NULL; psp_syncEnterExcl(deviceSem); /* search linked list of known devices */ for (p = deviceHead; p; p = p->next) { if (device == p->device) break; } if (p) return p->name; /* generate name for this device */ if ((name = get_device(device, src)) == NULL) return NULL; /* add this device to the linked list */ p = psp_getMemory(sizeof(DEVICE_LIST), 0); p->device = device; p->name = name; p->next = deviceHead; deviceHead = p; psp_syncExitExcl(deviceSem); return p->name;}/* =========================================================================== Return a string that completely and uniquely defines a file (the "truename" of the file) so that the lock manager can correctly handle lock contention. On UNIX this means the device name on a host with the inode for that file in the following format: <devicepath>@<hostname>:<inode>*/char *psp_truename( const char *src, PSP_MEMTAG tag){ char truename[FILEIDLEN]; struct stat stbuf; char *name; dev_t device; if (stat(src, &stbuf) == -1) return NULL; if ((name = find_device(stbuf.st_dev, src)) == NULL) return NULL; sprintf(truename, "%s:%ld", name, stbuf.st_ino); return psp_strdup(truename, tag);}/* =========================================================================== Return the default lock manager name*/char *psp_defLockmgr( void){ return "lockmgr";}/* =========================================================================== Return the validity of the give lock manager name*/int psp_validLockmgr( const char *name){ char c; if (!name) return PSP_FAILED; while ((c = *name++) != '\0') { if (!(isalnum(c) || c == '_' || c == ':' || c == '.')) return 0; } return 1;}static INTERRUPT_FCN *interrupt_fcn = NULL;static void handler( int sig){ signal(SIGINT, SIG_IGN); if (interrupt_fcn) (*interrupt_fcn)(); signal(SIGINT, handler);}/* =========================================================================== Setup a function for handling interrupts*/int psp_handleInterrupt( INTERRUPT_FCN *fcn){ if (!fcn) { signal(SIGINT, SIG_IGN); return PSP_OKAY; } interrupt_fcn = fcn; signal(SIGINT, handler); return PSP_OKAY;}/* =========================================================================== Get the current locale setting*/void psp_localeGet( DB_TCHAR *str, size_t len){ /* Not currently supported on UNIX */}/* =========================================================================== Set the current locale setting*/void psp_localeSet( const DB_TCHAR *str){ /* Not currently supported on UNIX */}/* =========================================================================== Prints an error to the screen and waits for input*/void psp_errPrint( const char *msg){ char ch; printf("%s\n", msg); printf("press <return> to continue "); do ch = (char) getchar(); while (ch != '\n' && ch != EOF);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?