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

GilGrissom

macrumors 65816
Original poster
Mar 13, 2005
1,042
1
Hey programmers of MacRumors, and otherwise more cleverer people than I!

I'm creating 2 programs to simulate a print que. One forks processes and communicates the PID and a random prioity number through a FIFO to a despooler program, which them reads then and is supposed to kill those processes off, as if they were being printed and no longer in the que!...great eh?!

My problem comes now that I suddenly cannot compile my main spooler/printer file. I get these error messages:

My Awful C Code! printer.c said:
printer.c:165: warning: passing argument 1 of 'gets' makes pointer from integer without a cast
printer.c:167: warning: passing argument 1 of 'strlen' makes pointer from integer without a cast
printer.c:167: warning: passing argument 2 of 'write' makes pointer from integer without a cast
Now I've done a little research and am I write in thinking this is most likely the GCC compiler being very picky? It didn't do it before and I'm not sure what I've changed to make it not work!

Is it one of those things that you can get the compiler to ignore and it will still work?

Any insights guys?

I'll post code if needed.
 

iMeowbot

macrumors G3
Aug 30, 2003
8,634
0
If not an actual mistake, this kind of message usually comes from an all the world's a VAX sort of assumption; i.e., it's probably a portability issue. It would be good to see the function call and see why it's saying that, and put an explicit cast (or change the variable type being used, if it really should be a pointer).
 

fimac

macrumors member
Jan 18, 2006
95
1
Finland
printer.c:167: warning: passing argument 1 of 'strlen' makes pointer from integer without a cast

The signature (or prototype, if you prefer) for strlen is something like:
Code:
size_t strlen(const char *s);

This gcc warning (it is only an error if you gave option "-Werror") is clearly telling that you are passing an integer. We would need to see the code to help further :)
 

GilGrissom

macrumors 65816
Original poster
Mar 13, 2005
1,042
1
Appologies for the lack of code!

I appreciate any help you guys have.

Links are here:

http://www.andrewshaw.net/printer.c
http://www.andrewshaw.net/killer.c

Just dumped the C code onto my ftp server. Didn't want to consume the bowls of this thread with my stupid code!

I'm guessing it's something daft I'm doing. I know what it's telling me, with the integers etc, but not sure why. I'm using FIFO to try and get printer.c to talk to killer.c, but are having to convert integers into characters to send down the pipe so that the killer.c process can pick them up and kill off the processes that it has been sent the PIDs for.

I appreciate any help and advice you can give, as well as splashes of cold water to slap me into gear!! :D

Yes, errors are pointless unless there is code. Especialy these types of errors, it's a matter of syntax and can be fixed easily :)

I hope so!...but I have a dreaded feeling I'm doing something fundamentally wrong which will require me to change how I'm doing something...as you can probably tell I'm no programmer and friend of coding! I try but it doesn't come naturally at all to me!
 

GilGrissom

macrumors 65816
Original poster
Mar 13, 2005
1,042
1
Hmmm...
Can you see what the program is trying to do? (appologies for bad commenting! You never think other outside people will ever actually get to see it!).

