Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

trey5498

macrumors regular
Original poster
Jun 16, 2008
191
0
Code:
if ([system("lpstat -a Printer1 | grep -o "accepting"")] == accepting)

Here is what I got. The system call works, but it is not working in the if statement

and when I make is


Code:
if (system("lpstat -a Printer1 | grep -o "accepting"") == accepting)
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Are you trying to run a system command and read in its output?

If so, you need a file descriptor, and assign the value of popen:
http://www.manpagez.com/man/3/popen/

something like:

Code:
FILE *myFD = NULL;
myFD = popen("lpstat -a Printer1 | grep -o "accepting","r");
if(myFD == NULL) {
  //There was a problem
}
/*
read from myFD using fgets, etc. into a character buffer
*/
pclose(myFD);

-Lee
 

trey5498

macrumors regular
Original poster
Jun 16, 2008
191
0
no what I am doing is calling a system command to display is a printer is already installed. No files involved. The line:

Code:
system("lpstat -a Printer1 | grep -o "accepting"")

it will get the word grab accepting out of "Printer1 accepting requests since friday ......" Basically if the printer is there and i grep the accepting, I am trying to compare string to string. and the file descriptor is the way? ok I will take a look into that a little more
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
popen is the way to read the output of a system command into your program. In this case, after the popen you would read from the file descriptor and see what the line is. Grep might not do what you think it does. You could do something like:
Code:
myFD = popen("lpstat -a Printer1 | grep -o \"accepting\"" | wc -l,"r");

Then when you read from there the output will be 0 if there is no line containing accepting or 1 if there is a line containing accepting. you will still read it as a character buffer, so you'd need to use something like:
Code:
strncmp(buffer,"1",1);

In unix everything is a file. In this case the file descriptor is reading/writing to the pipes for stdin and stdout for your commands. The pipes are files, like everything else.

-Lee
 

trey5498

macrumors regular
Original poster
Jun 16, 2008
191
0
Code:
myFD = popen("lpstat -a CSE-211-DJQ | grep -o \"accepting\"","r");
if (myFD == NULL) {
	[cse211djq setToolTip:@"CSE Plotters"];		 
} else {
	[cse211djq setToolTip:@"Printer already Installed"];
	[cse211djq setEnabled:false]; 
}
myFD = NULL;
myFD = popen("lpstat -a ARC-118-DJQ | grep -o \"accepting\"","r");
if (myFD == NULL) {
	[arc118djq setToolTip:@"Architecture Plotters"];		 
} else {
	[arc118djq setToolTip:@"Printer already Installed"];
	[arc118djq setEnabled:false]; 
}
Rest of the printers (total of 17)

strncmp(buffer,"1",1);
pclose(myFD);

Yields:

error: syntax error before string constant
warning: data definition has no type or storage class

to the strncmp command

and:

warning: parameter names (without types) in function declaration
warning: data definition has no type or storage class

to the pclose.

Have no idea about the strncmp but I am sure I can find something while searching or does it need to be called after setting myFD? However do I need to set myFD to null before closing it?

the grep command yeild ONLY the "accepting" if the printer is installed, that is tested and works ;)
 

trey5498

macrumors regular
Original poster
Jun 16, 2008
191
0
Update figured some of it out but I have another issue and moving pclose up a little bit in the entire .m file fixed its warnings:

Code:
myFD = popen("lpstat -a CSE-211-DJQ | grep -o \"accepting\"","r");
if (strcmp (myFD,"accepting")) {
		
		[cse211djq setToolTip:@"Printer already Installed"];
		[cse211djq setEnabled:false]; 

} else {
		[cse211djq setToolTip:@"CSE Plotters"];
}

yeilds a warning: passing argument 1 of 'strcmp' from incompatible pointer type after the use of strncmp even when i change the "accepting" to a "1"
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I was more pointing out what system calls to make to accomplish this.

You will need to use popen to run the command and get a file descriptor to it's stdout.

You will need to use fgets or something similar to read in to a char buffer from the file descriptor you opened.

You can then use strncmp to compare the char buffer you read to whatever. I didn't see the -o, so you could use strncmp to compare what you read to "accepting" as a string literal.

Close the file descriptor with pclose.

Repeat this process for each thing you need to examine.

-Lee
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Code:
myFD = popen("lpstat -a CSE-211-DJQ | grep -o \"accepting\"","r");
if (strcmp (myFD,"accepting")) {
		
		[cse211djq setToolTip:@"Printer already Installed"];
		[cse211djq setEnabled:false]; 

} else {
		[cse211djq setToolTip:@"CSE Plotters"];
}

yeilds a warning: passing argument 1 of 'strcmp' from incompatible pointer type after the use of strncmp even when i change the "accepting" to a "1"

This is no good. From terminal do "man strncmp" to see what arguments you need. It is two const char *s and 1 size_t. You are passing one FILE * and one const char * to strcmp. You need to read from the FILE * into a char *, then do the comparison. You need to compare the result of strcmp or strncmp to 0. If the result is equal to 0, the strings match. If it is not equal to 0, they do not match.

