"expected declaration specifiers" error message - c

I'm currently learning the C language in college so this is a homework assignment but I have a small problem. I'm guessing I've just misjudged the syntax or are missing something really obvious. My compiler is telling me that there is:
expected declaration specifiers or "..." before constant
and pointing to the O_RDWR.
I've googled and searched on Stack Exchange but there doesn't seem anything specific to it. Following the syntax in a C reference it's fine. I've looked around and it says I have not predefined the typedef but I've tried that to no avail.
I've starred the section that is causing the problem according to the compiler with **
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
int count;
printf ("This program was called \"%s\".\n",argv[0]);
if (argc > 1)
{
for (count = 1; count < argc; count++)
{
printf("argv[%d] = %s\n", count, argv[count]);
}
}
else
{
printf("The command had no arguments.\n");
}
if (argc == 4)
{
printf("There are the correct number of arguments(4)");
}
else
{
printf("Not enough arguments! please try again");
}
**int open(const char *argv[1], O_RDWR);
return 0;**
}

int open(const char *argv[1], O_RDWR);
What are you trying to do by this statement? Compiler treats this as function declaration, not function call. And it fails because O_RDWR is not a type name. If you need to call open(), syntax shall be like this:
int fd = open(argv[1], O_RDWR);
if(fd != -1)
{
// File opened OK. Proceed with file operations.
}
else
{
// File failed to open. Handle error occured
}

Try open(argv[1], O_RDWR); - you don't need to specify the arg's type or the return value.
... and I'm assuming the **'s are just to highlight the problem area - if not, they should go too... edit: just noticed you said that in the question!

The open call returns a HANDLE to the specified file of type int. So you only have to declare an int type HANDLE to collect from open. So,
int FileDesc ;
FileDesc = open( argv[1], O_RDWRD ) ;
// Check for Errors here

Related

How to choose the error code for an error?

Suppose I am asked to output an error if a certain file exist.
for example
I am asked to create a file called "del.txt", however, I have to check if such file exist first, and if it does I have to output an error of code 2.
So I know I have to use the O_EXCL to check if the file exist or not, and if it does I should give an error. however the error code is undefined, but I want to set it to 2.
Any idea how?
Here is my current code:
char *filename = "del.txt";
int n;
if((n = open(filename, O_EXCL) > 0){
perror(filename);
exit(1);
};
I am currently getting this:
del.txt: Undefined error: 0
The error check should be < 0, not > 0, the flags are missing an access mode (O_RDONLY/O_WRONLY/O_RDWR), and an O_CREAT needs to be used with O_EXCL (or else, POSIX says, the behavior is undefiend).
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
char const *filename = "del.txt";
int n;
if((n = open(filename, O_RDONLY|O_CREAT|O_EXCL) < 0)){
perror(filename);
exit(1);
};
}

RPC Client gives Can't encode arguments

I'm trying to write the simpliest client in RPC with this code:
#include <stdio.h>
#include <stdlib.h>
#include <rpc/rpc.h>
int main(int argc, char *argv[]){
int stat;
char out;
char in='f';
if(stat=callrpc(argv[1],0x20000001, 1, 1, (xdrproc_t)xdr_void, &in, (xdrproc_t)xdr_char, &out)!=0){
clnt_perrno(stat);
exit(1);
}
exit(0);
}
It compiles, but when I try to run it, it gives me a "RPC: Can't encode arguments"
EDIT: Actually the server do not recieve any argument neither it send back anything, that's why I put a xdr_void added &in and &out to avoid segmentation fault error.
You are missing some parentheses:
if (stat = callrpc(...) != 0)
is evaluated to
if (stat = (callrpc(...) != 0))
which always assigns 1 to stat in case of an error, which is RPC_CANTENCODEARGS. You need
if ((stat = callrpc(...)) != 0)
to get the real error code and message printed in
clnt_perrno(stat);

fopen returns null and perror prints invalid argument

I created a file named "test" but I'm unable to open it using fopen.
Here is the code-
#include<stdio.h>
int main()
{
FILE *fp;
fp=fopen("test.txt","r");
if(fp==NULL)
{
perror("Error: ");
}
fclose(fp);
return 0;
}
When I run the above code, I get the following output:
Error: Invalid argument
What could be the reason? When does perror return "Invalid argument" error message?
Have a look at man fopen:
EINVAL The mode provided to fopen(), fdopen(), or freopen() was invalid.
Probably test.txt is not readable.
Try compiling with -g. This lets you use gdb to debug the program step by step; look up how to use it. Probably a better way of doing this is with stat(2). Here is a sample of code that will return an error if the file does not exist, or is not a regular file:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
struct stat s;
int check = stat("test.txt", &s);
if(check != 0){
printf("ERROR: File does not exist!\n");
return -1;
}
return 0;
}
Stat stores a lot of information about a file (such as lenght, type, etc.) in the struct stat, which in this case is named "s". It also returns an integer value, which is non-zero if the file does not exist.

beginner in C under linux. write function doesn't work properly

