コード例 #1
0
std::shared_ptr<file_ownership_handle> file_handle_pool::register_file(const std::string& file_name) {
  std::lock_guard<std::mutex> guard(this->m_mutex);
  std::shared_ptr<file_ownership_handle> ret = get_file_handle(file_name);

  if (!ret) {
    logstream(LOG_DEBUG) << "register_file_handle for file " << sanitize_url(file_name) << std::endl;

    
    ret = std::make_shared<file_ownership_handle>(file_name, boost::algorithm::starts_with(file_name, "cache://"));
    m_file_handles[file_name] = ret;
  }

  /**  This seems to be the safest way to do this.  Ideally, we would
   *   like file_ownership_handle to take care of this.  However, it
   *   is not certain that the pool will be around when that object is
   *   destroyed, so that brings up a number of possible rare corner
   *   cases to check for.  Doing this is simplest for now. 
   */
  if( (++this->num_file_registers) % (16*1024) == 0) {
    for(auto it = m_file_handles.begin(); it != m_file_handles.end();) {
      if(it->second.expired()) {
        // Advances to the next element, or m_file_handles.end(); 
        it = m_file_handles.erase(it);
      } else {
        ++it;
      }
    }
  }

  return ret;
}
コード例 #2
0
ファイル: file.c プロジェクト: imgits/seaos-kernel
struct file *get_file_pointer(task_t *t, int n)
{
	struct file_ptr *fp = get_file_handle(t, n);
	if(fp && !fp->fi)
		panic(PANIC_NOSYNC, "found empty file handle in task %d pointer list", t->pid);
	return fp ? fp->fi : 0;
}
コード例 #3
0
ファイル: sd.cpp プロジェクト: KoljaWindeler/speedoino
int8_t sd::append_string(uint8_t* filename,uint8_t* buffer){
	FIL write_file;
	get_file_handle(filename,&write_file,FA_OPEN_ALWAYS | FA_WRITE | FA_READ);	// open and create if not existing
	f_lseek(&write_file,write_file.fsize);										// append -> jump to end
	int8_t status=writeString(&write_file,buffer);								// write the string
	f_close(&write_file);														// close the file
	return status;
}
コード例 #4
0
ファイル: file.c プロジェクト: imgits/seaos-kernel
void remove_file_pointer(task_t *t, int n)
{
	if(n > FILP_HASH_LEN) return;
	if(!t || !t->filp)
		return;
	struct file_ptr *f = get_file_handle(t, n);
	if(!f)
		return;
	t->filp[n] = 0;
	task_critical();
	f->fi->count--;
	task_uncritical();
	if(!f->fi->count)
		kfree(f->fi);
	kfree(f);
}
コード例 #5
0
bool file_handle_pool::mark_file_for_delete(std::string file_name) {
  Dlog_func_entry();

  // file is not registered with global pool, let caller
  // do the actual deletion
  std::lock_guard<std::mutex> guard(this->m_mutex);

  std::shared_ptr<file_ownership_handle> handle_ptr = get_file_handle(file_name);
  if (!handle_ptr) {
    return false;
  } else {
    // Mark the file for deletion and the file will be deleted when going out-of-scope
    logstream(LOG_DEBUG) << "mark file " << file_name << " for deletion " << std::endl;
    handle_ptr->delete_on_destruction();
    return true;
  }
}
コード例 #6
0
ファイル: sd.cpp プロジェクト: KoljaWindeler/speedoino
int16_t sd::get_line_n(int16_t line_nr,uint8_t* filename,uint8_t* buffer,uint16_t max_length, uint16_t* lines_in_file){
	FIL read_file;

	if(get_file_handle(filename,&read_file,FA_READ)<0){
		sd_failed=true;
		return -1;
	}

	bool found=false;
	bool eof=false;
	int16_t cur_line=0;
	int16_t buf_pointer=0;
	uint8_t char_buf[1]={0x00};
	////////// suche den anfang der richtigen zeile
	while(!found && !eof){									// solange suchen bis wir entweder den Datensatz oder das ende haben
		UINT n;
		f_read(&read_file,char_buf, 1,&n);					// jeweils nur 1 uint8_t lesen
		if(n==1){											// true, if not end of file
			if(char_buf[0]==0x0A){							// find end of line
				if(buf_pointer<max_length) buffer[buf_pointer]=0x00;	// if end reach, terminate string
				buf_pointer=0;								// reset buf write pointer
				if(cur_line==line_nr){						// if we have "our" line
					found=true;								// we found the right line
				};
				cur_line++;									// increase number of read lines
			} else {										// its not \n
				buffer[buf_pointer]=char_buf[0];			// so store it in the buffer
				if(buf_pointer<max_length) buf_pointer++;	// and increase the pointer until max
			};
		} else {							// if we were unable to read one further uint8_t
			eof=true;						// we have reached the eof before reading the target line
		};
	}
	f_close(&read_file);
	*lines_in_file=cur_line-1;

	if(eof){
		return -2;
	}
	return 0;
}
コード例 #7
0
ファイル: export.c プロジェクト: AndreRH/wine
int reg_export(int argc, WCHAR *argv[])
{
    HKEY root, hkey;
    WCHAR *path, *long_key;
    BOOL overwrite_file = FALSE;
    HANDLE hFile;
    int ret;

    if (argc == 3 || argc > 5)
        goto error;

    if (!parse_registry_key(argv[2], &root, &path, &long_key))
        return 1;

    if (argc == 5 && !(overwrite_file = is_overwrite_switch(argv[4])))
        goto error;

    if (RegOpenKeyExW(root, path, 0, KEY_READ, &hkey))
    {
        output_message(STRING_INVALID_KEY);
        return 1;
    }

    hFile = get_file_handle(argv[3], overwrite_file);
    export_file_header(hFile);
    ret = export_registry_data(hFile, hkey, long_key);
    export_newline(hFile);
    CloseHandle(hFile);

    RegCloseKey(hkey);

    return ret;

error:
    output_message(STRING_INVALID_SYNTAX);
    output_message(STRING_FUNC_HELP, struprW(argv[1]));
    return 1;
}
コード例 #8
0
ファイル: sd.cpp プロジェクト: KoljaWindeler/speedoino
int sd::get_file_handle(unsigned char *pathToFile,FIL *file_handle,uint8_t flags){
	unsigned char last_filename_buffer[strlen((char*)pathToFile)];
	return get_file_handle(pathToFile,last_filename_buffer,file_handle,flags);
}
コード例 #9
0
/**
 * main_enc_dec
 * @f: pointer to struct which contains information about input,temporary and output files
 * @user_args: pointer to struct user_args_t which contains arguments given by user in user-space
 *
 * Initiates basic validation checks to be performed before starting encryption/decryption. Gets the required file handles. Post encryption
 * or decryption, renames and unlinks the file as required.
 *
 * Returns 0 on success;non-zero otherwise
 */
