Like Tree1Likes
  • 1 Post By std10093

fread exit problems

This is a discussion on fread exit problems within the C Programming forums, part of the General Programming Boards category; Dear programmers, I'm working on a program that connects a FDTI device in Linux. I open the connection with: Code: ...

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    52

    fread exit problems

    Dear programmers,

    I'm working on a program that connects a FDTI device in Linux. I open the connection with:
    Code:
    PRS485 = fopen("/dev/ttyUSB0", "r+");
    Then I send data with:
    Code:
    fwrite (output , 1 , 9, PRS485);
    I read information with:
    Code:
    fread(input, 1, 9, PRS485);
    I've 2 LED's on the FTDI chip: 1 on the receive and 1 on the send data/

    The problem was:
    1. The code keeps sending, but never makes it to reading.
    I searched on Internet to a clue, and found out that a litle pause between fwrite and fread should fix this problem. So I putted a simple wait for loop in it.

    The problem now is:
    2. Somethimes it does not receive al the data, then the whole code Stops, couse fread expects more bytes or a \n.

    How can I stop fread after a amounth of time?
    Kind regards,

    Libpgeak

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Glyfada,Athens
    Posts
    2,650
    If i were you i would try to first open the file with the "r" extension for reading.Read data.Close the file.
    Then open the file with "w" extension and write it.Then close the file.

    Here is an example of how to copy files
    Code:
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    { FILE *ifp, *ofp;
      int n;
      char buf[1024];
      if (argc != 3) {
        fprintf(stderr,
                "Usage: %s <soure-file> <target-file>\n", argv[0]);
        return 1;
      }
      if ((ifp = fopen(argv[1], "r")) == NULL) { /* Open source file */
        perror("fopen source-file");
        return 1;
      }
      if ((ofp = fopen(argv[2], "w")) == NULL) { /* Open target file */
        perror("fopen target-file");
        return 1;
      }
      while (!feof(ifp)) {  /* While we don't reach the end of source */
                   /* Read characters from source file to fill buffer */
        n = fread(buf, sizeof(char), sizeof(buf), ifp);
                              /* Write characters read to target file */
        fwrite(buf, sizeof(char), n, ofp);
      }
      fclose(ifp);
      fclose(ofp);
      return 0;
    }
    In your case the FILE source should be the same as the target one.

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,334
    > while (!feof(ifp))
    After nearly 1000 posts, and nearly 2 years, and you're still doing this
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Glyfada,Athens
    Posts
    2,650
    Thank you salem for the reminder.

    I change the relative part to this
    Code:
                  /* Read characters from source file to fill buffer */
      while( ( n = fread(buf, sizeof(char), sizeof(buf), ifp) ) != 0 ){
                              /* Write characters read to target file */
        fwrite(buf, sizeof(char), n, ofp);
      }

  5. #5
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Glyfada,Athens
    Posts
    2,650
    Quote Originally Posted by Salem View Post
    > while (!feof(ifp))
    After nearly 1000 posts, and nearly 2 years, and you're still doing this
    Why salem is yelling at me (which i thank him for)
    Why it's bad to use feof as control of the loop
    rogster001 likes this.

  6. #6
    Left
    Join Date
    Oct 2011
    Posts
    816
    Since this is really serial port programming, just via an FTDI-USB bridge, I recommend using low-level I/O in unistd.h instead. See open(), close(), fcntl(), read() and write() for details. To set the baud rate and other serial port settings, use termios.h. See man 3 termios for the details.

    A key point to remember is that in all cases, the low-level read() and write() functions may, and will, return short counts. They are not guaranteed to read or write the number of chars you ask, so you absolutely have to always check the return values.

    There are two basic approaches you can take to implement a read or write timeout. First, you can use non-blocking I/O, in which case the function will return immediately if the data cannot be read/written. (It is then up to you whether you wait for a while and then retry, or if you want to do something else.) Second, you can use normal (blocking) I/O, but set up a signal -- usually SIGIO or SIGALRM -- to interrupt the blocking call if it takes too long.

    I really cannot say which approach is better, because it depends on the communications, latency requirements, and so on.

    I suspect blocking I/O is probably a bit easier to implement. Here is a very basic signal handler setup you can use for single-threaded applications:
    Code:
    #include <unistd.h>
    #include <signal.h>
    #include <sys/time.h>
    #include <errno.h>
    
    /* Helper macro, to silence warnings about unused parameters. */
    #define  UNUSED  __attribute__((unused))
    
    /* Timeout flag.
     *     0: Timeout has elapsed.
     *     1: Timeout is pending.
     *     2: Timeout is being set.
     *     3: Error setting timeouts.
     *     4: Timeouts have not been initialized yet.
     * Never modify the flag directly; use the timeout_set()/timeout_unset().
    */
    static volatile sig_atomic_t  timeout_pending = 4;
    
    /* Timeout signal handler. Just sets the timeout_pending. */
    static void timeout_handler(int signum UNUSED)
    {
        if (timeout_pending == 1)
            timeout_pending = 0;
    }
    
    /* Unset the timeout. Returns 1 if timeout had elapsed.
    */
    static int timeout_unset(void)
    {
        struct itimerval  value;
        int               saved_errno, retval;
    
        saved_errno = errno;
    
        if (timeout_pending == 0)
            retval = 1;
        else
            retval = 0;
    
        /* Cancel previous timeout. */
        value.it_value.tv_sec = 0L;
        value.it_value.tv_usec = 0L;
        value.it_interval.tv_sec = 0L;
        value.it_interval.tv_usec = 0L;
        setitimer(ITIMER_REAL, &value, NULL);
    
        errno = saved_errno;
        return retval;
    }
    
    /* Set the timeout, in wall-clock seconds (real time).
     * Only one timeout is active at any time.
     * Returns 0 if success, errno otherwise.
    */
    static int timeout_set(const double seconds)
    {
        struct itimerval  value;
    
        /* Cancel previous timeout. */
        value.it_value.tv_sec = 0L;
        value.it_value.tv_usec = 0L;
        value.it_interval.tv_sec = 0L;
        value.it_interval.tv_usec = 0L;
        setitimer(ITIMER_REAL, &value, NULL);
    
        /* Calculate new timeout. */
        value.it_value.tv_sec = (long)seconds;
        value.it_value.tv_usec = (long)(1000000.0 * (seconds - (double)value.it_value.tv_sec));
    
        /* Bad timeout? */
        if (seconds < 0.0 || value.it_value.tv_sec < 0L)
            return errno = EINVAL;
    
        /* Limit microseconds to 0 .. 999999 inclusive. */
        if (value.it_value.tv_usec < 0L)
            value.it_value.tv_usec = 0L;
        else
        if (value.it_value.tv_usec > 999999L)
            value.it_value.tv_usec = 999999L;
    
        /* Zero value is special. Use 1 us instead. */
        if (value.it_value.tv_sec == 0L && value.it_value.tv_usec == 0L)
            value.it_value.tv_usec = 1L;
    
        /* Set to repeat every millisecond, in case the initial interrupt is missed. */
        value.it_interval.tv_sec  = 0;
        value.it_interval.tv_usec = 1000; /* 1000 us = 1 ms = 0.001 s */
    
        /* Signal handler not installed yet? */
        if (timeout_pending == 4) {
            struct sigaction  act;
    
            sigemptyset(&act.sa_mask);
            act.sa_handler = timeout_handler;
            act.sa_flags = 0;
    
            if (sigaction(SIGALRM, &act, NULL) == -1)
                return errno;
        }
    
        /* Set the timeout_pending flag. */
        timeout_pending = 1;
    
        /* Set the new timeout. */
        if (setitimer(ITIMER_REAL, &value, NULL) == -1) {
            timeout_pending = 3;
            return errno;
        }
    
        /* Success. */
        return 0;
    }
    
    /*
     * Example main() follows.
    */
    
    
    /* Low-level write, which returns 0 if success and errno otherwise.
     * Ignores signal delivery interrupts.
    */
    static inline int writefd(const int descriptor, const void *const data, const size_t size)
    {
        const unsigned char       *head = (const unsigned char *)data;
        const unsigned char *const tail = size + (const unsigned char *)data;
        ssize_t                    bytes;
        int                        saved_errno;
    
        saved_errno = errno;
    
        while (head < tail) {
    
            bytes = write(descriptor, head, (size_t)(tail - head));
            if (bytes > (ssize_t)0) {
                head += bytes;
    
            } else
            if (bytes != (ssize_t)-1) {
                errno = saved_errno;
                return EIO;
    
            } else
            if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) {
                const int retval = errno;
                errno = saved_errno;
                return retval;
            }
        }
    
        errno = saved_errno;
        return 0;
    }
    
    static int wrerr(const char *const string)
    {
        size_t n = 0;
    
        if (string)
            while (string[n])
                n++;
    
        if (n > 0)
            return writefd(STDERR_FILENO, string, n);
    
        return 0;
    }
    
    int main(void)
    {
        while (1) {
            char     buffer[4096];
            ssize_t  n;
            int      elapsed;
    
            /* Set a five-second timeout. */
            timeout_set(5.0);
            n = read(STDIN_FILENO, buffer, sizeof buffer);
            elapsed = timeout_unset();
    
            /* No more input? */
            if (n == (ssize_t)0)
                break;
        
            /* If no data, and timeout elapsed, then: */
            if (n == (ssize_t)-1 && errno == EINTR && elapsed) {
                wrerr("Are you still there?\n");
                continue;
            }
    
            /* No data? (Spurious interrupt? I/O error?) */
            if (n < (ssize_t)1)
                continue;
    
            /* Write the data to standard output,
             * ignoring signal delivery interrupts. Abort if error.
            */
            if (writefd(STDOUT_FILENO, buffer, n))
                return 1;
        }
    
        return 0;
    }
    If you run it, it will prompt "Are you still there?" to standard error every five seconds, until you input something. (Because by default input is line-buffered, you need to press enter within the five-second interval; just adding text is not enough.) The main() just echoes the input back to standard output.

    Note that the writefd() function ignores signal interrupts. You cannot use it if you want a write to be interrupted. Use plain write() (checking errno if it returns -1), like I used plain read(), above. (timeout_unset() deliberately keeps errno intact.)
    Last edited by Nominal Animal; 11-16-2012 at 04:18 AM.

  7. #7
    Registered User
    Join Date
    Sep 2011
    Posts
    52
    Quote Originally Posted by std10093 View Post
    Thank you salem for the reminder.

    I change the relative part to this
    Code:
                  /* Read characters from source file to fill buffer */
      while( ( n = fread(buf, sizeof(char), sizeof(buf), ifp) ) != 0 ){
                              /* Write characters read to target file */
        fwrite(buf, sizeof(char), n, ofp);
      }
    The weird thing is, it still hangs on the read(and there is nothing printed). I made the code a litlle diffrent to this:
    Code:
      printf("writing\n\r");
      fwrite(output, 1, 9, ofp);
      /* Read characters from source file to fill buffer */
      printf("reading\n\r");
        while( ( n = fread(buf, sizeof(char), sizeof(buf), ifp) ) != 0 ){
            printf("%d",n);
            }
      printf("Done\n\r");

  8. #8
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Glyfada,Athens
    Posts
    2,650
    You close the file that you opened for reading before starting writing?

  9. #9
    Registered User
    Join Date
    Sep 2011
    Posts
    52
    Quote Originally Posted by std10093 View Post
    You close the file that you opened for reading before starting writing?
    Yes, I do

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fread/fwrite problems
    By scorpix in forum C Programming
    Replies: 2
    Last Post: 10-10-2009, 09:58 PM
  2. fread problems or memory problems
    By Lechuza in forum C Programming
    Replies: 1
    Last Post: 03-22-2009, 12:45 PM
  3. Reading from binary file; fread problems?
    By pmgeahan in forum C Programming
    Replies: 3
    Last Post: 01-15-2009, 04:07 PM
  4. fread problems
    By firyace in forum C Programming
    Replies: 19
    Last Post: 06-14-2007, 04:09 PM
  5. fread problems
    By Happy_Reaper in forum C Programming
    Replies: 4
    Last Post: 03-15-2006, 09:27 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21