Implemented exec() support function vfs_exec_io_context() which closes all

file descriptors that have O_CLOEXEC set.
Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9242 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-10-07 14:47:58 +00:00
parent 76dede71c7
commit 5c41c39314
+54 -20
View File
@@ -762,20 +762,21 @@ resolve_volume_root_to_mount_point(struct vnode *vnode)
/** \brief Gets the directory path and leaf name for a given path. /** \brief Gets the directory path and leaf name for a given path.
*
The supplied \a path is transformed to refer to the directory part of * The supplied \a path is transformed to refer to the directory part of
the entry identified by the original path, and into the buffer \a filename * the entry identified by the original path, and into the buffer \a filename
the leaf name of the original entry is written. * the leaf name of the original entry is written.
Neither the returned path nor the leaf name can be expected to be * Neither the returned path nor the leaf name can be expected to be
canonical. * canonical.
*
\param path The path to be analyzed. Must be able to store at least one * \param path The path to be analyzed. Must be able to store at least one
additional character. * additional character.
\param filename The buffer into which the leaf name will be written. * \param filename The buffer into which the leaf name will be written.
Must be of size B_FILE_NAME_LENGTH at least. * Must be of size B_FILE_NAME_LENGTH at least.
\return \c B_OK, if everything went fine, \c B_NAME_TOO_LONG, if the leaf * \return \c B_OK, if everything went fine, \c B_NAME_TOO_LONG, if the leaf
name is longer than \c B_FILE_NAME_LENGTH. * name is longer than \c B_FILE_NAME_LENGTH.
*/ */
static status_t static status_t
get_dir_path_and_leaf(char *path, char *filename) get_dir_path_and_leaf(char *path, char *filename)
{ {
@@ -1124,6 +1125,7 @@ get_vnode_name(struct vnode *vnode, struct vnode *parent,
* It might be a good idea, though, to check if the returned path exists * It might be a good idea, though, to check if the returned path exists
* in the calling function (it's not done here because of efficiency) * in the calling function (it's not done here because of efficiency)
*/ */
static status_t static status_t
dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize) dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
{ {
@@ -1772,6 +1774,38 @@ vfs_get_file_map(void *_vnode, off_t offset, size_t size, file_io_vec *vecs, siz
} }
/** Closes all file descriptors of the specified I/O context that
* don't have the O_CLOEXEC flag set.
*/
void
vfs_exec_io_context(void *_context)
{
struct io_context *context = (struct io_context *)_context;
uint32 i;
for (i = 0; i < context->table_size; i++) {
mutex_lock(&context->io_mutex);
struct file_descriptor *descriptor = context->fds[i];
bool remove = false;
if (descriptor != NULL && (descriptor->open_mode & O_CLOEXEC) != 0) {
context->fds[i] = NULL;
context->num_used_fds--;
remove = true;
}
mutex_unlock(&context->io_mutex);
if (remove)
put_fd(descriptor);
}
}
/** Sets up a new io_control structure, and inherits the properties /** Sets up a new io_control structure, and inherits the properties
* of the parent io_control if it is given. * of the parent io_control if it is given.
*/ */
@@ -1779,7 +1813,7 @@ vfs_get_file_map(void *_vnode, off_t offset, size_t size, file_io_vec *vecs, siz
void * void *
vfs_new_io_context(void *_parentContext) vfs_new_io_context(void *_parentContext)
{ {
size_t table_size; size_t tableSize;
struct io_context *context; struct io_context *context;
struct io_context *parentContext; struct io_context *parentContext;
@@ -1791,17 +1825,17 @@ vfs_new_io_context(void *_parentContext)
parentContext = (struct io_context *)_parentContext; parentContext = (struct io_context *)_parentContext;
if (parentContext) if (parentContext)
table_size = parentContext->table_size; tableSize = parentContext->table_size;
else else
table_size = DEFAULT_FD_TABLE_SIZE; tableSize = DEFAULT_FD_TABLE_SIZE;
context->fds = (file_descriptor **)malloc(sizeof(struct file_descriptor *) * table_size); context->fds = (file_descriptor **)malloc(sizeof(struct file_descriptor *) * tableSize);
if (context->fds == NULL) { if (context->fds == NULL) {
free(context); free(context);
return NULL; return NULL;
} }
memset(context->fds, 0, sizeof(struct file_descriptor *) * table_size); memset(context->fds, 0, sizeof(struct file_descriptor *) * tableSize);
if (mutex_init(&context->io_mutex, "I/O context") < 0) { if (mutex_init(&context->io_mutex, "I/O context") < 0) {
free(context->fds); free(context->fds);
@@ -1820,7 +1854,7 @@ vfs_new_io_context(void *_parentContext)
if (context->cwd) if (context->cwd)
inc_vnode_ref_count(context->cwd); inc_vnode_ref_count(context->cwd);
for (i = 0; i < table_size; i++) { for (i = 0; i < tableSize; i++) {
if (parentContext->fds[i] && (parentContext->fds[i]->open_mode & O_CLOEXEC) == 0) { if (parentContext->fds[i] && (parentContext->fds[i]->open_mode & O_CLOEXEC) == 0) {
context->fds[i] = parentContext->fds[i]; context->fds[i] = parentContext->fds[i];
atomic_add(&context->fds[i]->ref_count, 1); atomic_add(&context->fds[i]->ref_count, 1);
@@ -1835,7 +1869,7 @@ vfs_new_io_context(void *_parentContext)
inc_vnode_ref_count(context->cwd); inc_vnode_ref_count(context->cwd);
} }
context->table_size = table_size; context->table_size = tableSize;
list_init(&context->node_monitors); list_init(&context->node_monitors);
context->max_monitors = MAX_NODE_MONITORS; context->max_monitors = MAX_NODE_MONITORS;