blob: f17c28ec731deac2e6dc8bb8906385735425a622 [file] [log] [blame]
/*
* svn_io.h : general Subversion I/O definitions
*
* ====================================================================
* Copyright (c) 2000-2002 CollabNet. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://subversion.tigris.org/license-1.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://subversion.tigris.org/.
* ====================================================================
*/
/* ==================================================================== */
#ifndef SVN_IO_H
#define SVN_IO_H
#include <apr.h>
#include <apr_pools.h>
#include <apr_file_io.h>
#include <apr_thread_proc.h>
#include "svn_types.h"
#include "svn_error.h"
#include "svn_string.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* If PATH exists, set *KIND to the appropriate kind, else set it to
* svn_node_unknown.
*
* If PATH is a file, *KIND is set to svn_node_file.
*
* If PATH is a directory, *KIND is set to svn_node_dir.
*
* If PATH does not exist in its final component, *KIND is set to
* svn_node_none.
*
* If intermediate directories on the way to PATH don't exist, an
* error is returned, and *KIND's value is undefined.
*/
svn_error_t *svn_io_check_path (const char *path,
enum svn_node_kind *kind,
apr_pool_t *pool);
/* Open a new file (for writing) with a unique name based on PATH, in the
* same directory as PATH. The file handle is returned in *F, and the
* name, which ends with SUFFIX, is returned in *UNIQUE_NAME. If
* DELETE_ON_CLOSE is set, then the APR_DELONCLOSE flag will be used when
* opening the file.
*
* The name will include as much of PATH as possible, then a dot,
* then a random portion, then another dot, then an iterated attempt
* number (00001 for the first try, 00002 for the second, etc), and
* end with SUFFIX. For example, if PATH is
*
* tests/t1/A/D/G/pi
*
* then svn_io_open_unique_file(&f, &uniqe_name, PATH, ".tmp", pool) might pick
*
* tests/t1/A/D/G/pi.3221223676.00001.tmp
*
* the first time, then
*
* tests/t1/A/D/G/pi.3221223676.00002.tmp
*
* if called again while the first unique file still exists.
*
* It doesn't matter if PATH is a file or directory, the unique name will
* be in PATH's parent either way.
*
* *UNIQUE_NAME will never be exactly the same as PATH, even if PATH does
* not exist.
*
* *F and *UNIQUE_NAME are allocated in POOL.
*
* If no unique name can be found, SVN_ERR_IO_UNIQUE_NAMES_EXHAUSTED is
* the error returned.
*
* Claim of Historical Inevitability: this function was written
* because
*
* tmpnam() is not thread-safe.
* tempname() tries standard system tmp areas first.
*
* Claim of Historical Evitability: the random portion of the name is
* there because someday, someone will have a directory full of files
* whose names match the iterating portion and suffix (say, a
* database's holding area). The random portion is a safeguard
* against that case.
*/
svn_error_t *svn_io_open_unique_file (apr_file_t **f,
svn_stringbuf_t **unique_name,
const char *path,
const char *suffix,
svn_boolean_t delete_on_close,
apr_pool_t *pool);
/* Copy SRC to DST. DST will be overwritten if it exists, else it will be
created. If COPY_PERMS is set the file permissions of DST will be set to
match those of SRC, this will happen before the contents are copied. */
svn_error_t *svn_io_copy_file (const char *src,
const char *dst,
svn_boolean_t copy_perms,
apr_pool_t *pool);
/* Recursively copy directory SRC into DST_PARENT, as a new entry named
DST_BASENAME. If DST_BASENAME already exists in DST_PARENT, return
error. COPY_PERMS will be passed through to svn_io_copy_file when any
files are copied. */
svn_error_t *svn_io_copy_dir_recursively (svn_stringbuf_t *src,
svn_stringbuf_t *dst_parent,
svn_stringbuf_t *dst_basename,
svn_boolean_t copy_perms,
apr_pool_t *pool);
/* Return APR_SUCCESS if directory PATH is an empty directory,
APR_EGENERAL if it is not empty, or the associated apr error if
there was any trouble finding out whether or not it's empty. */
apr_status_t apr_check_dir_empty (const char *path, apr_pool_t *pool);
/* Append SRC to DST. DST will be appended to if it exists, else it
will be created. */
svn_error_t *svn_io_append_file (svn_stringbuf_t *src,
svn_stringbuf_t *dst,
apr_pool_t *pool);
/* Make a file as read-only as the operating system allows.
PATH is the path to the file. If IGNORE_ENOENT is TRUE,
don't fail if the target file doesn't exist. */
svn_error_t *svn_io_set_file_read_only (const char *path,
svn_boolean_t ignore_enoent,
apr_pool_t *pool);
/* Make a file as writable as the operating system allows.
PATH is the path to the file. If IGNORE_ENOENT is TRUE,
don't fail if the target file doesn't exist. */
svn_error_t *svn_io_set_file_read_write (const char *path,
svn_boolean_t ignore_enoent,
apr_pool_t *pool);
/* Read a line from FILE into BUF, but not exceeding *LIMIT bytes.
* Does not include newline, instead '\0' is put there.
* Length (as in strlen) is returned in *LIMIT.
* BUF should be pre-allocated.
* FILE should be already opened.
*
* When the file is out of lines, APR_EOF will be returned.
*/
apr_status_t
svn_io_read_length_line (apr_file_t *file, char *buf, apr_size_t *limit);
/* Set *APR_TIME to the later of PATH's (a regular file) mtime or ctime.
*
* Unix traditionally distinguishes between "mod time", which is when
* someone last modified the contents of the file, and "change time",
* when someone changed something else about the file (such as
* permissions).
*
* Since Subversion versions both kinds of information, our timestamp
* comparisons have to notice either kind of change. That's why this
* function gives the time of whichever kind came later. APR will
* hopefully make sure that both ctime and mtime always have useful
* values, even on OS's that do things differently. (?)
*/
svn_error_t *svn_io_file_affected_time (apr_time_t *apr_time,
svn_stringbuf_t *path,
apr_pool_t *pool);
/* Set *DIFFERENT_P to non-zero if FILE1 and FILE2 have different
* sizes, else set to zero.
*
* Setting *DIFFERENT_P to zero does not mean the files definitely
* have the same size, it merely means that the sizes are not
* definitely different. That is, if the size of one or both files
* cannot be determined, then the sizes are not known to be different,
* so *DIFFERENT_P is set to 0.
*/
svn_error_t *svn_io_filesizes_different_p (svn_boolean_t *different_p,
const char *file1,
const char *file2,
apr_pool_t *pool);
/* Return a POSIX-like file descriptor from FILE.
We need this because on some platforms, notably Windows, apr_file_t
is not based on a file descriptor; but we have to pass an FD to neon.
FIXME: This function will hopefully go away if/when neon gets
replaced by apr-serf. */
apr_status_t svn_io_fd_from_file (int *fd_p, apr_file_t *file);
/* Generic byte-streams */
/* svn_stream_t represents an abstract stream of bytes--either
incoming or outgoing or both.
The creator of a stream sets functions to handle read and write.
Both of these handlers accept a baton whose value is determined at
stream creation time; this baton can point to a structure
containing data associated with the stream. If a caller attempts
to invoke a handler which has not been set, it will generate a
runtime assertion failure. The creator can also set a handler for
close requests so that it can flush buffered data or whatever;
if a close handler is not specified, a close request on the stream
will simply be ignored. Note that svn_stream_close() does not
deallocate the memory used to allocate the stream structure; free
the pool you created the stream in to free that memory.
The read and write handlers accept length arguments via pointer.
On entry to the handler, the pointed-to value should be the amount
of data which can be read or the amount of data to write. When the
handler returns, the value is reset to the amount of data actually
read or written. Handlers are obliged to complete a read or write
to the maximum extent possible; thus, a short read with no
associated error implies the end of the input stream, and a short
write should never occur without an associated error. */
typedef struct svn_stream_t svn_stream_t;
/* Handler functions to implement the operations on a generic stream. */
typedef svn_error_t *(*svn_read_fn_t) (void *baton,
char *buffer,
apr_size_t *len);
typedef svn_error_t *(*svn_write_fn_t) (void *baton,
const char *data,
apr_size_t *len);
typedef svn_error_t *(*svn_close_fn_t) (void *baton);
/* Functions for creating generic streams. */
svn_stream_t *svn_stream_create (void *baton, apr_pool_t *pool);
svn_stream_t *svn_stream_dup (svn_stream_t *stream, apr_pool_t *pool);
void svn_stream_set_baton (svn_stream_t *stream, void *baton);
void svn_stream_set_read (svn_stream_t *stream, svn_read_fn_t read_fn);
void svn_stream_set_write (svn_stream_t *stream, svn_write_fn_t write_fn);
void svn_stream_set_close (svn_stream_t *stream, svn_close_fn_t close_fn);
/* Convenience function to create a readable generic stream which is
empty. */
svn_stream_t *svn_stream_empty (apr_pool_t *pool);
/* Convenience functions for creating streams which operate on APR
files or on stdio files. For convenience, if FILE or FP is NULL
then svn_stream_empty(pool) is returned. Note that the stream
returned by these operations is not considered to "own" the
underlying file, meaning that svn_stream_close() on the stream will
not close the file. */
svn_stream_t *svn_stream_from_aprfile (apr_file_t *file, apr_pool_t *pool);
svn_stream_t *svn_stream_from_stdio (FILE *fp, apr_pool_t *pool);
/* Functions for operating on generic streams. */
svn_error_t *svn_stream_read (svn_stream_t *stream, char *buffer,
apr_size_t *len);
svn_error_t *svn_stream_write (svn_stream_t *stream, const char *data,
apr_size_t *len);
svn_error_t *svn_stream_close (svn_stream_t *stream);
/* Sets *RESULT to a string containing the contents of FILENAME. */
svn_error_t *svn_string_from_file (svn_stringbuf_t **result,
const char *filename,
apr_pool_t *pool);
/* Sets *RESULT to a string containing the contents of the already opened
FILE. Reads from the current position in file to the end. Does not
close the file or reset the cursor position.*/
svn_error_t *svn_string_from_aprfile (svn_stringbuf_t **result,
apr_file_t *file,
apr_pool_t *pool);
/* Remove a file. This wraps apr_file_remove(), converting any error
to a Subversion error. */
svn_error_t *svn_io_remove_file (const char *path, apr_pool_t *pool);
/* Recursively remove directory PATH. */
apr_status_t apr_dir_remove_recursively (const char *path, apr_pool_t *pool);
/* Read all of the disk entries in directory PATH. Return a DIRENTS
hash mapping dirent names (char *) to enumerated dirent filetypes
(enum svn_node_kind *).
Note: the `.' and `..' directories normally returned by
apr_dir_read will NOT be returned in the hash. */
svn_error_t *svn_io_get_dirents (apr_hash_t **dirents,
svn_stringbuf_t *path,
apr_pool_t *pool);
/* Invoke CMD with ARGS, using PATH as working directory.
Connect CMD's stdin, stdout, and stderr to INFILE, OUTFILE, and
ERRFILE, except where they are null.
EXITCODE will contain the exit code of the process upon return, and
EXITWHY will indicate why the process terminated.
ARGS is a list of (const char *)'s, terminated by NULL. ARGS[0] is
the name of the program, though it need not be the same as CMD.
INHERIT sets whether the invoked program shall inherit its environment or
run "clean". */
svn_error_t *svn_io_run_cmd (const char *path,
const char *cmd,
const char *const *args,
int *exitcode,
apr_exit_why_e *exitwhy,
svn_boolean_t inherit,
apr_file_t *infile,
apr_file_t *outfile,
apr_file_t *errfile,
apr_pool_t *pool);
/* Invoke SVN_CLIENT_DIFF, with USER_ARGS (which is an array of NUM_USER_ARGS
arguments), if they are specified, or "-u" if they are not.
Diff runs in DIR, and its exit status is stored in EXITCODE, if it is not
NULL.
If LABEL is given, it will be passed in as the argument to the "-L" option.
FROM is the first file passed to diff, and TO is the second. The stdout of
diff will be sent to OUTFILE, and the stderr to ERRFILE. All memory will be
allocated using POOL. */
svn_error_t *svn_io_run_diff (const char *dir,
const char *const *user_args,
const int num_user_args,
const char *label,
const char *from,
const char *to,
int *exitcode,
apr_file_t *outfile,
apr_file_t *errfile,
apr_pool_t *pool);
/* Invoke SVN_CLIENT_DIFF3 in DIR like this:
diff3 -Em MINE OLDER YOURS > MERGED
(See the diff3 documentation for details.)
MINE, OLDER, and YOURS are paths, relative to DIR, to three files
that already exist. MERGED is an open file handle, and is left
open after the merge result is written to it. (MERGED should *not*
be the same file as MINE, or nondeterministic things may happen!)
MINE_LABEL, OLDER_LABEL, YOURS_LABEL are label parameters for
diff3's -L option. Any of them may be NULL, in which case the
corresponding MINE, OLDER, or YOURS parameter is used instead.
Set *EXITCODE to diff3's exit status. If *EXITCODE is anything
other than 0 or 1, then return SVN_ERR_EXTERNAL_PROGRAM. (Note the
following from the diff3 info pages: "An exit status of 0 means
`diff3' was successful, 1 means some conflicts were found, and 2
means trouble.")
*/
svn_error_t *svn_io_run_diff3 (const char *dir,
const char *mine,
const char *older,
const char *yours,
const char *mine_label,
const char *older_label,
const char *yours_label,
apr_file_t *merged,
int *exitcode,
apr_pool_t *pool);
/* Examine FILE to determine if it can be described by a known (as in,
known by this function) Multipurpose Internet Mail Extension (MIME)
type. If so, set MIMETYPE to a character string describing the
MIME type, else set it to NULL. Use POOL for any necessary
allocations. */
svn_error_t *svn_io_detect_mimetype (const char **mimetype,
const char *file,
apr_pool_t *pool);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* SVN_IO_H */
/* ----------------------------------------------------------------
* local variables:
* eval: (load-file "../../tools/dev/svn-dev.el")
* end:
*/