[부탁] 이 소스 컴파일 한번 해주세요!! (재업)

ergo50의 이미지

안녕하세요

아래 리플달아주신분이 BB코드로 올리하고 하셔서 다시 올립니다.
에러도 같이 첨부했습니다. 한번 봐 주세요^^

아래소스는 nanosec님께서 한빛미디어 C책에 나온 예제소스라 올려놓으신건데요,
제가 제 머신에서 아무리 컴파일 하려해도 자꾸만 에러가 나네요.
OS는 Solaris8 sparc 이고요,
머신은 Ultra60, Enterprise 3500 두군데서 다 해봤습니다.

컴파일은
gcc sys.c -lkstat 이라고 했습니다.

의심가는부분은 중간쯤에, 함수밖에 놓여있는 define과 if문 인데요,
=======================
#define UPDKCID(nk,ok) \
if (nk == -1) { \
Error("kstat read"); \
} \
if (nk != ok)\
goto kcid_changed;
=======================

newline 문자인 '\' 까지 들어있습니다.

이대로 컴파일을 하면,,,
=================================================
bash-2.05# gcc cpu.c -lkstat
cpu.c:120:24: warning: backslash and newline separated by space
cpu.c:121:17: warning: backslash and newline separated by space
cpu.c:122:25: warning: backslash and newline separated by space
cpu.c:123:3: warning: backslash and newline separated by space
cpu.c:124:14: warning: backslash and newline separated by space
/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.3.2/crt1.o(.text+0x5c): In function `_start':
: undefined reference to `main'
collect2: ld returned 1 exit status
bash-2.05#
=================================================
라고 나오고요,

의심가는 부분의 뉴라인문자를 제거하고 컴파일하면
=================================================bash-2.05# gcc cpu.c -lkstat
cpu.c:121: error: parse error before "if"
bash-2.05#
=================================================

이렇게 나옵니다.

한번 컴파일 좀 해봐주시고, 이상있는 부분 좀 알려주시면 정말 고맙겠습니다.

그럼 부탁드립니다.

-------------------------------------------------------------------------------------

#include <stdio.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <dirent.h> 
#include <nlist.h> 
#include <kvm.h> 
#include <sys/proc.h> 
#include <sys/procfs.h> 
#include <sys/var.h> 
#include <sys/cpuvar.h> 
#include <sys/file.h> 
#include <sys/swap.h> 
#include <kstat.h> 


/* system information related */ 
#define CPUSTATES 5 
#define NUM_STRINGS 8 

struct system_info{ 
double load_avg[3]; 
int *cpu_state; 
int *memory_state; 
}; 

#ifndef FSCALE 
#define FSHIFT 8 
#define FSCALE (1 << FSHIFT) 
#endif 

#define loaddouble(value) ((double)(value) / FSCALE) 

#define CPUSTATE_IOWAIT 3 
#define CPUSTATE_SWAP 4 

kstat_ctl_t *kopen = NULL; 
kstat_t **cpu_ks; 
cpu_stat_t *cpu_stat; 

int cpu_states[CPUSTATES]; 

int memory_state[3]; 

int nproc; 
int ncpus; 

int print_load_average(); 
int print_memory_state(); 
void print_cpu_state(); 
void Error(char *); 

char 
*itoa(register int val) 
{ 
char *ptr; 
static char buffer[16]; 

ptr = buffer + sizeof(buffer); 
*--ptr = '\0'; 

if (val == 0) 
*--ptr = '0'; 
else while (val != 0) 
{ 
*--ptr = (val % 10) + '0'; 
val /= 10; 
} 

return(ptr); 
} 

void 
get_cpu_relate_information(count, cpu_info, new, old, diffs) 
int count; 
int *cpu_info; 
long *new; 
long *old; 
long *diffs; 
{ 
int i; 
long change; 
long total_change; 
long *dp; 
long half_total; 

total_change = 0; 
dp = diffs; 

for (i = 0; i < count; i++) 
{ 
if ((change = *new - *old) < 0) 
change = (int) 
((unsigned long)*new-(unsigned long)*old); 

total_change += (*dp++ = change); 
*old++ = *new++; 
} 

if (total_change == 0) 
total_change = 1; 

half_total = total_change / 2L; 
for (i = 0; i < count; i++) 
*cpu_info++ = (int)((*diffs++ * 1000 + half_total) / total_change); 
} 

int 
format_k(int Mbyte) 
{ 
if (Mbyte >= 10000) 
{ 
Mbyte = (Mbyte + 512) / 1024; 
if (Mbyte >= 10000) 
Mbyte = (Mbyte + 512) / 1024; 
} 

return (Mbyte); 
} 

