C write() function not working - c

I am trying to write into a file, but it is not working. I can open a file, but while writing in the file using write function, tt is writting in the stdout itself, and the content of the file I opened remain unchanged.
#include<stdio.h>
#include<sys/file.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<limits.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/uio.h>
main() {
char fn[30];
int fd,i=0;
int actualbytes,bytesstored;
char buffer[100];
printf("\nEnter the filename with path");
scanf("%s",fn);
if(fd=open(fn,O_WRONLY|O_CREAT,S_IWUSR|S_IWUSR)<0)
{
perror("open");
exit(0);
}
else
{
write(stdout,"\n\nEnter the contents for the file\n");
write(stdout,"press CTRl+D at the end of the file\n\n");
fflush(stdout);
while((buffer[i]=getc(stdin))!=EOF) i++;
buffer[i]='\0';
bytesstored=sizeof(buffer);
if(actualbytes=write(fd,buffer,bytesstored)<0)
{
perror("write");
exit(0);
}
else
{
write(stdout,"\n\nfile is opened successfully");
write(stdout,"\nThe contents are written"); fflush(stdout);
}
if(close(fd)<0)
{
perror("close");
exit(0);
}
else
printf("\nfile is closed");
}
}

< has higher precedence than =.
if((fd=open(fn,O_WRONLY|O_CREAT,S_IWUSR|S_IWUSR))<0)

There are a lot of problems with this code. Make sure you enable warnings on your compiler, it should complain about quite a few things:
write() is in unistd.h. You're not including that, so your program cannot be correct.
Once you include that, you'll notice (with warnings enabled), that you're calling it incorrectly at least 5 times: stdout is not a file descriptor, it's a FILE*.
Use the printf() family of functions to print things on the console.
Second big problem is your if statements that have assignments in them.
if (a = b < 0) { ... }
is equivalent to:
if (a = (b < 0)) { ... }
So it's not doing what you think it is. You need to use parenthesis:
if ((fd = open(...)) < 0) { ... }
Note: you're always writing the full buffer to the file. Not all of it has been initialized. That doesn't sound like what you're after. Try only writing the data that you've read (you have that stored in i).

