CS241 System ProgrammingOutlineTerminologyReview from classExampleSlide 6SelectSelect – 4 MacrosSlide 9Slide 10PollSlide 12Slide 13Example (continued)File RepresentationBufferingSerializationSlide 18Floatlist.cSlide 20Slide 21Slide 22Slide 23Slide 24Slide 25memcpySummaryCS241 System ProgrammingDiscussion Section 7March 13 – March 16OutlineUNIX I/OBasic Operationsopen, close, read, writeselect, pollFile RepresentationSerializationTerminologyPeripheral deviceHardware accessed by a computer systemDevice DriverOS modules that enable other programs to interact with a device through system callsUNIX provides uniform access to most devices5 functions: open, close, read, write, ioctlReview from classReadssize_t read(int fildes, void *buf, size_t nbyte);Writessize_t write(int fildes, const void *buf, size_t nbyte);Openint open(const char *path, int oflag, ...);Closeint close(int fildes);ExampleReading a specific number of bytes (Program 4.7)ssize_t readblock(int fd, void *buf, size_t size) { char *bufp; size_t bytestoread; ssize_t bytesread; size_t totalbytes; for (bufp = buf, bytestoread = size, totalbytes = 0; bytestoread > 0; bufp += bytesread, bytestoread -= bytesread) { bytesread = read(fd, bufp, bytestoread); if ((bytesread == 0) && (totalbytes == 0)) return 0; if (bytesread == 0) { errno = EINVAL; return -1; } if ((bytesread) == -1 && (errno != EINTR)) return -1; if (bytesread == -1) bytesread = 0; totalbytes += bytesread; } return totalbytes;}ExampleA program to copy a file (Program 4.9)#define READ_FLAGS O_RDONLY#define WRITE_FLAGS (O_WRONLY | O_CREAT | O_EXCL)#define WRITE_PERMS (S_IRUSR | S_IWUSR) int main(int argc, char *argv[]) { if ((fromfd = open(argv[1], READ_FLAGS)) == -1) { perror("Failed to open input file"); return 1; } if ((tofd = open(argv[2], WRITE_FLAGS, WRITE_PERMS)) == -1) { perror("Failed to create output file"); return 1; } bytes = copyfile(fromfd, tofd); printf("%d bytes copied from %s to %s\n", bytes, argv[1], argv[2]); return 0; /* the return closes the files */ }Select#include <sys/select.h>int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds, struct timeval *restrict timeout);Provides a method of monitoring file descriptors from a single process: for 3 conditionsreadfds : whether read will not blockwritefds : whether write will not blockerrorfds : exceptionsReturns the number of descriptors contained in the descriptor sets if successful. -1 with errno set if unsuccessfulSelect – 4 MacrosSetting the corresponding bitvoid FD_SET(int fd, fd_set *fdset);Clearing the corresponding bitvoid FD_CLR(int fd, fd_set *fdset);Clearing all bitsvoid FD_ZERO(fd_set *fdset);Testing whether the corresponding bit is setint FD_ISSET(int fd, fd_set *fdset);ExampleMonitoring File Descriptors (Program 4.14) while (numnow > 0) { /* continue monitoring until all are done */ FD_ZERO(&readset); /* set up the file descriptor mask */ for (i = 0; i < numfds; i++) if (fd[i] >= 0) FD_SET(fd[i], &readset); numready = select(maxfd, &readset, NULL, NULL, NULL); /* which ready? */ /* Error checking skipped */ for (i = 0; (i < numfds) && (numready > 0); i++) { /* read and process */ if (fd[i] == -1) /* this descriptor is done */ continue; if (FD_ISSET(fd[i], &readset)) { /* this descriptor is ready */ bytesread = r_read(fd[i], buf, BUFSIZE); numready--; if (bytesread > 0) docommand(buf, bytesread); else { /* error occurred on this descriptor, close it */ r_close(fd[i]); fd[i] = -1; numnow--; } } } }ExampleProgram 4.15int waitfdtimed(int fd, struct timeval end) { fd_set readset; int retval; struct timeval timeout; FD_ZERO(&readset); FD_SET(fd, &readset); if (gettimeout(end, &timeout) == -1) return -1; while (((retval = select(fd + 1, &readset, NULL, NULL, &timeout)) == -1) && (errno == EINTR)) { if (gettimeout(end, &timeout) == -1) return -1; FD_ZERO(&readset); FD_SET(fd, &readset); } if (retval == 0) { errno = ETIME; return -1; } if (retval == -1) return -1; return 0;}Poll#include <poll.h>int poll(struct pollfd fds[], nfds_t nfds, int timeout);Provides a method of monitoring file descriptorsOrganizes the information by file descriptor: struct pollfdSelect: by the type of eventReturns the number of descriptors that have events if successful. 0 if timeout, or -1 with errno set if unsuccessfulPollstruct pollfdFile descriptor: int fd;Requested Events: short events;Returned Events: short revents;Event Flags: Table 4.2ExampleMonitoring an array of file descriptors (Program 4.17) if ((pollfd = (void *)calloc(numfds, sizeof(struct pollfd))) == NULL) return; for (i = 0; i < numfds; i++) { (pollfd + i)->fd = *(fd + i); (pollfd + i)->events = POLLRDNORM; } /* Continue monitoring until descriptors done */ while (numnow > 0) { numready = poll(pollfd, numfds, -1); if ((numready == -1) && (errno == EINTR)) continue; /* poll interrupted by a signal, try again */ else if (numready == -1)/* real poll error, can't continue */ break;Example (continued)Monitoring an array of file descriptors (Program 4.17) for (i = 0; i < numfds && numready > 0; i++) { if ((pollfd + i)->revents) { if ((pollfd + i)->revents & (POLLRDNORM | POLLIN) ) { bytesread = r_read(fd[i], buf, BUFSIZE); numready--; if (bytesread > 0) docommand(buf, bytesread); // some command to call on the data else bytesread = -1; /* end of file */ } else if ((pollfd + i)->revents & (POLLERR | POLLHUP)) bytesread = -1; else /* descriptor not involved in this round */ bytesread = 0; if (bytesread == -1) { /* error occurred, remove descriptor */ r_close(fd[i]); (pollfd + i)->fd = -1; numnow--; } } }}File RepresentationFile DescriptorRepresents a file or device that is openAn int-type index into the file descriptor table of each processCan refer to files, directories, blocks, sockets, pipesFile Pointerpoints to a data structure called a FILE structure in
View Full Document