Linux API/network2009. 7. 2. 16:38
원래는 파일의 생성일을 알아보려고 찾았는데..
리눅스에서는 파일 생성일은 저장을 안한다고 한다.

	struct stat
	{
		dev_t     st_dev;     /* ID of device containing file */
		ino_t     st_ino;     /* inode number */
		mode_t    st_mode;    /* protection */
		nlink_t   st_nlink;   /* number of hard links */
		uid_t     st_uid;     /* user ID of owner */
		gid_t     st_gid;     /* group ID of owner */
		dev_t     st_rdev;    /* device ID (if special file) */
		off_t     st_size;    /* total size, in bytes */
		blksize_t st_blksize; /* blocksize for filesystem I/O */
		blkcnt_t  st_blocks;  /* number of blocks allocated */
		time_t    st_atime;   /* time of last access */
		time_t    st_mtime;   /* time of last modification */
		time_t    st_ctime;   /* time of last status change */
	};

위는 man fstat의 내용으로, 위에 보듯, time_t 구조체가 세개가 있는데
last access / modification / change 세가지 뿐이다.

[링크 : http://www.linuxhomenetworking.com/forums/showthread.php?t=17449]
Posted by 구차니
Linux API/network2009. 6. 30. 17:21
File Descriptor
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
ssize_t read(int fildes, void *buf, size_t nbyte);
ssize_t write(int fildes, const void *buf, size_t nbyte);
int close(int fd);

int pipe(int filedes[2]); // filedes[0] is for reading, filedes[1] is for writing

int dup(int oldfd);
int dup2(int oldfd, int newfd);

ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
ssize_t pwrite(int fildes, const void *buf, size_t nbyte,off_t offset);

File Pointer
FILE *fopen(const char *path, const char *mode);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int fclose(FILE *fp);

FILE *fdopen(int fildes, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);

int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);
void rewind(FILE *stream);
int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, fpos_t *pos);

FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);

'Linux API > network' 카테고리의 다른 글

리눅스 소켓 프로그래밍 - linux socket programming  (0) 2009.07.17
fstat - 파일의 상태 얻어오기  (2) 2009.07.02
getline()  (0) 2009.06.25
fork에 관한 짧은 이야기  (2) 2009.06.23
signal / kill / raise  (0) 2009.06.21
Posted by 구차니
Linux API/network2009. 6. 25. 19:40
말그대로 라인을 얻어오는 함수이다.

SYNOPSIS
       #define _GNU_SOURCE
       #include <stdio.h>

       ssize_t getline(char **lineptr, size_t *n, FILE *stream);
       ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);

DESCRIPTION
       getline()  reads an entire line from stream, storing the address of the buffer containing the text into *lineptr.
       The buffer is null-terminated and includes the newline character, if one was found.

       If *lineptr is NULL, then getline() will allocate a buffer for storing the line, which should  be  freed  by  the
       user  program.   Alternatively,  before calling getline(), *lineptr can contain a pointer to a malloc()-allocated
       buffer *n bytes in size. If the buffer is not large enough to hold the line, getline() resizes it with realloc(),
       updating  *lineptr  and *n as necessary. In either case, on a successful call, *lineptr and *n will be updated to
       reflect the buffer address and allocated size respectively.

       getdelim() works like getline(), except a line delimiter other than newline can be  specified  as  the  delimiter
       argument. As with getline(), a delimiter character is not added if one was not present in the input before end of
       file was reached.

함수형을 보면, 파일에서 한줄씩(그러니까 CR/LF 까지) 읽어 오는데,
주의해야 할 점은, getline() 함수 내부적으로 malloc()를 호출 한다는 것이다.
즉, 만약에 malloc()을 해주지 않으려면, NULL 값인 포인터를 넘겨주면
알아서 malloc() 하거나 realloc() 해주므로 많은 신경을 쓰지 않아도 된다.

