From 0780ea991eb8d05f7d06eb2833e49925506ae17c Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 31 May 2008 16:21:42 +0200 Subject: [PATCH 1/1] Introduce the osl() wrapper and rename error_txt() to adu_strerror(). This gets rid of the copy of the error codes from libosl. Also, remove para_fgets() as it is unused. --- adu.c | 72 ++++++++++++++++---------------- error.h | 125 ++++++++++++++++++++++---------------------------------- fd.c | 30 +------------- fd.h | 1 - 4 files changed, 85 insertions(+), 143 deletions(-) diff --git a/adu.c b/adu.c index b0b7cb4..ae8cc43 100644 --- a/adu.c +++ b/adu.c @@ -9,6 +9,7 @@ #include "portable_io.h" DEFINE_ERRLIST; +int osl_errno; /** Command line and config file options. */ static struct gengetopt_args_info conf; @@ -303,8 +304,7 @@ static int add_directory(char *dirname, uint64_t *dir_num, uint64_t *parent_dir_ dir_objects[DT_BYTES].size = sizeof(*dir_size); dir_objects[DT_FILES].data = dir_files; dir_objects[DT_FILES].size = sizeof(*dir_files); - - return osl_add_row(dir_table, dir_objects); + return osl(osl_add_row(dir_table, dir_objects)); } static uint32_t num_uids; @@ -322,12 +322,12 @@ static int open_user_table(struct user_info *ui, int create) INFO_LOG(".............................uid #%u: %u\n", (unsigned)num_uids, (unsigned)ui->uid); if (create) { - ret = osl_create_table(ui->desc); + ret = osl(osl_create_table(ui->desc)); if (ret < 0) goto err; num_uids++; } - ret = osl_open_table(ui->desc, &ui->table); + ret = osl(osl_open_table(ui->desc, &ui->table)); if (ret < 0) goto err; return 1; @@ -365,7 +365,7 @@ static int create_tables(void) int ret; dir_table_desc.dir = para_strdup(conf.database_dir_arg); - ret = osl_create_table(&dir_table_desc); + ret = osl(osl_create_table(&dir_table_desc)); if (ret < 0) return ret; create_hash_table(); @@ -458,9 +458,9 @@ static int update_user_row(struct osl_table *t, uint64_t dir_num, struct osl_row *row; struct osl_object obj = {.data = &dir_num, .size = sizeof(dir_num)}; - int ret = osl_get_row(t, UT_DIR_NUM, &obj, &row); + int ret = osl(osl_get_row(t, UT_DIR_NUM, &obj, &row)); - if (ret < 0 && ret != -E_RB_KEY_NOT_FOUND) + if (ret == -E_OSL && osl_errno != E_OSL_RB_KEY_NOT_FOUND) return ret; if (ret < 0) { /* this is the first file we add */ struct osl_object objects[NUM_UT_COLUMNS]; @@ -473,25 +473,25 @@ static int update_user_row(struct osl_table *t, uint64_t dir_num, objects[UT_FILES].data = &num_files; objects[UT_FILES].size = sizeof(num_files); INFO_LOG("######################### ret: %d\n", ret); - ret = osl_add_row(t, objects); + ret = osl(osl_add_row(t, objects)); INFO_LOG("######################### ret: %d\n", ret); return ret; } else { /* add size and increment file count */ uint64_t num; struct osl_object obj1, obj2 = {.data = &num, .size = sizeof(num)}; - ret = osl_get_object(t, row, UT_BYTES, &obj1); + ret = osl(osl_get_object(t, row, UT_BYTES, &obj1)); if (ret < 0) return ret; num = *(uint64_t *)obj1.data + *add; - ret = osl_update_object(t, row, UT_BYTES, &obj2); + ret = osl(osl_update_object(t, row, UT_BYTES, &obj2)); if (ret < 0) return ret; - ret = osl_get_object(t, row, UT_FILES, &obj1); + ret = osl(osl_get_object(t, row, UT_FILES, &obj1)); if (ret < 0) return ret; num = *(uint64_t *)obj1.data + 1; - return osl_update_object(t, row, UT_FILES, &obj2); + return osl(osl_update_object(t, row, UT_FILES, &obj2)); } } @@ -576,10 +576,10 @@ static int get_dir_name_by_number(uint64_t *dirnum, char **name) int ret; again: - ret = osl_get_row(dir_table, DT_NUM, &obj, &row); + ret = osl(osl_get_row(dir_table, DT_NUM, &obj, &row)); if (ret < 0) goto out; - ret = osl_get_object(dir_table, row, DT_NAME, &obj); + ret = osl(osl_get_object(dir_table, row, DT_NAME, &obj)); if (ret < 0) goto out; if (result) { @@ -588,7 +588,7 @@ again: result = tmp; } else result = para_strdup((char *)obj.data); - ret = osl_get_object(dir_table, row, DT_PARENT_NUM, &obj); + ret = osl(osl_get_object(dir_table, row, DT_PARENT_NUM, &obj)); if (ret < 0) goto out; val = *(uint64_t *)obj.data; @@ -610,11 +610,11 @@ static int get_dir_name_of_row(struct osl_row *dir_table_row, char **name) char *this_dir, *prefix = NULL; *name = NULL; - ret = osl_get_object(dir_table, dir_table_row, DT_NAME, &obj); + ret = osl(osl_get_object(dir_table, dir_table_row, DT_NAME, &obj)); if (ret < 0) return ret; this_dir = para_strdup((char *)obj.data); - ret = osl_get_object(dir_table, dir_table_row, DT_PARENT_NUM, &obj); + ret = osl(osl_get_object(dir_table, dir_table_row, DT_PARENT_NUM, &obj)); if (ret < 0) goto out; if (!*(uint64_t *)obj.data) { @@ -700,7 +700,7 @@ static int global_stats_loop_function(struct osl_row *row, void *data) } if (summary || (gsi->count && (gsi->flags & GSF_PRINT_FILES))) { uint64_t files; - ret = osl_get_object(dir_table, row, DT_FILES, &obj); + ret = osl(osl_get_object(dir_table, row, DT_FILES, &obj)); if (ret < 0) return ret; files = *(uint64_t *)obj.data; @@ -715,7 +715,7 @@ static int global_stats_loop_function(struct osl_row *row, void *data) } if (summary || (gsi->count && (gsi->flags & GSF_PRINT_BYTES))) { uint64_t bytes; - ret = osl_get_object(dir_table, row, DT_BYTES, &obj); + ret = osl(osl_get_object(dir_table, row, DT_BYTES, &obj)); if (ret < 0) return ret; bytes = *(uint64_t *)obj.data; @@ -782,7 +782,7 @@ static int user_stats_loop_function(struct osl_row *row, void *data) return -E_LOOP_COMPLETE; if (usi->count && (usi->flags & USF_PRINT_DIRNAME)) { char *dirname; - ret = osl_get_object(usi->ui->table, row, UT_DIR_NUM, &obj); + ret = osl(osl_get_object(usi->ui->table, row, UT_DIR_NUM, &obj)); if (ret < 0) return ret; ret = get_dir_name_by_number((uint64_t *)obj.data, &dirname); @@ -796,7 +796,7 @@ static int user_stats_loop_function(struct osl_row *row, void *data) } if (summary || (usi->count && (usi->flags & USF_PRINT_FILES))) { uint64_t files; - ret = osl_get_object(usi->ui->table, row, UT_FILES, &obj); + ret = osl(osl_get_object(usi->ui->table, row, UT_FILES, &obj)); if (ret < 0) return ret; files = *(uint64_t *)obj.data; @@ -812,7 +812,7 @@ static int user_stats_loop_function(struct osl_row *row, void *data) } if (summary || (usi->count && (usi->flags & USF_PRINT_BYTES))) { uint64_t bytes; - ret = osl_get_object(usi->ui->table, row, UT_BYTES, &obj); + ret = osl(osl_get_object(usi->ui->table, row, UT_BYTES, &obj)); if (ret < 0) return ret; bytes = *(uint64_t *)obj.data; @@ -847,13 +847,13 @@ static void print_user_stats(void) printf("************************************************ uid %u\n", (unsigned) ui->uid); printf("----------------- Largest dirs -------------------\n"); - osl_rbtree_loop_reverse(ui->table, UT_BYTES, &usi, - user_stats_loop_function); + osl(osl_rbtree_loop_reverse(ui->table, UT_BYTES, &usi, + user_stats_loop_function)); printf("---------- dirs containing most files ------------\n"); usi.count = conf.limit_arg, usi.flags = USF_PRINT_DIRNAME | USF_PRINT_FILES; - osl_rbtree_loop_reverse(ui->table, UT_FILES, &usi, - user_stats_loop_function); + osl(osl_rbtree_loop_reverse(ui->table, UT_FILES, &usi, + user_stats_loop_function)); } } @@ -866,16 +866,16 @@ static int print_statistics(void) }; printf("----------------- Largest dirs -------------------\n"); - ret = osl_rbtree_loop_reverse(dir_table, DT_BYTES, &gsi, - global_stats_loop_function); + ret = osl(osl_rbtree_loop_reverse(dir_table, DT_BYTES, &gsi, + global_stats_loop_function)); if (ret < 0 && ret != -E_LOOP_COMPLETE) return ret; gsi.count = conf.limit_arg; gsi.flags = GSF_PRINT_DIRNAME | GSF_PRINT_FILES; printf("---------- dirs containing most files ------------\n"); - ret = osl_rbtree_loop_reverse(dir_table, DT_FILES, &gsi, - global_stats_loop_function); + ret = osl(osl_rbtree_loop_reverse(dir_table, DT_FILES, &gsi, + global_stats_loop_function)); if (ret < 0 && ret != -E_LOOP_COMPLETE) return ret; @@ -921,7 +921,7 @@ static int open_dir_table(void) { if (!dir_table_desc.dir) /* we did not create the table */ dir_table_desc.dir = para_strdup(conf.database_dir_arg); - return osl_open_table(&dir_table_desc, &dir_table); + return osl(osl_open_table(&dir_table_desc, &dir_table)); } static void close_dir_table(void) @@ -930,9 +930,9 @@ static void close_dir_table(void) if (!dir_table) return; - ret = osl_close_table(dir_table, OSL_MARK_CLEAN); + ret = osl(osl_close_table(dir_table, OSL_MARK_CLEAN)); if (ret < 0) - ERROR_LOG("failed to close dir table: %s\n", error_txt(-ret)); + ERROR_LOG("failed to close dir table: %s\n", adu_strerror(-ret)); free((char *)dir_table_desc.dir); dir_table = NULL; } @@ -943,10 +943,10 @@ static void close_user_table(struct user_info *ui) if (!ui || !ui_used(ui) || !ui_admissible(ui)) return; - ret = osl_close_table(ui->table, OSL_MARK_CLEAN); + ret = osl(osl_close_table(ui->table, OSL_MARK_CLEAN)); if (ret < 0) ERROR_LOG("failed to close user table %u: %s\n", - (unsigned) ui->uid, error_txt(-ret)); + (unsigned) ui->uid, adu_strerror(-ret)); free((char *)ui->desc->name); ui->desc->name = NULL; free((char *)ui->desc->dir); @@ -1083,7 +1083,7 @@ int main(int argc, char **argv) out: free(admissible_uids); if (ret < 0) { - ERROR_LOG("%s\n", error_txt(-ret)); + ERROR_LOG("%s\n", adu_strerror(-ret)); return -EXIT_FAILURE; } return EXIT_SUCCESS; diff --git a/error.h b/error.h index 1067e7f..d97ce50 100644 --- a/error.h +++ b/error.h @@ -1,10 +1,5 @@ -extern char *__errlist[]; -extern char *__error_txt; - -//__printf_2_3 void __log(int ll, const char* fmt,...); - /** - * This bit indicates whether a number is considered a system error number + * This bit indicates whether a number is considered a system error code. * If yes, the system errno is just the result of clearing this bit from * the given number. */ @@ -16,84 +11,19 @@ extern char *__error_txt; /** Set the system error bit for the given number. */ #define ERRNO_TO_ERROR(num) ((num) | (1 << SYSTEM_ERROR_BIT)) -/** Check whether a given number is a system error number. - * - * \param num The value to be checked. - * \param _errno The system error number. - * - * \return True if \a num is the representation of the system - * error identified by \a _errno. - */ -static inline int is_errno(int num, int _errno) -{ - assert(num > 0 && _errno > 0); - return ERRNO_TO_ERROR(_errno) == num; -} - -/** - * version of strerror(3). - * - * \param num The error number. - * - * \return The error text of \a num. - */ -static inline char *error_txt(int num) -{ - assert(num > 0); - if (IS_SYSTEM_ERROR(num)) - return strerror((num) & ((1 << SYSTEM_ERROR_BIT) - 1)); - else - return __errlist[num]; -} - #define ALL_ERRORS \ _ERROR(SUCCESS, "success") \ - _ERROR(BAD_DB_DIR, "invalid database directory") \ - _ERROR(NO_COLUMN_DESC, "missing column description") \ - _ERROR(BAD_NAME, "invalid name for a column/table") \ - _ERROR(BAD_STORAGE_TYPE, "invalid storage type") \ - _ERROR(BAD_STORAGE_FLAGS, "invalid storage flags") \ - _ERROR(NO_COLUMN_NAME, "missing column name") \ - _ERROR(NO_COLUMNS, "at least one column required") \ - _ERROR(BAD_COLUMN_NAME, "invalid name for a table column") \ - _ERROR(NO_UNIQUE_RBTREE_COLUMN, "need at least one mapped column with OSL_UNIQE and OSL_RBTREE OSL") \ - _ERROR(NO_RBTREE_COL, "at least one column needs an rbtree") \ - _ERROR(DUPLICATE_COL_NAME, "column name given twice") \ - _ERROR(BAD_STORAGE_SIZE, "invalid storage size") \ - _ERROR(NO_COMPARE_FUNC, "missing compare function") \ - _ERROR(BAD_DATA_SIZE, "wrong data size for fixed-size column") \ - _ERROR(NOT_MAPPED, "file not mapped") \ - _ERROR(ALREADY_MAPPED, "file already mapped") \ - _ERROR(BAD_SIZE, "invalid size specified") \ - _ERROR(TRUNC, "failed to truncate file") \ - _ERROR(BAD_TABLE, "table not open") \ - _ERROR(BAD_TABLE_DESC, "invalid table description") \ - _ERROR(RB_KEY_EXISTS, "key already exists in rbtree") \ - _ERROR(RB_KEY_NOT_FOUND, "key not found in rbtree") \ - _ERROR(BAD_ROW_NUM, "invalid row number") \ - _ERROR(INDEX_CORRUPTION, "index corruption detected") \ - _ERROR(INVALID_OBJECT, "reference to invalid object") \ - _ERROR(STAT, "can not stat file") \ - _ERROR(WRITE, "write error") \ - _ERROR(LSEEK, "lseek error") \ - _ERROR(BUSY, "table is busy") \ - _ERROR(SHORT_TABLE, "table too short") \ - _ERROR(NO_MAGIC, "missing table header magic") \ - _ERROR(VERSION_MISMATCH, "table version not supported") \ - _ERROR(BAD_COLUMN_NUM, "invalid column number") \ - _ERROR(BAD_TABLE_FLAGS, "invalid flags in table description") \ - _ERROR(BAD_ROW, "invalid row") \ + _ERROR(SYNTAX, "syntax error") \ + _ERROR(LOOP_COMPLETE, "loop complete") \ + _ERROR(HASH_TABLE_OVERFLOW, "hash table too small") \ + _ERROR(BAD_UID, "uid not found in hash table") \ _ERROR(ATOI_OVERFLOW, "value too large") \ _ERROR(STRTOLL, "unknown strtoll error") \ _ERROR(ATOI_NO_DIGITS, "no digits found in string") \ _ERROR(ATOI_JUNK_AT_END, "further characters after number") \ - _ERROR(FGETS, "fgets error") \ _ERROR(EMPTY, "file empty") \ _ERROR(MMAP, "mmap error") \ - _ERROR(SYNTAX, "syntax error") \ - _ERROR(LOOP_COMPLETE, "loop complete") \ - _ERROR(HASH_TABLE_OVERFLOW, "hash table too small") \ - _ERROR(BAD_UID, "uid not found in hash table") + _ERROR(OSL, "osl error") \ /** @@ -107,4 +37,45 @@ enum error_codes { }; #undef _ERROR #define _ERROR(err, msg) msg, -#define DEFINE_ERRLIST char *__errlist[] = {ALL_ERRORS} +#define DEFINE_ERRLIST char *adu_errlist[] = {ALL_ERRORS} + +extern int osl_errno; +extern char *adu_errlist[]; + + +/** + * adu's version of strerror(3). + * + * \param num The error number. + * + * \return The error text of \a num. + */ +static inline const char *adu_strerror(int num) +{ + assert(num > 0); + if (num == E_OSL) { + fprintf(stderr, "osl error %d\n", osl_errno & 0xff); + assert(osl_errno > 0); + return osl_strerror((osl_errno)); + } + if (IS_SYSTEM_ERROR(num)) + return strerror((num) & ((1 << SYSTEM_ERROR_BIT) - 1)); + return adu_errlist[num]; +} + +/** + * Wrapper for osl library calls. + * + * This should be used for all calls to osl functions that return an osl error + * code. It changes the return value to \p -E_OSL appropriately so that it can + * be used for printing the correct error message. + * + * \return \a ret if \a ret >= 0, \p -E_OSL otherwise. + */ +static inline int osl(int ret) +{ + if (ret >= 0) + return ret; + osl_errno = -ret; + return -E_OSL; +} diff --git a/fd.c b/fd.c index 7040b87..52569a1 100644 --- a/fd.c +++ b/fd.c @@ -38,7 +38,7 @@ ssize_t para_write(int fd, const void *buf, size_t size) ret = write(fd, buf, size); if ((ret < 0) && (errno == EAGAIN || errno == EINTR)) continue; - return ret >= 0? ret : -E_WRITE; + return ret >= 0? ret : -ERRNO_TO_ERROR(errno); } } @@ -239,34 +239,6 @@ void para_fd_set(int fd, fd_set *fds, int *max_fileno) *max_fileno = MAX(*max_fileno, fd); } -/** - * Paraslash's wrapper for fgets(3). - * - * \param line Pointer to the buffer to store the line. - * \param size The size of the buffer given by \a line. - * \param f The stream to read from. - * - * \return Unlike the standard fgets() function, an integer value - * is returned. On success, this function returns 1. On errors, -E_FGETS - * is returned. A zero return value indicates an end of file condition. - */ -__must_check int para_fgets(char *line, int size, FILE *f) -{ -again: - if (fgets(line, size, f)) - return 1; - if (feof(f)) - return 0; - if (!ferror(f)) - return -E_FGETS; - if (errno != EINTR) { - ERROR_LOG("%s\n", strerror(errno)); - return -E_FGETS; - } - clearerr(f); - goto again; -} - /** * Paraslash's wrapper for mmap. * diff --git a/fd.h b/fd.h index da0d349..33ae29d 100644 --- a/fd.h +++ b/fd.h @@ -13,7 +13,6 @@ int para_select(int n, fd_set *readfds, fd_set *writefds, __must_check int mark_fd_nonblocking(int fd); __must_check int mark_fd_blocking(int fd); void para_fd_set(int fd, fd_set *fds, int *max_fileno); -__must_check int para_fgets(char *line, int size, FILE *f); void *para_mmap(size_t length, int prot, int flags, int fd, off_t offset); int para_open(const char *path, int flags, mode_t mode); int para_opendir(const char *dirname, DIR **dir, int *cwd); -- 2.39.2