コード例 #1
0
ファイル: rstrunc.c プロジェクト: lwygitcat/Dynamic_Linker
/*------------------------------------------------------------------------
 * rstrunc - handle a truncate request
 *------------------------------------------------------------------------
 */
void	rstrunc (
	 struct	rf_msg_treq *reqptr,	/* ptr to read request		*/
	 struct	rf_msg_tres *resptr	/* ptr to read response		*/
	)
{
	int	fd;			/* file descriptor		*/
/* DEBUG */ printf("DEBUG: reached rstrunc\n");

	/* if file is open, close it */

	if (findex >= 0) {
		close(fptr->desc);
		fptr->desc = -1;
	}

	fd = open(reqptr->rf_name, O_TRUNC);
	if (fd < 0) {
		snderr( (struct rf_msg_hdr *)reqptr,
			(struct rf_msg_hdr *)resptr,
			 sizeof(struct rf_msg_tres) );
	} else {
		close(fd);
	}

	/* Return OK status */

	sndok ( (struct rf_msg_hdr *)reqptr,
		(struct rf_msg_hdr *)resptr,
		 sizeof(struct rf_msg_tres) );
	return;
}
コード例 #2
0
ファイル: rsdelete.c プロジェクト: lwygitcat/Dynamic_Linker
/*------------------------------------------------------------------------
 * rsdelete - handle a delete request
 *------------------------------------------------------------------------
 */
void	rsdelete (
	 struct	rf_msg_dreq *reqptr,	/* ptr to read request		*/
	 struct	rf_msg_dres *resptr	/* ptr to read response		*/
	)
{
	int	retval;			/* return value			*/
/*DEBUG*/ printf("DEBUG: reached rsdelete\n");

	/* if file is open, close it */

	if (findex >= 0) {
		close(fptr->desc);
		fptr->desc = -1;
	}

	retval = unlink(reqptr->rf_name);
	if (retval < 0) {
		snderr( (struct rf_msg_hdr *)reqptr,
			(struct rf_msg_hdr *)resptr,
			 sizeof(struct rf_msg_dres) );
			return;
	}

	/* Return OK status */

	sndok ( (struct rf_msg_hdr *)reqptr,
		(struct rf_msg_hdr *)resptr,
		 sizeof(struct rf_msg_sres) );
	return;
}
コード例 #3
0
ファイル: rsstat.c プロジェクト: pvanevery/school
/*------------------------------------------------------------------------
 * rsstat - handle a stat request
 *------------------------------------------------------------------------
 */
void	rsstat (
	 struct	rf_msg_sreq *reqptr,	/* ptr to read request		*/
	 struct	rf_msg_sres *resptr	/* ptr to read response		*/
	)
{
	struct	stat	stbuf;		/* buffer for file status	*/
	int	sreturn;		/* stat return value		*/

	sreturn = stat(reqptr->rf_name, &stbuf);

	if (sreturn < 0) {	/* file does not exist */
		resptr->rf_size = 0;
		snderr( (struct rf_msg_hdr *)reqptr,
			(struct rf_msg_hdr *)resptr,
			 sizeof(struct rf_msg_sres) );
		return;
	}

	/* Place the file size in the response message */

	resptr->rf_size = htonl(stbuf.st_size);

	/* Copy the header and send the response */

	sndok ( (struct rf_msg_hdr *)reqptr,
		(struct rf_msg_hdr *)resptr,
		 sizeof(struct rf_msg_sres) );
	return;
}
コード例 #4
0
ファイル: rsread.c プロジェクト: pvanevery/school
/*------------------------------------------------------------------------
 * rsread - handle a read request
 *------------------------------------------------------------------------
 */