Every time a process is forked (or a print job created!) I need to send the PID of that process, along with a random number generated for it (it's prioity number) to the FIFO for the despooler to pick up and go...ah...thanks...thats prioity 2, let me kill off prioity 1 first, then I'll kill you off!...or whatever prioity it is!...but first things first...I need a compiling printer/spooler that can dump stuff on the FIFO.

The PID and prioities are obviously both ints, which is why I'm trying to convert them into characters for the pipe. Is there an easier way? I need both numbers being sent as they both relate to the same job.
 

GilGrissom

macrumors 65816
Original poster
Mar 13, 2005
1,042
1
If I need to make a string for the FIFO, can I use the gets() function like this????:

char string [256];
string = PID + Prioity integers //this isnt actual syntax obviously...
gets (string);
printf ("Data being sent is: %s\n",string);
return 0;

So the PID and prioity are technically entered into the string called "string" which can then be read?

Will that work?...or will it not let me, as it's technically a string from an int again?

This was compiling before...but now I'm trying to get teh FIFO to talk to the despooler it's not liking it.
 

GilGrissom

macrumors 65816
Original poster
Mar 13, 2005
1,042
1
Ok, so I've got it to compile now, but not sure whether I've still done the right thing or not.

I have updated the previous links with the new code.

I have changed this bit, entering another sprintf() statement to make what it was moaning about from an int to a char.

int fifoint1;
int myfifoNum;
int fifoint2;

mknod(FIFO_FILE, S_IFIFO | 0666, 0);

/* This next screen print is to warn the user about any possible failure in IPC and the processes being killed */
/* The DeSpooler program, mine is called Killer, needs to be open and running in order for the FIFO to work correctly */
/* A FIFO needs to be open at both ends in order to work correctly, a read and a write end, being Printer and Killer */

printf("At this stage the FIFO may fail if you do not have the killer.c program running.\n");
printf("Please ensure you are running the DeSpooler program, Killer, in order for this to work correctly\n");
fifoint2 = open(FIFO_FILE, O_WRONLY);

char fifochar1[100]; /* used to make fifoint1 into a character for gets */
sprintf( fifochar1, "%d", fifoint1 ); /* this is the int to string conversion using sprintf */

while (gets(fifochar1), !feof(stdin))
{
if ((myfifoNum = write(fifoint2, fifochar1, strlen(fifochar1))) == -1) /* Write fail */
{
perror("write");
}
else /* Write successful */
{
printf("\nPrint Job Sent to the Killer (DeSpooler). Information: %d bytes\n", myfifoNum);
}
}
Links in previous post for full code of each files.

Although both now compile, they don't seem to be talking. I don't get any error messages or anything, anyone see where I'm going wrong with this FIFO reading and writing???????
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,566
Hey programmers of MacRumors, and otherwise more cleverer people than I!

I'm creating 2 programs to simulate a print que. One forks processes and communicates the PID and a random prioity number through a FIFO to a despooler program, which them reads then and is supposed to kill those processes off, as if they were being printed and no longer in the que!...great eh?!

My problem comes now that I suddenly cannot compile my main spooler/printer file. I get these error messages:


Now I've done a little research and am I write in thinking this is most likely the GCC compiler being very picky? It didn't do it before and I'm not sure what I've changed to make it not work!

Is it one of those things that you can get the compiler to ignore and it will still work?

Any insights guys?

I'll post code if needed.

You can get the compiler to ignore it, and you can be sure it will crash your program. The problem here is not that gcc is being picky, the problem is in this case that gcc only gives a warning for something that is a blatant, horrible bug in your program.

You get this warning when you use an integer in a situation where you should have used a pointer. For example

char* p, q; // Can you see a problem here?
strlen (p); // No warning
strlen (q); // Warning, should be an error and it will crash.

Find out what is wrong with the code and fix it. gcc tells you where it is, so there should be no problem.
 

szark

macrumors 68030
May 14, 2002
2,886
0
Arid-Zone-A
I don't get any error messages or anything, anyone see where I'm going wrong with this FIFO reading and writing???????

Remove the mknod statement from killer.c. By using mknod in both programs, you are creating two "different" FIFOs which aren't connected to each other.
 

GilGrissom

macrumors 65816
Original poster
Mar 13, 2005
1,042
1
Remove the mknod statement from killer.c. By using mknod in both programs, you are creating two "different" FIFOs which aren't connected to each other.
I managed to get printer.c to compile using an extra sprintf() statement to convert what it was moaning about into a char/string.

I also managed to get my 2 programs talking on the FIFO, however the printer doesn't seem to be working properly thanks to the FIFO. It doesn't hit my menus anymore, letting me run the functions that forks the processes. If I try and tweak it so it does it then creates the processes but ignores the FIFO and will not establish the connection.

When the FIFO is up and connected, my program stops and waits for my input for some reason. Anything I type and press enter on simply gets sent to the killer program...the printer program goes no further...hits none of the other code it was hitting before, and I can't figure out why.

I have had to move the mknod in printer.c to the top of main for it to establish the connection with FIFO.

www.andrewshaw.net/printer.c
www.andrewshaw.net/killer.c
latest uploads there.
 

szark

macrumors 68030
May 14, 2002
2,886
0
Arid-Zone-A
Now that I've had a chance to really look at your code (printer.c):

Short Analysis:

You have a loop in front of your initial menu that performs a gets() from stdin repeatedly until eof is reached. That is the code waiting for your input.


Long Analysis:

Your code is overly complex and contains endless recursion. Here are my suggestions to improve it.

  • main() should contain the following:
    1. variable initialization
    2. mknod() call
    3. initial screen display
    4. mymenu() call
    5. return(0)
    in that order, and nothing else.

  • myfork() and myforkvar():
    • You are trying to use a pipe to send the priority and PID values from the child process to the parent, but the parent process already has that information.
    • The fork routine should also contain a section for the parent process (if pid > 0) which performs the FIFO open, write, and close. It should not call mymenu().
    • myforkvar() should call myfork() for each job to eliminate duplicate code. It should also not call mymenu().

  • mymenu() should have a loop (endless, or with an exit flag) in place of the if (menuagain == 1) statement, to continually execute the menu. It should definitely not call itself.

  • about() should not call main().

I'm a bit tired so feel free to let me know if anything I've said is confusing. ;)
 

GilGrissom

macrumors 65816
Original poster
Mar 13, 2005
1,042
1
Szark,

Many thanks for your time and input.

I think I understand most of what your saying.

