memset(&newf->open_fds->fds_bits[start], 0, left); memset(&newf->close_on_exec->fds_bits[start], 0, left); 
memset(&new_fdt->open_fds->fds_bits[start], 0, left); memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); 
static int copy_files(unsigned long clone_flags, struct task_struct * tsk){	struct files_struct *oldf, *newf;	struct file **old_fds, **new_fds;	int open_files, size, i, error = 0, expand;	/*	 * A background process may not have any files ...	 */	oldf = current->files;	if (!oldf)		goto out;	if (clone_flags & CLONE_FILES) {		atomic_inc(&oldf->count);		goto out;	}	/*	 * Note: we may be using current for both targets (See exec.c)	 * This works because we cache current->files (old) as oldf. Don't	 * break this.	 */	tsk->files = NULL;	error = -ENOMEM;	newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL);	if (!newf) 		goto out;	atomic_set(&newf->count, 1);	spin_lock_init(&newf->file_lock);	newf->next_fd	    = 0;	newf->max_fds	    = NR_OPEN_DEFAULT;	newf->max_fdset	    = __FD_SETSIZE;	newf->close_on_exec = &newf->close_on_exec_init;	newf->open_fds	    = &newf->open_fds_init;	newf->fd	    = &newf->fd_array[0];	spin_lock(&oldf->file_lock);	open_files = count_open_files(oldf, oldf->max_fdset);	expand = 0;	/*	 * Check whether we need to allocate a larger fd array or fd set.	 * Note: we're not a clone task, so the open count won't  change.	 */	if (open_files > newf->max_fdset) {		newf->max_fdset = 0;		expand = 1;	}	if (open_files > newf->max_fds) {		newf->max_fds = 0;		expand = 1;	}	/* if the old fdset gets grown now, we'll only copy up to "size" fds */	if (expand) {		spin_unlock(&oldf->file_lock);		spin_lock(&newf->file_lock);		error = expand_files(newf, open_files-1);		spin_unlock(&newf->file_lock);		if (error < 0)			goto out_release;		spin_lock(&oldf->file_lock);	}	old_fds = oldf->fd;	new_fds = newf->fd;	memcpy(newf->open_fds->fds_bits, oldf->open_fds->fds_bits, open_files/8);	memcpy(newf->close_on_exec->fds_bits, oldf->close_on_exec->fds_bits, open_files/8);	for (i = open_files; i != 0; i--) {		struct file *f = *old_fds++;		if (f) {			get_file(f);		} else {			/*			 * The fd may be claimed in the fd bitmap but not yet			 * instantiated in the files array if a sibling thread			 * is partway through open().  So make sure that this			 * fd is available to the new process.			 */			FD_CLR(open_files - i, newf->open_fds);		}		*new_fds++ = f;	}	spin_unlock(&oldf->file_lock);	/* compute the remainder to be cleared */	size = (newf->max_fds - open_files) * sizeof(struct file *);	/* This is long word aligned thus could use a optimized version */ 	memset(new_fds, 0, size); 	if (newf->max_fdset > open_files) {		int left = (newf->max_fdset-open_files)/8;		int start = open_files / (8 * sizeof(unsigned long));		memset(&newf->open_fds->fds_bits[start], 0, left);		memset(&newf->close_on_exec->fds_bits[start], 0, left);	}	tsk->files = newf;	error = 0;out:	return error;out_release:	free_fdset (newf->close_on_exec, newf->max_fdset);	free_fdset (newf->open_fds, newf->max_fdset);	free_fd_array(newf->fd, newf->max_fds);	kmem_cache_free(files_cachep, newf);	goto out;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/badf16621c1f9d1ac753be056fce11b43d6e0be5/fork.c/buggy/kernel/fork.c