Question

I've been banging my head against my desk for a few hours now, trying to figure out why the following code is stalling at while(chars = read(fd, buff, BUFF_SZ)) > 0). The printf on the line directly following is not being called and the one directly above is. The file descriptor is returning 0, a valid value.

char *infile = argv[1];
int fd,chars;

if ((fd = open(infile, O_RDONLY) < 0)) {
    perror("open()");
    exit(1);
}
printf("%s - opened (fp: %d)\n", infile, fd);
while((chars = read(fd, buff, BUFF_SZ)) > 0){
    printf("%d\n", chars);
    for(i = 0; i < chars; i++){
        c = buff[i];
        total++;
        count[c]++;
    }
}

I don't even know how to debug this since nothing is being triggered following the line in question and everything looks fine before this line.

The full, compilable code:

#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

#include <unistd.h>

#define BUFF_SZ 4096

int main(int argc, char *argv[])
{
        if(argc != 2)
                perror("Wrong number of arguments!");

        int fd;
        char *infile = argv[1];
        char buff[BUFF_SZ];
        int chars,c,c2,i;
        long long total = 0;
        long long count[256];
        char line[71];

        printf("zeroing count[]\n");
        for (c = 0; c < 256; c++) {
                count[c] = 0;
        }

        if ((fd = open(infile, O_RDONLY) < 0)) {
                perror("open()");
                exit(1);
        }
        printf("%s - opened (fp: %d)\n", infile, fd);
        while((chars = read(fd, buff, BUFF_SZ)) > 0){
                printf("%d\n", chars);
                for(i = 0; i < chars; i++){
                        c = buff[i];
                        total++;
                        count[c]++;
                }
        }
        close(fd);
        printf("%s closed\n", infile);

        if(chars < 0){
                perror("read()");
        }

        printf("outputting results\n");
        for (c = 0;c < 256; c++) {
                printf("\t%d of 256\n", c+1);
                snprintf(line, 70, "%.70lf\n",
                         ((float)count[c] / (float)total));
                for (c2 = 68; c2; c2--) {
                        if (line[c2] != '0'
                                && line[c2] != '.')
                                break;
                }
                line[++c2] = 0;
                printf("%s\n", line);
        }
        return 0;
}
Was it helpful?

Solution

The problem is your assignment to fd.

if ((fd = open(infile, O_RDONLY) < 0)) {

should be:

if ((fd = open(infile, O_RDONLY)) < 0) {

The clue was when you said that fd is 0. That was unlikely, since fd 0 is stdin, and this shouldn't happen unless you closed stdin before opening infile.

You were assigning fd the result of comparing the return value of open with 0, instead of assigning the return value itself.

OTHER TIPS

You only need to rearrange the parenthesis

if ((fd = open(argv[1], O_RDONLY)) < 0) {
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top