Please note, from stdin(3):
#include <stdio.h>
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
stdin, stdout, are standard IO FILE * streams, for use with fprintf(3), fgets(3), and so forth.
read(2) and write(2) take filedescriptors (which are represented as ints).
Keeping the C-supplied standard IO streams and the Unix-supplied filedescriptors separate in your mind is vital to sane Unix programming; sorry it's complicated :) but it's well worth becoming an expert.
I suggest changing all your write(stdout,... to fprintf(stdout,....
Ah, I see Ignacio has spotted the core problem :) it's hard to put one past him.
Another issue to worry about, your scanf() call doesn't limit the length of input to the size of your buffer. Someone could overflow your buffer and scribble data of their choosing all over memory. It's not a big deal when you're learning, but this kind of bug is exactly how the first Internet worm infected some new machines, so it is well worth not making the same mistake again.
And the last issue I spotted is how you're writing out your buffer:
buffer[i]='\0';
bytesstored=sizeof(buffer);
if(actualbytes=write(fd,buffer,bytesstored)<0)
sizeof(buffer) is always going to return 100, because that is what you declared for buffer at the start of your program. So replace with this:
buffer[i++]='\0';
if(actualbytes=write(fd,buffer,i)<0)

As the others noted, there are a lot of problems with your code. Always instruct your compiler to show warnings. If you are using GCC then pass the argument -Wall to show all warnings. Now, if I do so with your code it suggests the following:
write.c:9: warning: return type defaults to ‘int’
write.c: In function ‘main’:
write.c:18: warning: suggest parentheses around assignment used as truth value
write.c:25: warning: implicit declaration of function ‘write’
write.c:34: warning: suggest parentheses around assignment used as truth value
write.c:45: warning: implicit declaration of function ‘close’
write.c:55: warning: control reaches end of non-void function
The first one means that your function main() defaults to int but you should always state a return type. On line 18 and 34 you need parentheses around the assignments before testing with < (as Ignacio said above). On line 25 and 45 it can't find the prototype for write() and close(), so you need to include the right header files. The last one means that you need to have a return statement (because it defaulted to type int).

just include and the warning will disappear.

Related

Calling yyrestart function in bison with no arguments causing sigsev on El Capitan

I'm curious about the function signature for yyrestart - namely in the lexer file I see that the signature is:
void yyrestart (FILE * input_file )
In my code I use yyrestart to flush the buffer, but I haven't been passing it any argument, it's just been empty:
yyrestart();
Which is currently working on every system we test on except for the latest version of OS X. Stepping through with GDB, it's clear on my rhel machine that just calling with no argument sets the file pointer to NULL:
yyrestart (input_file=0x0) at reglexer.c:1489
Whereas on El Capitan it comes through as garbage, which is causing the mem error later in generated code:
yyrestart (input_file=0x100001d0d) at reglexer.c:1489
I can't for the life of me figure out where yyrestart() is defined. Is there some macro in yacc/flex that defines the behavior for calling yyrestart with no arguments? If not, how is this even compiling?
*********** EDIT to Clarify the Compiling Question ************
As a small snippet to see what I'm talking about - this is what I have in a my .y file, which is executing the parser (this is a SLIGHT modification of what's this example):
int main() {
FILE *myfile = fopen("infile.txt", "r");
if (!myfile) {
fprintf(stderr, "can't open infile.txt\n");
return 1;
}
calcYYin = myfile;
do {
calcYYparse();
} while (!feof(calcYYin));
calcYYrestart();
return 0;
}
I can build that repository with whatever I want passed in as arguments to calcYYrestart() on that line. Substituting
calcYYrestart('a', 1, 5, 'a string');
still lets me compile the entire program using make (but a get a segv with bad input). But looking through the generated parcalc.c file, I don't see anything that would allow me to call calcYYrestart with anything except for a file pointer. I only see this as the prototype:
void calcYYrestart (FILE * input_file );
Where's the magic happening with the compiler that lets me put whatever I want as arguments to that generated function?
You are expecting C to gently lead you through the maze, holding your hand, chiding you when you err and applauding your successes.
These may not be unreasonable expectations for a language, but C is not that language. C does what you tell it to do, nothing more, and when your instructions fall short of clarity, it simply lets you fall.
Although, in its defense, you can ask it to be a bit more verbose. If you specify -Wall on the command line (at least with gcc and clang), the compiler will provide you with some warnings. [See note 1.]
In this case, it probably would have warned you that calcYYrestart was not declared, which would make it your responsibility to get the arguments right. The function is declared and defined in the lexer, but here you are using it in the parser, which is a separate compilation unit. You really should declare it in the parser prologue, but nothing will enforce the correctness of that declaration. (C++ would fail to link in that case, but C does not record argument types in the formal function name.)
It's worth noting that there are many problems with the sample code you are basing your work on. I'd suggest looking for a better bison/flex tutorial, or at least reading through the sections in the flex manual about how input is handled.
Here, I've added some annotations to the original example, which shows the calc.y bison input file:
/* This is unnecessary, since `calcYYparse` is defined in this file.
extern int calcYYparse();
*/
extern FILE *calcYYin;
/* Command line arguments are always good */
int main(int argc, char** argv) {
/* If there is an argument, use it. Otherwise, stick with stdin */
/* There is no need for a local variable. We can just use yyin */
if (argc > 1) {
calcYYin = fopen(argv[1], "r");
if (!calcYYin) {
fprintf(stderr, "can't open infile.txt\n");
return 1;
}
}
/* calcYYin = myfile; */
/* This loop is unnecessary, since yyparse parses input until it
* reaches EOF, unless it hits an error. And if it hits an error, it
* will call calcYYerror (below), which in turn calls exit(1), so it
* never returns.
*/
/* do { */
calcYYparse();
/* } while (!feof(calcYYin)); */
return 0;
}
void calcYYerror(const char* s) {
fprintf(stderr, "Error! %s\n", s);
/* Valid arguments to `exit` are 0 and small positive integers. */
exit(EXIT_FAILURE);
}
Of course, you probably don't want to just blow up the world if you hit a syntax error. The intention was probably to discard the rest of the line and then continue the parse. In that case, for obvious reasons, callYYerror should not call exit().
By default, after yyerror is called, yyparse returns immediately (after cleaning up its local storage) with an error indication. If you want it to instead continue, then you need to use an error production, which would be the best solution.
You could also simply call yyparse again, as in the example. However, that leaves an unknown amount of the input file in the flex buffer. There is no reason to believe that the buffer contains exactly the rest of the line in error. Since flex scanners typically read there input in large chunks (except for interactive input), resetting the input file with yyrestart will discard a random amount of input, leaving the input file pointer at a random position in the file, which probably does not correspond with the beginning of a new line.
Even if that were not the case, as with unbuffered (interactive) input, it is entirely possible that the error was detected at the end of a line, in which case the new line will already have been consumed. So discarding to the end of the current line will result in discarding the line following the error.
Finally, the use of feof(input) to terminate input loops is a well-known antipattern, and should be avoided in favour of terminating when an EOF is encountered while reading input. In the case of flex-generated scanners, when EOF is detected, the current input is discarded, and then (if yywrap doesn't succeed in creating a new input), the END indication is returned to the parser. By then, yyin is no longer valid (because it was discarded), and calling feof on it is undefined behaviour.
Notes
You get even more warnings by also specifying -Wextra. And you can make the compiler a little stricter by telling it to use the latest standard, -std=c11, instead of the 1989 version augmented with various gcc extensions, mostly now outdated.)