-Lee
 

trey5498

macrumors regular
Original poster
Jun 16, 2008
191
0
ahhh kk, well I have looked a little close and have figured some of the problems going and have figured out some. I will continue to look. The other problem is more down the line of importing headers (simple I know) However when I try to import the variables from lets say tooltips.h to dvrchk.m it seems I have to redeclare them? is this true?
 

trey5498

macrumors regular
Original poster
Jun 16, 2008
191
0
Code:
myFD = popen("lpstat -a CSE-211-DJQ | grep -o \"accepting\"","r");.
fgets(buffer, 10, myFD);
if (strncmp (buffer,"accepting",9) == 0) {
		
		[cse211djq setToolTip:@"Printer already Installed"];
		[cse211djq setEnabled:false]; 

} else {
		[cse211djq setToolTip:@"CSE Plotters"];
}


WORKS!!!!!! Thank you for your patience ;) Also thank you for pointing me in the direction however making me figure it out myself ;)
 

lazydog

macrumors 6502a
Sep 3, 2005
709
6
Cramlington, UK
Code:
Rest of the printers (total of 17)

Congratulations on getting your code to work, but I noticed the above comment. Not sure how many code blocks your are copying for all 17 printers but it might be worth thinking about getting rid of all this duplication - in the short term you may only save some typing and cutting and pasting, but in the long run your code will be easier to debug and maintain.

Best way is to create a printer class with members for the printer attributes, eg name etc, and methods for doing whatever it is you need to do to each printer. You would then maintain an array or set of printers. Adding or removing printers would be easy... well depending on how you've set up the UI part of your app. Ideally, your app, including the UI, should not be hard coded to any particular list of printers,.

If you prefer not to use objects/classes you can use a c struct to represent a printer and functions to initialise and manipulate the printers (passing a printer struct as an argument).

good luck

b e n
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Code:
myFD = popen("lpstat -a CSE-211-DJQ | grep -o \"accepting\"","r");.
fgets(buffer, 10, myFD);
if (strncmp (buffer,"accepting",9) == 0) {
		
		[cse211djq setToolTip:@"Printer already Installed"];
		[cse211djq setEnabled:false]; 

} else {
		[cse211djq setToolTip:@"CSE Plotters"];
}


WORKS!!!!!! Thank you for your patience ;) Also thank you for pointing me in the direction however making me figure it out myself ;)

You're welcome. I'm glad this is working, but I wanted to ensure that you are using pclose after each popen when you are done reading the associated file handle. If not, you are leaking file handles and this could lead to a "too many open files" error. This can be infuriating to track down.

-Lee
 

ElectricSheep

macrumors 6502
Feb 18, 2004
498
4
Wilmington, DE
You're welcome. I'm glad this is working, but I wanted to ensure that you are using pclose after each popen when you are done reading the associated file handle. If not, you are leaking file handles and this could lead to a "too many open files" error. This can be infuriating to track down.

-Lee

I haven't played around with it too much, but I wonder if the clang static analyzer would catch bugs like leaked file descriptors. It's something I've been meaning to investigate.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I haven't played around with it too much, but I wonder if the clang static analyzer would catch bugs like leaked file descriptors. It's something I've been meaning to investigate.

I have not tried clang before. I wrote a test program for this, and I'm not sure if clang is failing for some reason or if it is running successfully and is failing to detect the bug. I'm pretty sure clang is failing, but if you have it set up and it is working for you, you can test this with the code I wrote:
Code:
#include <stdio.h>
#include <string.h>
char *get_output_line(char *);
int main(int argc, char *argv[]) {
  char res[256];
  char *res_ptr = NULL;
  res_ptr=get_output_line("ls -l");
  if(res_ptr != NULL) {
    strncpy(res,res_ptr,(size_t)256);
    printf("Ls res: %s\n",res);
  } else {
    printf("Could not get result\n");
  }
  res_ptr=get_output_line("uname");
  if(res_ptr != NULL) {
    strncpy(res,res_ptr,(size_t)256);
    printf("uname res: %s\n",res);
  } else {
    printf("Could not get result\n");
  }
  res_ptr=get_output_line("uptime");
  if(res_ptr != NULL) {
    strncpy(res,res_ptr,(size_t)256);
    printf("uptime res: %s\n",res);
  } else {
    printf("Could not get result\n");
  }
  return 0;
}

char *get_output_line(char *command) {
  FILE *my_file = NULL;
  char result[256];
  if(command == NULL) return NULL;
  if(strlen(command) <= 0) return NULL;
  
  my_file = popen(command,"r");
  if(my_file == NULL) return NULL;
  fgets(result,(size_t)256,my_file);
  return result;
}

I don't think there are other bugs, so the only thing it should detect (if it can) is the failure in get_output_line to pclose my_file.

-Lee
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.