Changeset 4e6a610 in mainline for uspace/lib/posix/src
- Timestamp:
- 2018-06-25T09:54:28Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bfe90b6
- Parents:
- fb0ec570
- git-author:
- Jiri Svoboda <jiri@…> (2018-06-24 17:51:54)
- git-committer:
- Jiri Svoboda <jiri@…> (2018-06-25 09:54:28)
- Location:
- uspace/lib/posix/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/posix/src/stdio.c
rfb0ec570 r4e6a610 2 2 * Copyright (c) 2011 Jiri Zarevucky 3 3 * Copyright (c) 2011 Petr Koupy 4 * Copyright (c) 2018 Jiri Svoboda 4 5 * All rights reserved. 5 6 * … … 38 39 39 40 #include <assert.h> 40 41 41 #include <errno.h> 42 42 #include <stdbool.h> 43 #include <tmpfile.h> 44 45 #include "posix/fcntl.h" 43 46 #include "posix/stdlib.h" 44 47 #include "posix/string.h" 48 #include "posix/sys/stat.h" 45 49 #include "posix/sys/types.h" 46 50 #include "posix/unistd.h" … … 353 357 } 354 358 355 /** 356 * Get a unique temporary file name (obsolete). 357 * 358 * @param s Buffer for the file name. Must be at least L_tmpnam bytes long. 359 * @return The value of s on success, NULL on failure. 360 */ 361 char *tmpnam(char *s) 362 { 363 assert(L_tmpnam >= strlen("/tmp/tnXXXXXX")); 364 365 static char buffer[L_tmpnam + 1]; 366 if (s == NULL) { 367 s = buffer; 368 } 369 370 strcpy(s, "/tmp/tnXXXXXX"); 371 mktemp(s); 372 373 if (*s == '\0') { 374 /* Errno set by mktemp(). */ 375 return NULL; 376 } 377 378 return s; 379 } 380 381 /** 382 * Get an unique temporary file name with additional constraints (obsolete). 359 /** Determine if directory is an 'appropriate' temporary directory. 360 * 361 * @param dir Directory path 362 * @return @c true iff directory is appropriate. 363 */ 364 static bool is_appropriate_tmpdir(const char *dir) 365 { 366 struct stat sbuf; 367 368 /* Must not be NULL */ 369 if (dir == NULL) 370 return false; 371 372 /* Must not be empty */ 373 if (dir[0] == '\0') 374 return false; 375 376 if (stat(dir, &sbuf) != 0) 377 return false; 378 379 /* Must be a directory */ 380 if ((sbuf.st_mode & S_IFMT) != S_IFDIR) 381 return false; 382 383 /* Must be writable */ 384 if (access(dir, W_OK) != 0) 385 return false; 386 387 return true; 388 } 389 390 /** Construct unique file name. 391 * 392 * Never use this function. 383 393 * 384 394 * @param dir Path to directory, where the file should be created. … … 388 398 char *tempnam(const char *dir, const char *pfx) 389 399 { 390 /* Sequence number of the filename. */ 391 static int seq = 0; 392 393 size_t dir_len = strlen(dir); 394 if (dir[dir_len - 1] == '/') { 395 dir_len--; 396 } 397 398 size_t pfx_len = strlen(pfx); 399 if (pfx_len > 5) { 400 pfx_len = 5; 401 } 402 403 char *result = malloc(dir_len + /* slash*/ 1 + 404 pfx_len + /* three-digit seq */ 3 + /* .tmp */ 4 + /* nul */ 1); 405 406 if (result == NULL) { 407 errno = ENOMEM; 400 const char *dpref; 401 char *d; 402 char *buf; 403 int rc; 404 405 d = getenv("TMPDIR"); 406 if (is_appropriate_tmpdir(d)) 407 dpref = d; 408 else if (is_appropriate_tmpdir(dir)) 409 dpref = dir; 410 else if (is_appropriate_tmpdir(P_tmpdir)) 411 dpref = P_tmpdir; 412 else 413 dpref = "/"; 414 415 if (dpref[strlen(dpref) - 1] != '/') 416 rc = asprintf(&buf, "%s/%sXXXXXX", dpref, pfx); 417 else 418 rc = asprintf(&buf, "%s%sXXXXXX", dpref, pfx); 419 420 if (rc < 0) 421 return NULL; 422 423 rc = __tmpfile_templ(buf, false); 424 if (rc != 0) { 425 free(buf); 408 426 return NULL; 409 427 } 410 428 411 char *res_ptr = result; 412 strncpy(res_ptr, dir, dir_len); 413 res_ptr += dir_len; 414 strncpy(res_ptr, pfx, pfx_len); 415 res_ptr += pfx_len; 416 417 for (; seq < 1000; ++seq) { 418 snprintf(res_ptr, 8, "%03d.tmp", seq); 419 420 int orig_errno = errno; 421 errno = EOK; 422 /* Check if the file exists. */ 423 if (access(result, F_OK) == -1) { 424 if (errno == ENOENT) { 425 errno = orig_errno; 426 break; 427 } else { 428 /* errno set by access() */ 429 return NULL; 430 } 431 } 432 } 433 434 if (seq == 1000) { 435 free(result); 436 errno = EINVAL; 437 return NULL; 438 } 439 440 return result; 441 } 442 443 /** 444 * Create and open an unique temporary file. 445 * The file is automatically removed when the stream is closed. 446 * 447 * @param dir Path to directory, where the file should be created. 448 * @param pfx Optional prefix up to 5 characters long. 449 * @return Newly allocated unique path for temporary file. NULL on failure. 450 */ 451 FILE *tmpfile(void) 452 { 453 char filename[] = "/tmp/tfXXXXXX"; 454 int fd = mkstemp(filename); 455 if (fd == -1) { 456 /* errno set by mkstemp(). */ 457 return NULL; 458 } 459 460 /* Unlink the created file, so that it's removed on close(). */ 461 unlink(filename); 462 return fdopen(fd, "w+"); 429 return buf; 463 430 } 464 431 -
uspace/lib/posix/src/stdlib.c
rfb0ec570 r4e6a610 38 38 39 39 #include <errno.h> 40 #include <tmpfile.h> 40 41 41 42 #include "posix/fcntl.h" … … 163 164 int mkstemp(char *tmpl) 164 165 { 165 int fd = -1; 166 167 char *tptr = tmpl + strlen(tmpl) - 6; 168 169 while (fd < 0) { 170 if (*mktemp(tmpl) == '\0') { 171 /* Errno set by mktemp(). */ 172 return -1; 173 } 174 175 fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); 176 177 if (fd == -1) { 178 /* Restore template to it's original state. */ 179 snprintf(tptr, 7, "XXXXXX"); 180 } 181 } 182 183 return fd; 166 int tmpl_len; 167 int file; 168 169 tmpl_len = strlen(tmpl); 170 if (tmpl_len < 6) { 171 errno = EINVAL; 172 return -1; 173 } 174 175 char *tptr = tmpl + tmpl_len - 6; 176 if (strcmp(tptr, "XXXXXX") != 0) { 177 errno = EINVAL; 178 return -1; 179 } 180 181 file = __tmpfile_templ(tmpl, true); 182 if (file < 0) { 183 errno = EIO; // XXX could be more specific 184 return -1; 185 } 186 187 return file; 184 188 } 185 189 … … 194 198 char *mktemp(char *tmpl) 195 199 { 196 int tmpl_len = strlen(tmpl); 200 int tmpl_len; 201 int rc; 202 203 tmpl_len = strlen(tmpl); 197 204 if (tmpl_len < 6) { 198 205 errno = EINVAL; … … 208 215 } 209 216 210 static int seq = 0; 211 212 for (; seq < 1000000; ++seq) { 213 snprintf(tptr, 7, "%06d", seq); 214 215 int orig_errno = errno; 216 errno = 0; 217 /* Check if the file exists. */ 218 if (access(tmpl, F_OK) == -1) { 219 if (errno == ENOENT) { 220 errno = orig_errno; 221 break; 222 } else { 223 /* errno set by access() */ 224 *tmpl = '\0'; 225 return tmpl; 226 } 227 } 228 } 229 230 if (seq == 10000000) { 231 errno = EEXIST; 217 rc = __tmpfile_templ(tmpl, false); 218 if (rc != 0) { 219 errno = EIO; // XXX could be more specific 232 220 *tmpl = '\0'; 233 221 return tmpl; -
uspace/lib/posix/src/unistd.c
rfb0ec570 r4e6a610 39 39 #include <errno.h> 40 40 41 #include "posix/dirent.h" 41 42 #include "posix/string.h" 43 #include "posix/sys/types.h" 42 44 #include "posix/fcntl.h" 43 45 … … 368 370 */ 369 371 int fd = open(path, O_RDONLY); 370 if (fd < 0) 371 return -1; 372 close(fd); 373 return 0; 372 if (fd >= 0) { 373 close(fd); 374 return 0; 375 } 376 DIR *dir = opendir(path); 377 if (dir != NULL) { 378 closedir(dir); 379 return 0; 380 } 381 return -1; 374 382 } else { 375 383 /* Invalid amode argument. */
Note:
See TracChangeset
for help on using the changeset viewer.