Thread: information about file - stat sys call

  1. #1
    Registered User
    Join Date
    Apr 2015
    Posts
    180

    information about file - stat sys call

    I want to implemment ipc as is described in the comments. I'am having trouble with the stat sys call. After receiving file name in server if i write
    Code:
     printf("%ld\n", st.st_size);
    i get 1 when the file has 5M... Then it gives error in the perror when it tries to write. What it wrong?
    server: write error
    : Bad address


    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <string.h>
    
    #define BUFSIZE 1024
    
    int main()
    {
        int fd1[2], fd2[2], pid;
        size_t n;
        char buf[BUFSIZE];
        struct stat st;
        pipe(fd1);
        pipe(fd2);
        if ((pid = fork()) == 0)
        {
            close(fd1[0]);
            close(fd2[1]);
            n = read(STDIN_FILENO, buf, BUFSIZE - 1); // 1. client(child) reads file name from stdin
            buf[n] = '\0';
            write(fd1[1], buf, n); // 2. client sends file name over pipe to server
            while ((n = read(fd2[0], buf, BUFSIZE)) > 0)
            {
                if ((write (STDOUT_FILENO, buf, n)) != n) // 6. client reads file info from pipe and outputs to stdout
                {
                    perror("client: write error\n");
                }
            }
        }
        else
        {
            close(fd1[1]);
            close(fd2[0]);
            read(fd1[0], buf, BUFSIZE); // 3. server (parent) reads file name from pipe
            stat(buf, &st); // 4. server obtains information about the file (stat sys call)
            if (write(fd2[1], (void *)st.st_size, sizeof(st.st_size)) != sizeof(st.st_size)) // 5. server sends file information over pipe to client
            {
                perror("server: write error\n");
            } 
            if (write(fd2[1], (void *)st.st_atime, sizeof(st.st_atime)) != sizeof (st.st_atime))
            {
                perror("server: write error\n");
            }
        }
        return 0;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,063
    > if (write(fd2[1], (void *)st.st_size, sizeof(st.st_size)) != sizeof(st.st_size))
    That you had to use a cast should have been a warning that you're doing it wrong.

    write() needs a pointer, so just use
    if (write(fd2[1], &st.st_size, sizeof(st.st_size)) != sizeof(st.st_size))

    > write(fd1[1], buf, n); // 2. client sends file name over pipe to server
    You need to write n+1 if you want to send the \0 as well.

    > while ((n = read(fd2[0], buf, BUFSIZE)) > 0)
    > if ((write (STDOUT_FILENO, buf, n)) != n) // 6. client reads file info from pipe and outputs to stdout
    But you're writing binary data to the other end of the pipe.
    You're not going to see nicely formatted text on stdout with this code.
    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.

  3. #3
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    You forgot to zero-terminate the filename that the server reads (which should be limited to BUFSIZE-1). Ditto for the read in the client.

    You're sending the newline as part of the filename.

    read and write return an ssize_t (a signed value), not a size_t (an unsigned value).

    Writing the raw binary of the returned value to stdout is not going to be very useful. Why not use printf?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #define BUFSIZE 1024
    enum {IN, OUT};
    
    int main() {
        int CtoS[2], StoC[2], pid;
        ssize_t n;
        char buf[BUFSIZE];
    
        pipe(CtoS);
        pipe(StoC);
        pid = fork();
        if (pid == -1) {
            perror("fork error");
            exit(1);
        }
    
        if (pid == 0) {
            close(CtoS[IN]);
            close(StoC[OUT]);
    
            printf("Enter filename: ");
            fflush(stdout);
            fgets(buf, BUFSIZE, stdin);
            n = strlen(buf);
            if (buf[n - 1] == '\n')
                buf[--n] = '\0';
    
            write(CtoS[OUT], buf, n);
    
            ssize_t pos = 0;
            while ((n = read(StoC[IN], buf + pos, BUFSIZE - 1 - pos)) > 0)
                pos += n;
            buf[pos] = '\0';
    
            printf("size :[%ld]\n", (long)*(off_t*)buf);
            printf("atime:[%ld]\n", (long)*(time_t*)(buf + sizeof(off_t)));
        }
    
        else {
            struct stat st;
    
            close(CtoS[OUT]);
            close(StoC[IN]);
    
            n = read(CtoS[IN], buf, BUFSIZE - 1);
            buf[n] = '\0';
    
            if (stat(buf, &st) != 0) {
                perror("server: stat error");
                exit(1);
            }
    
            if (write(StoC[OUT], &st.st_size, sizeof(st.st_size)) != sizeof(st.st_size)) {
                perror("server: write error 1");
                exit(1);
            } 
    
            if (write(StoC[OUT], &st.st_atime, sizeof(st.st_atime)) != sizeof (st.st_atime)) {
                perror("server: write error 2");
                exit(1);
            }
        }
    
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Is my function call for reading train's information right?
    By bellagomes21 in forum C Programming
    Replies: 2
    Last Post: 04-05-2016, 07:21 AM
  2. Replies: 1
    Last Post: 12-06-2012, 02:46 PM
  3. stat() -> how to find out if file has S_IROTH
    By flegmik in forum C Programming
    Replies: 9
    Last Post: 12-09-2011, 05:59 AM
  4. help with my mIRC log file stat generator.
    By TravisS in forum C Programming
    Replies: 3
    Last Post: 06-13-2002, 09:28 PM
  5. Capturing file stat information
    By Sue Paterniti in forum C Programming
    Replies: 3
    Last Post: 04-15-2002, 05:47 AM

Tags for this Thread