David Brownell wrote: > > On Thursday 19 August 2004 8:32 am, Alan Stern wrote: > > On Thu, 19 Aug 2004, Alexander N. Kozhushkin wrote: > > > > > 3. The call completes without waiting for the device. The file > > > descriptor has been unusable for I/O operations on the device since > > > the disconnection, therefore the result of the call is not affected > > > if the device has been connected again. The result of the call > > > depends on the kind of the called function and other conditions. > > > However, the 'close' function closes the file, and there are system > > > calls which produce a specific error code in such situations. > > > > As I understand it, the kernel should always use your option 3. > > Certainly USB should do it that way in 2.6, although the device > drivers can try to implement other behavior. I think that's made > a big improvement in robustness. > > Other hotpluggable busses (or 2.4) may not act quite the same. > > - Dave > > The standard behavior should be: read, write, ioctl, fcntl, open,... > return ENODEV or something similar. Close should return 0. > > Alan Stern
Hi, Well, and what about the 'select()' system call? It is not a good idea to make the 'select()' function fail if some file descriptor in the argument descriptor sets corresponds to a disconnected device. It is much better if the 'select()' function treats such a file descriptor as if it is ready for I/O operations. Such a 'select()' function is more convenient in practice. Consider two 'select()' functions. The first function fails with the 'ENODEV' error code if some file descriptor in the argument descriptor sets corresponds to a disconnected device. The second treats such a file descriptor as if it is valid and ready for the respective I/O operation. That is, if some element of an argument descriptor set corresponds to a disconnected device, then the function adds that file descriptor to the respective output descriptor set and returns successfully. In this case, the output of the second function contains not only the elements of the argument descriptor sets which are really ready for reading or writing or really have exceptions, but also the elements of those sets which correspond to the disconnected device. First, if a call to 'select()' completed successfully, it is possible that the device which corresponds to some element of the output descriptor sets has been disconnected since the call completion. So it is always possible that some file descriptor in the output descriptor sets is unusable for I/O operations. Therefore, if a call to either of the 'select()' functions above has completed successfully and has modified the argument descriptor sets, then each file descriptor in the modified descriptor sets is either ready for the respective I/O operation or unusable. So the results of all I/O calls making use of the 'select()' results are still to be checked for the 'ENODEV' error. Second, if a call to the first 'select()' function has failed with the 'ENODEV' error code, the application is able to see that there exists a device which was disconnected. However, ordinarily there are several elements in the argument descriptor sets. So the result of the call does not provide the application with any reliable information about which file descriptors in the argument descriptor sets were spoiled by the disconnection. The information returned by the function in this case is incomplete, and additional system calls are needed only to find those spoiled file descriptors among the elements of the argument descriptor sets. On the other hand, if some device was disconnected before a call to the second 'select()' function, and in the argument descriptor sets there are file descriptors which correspond to that device, then those file descriptors are in the respective output descriptor sets. It should be noted that a 'select()' call is normally followed by calls to functions which perform read and write operations on the file descriptors in the output descriptor sets, i.e., on the ready file descriptors. As noted before, the results of those calls are to be checked for the 'ENODEV' error. So, in this case, the information provided by the second 'select()' function is usually sufficient not only to determine that there is a disconnected device, but also to find the unusable file descriptors in the argument descriptor sets and to distinguish between them and the other elements of the output descriptor sets which are actually ready for reading or writing. Moreover, if the second 'select()' function is in use, it does not matter whether a file descriptor in the argument descriptor sets was spoiled before a 'select()' call or a file descriptor in the output descriptor sets was spoiled immediately after it. In either case the device disconnection which spoiled the file descriptor is handled in the same way. Instead of checking the 'select()' results for the 'ENODEV' error and doing excessive system calls only to find unusable file descriptors, the application performs the calls to 'read()' and 'write()' on the file descriptors in the respective output descriptor set and checks the results of those read and write operations for the 'ENODEV' error, as usually. Those 'read()' and 'write()' calls are used to perform I/O operations and to find the unusable file descriptors at the same time. Therefore, the results of the second 'select()' function are more suitable in practice than the results of the first one, and so it seems that the following behavior of the 'select()' function is more reasonable: If a device was disconnected after a file descriptor corresponding to the device was created, that file descriptor is assumed to be always ready for reading and writing; the disconnection is assumed to be a permanent exceptional condition on the file descriptor. The 'select()' function treats that file descriptor as a valid and ready one. So if the file descriptor is contained in a descriptor set supplied to the 'select()' function as an argument, then the 'select()' function adds the file descriptor to the respective output descriptor set and returns successfully. In such a situation, the normal return value is clearly greater than 0, instead of "-1". Sincerely yours, A.N. Kozhushkin. -- ********************************************************* Alexander N. Kozhushkin. ADDR: [EMAIL PROTECTED] ********************************************************* ------------------------------------------------------- This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170 Project Admins to receive an Apple iPod Mini FREE for your judgement on who ports your project to Linux PPC the best. Sponsored by IBM. Deadline: Sept. 13. Go here: http://sf.net/ppc_contest.php _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel