Added an inode object to keep track of all file descriptors open for a
given file. Plugged a couple of potential file descriptor leaks.
This commit is contained in:
parent
ad068bc0c2
commit
580da246f5
233
server/fd.c
233
server/fd.c
|
@ -22,6 +22,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -29,6 +30,7 @@
|
|||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
@ -40,14 +42,25 @@
|
|||
#include "request.h"
|
||||
#include "console.h"
|
||||
|
||||
/* file descriptor object */
|
||||
|
||||
/* closed_fd is used to keep track of the unix fd belonging to a closed fd object */
|
||||
struct closed_fd
|
||||
{
|
||||
struct closed_fd *next; /* next fd in close list */
|
||||
int fd; /* the unix file descriptor */
|
||||
};
|
||||
|
||||
struct fd
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
const struct fd_ops *fd_ops; /* file descriptor operations */
|
||||
struct object *user; /* object using this file descriptor */
|
||||
int unix_fd; /* unix file descriptor */
|
||||
int poll_index; /* index of fd in poll array */
|
||||
int mode; /* file protection mode */
|
||||
struct object obj; /* object header */
|
||||
const struct fd_ops *fd_ops; /* file descriptor operations */
|
||||
struct inode *inode; /* inode that this fd belongs to */
|
||||
struct list inode_entry; /* entry in inode fd list */
|
||||
struct closed_fd *closed; /* structure to store the unix fd at destroy time */
|
||||
struct object *user; /* object using this file descriptor */
|
||||
int unix_fd; /* unix file descriptor */
|
||||
int poll_index; /* index of fd in poll array */
|
||||
};
|
||||
|
||||
static void fd_dump( struct object *obj, int verbose );
|
||||
|
@ -65,6 +78,42 @@ static const struct object_ops fd_ops =
|
|||
fd_destroy /* destroy */
|
||||
};
|
||||
|
||||
/* inode object */
|
||||
|
||||
struct inode
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
struct list entry; /* inode hash list entry */
|
||||
unsigned int hash; /* hashing code */
|
||||
dev_t dev; /* device number */
|
||||
ino_t ino; /* inode number */
|
||||
struct list open; /* list of open file descriptors */
|
||||
struct closed_fd *closed; /* list of file descriptors to close at destroy time */
|
||||
};
|
||||
|
||||
static void inode_dump( struct object *obj, int verbose );
|
||||
static void inode_destroy( struct object *obj );
|
||||
|
||||
static const struct object_ops inode_ops =
|
||||
{
|
||||
sizeof(struct inode), /* size */
|
||||
inode_dump, /* dump */
|
||||
no_add_queue, /* add_queue */
|
||||
NULL, /* remove_queue */
|
||||
NULL, /* signaled */
|
||||
NULL, /* satisfied */
|
||||
no_get_fd, /* get_fd */
|
||||
inode_destroy /* destroy */
|
||||
};
|
||||
|
||||
#define DUMP_LONG_LONG(val) do { \
|
||||
if (sizeof(val) > sizeof(unsigned long) && (val) > ~0UL) \
|
||||
fprintf( stderr, "%lx%08lx", (unsigned long)((val) >> 32), (unsigned long)(val) ); \
|
||||
else \
|
||||
fprintf( stderr, "%lx", (unsigned long)(val) ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* timeouts support */
|
||||
|
@ -311,21 +360,104 @@ void main_loop(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* inode functions */
|
||||
|
||||
#define HASH_SIZE 37
|
||||
|
||||
static struct list inode_hash[HASH_SIZE];
|
||||
|
||||
|
||||
static void inode_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct inode *inode = (struct inode *)obj;
|
||||
fprintf( stderr, "Inode dev=" );
|
||||
DUMP_LONG_LONG( inode->dev );
|
||||
fprintf( stderr, " ino=" );
|
||||
DUMP_LONG_LONG( inode->ino );
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
static void inode_destroy( struct object *obj )
|
||||
{
|
||||
struct inode *inode = (struct inode *)obj;
|
||||
|
||||
assert( !list_head(&inode->open) );
|
||||
|
||||
list_remove( &inode->entry );
|
||||
while (inode->closed)
|
||||
{
|
||||
struct closed_fd *fd = inode->closed;
|
||||
inode->closed = fd->next;
|
||||
close( fd->fd );
|
||||
free( fd );
|
||||
}
|
||||
}
|
||||
|
||||
/* retrieve the inode object for a given fd, creating it if needed */
|
||||
static struct inode *get_inode( dev_t dev, ino_t ino )
|
||||
{
|
||||
struct list *ptr;
|
||||
struct inode *inode;
|
||||
unsigned int hash = (dev ^ ino) % HASH_SIZE;
|
||||
|
||||
if (inode_hash[hash].next)
|
||||
{
|
||||
LIST_FOR_EACH( ptr, &inode_hash[hash] )
|
||||
{
|
||||
inode = LIST_ENTRY( ptr, struct inode, entry );
|
||||
if (inode->dev == dev && inode->ino == ino)
|
||||
return (struct inode *)grab_object( inode );
|
||||
}
|
||||
}
|
||||
else list_init( &inode_hash[hash] );
|
||||
|
||||
/* not found, create it */
|
||||
if ((inode = alloc_object( &inode_ops )))
|
||||
{
|
||||
inode->hash = hash;
|
||||
inode->dev = dev;
|
||||
inode->ino = ino;
|
||||
inode->closed = NULL;
|
||||
list_init( &inode->open );
|
||||
list_add_head( &inode_hash[hash], &inode->entry );
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
|
||||
/* add fd to the indoe list of file descriptors to close */
|
||||
static void inode_add_closed_fd( struct inode *inode, struct closed_fd *fd )
|
||||
{
|
||||
fd->next = inode->closed;
|
||||
inode->closed = fd;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* file descriptor functions */
|
||||
|
||||
static void fd_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct fd *fd = (struct fd *)obj;
|
||||
fprintf( stderr, "Fd unix_fd=%d mode=%06o user=%p\n", fd->unix_fd, fd->mode, fd->user );
|
||||
fprintf( stderr, "Fd unix_fd=%d user=%p\n", fd->unix_fd, fd->user );
|
||||
}
|
||||
|
||||
static void fd_destroy( struct object *obj )
|
||||
{
|
||||
struct fd *fd = (struct fd *)obj;
|
||||
|
||||
list_remove( &fd->inode_entry );
|
||||
if (fd->poll_index != -1) remove_poll_user( fd, fd->poll_index );
|
||||
close( fd->unix_fd );
|
||||
if (fd->inode)
|
||||
{
|
||||
inode_add_closed_fd( fd->inode, fd->closed );
|
||||
release_object( fd->inode );
|
||||
}
|
||||
else /* no inode, close it right away */
|
||||
{
|
||||
if (fd->unix_fd != -1) close( fd->unix_fd );
|
||||
}
|
||||
}
|
||||
|
||||
/* set the events that select waits for on this fd */
|
||||
|
@ -346,24 +478,22 @@ void set_fd_events( struct fd *fd, int events )
|
|||
}
|
||||
}
|
||||
|
||||
/* allocate an fd object */
|
||||
/* if the function fails the unix fd is closed */
|
||||
struct fd *alloc_fd( const struct fd_ops *fd_user_ops, int unix_fd, struct object *user )
|
||||
/* allocate an fd object, without setting the unix fd yet */
|
||||
struct fd *alloc_fd( const struct fd_ops *fd_user_ops, struct object *user )
|
||||
{
|
||||
struct fd *fd = alloc_object( &fd_ops );
|
||||
|
||||
if (!fd)
|
||||
{
|
||||
close( unix_fd );
|
||||
return NULL;
|
||||
}
|
||||
if (!fd) return NULL;
|
||||
|
||||
fd->fd_ops = fd_user_ops;
|
||||
fd->user = user;
|
||||
fd->unix_fd = unix_fd;
|
||||
fd->inode = NULL;
|
||||
fd->closed = NULL;
|
||||
fd->unix_fd = -1;
|
||||
fd->poll_index = -1;
|
||||
fd->mode = 0;
|
||||
list_init( &fd->inode_entry );
|
||||
|
||||
if ((unix_fd != -1) && ((fd->poll_index = add_poll_user( fd )) == -1))
|
||||
if ((fd->poll_index = add_poll_user( fd )) == -1)
|
||||
{
|
||||
release_object( fd );
|
||||
return NULL;
|
||||
|
@ -371,6 +501,71 @@ struct fd *alloc_fd( const struct fd_ops *fd_user_ops, int unix_fd, struct objec
|
|||
return fd;
|
||||
}
|
||||
|
||||
/* open() wrapper using a struct fd */
|
||||
/* the fd must have been created with alloc_fd */
|
||||
/* on error the fd object is released */
|
||||
struct fd *open_fd( struct fd *fd, const char *name, int flags, int *mode )
|
||||
{
|
||||
struct stat st;
|
||||
struct closed_fd *closed_fd;
|
||||
|
||||
assert( fd->unix_fd == -1 );
|
||||
|
||||
if (!(closed_fd = mem_alloc( sizeof(*closed_fd) )))
|
||||
{
|
||||
release_object( fd );
|
||||
return NULL;
|
||||
}
|
||||
if ((fd->unix_fd = open( name, flags, *mode )) == -1)
|
||||
{
|
||||
file_set_error();
|
||||
release_object( fd );
|
||||
free( closed_fd );
|
||||
return NULL;
|
||||
}
|
||||
closed_fd->fd = fd->unix_fd;
|
||||
fstat( fd->unix_fd, &st );
|
||||
*mode = st.st_mode;
|
||||
|
||||
if (S_ISREG(st.st_mode)) /* only bother with an inode for normal files */
|
||||
{
|
||||
struct inode *inode = get_inode( st.st_dev, st.st_ino );
|
||||
|
||||
if (!inode)
|
||||
{
|
||||
/* we can close the fd because there are no others open on the same file,
|
||||
* otherwise we wouldn't have failed to allocate a new inode
|
||||
*/
|
||||
release_object( fd );
|
||||
free( closed_fd );
|
||||
return NULL;
|
||||
}
|
||||
fd->inode = inode;
|
||||
fd->closed = closed_fd;
|
||||
list_add_head( &inode->open, &fd->inode_entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
free( closed_fd );
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* create an fd for an anonymous file */
|
||||
/* if the function fails the unix fd is closed */
|
||||
struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops, int unix_fd, struct object *user )
|
||||
{
|
||||
struct fd *fd = alloc_fd( fd_user_ops, user );
|
||||
|
||||
if (fd)
|
||||
{
|
||||
fd->unix_fd = unix_fd;
|
||||
return fd;
|
||||
}
|
||||
close( unix_fd );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* retrieve the object that is using an fd */
|
||||
void *get_fd_user( struct fd *fd )
|
||||
{
|
||||
|
|
|
@ -149,7 +149,7 @@ static struct file *create_file_for_fd( int fd, unsigned int access, unsigned in
|
|||
init_async_queue (&file->read_q);
|
||||
init_async_queue (&file->write_q);
|
||||
}
|
||||
if (!(file->fd = alloc_fd( &file_fd_ops, fd, &file->obj )))
|
||||
if (!(file->fd = create_anonymous_fd( &file_fd_ops, fd, &file->obj )))
|
||||
{
|
||||
release_object( file );
|
||||
return NULL;
|
||||
|
@ -165,9 +165,7 @@ static struct file *create_file( const char *nameptr, size_t len, unsigned int a
|
|||
{
|
||||
struct file *file;
|
||||
int hash, flags;
|
||||
struct stat st;
|
||||
char *name;
|
||||
int fd = -1;
|
||||
mode_t mode;
|
||||
|
||||
if (!(name = mem_alloc( len + 1 ))) return NULL;
|
||||
|
@ -200,31 +198,38 @@ static struct file *create_file( const char *nameptr, size_t len, unsigned int a
|
|||
(!strcasecmp( name + len - 4, ".exe" ) || !strcasecmp( name + len - 4, ".com" )))
|
||||
mode |= 0111;
|
||||
|
||||
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
|
||||
if ((fd = open( name, flags | O_NONBLOCK | O_LARGEFILE, mode )) == -1 )
|
||||
goto file_error;
|
||||
/* refuse to open a directory */
|
||||
if (fstat( fd, &st ) == -1) goto file_error;
|
||||
if (S_ISDIR(st.st_mode))
|
||||
if (!(file = alloc_object( &file_ops ))) goto error;
|
||||
|
||||
file->access = access;
|
||||
file->flags = attrs;
|
||||
file->sharing = sharing;
|
||||
file->drive_type = drive_type;
|
||||
file->name = name;
|
||||
file->next = file_hash[hash];
|
||||
file_hash[hash] = file;
|
||||
if (file->flags & FILE_FLAG_OVERLAPPED)
|
||||
{
|
||||
set_error( STATUS_ACCESS_DENIED );
|
||||
goto error;
|
||||
init_async_queue (&file->read_q);
|
||||
init_async_queue (&file->write_q);
|
||||
}
|
||||
|
||||
if (!(file = create_file_for_fd( fd, access, sharing, attrs, drive_type )))
|
||||
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
|
||||
if (!(file->fd = alloc_fd( &file_fd_ops, &file->obj )) ||
|
||||
!(file->fd = open_fd( file->fd, name, flags | O_NONBLOCK | O_LARGEFILE, &mode )))
|
||||
{
|
||||
free( name );
|
||||
release_object( file );
|
||||
return NULL;
|
||||
}
|
||||
/* refuse to open a directory */
|
||||
if (S_ISDIR(mode))
|
||||
{
|
||||
set_error( STATUS_ACCESS_DENIED );
|
||||
release_object( file );
|
||||
return NULL;
|
||||
}
|
||||
file->name = name;
|
||||
file->next = file_hash[hash];
|
||||
file_hash[hash] = file;
|
||||
return file;
|
||||
|
||||
file_error:
|
||||
file_set_error();
|
||||
error:
|
||||
if (fd != -1) close( fd );
|
||||
free( name );
|
||||
return NULL;
|
||||
}
|
||||
|
@ -241,29 +246,20 @@ int get_file_drive_type( struct file *file )
|
|||
return file->drive_type;
|
||||
}
|
||||
|
||||
/* Create an anonymous Unix file */
|
||||
int create_anonymous_file(void)
|
||||
/* create a temp file for anonymous mappings */
|
||||
struct file *create_temp_file( int access )
|
||||
{
|
||||
char tmpfn[21];
|
||||
char tmpfn[16];
|
||||
int fd;
|
||||
|
||||
sprintf(tmpfn,"/tmp/anonmap.XXXXXX");
|
||||
sprintf( tmpfn, "anonmap.XXXXXX" ); /* create it in the server directory */
|
||||
fd = mkstemp(tmpfn);
|
||||
if (fd == -1)
|
||||
{
|
||||
file_set_error();
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
unlink( tmpfn );
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Create a temp file for anonymous mappings */
|
||||
struct file *create_temp_file( int access )
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = create_anonymous_file()) == -1) return NULL;
|
||||
return create_file_for_fd( fd, access, 0, 0, DRIVE_FIXED );
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,10 @@ struct fd_ops
|
|||
|
||||
/* file descriptor functions */
|
||||
|
||||
extern struct fd *alloc_fd( const struct fd_ops *fd_ops, int unix_fd, struct object *user );
|
||||
extern struct fd *alloc_fd( const struct fd_ops *fd_user_ops, struct object *user );
|
||||
extern struct fd *open_fd( struct fd *fd, const char *name, int flags, int *mode );
|
||||
extern struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops,
|
||||
int unix_fd, struct object *user );
|
||||
extern void *get_fd_user( struct fd *fd );
|
||||
extern int get_unix_fd( struct fd *fd );
|
||||
extern void fd_poll_event( struct fd *fd, int event );
|
||||
|
@ -85,7 +88,6 @@ extern int get_file_unix_fd( struct file *file );
|
|||
extern int is_same_file( struct file *file1, struct file *file2 );
|
||||
extern int get_file_drive_type( struct file *file );
|
||||
extern int grow_file( struct file *file, int size_high, int size_low );
|
||||
extern int create_anonymous_file(void);
|
||||
extern struct file *create_temp_file( int access );
|
||||
extern void file_set_error(void);
|
||||
|
||||
|
|
|
@ -361,8 +361,8 @@ DECL_HANDLER(open_named_pipe)
|
|||
|
||||
if(!socketpair(PF_UNIX, SOCK_STREAM, 0, fds))
|
||||
{
|
||||
user->fd = alloc_fd( &pipe_user_fd_ops, fds[1], &user->obj );
|
||||
partner->fd = alloc_fd( &pipe_user_fd_ops, fds[0], &partner->obj );
|
||||
user->fd = create_anonymous_fd( &pipe_user_fd_ops, fds[1], &user->obj );
|
||||
partner->fd = create_anonymous_fd( &pipe_user_fd_ops, fds[0], &partner->obj );
|
||||
if (user->fd && partner->fd)
|
||||
{
|
||||
notify_waiter(partner,STATUS_SUCCESS);
|
||||
|
|
|
@ -85,7 +85,7 @@ static struct pipe *create_pipe_side( int fd, int side )
|
|||
pipe->other = NULL;
|
||||
pipe->side = side;
|
||||
}
|
||||
if (!(pipe->fd = alloc_fd( &pipe_fd_ops, fd, &pipe->obj )))
|
||||
if (!(pipe->fd = create_anonymous_fd( &pipe_fd_ops, fd, &pipe->obj )))
|
||||
{
|
||||
release_object( pipe );
|
||||
return NULL;
|
||||
|
|
|
@ -302,7 +302,7 @@ struct thread *create_process( int fd )
|
|||
first_process = process;
|
||||
|
||||
if (!(process->id = alloc_ptid( process ))) goto error;
|
||||
if (!(process->msg_fd = alloc_fd( &process_fd_ops, fd, &process->obj ))) goto error;
|
||||
if (!(process->msg_fd = create_anonymous_fd( &process_fd_ops, fd, &process->obj ))) goto error;
|
||||
|
||||
/* create the main thread */
|
||||
if (pipe( request_pipe ) == -1)
|
||||
|
|
|
@ -696,7 +696,7 @@ static void acquire_lock(void)
|
|||
if (listen( fd, 5 ) == -1) fatal_perror( "listen" );
|
||||
|
||||
if (!(master_socket = alloc_object( &master_socket_ops )) ||
|
||||
!(master_socket->fd = alloc_fd( &master_socket_fd_ops, fd, &master_socket->obj )))
|
||||
!(master_socket->fd = create_anonymous_fd( &master_socket_fd_ops, fd, &master_socket->obj )))
|
||||
fatal_error( "out of memory\n" );
|
||||
master_socket->timeout = NULL;
|
||||
set_fd_events( master_socket->fd, POLLIN );
|
||||
|
|
|
@ -150,25 +150,27 @@ static struct serial *create_serial( const char *nameptr, size_t len, unsigned i
|
|||
if(0>fcntl(fd, F_SETFL, 0))
|
||||
perror("fcntl");
|
||||
|
||||
if ((serial = alloc_object( &serial_ops )))
|
||||
if (!(serial = alloc_object( &serial_ops )))
|
||||
{
|
||||
serial->attrib = attributes;
|
||||
serial->access = access;
|
||||
serial->readinterval = 0;
|
||||
serial->readmult = 0;
|
||||
serial->readconst = 0;
|
||||
serial->writemult = 0;
|
||||
serial->writeconst = 0;
|
||||
serial->eventmask = 0;
|
||||
serial->commerror = 0;
|
||||
init_async_queue(&serial->read_q);
|
||||
init_async_queue(&serial->write_q);
|
||||
init_async_queue(&serial->wait_q);
|
||||
if (!(serial->fd = alloc_fd( &serial_fd_ops, fd, &serial->obj )))
|
||||
{
|
||||
release_object( serial );
|
||||
return NULL;
|
||||
}
|
||||
close( fd );
|
||||
return NULL;
|
||||
}
|
||||
serial->attrib = attributes;
|
||||
serial->access = access;
|
||||
serial->readinterval = 0;
|
||||
serial->readmult = 0;
|
||||
serial->readconst = 0;
|
||||
serial->writemult = 0;
|
||||
serial->writeconst = 0;
|
||||
serial->eventmask = 0;
|
||||
serial->commerror = 0;
|
||||
init_async_queue(&serial->read_q);
|
||||
init_async_queue(&serial->write_q);
|
||||
init_async_queue(&serial->wait_q);
|
||||
if (!(serial->fd = create_anonymous_fd( &serial_fd_ops, fd, &serial->obj )))
|
||||
{
|
||||
release_object( serial );
|
||||
return NULL;
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
|
|
27
server/smb.c
27
server/smb.c
|
@ -167,22 +167,21 @@ DECL_HANDLER(create_smb)
|
|||
return;
|
||||
}
|
||||
|
||||
smb = alloc_object( &smb_ops );
|
||||
if (smb)
|
||||
if (!(smb = alloc_object( &smb_ops )))
|
||||
{
|
||||
smb->tree_id = req->tree_id;
|
||||
smb->user_id = req->user_id;
|
||||
smb->dialect = req->dialect;
|
||||
smb->file_id = req->file_id;
|
||||
smb->offset = 0;
|
||||
if (!(smb->fd = alloc_fd( &smb_fd_ops, fd, &smb->obj )))
|
||||
{
|
||||
release_object( smb );
|
||||
return;
|
||||
}
|
||||
reply->handle = alloc_handle( current->process, smb, GENERIC_READ, 0);
|
||||
release_object( smb );
|
||||
close( fd );
|
||||
return;
|
||||
}
|
||||
smb->tree_id = req->tree_id;
|
||||
smb->user_id = req->user_id;
|
||||
smb->dialect = req->dialect;
|
||||
smb->file_id = req->file_id;
|
||||
smb->offset = 0;
|
||||
if ((smb->fd = create_anonymous_fd( &smb_fd_ops, fd, &smb->obj )))
|
||||
{
|
||||
reply->handle = alloc_handle( current->process, smb, GENERIC_READ, 0);
|
||||
}
|
||||
release_object( smb );
|
||||
}
|
||||
|
||||
DECL_HANDLER(get_smb_info)
|
||||
|
|
|
@ -616,7 +616,7 @@ static struct object *create_socket( int family, int type, int protocol, unsigne
|
|||
sock->message = 0;
|
||||
sock->wparam = 0;
|
||||
sock->deferred = NULL;
|
||||
if (!(sock->fd = alloc_fd( &sock_fd_ops, sockfd, &sock->obj )))
|
||||
if (!(sock->fd = create_anonymous_fd( &sock_fd_ops, sockfd, &sock->obj )))
|
||||
{
|
||||
release_object( sock );
|
||||
return NULL;
|
||||
|
@ -686,7 +686,7 @@ static struct sock *accept_socket( obj_handle_t handle )
|
|||
if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
|
||||
acceptsock->flags = sock->flags;
|
||||
acceptsock->deferred = 0;
|
||||
if (!(acceptsock->fd = alloc_fd( &sock_fd_ops, acceptfd, &acceptsock->obj )))
|
||||
if (!(acceptsock->fd = create_anonymous_fd( &sock_fd_ops, acceptfd, &acceptsock->obj )))
|
||||
{
|
||||
release_object( acceptsock );
|
||||
release_object( sock );
|
||||
|
|
|
@ -170,7 +170,7 @@ struct thread *create_thread( int fd, struct process *process )
|
|||
release_object( thread );
|
||||
return NULL;
|
||||
}
|
||||
if (!(thread->request_fd = alloc_fd( &thread_fd_ops, fd, &thread->obj )))
|
||||
if (!(thread->request_fd = create_anonymous_fd( &thread_fd_ops, fd, &thread->obj )))
|
||||
{
|
||||
release_object( thread );
|
||||
return NULL;
|
||||
|
@ -840,8 +840,8 @@ DECL_HANDLER(init_thread)
|
|||
fatal_protocol_error( current, "bad wait fd\n" );
|
||||
goto error;
|
||||
}
|
||||
current->reply_fd = alloc_fd( &thread_fd_ops, reply_fd, ¤t->obj );
|
||||
current->wait_fd = alloc_fd( &thread_fd_ops, wait_fd, ¤t->obj );
|
||||
current->reply_fd = create_anonymous_fd( &thread_fd_ops, reply_fd, ¤t->obj );
|
||||
current->wait_fd = create_anonymous_fd( &thread_fd_ops, wait_fd, ¤t->obj );
|
||||
if (!current->reply_fd || !current->wait_fd) return;
|
||||
|
||||
current->unix_pid = req->unix_pid;
|
||||
|
|
Loading…
Reference in New Issue