This loop at the beginning waiting for eof, I'm not sure what I'd need instead.
This stuff inside the loop, is that the stuff I need to place in the fork processes, as you mentioned as well?

I always thought the FIFO bits were all together, but do parts need to be cut and pasted elsewhere?

I'll try and streamline the other bits you kindly point out while I try and get my head around this FIFO and loop problem! Any ideas on exactly how to do it?

Really appreciate the time you put into that!
 

szark

macrumors 68030
May 14, 2002
2,886
0
Arid-Zone-A
This loop at the beginning waiting for eof, I'm not sure what I'd need instead.

That section of code at the beginning reads like example code to get input from the command line and feed it into the FIFO. The gets()/eof loop serves no purpose in your program (as I understand it). The only FIFO code in your main() subroutine should be the mknod() statement.

This stuff inside the loop, is that the stuff I need to place in the fork processes, as you mentioned as well?

I always thought the FIFO bits were all together, but do parts need to be cut and pasted elsewhere?

Yes, those are the open and write statements I was referring to (along with a missing close statement).


From your description and code, it appears you want the user to choose a selection from the menu (1 or 3) which will create one or more print jobs. The priority and PID of each process will be transmitted to the killer process through the FIFO. So the logical place to put the FIFO write code would be in the myfork() routine after the job is created -- create job, then report job to killer. Like this:

Code:
int myfork(void)
{	

:
:   [other existing code]
:

random = rand()%10;

printf("\n    Child Process Being Created...please wait...\n");				/* A wait (sleep) comes up shortly.  This is to make it more realistic */
																				/* ...that a print job is being passed to the printer */
			
sleep(2);																	/*  Makes the process wait for 2 seconds...  */
																				/* ...as my code is too blindingly fast for me!  */
																		
pid = fork();																/* Process begins to fork!  Mother gives birth! Spooler spools! */
				
/* At this point, the child process begins, being careful that none-required duplicate code does not occur...*/
/* ...in both parent and child process, this happened and I caused exponential forking! woops!*/

if (pid == 0) 
{
	/*++++++++++++++++++++++++++CHILD PROCESS OF MYFORK CONTINUES HERE++++++++++++++++++++++++++*/

	printf("\nChild Prioity = %d", random);								/* Prints the PRIOITY of the child process on screen,which is a random number*/
	printf("\nChild PID = %d\n\n", getpid());							/* Prints the PID of the child process on screen */
	char printTemp[10];													/*    */
	sprintf(printTemp, "%i", random);									/* Sprint: A method of converting an int to char for the pipe */
																				/*  Info here: www.cppreference.com/stdio/sprintf.html */
	write(pipePrioity[1], printTemp, 5);								/* Write: places the PRIOITY for that job into the pipe */
	sprintf(printTemp, "%i", getpid());									/* As above, this time for the PID and not prioity number */
	write(pipePID[1], printTemp, 5);									/* As above, this time for the PID placing into the pipe */
}											
else if (pid > 0)
{
	/*++++++++++++++++++++++++++PARENT PROCESS OF MYFORK CONTINUES HERE, IF CHILD WAS CREATED SUCCESSFULLY++++++++++++++++++++++++++*/

	int myfifoNum;
	int fifoint2;
	char fifochar1[80];	/*  used to make priority and PID into a string for FIFO transmission */	

	sprintf( fifochar1, "%d|%d", random, getpid() );									/*  this is the int to string conversion using sprintf */

	fifoint2 = open(FIFO_NAME, O_WRONLY); 

	if ((myfifoNum = write(fifoint2, fifochar1, strlen(fifochar1))) == -1)	/*  Write fail  */
	{
		perror("write");
		printf("\nERROR WRITING TO PIPE\n");
	}
	else														/*  Write successful  */
	{
		printf("\nPrint Job Sent to the Killer (DeSpooler).");  //Size of packet sent: %d bytes\n", myfifoNum);
	}

	close(FIFO_NAME);
} 
else
{
	/*++++++++++++++++++++++++++PARENT PROCESS OF MYFORK CONTINUES HERE, IF CHILD WAS NOT CREATED++++++++++++++++++++++++++*/

	perror("myfork");													/* If it has failed, an error message is printed */
	printf("Error Creating Print Job.  Print Job Not Created");
	exit(1);															/* Once message has been displayed to the user, the program will quit */
																				/* As there is no point in it continuing it it cannot create a process */
}


Also, you might want to check your array indexes in killer.c -- you're defining temp1 as a 2 element array (indexes 0 and 1) but you're writing to indexes 1 and 2. ;)
 

FarmerBen

macrumors newbie
Feb 17, 2009
1
0
Birmingham
Confused

Hi guys,

I have been programming in C for a few months and have found your producer and consumer example, i am trying to run it but am stuck to what should be in the:

:
: [other existing code]
:


Any help would be so helpful as this is the best example I have found so far.

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