단, 마지막 getline() 호출 후, 사용이 끝나면 반드시 free()를 해주어야 한다.

[링크 : http://linux.die.net/man/3/getline]
Posted by 구차니
Linux API/network2009. 6. 23. 00:50
fork()는 리눅스 시스템 콜로서, 프로세스를 생성한다.

#include "stdio.h"
#include "unistd.h"

int main() { pid_t pid; pid = fork();
switch( pid) { case -1: // fail case 0: // child default: // parent break; } }
개략적인 코드는 위와 같은데,
왜! switch 문데 child와 parent가 동시에 들어가는지에 대해서 생각을 해보도록 하자.

일단 fork() + exec() 의 조합으로 쓰게 되는데,
fork()는 프로세스를 생성하고, exec()는 프로그램을 바꾸어서 실행하는 역활을 한다.
다시 앞을 자세히 보자.

프로세스를 생성한다.

어려운 이야기를 제외하고, 프로세스는 메모리상에 올라와있는(적재되어 있는, 혹은 메모리에 load된)
프로그램으로, 프로세스를 생성하는 가장 편한 방법은 복사이다.
현재 수행중인 프로세스의 내용을 그대로 복사해서 다른 pid를 준다.
그게 바로 fork 이고, 위의 switch문을 이해할 수 있는 키가 된다.

굳이 비유를 하자면, 예전에 일요일에 했던 이휘재가 그래 결정했어! 를 외치던 그 프로그램을 떠올려 보자.
어느 시점에서 그대로 복제한 메모리의 정보가 생성이 되었고
그 분기점에서 어느길을 택할지를 결정하여 주면, 각각의 프로그램이 따로 돌아가게 된다.


즉, 복사한 시점에서 표지판 역활을 해주는 것이
fork()의 리턴값인 pid_t 형의 pid 이고,
이 값이 어느 쪽으로 분기되어 갈지를 결정하게 해주는 것이다.

그런 이유로, Parent, Child 의 코드가 하나의 소스에 들어 있게 되고
별거 아닌 것 같지만, 상당히 헷갈리는(왜 코드가 하나에 들어 있지?) 이유가 된다.

[링크 : http://linux.die.net/man/2/fork]

'Linux API > network' 카테고리의 다른 글

Linux File Descriptor / File pointer  (0) 2009.06.30
getline()  (0) 2009.06.25
signal / kill / raise  (0) 2009.06.21
flock - apply or remove an advisory lock on an open file  (0) 2009.06.20
네트워크 장치 갯수 얻기 (get amount of eth?)  (0) 2009.06.18
Posted by 구차니
Linux API/network2009. 6. 21. 13:04
signal - ANSI C signal handling
kill - send signal to a process
raise - send a signal to the current process

signal()은 시그널 핸들러를 등록하고
 #include <signal.h>
 sighandler_t signal(int signum, sighandler_t handler);

kill은 시그널 을 전송하고
 #include <sys/types.h>
 #include <signal.h>
 int kill(pid_t pid, int sig);

raise는 자기자신에게 시그널을 전송한다.
 #include <signal.h>
 int raise(int sig);
 kill(getpid(), sig);

아무래도, pid 단위로 시그널을 전송함으로서 제어에 상당한 제약이 있을것으로 보인다.
그리고 쓰레드는 2.5 커널 이상 부터는 pid가 동일하게 나온다고 한다.
[링크 : http://kldp.org/node/35609]

*** man page ***
[signal(2) : http://linux.die.net/man/2/signal]
[kill(2) : http://linux.die.net/man/2/kill]
[raise(2) : http://linux.die.net/man/3/raise]

*** joinc wiki ***
시그널 처리하기
시그널 사용하기 1
시그널 사용하기 2
리눅스 시스템 프로그래밍 6장 시그널

'Linux API > network' 카테고리의 다른 글

getline()  (0) 2009.06.25
fork에 관한 짧은 이야기  (2) 2009.06.23
flock - apply or remove an advisory lock on an open file  (0) 2009.06.20
네트워크 장치 갯수 얻기 (get amount of eth?)  (0) 2009.06.18
gateway 정보  (0) 2009.06.05
Posted by 구차니
Linux API/network2009. 6. 20. 18:55
flock은 이름대로 파일 디스크립터를 lock 하거나 unlock 하는데 사용한다.
멀티 유저/ 멀티 프로세스 OS인 관계로 Linux/Unix에서는 열린 파일도 여러사람이 또 열어서 쓸 수 있는데
다르게 말하자면 시리얼 포트 역시 동시에 여러사람이 열어서 사용이 가능하다는 의미이다.

하지만, 시리얼 포트를 동시에 여러 사람이 열어서 사용하다 보면 문제가 발생할 수도 있기에
(내용이 서로 엇갈린다던가) 특정 시기에 대해서는 타인이 사용하지 못하도록 배타적으로 잠궈야 할 때도 있다.

int flock(int fd, int operation);

    LOCK_SH
        Place a shared lock. More than one process may hold a shared lock for a given file at a given time.

    LOCK_EX
        Place an exclusive lock. Only one process may hold an exclusive lock for a given file at a given time.

    LOCK_UN
        Remove an existing lock held by this process.

[링크 : http://linux.die.net/man/2/flock]

LOCK_EX로 하면 자기만 쓸 수 있도록 잠그는 것이고,
LOCK_UN으로 잠금을 해제 한다.



[링크 : http://feedtome.springnote.com/pages/141729]
[링크 : http://stackoverflow.com/questions/691676/getting-exclusive-access-to-a-tty-device-from-a-root-program-on-linux]

'Linux API > network' 카테고리의 다른 글

fork에 관한 짧은 이야기  (2) 2009.06.23
signal / kill / raise  (0) 2009.06.21
네트워크 장치 갯수 얻기 (get amount of eth?)  (0) 2009.06.18
gateway 정보  (0) 2009.06.05
linux에서 ip/mac address 받아오기 관련 링크  (0) 2009.06.05
Posted by 구차니
Linux API/network2009. 6. 18. 21:19
아래의 소스에서 눈여겨 볼 부분은 다음과 같다.
    struct ifreq *ifr;
    struct ifconf ifcfg;

    ioctl(fd, SIOCGIFCONF, (char *)&ifcfg);

    // 네트워크 장치의 정보를 얻어온다. 
    // 보통 루프백과 하나의 이더넷 카드를 가지고 있을 것이므로
    // 2개의 정보를 출력할 것이다.

    ifr = ifcfg.ifc_req;
    for (n = 0; n < ifcfg.ifc_len; n+= sizeof(struct ifreq))
    {
        // 주소값을 출력하고 루프백 주소인지 확인한다.
        printf("[%s]\n", ifr->ifr_name);
        sin = (struct sockaddr_in *)&ifr->ifr_addr;
        printf("IP    %s %d\n", inet_ntoa(sin->sin_addr), sin->sin_addr.s_addr);
        if ( ntohl(sin->sin_addr.s_addr) == INADDR_LOOPBACK)
        {
            printf("Loop Back\n");
        }
        else
        {
            // 루프백장치가 아니라면 MAC을 출력한다.
        }
        ifr++;
    }

ifr은 struct ifreq인데, 여러개가 있을 수 있으니, 저런식으로 포인터로 증가를 시켜준다. (ifr++)
그리고 n개의 네트워크 장치가 있을 수 있으니, ifcfg.ifc_len의 값으로 전체 갯수를 알려준다.
그 다음에는 장치명(익숙한 eth0 라던가)은 ifr->ifr_name에 들어있다.

#include "sys/ioctl.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "sys/socket.h"
#include "unistd.h"
#include "netinet/in.h"
#include "arpa/inet.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "net/if.h"
#include "arpa/inet.h"

int main()
{
    // 이더넷 데이터 구조체 
    struct ifreq *ifr;
    struct sockaddr_in *sin;
    struct sockaddr *sa;

    // 이더넷 설정 구조체
    struct ifconf ifcfg;
    int fd;
    int n;
    int numreqs = 30;
    fd = socket(AF_INET, SOCK_DGRAM, 0);

    // 이더넷 설정정보를 가지고오기 위해서 
    // 설정 구조체를 초기화하고  
    // ifreq데이터는 ifc_buf에 저장되며, 
    // 네트워크 장치가 여러개 있을 수 있으므로 크기를 충분히 잡아주어야 한다.  
    // 보통은 루프백주소와 하나의 이더넷카드, 2개의 장치를 가진다.
    memset(&ifcfg, 0, sizeof(ifcfg));
    ifcfg.ifc_buf = NULL;
    ifcfg.ifc_len = sizeof(struct ifreq) * numreqs;
    ifcfg.ifc_buf = malloc(ifcfg.ifc_len);

    for(;;)
    {
        ifcfg.ifc_len = sizeof(struct ifreq) * numreqs;
        ifcfg.ifc_buf = realloc(ifcfg.ifc_buf, ifcfg.ifc_len);
        if (ioctl(fd, SIOCGIFCONF, (char *)&ifcfg) < 0)
        {
            perror("SIOCGIFCONF ");
            exit;
        }
        // 디버깅 메시지 ifcfg.ifc_len/sizeof(struct ifreq)로 네트워크 
        // 장치의 수를 계산할 수 있다.  
        // 물론 ioctl을 통해서도 구할 수 있는데 그건 각자 해보기 바란다.
        printf("%d : %d \n", ifcfg.ifc_len, sizeof(struct ifreq));
        break;
    }

    // 주소를 비교해 보자.. ifcfg.if_req는 ifcfg.ifc_buf를 가리키고 있음을 
    // 알 수 있다. 
    printf("address %d\n", &ifcfg.ifc_req);
    printf("address %d\n", &ifcfg.ifc_buf);

    // 네트워크 장치의 정보를 얻어온다.  
    // 보통 루프백과 하나의 이더넷 카드를 가지고 있을 것이므로 
    // 2개의 정보를 출력할 것이다. 
    ifr = ifcfg.ifc_req;
    for (n = 0; n < ifcfg.ifc_len; n+= sizeof(struct ifreq))
    {
        // 주소값을 출력하고 루프백 주소인지 확인한다.
        printf("[%s]\n", ifr->ifr_name);
        sin = (struct sockaddr_in *)&ifr->ifr_addr;
        printf("IP    %s %d\n", inet_ntoa(sin->sin_addr), sin->sin_addr.s_addr);
        if ( ntohl(sin->sin_addr.s_addr) == INADDR_LOOPBACK)
        {
            printf("Loop Back\n");
        }
        else
        {
            // 루프백장치가 아니라면 MAC을 출력한다.
            ioctl(fd, SIOCGIFHWADDR, (char *)ifr);
            sa = &ifr->ifr_hwaddr;
            printf("%s\n", ether_ntoa((struct ether_addr *)sa->sa_data));
        }
        // 브로드 캐스팅 주소 
        ioctl(fd,  SIOCGIFBRDADDR, (char *)ifr);
        sin = (struct sockaddr_in *)&ifr->ifr_broadaddr;
        printf("BROD  %s\n", inet_ntoa(sin->sin_addr));
        // 네트워크 마스팅 주소
        ioctl(fd, SIOCGIFNETMASK, (char *)ifr);
        sin = (struct sockaddr_in *)&ifr->ifr_addr;
        printf("MASK  %s\n", inet_ntoa(sin->sin_addr));
        // MTU값
        ioctl(fd, SIOCGIFMTU, (char *)ifr);
        printf("MTU   %d\n", ifr->ifr_mtu);
        printf("\n");
        ifr++;
    }
}

[링크 : http://www.joinc.co.kr/modules.php?file=article&mode=nested&name=News&sid=148]
Posted by 구차니
Linux API/usb2009. 6. 8. 20:27
증상 : USB hotplug 및 인식/사용에 아무런 이상없으나, /proc/bus/usb 에 아무런 파일 없음

mount -t usbfs usbfs /proc/bus/usb/
를 실행해주면 해결된다.

[링크 : http://www.linuxquestions.org/.../cannot-open-procbususbdevices-no-such-file-or-directory-378916/]


다른 링크에 의하면 ACPI 문제라던가, 커널 설정상의 문제가 있을 가능성이 있다고 한다.
[링크 : http://www.linuxquestions.org/.../mdk-10.2-no-usb-at-all-procbususbdevices-missing-326350/]

---
2012.02.04 추가

우분투에서 하니 usbfs로 마운트가 되지 않고 /proc/bus/usb 를 찾을 수 없다는 에러만 나타낸다.
그래서 mkdir로 생성해주려고 해도 배째는데, 아래와 같이 ln 으로 연결해주니 된다!!
대신 기존의 /proc/bus 는 통채로 사라지니 주의해야 한다.
차라리 /sys/kernel/debug/usb/devices 를 들어가서 보는게 나을지도 모르겠다.
$ sudo mount --bind /dev/bus /proc/bus
$ sudo ln -s /sys/kernel/debug/usb/devices /proc/bus/usb/devices   

[링크 : http://ubuntuforums.org/showthread.php?t=1648118 ] 



'Linux API > usb' 카테고리의 다른 글

usbfs / usb api  (0) 2012.02.04
usb 버스 정보 얻기  (0) 2009.06.08
Posted by 구차니
Linux API/usb2009. 6. 8. 17:47
/proc/bus/usb/devices 를 읽으면 되는데
보기가 힘들다.


이걸 쉽게 보려면
usbtree 라는 perl 스크립트를 http://www.linux-usb.org/usb2.html 페이지에서 받아서 사용하면된다.

/: Bus 05.Port 1: Dev 1, Class=root_hub, Drv=ehci_hcd/8p, 480M
    |_ Port 1: Dev 7, If 0, Prod=ST3250310AS, Class=stor., Drv=usb-storage, 480M
    |_ Port 2: Dev 6, If 0, Prod=SKYMIRROR, Class=stor., Drv=usb-storage, 480M
/: Bus 04.Port 1: Dev 1, Class=root_hub, Drv=uhci_hcd/2p, 12M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Drv=uhci_hcd/2p, 12M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Drv=uhci_hcd/2p, 12M
    |_ Port 1: Dev 2, If 0, Prod=USB Optical Mouse, Class=HID, Drv=usbhid, 1.5M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Drv=uhci_hcd/2p, 12M

내용을 보니 그래도 버스 순서대로 출력이 되는 듯 하다.

'Linux API > usb' 카테고리의 다른 글

usbfs / usb api  (0) 2012.02.04
/proc/bus/usb 의 내용이 없을 경우(There is no files /proc/bus/usb)  (0) 2009.06.08
Posted by 구차니
Linux API/network2009. 6. 5. 19:33
$ more /proc/net/route
Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT
eth0    000AA8C0        00000000        0001    0       0       0       00FFFFFF        0       0       0
eth0    0000FEA9        00000000        0001    0       0       0       0000FFFF        0       0       0
eth0    00000000        010AA8C0        0003    0       0       0       00000000        0       0       0

$ netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.10.0    0.0.0.0         255.255.255.0   U         0 0          0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth0
0.0.0.0         192.168.10.1    0.0.0.0         UG        0 0          0 eth0


0x010AA8C0 이 gateway인데 숫자가 뒤집혀 있다.
0x01. 0x0A. 0xA8. 0xC0
1.      10.     168.   192
Posted by 구차니