/** Build a file descriptor for a socket. @param [in] pSocketProtocol Socket protocol structure address @param [in] pErrno Address of the errno variable @return The file descriptor for the socket or -1 if an error occurs. **/ int BslSocketProtocolToFd ( IN EFI_SOCKET_PROTOCOL * pSocketProtocol, IN int * pErrno ) { int FileDescriptor; struct __filedes * pDescriptor; // // Assume failure // FileDescriptor = -1; // // Locate a file descriptor // FileDescriptor = FindFreeFD ( VALID_CLOSED ); if ( FileDescriptor < 0 ) { // // All available FDs are in use // errno = EMFILE; } else { // // Initialize the file descriptor // pDescriptor = &gMD->fdarray[ FileDescriptor ]; pDescriptor->f_offset = 0; pDescriptor->f_flag = 0; pDescriptor->f_iflags = DTYPE_SOCKET; pDescriptor->MyFD = (UINT16)FileDescriptor; pDescriptor->Oflags = O_RDWR; pDescriptor->Omode = S_ACC_READ | S_ACC_WRITE; pDescriptor->RefCount = 1; FILE_SET_MATURE ( pDescriptor ); // // Socket specific file descriptor initialization // pDescriptor->devdata = pSocketProtocol; pDescriptor->f_ops = &SocketOperations; } // // Return the socket's file descriptor // return FileDescriptor; }
/** The fcntl() function shall perform the operations described below on open files. The fildes argument is a file descriptor. The available values for cmd are defined in <fcntl.h> and are as follows: - F_DUPFD - Return a new file descriptor which shall be the lowest numbered available (that is, not already open) file descriptor greater than or equal to the third argument, arg, taken as an integer of type int. The new file descriptor shall refer to the same open file description as the original file descriptor, and shall share any locks. The FD_CLOEXEC flag associated with the new file descriptor shall be cleared to keep the file open across calls to one of the exec functions. - F_GETFD - Get the file descriptor flags defined in <fcntl.h> that are associated with the file descriptor fildes. File descriptor flags are associated with a single file descriptor and do not affect other file descriptors that refer to the same file. - F_SETFD - Set the file descriptor flags defined in <fcntl.h>, that are associated with fildes, to the third argument, arg, taken as type int. If the FD_CLOEXEC flag in the third argument is 0, the file shall remain open across the exec functions; otherwise, the file shall be closed upon successful execution of one of the exec functions. - F_GETFL - Get the file status flags and file access modes, defined in <fcntl.h>, for the file description associated with fildes. The file access modes can be extracted from the return value using the mask O_ACCMODE, which is defined in <fcntl.h>. File status flags and file access modes are associated with the file description and do not affect other file descriptors that refer to the same file with different open file descriptions. - F_SETFL - Set the file status flags, defined in <fcntl.h>, for the file description associated with fildes from the corresponding bits in the third argument, arg, taken as type int. Bits corresponding to the file access mode and the file creation flags, as defined in <fcntl.h>, that are set in arg shall be ignored. If any bits in arg other than those mentioned here are changed by the application, the result is unspecified. - F_GETOWN - If fildes refers to a socket, get the process or process group ID specified to receive SIGURG signals when out-of-band data is available. Positive values indicate a process ID; negative values, other than -1, indicate a process group ID. If fildes does not refer to a socket, the results are unspecified. - F_SETOWN - If fildes refers to a socket, set the process or process group ID specified to receive SIGURG signals when out-of-band data is available, using the value of the third argument, arg, taken as type int. Positive values indicate a process ID; negative values, other than -1, indicate a process group ID. If fildes does not refer to a socket, the results are unspecified. The fcntl() function shall fail if: [EBADF] The fildes argument is not a valid open file descriptor. [EINVAL] The cmd argument is invalid, or the cmd argument is F_DUPFD and arg is negative or greater than or equal to {OPEN_MAX}. [EMFILE] The argument cmd is F_DUPFD and {OPEN_MAX} file descriptors are currently open in the calling process, or no file descriptors greater than or equal to arg are available. [EOVERFLOW] One of the values to be returned cannot be represented correctly. @return Upon successful completion, the value returned shall depend on cmd as follows: - F_DUPFD - A new file descriptor. - F_GETFD - Value of flags defined in <fcntl.h>. The return value shall not be negative. - F_SETFD - Value other than -1. - F_GETFL - Value of file status flags and access modes. The return value is not negative. - F_SETFL - Value other than -1. - F_GETOWN - Value of the socket owner process or process group; this will not be -1. - F_SETOWN - Value other than -1. Otherwise, -1 shall be returned and errno set to indicate the error. **/ int fcntl (int fildes, int cmd, ...) { va_list p3; struct __filedes *MyFd; int retval = -1; int temp; //Print(L"%a( %d, %d, ...)\n", __func__, fildes, cmd); va_start(p3, cmd); if(ValidateFD( fildes, VALID_OPEN )) { MyFd = &gMD->fdarray[fildes]; switch(cmd) { case F_DUPFD: temp = va_arg(p3, int); if(ValidateFD( temp, VALID_DONT_CARE )) { temp = FindFreeFD( temp ); if(temp < 0) { errno = EMFILE; break; } /* temp is now a valid fd reserved for further use so copy fd into temp. */ (void)memcpy(&gMD->fdarray[temp], MyFd, sizeof(struct __filedes)); retval = temp; } else { errno = EINVAL; } break; case F_SETFL: retval = MyFd->Oflags; // Get original value temp = va_arg(p3, int); temp &= O_SETMASK; // Only certain bits can be set temp |= retval & O_SETMASK; MyFd->Oflags = temp; // Set new value break; case F_SETFD: retval = MyFd->f_iflags; break; //case F_SETOWN: // retval = MyFd->SocProc; // MyFd->SocProc = va_arg(p3, int); // break; case F_GETFD: retval = MyFd->f_iflags; break; case F_GETFL: retval = MyFd->Oflags; break; //case F_GETOWN: // retval = MyFd->SocProc; // break; default: errno = EINVAL; break; } } else {