Datum pg_file_unlink(PG_FUNCTION_ARGS) { char *filename; requireSuperuser(); filename = convert_and_check_filename(PG_GETARG_TEXT_PP(0), false); if (access(filename, W_OK) < 0) { if (errno == ENOENT) PG_RETURN_BOOL(false); else ereport(ERROR, (errcode_for_file_access(), errmsg("file \"%s\" is not accessible: %m", filename))); } if (unlink(filename) < 0) { ereport(WARNING, (errcode_for_file_access(), errmsg("could not unlink file \"%s\": %m", filename))); PG_RETURN_BOOL(false); } PG_RETURN_BOOL(true); }
Datum pg_file_write(PG_FUNCTION_ARGS) { FILE *f; char *filename; text *data; int64 count = 0; requireSuperuser(); filename = convert_and_check_filename(PG_GETARG_TEXT_P(0)); data = PG_GETARG_TEXT_P(1); if (!PG_GETARG_BOOL(2)) { struct stat fst; if (stat(filename, &fst) >= 0) ereport(ERROR, (ERRCODE_DUPLICATE_FILE, errmsg("file \"%s\" exists", filename))); f = fopen(filename, "wb"); } else f = fopen(filename, "ab"); if (!f) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\" for writing: %m", filename))); if (VARSIZE(data) != 0) { count = fwrite(VARDATA(data), 1, VARSIZE(data) - VARHDRSZ, f); if (count != VARSIZE(data) - VARHDRSZ) ereport(ERROR, (errcode_for_file_access(), errmsg("could not write file \"%s\": %m", filename))); } fclose(f); PG_RETURN_INT64(count); }
Datum pg_file_length(PG_FUNCTION_ARGS) { text *filename_t = PG_GETARG_TEXT_P(0); char *filename; struct stat fst; requireSuperuser(); filename = convert_and_check_filename(filename_t); if (stat(filename, &fst) < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", filename))); PG_RETURN_INT64((int64) fst.st_size); }
Datum pg_file_rename(PG_FUNCTION_ARGS) { char *fn1, *fn2, *fn3; int rc; requireSuperuser(); if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) PG_RETURN_NULL(); fn1 = convert_and_check_filename(PG_GETARG_TEXT_PP(0), false); fn2 = convert_and_check_filename(PG_GETARG_TEXT_PP(1), false); if (PG_ARGISNULL(2)) fn3 = 0; else fn3 = convert_and_check_filename(PG_GETARG_TEXT_PP(2), false); if (access(fn1, W_OK) < 0) { ereport(WARNING, (errcode_for_file_access(), errmsg("file \"%s\" is not accessible: %m", fn1))); PG_RETURN_BOOL(false); } if (fn3 && access(fn2, W_OK) < 0) { ereport(WARNING, (errcode_for_file_access(), errmsg("file \"%s\" is not accessible: %m", fn2))); PG_RETURN_BOOL(false); } rc = access(fn3 ? fn3 : fn2, 2); if (rc >= 0 || errno != ENOENT) { ereport(ERROR, (ERRCODE_DUPLICATE_FILE, errmsg("cannot rename to target file \"%s\"", fn3 ? fn3 : fn2))); } if (fn3) { if (rename(fn2, fn3) != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not rename \"%s\" to \"%s\": %m", fn2, fn3))); } if (rename(fn1, fn2) != 0) { ereport(WARNING, (errcode_for_file_access(), errmsg("could not rename \"%s\" to \"%s\": %m", fn1, fn2))); if (rename(fn3, fn2) != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not rename \"%s\" back to \"%s\": %m", fn3, fn2))); } else { ereport(ERROR, (ERRCODE_UNDEFINED_FILE, errmsg("renaming \"%s\" to \"%s\" was reverted", fn2, fn3))); } } } else if (rename(fn1, fn2) != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not rename \"%s\" to \"%s\": %m", fn1, fn2))); } PG_RETURN_BOOL(true); }