void	rsread (
	 struct	rf_msg_rreq *reqptr,	/* ptr to read request		*/
	 struct	rf_msg_rres *resptr	/* ptr to read response		*/
	)
{
	int	fd;			/* file descriptor		*/
	int	i, j;			/* general loop indexes		*/
	struct	stat	buf;		/* buffer for file status	*/
	int	retval;			/* function return value	*/
	char	*to, *from;		/* used during copy		*/
	int	nbytes;			/* num. of bytes read from file	*/

	retval = stat(reqptr->rf_name, &buf);
	if(retval >= 0) {
		if(buf.st_mode & S_IFDIR) {
			rsdirread(reqptr, resptr);
			return;
		}
	}

	/* if file is not open, try to open it */

	if (findex < 0) {
		if ( (fd = rsofile(reqptr->rf_name,O_RDWR)) < 0 ) {
			resptr->rf_pos = reqptr->rf_pos;
			resptr->rf_len = 0; /* set length to zero */
			snderr( (struct rf_msg_hdr *)reqptr,
				(struct rf_msg_hdr *)resptr,
				sizeof(struct rf_msg_rreq) );
			return;
		}
		for (i=0; i<MAXFILES; i++) {

			/* If entry is free, stop searching */

			if (ofiles[i].desc < 0) {
				break;
			}
		}
		if (i >= MAXFILES) {	/* table is full */
			i = fnext;	/* choose entry to close */
			close(ofiles[fnext].desc);

			/* move to next slot for the future , wrap */
			/*	around the table, if necessary	   */

			fnext++;
			if (fnext >= MAXFILES) {
				fnext = 0;
			}
		}
		ofiles[i].desc = fd;
		from = reqptr->rf_name;
		to =ofiles[i].name;

		/* copy name to open file table */

		while ( (*to++ = *from++) ) {
			;
		}
	} else {
		fd = fptr->desc;
	}

	/* stat file to get its current size */

	retval = fstat(fd, &buf);

	/* if requested offset is beyond EOF, return error */

	if ( (retval<0) || (ntohl(reqptr->rf_pos) > buf.st_size) ) {
		resptr->rf_pos = reqptr->rf_pos;
		resptr->rf_len = 0;	 /* set length to zero */
		snderr( (struct rf_msg_hdr *)reqptr,
			(struct rf_msg_hdr *)resptr,
			sizeof(struct rf_msg_rreq) );
		return;
	}

	/* seek to specified offset and read data */

	lseek(fd, ntohl(reqptr->rf_pos), SEEK_SET);
	memset(resptr->rf_data, NULLCH, RF_DATALEN);
	nbytes = read(fd, resptr->rf_data, ntohl(reqptr->rf_len));

	if (nbytes < 0) {
		resptr->rf_pos = reqptr->rf_pos;
		resptr->rf_len = 0; /* set length to zero */
		snderr( (struct rf_msg_hdr *)reqptr,
			(struct rf_msg_hdr *)resptr,
			sizeof(struct rf_msg_rreq) );
		return;
	}

	/* set bytes read */
	
	resptr->rf_pos = reqptr->rf_pos;
	resptr->rf_len = htonl(nbytes);
	sndok(	(struct rf_msg_hdr *)reqptr,
		(struct rf_msg_hdr *)resptr,
		sizeof(struct rf_msg_rres) );
	return;
}
コード例 #5
0
ファイル: socket.c プロジェクト: ECE492W2014G4/G4Capstone
int
sosend(struct socket *so, 
       struct mbuf *nam,      /* sockaddr, if UDP socket, NULL if TCP */
       char  *data,           /* data to send */
       int   *data_length,    /* IN/OUT  length of (remaining) data */
       int   flags)
{
   struct mbuf *head = (struct mbuf *)NULL;
   struct mbuf *m;
   int   space;
   int   resid;
   int   len;
   int   error = 0;
   int   dontroute;
   int   first = 1;

   resid = *data_length;

   /*
    * In theory resid should be unsigned.
    * However, space must be signed, as it might be less than 0
    * if we over-committed, and we must use a signed comparison
    * of space and resid.  On the other hand, a negative resid
    * causes us to loop sending 0-length segments to the protocol.
    */
   if (resid < 0)
      return (EINVAL);

   INET_TRACE (INETM_IO, ("INET:sosend: so %lx resid %d sb_hiwat %d so_state %x\n",
               so, resid, so->so_snd.sb_hiwat, so->so_state));

   if (sosendallatonce(so) && (resid > (int)so->so_snd.sb_hiwat))
      return (EMSGSIZE);

   dontroute = (flags & MSG_DONTROUTE) &&
               ((so->so_options & SO_DONTROUTE) == 0) &&
               (so->so_proto->pr_flags & PR_ATOMIC);

#define     snderr(errno)     {  error =  errno;   goto  release; }

restart:
   sblock(&so->so_snd);
   do 
   {
      if (so->so_error) 
      {
         error = so->so_error;
         so->so_error = 0;          /* ??? */
         goto release;
      }
      if (so->so_state & SS_CANTSENDMORE)
         snderr(EPIPE);
      if ((so->so_state & SS_ISCONNECTED) == 0) 
      {
         if (so->so_proto->pr_flags & PR_CONNREQUIRED)
            snderr(ENOTCONN);
         if (nam == 0)
            snderr(EDESTADDRREQ);
      }
      if (flags & MSG_OOB)
         space = 1024;
      else 
      {
         space = (int)sbspace(&so->so_snd);
         if ((sosendallatonce(so) && (space < resid)) ||
             ((resid >= CLBYTES) && (space < CLBYTES) &&
              (so->so_snd.sb_cc >= CLBYTES) &&
              ((so->so_state & SS_NBIO) == 0) &&
              ((flags & MSG_DONTWAIT) == 0)))
         {
            if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT))
            {
               if (first)
                  error = EWOULDBLOCK;
               goto release;
            }
            sbunlock(&so->so_snd);
            sbwait(&so->so_snd);
            goto restart;
         }
      }
      if ( space <= 0 ) 
      {
         /* no space in socket send buffer - see if we can wait */
         if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT))
         {
            if (first)     /* report first error */
               error = EWOULDBLOCK;
            goto release;
         }
         /* If blocking socket, let someone else run */
         sbunlock(&so->so_snd);
         sbwait(&so->so_snd);
         goto restart;
      }

      while (space > 0) 
      {
         len = resid;
         if ( so->so_type == SOCK_STREAM )
         {
            m = m_getwithdata(MT_TXDATA, len);
            if (!m)   
               snderr(ENOBUFS);
            MEMCPY(m->m_data, data, len);
            so->so_snd.sb_flags |= SB_MBCOMP;   /* allow compression */
         }
         else
         {
            m = m_get (M_WAIT, MT_TXDATA);
            m->m_data = data;
         }
         INET_TRACE (INETM_IO,
          ("sosend:got %d bytes so %lx mlen %d, off %d mtod %x\n",
             len, so, m->m_len, m->m_off, mtod (m, caddr_t)));

         *data_length -= len;
         resid -= len;
         data += len;
         m->m_len = len;
         if (head == (struct mbuf *)NULL)
            head = m;
         if (error)
            goto release;
         if (*data_length <= 0)
            break;
      }

      if (dontroute)
         so->so_options |= SO_DONTROUTE;

      so->so_req = (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND;
      error = (*so->so_proto->pr_usrreq)(so, head, nam);

      if (dontroute)
         so->so_options &= ~SO_DONTROUTE;

      head = (struct mbuf *)NULL;
      first = 0;
   } while ((resid != 0) && (error == 0));

