|
|
| version 1.6, 2011/06/07 11:49:39 | version 1.7.2.1, 2011/11/02 13:13:48 |
|---|---|
| Line 558 ioWatchDirLoop(const char *csDir, int (*callback)(cons | Line 558 ioWatchDirLoop(const char *csDir, int (*callback)(cons |
| close(kq); | close(kq); |
| return n; | return n; |
| } | } |
| /* | |
| * ioCreatePIDFile() Create PID file | |
| * @csName = PID filename | |
| * @ifExists = !=0 if filename exists return error | |
| * return: -1 error or 0 ok | |
| */ | |
| inline int | |
| ioCreatePIDFile(const char *csName, int ifExists) | |
| { | |
| int fd; | |
| char str[STRSIZ] = { 0 }; | |
| if (!csName) | |
| return -1; | |
| fd = open(csName, O_WRONLY | O_CREAT | (ifExists ? O_EXCL : 0), 0644); | |
| if (fd == -1) { | |
| LOGERR; | |
| return -1; | |
| } | |
| snprintf(str, sizeof str, "%d", getpid()); | |
| write(fd, str, strlen(str)); | |
| close(fd); | |
| return 0; | |
| } | |
| /* | |
| * ioSendFile() AITNET sendfile() userland implementation, not dependant from OS | |
| * @s = socket | |
| * @csFile = file for send | |
| * @sendLen = bytes to send, if 0 send all data | |
| * @offset = start file offset | |
| * return: 0 error, >0 ok, sended bytes | |
| */ | |
| size_t | |
| ioSendFile(int s, const char *csFile, size_t sendLen, off_t offset) | |
| { | |
| void *addr; | |
| int fd; | |
| size_t len; | |
| if (!csFile) | |
| return 0; | |
| fd = open(csFile, O_RDONLY); | |
| if (fd == -1) { | |
| LOGERR; | |
| return 0; | |
| } | |
| if (!sendLen) { | |
| sendLen = lseek(fd, 0, SEEK_END); | |
| if (sendLen == -1) { | |
| LOGERR; | |
| close(fd); | |
| return 0; | |
| } | |
| } | |
| addr = mmap(NULL, sendLen, PROT_READ, MAP_SHARED, fd, offset); | |
| if (addr == MAP_FAILED) { | |
| LOGERR; | |
| close(fd); | |
| return 0; | |
| } else | |
| close(fd); | |
| len = write(s, addr, sendLen); | |
| if (len == -1) { | |
| LOGERR; | |
| munmap(addr, sendLen); | |
| return 0; | |
| } | |
| if (len != sendLen) { | |
| io_SetErr(ECANCELED, "Different sizes - request %u bytes, actually sended %u bytes\n", | |
| sendLen, len); | |
| len ^= len; | |
| } | |
| munmap(addr, sendLen); | |
| return len; | |
| } | |
| /* | |
| * ioRecvFile() Receive file from socket, fastest (zero-copy) way | |
| * @s = socket | |
| * @csFile = file for receive | |
| * @recvLen = receive bytes | |
| * @over = overwrite file if exists with mode like 0644 | |
| * return: 0 error, >0 ok, received bytes | |
| */ | |
| size_t | |
| ioRecvFile(int s, const char *csFile, size_t recvLen, int over) | |
| { | |
| void *addr; | |
| int fd; | |
| size_t len; | |
| if (!csFile || !recvLen) | |
| return 0; | |
| if (!over && !access(csFile, F_OK)) | |
| return 0; | |
| fd = open(csFile, O_WRONLY | O_CREAT | O_TRUNC, over); | |
| if (fd == -1) { | |
| LOGERR; | |
| unlink(csFile); | |
| return 0; | |
| } | |
| if (lseek(fd, recvLen - 1, SEEK_SET) == -1) { | |
| LOGERR; | |
| close(fd); | |
| unlink(csFile); | |
| return 0; | |
| } | |
| if (write(fd, "", 1) == -1) { | |
| LOGERR; | |
| close(fd); | |
| unlink(csFile); | |
| return 0; | |
| } | |
| addr = mmap(NULL, recvLen, PROT_WRITE, MAP_SHARED, fd, 0); | |
| if (addr == MAP_FAILED) { | |
| LOGERR; | |
| close(fd); | |
| unlink(csFile); | |
| return 0; | |
| } else | |
| close(fd); | |
| len = read(s, addr, recvLen); | |
| if (len == -1) { | |
| LOGERR; | |
| munmap(addr, recvLen); | |
| unlink(csFile); | |
| return 0; | |
| } | |
| if (len != recvLen) | |
| io_SetErr(EAGAIN, "Different sizes - request %u bytes, actually received %u bytes\n", | |
| recvLen, len); | |
| munmap(addr, recvLen); | |
| return len; | |
| } |