67 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						|
#include "fs.h"
 | 
						|
#include "file.h"
 | 
						|
#include "fproc.h"
 | 
						|
 | 
						|
_PROTOTYPE( int gcov_flush, (cp_grant_id_t grantid, size_t size ));
 | 
						|
 | 
						|
/*===========================================================================*
 | 
						|
 *				do_gcov_flush				*
 | 
						|
 *===========================================================================*/
 | 
						|
PUBLIC int do_gcov_flush()
 | 
						|
{
 | 
						|
/* A userland tool has requested the gcov data from another
 | 
						|
 * process (possibly vfs itself). Grant the target process
 | 
						|
 * access to the supplied buffer, and perform the call that
 | 
						|
 * makes the target copy its buffer to the caller (incl vfs
 | 
						|
 * itself).
 | 
						|
 */
 | 
						|
  struct fproc *rfp;
 | 
						|
  ssize_t size;
 | 
						|
  cp_grant_id_t grantid;
 | 
						|
  int r, n;
 | 
						|
  pid_t target;
 | 
						|
  message m;
 | 
						|
 | 
						|
  size = m_in.GCOV_BUFF_SZ;
 | 
						|
  target = m_in.GCOV_PID;
 | 
						|
 | 
						|
  /* If the wrong process is sent to, the system hangs; so make this root-only.
 | 
						|
   */
 | 
						|
 | 
						|
  if (!super_user) return(EPERM);
 | 
						|
 | 
						|
  /* Find target gcov process. */
 | 
						|
  for(n = 0; n < NR_PROCS; n++) {
 | 
						|
	if(fproc[n].fp_endpoint != NONE && fproc[n].fp_pid == target)
 | 
						|
		 break;
 | 
						|
  }
 | 
						|
  if(n >= NR_PROCS) {
 | 
						|
	printf("VFS: gcov process %d not found\n", target);
 | 
						|
	return(ESRCH);
 | 
						|
  }
 | 
						|
  rfp = &fproc[n];
 | 
						|
 | 
						|
  /* Grant target process to requestor's buffer. */
 | 
						|
  if ((grantid = cpf_grant_magic(rfp->fp_endpoint, who_e,
 | 
						|
				 (vir_bytes) m_in.GCOV_BUFF_P, size,
 | 
						|
				 CPF_WRITE)) < 0) {
 | 
						|
	printf("VFS: gcov_flush: grant failed\n");
 | 
						|
	return(ENOMEM);
 | 
						|
  }
 | 
						|
 | 
						|
  if(rfp->fp_endpoint == VFS_PROC_NR) {
 | 
						|
	/* Request is for VFS itself. */
 | 
						|
	r = gcov_flush(grantid, size);
 | 
						|
  } else {
 | 
						|
	/* Perform generic GCOV request. */
 | 
						|
	m.GCOV_GRANT = grantid;
 | 
						|
	m.GCOV_BUFF_SZ = size;
 | 
						|
	r = _taskcall(rfp->fp_endpoint, COMMON_REQ_GCOV_DATA, &m);
 | 
						|
  }
 | 
						|
 | 
						|
  cpf_revoke(grantid);
 | 
						|
 | 
						|
  return(r);
 | 
						|
}
 |