int main_enc_dec(struct file_struct *f, struct user_args_t *user_args)
{
	int err, tmp_err;

	char *key_hash;
	struct dentry *lower_old_dentry;
	struct dentry *lower_new_dentry;
	struct dentry *lower_old_dir_dentry;
	struct dentry *lower_new_dir_dentry;
	struct dentry *trap = NULL;

	err = validate_in_out_file(f);
	f->filp_in = f->filp_out = f->filp_temp = NULL;
	if (err) {
		printk(KERN_ALERT"error in validate in out");
		goto ERR;
	}

	key_hash = get_key_hash(user_args->enc_key);
	if (IS_ERR(key_hash)) {
		err = PTR_ERR(key_hash);
		goto ERR;
	}

	err = get_file_handle(&(f->filp_in), f->in_file->name, O_RDONLY, 0);
	if (err)
		goto ERR_KEY;

	if (!(f->filp_in->f_op->read)) {
		printk(KERN_ALERT"read operation not supported\n");
		err = -EPERM;
		goto ERR_IN;
	}

	printk(KERN_ALERT"read file permission\n");

	if (f->create_out_file == 'y') {
		printk(KERN_ALERT"file with default permission\n");
		err = get_file_handle(&(f->filp_temp), "/tmp/my_temp_file", O_WRONLY|O_CREAT|O_TRUNC, 0666-current_umask());
	} else {
		printk(KERN_ALERT"creating file with outfile mode\n");
		err = get_file_handle(&(f->filp_temp), "/tmp/my_temp_file", O_WRONLY|O_CREAT|O_TRUNC, f->out_file_mode);
	}

	if (err)
		goto ERR_IN;

	printk(KERN_ALERT"file permission for temp file=\n");
	printk(KERN_ALERT"\n");

	if (user_args->flags == 1)
		err = encrypt(f, &key_hash[0], user_args);
	else
		err = decrypt(f, &key_hash[0], user_args);


	if (err) {
		tmp_err = err;
		err = vfs_unlink(d_inode(f->filp_temp->f_path.dentry->d_parent), f->filp_temp->f_path.dentry, NULL);
		if (err)
			printk(KERN_ALERT"Error in unlink\n");
		err = tmp_err;
		goto ERR_IN;
	}
	printk(KERN_ALERT"enc/dec done so now doing a rename\n");

	if (f->create_out_file == 'y')
		err = get_file_handle(&(f->filp_out), f->out_file->name, O_WRONLY|O_CREAT|O_TRUNC, 0666-current_umask());
	else
		err = get_file_handle(&(f->filp_out), f->out_file->name, O_WRONLY, 0);

	if (err)
		goto ERR_OUT;

	if (!(f->filp_out->f_op->write)) {
		printk(KERN_ALERT"write operation not supported\n");
		err = -EPERM;
		goto ERR;
	}
	lower_old_dentry = f->filp_temp->f_path.dentry;
	lower_old_dir_dentry = dget_parent(lower_old_dentry);
	lower_new_dentry = f->filp_out->f_path.dentry;
	lower_new_dir_dentry = dget_parent(lower_new_dentry);

	trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);

	err = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry,
			d_inode(lower_new_dir_dentry), lower_new_dentry,
			NULL, 0);
	if (err) {
		printk(KERN_ALERT"error in rename\n");
		tmp_err = err;

		err = vfs_unlink(d_inode(f->filp_temp->f_path.dentry->d_parent), f->filp_temp->f_path.dentry, NULL);
		if (err)
			printk(KERN_ALERT"Error in unlink\n");

		if (f->create_out_file == 'y') {
			err = vfs_unlink(d_inode(f->filp_temp->f_path.dentry->d_parent), f->filp_temp->f_path.dentry, NULL);
			if (err)
				printk(KERN_ALERT"Error in unlink\n");
		}
		err = tmp_err;

	}
	printk(KERN_ALERT"rename done!\n");

	unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
	if (f->filp_temp)
		filp_close(f->filp_temp, NULL);

