Thread: Help porting code lseek(), open() and read()

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    6

    Help porting code lseek(), open() and read()

    Hi ppl,
    This is my debut in this forum and i'm hoping you ppl will be able to help me out. I'm working in a embedded platform where open(), read(), lseek() are not supported by the filesystem that i've. I've tried to replace these by fopen(), fread() and fseek(). But its giving me issues like at times not being able to seek to certain sectors and so on. (I'm trying to read a dvd and parse its information). The same things happen if i run the modified code in linux. Can someone specify as to how different are these functions and if i should consider any important things while doing the switch from the non-standard ones to the standard ones.
    What i cant understand is that the fseek uses FILE *fd while the lseek uses int fd and how are they going to match?
    If anyone needs any more information on the problem, please ask. I stopped here coz i dint want to distract you with more information.
    Thanks.
    Karthik.

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    fopen() and fseek() are standard functions. read(), write(), open(), lseek() are no-standard, so the aren't generally portable. As a first note you are better with fopen(), fseek(), fread() etc etc.
    In Linux a proper code should work. So you can post the code and ppl can find the problem.
    Embedded systems vary. There are not standard things for them when it comes to the I/O operations and the filesystem.
    FILE is a type defined somewhere. It could be an int, it could be a long. Or a struct. I would guess it is an int, but I have no idea for sure. But why not use fseek() and fopen()? Why not use the standard functions?
    Does it read lets say one character? Does it give an error when searching in certain sections? Do you try to see if the functions succeed from their return code??

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    6
    Quote Originally Posted by C_ntua View Post
    fopen() and fseek() are standard functions. read(), write(), open(), lseek() are no-standard, so the aren't generally portable. As a first note you are better with fopen(), fseek(), fread() etc etc.
    In Linux a proper code should work. So you can post the code and ppl can find the problem.
    Embedded systems vary. There are not standard things for them when it comes to the I/O operations and the filesystem.
    FILE is a type defined somewhere. It could be an int, it could be a long. Or a struct. I would guess it is an int, but I have no idea for sure. But why not use fseek() and fopen()? Why not use the standard functions?
    Does it read lets say one character? Does it give an error when searching in certain sections? Do you try to see if the functions succeed from their return code??
    To answer some of your questions
    Yes i am using fseek and fopen and fread. And it is them that are giving me the problem.
    Yes i am monitoring the return codes of these functions.. It typically fails when trying to seek. You have to understand that this is a huge library (libdvdnav) which i'm trying to port. I'm modifying the underlying physical layer so that the reading part syncs with the filesystem that i have.
    To show you some of the modifications that i'm doing.
    Code:
    static dvd_input_t file_open(const char *target)
    {
      dvd_input_t dev;
      
      /* Allocate the library structure */
      dev = (dvd_input_t) malloc(sizeof(*dev));
      if(dev == NULL) {
        fprintf(stderr, "libdvdread: Could not allocate memory.\n");
        return NULL;
      }
      #if 0
      /* Open the device */
    #ifndef WIN32
      dev->fd = open(target, O_RDONLY);
    #else
      dev->fd = open(target, O_RDONLY | O_BINARY);
    #endif
    #endif
    	dev->fd = fopen(target,"r");
      if(dev->fd < 0) {
        perror("libdvdread: Could not open input");
        free(dev);
        return NULL;
      }
      
      return dev;
    }
    The commented part was what was initially there.
    The problem is that it is able to read in general and its reading and giving me few chars and all properly. But when it tries to seek there is a error and it returns saying cant seek to sector %d.
    Code:
    static int file_seek(dvd_input_t dev, int blocks)
    {
      off_t pos;
     //pos = lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET);
      pos = fseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET);
      if(pos < 0) {
          return pos;
      }
      /* assert pos % DVD_VIDEO_LB_LEN == 0 */
      return (int) (pos / DVD_VIDEO_LB_LEN);
    }
    Again where his fd is a int while mine is a FILE*.
    My question is is this kind of transformation ok? or should i take into account something else?
    This modified code fails in linux as well.
    Thanks for your comments..

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    if(dev->fd < 0) {
    This should change to
    Code:
    if(dev->fd != NULL) {
    as a FILE * may well be less than zero when translated to a signed integer.

    The fseek code is broken because you expect the return value to be the actual position, not as fseek man page states:
    Quote Originally Posted by man fseek
    The fgetpos(), fseek(), fseeko(), and fsetpos() functions return the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error.
    You will need to return the block * DVD_VIDEO_LB_LEN value if fseek returned successfully, or errno if it was a failure.

    Also, if the file is bigger than 2GB, you may need to use fseek64 or fseeko (which you use depends on the OS, you may want to use a macro to translate the name to a common name that you can use without ifdefs in the seek code itself) to get to the right position.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Another thing you have to take into account is that fseek uses long int instead of off_t and returns an int instead of off_t
    see here:
    http://www.cplusplus.com/reference/c...dio/fseek.html
    and for lseek:
    http://www.opengroup.org/onlinepubs/...ons/lseek.html

    It should give you a warning on the compiler. I wouldn't expect it to cause any problems, but make the changes and try again.

    Also, you don't use correctly the returning value.
    fopen returns a NULL pointer if something wrong. So you have to check for the NULL pointer and not for < 0.
    fseek returns a non-zero value if something is wrong. So you have to check for !=0 not <0.

    Apart from that everything else seems fine. So fix these and check again

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Code:
    #endif
    #endif
    That second endif might cause problems.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by robwhit View Post
    Code:
    #endif
    #endif
    That second endif might cause problems.
    No, the first endif relates to the #if WIN32, and the second endif relates to the (incorrectly indented) #if 0 above it.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by matsp View Post
    No, the first endif relates to the #if WIN32, and the second endif relates to the (incorrectly indented) #if 0 above it.

    --
    Mats
    This is why I like to add comments to my #endif to say what condition they're #endif'ing

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by matsp View Post
    No, the first endif relates to the #if WIN32, and the second endif relates to the (incorrectly indented) #if 0 above it.
    Ah I see. The indentation threw me off.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OPen a file and read it from the last line
    By c_geek in forum C Programming
    Replies: 14
    Last Post: 01-26-2008, 06:20 AM
  2. How do you read code?
    By someprogr in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 01-08-2008, 02:27 PM
  3. Big help in Astar search code...
    By alvifarooq in forum C++ Programming
    Replies: 6
    Last Post: 09-24-2004, 11:38 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. open and read data from files
    By ethorn10 in forum C Programming
    Replies: 5
    Last Post: 02-04-2003, 04:00 AM