X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=osl.c;h=36da808af853aa58495382c2c6fd1afe3893b5e8;hb=cd38753609763dbc55e72a7df446837792628d6d;hp=ab3b8de4683df09c306bcd968ae868f2d978cc8d;hpb=2c679eeb8bbc93220f85403eca6e9380dc624a6a;p=paraslash.git diff --git a/osl.c b/osl.c index ab3b8de4..36da808a 100644 --- a/osl.c +++ b/osl.c @@ -17,7 +17,7 @@ /** * A wrapper for lseek(2). * - * \param fd The filedescriptor whose offset is to be to repositioned. + * \param fd The file descriptor whose offset is to be to repositioned. * \param offset A value-result parameter. * \param whence Usual repositioning directive. * @@ -46,8 +46,8 @@ int para_lseek(int fd, off_t *offset, int whence) * \param buf The buffer to write. * \param size The length of \a buf in bytes. * - * This function writes out the given bufffer and retries if an interrupt - * occured during the write. + * This function writes out the given buffer and retries if an interrupt + * occurred during the write. * * \return On success, the number of bytes written is returned, otherwise, the * function returns \p -E_WRITE. @@ -211,9 +211,10 @@ out: * \param func The function to call for each entry. * \param private_data Pointer to an arbitrary data structure. * - * For each regular file in \a dirname, the supplied function \a func is + * For each regular file under \a dirname, the supplied function \a func is * called. The full path of the regular file and the \a private_data pointer - * are passed to \a func. + * are passed to \a func. Directories for which the calling process has no + * permissions to change to are silently ignored. * * \return On success, 1 is returned. Otherwise, this function returns a * negative value which indicates the kind of the error. @@ -226,7 +227,7 @@ int for_each_file_in_dir(const char *dirname, int cwd_fd, ret2, ret = para_opendir(dirname, &dir, &cwd_fd); if (ret < 0) - return ret; + return ret == -E_CHDIR_PERM? 1 : ret; /* scan cwd recursively */ while ((entry = readdir(dir))) { mode_t m; @@ -365,7 +366,7 @@ static int init_column_descriptions(struct osl_table *t) if (ret < 0) goto err; ret = -E_BAD_DB_DIR; - if (!t->desc->dir) + if (!t->desc->dir && (t->num_disk_storage_columns || t->num_mapped_columns)) goto err; /* the size of the index header without column descriptions */ t->index_header_size = IDX_COLUMN_DESCRIPTIONS; @@ -658,10 +659,7 @@ static int create_table_index(struct osl_table *t) * * \param desc Pointer to the table description. * - * \return Positive on success, negative on errors. Possible errors include: \p - * E_BAD_TABLE_DESC, \p E_BAD_DB_DIR, \p E_BAD_NAME, \p E_NO_COMPARE_FUNC, \p - * E_NO_COLUMN_NAME, \p E_DUPLICATE_COL_NAME, \p E_MKDIR, any errors returned - * by para_open(). + * \return Standard. */ int osl_create_table(const struct osl_table_description *desc) { @@ -678,7 +676,7 @@ int osl_create_table(const struct osl_table_description *desc) continue; if (!table_dir) { ret = para_mkdir(desc->dir, 0777); - if (ret < 0 && ret != -E_EXIST) + if (ret < 0 && !is_errno(-ret, EEXIST)) goto out; table_dir = make_message("%s/%s", desc->dir, desc->name); @@ -1085,7 +1083,7 @@ void clear_rbtrees(struct osl_table *t) * \param flags Options for what should be cleaned up. * * If osl_open_table() succeeds, the resulting table pointer must later be - * passed to this function in order to flush all changes to the filesystem and + * passed to this function in order to flush all changes to the file system and * to free the resources that were allocated by osl_open_table(). * * \return Positive on success, negative on errors. Possible errors: \p E_BAD_TABLE, @@ -1202,10 +1200,7 @@ int init_rbtrees(struct osl_table *t) * The table description given by \a desc should coincide with the * description used at creation time. * - * \return Positive on success, negative on errors. Possible errors include: - * errors returned by init_table_structure(), \p E_NOENT, \p E_STAT, \p \p - * E_NOTDIR, \p E_BAD_TABLE_DESC, \p E_BAD_DB_DIR, \p E_NO_COMPARE_FUNC, \p - * E_NO_COLUMN_NAME, errors returned by init_rbtrees(). + * \return Standard. */ int osl_open_table(const struct osl_table_description *table_desc, struct osl_table **result) @@ -1225,13 +1220,10 @@ int osl_open_table(const struct osl_table_description *table_desc, ret = stat(dirname, &statbuf); free(dirname); if (ret < 0) { - if (errno == ENOENT) - ret = -E_NOENT; - else - ret = -E_STAT; + ret = -ERRNO_TO_PARA_ERROR(errno); goto err; } - ret = -E_NOTDIR; + ret = -ERRNO_TO_PARA_ERROR(ENOTDIR); if (!S_ISDIR(statbuf.st_mode)) goto err; } @@ -1264,7 +1256,7 @@ static int create_disk_storage_object_dir(const struct osl_table *t, dirname = disk_storage_dirname(t, col_num, ds_name); ret = para_mkdir(dirname, 0777); free(dirname); - if (ret < 0 && ret != -E_EXIST) + if (ret < 0 && !is_errno(-ret, EEXIST)) return ret; return 1; } @@ -1357,15 +1349,11 @@ static int delete_disk_storage_file(const struct osl_table *t, unsigned col_num, const char *ds_name) { char *dirname, *filename = disk_storage_path(t, col_num, ds_name); - int ret = unlink(filename); + int ret = unlink(filename), err = errno; - PARA_DEBUG_LOG("deleted %s\n", filename); free(filename); - if (ret < 0) { - if (errno == ENOENT) - return -E_NOENT; - return -E_UNLINK; - } + if (ret < 0) + return -ERRNO_TO_PARA_ERROR(err); if (!(t->desc->flags & OSL_LARGE_TABLE)) return 1; dirname = disk_storage_dirname(t, col_num, ds_name); @@ -1667,7 +1655,7 @@ static int check_rbtree_col(const struct osl_table *t, unsigned col_num, * Lookup \a obj in \a t and return the row containing \a obj. The column * specified by \a col_num must have an associated rbtree. * - * \return Positive on success, negative on errors. If an error occured, \a + * \return Positive on success, negative on errors. If an error occurred, \a * result is set to \p NULL. Possible errors include: \p E_BAD_TABLE, \p * E_BAD_STORAGE_FLAGS, errors returned by get_mapped_object(), \p * E_RB_KEY_NOT_FOUND. @@ -1697,9 +1685,12 @@ int osl_get_row(const struct osl_table *t, unsigned col_num, static int rbtree_loop(struct osl_column *col, void *private_data, osl_rbtree_loop_func *func) { - struct rb_node *n; + struct rb_node *n, *tmp; - for (n = rb_first(&col->rbtree); n; n = rb_next(n)) { + /* this for-loop is safe against removal of an entry */ + for (n = rb_first(&col->rbtree), tmp = n? rb_next(n) : NULL; + n; + n = tmp, tmp = tmp? rb_next(tmp) : NULL) { struct osl_row *r = get_row_pointer(n, col->rbtree_num); int ret = func(r, private_data); if (ret < 0) @@ -1711,9 +1702,12 @@ static int rbtree_loop(struct osl_column *col, void *private_data, static int rbtree_loop_reverse(struct osl_column *col, void *private_data, osl_rbtree_loop_func *func) { - struct rb_node *n; + struct rb_node *n, *tmp; - for (n = rb_last(&col->rbtree); n; n = rb_prev(n)) { + /* safe against removal of an entry */ + for (n = rb_last(&col->rbtree), tmp = n? rb_prev(n) : NULL; + n; + n = tmp, tmp = tmp? rb_prev(tmp) : NULL) { struct osl_row *r = get_row_pointer(n, col->rbtree_num); int ret = func(r, private_data); if (ret < 0) @@ -1733,9 +1727,9 @@ static int rbtree_loop_reverse(struct osl_column *col, void *private_data, * This function does an in-order walk of the rbtree associated with \a * col_num. It is an error if the \p OSL_RBTREE flag is not set for this * column. For each node in the rbtree, the given function \a func is called - * with two \p void* pointers as arguments: The first argument points to the + * with two pointers as arguments: The first osl_row* argument points to the * row that contains the object corresponding to the rbtree node currently - * traversed, and the \a private_data pointer is passed to \a func as the + * traversed, and the \a private_data pointer is passed verbatim to \a func as the * second argument. The loop terminates either if \a func returns a negative * value, or if all nodes of the tree have been visited. * @@ -1829,16 +1823,14 @@ out: * * This function gets rid of all references to the old object. This includes * removal of the rbtree node in case there is an rbtree associated with \a - * col_num. It then inserts \a obj into the table and the rbtree if neccessary. + * col_num. It then inserts \a obj into the table and the rbtree if necessary. * * If the \p OSL_RBTREE flag is set for \a col_num, you \b MUST call this * function in order to change the contents of an object, even for volatile or * mapped columns of constant size (which may be updated directly if \p * OSL_RBTREE is not set). Otherwise the rbtree might become corrupted. * - * \return Positive on success, negative on errors. Possible errors include: \p - * E_BAD_TABLE, \p E_RB_KEY_EXISTS, \p E_BAD_SIZE, \p E_NOENT, \p E_UNLINK, - * errors returned by para_write_file(), \p E_MKDIR. + * \return Standard */ int osl_update_object(struct osl_table *t, const struct osl_row *r, unsigned col_num, struct osl_object *obj) @@ -1870,7 +1862,7 @@ int osl_update_object(struct osl_table *t, const struct osl_row *r, if (ret < 0) return ret; ret = delete_disk_storage_file(t, col_num, ds_name); - if (ret < 0 && ret != -E_NOENT) { + if (ret < 0 && !is_errno(-ret, ENOENT)) { free(ds_name); return ret; } @@ -2007,7 +1999,7 @@ int osl_get_num_rows(const struct osl_table *t, unsigned *num_rows) * \param rank Result pointer. * * The rank is, by definition, the position of the row in the linear order - * determined by an inorder tree walk of the rbtree associated with column + * determined by an in-order tree walk of the rbtree associated with column * number \a col_num of \a table. * * \return Positive on success, negative on errors.