#define UPDKCID(nk,ok) \ 
if (nk == -1) { \ 
Error("kstat read"); \ 
} \ 
if (nk != ok)\ 
goto kcid_changed; 

int 
get_cpu_and_load_average(int load_average[3]) 
{ 
kstat_t *lookup; 
kid_t chaind_update; 
int i; 
int changed = 0; 
static int ncpu = 0; 
static kid_t chaing_ID = 0; 
kstat_named_t *data_lookup; 


if (!kopen) 
{ 
kopen = kstat_open(); 
if (!kopen) 
Error("kstat open"); 

changed = 1; 
chaing_ID = kopen->kc_chain_id; 
} 

kcid_changed: 

chaind_update = kstat_chain_update(kopen); 

if (chaind_update) 
{ 
changed = 1; 
chaing_ID = chaind_update; 
} 

UPDKCID(chaind_update,0); 

lookup = kstat_lookup(kopen, "unix", 0, "system_misc"); 
if (kstat_read(kopen, lookup, 0) == -1) 
Error("kstat read"); 

data_lookup = kstat_data_lookup(lookup, "avenrun_1min"); 
if (data_lookup) 
load_average[0] = data_lookup->value.ui32; 

data_lookup = kstat_data_lookup(lookup, "avenrun_5min"); 

if (data_lookup) 
load_average[1] = data_lookup->value.ui32; 

data_lookup = kstat_data_lookup(lookup, "avenrun_15min"); 

if (data_lookup) 
load_average[2] = data_lookup->value.ui32; 

data_lookup = kstat_data_lookup(lookup, "nproc"); 
if (data_lookup) nproc = data_lookup->value.ui32; 

if (changed) 
{ 
ncpu = 0; 

data_lookup = kstat_data_lookup(lookup, "ncpus"); 
if (data_lookup && data_lookup->value.ui32 > ncpus) 
{ 
ncpus = data_lookup->value.ui32; 
cpu_ks = (kstat_t **) 
realloc (cpu_ks, ncpus * sizeof (kstat_t *)); 
cpu_stat = (cpu_stat_t *) realloc (cpu_stat, 
ncpus * sizeof (cpu_stat_t)); 
} 

for (lookup = kopen->kc_chain; lookup; lookup = lookup->ks_next) 
{ 
if (strncmp(lookup->ks_name, "cpu_stat",  == 0) 
{ 
chaind_update = kstat_read(kopen, lookup, NULL); 
UPDKCID(chaind_update, chaing_ID); 

cpu_ks[ncpu] = lookup; 
ncpu++; 
if (ncpu > ncpus) 
Error("kstat finds too many cpus"); 
} 
} 
changed = 0; 
} 

for (i = 0; i < ncpu; i++) 
{ 
chaind_update = kstat_read(kopen, cpu_ks[i], &cpu_stat[i]); 
UPDKCID(chaind_update, chaing_ID); 
} 

return(ncpu); 
} 

void 
get_system_information(struct system_info *system_information) 
{ 
int load_average[3]; 
static int free_memory; 
static int total_memory; 
static int available_memory; 
static long cpu_info[CPUSTATES]; 
static long cpu_old[CPUSTATES]; 
static long system_diff[CPUSTATES]; 
int j, i; 

kstat_t *lookup; 
kstat_named_t *data_lookup; 
int cpu_number; 

for (j = 0; j < CPUSTATES; j++) 
cpu_info[j] = 0L; 

cpu_number = get_cpu_and_load_average(load_average); 
for (i = 0; i < cpu_number; i++) 
{ 
/* **************************************************** */ 
// idle%, user%, kernel%에 대한 값을 cpu_info[]에 저장한다. 
/* **************************************************** */ 
for (j = 0; j < 3; j++) 
cpu_info[j] += (long) cpu_stat[i].cpu_sysinfo.cpu[j]; 

/* **************************************************** */ 
// iowait% 구하기 
/* **************************************************** */ 
cpu_info[CPUSTATE_IOWAIT] += (long) cpu_stat[i].cpu_sysinfo.wait[W_IO] 
+ (long) cpu_stat[i].cpu_sysinfo.wait[W_PIO]; 
/* **************************************************** */ 
// swap% 구하기 
/* **************************************************** */ 
cpu_info[CPUSTATE_SWAP] += (long) cpu_stat[i].cpu_sysinfo.wait[W_SWAP]; 
} 

lookup = kstat_lookup(kopen, "unix", 0, "system_pages"); 
if (kstat_read(kopen, lookup, 0) == -1) 
Error("kstat read"); 

/* **************************************************** */ 
// free memory 구하기 
/* **************************************************** */ 
data_lookup = kstat_data_lookup(lookup, "freemem"); 
if (data_lookup) 
free_memory = data_lookup->value.ul; 

/* **************************************************** */ 
// cpu_states[] : idle, user, kernel, iowait, swap 등이 
// 저장된다. 
/* **************************************************** */ 
get_cpu_relate_information (CPUSTATES, 
cpu_states, cpu_info, cpu_old, system_diff); 

/* **************************************************** */ 
// load 평균 저장하기 
/* **************************************************** */ 
for (i = 0; i < 3; i++) 
system_information->load_avg[i] = loaddouble(load_average[i]); 

/* **************************************************** */ 
// sysconf()로 전체 메모리 구하기 
/* **************************************************** */ 
total_memory = sysconf(_SC_PHYS_PAGES); 

memory_state[0] = (total_memory << 3) / 1024; 
memory_state[1] = 0; 
memory_state[2] = (free_memory << 3) / 1024; 

system_information->cpu_state = cpu_states; 
system_information->memory_state = memory_state; 
} 

int 
print_memory_state(int *stats) 
{ 

puts(""); 
printf(">> memory state :"); 

/* total memory, active(null), free memory */ 
printf("%s ", format_k(*stats++)); *stats++; 
printf("%s\n", format_k(*stats)); 
} 

int 
print_load_average(int mpid, double *load_average) 
{ 
int i; 

puts(""); 
puts("=========================================================="); 
printf(">> load average : "); 

for (i = 0; i < 3; i++) 
printf("%5.2f", load_average[i]); 

} 

void 
print_cpu_state(states) 
int *states; 
{ 
static int count = 0; 
int j, i = 0; 
int value; 
char *cpu_state_menu[] = 
{"idle", "user", "kernel", "iowait", "swap", NULL}; 
char **names = cpu_state_menu; 
char *thisname; 

if(count == 0) { count = 1; return; } 

printf("\n>> CPU state : "); 

for(j = 0;j < 5;j++) 
{ 
thisname = *names++; 
if (*thisname != '\0') 
{ 
value = *states++; 

printf((value >= 1000 ? "%s%4.0f%% %s" : "%s%4.1f%% %s"), 
i++ == 0 ? "" : ", ", ((float)value)/10., thisname); 
} 
} 
} 

void 
Error(char *error_name) 
{ 
perror(error_name); 
exit(0); 
}
File attachments: 
첨부파일 크기
Package icon system_info.zip7.38 KB
saxboy의 이미지

main() 이 없는데 링킹이 안되는건 당연하지 않나요.
그 전에 보이는 warning은 \ 뒤에 "space"가 있기 때문에 생긴 문제이지, \n을 지워야 한다는 의미는 아닙니다.

대부분 executable 의 실제 엔트리 포인트 심벌은 _start 이고, _start를 구현해 main() 을 호출해주는 역할을 하는 부분이 crt 코드에 들어 있는데, 지금은 코드에 main이 없으니 crt 코드와 링킹을 제대로 하지 못해서 생긴 에러입니다.

ergo50의 이미지

에고~ 메인이 없었네요--
그렇다면, 가장 간단한 메인을 만들면 어떤모양이나올까요?
아래와 같이 하면 될까요????
int main(void) {

struct system_info *system_information;
get_system_information(system_information) ;
return 0;
}

그리고,,, 위의 메인들 달고 컴파일하면 아래와같이 에러가 생깁니다.

bash-2.05# gcc sys.c -lkstat
sys.c:117: error: parse error before "if"
bash-2.05#

위에서 말씀드린 뉴라인 있는부분인데요, define밑에 아무 함수에도 속하지 않은 if문이 두개 있는데
이것때문에 그런건지요?
문법적으로 이런경우도 있는건지요??? 부탁드립니다

feanor의 이미지

C 언어에서 \가 줄의 마지막 글자이면 그 줄과 다음 줄은 한 줄로 합쳐집니다.

#define 원래대로 그대로 놓아두시고, \와 줄바꿈 문자 사이에 공백이 있으면 공백을 모두 지우십시오.

--feanor

feanor의 이미지

관리자님, http://bbs.kldp.org/viewtopic.php?t=36123 와 중복이니 합쳐주시기 바랍니다.

--feanor

nanosec의 이미지

server.c : 서버의 시스템 정보를 구해 클라이언트에 전송
system_info.c : 서버의 시스템 정보를 실제적으로 구하는 루틴
client.c : 서버에 시스템 정보를 요청하고 이를 화며에 출력
analysis.c : 분석한 로그 파일을 월, 일, 시별로 평균값과 최대값을 구해 출력

으로 구현 되어 있습니다.

정확한 책 제목은 "유닉스 시스템 프로그래밍" 입니다. ^^

댓글 첨부 파일: 
첨부파일 크기
Package icon 0바이트

0x2B | ~0x2B
- Hamlet

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.