device_initialize()
関数が呼ばれる必要があります。各 I/O 要求には、どの I/O 操作が要求されているのかを表すタグがついています。このメインループでは、デバイスオープン要求用の IO_MESG_OPEN
とデバイスシャットダウン要求用の IO_MESG_TERM
だけが受け付けられます。
IO_MESG_OPEN
要求を受け取ると、デバイスサーバプロセスは実際の I/O 要求を処理する子プロセスを fotk します。
#include <score_device.h> int main( int argc, char **argv ) { struct sockaddr addr; pid_t pid; int addrsize; int fd; int tag; int cell; ioarg_t offset0, offset1; if(device_initialize(argc, argv) < 0) device_terminate( 3 ); device_log("Device Initialized !!"); while(1) { addrsize = sizeof(struct sockaddr); if((fd = accept(fd_listen, &addr, &addrsize)) < 0) { if(errno == EINTR) continue; /* in case of SIGCHLD */ device_log("Accept error"); device_terminate(1); } set_tcp_nodelay(fd); if(read_device_op( &tag, &cell, &offset0, &offset1, fd ) != 0) { device_log("Error in read device-op"); break; } switch(tag) { case IO_MESG_OPEN: if((pid = fork()) == 0) { /* if device process */ null_device(fd); } else if (pid > 0) { /* if device server process */ if(write_device_ack(fd, NORMAL_END, cell) != 0) { device_log("Error in write device ack"); } close(fd); } else { /* if error in fork() */ if(write_device_ack( fd, EIO, cell ) != 0) { device_log("Error in write device ack"); } device_log("Cannot fork device process"); } break; case IO_MESG_TERM: device_log("device shutdown"); device_terminate(0); break; default: device_log("Unknown I/O message tag (%d) (cell=%d,off=%d,wh=%d)", tag, cell, offset, whence); device_terminate(1); break; } } return(0); }
IO_MESG_WRITE
) は何もせず、読み込み要求は対応する I/O セルをゼロで埋めます。
#include <score_device.h> void null_device (int fd) { int tag; int cell; ioarg_t offset0, offset1; char pseudo_dev[IO_BUFFER_SIZE]; char *iobuf; int length; while(1) { if(read_device_op( &tag, &cell, &offset0, &offset1, fd) != 0) { device_log("Error in read device-op"); device_terminate(1); } switch(tag) { case IO_MESG_WRITE: length = get_iocell(cell, &iobuf); /* actual write operation here */ if(write_device_ack(fd, NORMAL_END, cell) != 0) { device_log("Error in write device ack"); } break; case IO_MESG_READ: length = get_iocell(cell, &iobuf); bzero(iobuf, length); set_iocell_length(cell, length); if(write_device_ack(fd, NORMAL_END, cell) != 0) { device_log("Error in write device ack"); } break; case IO_MESG_CLOSE: if(write_device_ack( fd, NORMAL_END, cell) != 0) { device_log("Error in write device ack"); } close(fd); device_terminate(0); break; default: device_log("Unknown I/O message tag"); device_terminate(1); break; } } }