Opening a file in C through a proccess

I am trying to create a a program that does the following actions:
Open a file and read one line.
Open another file and read another line.
Compare the two lines and print a message.
This is my code:
#include <stdio.h>
#include <string.h>
int findWord(char sizeLineInput2[512]);
int main()
{
FILE*cfPtr2,*cfPtr1;
int i;
char sizeLineInput1[512],sizeLineInput2[512];
cfPtr2=fopen("mike2.txt","r");
// I open the first file
while (fgets(sizeLineInput2, 512, cfPtr2)!=NULL)
// I read from the first 1 file one line
{
if (sizeLineInput2[strlen(sizeLineInput2)-1]=='\n')
sizeLineInput2[strlen(sizeLineInput2)-1]='\0';
printf("%s \n",sizeLineInput2);
i=findWord(sizeLineInput2);
//I call the procedure that compares the two lines
}
getchar();
return 0;
}
int findWord(char sizeLineInput2[512])
{
int x;
char sizeLineInput1[512];
File *cfPtr1;
cfPtr1=fopen("mike1.txt","r");
// here I open the second file
while (fgets(sizeLineInput1, 512,cfPtr1)!=NULL)
{
if (sizeLineInput1[strlen(sizeLineInput1)-1]=='\n')
sizeLineInput1[strlen(sizeLineInput1)-1]='\0';
if (strcmp(sizeLineInput1,sizeLineInput2)==0)
//Here, I compare the two lines
printf("the words %s and %s are equal!\n",sizeLineInput1,sizeLineInput2);
else
printf("the words %s and %s are not equal!\n",sizeLineInput1,sizeLineInput2);
}
fclose(cfPtr1);
return 0;
}
It seems to have some problem with file pointers handling. Could someone check it and tell me what corrections I have to do?
Deconstruction and Reconstruction
The current code structure is, to be polite about it, cock-eyed.
You should open the files in the same function - probably main(). There should be two parallel blocks of code. In fact, ideally, you'd do your opening and error handling in a function so that main() simply contains:
FILE *cfPtr1 = file_open("mike1.txt");
FILE *cfPtr2 = file_open("mike2.txt");
If control returns to main(), the files are open, ready for use.
You then need to read a line from each file - in main() again. If either file does not contain a line, then you can bail out with an appropriate error:
if (fgets(buffer1, sizeof(buffer1), cfPtr1) == 0)
...error: failed to read file1...
if (fgets(buffer2, sizeof(buffer2), cfPtr2) == 0)
...error: failed to read file2...
Then you call you comparison code with the two lines:
findWord(buffer1, buffer2);
You need to carefully segregate the I/O operations from the actual processing of data; if you interleave them as in your first attempt, it makes everything very messy. I/O tends to be messy, simply because you have error conditions to deal with - that's why I shunted the open operation into a separate function (doubly so since you need to do it twice).
You could decide to wrap the fgets() call and error handling up in a function, too:
const char *file1 = "mike1.txt";
const char *file2 = "mike2.txt";
read_line(cfPtr1, file1, buffer1, sizeof(buffer1));
read_line(cfPtr2, file2, buffer2, sizeof(buffer2));
That function can trim the newline off the end of the string and deal with anything else that you want it to do - and report an accurate error, including the file name, if anything goes wrong. Clearly, with the variables 'file1' and 'file2' on hand, you'd use those instead of literal strings in the file_open() calls. Note, too, that making them into variables means it is trivial to take the file names from the command line; you simply set 'file1' and 'file2' to point to the argument list instead of the hard-wired defaults. (I actually wrote: const char file1[] = "mike1.txt"; briefly - but then realized that if you handle the file names via the command line, then you need pointers, not arrays.)
Also, if you open a file, you should close the file too. Granted, if your program exits, the o/s cleans up behind you, but it is a good discipline to get into. One reason is that not every program exits (think of the daemons running services on your computer). Another is that you quite often use a resource (file, in the current discussion) briefly and do not need it again. You should not hold resources in your program for longer than you need them.
Philosophy
Polya, in his 1957 book "How To Solve It", has a dictum:
Try to treat symmetrically what is symmetrical, and do not destroy wantonly any natural symmetry.
That is as valid advice in programming as it is in mathematics. And in their classic 1978 book 'The Elements of Programming Style', Kernighan and Plauger make the telling statements:
[The] subroutine call permits us to summarize the irregularities in the argument list [...]
The subroutine itself summarizes the regularities of the code.
In more modern books such as 'The Pragmatic Programmer' by Hunt & Thomas (1999), the dictum is translated into a snappy TLA:
DRY - Don't Repeat Yourself.
If you find your code doing the 'same' lines of code repeated several times, write a subroutine to do it once and call the subroutine several times.
That is what my suggested rewrite is aiming at.
In both main() and findWord() you should not use strlen(sizeLineInputX) right after reading the file with fgets() - there may be no '\0' in sizeLineInput2 and you will have strlen() read beyond the 512 bytes you have.
Instead of using fgets use fgetc to read char by char and check for a newline character (and for EOF too).
UPD to your UPD: you compare each line of mike2.txt with each line of mike1.txt - i guess that's not what you want. Open both files one outside while loop in main(), use one loop for both files and check for newline and EOF on both of them in that loop.

