/* Write size random bytes into file descriptor fd at offset,
   returning the number of bytes actually written */
uint64_t tests_write_filled_file(int fd, off_t offset, uint64_t size)
{
	ssize_t written;
	size_t sz;
	unsigned start = 0, length;
	uint64_t remains;
	uint64_t actual_size = 0;

	CHECK(lseek(fd, offset, SEEK_SET) == offset);

	init_write_buffer();
	remains = size;
	start = offset % WRITE_BUFFER_SIZE;
	while (remains > 0) {
		length = WRITE_BUFFER_SIZE - start;
		if (remains > length)
			sz = length;
		else
			sz = (size_t) remains;
		written = write(fd, write_buffer + start, sz);
		if (written <= 0) {
			CHECK(errno == ENOSPC); /* File system full */
			errno = 0;
			break;
		}
		remains -= written;
		actual_size += written;
		if (written == sz)
			start = 0;
		else
			start += written;
	}
	tests_maybe_sync(fd);
	return actual_size;
}
Ejemplo n.º 2
0
/* Write size random bytes into file descriptor fd at the current position,
   returning the number of bytes actually written */
static uint64_t fill_file(int fd, uint64_t size)
{
	ssize_t written;
	size_t sz;
	unsigned start = 0, length;
	uint64_t remains;
	uint64_t actual_size = 0;

	init_write_buffer();
	remains = size;
	while (remains > 0) {
		length = WRITE_BUFFER_SIZE - start;
		if (remains > length)
			sz = length;
		else
			sz = (size_t) remains;
		before();
		written = write(fd, write_buffer + start, sz);
		if (written <= 0) {
			CHECK(errno == ENOSPC); /* File system full */
			errno = 0;
			after("write");
			fprintf(stderr,"\nrndrm99: write failed with ENOSPC\n");fflush(stderr);
			display_stats();
			break;
		}
		after("write");
		remains -= written;
		actual_size += written;
		if ((size_t) written == sz)
			start = 0;
		else
			start += written;
	}
	return actual_size;
}
Ejemplo n.º 3
0
/**
* @brief Test read/write functionality of spi by using loopback
*
* @par Detailed Description:
* Tests the read and write functionality of the spi device by putting the device
* in loopback mode.  This is tested in 2 ways: writing the data then reading it
* back from the read buffer or by doing the read/write at the same time using ioctl
*
* Test:
* 1) Opens file for spi device ('/dev/spi-8')
* 2) Sets up the spi device in loopback mode using ioctl
* 3) Write to the spi bus
* 4) Read from the spi bus buffer
* 5) Commented Out ---- Check if data written matches data read
* 6) Loop though steps 4-5 for  SPI_TEST_CYCLES number of cycles
* 7) So ioctl read/write operation and check if data written matches data read
* 8) Close spi bus
*
* @return
* SUCCESS  ------ Test Passes
* ERROR ------ Test Failed
*/
int dspal_tester_spi_loopback_test(void)
{
	int spi_fildes = SUCCESS;
	int cycle_count;
	int result = SUCCESS;
	uint8_t write_data_buffer[SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH];
	uint8_t read_data_buffer[SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH];
	int test_data_length_in_bytes = SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH - 1;
	struct dspal_spi_ioctl_loopback loopback;
	struct dspal_spi_ioctl_read_write read_write;

	LOG_DEBUG("testing spi open for: %s", SPI_DEVICE_PATH);
	spi_fildes = open(SPI_DEVICE_PATH, 0);

	if (spi_fildes < SUCCESS) {
		LOG_ERR("error: failed to open spi device path: %s", SPI_DEVICE_PATH);
		result = ERROR;
		goto exit;
	}

	/*
	 * Initialize the write buffers in preparation for a read/write sequence.
	 */
	write_data_buffer[SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH - 1] = 0;
	init_write_buffer(write_data_buffer, SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH - 1);

	/*
	 * Enable loopback mode to allow write/reads to be tested internally.
	 */
	LOG_DEBUG("enabling spi loopback mode");
	loopback.state = SPI_LOOPBACK_STATE_ENABLED;
	result = ioctl(spi_fildes, SPI_IOCTL_LOOPBACK_TEST, &loopback);

	if (result < SUCCESS) {
		LOG_ERR("error: unable to activate spi loopback mode");
		goto exit;
	}

	/*
	 * Test loopback mode using combined read/write mode.
	 */
	LOG_DEBUG("testing spi write/read for %d cycles", SPI_TEST_CYCLES);

	for (cycle_count = 0; cycle_count < SPI_TEST_CYCLES; cycle_count++) {
		memset(read_data_buffer, 0, sizeof(read_data_buffer));
		read_write.read_buffer = &read_data_buffer[0];
		read_write.read_buffer_length = test_data_length_in_bytes;
		read_write.write_buffer = &write_data_buffer[0];
		read_write.write_buffer_length = test_data_length_in_bytes;

		LOG_DEBUG("writing bytes: (%d bytes)",
			  test_data_length_in_bytes);

		result = ioctl(spi_fildes, SPI_IOCTL_RDWR, &read_write);

		if (result < SUCCESS) {
			LOG_ERR("error: unable to activate read/write ioctl");
			goto exit;
		}

		if (!dpsal_tester_is_memory_matching(write_data_buffer, read_data_buffer, test_data_length_in_bytes)) {
			LOG_ERR("error: read/write memory buffers do not match");
			goto exit;
		}

		LOG_DEBUG("written data matches read data");
	}

	result = SUCCESS;
	LOG_DEBUG("SPI lookback test passed");

exit:

	if (spi_fildes > SUCCESS) {
		close(spi_fildes);
	}

	return result;
}
Ejemplo n.º 4
0
Archivo: sunlink.c Proyecto: aosm/srm
int sunlink(const char *path) {
  struct stat statbuf;
  struct statfs fs_stats;
#if HAVE_LINUX_EXT2_FS_H
  int flags = 0;
#endif
  int fmode = (options & OPT_VERIFY) ? O_RDWR : O_WRONLY;
  struct flock flock;

  if (lstat(path, &statbuf) == -1) 
    return -1;
  if (!S_ISREG(statbuf.st_mode))
    return rename_unlink(path);

  if (statbuf.st_nlink > 1) {
    rename_unlink(path);
    errno = EMLINK;
    return -1;
  }

  if ( (file = open(path, fmode)) == -1) /* BSD doesn't support O_SYNC */
    return -1;

  if (fcntl(file, F_WRLCK, &flock) == -1) {
    close(file);
    return -1;
  }

  if (fstatfs(file, &fs_stats) == -1 && errno != ENOSYS) {
    close(file);
    return -1;
  }

  /* warn when trying to overwrite files on a non-local fs,
     since there are no guarantees that writes will not be
     buffered on the server, or will overwrite the same spot. */
  if (options & OPT_V) {
    if ((fs_stats.f_flags & MNT_LOCAL) == 0) {
      printf("warning: %s is not on a local filesystem!\n", path);
      fflush(stdout);
    }
  }

#if HAVE_LINUX_EXT2_FS_H
  if (fs_stats.f_type == EXT2_SUPER_MAGIC) 
    if (ioctl(file, EXT2_IOC_GETFLAGS, &flags) == -1) {
      close(file);
      return -1;
    } 

  if ( (flags & EXT2_UNRM_FL) || (flags & EXT2_IMMUTABLE_FL) ||
      (flags & EXT2_APPEND_FL) )  
    {
      close(file);
      errno = EPERM;
      return -1;
    }

#endif /* HAVE_LINUX_EXT2_FS_H */

/* chflags(2) turns out to be a different system call in every BSD
   derivative. The important thing is to make sure we'll be able to
   unlink it after we're through messing around. Unlinking it first
   would remove the need for any of these checks, but would leave the
   user with no way to overwrite the file if the process was
   interrupted during the overwriting. So, instead we assume that the
   open() above will fail on immutable and append-only files and try
   and catch only platforms supporting NOUNLINK here.

   FreeBSD - supports NOUNLINK (from 4.4 on?)
   MacOS X - doesn't support NOUNLINK (as of 10.3.5)
   OpenBSD - doesn't support NOUNLINK (as of 3.1)
   Tru64   - unknown
   
   Note: unsupported flags are defined as 0 at the top of this file,
   so a specific platform check is not required here.
*/

#if HAVE_CHFLAGS
  if ((statbuf.st_flags & UF_IMMUTABLE) || 
      (statbuf.st_flags & UF_APPEND) ||
      (statbuf.st_flags & UF_NOUNLINK) || 
      (statbuf.st_flags & SF_IMMUTABLE) ||
      (statbuf.st_flags & SF_APPEND) ||
      (statbuf.st_flags & SF_NOUNLINK)) 
    {
      close(file);
      errno = EPERM;
      return -1;
    }
#endif /* HAVE_CHFLAGS */

  if (init_write_buffer(&statbuf, &fs_stats) == -1) {
    close(file);
    return -1;
  }
#if defined F_NOCACHE
  /* before performing file I/O, set F_NOCACHE to prevent caching */
  (void)fcntl(file, F_NOCACHE, 1);
#endif

  overwrite_file();

#if HAVE_LINUX_EXT2_FS_H
  ioctl(file, EXT2_IOC_SETFLAGS, EXT2_SECRM_FL);
#endif

  if ((options & OPT_N) == 0) {
    if (ftruncate(file, 0) == -1) {
      close(file);
      return -1;
    }
  }

  close(file);

#if __APPLE__
  /* Also overwrite the file's resource fork, if present. */
  {
    static const char *RSRCFORKSPEC = "/..namedfork/rsrc";
    size_t rsrc_fork_size;
    size_t rsrc_path_size = strlen(path) + strlen(RSRCFORKSPEC) + 1;
    char *rsrc_path = (char *)alloca(rsrc_path_size);
    if (rsrc_path == NULL) {
      errno = ENOMEM;
      return -1;
    }
    if (snprintf(rsrc_path, MAXPATHLEN,
        "%s%s", path, RSRCFORKSPEC ) > MAXPATHLEN - 1) {
      errno = ENAMETOOLONG;
      return -1;
    }

    if (lstat(rsrc_path, &statbuf) != 0) {
      int err = errno;
      if (err == ENOENT || err == ENOTDIR) {
        rsrc_fork_size = 0;
      } else {
        return -1;
      }
    } else {
      rsrc_fork_size = statbuf.st_size;
    }

    if (rsrc_fork_size > 0) {

      if ((file = open(rsrc_path, O_WRONLY)) == -1) {
        return -1;
      }
      if (fcntl(file, F_WRLCK, &flock) == -1) {
        close(file);
        return -1;
      }

      if (options & OPT_V) {
        printf("removing %s\n", rsrc_path);
        fflush(stdout);
      }

      if (init_write_buffer(&statbuf, &fs_stats) == -1) {
        close(file);
        return -1;
      }
    #if defined F_NOCACHE
      /* before performing file I/O, set F_NOCACHE to prevent caching */
      (void)fcntl(file, F_NOCACHE, 1);
    #endif

      overwrite_file();

      if ((options & OPT_N) == 0) {
        if (ftruncate(file, 0) == -1) {
          close(file);
          return -1;
        }
      }
      close(file);
    }
  }
#endif /* __APPLE__ */

  if (options & OPT_N)
    return 0;

  return rename_unlink(path);
}