Added dup_foreign_fd() to duplicate a FD from another team.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29468 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-03-11 00:57:17 +00:00
parent b876eba2f9
commit b538ceb816
2 changed files with 42 additions and 1 deletions

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@ -85,6 +85,7 @@ extern status_t close_fd_index(struct io_context *context, int fd);
extern void put_fd(struct file_descriptor *descriptor);
extern void disconnect_fd(struct file_descriptor *descriptor);
extern void inc_fd_ref_count(struct file_descriptor *descriptor);
extern int dup_foreign_fd(team_id fromTeam, int fd, bool kernel);
extern status_t select_fd(int32 fd, struct select_info *info, bool kernel);
extern status_t deselect_fd(int32 fd, struct select_info *info, bool kernel);
extern bool fd_is_valid(int fd, bool kernel);

View File

@ -449,6 +449,46 @@ dup2_fd(int oldfd, int newfd, bool kernel)
}
/*! Duplicates an FD from another team to this/the kernel team.
\param fromTeam The team which owns the FD.
\param fd The FD to duplicate.
\param kernel If \c true, the new FD will be created in the kernel team,
the current userland team otherwise.
\return The newly created FD or an error code, if something went wrong.
*/
int
dup_foreign_fd(team_id fromTeam, int fd, bool kernel)
{
// get the I/O context for the team in question
InterruptsSpinLocker teamsLocker(gTeamSpinlock);
struct team* team = team_get_team_struct_locked(fromTeam);
if (team == NULL)
return B_BAD_TEAM_ID;
io_context* fromContext = team->io_context;
vfs_get_io_context(fromContext);
teamsLocker.Unlock();
CObjectDeleter<io_context> _(fromContext, vfs_put_io_context);
// get the file descriptor
file_descriptor* descriptor = get_fd(fromContext, fd);
if (descriptor == NULL)
return B_FILE_ERROR;
CObjectDeleter<file_descriptor> descriptorPutter(descriptor, put_fd);
// create a new FD in the target I/O context
int result = new_fd(get_current_io_context(kernel), descriptor);
if (result >= 0) {
// the descriptor reference belongs to the slot, now
descriptorPutter.Detach();
}
return result;
}
static status_t
fd_ioctl(bool kernelFD, int fd, ulong op, void *buffer, size_t length)
{