release:
   sbunlock(&so->so_snd);  
   if (head)
      m_freem(head);
   return error;
}
コード例 #6
0
ファイル: kttcp.c プロジェクト: yazshel/netbsd-kernel
/*
 * Slightly changed version of sosend()
 */
static int
kttcp_sosend(struct socket *so, unsigned long long slen,
	     unsigned long long *done, struct lwp *l, int flags)
{
	struct mbuf **mp, *m, *top;
	long space, len, mlen;
	int error, dontroute, atomic;
	long long resid;

	atomic = sosendallatonce(so);
	resid = slen;
	top = NULL;
	/*
	 * In theory resid should be unsigned.
	 * However, space must be signed, as it might be less than 0
	 * if we over-committed, and we must use a signed comparison
	 * of space and resid.  On the other hand, a negative resid
	 * causes us to loop sending 0-length segments to the protocol.
	 */
	if (resid < 0) {
		error = EINVAL;
		goto out;
	}
	dontroute =
	    (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
	    (so->so_proto->pr_flags & PR_ATOMIC);
	l->l_ru.ru_msgsnd++;
#define	snderr(errno)	{ error = errno; goto release; }
	solock(so);
 restart:
	if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
		goto out;
	do {
		if (so->so_state & SS_CANTSENDMORE)
			snderr(EPIPE);
		if (so->so_error) {
			error = so->so_error;
			so->so_error = 0;
			goto release;
		}
		if ((so->so_state & SS_ISCONNECTED) == 0) {
			if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
				snderr(ENOTCONN);
			} else {
				snderr(EDESTADDRREQ);
			}
		}
		space = sbspace(&so->so_snd);
		if (flags & MSG_OOB)
			space += 1024;
		if ((atomic && resid > so->so_snd.sb_hiwat))
			snderr(EMSGSIZE);
		if (space < resid && (atomic || space < so->so_snd.sb_lowat)) {
			if (so->so_state & SS_NBIO)
				snderr(EWOULDBLOCK);
			SBLASTRECORDCHK(&so->so_rcv,
			    "kttcp_soreceive sbwait 1");
			SBLASTMBUFCHK(&so->so_rcv,
			    "kttcp_soreceive sbwait 1");
			sbunlock(&so->so_snd);
			error = sbwait(&so->so_snd);
			if (error)
				goto out;
			goto restart;
		}
		mp = &top;
		do {
			sounlock(so);
			do {
				if (top == 0) {
					m = m_gethdr(M_WAIT, MT_DATA);
					mlen = MHLEN;
					m->m_pkthdr.len = 0;
					m->m_pkthdr.rcvif = NULL;
				} else {
					m = m_get(M_WAIT, MT_DATA);
					mlen = MLEN;
				}
				if (resid >= MINCLSIZE && space >= MCLBYTES) {
					m_clget(m, M_WAIT);
					if ((m->m_flags & M_EXT) == 0)
						goto nopages;
					mlen = MCLBYTES;
#ifdef	MAPPED_MBUFS
					len = lmin(MCLBYTES, resid);
#else
					if (atomic && top == 0) {
						len = lmin(MCLBYTES - max_hdr,
						    resid);
						m->m_data += max_hdr;
					} else
						len = lmin(MCLBYTES, resid);
#endif
					space -= len;
				} else {
nopages:
					len = lmin(lmin(mlen, resid), space);
					space -= len;
					/*
					 * For datagram protocols, leave room
					 * for protocol headers in first mbuf.
					 */
					if (atomic && top == 0 && len < mlen)
						MH_ALIGN(m, len);
				}
				resid -= len;
				m->m_len = len;
				*mp = m;
				top->m_pkthdr.len += len;
				if (error)
					goto release;
				mp = &m->m_next;
				if (resid <= 0) {
					if (flags & MSG_EOR)
						top->m_flags |= M_EOR;
					break;
				}
			} while (space > 0 && atomic);
			solock(so);

			if (so->so_state & SS_CANTSENDMORE)
				snderr(EPIPE);
			if (dontroute)
				so->so_options |= SO_DONTROUTE;
			if (resid > 0)
				so->so_state |= SS_MORETOCOME;
			if (flags & MSG_OOB)
				error = (*so->so_proto->pr_usrreqs->pr_sendoob)(so,
				    top, NULL);
			else
				error = (*so->so_proto->pr_usrreqs->pr_send)(so,
				    top, NULL, NULL, l);
			if (dontroute)
				so->so_options &= ~SO_DONTROUTE;
			if (resid > 0)
				so->so_state &= ~SS_MORETOCOME;
			top = 0;
			mp = &top;
			if (error)
				goto release;
		} while (resid && space > 0);
	} while (resid);

 release:
	sbunlock(&so->so_snd);
 out:
 	sounlock(so);
	if (top)
		m_freem(top);
	*done = slen - resid;
#if 0
	printf("sosend: error %d slen %llu resid %lld\n", error, slen, resid);
#endif
	return (error);
}