ERR_OUT:
	if (f->filp_out)
		filp_close(f->filp_out, NULL);
ERR_IN:
	if (f->filp_in)
		filp_close(f->filp_in, NULL);
ERR_KEY:
	kfree(key_hash);
ERR:
	return err;

}
コード例 #10
0
int sys_read(int fd, userptr_t buf, int len, int* retval)
{
	// argument checks.

	if(fd <0 || fd>= OPEN_MAX)
		return EBADF;
	
	int result;
	char kern_buffer[len + 1];

	// are we using this properly?.. check jinghao's blog for example
	// no actual use for the kern buffer, just doing this to check if memory location is valid.

	if(buf!= NULL)
	{
		result = copyin(buf, kern_buffer, len); // using this because users are stupid/malicious and can pass invalid memory addresses to the kernel.
	
		if(result)
		{
			kprintf("read copy in bad \n");
			return result;

		}
	}

	struct file_handle* fh = get_file_handle(curproc->t_file_table, fd);
	
	if(fh == NULL)
		return EBADF;

	if(!can_read(fh->openflags)) // could have other flags Or'd with O_RDONLY, need to change this.
		return EBADF;
	

// !!!! Should we do copyin's to kernel space, or will the VOP_WRITE take care of the invalid address issue for us.

	lock_acquire(fh->fh_lock); // IS this really necessary??.. turns out it is , offset should be synchronized. imagine if parent and child call this at the same time.
	struct iovec iov;
	struct uio u;

	iov.iov_ubase = (userptr_t)buf;
	iov.iov_len = len;		 // length of the memory space
	u.uio_iov = &iov;
	u.uio_iovcnt = 1;
	u.uio_resid = len;          // amount to read from the file
	u.uio_offset = fh->offset;
	u.uio_segflg =  UIO_USERSPACE;
	u.uio_rw = UIO_READ;
	u.uio_space = proc_getas(); // lifted from loadelf.c, is this the right way to do it?

	result = VOP_READ(fh->file, &u);
	if (result) {
		lock_release(fh->fh_lock);
		return result;
	}

	if (u.uio_resid != 0) {
//		kprintf("ELF: short read on segment - file truncated?\n");
	}

	// should update offset in the file handle.use lock. uio_offset will be updated. can use it directly.
	fh->offset = u.uio_offset;

	lock_release(fh->fh_lock);

	*retval = len - u.uio_resid; // number of bytes gets returned to the user
	return 0; 


}