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:
+56
-22
@@ -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 entry identified by the original path, and into the buffer \a filename
|
||||||
|
* the leaf name of the original entry is written.
|
||||||
|
* Neither the returned path nor the leaf name can be expected to be
|
||||||
|
* canonical.
|
||||||
|
*
|
||||||
|
* \param path The path to be analyzed. Must be able to store at least one
|
||||||
|
* additional character.
|
||||||
|
* \param filename The buffer into which the leaf name will be written.
|
||||||
|
* 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
|
||||||
|
* name is longer than \c B_FILE_NAME_LENGTH.
|
||||||
|
*/
|
||||||
|
|
||||||
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 leaf name of the original entry is written.
|
|
||||||
Neither the returned path nor the leaf name can be expected to be
|
|
||||||
canonical.
|
|
||||||
|
|
||||||
\param path The path to be analyzed. Must be able to store at least one
|
|
||||||
additional character.
|
|
||||||
\param filename The buffer into which the leaf name will be written.
|
|
||||||
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
|
|
||||||
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,10 +1125,11 @@ 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)
|
||||||
{
|
{
|
||||||
FUNCTION(("dir_vnode_to_path(%p, %p, %lu\n)", vnode, buffer, bufferSize));
|
FUNCTION(("dir_vnode_to_path(%p, %p, %lu\n)", vnode, buffer, bufferSize));
|
||||||
|
|
||||||
/* this implementation is currently bound to SYS_MAX_PATH_LEN */
|
/* this implementation is currently bound to SYS_MAX_PATH_LEN */
|
||||||
char path[SYS_MAX_PATH_LEN];
|
char path[SYS_MAX_PATH_LEN];
|
||||||
@@ -1256,7 +1258,7 @@ FUNCTION(("dir_vnode_to_path(%p, %p, %lu\n)", vnode, buffer, bufferSize));
|
|||||||
if (path[insert] == '\0')
|
if (path[insert] == '\0')
|
||||||
path[--insert] = '/';
|
path[--insert] = '/';
|
||||||
|
|
||||||
PRINT((" path is: %s\n", path + insert));
|
PRINT((" path is: %s\n", path + insert));
|
||||||
|
|
||||||
// copy the path to the output buffer
|
// copy the path to the output buffer
|
||||||
length = sizeof(path) - insert;
|
length = sizeof(path) - insert;
|
||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user