有限状态机实现文件拷贝

通过有限状态机实现文件相互拷贝

 

 

 

示例:relay.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#define FILE1 "/tmp/out1"  
#define FILE2 "/tmp/out2"
#define BUFFSIZE 1024

enum fsmstate  //状态机状态
{
  STATE_R,
  STATE_W,
  STATE_EX,
  STATE_T
};

struct fsm_st  //状态机结构体
{
  enum fsmstate state;
  int sfd;
  int dfd;
  int lenth;
  int pos;
  char *err;
  char buff[BUFFSIZE];
};

static void fsm_driver(struct fsm_st *fsm)  //状态机驱动函数
{
  int ret;

  switch(fsm->state)  //状态判断
  {
    case STATE_R: //读状态
      fsm->lenth = read(fsm->sfd,fsm->buff,BUFFSIZE);
      if(fsm->lenth<0)
      {
        if(errno == EAGAIN)
          fsm->state = STATE_R;
        else
        {
          fsm->err = "read";
          fsm->state = STATE_EX;
        }
      }
      else if(fsm->lenth == 0)
        fsm->state = STATE_T;
      else
      {
        fsm->pos =0;
        fsm->state = STATE_W;
      }
      break;
    case STATE_W:  //写状态
      ret = write(fsm->dfd,fsm->buff + fsm->pos,fsm->lenth);
      if(ret <0)
      {
        if(errno == EAGAIN)
          fsm->state = STATE_W;
        else
        {
          fsm->err = "write";
          fsm->state = STATE_EX;
        }
      }
      else
      {
        fsm->pos +=ret;
        fsm->lenth -=ret;
        if(fsm->lenth ==0)
          fsm->state = STATE_T;
        fsm->state = STATE_W;
      }
      break;
    case STATE_EX:  //出错
      fprintf(stderr,"%s\n",fsm->err);
      fsm->state = STATE_T;
      break;
    case STATE_T:  //完成
      break;
    default:
      abort();
      break;
  }
}

static void relay(int fd1, int fd2)
{
  struct fsm_st fsm12,fsm21;
  int fd1_save,fd2_save;

  fd1_save = fcntl(fd1,F_GETFL); //保存文件flag
  fsm12.state = STATE_R;  //设置初始状态
  fsm12.sfd = fd1;
  fsm12.dfd = fd2;

  fd2_save = fcntl(fd2,F_GETFL);
  fsm21.state = STATE_R;
  fsm21.sfd = fd2;
  fsm21.dfd = fd1;

  while(fsm12.state != STATE_T || fsm21.state != STATE_T) //启动状态机
  {
    fsm_driver(&fsm12);
    fsm_driver(&fsm21);
  }
  fcntl(fd1,F_SETFL,fd1_save);
  fcntl(fd2,F_SETFL,fd2_save);
}

int main()
{
  int fd1,fd2;

  fd1 = open(FILE1,O_RDWR|O_NONBLOCK); //状态机非阻塞打开
  if(fd1 <0)
  {
    perror("open()");
    exit(1);
  }

  fd2 = open(FILE2,O_RDWR|O_NONBLOCK);
  if(fd2 <0)
  {
    perror("open()");
    exit(1);
  }


  relay(fd1,fd2);

  close(fd1);
  close(fd2);

  exit(0);
}

posted @ 2022-07-28 09:50  *^VV^*  阅读(24)  评论(0编辑  收藏  举报