How can I write commands to the vxworks shell with a c program

If I wanted to run a shell command in linux with a c program, I would use
system("ls");
Is there a way I can accomplish this in Wind River vxworks?
I found the below example but I'm wondering do I need to include vxworks header files for this to work? I assume I do, but how do I figure out which one?
Example:
// This function runs a shell command and captures the output to the
// specified file
//
extern int consoleFd;
typedef unsigned int (*UINTFUNCPTR) ();
extern "C" int shellToFile(char * shellCmd, char * outputFile)
{
int rtn;
int STDFd;
int outFileFd;
outFileFd = creat( outputFile, O_RDWR);
printf("creat returned %x as a file desc\n",outFileFd);
if (outFileFd != -1)
{
STDFd=ioGlobalStdGet(STD_OUT);
ioGlobalStdSet(STD_OUT,outFileFd);
rtn=execute(shellCmd);
if (rtn !=0)
printf("execute returned %d \n",outFileFd);
ioGlobalStdSet(STD_OUT,STDFd);
}
close(outFileFd);
return (rtn);
}
I found the code segment below worked for me. For some reason changing the globalStdOut didn't work. Also the execute function did not work for me. But my setting the specific task out to my file, I was able to obtain the data I needed.
/* This function directs the output from the devs command into a new file*/
int devsToFile(const char * outputFile)
{
int stdTaskFd;
int outputFileFd;
outputFileFd = creat( outputFile, O_RDWR);
if (outputFileFd != ERROR)
{
stdTaskFd = ioTaskStdGet(0,1);
ioTaskStdSet(0,1,outputFileFd);
devs();
ioTaskStdSet(0,1,stdTaskFd);
close(outputFileFd);
return (OK);
}
else
return (ERROR);
}
If this is a target/kernel shell (i.e. running on the target itself), then remember that all the shell commands are simply translated to function calls.
Thus "ls" really is a call to ls(), which I believe is declared in dirLib.h
I think that the ExecCmd function is what you are looking for.
http://www.dholloway.com/vxworks/6.5/man/cat2/ExecCmd.shtml
As ever, read the documentation. ioLib.h is required for most of the functions used in that example, and stdio.h of course for printf().
As to the general question of whether you need to include any particular headers for any code to compile, you do need to declare all symbols used, and generally that means including appropriate headers. The compiler will soon tell you about any undefined symbols, either by warning or error (in C89/90 undefined functions are not an error, just a bad idea).

