Thread: A task in Linux. Can't make it work

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    10

    A task in Linux. Can't make it work

    Hello,

    I know that many of you get annoyed when someone asks for help with a task they have been assigned but I hope that you wouldn't be angry at me because I've really tried to make this thing work.
    So, I got this task in C to create a program that imitates the cat function in Linux. I'm not very good in neither C nor Linux but managed to come up with sth that compiles with no errrors in gcc 3.2 under Slackware but when I try to execute it shows the following error:

    /usr/lib/gcc-lib/i486-slackware-linux/3.2.3/../../../../i486-slackware-linux/bin/ld:file: file format not recognized; treating as linker script
    /usr/lib/gcc-lib/i486-slackware-linux/3.2.3/../../../../i486-slackware-linux/bin/ld:file:1: parse error
    collect2: ld returned 1 exit status
    This is the source I'm using
    Code:
    #include <sys/cdefs.h>
    #include <sys/param.h>
    #include <sys/stat.h>
    #include <locale.h>
    #include <ctype.h>
    #include <err.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #define EFTYPE 79
    
    int bflag, eflag, fflag, nflag, sflag, tflag, vflag;
    int rval;
    const char *filename;
    
    int main __P((int, char *[]));
    void cook_args __P((char *argv[]));
    void cook_buf __P((FILE *));
    void raw_args __P((char *argv[]));
    void raw_cat __P((int));
    
    int
    main(argc, argv)
    	int argc;
    	char *argv[];
    {
    	int ch;
    
    	(void)setlocale(LC_ALL, "");
    
    	while ((ch = getopt(argc, argv, "befnstuv")) != -1)
    		switch (ch) {
    		case 'b':
    			bflag = nflag = 1;	/* -b implies -n */
    			break;
    		case 'e':
    			eflag = vflag = 1;	/* -e implies -v */
    			break;
    		case 'n':
    			nflag = 1;
    			break;
    		case 's':
    			sflag = 1;
    			break;
    		case 'f':
    			fflag = 1;
    			break;
    		case 't':
    			tflag = vflag = 1;	/* -t implies -v */
    			break;
    		case 'u':
    			setbuf(stdout, (char *)NULL);
    			break;
    		case 'v':
    			vflag = 1;
    			break;
    		default:
    		case '?':
    			(void)fprintf(stderr,
    			    "usage: cat [-benstuv] [-] [file ...]\n");
    			exit(1);
    			/* NOTREACHED */
    		}
    	argv += optind;
    
    	if (bflag || eflag || nflag || sflag || tflag || vflag)
    		cook_args(argv);
    	else
    		raw_args(argv);
    	if (fclose(stdout))
    		err(1, "stdout");
    	exit(rval);
    	/* NOTREACHED */
    }
    
    void
    cook_args(argv)
    	char **argv;
    {
    	FILE *fp;
    
    	fp = stdin;
    	filename = "stdin";
    	do {
    		if (*argv) {
    			if (!strcmp(*argv, "-"))
    				fp = stdin;
    			else if ((fp = fopen(*argv, "rw")) == NULL) {
    				warn("%s", *argv);
    				rval = 1;
    				++argv;
    				continue;
    			}
    			filename = *argv++;
    		}
    		cook_buf(fp);
    		if (fp != stdin)
    			(void)fclose(fp);
    	} while (*argv);
    }
    
    void
    cook_buf(fp)
    	FILE *fp;
    {
    	int ch, gobble, line=0, prev;
    
    	line = gobble = 0;
    	for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
    		if (prev == '\n') {
    			if (ch == '\n') {
    				if (sflag) {
    					if (!gobble && putchar(ch) == EOF)
    						break;
    					gobble = 1;
    					continue;
    				}
    				if (nflag) {
    					if (!bflag) {
    						(void)fprintf(stdout,
    						    "%6d\t", ++line);
    						if (ferror(stdout))
    							break;
    					} else if (eflag) {
    						(void)fprintf(stdout,
    						    "%6s\t", "");
    						if (ferror(stdout))
    							break;
    					}
    				}
    			} else if (nflag) {
    				(void)fprintf(stdout, "%6d\t", ++line);
    				if (ferror(stdout))
    					break;
    			}
    		}
    		gobble = 0;
    		if (ch == '\n') {
    			if (eflag)
    				if (putchar('$') == EOF)
    					break;
    		} else if (ch == '\t') {
    			if (tflag) {
    				if (putchar('^') == EOF || putchar('I') == EOF)
    					break;
    				continue;
    			}
    		} else if (vflag) {
    			if (!isascii(ch)) {
    				if (putchar('M') == EOF || putchar('-') == EOF)
    					break;
    				ch = toascii(ch);
    			}
    			if (iscntrl(ch)) {
    				if (putchar('^') == EOF ||
    				    putchar(ch == '\177' ? '?' :
    				    ch | 0100) == EOF)
    					break;
    				continue;
    			}
    		}
    		if (putchar(ch) == EOF)
    			break;
    	}
    	if (ferror(fp)) {
    		warn("%s", filename);
    		rval = 1;
    		clearerr(fp);
    	}
    	if (ferror(stdout))
    		err(1, "stdout");
    }
    
    void
    raw_args(argv)
    	char **argv;
    {
    	int fd;
    
    	fd = fileno(stdin);
    	filename = "stdin";
    	do {
    		if (*argv) {
    			if (!strcmp(*argv, "-"))
    				fd = fileno(stdin);
    			else if (fflag) {
    				struct stat st;
    				fd = open(*argv, O_RDONLY|O_NONBLOCK, 0);
    				if (fd < 0)
    					goto skip;
    
    				if (fstat(fd, &st) == -1) {
    					close(fd);
    					goto skip;
    				}
    				if (!S_ISREG(st.st_mode)) {
    					close(fd);
    					errno = EFTYPE;
    					goto skip;
    				}
    			}
    			else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
    skip:
    				warn("%s", *argv);
    				rval = 1;
    				++argv;
    				continue;
    			}
    			filename = *argv++;
    		}
    		raw_cat(fd);
    		if (fd != fileno(stdin))
    			(void)close(fd);
    	} while (*argv);
    }
    
    void
    raw_cat(rfd)
    	int rfd;
    {
    	int wfd;
    	static char *buf;
    	static char fb_buf[BUFSIZ];
    	struct stat sbuf;
    	static size_t bsize;
    	ssize_t nr, nw, off;
    
    	wfd = fileno(stdout);
    	if (buf == NULL) {
    		if (fstat(wfd, &sbuf) == 0) {
    			bsize = MIN(sbuf.st_blksize, SSIZE_MAX);
    			bsize = MAX(bsize, BUFSIZ);
    			buf = malloc(bsize);
    		}
    		if (buf == NULL) {
    			buf = fb_buf;
    			bsize = BUFSIZ;
    		}
    	}
    	while ((nr = read(rfd, buf, bsize)) > 0)
    		for (off = 0; nr; nr -= nw, off += nw)
    			if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
    				err(1, "stdout");
    	if (nr < 0) {
    		warn("%s", filename);
    		rval = 1;
    	}
    }
    If anyone has an idea what's wrong please share it with me because I'm quite stuck and really don't know how to fix this.

    Kind regards,
    Valentin
    Last edited by sanchopansa; 11-02-2006 at 06:38 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > So, I got this task in C to create a program that imitates the cat function in Linux. I'm not very good in neither C nor Linux
    I'm pretty sure this isn't your code at all, but the source code of the actual cat program you've downloaded off the net.
    There are certain things in the code which no 'C noob' would really know about.
    Being able to code is so much more than who's got the best google skills.

    > /usr/lib/gcc-lib/i486-slackware-linux/3.2.3/../../../../i486-slackware-linux/bin/ld:file: file format not recognized; treating as linker script
    What did you type in to try and compile the file?
    This is not the normal kind of error message you see from the compiler.

    gcc prog.c
    Is the usual thing to type.


    Have you tested your compiler installation by trying to compile something simple like
    Code:
    #include <stdio.h>
    int main ( ) {
      printf( "hello world\n" );
      return 0;
    }
    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
    Oct 2006
    Posts
    10
    I used gcc -c /path/to/mycat.c to compile this and it didn't show any errors. I've tried testing my compiler as you suggeted and everything is fine with it. As for the error that I've quoted it's not from the compiler (the compiler does not show any error) it is when I try to execute it.

    And about downloading from the net- I haven't said that I've done the program myself and I copy/pasted the whole the stuff and then tried to modify and rewrite all the source that I could and I did find a way to redo some of the things. Of course this doesn't mean that I have programmed it but I can tell that I have spent the last 4 days trying to modify and make it work and it still doesn't unfortunately. So I would really aprreciate it if someone could help start it.

    Kind regards,
    Valentin

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > gcc -c /path/to/mycat.c
    The -c just means you compile it (to a .o) file.
    That .o file is NOT an executable file.

    Try gcc mycat.c
    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.

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    10
    Thanks for even bothering to answer my lame questions, Salem. I've tried this and it doesn't show any errors but simply returns to the console. How can I execute it?

    -------------------------------------------

    Sorry about this. It's ok now. I've fixed it. Thanks for your help, I really appreciate it.
    Last edited by sanchopansa; 11-02-2006 at 07:51 AM.

  6. #6
    Fear the Reaper...
    Join Date
    Aug 2005
    Location
    Toronto, Ontario, Canada
    Posts
    625
    ./mycat (Assuming that's what you ouputed to. However, if you did gcc mycat.c as Salem said, chances are you'll have to do ./a.out )
    Teacher: "You connect with Internet Explorer, but what is your browser? You know, Yahoo, Webcrawler...?" It's great to see the educational system moving in the right direction

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Lemme guess, you called the output program 'test' ?

    test is a build-in program which evaluates it's arguments as an expression and returns the answer in the exit status.

    Call it something else, or maybe try
    ./test
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Wireless Network Linux & C Testbed
    By james457 in forum Networking/Device Communication
    Replies: 3
    Last Post: 06-11-2009, 11:03 AM
  2. linux, doubles, and unions
    By paraglidersd in forum Linux Programming
    Replies: 14
    Last Post: 11-19-2008, 11:41 AM
  3. MMO Theory, How to make Gameloop & Sockets both work?
    By Zeusbwr in forum Game Programming
    Replies: 3
    Last Post: 08-01-2005, 12:29 PM
  4. Linux Linux why Linux??
    By afreedboy in forum Tech Board
    Replies: 146
    Last Post: 01-21-2004, 06:27 PM
  5. how do you make the X Y thing work?
    By bluehead in forum C++ Programming
    Replies: 2
    Last Post: 11-05-2001, 04:19 PM