1.5 Die Systemrufe open und close

/* Ausschnitte aus Datei /usr/src/linux/fs/open.c, Kernel 2.2.5*/
struct file *filp_open(const char * filename, int flags, int mode)
{
	struct inode * inode;
	struct dentry * dentry;
	struct file * f;
	int flag,error;

	error = -ENFILE;
	f = get_empty_filp();                           /*neuer Filepointer*/
	if (!f)
		goto out;
	f->f_flags = flag = flags;                      /*Flags setzen*/
	f->f_mode = (flag+1) & O_ACCMODE;
	if (f->f_mode)
		flag++;
	if (flag & O_TRUNC)
		flag |= 2;
	dentry = open_namei(filename,flag,mode);        /*voller
							Verzeichnispfad*/
	error = PTR_ERR(dentry);
	if (IS_ERR(dentry))
		goto cleanup_file;
	inode = dentry->d_inode;                        /*Inode ermitteln*/
	if (f->f_mode & FMODE_WRITE) {                  /*Zugriffsrechte ?*/
		error = get_write_access(inode);
		if (error)
			goto cleanup_dentry;
	}

	f->f_dentry = dentry;                           /*File-Struktur
							  Inhalt setzen*/
	f->f_pos = 0;
	f->f_reada = 0;
	f->f_op = NULL;                                 /*File-Operationen*/
	if (inode->i_op)
		f->f_op = inode->i_op->default_file_ops;
	if (f->f_op && f->f_op->open) {
		error = f->f_op->open(inode,f);
		if (error)
			goto cleanup_all;
	}
	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);

	return f;                               /*File-Pointer zurückgeben*/

cleanup_all:
	if (f->f_mode & FMODE_WRITE)
		put_write_access(inode);
cleanup_dentry:
	f->f_dentry = NULL;
	dput(dentry);
cleanup_file:
	put_filp(f);
out:
	return ERR_PTR(error);                  /*Fehler zurückgeben*/
}

asmlinkage int sys_open(const char * filename, int flags, int mode)
{
	char * tmp;
	int fd, error;

	tmp = getname(filename);                /*kopiert filename in den
						  kernel data space */
	fd = PTR_ERR(tmp);
	if (!IS_ERR(tmp)) {
		lock_kernel();                  /*lock verhindert, daß
						  andere Zugriff haben*/
		fd = get_unused_fd();           /*neuer
						File-Deskriptor(Nr.)*/
		if (fd >= 0) {
			struct file * f = filp_open(tmp, flags, mode);
			error = PTR_ERR(f);
			if (IS_ERR(f))
				goto out_error;
			fd_install(fd, f);      /*File-Pointer der
						  File-Nummer zuordnen*/
		}
out:
		unlock_kernel();
		putname(tmp);
	}
	return fd;

out_error:
	put_unused_fd(fd);                      /*fd wird nicht mehr
						  gebraucht*/
	fd = error;                             /*Fehler zurück*/
	goto out;
}

 asmlinkage int sys_close(unsigned int fd)
{
	int error;
	struct file * filp;

	lock_kernel();
	error = -EBADF;                                 
	filp = fcheck(fd);				/*Filepointer holen*/
	if (filp) {
		struct files_struct * files = current->files;
		files->fd[fd] = NULL;
		put_unused_fd(fd);                      /*Filenummer freigeben*/
		FD_CLR(fd, &files->close_on_exec);
		error = filp_close(filp, files);
	}
	unlock_kernel();
	return error;
}

int filp_close(struct file *filp, fl_owner_t id)
{
	int retval;
	struct dentry *dentry = filp->f_dentry;

	if (filp->f_count == 0) {
		printk("VFS: Close: file count is 0\n");
		return 0;                               /*Dateigröße Null*/
	}
	retval = 0;
	if (filp->f_op && filp->f_op->flush)
		retval = filp->f_op->flush(filp);       /*Dateipuffer leeren*/
	if (dentry->d_inode)
		locks_remove_posix(filp, id);
	fput(filp);                                     /*Pointer freigeben*/
	return retval;
}

    

Zurück Weiter Inhalt