I'm trying to write a C program, that make user able to write stuff in a file. My Problem is that after making and running the program the file stay empty ?? any idea how can I solve this.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
// the user should give a file to write the file
int main (int argc , char**argv)
{
int fd; // file descriptor
char ret; // the character
int offset;
if(argc != 2) {
printf("You have to give the name or the path of the file to work with \n");
printf("Exiting the program \n")
return -1;
}
fd = open (argv[1], O_WRONLY/*write*/|O_CREAT/*create if not found */, S_IRUSR|S_IWUSR/*user can read and write*/);
if (fd == -1) {
printf("can'T open the file ");
return -1;
}
printf("At wich position you want to start ");
scanf("%d",&offset);
lseek(fd,offset,SEEK_SET);
while(1) {
ret = getchar();
if(ret == '1') {
printf("closing the file");
close (fd);
return 1;
}
else
write (fd,red, sizeof(char));
}
return 0;
}
thanks in advance for you help.
I have made some changes,this should work:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main (int argc , char**argv)
{
int fd; // file descriptor
char ret; // the character
int offset;
if(argc != 2){
printf("You have to give the name or the path of the file to work with \n");
printf("Exiting the program \n"); **//There was ';' missing here**
return -1;
}
fd = open (argv[1], O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
if (fd == -1) {
printf("can'T open the file ");
return -1;
}
printf("At wich position you want to start ");
scanf("%d",&offset);
lseek(fd,offset,SEEK_SET);
while(1){
ret = getchar();
if(ret == '1'){
printf("closing the file");
close (fd);
return 1;
}
else
write (fd,&ret, sizeof(char)); **//red has been changed to &ret**
}
return 0;
}
One error I can notice, the call of write function:
write (fd,red, sizeof(char));
should be:
write (fd, &red, sizeof(char));
You forgot & before red, write need address.
syntax of write: int write( int handle, void *buffer, int nbyte );
This will cause an undefined behavior in your code at run time
Edit: in write function you are using red that is not defined, I think it should be ret variable in your code. correct it as write (fd, &ret, sizeof(char));
second, you forgot ; after printf("Exiting the program \n") in if, but I also think its mistake while posting question as you says you are getting run time error.
side note: If you are using gcc compiler then you can use gcc -Wall -pedantic to generate warnings
It should be:
write (fd,&ret, sizeof(char));
write takes the pointer to the memory position, and since ret is a single char, you need to pass a pointer to it.

changing a program in c, so it takes an optional command line argument *infile*

Now I do have a hw question for everyone...I've been staring at this for a couple of days kind of tinkering and playing around but even with that I end up with a load of errors...
What I'm trying to do is take the program below and change it so that it takes an optional command line argument infile. If infile is given, then copy infile to standard output, otherwise copy standard input to standard output as before.
The trick about this is that the solution must use the original copy loop (lines 9-11) for both cases. One can only insert code, and not change any of the existing code. Any help would be great. Thanks.
/* $begin cpfile */
include "csapp.h"
int main(int argc, char **argv)
{
int n;
rio_t rio;
char buf[MAXLINE];
Rio_readinitb(&rio, STDIN_FILENO); //line 9
while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) //line 10
Rio_writen(STDOUT_FILENO, buf, n); //line 11
/* $end cpfile */
exit(0);
/* $begin cpfile */
}
/* $end cpfile */
C programs get command line arguments through the two arguments to main(), traditionally called argc and argv (for argument count and argument vector, respectively).
Arguments are not "named" anything, they're just strings.
A solution for you could look like this:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fileno;
/* ... your definitions should remain here, too */
if(argc > 1)
{
/* Assume first argument is filename, and open it. */
fileno = open(argv[1], O_RDONLY);
if(fileno < 0)
{
printf("Unable to open file, aborting\n");
return 1;
}
}
else
fileno = STDIN_FILENO;
/* ... your code goes here ... */
}
Then you'd of course need to change the call to Rio_readinitb() to use the fileno variable for the file descriptor.
If you literally can't change that line, for whatever reason ... I guess you can use the preprocessor to make the symbol evaluate to the new variable name:
#undef STDIN_FILENO
#define STDIN_FILENO fileno
This is of course not exactly pretty, but should work.
Make sure you put those preprocessor macros after the fileno = STDIN_FILENO; line.
You can insert dup2 before the lines 9 - 11 and it seems that you will not need change code on the lines 9 - 11. This is an example.
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int file_handle;
int dup2_res;
if (argc == 2) {
file_handle = open(argv[1], O_RDONLY);
dup2_res = dup2 (file_handle, STDIN_FILENO);
}
char buffer[100];
ssize_t read_bytes = 1;
while (read_bytes)
{
read_bytes = read(STDIN_FILENO, &buffer, sizeof(buffer) );
buffer[read_bytes] = 0;
printf("%s", buffer);
}
close(file_handle);
return 0;
}
If STDIN_FILENO cannot be reassigned, it sounds like a task for freopen():
freopen(argv[1], "r", stdin);

Resources