/* * Returns the current user name. */ static char * get_username(void) { char *ret; #ifndef WIN32 struct passwd *pw; pw = getpwuid(geteuid()); ret = (pw ? pw->pw_name : NULL); #else static char username[128]; /* remains after function execute */ DWORD len = sizeof(username) - 1; if (GetUserNameA(username, &len)) ret = username; else { _dosmaperr(GetLastError()); ret = NULL; } #endif if (ret == NULL) ereport(ERROR, (errcode_errno(), errmsg("could not get current user name: "))); return ret; }
void * pgut_realloc(void *p, size_t size) { char *ret; if ((ret = realloc(p, size)) == NULL) ereport(FATAL, (errcode_errno(), errmsg("could not re-allocate memory (%lu bytes): ", (unsigned long) size))); return ret; }
char * pgut_strdup(const char *str) { char *ret; if (str == NULL) return NULL; if ((ret = strdup(str)) == NULL) ereport(FATAL, (errcode_errno(), errmsg("could not duplicate string \"%s\": ", str))); return ret; }
/* * Try open file. Also create parent directries if open for writes. * * mode can contain 'R', that is same as 'r' but missing ok. */ FILE * pgut_fopen(const char *path, const char *omode) { FILE *fp; bool missing_ok = false; char mode[16]; strlcpy(mode, omode, lengthof(mode)); if (mode[0] == 'R') { mode[0] = 'r'; missing_ok = true; } retry: if ((fp = fopen(path, mode)) == NULL) { if (errno == ENOENT) { if (missing_ok) return NULL; if (mode[0] == 'w' || mode[0] == 'a') { char dir[MAXPGPATH]; strlcpy(dir, path, MAXPGPATH); get_parent_directory(dir); pgut_mkdir(dir); goto retry; } } ereport(ERROR, (errcode_errno(), errmsg("could not open file \"%s\": ", path))); } return fp; }
int wait_for_sockets(int nfds, fd_set *fds, struct timeval *timeout) { int i; for (;;) { i = select(nfds, fds, NULL, NULL, timeout); if (i < 0) { CHECK_FOR_INTERRUPTS(); if (errno != EINTR) { ereport(ERROR, (errcode_errno(), errmsg("select failed: "))); return -1; } } else return i; } }
/* * this tries to build all the elements of a path to a directory a la mkdir -p * we assume the path is in canonical form, i.e. uses / as the separator. */ bool pgut_mkdir(const char *dirpath) { struct stat sb; int first, last, retval; char *path; char *p; Assert(dirpath != NULL); p = path = pgut_strdup(dirpath); retval = 0; #ifdef WIN32 /* skip network and drive specifiers for win32 */ if (strlen(p) >= 2) { if (p[0] == '/' && p[1] == '/') { /* network drive */ p = strstr(p + 2, "/"); if (p == NULL) { free(path); ereport(ERROR, (errcode(EINVAL), errmsg("invalid path \"%s\"", dirpath))); return false; } } else if (p[1] == ':' && ((p[0] >= 'a' && p[0] <= 'z') || (p[0] >= 'A' && p[0] <= 'Z'))) { /* local drive */ p += 2; } } #endif if (p[0] == '/') /* Skip leading '/'. */ ++p; for (first = 1, last = 0; !last; ++p) { if (p[0] == '\0') last = 1; else if (p[0] != '/') continue; *p = '\0'; if (!last && p[1] == '\0') last = 1; if (first) first = 0; retry: /* check for pre-existing directory; ok if it's a parent */ if (stat(path, &sb) == 0) { if (!S_ISDIR(sb.st_mode)) { if (last) errno = EEXIST; else errno = ENOTDIR; retval = 1; break; } } else if (mkdir(path, S_IRWXU) < 0) { if (errno == EEXIST) goto retry; /* another thread might create the directory. */ retval = 1; break; } if (!last) *p = '/'; } free(path); if (retval == 0) { ereport(ERROR, (errcode_errno(), errmsg("could not create directory \"%s\": ", dirpath))); return false; } return true; }