blob: 0fccec977798f77650fbac644c2c0d51dfa9c5a1 [file] [log] [blame]
/*
*
* Copyright (c) International Business Machines Corp., 2001
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* NAME
* getcwd02
*
* DESCRIPTION
* Testcase to check the basic functionality of the getcwd(2) system call.
*
* ALGORITHM
* Get the path name of the current working directory from the current
* shell through a pipe, and compare it with what is returned by
* getcwd(2) system call.
*
* Blocks 1-4 are with char[], #4 is special case where address is -1
*
* Block 1: Call getcwd(2) with valid cwd[]:
* Should work fine
* Block 2: Call getcwd(2) with valid cwd[], size = 0:
* Should return NULL, errno = EINVAL
* Block 3: Call getcwd(2) with valid cwd[], size <= strlen(path):
* i.e. size = 1, Should return NULL, errno = ERANGE
* Block 4: Call getcwd(2) with cwd address = -1, size > strlen(path):
* Should return NULL, errno = EFAULT
*
* Blocks 5-7 are with char*
*
* Block 5: Call getcwd(2) with *buffer = NULL, size = 0:
* Should allocate buffer, and work fine
* Block 6: Call getcwd(2) with *buffer = NULL, size <= strlen(path):
* i.e. size = 1, Should return NULL, errno = ERANGE
* Block 7: Call getcwd(2) with *buffer = NULL, size > strlen(path):
* Should work fine and allocate buffer
*
* HISTORY
* 07/2001 Ported by Wayne Boyer
* 02/2002 Added more testcases, cleaned up by wjh
*
* RESTRICTIONS
* NONE
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "test.h"
#define FAILED 1
char *pwd = "/bin/pwd";
int flag;
char *TCID = "getcwd02";
int TST_TOTAL = 7;
void cleanup(void);
void setup(void);
void do_block1(void);
void do_block2(void);
void do_block3(void);
void do_block4(void);
void do_block5(void);
void do_block6(void);
void do_block7(void);
char pwd_buf[BUFSIZ]; //holds results of pwd pipe
char cwd[BUFSIZ]; //used as our valid buffer
char *buffer = NULL; //catches the return value from getcwd when passing NULL
char *cwd_ptr = NULL; //catches the return value from getcwd() when passing cwd[]
int main(int ac, char **av)
{
FILE *fin;
char *cp;
int lc;
const char *msg; /* parse_opts() return message */
if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
}
setup();
/*
* The following loop checks looping state if -i option given
*/
for (lc = 0; TEST_LOOPING(lc); lc++) {
tst_count = 0;
if ((fin = popen(pwd, "r")) == NULL) {
tst_resm(TINFO, "%s: can't run %s", TCID, pwd);
tst_brkm(TBROK, cleanup, "%s FAILED", TCID);
}
while (fgets(pwd_buf, sizeof(pwd_buf), fin) != NULL) {
if ((cp = strchr(pwd_buf, '\n')) == NULL) {
tst_brkm(TBROK, cleanup, "pwd output too long");
}
*cp = 0;
}
pclose(fin);
do_block1();
do_block2();
do_block3();
do_block4();
do_block5();
do_block6();
do_block7();
}
cleanup();
tst_exit();
}
void do_block1(void) //valid cwd[]: -> Should work fine
{
int flag = 0;
tst_resm(TINFO, "Enter Block 1");
if ((cwd_ptr = getcwd(cwd, sizeof(cwd))) == NULL) {
tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly");
flag = FAILED;
}
if ((flag != FAILED) && (strcmp(pwd_buf, cwd) != 0)) {
tst_resm(TFAIL, "getcwd() returned unexpected working "
"directory: expected: %s, got: %s\n", pwd_buf, cwd);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 1");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 1 FAILED");
} else {
tst_resm(TPASS, "Block 1 PASSED");
}
}
void do_block2(void) //valid cwd[], size = 0: -> Should return NULL, errno = EINVAL
{
int flag = 0;
tst_resm(TINFO, "Enter Block 2");
if (((cwd_ptr = getcwd(cwd, 0)) == NULL)
&& (errno != EINVAL)) {
tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly (wanted EINVAL)");
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 2");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 2 FAILED");
} else {
tst_resm(TPASS, "Block 2 PASSED");
}
}
void do_block3(void) //valid cwd[], size = 1 -> Should return NULL, errno = ERANGE
{
int flag = 0;
tst_resm(TINFO, "Enter Block 3");
if (((cwd_ptr = getcwd(cwd, 1)) != NULL)
|| (errno != ERANGE)) {
tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly (wanted ERANGE)");
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 3");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 3 FAILED");
} else {
tst_resm(TPASS, "Block 3 PASSED");
}
}
void do_block4(void) //invalid cwd[] = -1, size = BUFSIZ: -> return NULL, errno = FAULT
{
/* Skip since uClinux does not implement memory protection */
#ifndef UCLINUX
int flag = 0;
tst_resm(TINFO, "Enter Block 4");
if (((cwd_ptr = getcwd((char *)-1, sizeof(cwd))) != NULL)
|| (errno != EFAULT)) {
tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly (wanted EFAULT)");
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 4");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 4 FAILED");
} else {
tst_resm(TPASS, "Block 4 PASSED");
}
#else
tst_resm(TINFO, "Skipping Block 4 on uClinux");
#endif
}
void do_block5(void) //buffer = NULL, and size = 0, should succeed
{
int flag = 0;
tst_resm(TINFO, "Enter Block 5");
if ((buffer = getcwd(NULL, 0)) == NULL) {
tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly");
flag = FAILED;
}
if ((flag != FAILED) && (strcmp(pwd_buf, buffer) != 0)) {
tst_resm(TFAIL, "getcwd() returned unexpected working "
"directory: expected: %s, got: %s\n", pwd_buf, buffer);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 5");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 5 FAILED");
} else {
tst_resm(TPASS, "Block 5 PASSED");
}
free(buffer);
buffer = NULL;
}
void do_block6(void) //buffer = NULL, size = 1: -> return NULL, errno = ERANGE
{
int flag = 0;
tst_resm(TINFO, "Enter Block 6");
if (((buffer = getcwd(NULL, 1)) != NULL)
|| (errno != ERANGE)) {
tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly (wanted ERANGE)");
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 6");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 6 FAILED");
} else {
tst_resm(TPASS, "Block 6 PASSED");
}
}
void do_block7(void) //buffer = NULL, size = BUFSIZ: -> work fine, allocate buffer
{
int flag = 0;
tst_resm(TINFO, "Enter Block 7");
if ((buffer = getcwd(NULL, sizeof(cwd))) == NULL) {
tst_resm(TFAIL|TERRNO, "getcwd() failed unexpectedly");
flag = FAILED;
}
if ((flag != FAILED) && (strcmp(pwd_buf, buffer) != 0)) {
tst_resm(TFAIL, "getcwd() returned unexpected working "
"directory: expected: %s, got: %s\n", pwd_buf, buffer);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 7");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 7 FAILED");
} else {
tst_resm(TPASS, "Block 7 PASSED");
}
free(buffer);
buffer = NULL;
}
void setup(void)
{
/* FORK is set here because of the popen() call above */
tst_sig(FORK, DEF_HANDLER, cleanup);
TEST_PAUSE;
/* create a test directory and cd into it */
tst_tmpdir();
}
void cleanup(void)
{
/* remove the test directory */
tst_rmdir();
}