00001 /** 00002 * @copyright 00003 * ==================================================================== 00004 * Copyright (c) 2000-2006 CollabNet. All rights reserved. 00005 * 00006 * This software is licensed as described in the file COPYING, which 00007 * you should have received as part of this distribution. The terms 00008 * are also available at http://subversion.tigris.org/license-1.html. 00009 * If newer versions of this license are posted there, you may use a 00010 * newer version instead, at your option. 00011 * 00012 * This software consists of voluntary contributions made by many 00013 * individuals. For exact contribution history, see the revision 00014 * history and logs, available at http://subversion.tigris.org/. 00015 * ==================================================================== 00016 * @endcopyright 00017 * 00018 * @file svn_io.h 00019 * @brief General file I/O for Subversion 00020 */ 00021 00022 /* ==================================================================== */ 00023 00024 00025 #ifndef SVN_IO_H 00026 #define SVN_IO_H 00027 00028 #include <apr.h> 00029 #include <apr_pools.h> 00030 #include <apr_file_io.h> 00031 #include <apr_thread_proc.h> 00032 00033 #include "svn_types.h" 00034 #include "svn_error.h" 00035 #include "svn_string.h" 00036 00037 #ifdef __cplusplus 00038 extern "C" { 00039 #endif /* __cplusplus */ 00040 00041 00042 00043 /** Used as an argument when creating temporary files to indicate 00044 * when a file should be removed. 00045 * 00046 * @since New in 1.4. 00047 * 00048 * Not specifying any of these means no removal at all. */ 00049 typedef enum svn_io_file_del_t 00050 { 00051 /** No deletion ever */ 00052 svn_io_file_del_none = 0, 00053 /** Remove when the file is closed */ 00054 svn_io_file_del_on_close, 00055 /** Remove when the associated pool is cleared */ 00056 svn_io_file_del_on_pool_cleanup 00057 } svn_io_file_del_t; 00058 00059 00060 00061 /** Represents the kind and special status of a directory entry. 00062 * 00063 * @since New in 1.3. 00064 */ 00065 typedef struct svn_io_dirent_t { 00066 /** The kind of this entry. */ 00067 svn_node_kind_t kind; 00068 /** If @c kind is @c svn_node_file, whether this entry is a special file; 00069 * else false. 00070 * 00071 * @see svn_io_check_special_path(). 00072 */ 00073 svn_boolean_t special; 00074 } svn_io_dirent_t; 00075 00076 /** Determine the @a kind of @a path. 00077 * 00078 * If utf8-encoded @a path exists, set @a *kind to the appropriate kind, 00079 * else set it to @c svn_node_unknown. 00080 * 00081 * If @a path is a file, @a *kind is set to @c svn_node_file. 00082 * 00083 * If @a path is a directory, @a *kind is set to @c svn_node_dir. 00084 * 00085 * If @a path does not exist in its final component, @a *kind is set to 00086 * @c svn_node_none. 00087 * 00088 * If intermediate directories on the way to @a path don't exist, an 00089 * error is returned, and @a *kind's value is undefined. 00090 */ 00091 svn_error_t *svn_io_check_path(const char *path, 00092 svn_node_kind_t *kind, 00093 apr_pool_t *pool); 00094 00095 /** 00096 * Like svn_io_check_path(), but also set *is_special to @c TRUE if 00097 * the path is not a normal file. 00098 * 00099 * @since New in 1.1. 00100 */ 00101 svn_error_t *svn_io_check_special_path(const char *path, 00102 svn_node_kind_t *kind, 00103 svn_boolean_t *is_special, 00104 apr_pool_t *pool); 00105 00106 /** Like svn_io_check_path(), but resolve symlinks. This returns the 00107 same varieties of @a kind as svn_io_check_path(). */ 00108 svn_error_t *svn_io_check_resolved_path(const char *path, 00109 svn_node_kind_t *kind, 00110 apr_pool_t *pool); 00111 00112 00113 /** Open a new file (for writing) with a unique name based on utf-8 00114 * encoded @a path, in the same directory as @a path. The file handle is 00115 * returned in @a *f, and the name, which ends with @a suffix, is returned 00116 * in @a *unique_name_p, also utf8-encoded. Either @a f or @a unique_name_p 00117 * may be @c NULL. 00118 * 00119 * If @a delete_when is @c svn_io_file_del_on_close, then the @c APR_DELONCLOSE 00120 * flag will be used when opening the file. The @c APR_BUFFERED flag will 00121 * always be used. 00122 * 00123 * The first attempt will just append @a suffix. If the result is not 00124 * a unique name, then subsequent attempts will append a dot, 00125 * followed by an iteration number ("2", then "3", and so on), 00126 * followed by the suffix. For example, if @a path is 00127 * 00128 * tests/t1/A/D/G/pi 00129 * 00130 * then successive calls to 00131 * 00132 * svn_io_open_unique_file2(&f, &unique_name, @a path, ".tmp", ..., pool) 00133 * 00134 * will open 00135 * 00136 * tests/t1/A/D/G/pi.tmp 00137 * tests/t1/A/D/G/pi.2.tmp 00138 * tests/t1/A/D/G/pi.3.tmp 00139 * tests/t1/A/D/G/pi.4.tmp 00140 * tests/t1/A/D/G/pi.5.tmp 00141 * ... 00142 * 00143 * Assuming @a suffix is non-empty, @a *unique_name_p will never be exactly 00144 * the same as @a path, even if @a path does not exist. 00145 * 00146 * It doesn't matter if @a path is a file or directory, the unique name will 00147 * be in @a path's parent either way. 00148 * 00149 * Allocate @a *f and @a *unique_name_p in @a pool. 00150 * 00151 * If no unique name can be found, @c SVN_ERR_IO_UNIQUE_NAMES_EXHAUSTED is 00152 * the error returned. 00153 * 00154 * Claim of Historical Inevitability: this function was written 00155 * because 00156 * 00157 * - tmpnam() is not thread-safe. 00158 * - tempname() tries standard system tmp areas first. 00159 * 00160 * 00161 * @since New in 1.4 00162 * 00163 */ 00164 svn_error_t *svn_io_open_unique_file2(apr_file_t **f, 00165 const char **unique_name_p, 00166 const char *path, 00167 const char *suffix, 00168 svn_io_file_del_t delete_when, 00169 apr_pool_t *pool); 00170 00171 /** Like svn_io_open_unique_file2, but can't delete on pool cleanup. 00172 * 00173 * @deprecated Provided for backward compatibility with the 1.0 API 00174 * 00175 * @note In 1.4 the API was extended to require either @a f or 00176 * @a unique_name_p (the other can be NULL). Before that, both were 00177 * required. 00178 * 00179 */ 00180 svn_error_t *svn_io_open_unique_file(apr_file_t **f, 00181 const char **unique_name_p, 00182 const char *path, 00183 const char *suffix, 00184 svn_boolean_t delete_on_close, 00185 apr_pool_t *pool); 00186 00187 /** 00188 * Like svn_io_open_unique_file(), except that instead of creating a 00189 * file, a symlink is generated that references the path @a dest. 00190 * 00191 * @since New in 1.1. 00192 */ 00193 svn_error_t *svn_io_create_unique_link(const char **unique_name_p, 00194 const char *path, 00195 const char *dest, 00196 const char *suffix, 00197 apr_pool_t *pool); 00198 00199 00200 /** 00201 * Set @a *dest to the path that the symlink at @a path references. 00202 * Allocate the string from @a pool. 00203 * 00204 * @since New in 1.1. 00205 */ 00206 svn_error_t *svn_io_read_link(svn_string_t **dest, 00207 const char *path, 00208 apr_pool_t *pool); 00209 00210 00211 /** Set @a *dir to a directory path (allocated in @a pool) deemed 00212 * usable for the creation of temporary files and subdirectories. 00213 */ 00214 svn_error_t *svn_io_temp_dir(const char **dir, 00215 apr_pool_t *pool); 00216 00217 00218 /** Copy @a src to @a dst atomically, in a "byte-for-byte" manner. 00219 * Overwrite @a dst if it exists, else create it. Both @a src and @a dst 00220 * are utf8-encoded filenames. If @a copy_perms is true, set @a dst's 00221 * permissions to match those of @a src. 00222 */ 00223 svn_error_t *svn_io_copy_file(const char *src, 00224 const char *dst, 00225 svn_boolean_t copy_perms, 00226 apr_pool_t *pool); 00227 00228 /** 00229 * Copy symbolic link @a src to @a dst atomically. Overwrite @a dst 00230 * if it exists, else create it. Both @a src and @a dst are 00231 * utf8-encoded filenames. After copying, the @a dst link will point 00232 * to the same thing @a src does. 00233 * 00234 * @since New in 1.1. 00235 */ 00236 svn_error_t *svn_io_copy_link(const char *src, 00237 const char *dst, 00238 apr_pool_t *pool); 00239 00240 00241 /** Recursively copy directory @a src into @a dst_parent, as a new entry named 00242 * @a dst_basename. If @a dst_basename already exists in @a dst_parent, 00243 * return error. @a copy_perms will be passed through to svn_io_copy_file() 00244 * when any files are copied. @a src, @a dst_parent, and @a dst_basename are 00245 * all utf8-encoded. 00246 * 00247 * If @a cancel_func is non-null, invoke it with @a cancel_baton at 00248 * various points during the operation. If it returns any error 00249 * (typically @c SVN_ERR_CANCELLED), return that error immediately. 00250 */ 00251 svn_error_t *svn_io_copy_dir_recursively(const char *src, 00252 const char *dst_parent, 00253 const char *dst_basename, 00254 svn_boolean_t copy_perms, 00255 svn_cancel_func_t cancel_func, 00256 void *cancel_baton, 00257 apr_pool_t *pool); 00258 00259 00260 00261 /** Create directory @a path on the file system, creating intermediate 00262 * directories as required, like <tt>mkdir -p</tt>. Report no error if @a 00263 * path already exists. @a path is utf8-encoded. 00264 * 00265 * This is essentially a wrapper for apr_dir_make_recursive(), passing 00266 * @c APR_OS_DEFAULT as the permissions. 00267 */ 00268 svn_error_t *svn_io_make_dir_recursively(const char *path, apr_pool_t *pool); 00269 00270 00271 /** Set @a *is_empty_p to @c TRUE if directory @a path is empty, else to 00272 * @c FALSE if it is not empty. @a path must be a directory, and is 00273 * utf8-encoded. Use @a pool for temporary allocation. 00274 */ 00275 svn_error_t * 00276 svn_io_dir_empty(svn_boolean_t *is_empty_p, 00277 const char *path, 00278 apr_pool_t *pool); 00279 00280 00281 /** Append @a src to @a dst. @a dst will be appended to if it exists, else it 00282 * will be created. Both @a src and @a dst are utf8-encoded. 00283 */ 00284 svn_error_t *svn_io_append_file(const char *src, 00285 const char *dst, 00286 apr_pool_t *pool); 00287 00288 00289 /** Make a file as read-only as the operating system allows. 00290 * @a path is the utf8-encoded path to the file. If @a ignore_enoent is 00291 * @c TRUE, don't fail if the target file doesn't exist. 00292 */ 00293 svn_error_t *svn_io_set_file_read_only(const char *path, 00294 svn_boolean_t ignore_enoent, 00295 apr_pool_t *pool); 00296 00297 00298 /** Make a file as writable as the operating system allows. 00299 * @a path is the utf8-encoded path to the file. If @a ignore_enoent is 00300 * @c TRUE, don't fail if the target file doesn't exist. 00301 * @warning On Unix this function will do the equivalent of chmod a+w path. 00302 * If this is not what you want you should not use this function, but rather 00303 * use apr_file_perms_set(). 00304 */ 00305 svn_error_t *svn_io_set_file_read_write(const char *path, 00306 svn_boolean_t ignore_enoent, 00307 apr_pool_t *pool); 00308 00309 00310 /** Similar to svn_io_set_file_read_* functions. 00311 * Change the read-write permissions of a file. 00312 * @since New in 1.1. 00313 * 00314 * When making @a path read-write on operating systems with unix style 00315 * permissions, set the permissions on @a path to the permissions that 00316 * are set when a new file is created (effectively honoring the user's 00317 * umask). 00318 * 00319 * When making the file read-only on operating systems with unix style 00320 * permissions, remove all write permissions. 00321 * 00322 * On other operating systems, toggle the file's "writability" as much as 00323 * the operating system allows. 00324 * 00325 * @a path is the utf8-encoded path to the file. If @a enable_write 00326 * is @c TRUE, then make the file read-write. If @c FALSE, make it 00327 * read-only. If @a ignore_enoent is @c TRUE, don't fail if the target 00328 * file doesn't exist. 00329 * 00330 * @deprecated Provided for backward compatibility with the 1.3 API. 00331 */ 00332 svn_error_t *svn_io_set_file_read_write_carefully(const char *path, 00333 svn_boolean_t enable_write, 00334 svn_boolean_t ignore_enoent, 00335 apr_pool_t *pool); 00336 00337 /** Toggle a file's "executability". 00338 * 00339 * When making the file executable on operating systems with unix style 00340 * permissions, never add an execute permission where there is not 00341 * already a read permission: that is, only make the file executable 00342 * for the user, group or world if the corresponding read permission 00343 * is already set for user, group or world. 00344 * 00345 * When making the file non-executable on operating systems with unix style 00346 * permissions, remove all execute permissions. 00347 * 00348 * On other operating systems, toggle the file's "executability" as much as 00349 * the operating system allows. 00350 * 00351 * @a path is the utf8-encoded path to the file. If @a executable 00352 * is @c TRUE, then make the file executable. If @c FALSE, make it 00353 * non-executable. If @a ignore_enoent is @c TRUE, don't fail if the target 00354 * file doesn't exist. 00355 */ 00356 svn_error_t *svn_io_set_file_executable(const char *path, 00357 svn_boolean_t executable, 00358 svn_boolean_t ignore_enoent, 00359 apr_pool_t *pool); 00360 00361 /** Determine whether a file is executable by the current user. 00362 * Set @a *executable to @c TRUE if the file @a path is executable by the 00363 * current user, otherwise set it to @c FALSE. 00364 * 00365 * On Windows and on platforms without userids, always returns @c FALSE. 00366 */ 00367 svn_error_t *svn_io_is_file_executable(svn_boolean_t *executable, 00368 const char *path, 00369 apr_pool_t *pool); 00370 00371 00372 /** Read a line from @a file into @a buf, but not exceeding @a *limit bytes. 00373 * Does not include newline, instead '\\0' is put there. 00374 * Length (as in strlen) is returned in @a *limit. 00375 * @a buf should be pre-allocated. 00376 * @a file should be already opened. 00377 * 00378 * When the file is out of lines, @c APR_EOF will be returned. 00379 */ 00380 svn_error_t * 00381 svn_io_read_length_line(apr_file_t *file, char *buf, apr_size_t *limit, 00382 apr_pool_t *pool); 00383 00384 00385 /** Set @a *apr_time to the time of last modification of the contents of the 00386 * file @a path. @a path is utf8-encoded. 00387 * 00388 * @note This is the APR mtime which corresponds to the traditional mtime 00389 * on Unix, and the last write time on Windows. 00390 */ 00391 svn_error_t *svn_io_file_affected_time(apr_time_t *apr_time, 00392 const char *path, 00393 apr_pool_t *pool); 00394 00395 /** Set the timestamp of file @a path to @a apr_time. @a path is 00396 * utf8-encoded. 00397 * 00398 * @note This is the APR mtime which corresponds to the traditional mtime 00399 * on Unix, and the last write time on Windows. 00400 */ 00401 svn_error_t *svn_io_set_file_affected_time(apr_time_t apr_time, 00402 const char *path, 00403 apr_pool_t *pool); 00404 00405 00406 00407 /** Set @a *different_p to non-zero if @a file1 and @a file2 have different 00408 * sizes, else set to zero. Both @a file1 and @a file2 are utf8-encoded. 00409 * 00410 * Setting @a *different_p to zero does not mean the files definitely 00411 * have the same size, it merely means that the sizes are not 00412 * definitely different. That is, if the size of one or both files 00413 * cannot be determined, then the sizes are not known to be different, 00414 * so @a *different_p is set to 0. 00415 */ 00416 svn_error_t *svn_io_filesizes_different_p(svn_boolean_t *different_p, 00417 const char *file1, 00418 const char *file2, 00419 apr_pool_t *pool); 00420 00421 00422 /** Put the md5 checksum of @a file into @a digest. 00423 * @a digest points to @c APR_MD5_DIGESTSIZE bytes of storage. 00424 * Use @a pool only for temporary allocations. 00425 */ 00426 svn_error_t *svn_io_file_checksum(unsigned char digest[], 00427 const char *file, 00428 apr_pool_t *pool); 00429 00430 00431 /** Set @a *same to TRUE if @a file1 and @a file2 have the same 00432 * contents, else set it to FALSE. Use @a pool for temporary allocations. 00433 */ 00434 svn_error_t *svn_io_files_contents_same_p(svn_boolean_t *same, 00435 const char *file1, 00436 const char *file2, 00437 apr_pool_t *pool); 00438 00439 /** Create file at @a file with contents @a contents. 00440 * will be created. Path @a file is utf8-encoded. 00441 * Use @a pool for memory allocations. 00442 */ 00443 svn_error_t *svn_io_file_create(const char *file, 00444 const char *contents, 00445 apr_pool_t *pool); 00446 00447 /** 00448 * Lock file at @a lock_file. If @a exclusive is TRUE, 00449 * obtain exclusive lock, otherwise obtain shared lock. 00450 * Lock will be automatically released when @a pool is cleared or destroyed. 00451 * Use @a pool for memory allocations. 00452 * 00453 * @deprecated Provided for backward compatibility with the 1.0 API. 00454 */ 00455 svn_error_t *svn_io_file_lock(const char *lock_file, 00456 svn_boolean_t exclusive, 00457 apr_pool_t *pool); 00458 00459 /** 00460 * Lock file at @a lock_file. If @a exclusive is TRUE, 00461 * obtain exclusive lock, otherwise obtain shared lock. 00462 * 00463 * If @a nonblocking is TRUE, do not wait for the lock if it 00464 * is not available: throw an error instead. 00465 * 00466 * Lock will be automatically released when @a pool is cleared or destroyed. 00467 * Use @a pool for memory allocations. 00468 * 00469 * @since New in 1.1. 00470 */ 00471 svn_error_t *svn_io_file_lock2(const char *lock_file, 00472 svn_boolean_t exclusive, 00473 svn_boolean_t nonblocking, 00474 apr_pool_t *pool); 00475 /** 00476 * Flush any unwritten data from @a file to disk. Use @a pool for 00477 * memory allocations. 00478 * 00479 * @since New in 1.1. 00480 */ 00481 svn_error_t *svn_io_file_flush_to_disk(apr_file_t *file, 00482 apr_pool_t *pool); 00483 00484 /** Copy file @a file from location @a src_path to location @a dest_path. 00485 * Use @a pool for memory allocations. 00486 */ 00487 svn_error_t *svn_io_dir_file_copy(const char *src_path, 00488 const char *dest_path, 00489 const char *file, 00490 apr_pool_t *pool); 00491 00492 00493 /** Generic byte-streams 00494 * 00495 * @defgroup svn_io_byte_streams generic byte streams 00496 * @{ 00497 */ 00498 00499 /** An abstract stream of bytes--either incoming or outgoing or both. 00500 * 00501 * The creator of a stream sets functions to handle read and write. 00502 * Both of these handlers accept a baton whose value is determined at 00503 * stream creation time; this baton can point to a structure 00504 * containing data associated with the stream. If a caller attempts 00505 * to invoke a handler which has not been set, it will generate a 00506 * runtime assertion failure. The creator can also set a handler for 00507 * close requests so that it can flush buffered data or whatever; 00508 * if a close handler is not specified, a close request on the stream 00509 * will simply be ignored. Note that svn_stream_close() does not 00510 * deallocate the memory used to allocate the stream structure; free 00511 * the pool you created the stream in to free that memory. 00512 * 00513 * The read and write handlers accept length arguments via pointer. 00514 * On entry to the handler, the pointed-to value should be the amount 00515 * of data which can be read or the amount of data to write. When the 00516 * handler returns, the value is reset to the amount of data actually 00517 * read or written. Handlers are obliged to complete a read or write 00518 * to the maximum extent possible; thus, a short read with no 00519 * associated error implies the end of the input stream, and a short 00520 * write should never occur without an associated error. 00521 */ 00522 typedef struct svn_stream_t svn_stream_t; 00523 00524 00525 00526 /** Read handler function for a generic stream. @see svn_stream_t. */ 00527 typedef svn_error_t *(*svn_read_fn_t)(void *baton, 00528 char *buffer, 00529 apr_size_t *len); 00530 00531 /** Write handler function for a generic stream. @see svn_stream_t. */ 00532 typedef svn_error_t *(*svn_write_fn_t)(void *baton, 00533 const char *data, 00534 apr_size_t *len); 00535 00536 /** Close handler function for a generic stream. @see svn_stream_t. */ 00537 typedef svn_error_t *(*svn_close_fn_t)(void *baton); 00538 00539 00540 /** Create a generic stream. @see svn_stream_t. */ 00541 svn_stream_t *svn_stream_create(void *baton, apr_pool_t *pool); 00542 00543 /** Set @a stream's baton to @a baton */ 00544 void svn_stream_set_baton(svn_stream_t *stream, void *baton); 00545 00546 /** Set @a stream's read function to @a read_fn */ 00547 void svn_stream_set_read(svn_stream_t *stream, svn_read_fn_t read_fn); 00548 00549 /** Set @a stream's write function to @a write_fn */ 00550 void svn_stream_set_write(svn_stream_t *stream, svn_write_fn_t write_fn); 00551 00552 /** Set @a stream's close function to @a close_fn */ 00553 void svn_stream_set_close(svn_stream_t *stream, svn_close_fn_t close_fn); 00554 00555 00556 /** Create a stream that is empty for reading and infinite for writing. */ 00557 svn_stream_t *svn_stream_empty(apr_pool_t *pool); 00558 00559 /** Return a stream allocated in @a pool which forwards all requests 00560 * to @a stream. Destruction is explicitly excluded from forwarding. 00561 * 00562 * @see notes/destruction-of-stacked-resources 00563 * 00564 * @since New in 1.4. 00565 */ 00566 svn_stream_t *svn_stream_disown(svn_stream_t *stream, apr_pool_t *pool); 00567 00568 /** Create a stream from an APR file. For convenience, if @a file is 00569 * @c NULL, an empty stream created by svn_stream_empty() is returned. 00570 * 00571 * This function should normally be called with @a disown set to false, 00572 * in which case closing the stream will also close the underlying file. 00573 * 00574 * If @a disown is true, the stream will disown the underlying file, 00575 * meaning that svn_stream_close() will not close the file. 00576 * 00577 * @since New in 1.4. 00578 */ 00579 svn_stream_t * svn_stream_from_aprfile2(apr_file_t *file, 00580 svn_boolean_t disown, 00581 apr_pool_t *pool); 00582 00583 /** Similar to svn_stream_from_aprfile2(), except that the file will 00584 * always be disowned. 00585 * 00586 * @note The stream returned is not considered to "own" the underlying 00587 * file, meaning that svn_stream_close() on the stream will not 00588 * close the file. 00589 * 00590 * @deprecated Provided for backward compatibility with the 1.3 API. 00591 */ 00592 svn_stream_t *svn_stream_from_aprfile(apr_file_t *file, apr_pool_t *pool); 00593 00594 /** Set @a *out to a generic stream connected to stdout, allocated in 00595 * @a pool. The stream and its underlying APR handle will be closed 00596 * when @a pool is cleared or destroyed. 00597 */ 00598 svn_error_t *svn_stream_for_stdout(svn_stream_t **out, apr_pool_t *pool); 00599 00600 /** Return a generic stream connected to stringbuf @a str. Allocate the 00601 * stream in @a pool. 00602 */ 00603 svn_stream_t *svn_stream_from_stringbuf(svn_stringbuf_t *str, 00604 apr_pool_t *pool); 00605 00606 /** Return a stream that decompresses all data read and compresses all 00607 * data written. The stream @a stream is used to read and write all 00608 * compressed data. All compression data structures are allocated on 00609 * @a pool. If compression support is not compiled in then 00610 * svn_stream_compressed() returns @a stream unmodified. Make sure you 00611 * call svn_stream_close() on the stream returned by this function, 00612 * so that all data are flushed and cleaned up. 00613 */ 00614 svn_stream_t *svn_stream_compressed(svn_stream_t *stream, 00615 apr_pool_t *pool); 00616 00617 /** Return a stream that calculates checksums for all data read 00618 * and written. The stream @a stream is used to read and write all data. 00619 * The stream and the resulting digests are allocated in @a pool. 00620 * 00621 * When the stream is closed, @a read_digest and @a write_digest 00622 * are set to point to the resulting digests. 00623 * 00624 * Both @a read_digest and @a write_digest 00625 * can be @c NULL, in which case the respective checksum isn't calculated. 00626 * 00627 * If @a read_all is true, make sure that all data available on @a 00628 * stream is read (and checksummed) when the stream is closed. 00629 * 00630 * Read and write operations can be mixed without interfering. 00631 * 00632 * The @a stream passed into this function is closed when the created 00633 * stream is closed. 00634 * 00635 * @since New in 1.4. 00636 */ 00637 svn_stream_t *svn_stream_checksummed(svn_stream_t *stream, 00638 const unsigned char **read_digest, 00639 const unsigned char **write_digest, 00640 svn_boolean_t read_all, 00641 apr_pool_t *pool); 00642 00643 /** Read from a generic stream. @see svn_stream_t. */ 00644 svn_error_t *svn_stream_read(svn_stream_t *stream, char *buffer, 00645 apr_size_t *len); 00646 00647 /** Write to a generic stream. @see svn_stream_t. */ 00648 svn_error_t *svn_stream_write(svn_stream_t *stream, const char *data, 00649 apr_size_t *len); 00650 00651 /** Close a generic stream. @see svn_stream_t. */ 00652 svn_error_t *svn_stream_close(svn_stream_t *stream); 00653 00654 00655 /** Write to @a stream using a printf-style @a fmt specifier, passed through 00656 * apr_psprintf() using memory from @a pool. 00657 */ 00658 svn_error_t *svn_stream_printf(svn_stream_t *stream, 00659 apr_pool_t *pool, 00660 const char *fmt, 00661 ...) 00662 __attribute__ ((format(printf, 3, 4))); 00663 00664 /** Write to @a stream using a printf-style @a fmt specifier, passed through 00665 * apr_psprintf() using memory from @a pool. The resulting string 00666 * will be translated to @a encoding before it is sent to @a stream. 00667 * 00668 * @note Use @c APR_LOCALE_CHARSET to translate to the encoding of the 00669 * current locale. 00670 * 00671 * @since New in 1.3. 00672 */ 00673 svn_error_t *svn_stream_printf_from_utf8(svn_stream_t *stream, 00674 const char *encoding, 00675 apr_pool_t *pool, 00676 const char *fmt, 00677 ...) 00678 __attribute__ ((format(printf, 4, 5))); 00679 00680 /** Allocate @a *stringbuf in @a pool, and read into it one line (terminated 00681 * by @a eol) from @a stream. The line-terminator is read from the stream, 00682 * but is not added to the end of the stringbuf. Instead, the stringbuf 00683 * ends with a usual '\\0'. 00684 * 00685 * If @a stream runs out of bytes before encountering a line-terminator, 00686 * then set @a *eof to @c TRUE, otherwise set @a *eof to FALSE. 00687 */ 00688 svn_error_t * 00689 svn_stream_readline(svn_stream_t *stream, 00690 svn_stringbuf_t **stringbuf, 00691 const char *eol, 00692 svn_boolean_t *eof, 00693 apr_pool_t *pool); 00694 00695 /** 00696 * Read the contents of the readable stream @a from and write them to the 00697 * writable stream @a to. 00698 * 00699 * @since New in 1.1. 00700 */ 00701 svn_error_t *svn_stream_copy(svn_stream_t *from, svn_stream_t *to, 00702 apr_pool_t *pool); 00703 00704 /** Set @a *same to TRUE if @a stream1 and @a stream2 have the same 00705 * contents, else set it to FALSE. Use @a pool for temporary allocations. 00706 * 00707 * @since New in 1.4. 00708 */ 00709 svn_error_t * 00710 svn_stream_contents_same(svn_boolean_t *same, 00711 svn_stream_t *stream1, 00712 svn_stream_t *stream2, 00713 apr_pool_t *pool); 00714 00715 /** @} */ 00716 00717 /** Sets @a *result to a string containing the contents of @a filename, a 00718 * utf8-encoded path. 00719 * 00720 * If @a filename is "-", return the error @c SVN_ERR_UNSUPPORTED_FEATURE 00721 * and don't touch @a *result. 00722 * 00723 * ### Someday, "-" will fill @a *result from stdin. The problem right 00724 * now is that if the same command invokes the editor, stdin is crap, 00725 * and the editor acts funny or dies outright. One solution is to 00726 * disallow stdin reading and invoking the editor, but how to do that 00727 * reliably? 00728 */ 00729 svn_error_t *svn_stringbuf_from_file(svn_stringbuf_t **result, 00730 const char *filename, 00731 apr_pool_t *pool); 00732 00733 /** Sets @a *result to a string containing the contents of the already opened 00734 * @a file. Reads from the current position in file to the end. Does not 00735 * close the file or reset the cursor position. 00736 */ 00737 svn_error_t *svn_stringbuf_from_aprfile(svn_stringbuf_t **result, 00738 apr_file_t *file, 00739 apr_pool_t *pool); 00740 00741 /** Remove file @a path, a utf8-encoded path. This wraps apr_file_remove(), 00742 * converting any error to a Subversion error. 00743 */ 00744 svn_error_t *svn_io_remove_file(const char *path, apr_pool_t *pool); 00745 00746 /** Recursively remove directory @a path. @a path is utf8-encoded. */ 00747 svn_error_t *svn_io_remove_dir(const char *path, apr_pool_t *pool); 00748 00749 /** Read all of the disk entries in directory @a path, a utf8-encoded 00750 * path. Set @a *dirents to a hash mapping dirent names (<tt>char *</tt>) to 00751 * undefined non-NULL values, allocated in @a pool. 00752 * 00753 * @note The `.' and `..' directories normally returned by 00754 * apr_dir_read() are NOT returned in the hash. 00755 * 00756 * @since New in 1.4. 00757 */ 00758 svn_error_t *svn_io_get_dir_filenames(apr_hash_t **dirents, 00759 const char *path, 00760 apr_pool_t *pool); 00761 00762 /** Read all of the disk entries in directory @a path, a utf8-encoded 00763 * path. Set @a *dirents to a hash mapping dirent names (<tt>char *</tt>) to 00764 * @c svn_io_dirent_t structures, allocated in @a pool. 00765 * 00766 * @note The `.' and `..' directories normally returned by 00767 * apr_dir_read() are NOT returned in the hash. 00768 * 00769 * @since New in 1.3. 00770 */ 00771 svn_error_t *svn_io_get_dirents2(apr_hash_t **dirents, 00772 const char *path, 00773 apr_pool_t *pool); 00774 00775 /** Similar to svn_io_get_dirents2(), but @a *dirents is a hash table 00776 * with @c svn_node_kind_t values. 00777 * 00778 * @deprecated Provided for backwards compatibility with the 1.2 API. 00779 */ 00780 svn_error_t *svn_io_get_dirents(apr_hash_t **dirents, 00781 const char *path, 00782 apr_pool_t *pool); 00783 00784 00785 /** Callback function type for svn_io_dir_walk() */ 00786 typedef svn_error_t * (*svn_io_walk_func_t)(void *baton, 00787 const char *path, 00788 const apr_finfo_t *finfo, 00789 apr_pool_t *pool); 00790 00791 /** This function will recursively walk over the files and directories 00792 * rooted at @a dirname, a utf8-encoded path. For each file or directory, 00793 * @a walk_func is invoked, passing in the @a walk_baton, the utf8-encoded 00794 * full path to the entry, an @c apr_finfo_t structure, and a temporary 00795 * pool for allocations. For any directory, @a walk_func will be invoked 00796 * on the directory itself before being invoked on any subdirectories or 00797 * files within the directory. 00798 * 00799 * The set of information passed to @a walk_func is specified by @a wanted, 00800 * and the items specified by @c APR_FINFO_TYPE and @c APR_FINFO_NAME. 00801 * 00802 * All allocations will be performed in @a pool. 00803 */ 00804 svn_error_t *svn_io_dir_walk(const char *dirname, 00805 apr_int32_t wanted, 00806 svn_io_walk_func_t walk_func, 00807 void *walk_baton, 00808 apr_pool_t *pool); 00809 00810 /** 00811 * Start @a cmd with @a args, using utf8-encoded @a path as working 00812 * directory. Connect @a cmd's stdin, stdout, and stderr to @a infile, 00813 * @a outfile, and @a errfile, except where they are null. Return the 00814 * process handle for the invoked program in @a *cmd_proc. 00815 * 00816 * @a args is a list of utf8-encoded <tt>const char *</tt> arguments, 00817 * terminated by @c NULL. @a args[0] is the name of the program, though it 00818 * need not be the same as @a cmd. 00819 * 00820 * If @a inherit is true, the invoked program inherits its environment from 00821 * the caller and @a cmd, if not absolute, is searched for in PATH. 00822 * Otherwise, the invoked program runs with an empty environment and @a cmd 00823 * must be an absolute path. 00824 * 00825 * @note On some platforms, failure to execute @a cmd in the child process 00826 * will result in error output being written to @a errfile, if non-NULL, and 00827 * a non-zero exit status being returned to the parent process. 00828 * 00829 * @since New in 1.3. 00830 */ 00831 svn_error_t *svn_io_start_cmd(apr_proc_t *cmd_proc, 00832 const char *path, 00833 const char *cmd, 00834 const char *const *args, 00835 svn_boolean_t inherit, 00836 apr_file_t *infile, 00837 apr_file_t *outfile, 00838 apr_file_t *errfile, 00839 apr_pool_t *pool); 00840 00841 /** 00842 * Wait for the process @a *cmd_proc to complete and optionally retrieve 00843 * its exit code. @a cmd is used only in error messages. 00844 * 00845 * If @a exitcode is not null, @a *exitcode will contain the exit code 00846 * of the process upon return, and if @a exitwhy is not null, @a 00847 * *exitwhy will indicate why the process terminated. If @a exitwhy is 00848 * null, and the exit reason is not @c APR_PROC_CHECK_EXIT(), or if 00849 * @a exitcode is null and the exit code is non-zero, then an 00850 * @c SVN_ERR_EXTERNAL_PROGRAM error will be returned. 00851 * 00852 * @since New in 1.3. 00853 */ 00854 svn_error_t *svn_io_wait_for_cmd(apr_proc_t *cmd_proc, 00855 const char *cmd, 00856 int *exitcode, 00857 apr_exit_why_e *exitwhy, 00858 apr_pool_t *pool); 00859 00860 /** Run a command to completion, by first calling svn_io_start_cmd() and 00861 * then calling svn_io_wait_for_cmd(). The parameters correspond to 00862 * the same-named parameters of those two functions. 00863 */ 00864 svn_error_t *svn_io_run_cmd(const char *path, 00865 const char *cmd, 00866 const char *const *args, 00867 int *exitcode, 00868 apr_exit_why_e *exitwhy, 00869 svn_boolean_t inherit, 00870 apr_file_t *infile, 00871 apr_file_t *outfile, 00872 apr_file_t *errfile, 00873 apr_pool_t *pool); 00874 00875 /** Invoke @c the configured diff program, with @a user_args (an array 00876 * of utf8-encoded @a num_user_args arguments), if they are specified, 00877 * or "-u" if they are not. 00878 * 00879 * Diff runs in utf8-encoded @a dir, and its exit status is stored in 00880 * @a exitcode, if it is not @c NULL. 00881 * 00882 * If @a label1 and/or @a label2 are not null they will be passed to the diff 00883 * process as the arguments of "-L" options. @a label1 and @a label2 are also 00884 * in utf8, and will be converted to native charset along with the other args. 00885 * 00886 * @a from is the first file passed to diff, and @a to is the second. The 00887 * stdout of diff will be sent to @a outfile, and the stderr to @a errfile. 00888 * 00889 * @a diff_cmd must be non-null. 00890 * 00891 * Do all allocation in @a pool. 00892 */ 00893 svn_error_t *svn_io_run_diff(const char *dir, 00894 const char *const *user_args, 00895 int num_user_args, 00896 const char *label1, 00897 const char *label2, 00898 const char *from, 00899 const char *to, 00900 int *exitcode, 00901 apr_file_t *outfile, 00902 apr_file_t *errfile, 00903 const char *diff_cmd, 00904 apr_pool_t *pool); 00905 00906 00907 /** Invoke @c the configured diff3 program, in utf8-encoded @a dir 00908 * like this: 00909 * 00910 * diff3 -E -m @a mine @a older @a yours > @a merged 00911 * 00912 * (See the diff3 documentation for details.) 00913 * 00914 * If @a user_args is non-NULL, replace "-E" with the <tt>const char*</tt> 00915 * elements that @a user_args contains. 00916 * 00917 * @a mine, @a older, and @a yours are utf8-encoded paths, relative to @a dir, 00918 * to three files that already exist. @a merged is an open file handle, and 00919 * is left open after the merge result is written to it. (@a merged 00920 * should *not* be the same file as @a mine, or nondeterministic things 00921 * may happen!) 00922 * 00923 * @a mine_label, @a older_label, @a yours_label are utf8-encoded label 00924 * parameters for diff3's -L option. Any of them may be @c NULL, in 00925 * which case the corresponding @a mine, @a older, or @a yours parameter is 00926 * used instead. 00927 * 00928 * Set @a *exitcode to diff3's exit status. If @a *exitcode is anything 00929 * other than 0 or 1, then return @c SVN_ERR_EXTERNAL_PROGRAM. (Note the 00930 * following from the diff3 info pages: "An exit status of 0 means 00931 * `diff3' was successful, 1 means some conflicts were found, and 2 00932 * means trouble.") 00933 * 00934 * @a diff3_cmd must be non-null. 00935 * 00936 * Do all allocation in @a pool. 00937 * 00938 * @since New in 1.4. 00939 */ 00940 svn_error_t *svn_io_run_diff3_2(int *exitcode, 00941 const char *dir, 00942 const char *mine, 00943 const char *older, 00944 const char *yours, 00945 const char *mine_label, 00946 const char *older_label, 00947 const char *yours_label, 00948 apr_file_t *merged, 00949 const char *diff3_cmd, 00950 const apr_array_header_t *user_args, 00951 apr_pool_t *pool); 00952 00953 /** Similar to @a svn_io_run_diff3_2(), but with @a user_args set to @c NULL. 00954 * 00955 * @deprecated Provided for backwards compatibility with the 1.3 API. 00956 */ 00957 svn_error_t *svn_io_run_diff3(const char *dir, 00958 const char *mine, 00959 const char *older, 00960 const char *yours, 00961 const char *mine_label, 00962 const char *older_label, 00963 const char *yours_label, 00964 apr_file_t *merged, 00965 int *exitcode, 00966 const char *diff3_cmd, 00967 apr_pool_t *pool); 00968 00969 00970 /** Examine utf8-encoded @a file to determine if it can be described by a 00971 * known (as in, known by this function) Multipurpose Internet Mail 00972 * Extension (MIME) type. If so, set @a *mimetype to a character string 00973 * describing the MIME type, else set it to @c NULL. Use @a pool for any 00974 * necessary allocations. 00975 */ 00976 svn_error_t *svn_io_detect_mimetype(const char **mimetype, 00977 const char *file, 00978 apr_pool_t *pool); 00979 00980 00981 /** Wrapper for apr_file_open(), which see. @a fname is utf8-encoded. */ 00982 svn_error_t * 00983 svn_io_file_open(apr_file_t **new_file, const char *fname, 00984 apr_int32_t flag, apr_fileperms_t perm, 00985 apr_pool_t *pool); 00986 00987 00988 /** Wrapper for apr_file_close(), which see. */ 00989 svn_error_t * 00990 svn_io_file_close(apr_file_t *file, apr_pool_t *pool); 00991 00992 00993 /** Wrapper for apr_file_getc(), which see. */ 00994 svn_error_t * 00995 svn_io_file_getc(char *ch, apr_file_t *file, apr_pool_t *pool); 00996 00997 00998 /** Wrapper for apr_file_info_get(), which see. */ 00999 svn_error_t * 01000 svn_io_file_info_get(apr_finfo_t *finfo, apr_int32_t wanted, 01001 apr_file_t *file, apr_pool_t *pool); 01002 01003 01004 /** Wrapper for apr_file_read(), which see. */ 01005 svn_error_t * 01006 svn_io_file_read(apr_file_t *file, void *buf, 01007 apr_size_t *nbytes, apr_pool_t *pool); 01008 01009 01010 /** Wrapper for apr_file_read_full(), which see. */ 01011 svn_error_t * 01012 svn_io_file_read_full(apr_file_t *file, void *buf, 01013 apr_size_t nbytes, apr_size_t *bytes_read, 01014 apr_pool_t *pool); 01015 01016 01017 /** Wrapper for apr_file_seek(), which see. */ 01018 svn_error_t * 01019 svn_io_file_seek(apr_file_t *file, apr_seek_where_t where, 01020 apr_off_t *offset, apr_pool_t *pool); 01021 01022 01023 /** Wrapper for apr_file_write(), which see. */ 01024 svn_error_t * 01025 svn_io_file_write(apr_file_t *file, const void *buf, 01026 apr_size_t *nbytes, apr_pool_t *pool); 01027 01028 01029 /** Wrapper for apr_file_write_full(), which see. */ 01030 svn_error_t * 01031 svn_io_file_write_full(apr_file_t *file, const void *buf, 01032 apr_size_t nbytes, apr_size_t *bytes_written, 01033 apr_pool_t *pool); 01034 01035 01036 /** Wrapper for apr_stat(), which see. @a fname is utf8-encoded. */ 01037 svn_error_t * 01038 svn_io_stat(apr_finfo_t *finfo, const char *fname, 01039 apr_int32_t wanted, apr_pool_t *pool); 01040 01041 01042 /** Wrapper for apr_file_rename(), which see. @a from_path and @a to_path 01043 * are utf8-encoded. 01044 */ 01045 svn_error_t * 01046 svn_io_file_rename(const char *from_path, const char *to_path, 01047 apr_pool_t *pool); 01048 01049 01050 /** Move the file from @a from_path to @a to_path, even across device 01051 * boundaries. Overwrite @a to_path if it exists. 01052 * 01053 * @note This function is different from svn_io_file_rename in that the 01054 * latter fails in the 'across device boundaries' case. 01055 * 01056 * @since New in 1.3. 01057 */ 01058 svn_error_t * 01059 svn_io_file_move(const char *from_path, const char *to_path, 01060 apr_pool_t *pool); 01061 01062 01063 /** Wrapper for apr_dir_make(), which see. @a path is utf8-encoded. */ 01064 svn_error_t * 01065 svn_io_dir_make(const char *path, apr_fileperms_t perm, apr_pool_t *pool); 01066 01067 /** Same as svn_io_dir_make(), but sets the hidden attribute on the 01068 directory on systems that support it. */ 01069 svn_error_t * 01070 svn_io_dir_make_hidden(const char *path, apr_fileperms_t perm, 01071 apr_pool_t *pool); 01072 01073 /** 01074 * Same as svn_io_dir_make(), but attempts to set the sgid on the 01075 * directory on systems that support it. Does not return an error if 01076 * the attempt to set the sgid bit fails. On Unix filesystems, 01077 * setting the sgid bit on a directory ensures that files and 01078 * subdirectories created within inherit group ownership from the 01079 * parent instead of from the primary gid. 01080 * 01081 * @since New in 1.1. 01082 */ 01083 svn_error_t * 01084 svn_io_dir_make_sgid(const char *path, apr_fileperms_t perm, 01085 apr_pool_t *pool); 01086 01087 /** Wrapper for apr_dir_open(), which see. @a dirname is utf8-encoded. */ 01088 svn_error_t * 01089 svn_io_dir_open(apr_dir_t **new_dir, const char *dirname, apr_pool_t *pool); 01090 01091 01092 /** Wrapper for apr_dir_remove(), which see. @a dirname is utf8-encoded. 01093 * @note This function has this name to avoid confusion with 01094 * svn_io_remove_dir(), which is recursive. 01095 */ 01096 svn_error_t * 01097 svn_io_dir_remove_nonrecursive(const char *dirname, apr_pool_t *pool); 01098 01099 01100 /** Wrapper for apr_dir_read(). Ensures that @a finfo->name is 01101 * utf8-encoded, which means allocating @a finfo->name in @a pool, 01102 * which may or may not be the same as @a finfo's pool. Use @a pool 01103 * for error allocation as well. 01104 */ 01105 svn_error_t * 01106 svn_io_dir_read(apr_finfo_t *finfo, 01107 apr_int32_t wanted, 01108 apr_dir_t *thedir, 01109 apr_pool_t *pool); 01110 01111 01112 01113 /** Version/format files. 01114 * 01115 * @defgroup svn_io_format_files version/format files 01116 * @{ 01117 */ 01118 01119 /** Set @a *version to the integer that starts the file at @a path. If the 01120 * file does not begin with a series of digits followed by a newline, 01121 * return the error @c SVN_ERR_BAD_VERSION_FILE_FORMAT. Use @a pool for 01122 * all allocations. 01123 */ 01124 svn_error_t * 01125 svn_io_read_version_file(int *version, const char *path, apr_pool_t *pool); 01126 01127 /** Create (or overwrite) the file at @a path with new contents, 01128 * formatted as a non-negative integer @a version followed by a single 01129 * newline. On successful completion the file will be read-only. Use 01130 * @a pool for all allocations. 01131 */ 01132 svn_error_t * 01133 svn_io_write_version_file(const char *path, int version, apr_pool_t *pool); 01134 01135 /** @} */ 01136 01137 #ifdef __cplusplus 01138 } 01139 #endif /* __cplusplus */ 01140 01141 #endif /* SVN_IO_H */