Read command result error (fgets)
I wrote a simple cocoa app with a button.
When the button is clicked, a timer is triggered:
[NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(readCommandResult:)
userInfo:nil
repeats:YES];
And here is the timer:
-(void)readCommandResult:(NSTimer *) timer
{
char ps_cmd[256] = {"ls"};
BOOL isFgetsOK = NO;
FILE *fp = popen(ps_cmd, "r");
if (fp) {
char line[4096];
while (line == fgets(line, 4096, fp)) {
isFgetsOK = YES;
}
pclose(fp);
}
else {
NSLog(@"popen error");
}
if (!isFgetsOK) {
NSLog(@"fgets error");
}
}
When I run the app, I will get the "fgets error" sometimes, it seems like "line == fgets(line, 4096, fp))" is failed but I don't why?
Could some please explain it to me why I get a "fgets error" here sometimes randomly??
PS: I tried to change the comamnd (from "ls" to "ps"); In the terminal, I got the result:
PID TTY TIME CMD
744 ttys000 0:00.02 -bash
And the new code in the timer:
-(void)readCommandResult:(NSTimer *) timer
{
char ps_cmd[256] = {"ps"};
BOOL isFgetsOK = NO;
FILE *fp = popen(ps_cmd, "r");
if (fp) {
char line[4096];
while (line == fgets(line, 4096, fp)) {
NSLog(@"length:%d line:%s", strlen(line), line);
isFgetsOK = YES;
}
pclose(fp);
}
else {
NSLog(@"popen error");
}
if (!isFgetsOK) {
NSLog(@"fgets error");
}
}
And I got th开发者_StackOverflow社区e log:
19:56:23.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:23.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:24.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:24.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:25.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:25.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:26.780 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:26.781 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:27.782 TopDemo[856:a0f] fgets error
19:56:28.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:28.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:29.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:29.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:30.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:30.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:31.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:31.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:32.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:32.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:33.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:33.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:34.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:34.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:35.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:35.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:36.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:36.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:37.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:37.783 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:38.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:38.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:39.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:39.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:40.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:40.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:41.782 TopDemo[856:a0f] fgets error
19:56:42.783 TopDemo[856:a0f] fgets error
19:56:43.782 TopDemo[856:a0f] fgets error
19:56:44.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:44.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:45.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:45.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:46.782 TopDemo[856:a0f] fgets error
19:56:47.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:47.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
19:56:48.781 TopDemo[856:a0f] length:29 line: PID TTY TIME CMD
19:56:48.782 TopDemo[856:a0f] length:31 line: 744 ttys000 0:00.02 -bash
And I tried to run the app several times and the "fgets error" come out randomly...
From the manpage (http://pubs.opengroup.org/onlinepubs/007908799/xsh/fgets.html):
Upon successful completion, fgets() returns s. If the stream is at end-of-file, the end-of-file indicator for the stream is set and fgets() returns a null pointer. If a read error occurs, the error indicator for the stream is set, fgets() returns a null pointer and sets errno to indicate the error.
On end of file, it returns null, and if the file is less than 4096 characters, it would hit EOF on the first iteration, so isFgetsOK = YES;
would not be reached.
Sorry, misinterpreted... It returns null if the stream is at EOF when fgets is called, not if it reaches EOF during the call... ^^;
精彩评论