Casting to void doesn't remove warn_unused_result error

In a test, I'm discarding anything from stderr since it clutters the output of the test case. I'm using the following code:
freopen("/dev/null", "w", stderr);
When compiling with -Wall -Werror, I get the error
error: ignoring return value of ‘freopen’, declared with attribute warn_unused_result
which is expected. However, the usual solution of casting to void doesn't seem to work. That is, changing the code to
(void) freopen("/dev/null", "w", stderr);
still produces the same warning. I don't care if this function fails since the worst case scenario is a bit of extra output. Any other way I can fix this?
EDIT: I know I could introduce an extra unnecessary variable. I would really like to know why casting to void doesn't work.
UPDATE:
I decided to go with this:
FILE *null = fopen("/dev/null", "w");
if (null) { fclose(stderr); stderr = null; }
After reading the freopen documentation more carefully, I see that if opening /dev/null fails, stderr will still be destroyed. This solves that problem.
A little heavy on the GCC extensions, but no externally visible variables:
#define ignore_result(x) ({ typeof(x) z = x; (void)sizeof z; })
ignore_result(freopen("/dev/null", "w", stderr));
Why not simply use the result, as the warning suggests you should.
if (freopen("/dev/null", "w", stderr) == 0)
...oops...lost stderr...hard to report errors...
Since the function is declared with the 'warn_unused_result' attribute, you will get the warning unless you use the return value. Since the function either returns null on failure or the file stream argument on success, you might think about assigning the result. However, you should not
assign to stderr like that (see below), so this is a bad idea:
stderr = freopen("/dev/null", "w", stderr);
Theoretically, you should make that check; there are dire (and implausible) circumstances under which you could fail to open "/dev/null".
Footnote 229 in the C99 standard notes:
229) The primary use of the freopen function is to change the file associated with a standard text stream
(stderr, stdin, or stdout), as those identifiers need not be modifiable lvalues to which the value
returned by the fopen function may be assigned.
Therefore, the assignment is ill-advised. But testing the return value would deal with the compiler warning and might help prevent core dumps too. It is unlikely to improve your code coverage figures, though (the error path is not going be taken very often; it will be hard to force coverage of the error handling).
Note that the POSIX description of freopen() has some moderately caustic comments about the design of freopen(), which was invented by the C standard committee (1989 version), presumably without input from POSIX.
int tossmeout = freopen("/dev/null", "w", stderr);
As comments below try
FILE *tossmeout = freopen("/dev/null", "w", stderr);
and
(void *)freopen("/dev/null", "w", stderr);
If you really have to use the C language (not C++) then you may use this workaround:
inline void ignore_result_helper(int __attribute__((unused)) dummy, ...)
{
}
#define IGNORE_RESULT(X) ignore_result_helper(0, (X))
For example
typedef struct A
{
int x;
} A;
__attribute__((warn_unused_result)) A GetA()
{
A const a;
return a;
}
int main()
{
IGNORE_RESULT(GetA());
return 0;
}

runtime error (SIGSEGV)

can anyone tell me whats wrong in the following program that accepts 1 or 2 digit integers untill it encounters the number 42 after which it prints the previously entered numbers??when i upload this to the sphere online judge site it says compilation successful but runtime error (SIGSEGV).
#include <stdio.h>
int main()
{
int i;
FILE *fp;
fp=fopen("\\db.txt","w+");
if(fp==NULL)
{
printf("file not exitsts and cant be created");
system("exit");
}
while(1)
{
scanf("%d",&i);
if(i==42)
break;
else
{
fprintf(fp,"%d\n",i);
}
}
fclose(fp);
fp=fopen("\\db.txt","r+");
if(fp==NULL)
{
printf("file not exitsts and cant be created");
system("exit");
}
fscanf(fp,"%d",&i);
printf("%d\n",i);
while((!feof(fp)))
{
fscanf(fp,"%d",&i);
if(!feof(fp))
printf("%d\n",i);
}
fclose(fp);
return 0;
}
It seems like you're trying to answer this: http://www.spoj.pl/problems/TEST/ . This problem certainly does not require you to read or write anything from a file, and their server may not allow you to open files on its disk. Even if it does, you're trying to use a windows-style path (with a backslash) on what may be a non-Windows server. And even if it does allow file creation and windows-style path separation, you are trying to create your file in the filesystem root directory, and they almost certainly do not allow file creation there.
Combined with the system("exit") issue that everyone pointed out where it doesn't actually exit the program, this will cause you to receive a NULL file pointer and crash when you try to use it.
Re-read the problem description - you're over-thinking it. It doesn't say anywhere that you have to wait until you get a 42 to print out the other numbers. All you have to do is print back what is entered until you get a 42. That should make the solution much simpler. It's not supposed to be even a mildly challenging problem; it's just supposed to familiarize you with their system.
I don't know what you think:
system("exit");
will do, but the way to exit a program in C is:
exit(1);
You should replace
system("exit");
with
exit(1);
or, because you're already in main:
return 1;
I suspect the SIGSEGV is caused because you cannot write to the file \\db.txt, but the program continues because system("exit") is not causing it to terminate.
On an semi-related note, SIGSEGV is usually a Unix signal, and path separators on Unix are / rather than \.
I don't know precisely the cause of the SEGV, but I guess it is because the input doesn't match what you expect. In any case, this line doesn't do what you think it does:
system("exit");
at which line do you receive the error?
is your empty #include intended? i think it should mean #include
have you got the error for every input or just for 42?
regards
SIGSEGV is an access violation error, which indicates a null pointer. Since system("exit") isn't doing anything, fp is getting set to null, and then when you try to use that pointer (for example with fprintf())... boom, your program crashes.
Replace system("exit") with return 1 (or whatever error code you desire), that should fix it.
$ gcc -Wall test.c -o test
test.c: In function ‘main’:
test.c:8: warning: implicit declaration of function ‘system’
$ ./test
1
2
3
10
42
1
2
3
10
But yes, I do agree that the system("exit") does not what you expect. What you are exiting from, with that call, is a subshell that is spawned by your program, and then goes on. From the system man page
The system() function hands the
argument command to the command
interpreter sh(1). The calling
process waits for the shell to finish
executing the command, ignoring SIGINT
and SIGQUIT, and blocking SIGCHLD.

Resources