| /* A part of the Windows CE C Extra Library (celibc) |
| Copyright 2007-2015 PC GO Ld. |
| |
| This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
| */ |
| |
| #include <unistd.h> |
| #include <windows.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| |
| #define ZERO_BUFFER_SIZE (512) |
| |
| int ftruncate(int fd, off_t length) { |
| off_t current = lseek(fd, 0, SEEK_CUR); |
| if(current == -1) return -1; |
| off_t current_eof = lseek(fd, 0, SEEK_END); |
| if(current_eof == -1) return -1; |
| |
| off_t offset = length - current_eof; |
| if(offset < 0) { |
| if(lseek(fd, length, SEEK_SET) == -1) goto failed; |
| if(!SetEndOfFile((void *)fd)) goto failed; |
| } else if(offset > 0) { |
| void *buffer = malloc(ZERO_BUFFER_SIZE); |
| if(!buffer) goto failed; |
| memset(buffer, 0, ZERO_BUFFER_SIZE); |
| while(offset > 0) { |
| int s = write(fd, buffer, ZERO_BUFFER_SIZE < offset ? ZERO_BUFFER_SIZE : offset); |
| if(s < 0) { |
| free(buffer); |
| goto failed; |
| } |
| offset -= s; |
| } |
| free(buffer); |
| } |
| |
| lseek(fd, current, SEEK_SET); |
| return 0; |
| |
| failed: ; |
| int e = errno; |
| lseek(fd, current, SEEK_SET); |
| errno = e; |
| return -1; |
| } |
| |
| int truncate(const char *path, off_t length) { |
| if(!path) { |
| errno = EFAULT; |
| return -1; |
| } |
| if(length < 0) { |
| errno = EINVAL; |
| return -1; |
| } |
| if(!*path) { |
| errno = ENOENT; |
| return -1; |
| } |
| |
| int fd = open(path, O_WRONLY); |
| if(fd == -1) return -1; |
| |
| int r = ftruncate(fd, length); |
| int e = errno; |
| if(close(fd) < 0) return -1; |
| errno = e; |
| return r; |
| } |