📄 sysdep.cc
字号:
// poll file or socket#if defined(BSD) retVal = select(32, (fd_set*)&rfd, (fd_set*)&wfd, (fd_set*)&xfd, &pollTime);#elif defined(SOLARIS) || defined(LINUX) // KMS retVal = select(32, &rfd, &wfd, &xfd, &pollTime);#else retVal = select(32, &rfd, &wfd, &xfd, &pollTime);#endif ASSERT((retVal == 0) || (retVal == 1)); if (retVal == 0) return FALSE; // no char waiting to be read return TRUE;}//----------------------------------------------------------------------// OpenForWrite// Open a file for writing. Create it if it doesn't exist; truncate it // if it does already exist. Return the file descriptor.//// "name" -- file name//----------------------------------------------------------------------intOpenForWrite(char *name){ int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0666); ASSERT(fd >= 0); return fd;}//----------------------------------------------------------------------// OpenForReadWrite// Open a file for reading or writing.// Return the file descriptor, or error if it doesn't exist.//// "name" -- file name//----------------------------------------------------------------------intOpenForReadWrite(char *name, bool crashOnError){ int fd = open(name, O_RDWR, 0); ASSERT(!crashOnError || fd >= 0); return fd;}//----------------------------------------------------------------------// Read// Read characters from an open file. Abort if read fails.//----------------------------------------------------------------------voidRead(int fd, char *buffer, int nBytes){ int retVal = read(fd, buffer, nBytes); ASSERT(retVal == nBytes);}//----------------------------------------------------------------------// ReadPartial// Read characters from an open file, returning as many as are// available.//----------------------------------------------------------------------intReadPartial(int fd, char *buffer, int nBytes){ return read(fd, buffer, nBytes);}//----------------------------------------------------------------------// WriteFile// Write characters to an open file. Abort if write fails.//----------------------------------------------------------------------voidWriteFile(int fd, char *buffer, int nBytes){ int retVal = write(fd, buffer, nBytes); ASSERT(retVal == nBytes);}//----------------------------------------------------------------------// Lseek// Change the location within an open file. Abort on error.//----------------------------------------------------------------------void Lseek(int fd, int offset, int whence){ int retVal = lseek(fd, offset, whence); ASSERT(retVal >= 0);}//----------------------------------------------------------------------// Tell// Report the current location within an open file.//----------------------------------------------------------------------int Tell(int fd){#if defined(BSD) || defined(SOLARIS) || defined(LINUX) return lseek(fd,0,SEEK_CUR); // 386BSD doesn't have the tell() system call // neither do Solaris and Linux -KMS#else return tell(fd);#endif}//----------------------------------------------------------------------// Close// Close a file. Abort on error.//----------------------------------------------------------------------int Close(int fd){ int retVal = close(fd); ASSERT(retVal >= 0); return retVal;}//----------------------------------------------------------------------// Unlink// Delete a file.//----------------------------------------------------------------------bool Unlink(char *name){ return unlink(name);}//----------------------------------------------------------------------// OpenSocket// Open an interprocess communication (IPC) connection. For now, // just open a datagram port where other Nachos (simulating // workstations on a network) can send messages to this Nachos.//----------------------------------------------------------------------intOpenSocket(){ int sockID; sockID = socket(AF_UNIX, SOCK_DGRAM, 0); ASSERT(sockID >= 0); return sockID;}//----------------------------------------------------------------------// CloseSocket// Close the IPC connection. //----------------------------------------------------------------------voidCloseSocket(int sockID){ (void) close(sockID);}//----------------------------------------------------------------------// InitSocketName// Initialize a UNIX socket address -- magical!//----------------------------------------------------------------------static void InitSocketName(struct sockaddr_un *uname, char *name){ uname->sun_family = AF_UNIX; strcpy(uname->sun_path, name);}//----------------------------------------------------------------------// AssignNameToSocket// Give a UNIX file name to the IPC port, so other instances of Nachos// can locate the port. //----------------------------------------------------------------------voidAssignNameToSocket(char *socketName, int sockID){ struct sockaddr_un uName; int retVal; (void) unlink(socketName); // in case it's still around from last time InitSocketName(&uName, socketName); retVal = bind(sockID, (struct sockaddr *) &uName, sizeof(uName)); ASSERT(retVal >= 0); DEBUG(dbgNet, "Created socket " << socketName);}//----------------------------------------------------------------------// DeAssignNameToSocket// Delete the UNIX file name we assigned to our IPC port, on cleanup.//----------------------------------------------------------------------voidDeAssignNameToSocket(char *socketName){ (void) unlink(socketName);}//----------------------------------------------------------------------// PollSocket// Return TRUE if there are any messages waiting to arrive on the// IPC port.//----------------------------------------------------------------------boolPollSocket(int sockID){ return PollFile(sockID); // on UNIX, socket ID's are just file ID's}//----------------------------------------------------------------------// ReadFromSocket// Read a fixed size packet off the IPC port. Abort on error.//----------------------------------------------------------------------voidReadFromSocket(int sockID, char *buffer, int packetSize){ int retVal;#if defined(__GNUC__) && __GNUC__ < 3 extern int errno;#endif struct sockaddr_un uName;#ifdef LINUX socklen_t size = sizeof(uName);#else int size = sizeof(uName);#endif retVal = recvfrom(sockID, buffer, packetSize, 0, (struct sockaddr *) &uName, &size); if (retVal != packetSize) { perror("in recvfrom");#if defined (CYGWIN) || (__GNUC__ >= 3) cerr << "called with " << packetSize << ", got back " << retVal << ", and " << "\n";#else cerr << "called with " << packetSize << ", got back " << retVal << ", and " << errno << "\n";#endif } ASSERT(retVal == packetSize);}//----------------------------------------------------------------------// modified by KMS to add retry...// SendToSocket// Transmit a fixed size packet to another Nachos' IPC port.// Try 10 times with a one second delay between attempts.// This is useful, e.g., to give the other socket a chance// to get set up.// Terminate if we still fail after 10 tries.//----------------------------------------------------------------------voidSendToSocket(int sockID, char *buffer, int packetSize, char *toName){ struct sockaddr_un uName; int retVal; int retryCount; InitSocketName(&uName, toName); for(retryCount=0;retryCount < 10;retryCount++) { retVal = sendto(sockID, buffer, packetSize, 0, (struct sockaddr *) &uName, sizeof(uName)); if (retVal == packetSize) return; // if we did not succeed, we should see a negative // return value indicating complete failure. If we // don't, something fishy is going on... ASSERT(retVal < 0); // wait a second before trying again Delay(1); } // At this point, we have failed many times // The most common reason for this is that the target machine // has halted and its socket no longer exists. // We simply do nothing (drop the packet). // This may mask other kinds of failures, but it is the // right thing to do in the common case.}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -