// create stages initaliztion int pipe_create(pipe_t *pipe, int stages) { int pipe_index; stage_t **link = &pipe->head, *new_stage, *stage; //init PCHECK(pthread_mutex_init(&pipe->mutex, NULL)); pipe->stages = stages; pipe->active = 0; for (pipe_index = 0; pipe_index <= stages; ++pipe_index) { EV_TEST(NULL, new_stage, (stage_t*)malloc(sizeof(stage_t))); PCHECK(pthread_mutex_init(&new_stage->mutex, NULL)); PCHECK(pthread_cond_init(&new_stage->avail, NULL)); PCHECK(pthread_cond_init(&new_stage->ready, NULL)); new_stage->data_ready = 0; *link = new_stage; link = &new_stage->next; } *link = (stage_t*)NULL; pipe->tail = new_stage; for (stage = pipe->head; stage->next != NULL; stage = stage->next) { PCHECK(pthread_create(&stage->thread, NULL, pipe_stage, (void*)stage)); } return 0; }
int main() { const char fifo_path[] = "./my_fifo" ; int res ; int wr_df = -1 ; char buf[PIPE_BUF] ; int write_bytes ; //create a fifo if no have my_fifo if(-1 == access(fifo_path, F_OK)) { E_TEST(-1, mkfifo(fifo_path, 0777)) } EV_TEST(-1, wr_df, open(fifo_path, O_WRONLY)) printf("Process %d result %d\n", getpid(), wr_df) ; for(write_bytes = 0 ; write_bytes < TEN_MEG; write_bytes += res) { //write to fifo EV_TEST(-1, res, write(wr_df, buf, BUF_SIZE)) } printf("the Process %d, total send %dKB(s).\n", getpid(), write_bytes/1024) ; return 0 ; }
int main() { pid_t pid ; unsigned int s = 0 ; while (true) { printf("##start fork\n") ; for (;s < 10; s+=2) { EV_TEST((pid_t)-1, pid, fork()) ; if (pid == (pid_t)0) { (void)printf("create child:%u\n", (unsigned)getpid()) ; (void)sleep(s+2) ; printf("over child:%u\n", (unsigned)getpid()) ; exit(EXIT_SUCCESS) ; } else { /* wait for any child */ do { int status ; (void)printf("parent wiat:%ld\n", (long int)pid) ; pid = waitpid(-1, &status, WNOHANG); //pid = wait(&status) ; if (-1 == pid) { perror("waitpid error") ; exit(EXIT_FAILURE) ; } (void)printf("parent returen wiat:%ld status:%d\n", (long int)pid, status ); } while (pid != (pid_t)0) ; } } } return 0 ; }
/// 创建(打开)伪终端设备有多种接口 void createPty() { int masterFd; //same as posix_openpt 返回主设备句柄 EV_TEST(-1, masterFd, open("/dev/ptmx", O_RDWR | O_NOCTTY)); printf("savle dives name:%s\n", ptsname(masterFd)); //得到从设备名称后,在打开 /*close(masterFd);*/ }
int main() { int ret; ///1 使用 aio_read 需要初始化 aiocb struct aiocb my_aiocb; bzero(&my_aiocb, sizeof my_aiocb); // allocate data buf my_aiocb.aio_buf = malloc(AIO_BUF_SIZE+1); if (my_aiocb.aio_buf == NULL) perror("malloc failed"); // initialize the necessary fields // 每次读不会超过 buf 的大小 my_aiocb.aio_nbytes = AIO_BUF_SIZE; int fd ; EV_TEST(-1, fd, open("README.md", O_RDONLY)); my_aiocb.aio_fildes = fd; /// EE 设置读取的偏移量 read的时候 偏移量是在fd中维护的 //但在异步情况下要为每次读操作都指定偏移量 //aio_read 后kernel不会改变aio_offset 的值 my_aiocb.aio_offset = 0; next: E_TEST(-1, aio_read(&my_aiocb)); ///EE 使用 aio_error 来查询aiocb的状态 //如果是 EINPROGRESS //就一直忙等待,直到状态发生变化为止 while (aio_error(&my_aiocb) == EINPROGRESS) { printf("aio_error is EINPROGRESS\n"); } if ((ret = aio_return(&my_aiocb)) > 0) { // read ret B data printf("aio_return :%d\n", ret); ((char*)my_aiocb.aio_buf)[ret] = '\0'; printf("%s\n", (char*)my_aiocb.aio_buf); //updata aio_offset for next read my_aiocb.aio_offset += ret; goto next; } else if ( ret == 0) { printf("aio_return :%d\n", ret); //read EOF } else { printf("aio_return :%d\n", ret); perror("aio_return failed"); //error occued } E_TEST(-1, close(fd)); return 0; }
int main() { int epoll_fd = -1; EV_TEST(-1, epoll_fd, epoll_create1(0)); //epoll 内部会复制一个e // EE get read fd int pid = fork(); if (pid == 0) { int ofd = open("./epoll.c", O_RDONLY); if (ofd == -1) err_exit("open error"); printf("child start ofd:%d\n", ofd); // add new fd EPOLLET 边沿触发 struct epoll_event e = {EPOLLIN | EPOLLERR, (epoll_data_t)ofd}; //epoll 内部会复制一个e E_TEST(-1, epoll_ctl(epoll_fd, EPOLL_CTL_ADD, e.data.fd, &e)); sleep(5); } else { sleep(2); //EE chlid 添加的fd可以wait到,但是不能操作因为 paren没有对于的fd struct epoll_event evlist ; E_TEST(-1, epoll_wait(epoll_fd, &evlist, 1, -1)); printf("wait 1 fd:%d\n", evlist.data.fd); char buf[15]; E_TEST(-1, read(evlist.data.fd,buf,10)); printf("read:%s\n", buf); // E_TEST(-1, close(evlist.data.fd)); // E_TEST(-1, epoll_wait(epoll_fd, &evlist, 1, -1)); // printf("wait 2 fd:%d\n", evlist.data.fd); // int ofd = open("./epoll.c", O_RDONLY); // if (ofd == -1) err_exit("open error"); // printf("parent start ofd:%d\n", ofd); // // add new fd EPOLLET 边沿触发 // struct epoll_event e = {EPOLLIN | EPOLLERR |EPOLLET, (epoll_data_t)ofd}; // epoll 内部会复制一个e // E_TEST(-1, epoll_ctl(epoll_fd, EPOLL_CTL_ADD, e.data.fd, &e)); } // close(ofd);// close 掉epoll 中添加的fd epoll会自动删除fd event, 不会触发任何的event //close fd epoll will auto clean epoll_fd close(epoll_fd); return 0; }
int main() { const char str[] = "Hi, my child" ; int pipedf[2] ; int pid = -1 ; char buf[1024] ; memset(buf, 0, sizeof(buf)) ; //get pipe E_TEST(-1, pipe(pipedf)) //create a child process EV_TEST(-1, pid, fork()) if(0 == pid) { //child process sprintf(buf, "%d", pipedf[0]) ; E_TEST(-1, execl("pip_read", "pip_read", buf, (char *)0)) return 0 ; } else {
int main() { const char fifo_path[] = "./my_fifo" ; int rd, wd ; //create a fifo if no have my_fifo if(-1 == access(fifo_path, F_OK)) { E_TEST(-1, mkfifo(fifo_path, 0777)) } //open fifo by read //EV_TEST(-1, rd, open(fifo_path, O_RDONLY | O_NONBLOCK)) //printf("the fifo read opened\n") ; //open fifo by write EV_TEST(-1, wd, open(fifo_path, O_WRONLY | O_NONBLOCK)) printf("the fifo write opened\n") ; //S_TEST(0, close(rd)) S_TEST(0, close(wd)) return 0 ; }
/* * Test whether a device has haptic properties. * Returns available properties or 0 if there are none. */ static int EV_IsHaptic(int fd) { unsigned int ret; unsigned long features[1 + FF_MAX / sizeof(unsigned long)]; /* Ask device for what it has. */ ret = 0; if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(features)), features) < 0) { SDL_SetError("Haptic: Unable to get device's features: %s", strerror(errno)); return -1; } /* Convert supported features to SDL_HAPTIC platform-neutral features. */ EV_TEST(FF_CONSTANT, SDL_HAPTIC_CONSTANT); EV_TEST(FF_SINE, SDL_HAPTIC_SINE); EV_TEST(FF_SQUARE, SDL_HAPTIC_SQUARE); EV_TEST(FF_TRIANGLE, SDL_HAPTIC_TRIANGLE); EV_TEST(FF_SAW_UP, SDL_HAPTIC_SAWTOOTHUP); EV_TEST(FF_SAW_DOWN, SDL_HAPTIC_SAWTOOTHDOWN); EV_TEST(FF_RAMP, SDL_HAPTIC_RAMP); EV_TEST(FF_SPRING, SDL_HAPTIC_SPRING); EV_TEST(FF_FRICTION, SDL_HAPTIC_FRICTION); EV_TEST(FF_DAMPER, SDL_HAPTIC_DAMPER); EV_TEST(FF_INERTIA, SDL_HAPTIC_INERTIA); EV_TEST(FF_CUSTOM, SDL_HAPTIC_CUSTOM); EV_TEST(FF_GAIN, SDL_HAPTIC_GAIN); EV_TEST(FF_AUTOCENTER, SDL_HAPTIC_AUTOCENTER); /* Return what it supports. */ return ret; }
int main() { // EE create a epoll instance // epoll_create 中的参数已经不使用了, // epoll_create1 中的参数可以是0和O_CLOEXEC. 0时和epoll_create 相同 // O_CLOEXEC see man-page open int epoll_fd = -1; EV_TEST(-1, epoll_fd, epoll_create1(0)); // EE set epoll // add new fd EPOLLET 边沿触发 //epoll 内部会复制一个e // EE get read fd int pid = fork(); if (pid == 0) { printf("child start\n"); int ofd = open("./epoll.c", O_RDONLY); if (ofd == -1) err_exit("open error"); // add new fd EPOLLET 边沿触发 struct epoll_event e = {EPOLLIN | EPOLLERR |EPOLLET, (epoll_data_t)ofd}; //epoll 内部会复制一个e E_TEST(-1, epoll_ctl(epoll_fd, EPOLL_CTL_ADD, e.data.fd, &e)); sleep(5); } else { sleep(2); printf("parent, child pid:%d\n", pid); struct epoll_event evlist ; for (;;) { int size=0; //通常值等待1个 EV_TEST(-1, size, epoll_wait(epoll_fd, &evlist, 1, -1)); printf("size:%d\n", size); if (evlist.events & EPOLLRDHUP) { printf("EPOLLRDHUP\n"); } if (evlist.events & EPOLLERR) { printf("EPOLLERR\n"); } if (evlist.events & EPOLLHUP) {//如果不把产生的HUP的df移除会一直产生 printf("EPOLLHUP fd:%d\n", evlist.data.fd); epoll_ctl(epoll_fd, EPOLL_CTL_DEL, evlist.data.fd, NULL); break ; } if (evlist.events & EPOLLOUT) { printf("EPOLLOUT\n"); } if (evlist.events & EPOLLIN) { //pipe 对方close一段不会触发EPOLLIN printf("EPOLLIN\n"); // handld every readly fd printf("fd%d\n", evlist.data.fd); } } } // close(ofd);// close 掉epoll 中添加的fd epoll会自动删除fd event, 不会触发任何的event //close fd epoll will auto clean epoll_fd close(epoll_fd); return 0; }