![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Newbie
|
new unix problem: signals and write() calls
The following code will print prime numbers and output them to a file specified by the user. Also, it will call the alarm() based on values passed on the command line. The SIGALRM and the SIGUSR1 will cause the program to print the last prime number generated. I'm having problems doing my write(). It should be the most straightforward function but I'm really tired and I can't seem to figure it out. There's also a bug with the way I implemented my command line arguments to call the alarm() but I'm not requesting help with that. I just haven't gotten to fixing it yet.
Thanks in advance. Sorry for how ugly the code is. #include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <list>
#include <algorithm>
#include <fcntl.h>
using namespace std;
void generatePrimesFile(int*, char*);
void usr1_handler(int);
void alarm_handler(int);
list<int> alarm_values;
//I don't like globals but we can't pass the handler functions anything
int currentPrime = 1;
int main(int argc, char *argv[]) {
if(argc < 2){
cerr << "Usage: Lab6 <file to be written> <optional time>" << endl;
return 1;
}
char * name = argv[1];
int * cp_ptr = ¤tPrime;
// Setup the signal handlers
struct sigaction usr1Act;
struct sigaction alarmAct;
usr1Act.sa_handler = usr1_handler;
sigemptyset( &usr1Act.sa_mask );
usr1Act.sa_flags = SA_RESTART;
alarmAct.sa_handler = alarm_handler;
sigemptyset( &alarmAct.sa_mask);
alarmAct.sa_flags = SA_RESTART;
if( sigaction( SIGUSR1 , &usr1Act, NULL ) == -1 ) {
//syserr("sigaction");
perror( "sigaction" );
exit( 1 );
}
if( sigaction( SIGALRM, &alarmAct, NULL) == -1 ) {
perror( "sigaction alarm");
exit(1);
}
//fill alarm values list
alarm_values.clear();
for(int i= 2; i < argc; i++){
alarm_values.push_back(i);
}
//sort it
alarm_values.unique();
alarm_values.sort();
//set the alarm to the lowest value in the list
alarm( alarm_values.front() );
generatePrimesFile(cp_ptr, name);
}
void usr1_handler(int signo){
cout << "Current Prime: " << currentPrime << endl;
}
void alarm_handler(int signo) {
cout << "Current Prime: " << currentPrime << endl;
if(!alarm_values.empty()){
int temp = alarm_values.front();
alarm_values.pop_front();
alarm( alarm_values.front() - temp );
}
}
void generatePrimesFile(int * currentPrime, char* name) {
const int BIGNUMBER = 65534;
bool isPrime=true;
int fd;
if( (fd = open(name, O_WRONLY|O_APPEND|O_CREAT, 0700)) == -1){
perror("open");
exit(1);
}
for ( int i = 0; i < BIGNUMBER; i++) {
for ( int j = 2; j < BIGNUMBER; j++) {
if ( i!=j && i % j == 0 ) {
isPrime=false;
break;
}
}
if (isPrime) {
*currentPrime = i;
int buff[] = {i};
write(fd, buff, 2);
sleep(1);
}
isPrime=true;
}
} |
|
|
|
|
|
#2 |
|
Professional Programmer
Join Date: May 2006
Location: Maryland, USA
Posts: 306
Rep Power: 3
![]() |
Did you even look up the prototype of write?
ssize_t write(int fildes, const void *buf, size_t nbyte); |
|
|
|
|
|
#3 |
|
Newbie
|
Well that certainly explains why I wasn't getting readable files. But I included <stdlib.h> and itoa() is reported as undefined. Does Gcc not support it?
Edit: A little googling made me aware of sprintf(). I'm going to try that. Edit2: sprintf works for my purposes. Last edited by Ghosty; Dec 14th, 2006 at 9:27 PM. |
|
|
|
|
|
#4 |
|
Newbie
|
This code works for the most part. I don't know how to format the output though. Ideally, I'd like the output file to look similar to this:
1 2 3 5 7 11 13 and so on with primes Thanks in advance and again sorry for the mess. #include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <list>
#include <algorithm>
#include <fcntl.h>
#include <cstdio>
#include <signal.h>
using namespace std;
void generatePrimesFile(int*, char*);
void usr1_handler(int);
void alarm_handler(int);
//I don't like globals but we can't pass the handler functions anything
int currentPrime = 1;
list<int> alarm_values;
int main(int argc, char *argv[]) {
if(argc < 2){
cerr << "Usage: Lab6 <file to be written> <optional time>" << endl;
return 1;
}
char * name = argv[1];
int * cp_ptr = ¤tPrime;
// Setup the signal handlers
struct sigaction usr1Act;
struct sigaction alarmAct;
usr1Act.sa_handler = usr1_handler;
sigemptyset( &usr1Act.sa_mask );
usr1Act.sa_flags = SA_RESTART;
alarmAct.sa_handler = alarm_handler;
sigemptyset( &alarmAct.sa_mask);
alarmAct.sa_flags = SA_RESTART;
if( sigaction( SIGUSR1 , &usr1Act, NULL ) == -1 ) {
//syserr("sigaction");
perror( "sigaction" );
exit( 1 );
}
if( sigaction( SIGALRM, &alarmAct, NULL) == -1 ) {
perror( "sigaction alarm");
exit(1);
}
//fill alarm values list
alarm_values.clear();
for(int i= 2; i < argc; i++){
alarm_values.push_back(atoi(argv[i]));
}
//sort it
alarm_values.unique();
alarm_values.sort();
//set the alarm to the lowest value in the list
alarm( alarm_values.front() );
generatePrimesFile(cp_ptr, name);
}
void usr1_handler(int signo){
cout << "Current Prime: " << currentPrime << endl;
}
void alarm_handler(int signo) {
cout << "Current Prime: " << currentPrime << endl;
if(!alarm_values.empty()){
int temp = alarm_values.front();
alarm_values.pop_front();
alarm( alarm_values.front() - temp );
}
}
void generatePrimesFile(int * currentPrime, char* name) {
const int BIGNUMBER = 2000;
bool isPrime=true;
int fd;
if( (fd = open(name, O_WRONLY|O_APPEND|O_CREAT|O_TRUNC, 0700)) == -1){
perror("open");
exit(1);
}
for ( int i = 0; i < BIGNUMBER; i++) {
for ( int j = 2; j < BIGNUMBER; j++) {
if ( i!=j && i % j == 0 ) {
isPrime=false;
break;
}
}
if (isPrime) {
*currentPrime = i;
char buff[500];
int n = sprintf( buff, "%d", i );
buff[n+1] += '\0';
write(fd, buff, n+1);
sleep(1);
}
isPrime=true;
}
} |
|
|
|
|
|
#5 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
You need to be more than aware of sprintf; you need to read its docs (and possibly follow the link to printf). If you want a newline after the number, consider using "%d\n".
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#6 |
|
Newbie
|
You are indeed right DaWei. I was in a rush to fix the code and didn't bother reading up on sprintf. I have the code working however.
Thanks for the help GE. |
|
|
|
|
|
#7 | ||
|
Caffeinated Neural Net
![]() Join Date: Jun 2005
Location: Dry west coast of Canada
Posts: 1,007
Rep Power: 5
![]() |
Quote:
Quote:
An alternative that avoids all of these allocation size issues would be to use stringstreams. This lets you use the stream I/O syntax you're already familiar with. Info to get you started can be found here.
__________________
And once again, Probability proves itself willing to sneak into a back alley and service Drama as would a copper-piece harlot. - Vaarsuvius, Order of the Stick |
||
|
|
|
|
|
#8 | |
|
Newbie
|
Quote:
|
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|